why do we need the shared library during compile time
Asked Answered
T

2

43

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?

Thermodynamic answered 13/2, 2018 at 16:7 Comment(12)
Your gcc line is not only compiling but also linking.Overbearing
You're also having the compiler perform the linking step. Try gcc -c -o main.o main.c.Explain
@水飲み鳥 isn't link done at load time?Suppository
adding -undefined dynamic_lookup will tell the compiler to assume any undefined symbols will be resolved when dynamic linking happensFetter
@Thermodynamic - With GCC, it's a bit involved actually... #23485989Letitialetizia
And come to think of it, I think the question I linked may be a duplicate to yours...Letitialetizia
@Fetter I didn't find this option for gccSuppository
@StoryTeller Is it? The question in link is about delay loading on Linux, not how gcc uses -l options.Insult
@Insult - Reading this I gathered the OP wanted to know why it doesn't work as she'd expect for "loading at run-time". You'd notice I didn't vote to close it, given the margin of error in my assessment. Left it to he OP to decide.Letitialetizia
If you write code using dlopen, dlsym, etc, then you don't need the library until you run it. But when you use the linker, it looks up things like symbol versions and the real library name. I.E. you link to libfoo but then the linker really links you to libfoo.so.4Mcgee
@Thermodynamic It is not an option of the binutils linker ld. It is supported by ld on macOS. See manpagez.com/man/1/ldSelena
Coming from a Windows background, I know that it's possible to link against an import library and not have access to the actual DLL at compile time (of course the DLL is eventually needed at run-time, but only the .lib import library is needed for linking). Furthermore, there's a way to access the functions of the DLL without using an import library at all (LoadLibrary, GetProcAddress) so I find this question very relevant. I would hope that answers will address this aspect of it too.Narghile
M
19

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

Minnie answered 13/2, 2018 at 16:20 Comment(2)
So, it is mostly to record the name and version of required shared libraries in the executable.Nikolaos
I think this answer is confusing. The OP muddled compile time for link time, but his question is one that any Windows programmer might be wondering (as on Windows you might link a static library when using a dynamic library, but you'd never link the dynamic library itself). You could improve it by focusing on the information you've provided about the reasons dynamic libraries are linked by common Linux linkers, rather than focusing on the difference between compilation and linking, which is well covered elsewhere. As it is the second bullet point assumes the knowledge that the OP is afterInamorata
P
-1
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.

Provincial answered 13/2, 2018 at 16:12 Comment(8)
Isn't the declaration of the function enough for the linker? At linking time by ld, does ld really need the definition of the function in the shared lib?Suppository
@Thermodynamic Yes, in order to link the executable, the linker needs the definition of the function to be available.Provincial
Why? we have the dynamic linking at load time. What is the information in the definition of the functions that is needed by the linker, or what the linker ld needs to know in the definition of the function ?Suppository
@Thermodynamic The executable needs to know the address of the function within the shared object file in order to generate the correct function call.Provincial
Really? why the runtime linker can't do that?Nikolaos
@Nikolaos I'm not sure what you mean by "run time linker". Linking happens at build time.Provincial
@Provincial The shared object are loaded and linked against at run-time. The executable stores the name of the shared library and the path of the dynamic-linker inside it. The dynamic linker (usually ld.so) loads the shared library and finds the address of the symbol. So, IMO, the actual linking with shared objects occur at execution time. But as pointed in the above answer, a verification happens at build time and the names of the shared library is recorded in the executable.Nikolaos
@sanjivgupta. Wanted to add, in addition to recording shared library names, additional relocation information of shared symbols, like default values present in other libraries are also added, which needs to be initialized as soon as the dynamic object file is loaded. more info - eli.thegreenplace.net/2011/08/25/…Kos

© 2022 - 2024 — McMap. All rights reserved.