Search code examples
cgccmakefilegnu

How to tell where the symbols are defined when linking C code


I am facing an undefined reference issue with specific symbols in my linkage.

error: undefined reference to 'g_queue_pop_nth'

I am working on LOP & ARM platforms. We are using the same environment on both platforms. Our ARM build is linking without any issues. But on the LOP platform I am hitting the failure above. I want to check from which library that symbol is being defined on the ARM host. Are there any flags or parameters for GCC to get information about what library provides the definition of this symbol?


Solution

  • At linktime you may request the linker to tell you in which input file (object file, static library member or shared library) it finds the definition of any symbol and in which files it finds that symbol referred to, using the linker option -trace-symbol=name.

    For example:

    $ cat main.c
    extern void foo(void);
    
    int main(void)
    {
        foo();
        return 0;
    }
    
    $ cat foo.c
    #include <stdio.h>
    
    void foo(void)
    {
        fputs(__func__,stdout);
    }
    

    Compile the sources:

    $ gcc -Wall -c main.c foo.c
    

    Make a static library:

    $ ar rcs libfoo.a foo.o
    

    Link a program, requesting symbol traces for foo and fputs:

    $ gcc -o prog main.o -L. -lfoo -Wl,-trace-symbol=foo,-trace-symbol=fputs
    /usr/bin/ld: main.o: reference to foo
    /usr/bin/ld: ./libfoo.a(foo.o): definition of foo
    /usr/bin/ld: ./libfoo.a(foo.o): reference to fputs
    /usr/bin/ld: //lib/x86_64-linux-gnu/libc.so.6: definition of fputs
    

    So foo is defined in archive member foo.o of ./libfoo.a and fputs is defined in /lib/x86_64-linux-gnu/libc.so.6