Undefined reference to printf when using GCC cross compiler
It is necessary to build libraries to go with your cross compiler. In particular, you need to have a cross-compiled version of glibc or some other implementation of the standard library, to get a version of printf()
.
Have a look at this link for an example of the type of things you need to consider to get all the things you need - the cross-compiler, the headers, and libraries.
Related videos on Youtube
pwaring
Updated on June 04, 2021Comments
-
pwaring about 3 years
I'm trying to get the following simple 'Hello World' program to compile using a cross compiler (GCC 4.9.2) targeting
mips
:#include <stdio.h> int main() { int x = 5; printf("x = %d\n", x); }
The
x
variable is there to stop GCC changingprintf
toputs
, which it seems to do automatically for a simple newline-terminated string.I've built a cross compiler under
${HOME}/xc
and am executing it using the following command:${HOME}/xc/bin/mips-gcc -v hello.c
However, I'm getting the following error:
/tmp/ccW5mHJu.o: In function `main': (.text+0x24): undefined reference to `printf' collect2: error: ld returned 1 exit status
I'm assuming this is a problem with the linker, as I'd expect the process to fail earlier if for example
stdio.h
couldn't be found on the search path. I can compile a simpler program which simply returns zero, so it's not the case that the entire toolchain is broken, presumably just the standard library linking (I'm using newlib 2.2.0-1).I get the same error regardless of whether I run the cross compiler under Linux (Ubuntu 14.10) or Cygwin (Windows 8).
The full output from GCC is:
Using built-in specs. COLLECT_GCC=/home/paul/xc/bin/mips-gcc COLLECT_LTO_WRAPPER=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper Target: mips Configured with: /home/paul/xc/mips/tmp/gcc-4.9.2/configure --prefix=/home/paul/xc --target=mips --enable-languages=c --with-newlib --without-isl --without-cloogs --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap Thread model: single gcc version 4.9.2 (GCC) COLLECT_GCC_OPTIONS='-v' /home/paul/xc/libexec/gcc/mips/4.9.2/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -auxbase hello -version -o /tmp/ccCpAajQ.s GNU C (GCC) version 4.9.2 (mips) compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/sys-include" #include "..." search starts here: #include <...> search starts here: /home/paul/xc/lib/gcc/mips/4.9.2/include /home/paul/xc/lib/gcc/mips/4.9.2/include-fixed /home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/include End of search list. GNU C (GCC) version 4.9.2 (mips) compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: cffaaedf0b24662e67a5d97387fc5b17 COLLECT_GCC_OPTIONS='-v' /home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/as -EB -O1 -no-mdebug -mabi=32 -o /tmp/ccW5mHJu.o /tmp/ccCpAajQ.s COMPILER_PATH=/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/ LIBRARY_PATH=/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib/ COLLECT_GCC_OPTIONS='-v' /home/paul/xc/libexec/gcc/mips/4.9.2/collect2 -plugin /home/paul/xc/libexec/gcc/mips/4.9.2/liblto_plugin.so -plugin-opt=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper -plugin-opt=-fresolution=/tmp/cc8TAJb9.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -EB /home/paul/xc/lib/gcc/mips/4.9.2/crti.o /home/paul/xc/lib/gcc/mips/4.9.2/crtbegin.o -L/home/paul/xc/lib/gcc/mips/4.9.2 -L/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib /tmp/ccW5mHJu.o -lgcc -lgcc /home/paul/xc/lib/gcc/mips/4.9.2/crtend.o /home/paul/xc/lib/gcc/mips/4.9.2/crtn.o /home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400050 /tmp/ccW5mHJu.o: In function `main': (.text+0x24): undefined reference to `printf' collect2: error: ld returned 1 exit status
The build script I'm using is here (I wrote it based on half a dozen tutorials which all suggested slightly different things):
https://github.com/UoMCS/mips-cross-compile
Basically it does the following steps:
- Build binutils.
- Build GCC (stage 1).
- Build newlib.
- Build GCC (stage 2).
I'm aware that there are other tools such as crosstool-ng and builtroot, however the person I'm building this toolchain for wants to edit parts of binutils before setting off the build process, and the toolchain also has to work under Cygwin (crosstool-ng won't for various reasons, including case-sensitive file paths).
I think this is probably going to be something obvious, but I've been messing around with this for a week and can't see what it could be. Any help would be greatly appreciated!
-
M.M about 9 yearsTry dumping the list of symbols defined by newlib
-
pwaring about 9 yearsI have used the instructions in the link you mentioned, but I could never get glibc to compile, which is why I've switched to newlib (which has compiled successfully).
-
pwaring about 9 yearsI'm aware that
printf
is defined inlibc
, what I want to know is how to fix the linker error. 'Check your C lib' isn't terribly helpful. -
pwaring about 9 yearsThat won't work,
putchar
is part of the standard library so if there's a linker problem it will break onputchar
just as it will forprintf
. -
pwaring about 9 yearsThis is probably the closest answer to the eventual solution - I had to use glibc and play around with the various config options until I found ones which worked (
--disable-werror
was important). -
4566976 about 9 years@pwaring You're almost done.
${HOME}/xc/bin/mips-gcc hello.c -lc -lcfe -lc
should yield ana.out
. newlib should work. Just_start
is still missing for the argv and calling the main function. -
pwaring about 9 years@4566976 newlib doesn't work at all, GCC fails in the second stage with an error about not being able to find
crti.o
etc. -
4566976 about 9 years@pwaring strange, using your build script
crti.o
was created: see directory contents in the update of my answer. -
pwaring about 9 yearsThat's the glibc version of the build script.
crti.o
isn't created using the newlib version (there are two branches other than master).