Undefined reference to printf when using GCC cross compiler

40,673

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.

Share:
40,673

Related videos on Youtube

pwaring
Author by

pwaring

Updated on June 04, 2021

Comments

  • pwaring
    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 changing printf to puts, 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:

    1. Build binutils.
    2. Build GCC (stage 1).
    3. Build newlib.
    4. 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
      M.M about 9 years
      Try dumping the list of symbols defined by newlib
  • pwaring
    pwaring about 9 years
    I 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
    pwaring about 9 years
    I'm aware that printf is defined in libc, what I want to know is how to fix the linker error. 'Check your C lib' isn't terribly helpful.
  • pwaring
    pwaring about 9 years
    That won't work, putchar is part of the standard library so if there's a linker problem it will break on putchar just as it will for printf.
  • pwaring
    pwaring about 9 years
    This 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
    4566976 about 9 years
    @pwaring You're almost done. ${HOME}/xc/bin/mips-gcc hello.c -lc -lcfe -lc should yield an a.out. newlib should work. Just _start is still missing for the argv and calling the main function.
  • pwaring
    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
    4566976 about 9 years
    @pwaring strange, using your build script crti.o was created: see directory contents in the update of my answer.
  • pwaring
    pwaring about 9 years
    That's the glibc version of the build script. crti.o isn't created using the newlib version (there are two branches other than master).

Related