Contiki: Why is a linker script for cc253x not present? - linker

I was going through the codes of Contiki for cc2530, i find that a linker script is missing for cc2530. Can anybody tell me how it works without a linker script?

Please take a look on this Makefile.
%.banked-hex: %.flags
### Link again with new bank allocations
#echo "\nFinal Link"
#echo "==============="
$(CC) $(LDFLAGS) $(shell cat $<) -o $# $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib > /dev/null
Is this a final link script as you mean?

Related

Makefile link issue

I can't figure out how link static libraries in Makefiles. I use ubuntu 20.04 LTS. I even tried to use direct path to these libraries, and the issue remains unchanged. Here's my Makefile code.
LIB = libgeoms.a
SRC = mlx_pxl_put.c \
std_arc.c \
std_crcl.c \
std_line.c \
std_poly.c \
std_rect.c \
CC = clang
WARNS = -Wall -Wextra -Werror
OBJ = $(SRC:.c=.o)
SRCP = /usr/local/wealdboar/src/
INCLUDEP = /usr/local/wealdboar/include/
LIBP = /usr/local/wealdboar/lib/
HEADER = geoms.h
LX11P = /usr/lib/x86_64-linux-gnu/libX11.a
LXEXTP = /usr/lib/x86_64-linux-gnu/libXext.a
LMLX = /usr/local/lib/libmlx.a
$(LIB): $(OBJ)
#echo "Every funtion is compile proved ..."
#ar rcs $(LIB) $(OBJ)
#echo "All functions added to static lib ..."
$(OBJ): %.o :%.c
#echo "check $< to be right"
#$(CC) $(WARNS) -c $(LX11P) $(LMLX) $(LXEXTP) $< -o $#
all: $(LIB)
clean:
#echo "removing all binaries ..."
#rm -rf $(OBJ)
fclean: clean
#echo "removing static library ..."
#rm -rf $(LIB)
re: fclean all
install: re clean
#echo "coping $(LIB) to $(LIBP)"
#sudo cp $(LIB) $(LIBP)
#echo "coping sources to $(SRCP)"
#sudo cp $(SRC) $(SRCP)
#echo "coping header to $(INCLUDEP)"
#sudo cp $(HEADER) $(INCLUDEP)
Issue image
You haven't specified the -l or -L flags to tell clang to link against choosen libraries.
First please don't paste image links in StackOverflow. They aren't searchable, they aren't quotable, and many people are not willing to click a on links to other sites. Please cut and paste the actual messages.
Second, when working with makefiles you should not use the # option which hides the most important information about the commands being run. It's much harder to debug a makefile when the command lines are not visible. If you really want to hide the actual commands you should either add in the # after everything is already working and not before, or else use tricks like this to allow for a debug mode.
Finally your error is as I suggested in my comment above. You are trying to add static libraries to a compile command (a command that compiles source files into object files). Libraries can only be added into link commands (commands that convert object files and libraries into executables).
You are not actually creating an executable anywhere in your makefile that I can see, so there's nowhere that you can add libraries here. But, you need to remove them from the compile rule:
$(OBJ): %.o :%.c
#echo "check $< to be right"
#$(CC) $(WARNS) -c $< -o $#

gmake (Gnu) to make (Cygwin) - verification of my implementation [only 3 statements]

I need to convert a makefile built for gmake into a makefile that could be executed via cygwin "make" command.
The GMAKE code is below:
OBJ := ${SOURCES:%.c=%.o}
%.o: %.c
$(CC) -c -o $# $< $(CFLAGS) $(DEFINES)
$(LIBNAME).lib: $(OBJ)
$(AR) rcs $# $(OBJ)
clean:
del $(OBJ)
del *.out
I've used the statements below in the Cygwin makefile. Could you please confirm, if it replicates the gmake statements above or am I missing something. Any inputs would be helpful.
Cygwin "make":
OBJ := ${SOURCES:%.c=%.o}
%.obj: %.c
$(CC) -c -o `cygpath -w $#` `cygpath -w $<` $(CFLAGS) $(DEFINES)
.DEFAULT_GOAL := ${LIBNAME}.lib
${LIBNAME}.lib: $(OBJS)
$(SILENCE)echo -e "Archive: ${LIBNAME}.lib\n"
$(SILENCE)$(AR) $(ARFLAGS) `cygpath -w $#` ${OBJS}}
clean:
rm $(OBJ)
rm *.out
Thanks much in advance.
As pointed out by #matzeri, cygwin make is gnu make.
That's why I use it.
The first makefile looks fine to me.
If all your files use relative paths, everything should be fine.
Even the Microsoft compiler can build subdir/file.cpp and stick the object into objdir/file.o (cl subdir/file.cpp -o objdir/file.o).
Hint: Strive manfully to use forward slashes in your filenames. Always.
The only difficulty you might have is with absolute paths,
as typically appear in include paths say.
/usr/local/include only makes sense to cygwin programs.
cl.exe would like this translated to C:/cygwin64/usr/local/include.
Don't use backslashes unless the command really really requires it.
One issue then is that bash interprets backslashes,
so you will have to quote the filename in some way to prevent this.
objdir/1.o: /usr/local/src/1.cpp
some-odd-compiler "$$(cygpath -wa $<)" -o "$$(cygpath -w $#)"
Quoting not required if you use forward slashes (cygpath -ma).
Why prefer $(…) over `…`? Because then the double quotes nest.
Useful if the path in question expands to something with a space in it ("$$(cygpath -wa "$<")")

