Reputation: 4853
I am working with the ARM-gcc cross compiler and am having issues linking to any implementation within libc
.
Compiling prog.c, writing to prog.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c prog.c -o prog.o > prog.lst
Compiling ../common/sysinit.c, writing to sysinit.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c ../common/sysinit.c -o sysinit.o > sysinit.lst
Assembling ../common/crt0.s, writing to crt0.o...
~/.programs/arm-gcc/bin/arm-none-eabi-as -mcpu=cortex-m4 -o crt0.o ../common/crt0.s > crt0.lst
Compiling uart.c, writing to uart.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c uart.c -o uart.o > uart.lst
~/.programs/arm-gcc/bin/arm-none-eabi-ld prog.o sysinit.o crt0.o uart.o -Map=prog.map -T../common/Teensy31_flash.ld -L~/.programs/arm-gcc/arm-none-eabi/lib -o prog.elf
prog.o: In function `print_char':
/home/user/workspace/prog/src/prog.c:47: undefined reference to `sprintf'
/home/user/workspace/prog/src/prog.c:48: undefined reference to `printf'
/home/user/workspace/prog/src/prog.c:49: undefined reference to `strlen'
prog.o: In function `main':
/home/user/workspace/prog/src/prog.c:72: undefined reference to `memset'
make: *** [makefile:133: prog.elf] Error 1
I threw in a few calls to stdlib to make the point. I have tried to explicitly link against libc using -lc
but am met with:
/home/prog/.programs/arm-gcc/bin/arm-none-eabi-ld: cannot find -lc
The archive directory is passed to the linker via:
L~/.programs/arm-gcc/arm-none-eabi/lib
I have checked the contents of this directory and verified the archive to be present:
$ ls ~/.programs/arm-gcc/arm-none-eabi/lib
aprofile-validation.specs libc_s.a linux.specs
aprofile-ve.specs libg.a nano.specs
armv6-m libgloss-linux.a nosys.specs
armv7-ar libg_s.a pid.specs
armv7e-m libm.a rdimon-crt0.o
armv7-m libnosys.a rdimon.specs
cpu-init librdimon.a rdpmon-crt0.o
crt0.o librdimon_s.a rdpmon.specs
fpu librdpmon.a redboot-crt0.o
iq80310.specs libstdc++.a redboot.ld
ldscripts libstdc++.a-gdb.py redboot.specs
libarm_cortexM0l_math.a libstdc++_s.a redboot-syscalls.o
libarm_cortexM4lf_math.a libsupc++.a thumb
libarm_cortexM4l_math.a libsupc++_s.a
libc.a linux-crt0.o
And, finally, the libc does export sprintf
(and others)
$ nm libc.a | grep "sprintf"
...
lib_a-sprintf.o:
00000000 T sprintf
00000000 T _sprintf_r
U sprintf
U _sprintf_r
...
Info on the ARM-GCC build I am using:
$ ./arm-none-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/home/user/.programs/arm-gcc/bin/../lib/gcc/arm-none-eabi/5.4.1/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/work/GCC-5-0-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-5-0-build/install-native --libexecdir=/home/build/work/GCC-5-0-build/install-native/lib --infodir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-5-0-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-isl=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r,armv8-m.base,armv8-m.main
Thread model: single
gcc version 5.4.1 20160609 (release) [ARM/embedded-5-branch revision 237715] (GNU Tools for ARM Embedded Processors)
Upvotes: 1
Views: 1683
Reputation: 3464
The ~
in -L~/.programs/arm-gcc/arm-none-eabi/lib
doesn't get expanded. It is the shell that expands ~
into /home/user
, but only when it is at the beginning of a word.
Actually, it isn't necessary to add this -L
option, because this is already in gcc's default search path. However, you link directly with ld
instead of with gcc
. That is not a good idea. It is better to link with gcc
and allow it to add the default search paths and other required libraries, like libc
and libgcc
. Since you supply your own crt0, add -nostartfiles
to the arguments. So link with:
~/.programs/arm-gcc/bin/arm-none-eabi-gcc prog.o sysinit.o crt0.o uart.o \
-Wl,-Map=prog.map -Wl,-T../common/Teensy31_flash.ld -nostartfiles -o prog.elf
Upvotes: 1