Contiki port will not override printf - c

I am trying to create a port of contiki for my custom platform using an stm32l1 processor. However when i am trying to override the default printf function from arm-none-eabi-gcc newlib it will not let me.
I have tried creating hedaer and source files, adding them to be built and then either creating the function 'printf' and 'sprintf' in them or naming them something different and then trying to use
#define printf my_printf.
I have also followed other tips i found online that tells me to create a newlib stub file providing the various functions _sbrk , _write , _read... and so on.
However everytime i try to build my program with any printf command, the linker complains on all the newlib stub files with undefinded references.
undefined reference to _sbrk
How can i get the contiki build system to override the standard printf function?
On ubuntu14:10 with gcc 4.93.
CC targets/r1501/printf/printf-stdarg.c
CC contiki/../arm/stm32l152/./syscalls.c
CC ....
CC contiki/core/net/mac/cxmac/cxmac.c
AR contiki-r1501.a
CC project.c
LD project.r1501
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/thumb/libg.a(lib_a-sbrkr.o): In function_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to _sbrk'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/thumb/libg.a(lib_a-writer.o): In function_write_r':
writer.c:(.text._write_r+0x10): undefined reference to _write'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/thumb/libg.a(lib_a-closer.o): In function_close_r':
....More errors from libg.a `
In the syscalls.c file all of theese undefined references are specified.
and printf and sprintf are defined in printf-sdarg.c
arm-none-eabi-gcc -DCONTIKI=1 -DCONTIKI_TARGET_R1501=1
-DNETSTACK_CONF_WITH_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -DAUTOSTART_ENABLE -DHSE_VALUE=8000000 -DF_CPU=32000000 -DPLL_SOURCE_HSE -D'GIT_DESC="v0.1-23-g0c3a4d8-dirty"' -specs=nosys.specs -I. -Icontiki/core -Icontiki/../arm/stm32l152 -Icontiki/../arm/stm32l152/loader -Icontiki/../arm/stm32l152/lib/STM32L1xx_StdPeriph_Driver/inc -Icontiki/../arm/stm32l152/lib/CMSIS/Include -Icontiki/../arm/stm32l152 -Icontiki/platform/r1501 -DWITH_ASCII -DMCK=32000000 -mlittle-endian -mthumb -mcpu=cortex-m3 -msoft-float -Wno-strict-aliasing -DRUN_AS_SYSTEM -DROM_RUN -std=c99 -g -lc -larchive -Lcontiki/../arm/stm32l152 -fdiagnostics-color=always -O0 -I. -Itargets/r1501/. -Itargets/r1501/dev -Itargets/r1501/rf230bb -Itargets/r1501/printf -Icontiki/../arm/stm32l152/. -Icontiki/../arm/stm32l152/lib/STM32L1xx_StdPeriph_Driver/src -Icontiki/core/dev -Icontiki/core/lib -Icontiki/core/net -Icontiki/core/net/llsec -Icontiki/core/net/mac -Icontiki/core/net/rime -Icontiki/core/net/rpl -Icontiki/core/sys -Icontiki/core/cfs -Icontiki/core/ctk -Icontiki/core/lib/ctk -Icontiki/core/loader -Icontiki/core/. -Icontiki/apps/ping6 -Icontiki/core/sys -Icontiki/core/dev -Icontiki/core/lib -Icontiki/core/net/ipv6 -Icontiki/core/net/ip -Icontiki/core/net/rpl -Icontiki/core/net/mac -Icontiki/core/net/llsec -Icontiki/core/net/mac/sicslowmac -Icontiki/core/net/rime -Icontiki/core/net -Icontiki/core/net/mac/contikimac -Icontiki/core/net/mac/cxmac -Itargets/r1501/ -Icontiki -DCONTIKI_VERSION_STRING=\"Contiki-2.6-2077-ga79edc6\" -DAUTOSTART_ENABLE -c project.c -o project.co arm-none-eabi-gcc -L contiki/../arm/stm32l152 -T contiki/../arm/stm32l152/stm32l1xx.ld -g
-nostartfiles -mthumb -fdiagnostics-color=always project.co obj_r1501/contiki-main.o \
contiki-r1501.a -o project.r1501 /usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/thumb/libg.a(lib_a-sbrkr.o): In function `_sbrk_r':