Makefile logging which stops at first error and display the error

I am looking for a way to log compilation errors within a makefile but here is my problem:
the line without log function is as follows:
$(OBJ_PATH)/%.obj: $(SRC_PATH_ASW)/%.c
#echo -Compiling $<:
$(CC) $(INCLUDE_ASW) $(INCLUDE_ASW_AUTO) $(INCLUDE_BSW) -c $< $(CFLAGS)
I tried to redirect stderr and/or stdout in a log file using the following command
$(OBJ_PATH)/%.obj: $(SRC_PATH_ASW)/%.c
#echo -Compiling $<:
$(CC) $(INCLUDE_ASW) $(INCLUDE_ASW_AUTO) $(INCLUDE_BSW) -c $< $(CFLAGS) > $#.log
This solution won't display the message to the terminal but only within the log file. (i tried all possible kind of redirection without success)
I also tried with tee but the problem is different, in fact the makefile won't stop at first error since the tee command return code will always be successful.
$(OBJ_PATH)/%.obj: $(SRC_PATH_ASW)/%.c
#echo -Compiling $<:
$(CC) $(INCLUDE_ASW) $(INCLUDE_ASW_AUTO) $(INCLUDE_BSW) -c $< $(CFLAGS) | tee $#.log
What I would like if possible is to be able to log compilation result into a file as well as disply it but that the makefile stops at first compilation error and does not continue with other files compilation.
Thank you for your support.
You can use set -o pipefail or PIPESTATUS[0]
set -o pipefail; $(CC) ... | tee file.log
will return an error if the $(CC) ... or tee... commands fail. Alternatively if you just do
$(CC) ... | tee file.log
Then ${PIPESTATUS[0]} will be the error code of the first command ($(CC)...) (you can tack an exit ${PIPESTATUS[0]} at the end of the line for example.
I've often wanted to do this too and the solution I came up with was to create this short shell script and alias make to run that instead.
#!/bin/sh
make $* | tee make.log

Can I regenerate a makefile for a C project, with correct link order and dependencies?

I have source code I last worked on in the late 90's-2000 and have it all backed up, apart from the makefile (yes berate away, bad backups are almost as good as no backups): so... I am wondering if there is any automated way to generate the makefile or a good way to analyse the dependencies quickly?
Specifically I am looking for:
a tool which could analyse the dependencies and correct the link order for me.
if such does not exist, then advice is greatly appreciated as to how to best approach this problem from someone who has had similar problem(s) in the past
failing either of the above two options, I think the best approach is to create an analysis/make-file creation tool which can automatically generate the dependencies order for linking (I have held off on this approach as time is always in short supply to squeeze in another project).
The reason for this quest for help/advice is that the code-base is 300,000 lines of code (excluding comments) and spans hundreds of C/O files, and as often as I have tried creating a make-file by hand, it frustrates and confounds, hence my last attempt to seek help and ask in here.
For reference: I have tried Cmake, AutoMake, GenMake and similar tools in the past to generate the makefile, all to no avail, as the dependencies are horrendous.
Generic makefile script
As it may be of use to others, here is the makefile I usually use for less convoluted C and C++ projects, as it saves me having to worry about creating a new one every time:
$(VERBOSE).SILENT:
PROGRAMNAME = prog
CC = gcc
CC += -c
CPP = g++
CPP += -c
ASM = nasm
ASM += -f elf -d ELF_TYPE
LD = g++
OBJFILES = $(patsubst %.c,%.o,$(wildcard *.c))
OBJFILES += $(patsubst %.s,%.o,$(wildcard *.s))
OBJFILES += $(patsubst %.cpp,%.o,$(wildcard *.cpp))
all: $(PROGRAMNAME)
clean:
#echo "Cleaning object files"
#echo " rm -f *.o"
rm -f *.o
#echo "Cleaning backups"
#echo " rm -f *~"
rm -f *~
#echo "Removing program file"
#echo " rm -f "$(PROGRAMNAME)
rm -f $(PROGRAMNAME)
%.o: %.s
#echo "Assembling ASMs "$#
#echo " ASM "$<
$(ASM) $<
%.o: %.c
#echo "(C)ompiling "$#
#echo " CC "$<
$(CC) $<
%.o: %.cpp
#echo "(C++)ompiling "$#
#echo " CPP "$<
$(CPP) $<
$(PROGRAMNAME): $(OBJFILES)
#echo "Get ready...."
#echo "Linking "$#
#echo " LD -o "$(PROGRAMNAME)" "$(OBJFILES)
$(LD) -o $(PROGRAMNAME) $(OBJFILES)
#echo "Cry if it worked! Scream swear and cry if it did not..."
strip: $(PROGRAMNAME)
#echo "Stripping "$(PROGRAMNAME)
echo -n "Size of "$(PROGRAMNAME)" before stripping is "
ls -sh $(PROGRAMNAME) | cut -d' ' -f1
#echo " Stripping "$(PROGRAMNAME)
strip $(PROGRAMNAME)
echo -n "Size of "$(PROGRAMNAME)" after stripping is "
ls -sh $(PROGRAMNAME) | cut -d' ' -f1
nothing:
#echo "Nothing to do; see you later - I'm going home!!!"
#echo "Hey, try some of these:"
#echo "make all - this would be the one you want"
#echo "make strip - does not work in the real world, only in computers"
#echo "make clean - will help clean your mind up"
You are looking for the classic Unix tool from MIT, makedepend.
gcc & clang can generate dependencies, see Advanced Auto-Dependency Generation , this won't solve the whole problem but shall help you.
On a linux/unix system:
find . -name "*.c" -print > sources will give you a list of all the sources.
find . -name "*.c" -print|sed s/\.c/\.o > objects should give you a list that you can stick "OBJECTS=" in front of [maybe manually add some linebreaks].
cat sources|xargs gcc -M > myprog.deps should give you a list of header dependencies that you can include myprog.deps in your makefile. [1]
Now all you need is
TARGET = myprog # Whatever you call your program!
OBJECTS = ... # from "objects" file above.
SOURCES = ... # from "sources" file above
INCLUDES = -I subdir1 -I subdir2 ... # include directories used by this product
CFLAGS = ... ${INCLUDES} # Some suitable settings
CC = gcc
LD = ${CC}
LDFLAGS = ... # I don't know what this needs to be - usually nothing complicated.
all: ${TARGET}
clean:
rm -f ${TARGET} ${OBJECTS}
${TARGET}: ${OBJECTS}
${LD} -o $# ${OBJECTS}
.c.o:
${CC} -o $# $<
That should have MOST of the hard work done, unless you have to build internal tools or your many source files don't actually produce one final binary of course - in the latter case, you'll probably have to search for "main" and go through the above steps for each executable - you can still use a top-level Makefile and use include of the intermediate ones.
[1] You could add to the makefile - particularly if your project produces many different executables.
myprog.deps: ${SOURCES}
${CC} -MM ${SOURCES} > myprog.deps
include myprog.deps
Thanks for the great response: concise and very informational. Based on the answers I am now using a mixture of manual effort and GNU AutoMake (the modern successor to makedepend) to try recompiling, and so far seems to be quite effective.
Then shall come the fun and games of porting to OO code in C++...that's a task I would gladly avoid but needs must.
Thanks again!

How to solve this linking problem in Makefile?

Here's my Makefile:
DIR=..
ARG=$(QUERY_STRING)
MAIN=main
SRC_DIR=$(DIR)/src
BIN_DIR=$(DIR)/bin
INC_DIR=$(DIR)/inc
LIB_DIR=$(DIR)/lib
LIBS=markdown
all: $(MAIN) exec
$(MAIN): $(MAIN).o
$(LD) $^ -L $(LIB_DIR) -l $(LIBS) -o $(BIN_DIR)/$#
$(MAIN).o: $(SRC_DIR)/$(MAIN).c
$(CC) $^ -I $(INC_DIR) -o $#
exec:
$(BIN_DIR)/$(MAIN) $(ARG)
clean:
rm -f *.o core.* $(BIN)/$(MAIN)
It's clearly defined how my project is organized, so I will not explain it. It does compile without any problems, but on binary execution $(BIN_DIR)/$(MAIN) the following error appears:
../bin/main: error while loading shared libraries: rintf: cannot open shared object file: No such file or directory
make: *** [exec] Error 127
What library does rintf belong? I tried to link -lc too, but that doesn't solves the problem.
Is there something wrong with my Makefile? Or should I link something extra to $(MAIN)?
Thanks in advance for your responses.
You should essentially never link a program by invoking ld directly; always use your compiler to do the linking. It passes all sorts of extra arguments to ld to make things work. Replace the $(LD) with $(CC). Do that regardless of whether it actually fixes your problem or not.
'Tis odd that you are not getting the name of the shared object specified in the error message.
This manual page for rintf() indicates that it is declared in <math.h>; most likely, you need to add the maths library to the link line: -lm.
I would rewrite some of your makefile:
LIB1 = -lmarkdown
LIB2 = -lm
LIBS = $(LIB1) $(LIB2)
LDFLAGS = -L $(LIB_DIR)
...
$(MAIN): $(MAIN).o
$(CC) $^ $(LDFLAGS) $(LIBS) -o $(BIN_DIR)/$#
Usually, this error appears when the linker is not able to find the needed shared object (.so file).I am assuming Linux platform.
In Linux OS, you can search for the file using: find, or locate. If you can find the .so file, try to update the linker cache using ldconfig. If it did not work, check the linker configuration files under /etc/ld.conf.d/ to see if the library path is included. If you changed the configuration, don't forget to update the cache again!

Resources