can't understand linking behaviour
Consider:
main.c calls function firstcall()a.c defines function firstcall() which calls secondcall() b.c defines function secondcall()
To build the executable main, I need to do:
gcc -fPIC -c a.c
gcc -fPIC -shared -o liba.so a.o
gcc -fPIC -c b.c
gcc -fPIC -shared -o libb.so b.o
gcc -o main main.c -L. -la -lb
My question is, why does not the creation of liba.so require the presence of and linking against libb.so, seeing as a.o contains firstcall() which calls secondcall() present only in libb.so?
The gcc command building liba.so does not use -c which would prevent the linker from being called. So if the linker is called then it should require the presence of and linking to libb.so to resolve the reference to the external function secondcall(). But this does not happen.
What does happen is that I am supposed to specify at the point of building the *executable* not only the libraries that the executable depends on, but also the libraries that *those* libraries depend on, as well as, presumably, any third-level, fourth-level and upto n-th level dependencies.
This seems highly counter-intuitive. Why would the linker require *only* at *executable* build-time the libraries, and the whole dependency *tree* at that, to be specified? Why does it not need at each level of build of an executable or library its and only its own dependencies?
Thanks as always, in advance,
Shriramana Sharma.
Quoted 12 lines · Shriramana Sharma
main.ccalls functionfirstcall()a.cdefines functionfirstcall()which callssecondcall()b.cdefines functionsecondcall()To build the executable main, I need to do:
gcc -fPIC -c
a.c
gcc -fPIC -shared -o liba.so a.o
gcc -fPIC -cb.c
gcc -fPIC -shared -o libb.so b.o
gcc -o mainmain.c-L. -la -lb
Quoted 8 lines
My question is, why does not the creation of liba.so require the presence of and linking against libb.so, seeing as a.o contains
firstcall()which callssecondcall()present only in libb.so?The gcc command building liba.so does not use -c which would prevent the linker from being called. So if the linker is called then it should require the presence of and linking to libb.so to resolve the reference to the external function
secondcall(). But this does not happen.
Libraries can have undefined references. Sometimes this is necessary, e.g. if the library depends upon a function which is supposed to be provided by the executable.
Quoted 5 lines
What does happen is that I am supposed to specify at the point of building the *executable* not only the libraries that the executable depends on, but also the libraries that *those* libraries depend on, as well as, presumably, any third-level, fourth-level and upto n-th level dependencies.
Not if the libraries themselves have dependency information. E.g.:
gcc -fPIC -c b.c
gcc -fPIC -shared -o libb.so b.o
gcc -fPIC -c a.c
gcc -fPIC -shared -o liba.so a.o -L. -lb gcc -o main main.c -L. -Wl,-rpath-link,. -la
Quoted 2 lines
This seems highly counter-intuitive. Why would the linker require *only* at *executable* build-time the libraries,
You're looking it at the wrong way.
Why would the linker require all external symbols to be resolved at the time the library is built?
Quoted 1 line
and the whole dependency *tree* at that, to be specified?
Ultimately, any symbols which are required must be provided, so this is checked when the executable is built. There isn't any need to check it before then.
Quoted 2 lines
Why does it not need at each level of
build of an executable or library its and only its own dependencies?
Because there is no reason for such a requirement.
Signature · 1 line
Glynn Clements <[email protected]>
Quoted 3 lines · Glynn Clements
Libraries can have undefined references. Sometimes this is necessary, e.g. if the library depends upon a function which is supposed to be provided by the executable.
To my mind, in the real world, if a library must access a function that the executable provides, it will only be through a function pointer -- the library may provide, for e.g. a binary search facility, and the program uses this to carry out a binary search on a function in its body.
What real world application would make a library A to call a function foo() when foo() is defined in the body of an executable X that itself depends on A? If foo() were in a dependency of A, say library B, then it can be understood, but to expect the function to come from X is, although *theoretically* possible, how practically necessary?
Quoted 1 line
gcc -o main
main.c-L. -Wl,-rpath-link,. -la
On my system doing the same without the -Wl, command seems to produce the same effect. However the symbol is still marked undefined by nm, even if I have linked it.
Quoted 4 lines
Quoted 1 line
This seems highly counter-intuitive. Why would the linker require *only* at *executable* build-time the libraries,
Why would the linker require all external symbols to be resolved at the time the library is built?
If you prove that there is a valid real-life situation where the library needs a symbol from an application, then the linker would not require all external symbols to be resolved.
Shriramana Sharma.
Quoted 9 lines · Shriramana Sharma
Quoted 3 lines · Glynn Clements
Libraries can have undefined references. Sometimes this is necessary, e.g. if the library depends upon a function which is supposed to be provided by the executable.
To my mind, in the real world, if a library must access a function that the executable provides, it will only be through a function pointer -- the library may provide, for e.g. a binary search facility, and the program uses this to carry out a binary search on a function in its body.
Actually, that's what you do when you allow the function called by the library to have any name: you call it by a pointer. It is more flexible, but not necessarily the only way around.
Quoted 5 lines
What real world application would make a library A to call a function
foo()whenfoo()is defined in the body of an executable X that itself depends on A? Iffoo()were in a dependency of A, say library B, then it can be understood, but to expect the function to come from X is, although *theoretically* possible, how practically necessary?
I suppose it is just because it is more simple and flexible to implement it this way. Because for library A (and for the compiler and linker) it doesn't matter if foo() comes from executable X or library B. At compile time, those symbols are simply inserted in the table of defined symbols, so it doesn't matter where they come from (and C doesn't even have namespaces or something like that anyway; symbols are just global or local).
Quoted 9 lines
Quoted 5 lines
Quoted 2 lines
This seems highly counter-intuitive. Why would the linker require *only* at *executable* build-time the libraries,
Why would the linker require all external symbols to be resolved at the time the library is built?
If you prove that there is a valid real-life situation where the library needs a symbol from an application, then the linker would not require all external symbols to be resolved.
Here is an example of library using a symbol from the application: the external environ variable referenced in unistd.h is defined by the application. The exec* family of functions (excluding execle() I guess) use it internally only.
Cheers,
Pedro.
Signature · 6 lines
Pedro de Medeiros - Ciência da Computação - Universidade de Brasília Home Page: http://www.nonseq.net - Linux User No.: 234250 - To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html