Related

Compiling CUDA code while linking a static library

I have C code main_code.c and helper_code.c. The former depends on some CUDA code cuda_code.cu and the latter on an external library mylib. For my external library mylib to work, I need to link it to my code with the -static flag:
g++ main_code.c helper_code.c -o main_code -static -L/usr/local/mylib/lib -lmylib -lmylib2
But main_code.c also depends on CUDA code- cuda_code.cu. I can link it with:
nvcc cuda_code.cu -c
g++ main_code.c -o main_code cuda_code.o -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
I want to compile my code together with the CUDA code and the external library mylib. However, linking mylib works only with the -static flag. A naive attempt would be the following but it does not work:
nvcc cuda_code.cu -c
g++ main_code.c helper_code.c -o main_code cuda_code.o -static -L/usr/local/mylib/lib -lmylib -lmylib2 -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
This gives the error:
/usr/bin/ld: cannot find -lcudart
which I'm assuming is because you cannot use the static flag while linking with CUDA (because it goes away when I remove the -static flag (in addition to also removing the mylib library linking)).
I then tried compiling helper_code.c separately and then linking it to main_code.c since it's just helper_code.c that needs mylib:
helper.o:
g++ helper_code.c -c -static -L/usr/local/mylib/lib -lmylib -lmylib2
cuda-code.o:
nvcc cuda_code.cu -c
main-code: helper.o cuda-code.o
g++ main_code.c -o main_code helper_code.o cuda_code.o -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
But this also does not work. I get an undefined reference error that's referring to a function defined in mylib, meaning the linking to mylib isn't working. I can resolve that error by including the mylib library and using the -static flag but that then breaks the CUDA linking.
I can separately get the CUDA linking (to cuda_code.cu) to work or mylib linking to work but not both at the same time.
So is there a workaround to link mylib (which needs -static) while at the same time also linking my CUDA code (which does not allow -static)?
Following the answer linked in talonmies's comment, the following did the trick:
g++ main_code.c -o main_code helper_code.o cuda_code.o -L/usr/local/mylib/lib -L/usr/local/cuda-10.0/lib64 -Wl,-Bstatic -lmylib -lmylib2 -Wl,-Bdynamic -lcudart

Why the functions such as "_write" in retarget.c is not linked when retarget.o is archived in a static library?

I implement a retarget.c to retarget the printf output to serial port for debugging, it can be linked and works very well, if my link command likes this:
arm-none-eabi-gcc --specs=nano.specs --specs=nosys.specs -g -mcpu=cortex-m4 -mthumb -fmessage-length=0 -std=c99 -fno-builtin -Wl,--gc-sections -Wl,-Map=main.map -T"$(LINKERFILE)" -o main.elf main.o retarget.o $(BUILDDIR)/libs.a -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
but when I archive retarget.o into the archive file $(BUILDDIR)/libs.a, and the link command likes this one:
arm-none-eabi-gcc --specs=nano.specs --specs=nosys.specs -g -mcpu=cortex-m4 -mthumb -fmessage-length=0 -std=c99 -fno-builtin -Wl,--gc-sections -Wl,-Map=main.map -T"$(LINKERFILE)" -o main.elf main.o $(BUILDDIR)/libs.a -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
it can be linked successfully, but the function printf doesn't output anything to the serial port, it seems that the my own version functions, such as _write in the retarget.c are not used in the final compiled program.
your _write implementation isn't linked because _write is already defined in libnosys.a which you included via --specs=nosys.specs.
To use the _write symbol defined in your static library libs.a, invoke gcc with -Wl,--undefined=_write during the final linking.
see: man ld | grep -A4 --undefined=symbol
--undefined=symbol
Force symbol to be entered in the output file as an undefined symbol.
Details
First: spec files. gcc is a compiler-driver which invokes subprograms including cc and ld. Spec files are used to specify the behavior of gcc.
The compiler's builtin specs can be seen with arm-none-eabi-gcc -dumpspecs. Try it out! See also: gcc -dumpspecs
Passing --specs=nosys.specs at the beginning of the command line inserts a -lnosys in the call to ld. (What are “nosys”, “nano”, “rdimon” terms when using ARM GCC?)
arm-none-eabi-objdump -t arm-none-eabi/lib/libnosys.a | grep _write locates the _write(...) that is likely overriding the one you defined in $(BUILDDIR)/libs.a
See also: the Makani firmware repository, in which a static library implementing syscalls marks them as --undefined (Generation of linker options)

