Why symbols of a shared library are not resolved at link time?

13,468

Solution 1

Does adding -z defs when building the library do what you want? If not, check the ld man pages, there are quite a few options on the handling of undefined symbols.

Solution 2

Since you didn't give the -c (compile only) option, you requested gcc to compile the two source files and link them with the standard library (libc) and the c run-time startup (crt0, typically) to produce a running program. crt0 tries to enter your program by calling main(), which is the undefined symbol the linker can't find. It can't find it because you don't have a main() in either of your .c files, right?

So, on to your actual question, "Why symbols of a shared library are not resolved at link time?" The answer is, what do you mean by "link time?" By defintion, a dynamically linked program isn't "linked" until it starts (or maybe not even then, depending on your system.)

On a Linux system, you can see which dynamic libraries a program depends on with the ldd command (on Mac OS use 'otool -L'). The output of ldd will tell you which dynamic libraries a program depends on, which where found in the library search path, and which ones cannot be found (if any).

When you dynamic program starts, the dynamic linker that was linked into it locates and loads the dynamic libraries the program depends on, and "fixes" the references to the external symbols. If any of these fail, your program will fail to start. One all of the formerly unresolved symbols have been resolved, the dynamic linker returns and the C runtime will call your main() function. (It's somewhat different on Mac OS, but similar in effect, the linking happens after your program is started.)

Solution 3

I think the linker option -Bsymbolic is what you're looking for.

Share:
13,468

Related videos on Youtube

xyz
Author by

xyz

Updated on April 26, 2022

Comments

  • xyz
    xyz about 2 years

    This is my 2nd post on this site in my effort to understand the compilation/linking process with gcc. When I try to make an executable, symbols need to be resolved at link time, but when I try to make a shared library, symbols are not resolved at link time of this library. They will perhaps be resolved when I am trying to make an executable using this shared library. Hands-on:

    bash$ cat printhello.c
    #include <stdio.h>
    //#include "look.h"
    
    void PrintHello()
    {
    look();
    printf("Hello World\n");
    }
    
    bash$ cat printbye.c
    #include <stdio.h>
    //#include "look.h"
    
    void PrintBye()
    {
    look();
    printf("Bye bye\n");
    }
    
    bash$  cat look.h
    void look();
    
    bash$ cat look.c
    #include <stdio.h>
    
    void look()
    {
    printf("Looking\n");
    }
    
    bash$ gcc printhello.c printbye.c
    /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o: In function `_start':
    (.text+0x18): undefined reference to `main'
    /tmp/cck21S0u.o: In function `PrintHello':
    printhello.c:(.text+0x7): undefined reference to `look'
    /tmp/ccNWbCnd.o: In function `PrintBye':
    printbye.c:(.text+0x7): undefined reference to `look'
    collect2: ld returned 1 exit status
    
    bash$ gcc -Wall -shared -o libgreet printhello.c printbye.c
    printhello.c: In function 'PrintHello':
    printhello.c:6: warning: implicit declaration of function 'look'
    printbye.c: In function 'PrintBye':
    printbye.c:5: warning: implicit declaration of function 'look'
    

    So my question is why are symbols not resolved when I am linking a shared library. This work(Resolving symbols of its downstream) will need to be done when I will use this library to make an executable, but that means we need to know what this library depends on when using this library, but isn't it not undesirable?

    Thanks, Jagrati