26
votes

Why we need the presence of the shared library during the compile time of my executable? My reasoning is that since shared library is not included into my executable and is loaded during the runtime, it is not supposed to be needed during compile time. Or Am I missing something?

#include<stdio.h>
int addNumbers(int, int); //prototype should be enough, no? 
int main(int argc, char* argv[]){
  int sum = addNumbers(1,2);
  printf("sum is %d\n", sum);
  return 0;
}

I had the libfoo.so in my current dir but I changed its name to libfar.so to find that shared lib is needed at compile or it doesn't compile.

gcc -o main main.c -L. -lfoo gives main.c:(.text+0x28): undefiend reference to 'addNumber'

I think it should be enough to only have the name of the shared library. The shared library itself is not needed since it is found in the LD_LIBRARY_PATH and loaded dynamically at runtime. Is there something else needed other than the name of the shared lib?

2
Your gcc line is not only compiling but also linking.里纳尔迪
adding -undefined dynamic_lookup will tell the compiler to assume any undefined symbols will be resolved when dynamic linking happensC_Elegans
@Gab是好人 - With GCC, it's a bit involved actually... stackoverflow.com/questions/23485489/…StoryTeller - Unslander Monica
And come to think of it, I think the question I linked may be a duplicate to yours...StoryTeller - Unslander Monica
@C_Elegans I didn't find this option for gccGab是好人

2 Answers

16
votes

Nothing is needed at compile time, because C has a notion of separate compilation of translation units. But once all the different sources have been compiled, it is time to link everything together. The notion of shared library is not present in the standard but is it now a common thing, so here is how a common linker proceeds:

  • it looks in all compiled modules for identifiers with external linkage either defined or only declared
  • it looks in libraries (both static and dynamic) for identifiers already used and not defined. It then links the modules from static libraries, and stores references from dynamic libraries. But at least on Unix-likes, it needs to access the shared library for potential required (declared and not defined) identifiers in order to make sure they are already defined or can be found in other linked libraries be them static or dynamic

This produces the executable file. Then at load time, the dynamic loader knows all the dynamic modules that are required and loads them in memory (if they are not already there) along with the actual executable and builds a (virtual) memory map

0
votes
gcc -o main main.c -L. -lfoo

This command does (at least) two steps: compile main.c into an object file and link all resources into an executable main. The error you see is from the last step, the linker.

The linker is responsible for generating the final executable machine code. It requires the shared object library because it needs to generate the machine code which loads it and executes any functions used in it.