gcc flags equivalent to LD_PRELOAD?

I currently compile a program called do_foo like so:
gcc -Wall -Wextra -g3 -pthread do_foo.c -o do_foo
and I run it like this:
LD_LIBRARY_PATH=.. LD_PRELOAD=libfoo.so ./do_foo
libfoo.so is strange because:
Has a bunch of functions marked with __attribute__((constructor)) and
Intercepts libc functions like malloc, send, etc
Instead of using LD_PRELOAD to link libfoo.so, I'd like to do it at compile time. I would expect to be able to do it like this:
gcc -Wall -Wextra -g3 -L.. -lfoo -pthread do_foo.c -o do_foo_ld
but this doesn't work: none of the ctor functions run and none of the libc functions get intercepted. When I run ldd do_foo_ld, I don't see libfoo.so in the list of libraries linked to it.
What gcc flags are equivalent to LD_PRELOAD? I assume t here is some simple translation between the two, but I haven't been able to find it.
EDIT: I've made some progress with the following:
gcc -Wall -Wextra -g3 -nodefaultlibs -pthread -L.. -lfoo -lc -lgcc do_foo.c -o do_foo_ld
My rationale is that I need to prevent loading libc at first with -nodefaultlibs, then link libfoo.so, then manually pull whatever gets taken out by nodefaultlibs in afterwards. With this, I don't get undefined reference errors about symbols from libc, but I do get the following:
/tmp/ccSsQHmx.o: In function `fun_1':
/my/proj/do_foo.c:217: undefined reference to `pthread_create'
/tmp/ccSsQHmx.o: In function `fun_2':
/my/proj/do_foo.c:269: undefined reference to `pthread_create'
/tmp/ccSsQHmx.o: In function `fun_3':
/my/proj/do_foo.c:281: undefined reference to `pthread_join'
No combination of -pthread -lpthread at various points in the gcc invocation seems to fix it, and I'm not sure why. I thought that nodefaultlibs might mean "prevent any of the default libraries from being linked" rather than just "don't link them yet," so I tried making a new symlink:
ln -s /lib/x86_64-linux-gnu/libpthread.so.0 ../libnotpthread.so
and adding the following:
gcc -Wall -Wextra -g3 -nodefaultlibs -pthread -L.. -lfoo -lnotpthread -lc -lgcc do_foo.c -o do_foo_ld
but no dice.
What am I missing here?
You should put linked libraries after source or object files:
gcc -Wall -Wextra -g3 do_foo.c -L.. -lfoo -pthread -o do_foo_ld
If this fails to work, try the big hammer:
gcc -Wall -Wextra -g3 do_foo.c -Wl,--no-as-needed -L.. -lfoo -Wl,--as-needed -pthread -o do_foo_ld
Modern distroes enable -Wl,--as-needed flag by default which forces -lfoo to be ignored if none of preceding source or object files uses it (in your case there are no files so it's considered to be unused).

Undefined reference to `initscr' Ncurses

I'm trying to compile my project and I use the lib ncurse. And I've got some errors when compiler links files.
Here is my flags line in Makefile:
-W -Wall -Werror -Wextra -lncurses
I've included ncurses.h
Some layouts :
prompt$> dpkg -S curses.h
libslang2-dev:amd64: /usr/include/slcurses.h
libncurses5-dev: /usr/include/ncurses.h
libncurses5-dev: /usr/include/curses.h
prompt$> dpkg -L libncurses5-dev | grep .so
/usr/lib/x86_64-linux-gnu/libncurses.so
/usr/lib/x86_64-linux-gnu/libcurses.so
/usr/lib/x86_64-linux-gnu/libmenu.so
/usr/lib/x86_64-linux-gnu/libform.so
/usr/lib/x86_64-linux-gnu/libpanel.s
And here are my erros :
gcc -W -Wall -Werror -Wextra -I./Includes/. -lncurses -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c
./Sources/NCurses/ncurses_init.o: In function `ncruses_destroy':
ncurses_init.c:(.text+0x5): undefined reference to `endwin'
./Sources/NCurses/ncurses_init.o: In function `ncurses_write_line':
ncurses_init.c:(.text+0xc5): undefined reference to `mvwprintw'
./Sources/NCurses/ncurses_init.o: In function `ncurses_init':
ncurses_init.c:(.text+0xee): undefined reference to `initscr'
collect2: error: ld returned 1 exit status
Thanks a lot
You need to change your makefile so that the -lncurses directive comes after your object code on the gcc command line, i.e. it needs to generate the command:
gcc -W -Wall -Werror -Wextra -I./Includes/. -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c -lncurses
This is because object files and libraries are linked in order in a single pass.
In C++ , I fixed it just by linking the ncurses library .
Here is the command :
g++ main.cpp -lncurses
I got flags to correct order by using LDLIBS variable:
ifndef PKG_CONFIG
PKG_CONFIG=pkg-config
endif
CFLAGS+=-std=c99 -pedantic -Wall
LDLIBS=$(shell $(PKG_CONFIG) --libs ncurses)
man gcc | grep -A10 "\-l library"
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX
compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files
in the order they are specified. Thus, foo.o -lz bar.o searches
library z after file foo.o but
before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

Linking Math Library in GCC 4.6.1 (Ubuntu 11.10)

I find a problem in the linking process of my application. I did not have the same with gcc 4.5. It tries to link math library with the following command.
gcc -Wall -Wno-unused -MD -o mems_seektest mems_seektest.o -lm -L. -g -DASSERTS -I../src// -I../ -I../src//src -DDEBUG -lmems_internals
and report following error massages:
undefined reference to `sqrt'
Any idea ?
recent gcc/ld uses the --as-needed linker flag as default. Practically, that means libraries have to be specified in the reverse order of dependencies on the command line. If the mems_internals library needs the sqrt function your -lm after -lmems_internals.
gcc -Wall -Wno-unused -MD -o mems_seektest mems_seektest.o -L. -g -DASSERTS -I../src// -I../ -I../src//src -DDEBUG -lmems_internals -lm
I've had the same problem with gcc 4.6.1, even with only one library. This doesn't work:
$ gcc -lm eg.o -o eg
eg.o: In function `foo':
/home/nick/tmp/eg.c:5: undefined reference to `sqrt'
collect2: ld returned 1 exit status
But this does:
$ gcc eg.o -o eg -lm
I hit this because I was using "LDFLAGS=-lm" in my Makefile. Works fine if you use "LDLIBS=-lm" instead.
You didn't tell us what -lmems_internals is, but maybe the unresolved symbol comes from there. The order of the -l options is generally important to the linker, you should always put system libraries last.
You can check where the unresolved symbol comes from by using something like
nm yourLibrary | grep sqrt
if there is a U in front of sqrt the symbol is undefined.
I'd say the linker is using the wrong libm.

Resources