Consider we have the following situation:
program
which depends dynamically on libfoo.so
libfoo.so
that depends on nothing (well, it depends on libstdc++
and stuff but I guess we can omit that)program
runs perfectly.
Suddenly, libfoo
codes changes, and some function now uses internally func_bar()
a function that is provided by another library libbar.so
.
libfoo.so
is recompiled and now depends on libbar.so
. program
remains unchanged, it still depends only on libfoo.so
.
Now when I execute program
it complains that he can't find func_bar()
.
Here are my questions:
libfoo.so
interface didn't change, only its implementation. Why does program
have to explicitely link with libbar.so
?libfoo.so
depends on libbar.so
, libbar.so
would have been automatically added to the dependency list of program
, without recompilation. However, ldd program
shows that it is not the case.It seems weird that one has to recompile (relink) every binary that depends on some library everytime that library's dependencies change. What solutions do I have here to prevent this ?
Dynamic linking is a two-step process that relies on accessing the addresses of code. The first step occurs at compilation. When a file is compiled with a dynamic library, instead of copying the actual object code contained in the library, the linker simply scans the code contained and checks for missing symbols.
Dynamic linking is the most common method, especially on Linux systems. Dynamic linking keeps libraries modular, so just one library can be shared between any number of applications. Modularity also allows a shared library to be updated independently of the applications that rely upon it.
In the dynamic linking approach, the linker does not copy the routines into the executables. It takes note that the program has a dependency on the library. When the program actually executes, the linker binds the function calls in the program to the shared library present in the disk.
In computing, a dynamic linker is the part of an operating system that loads and links the shared libraries needed by an executable when it is executed (at "run time"), by copying the content of libraries from persistent storage to RAM, filling jump tables and relocating pointers.
The problem arises when you have not linked libfoo.so
against libbar
. When you are compiling an executable, by default the linker will not let you leave undefined references. However, when you're compiling a shared library, it will - and it will expect them to be satisfied at link time. This is so that libfoo
can use functions exported by program
itself - when you try to run it, the dynamic linker is expecting func_bar()
to be supplied by program
. The problem is illustrated like so:
(foo.c
is selfcontained)
export LD_RUN_PATH=`pwd` gcc -Wall -shared foo.c -o libfoo.so gcc -Wall -L. p.c -lfoo -o p
At this point, ./p
runs correctly, as you would expect. We then create libbar.so
and modify foo.c
to use it:
gcc -Wall -shared bar.c -o libbar.so gcc -Wall -shared foo.c -o libfoo.so
At this point, ./p
gives the error you describe. If we check ldd libfoo.so
, we notice that it does not have a dependency on libbar.so
- this is the error. To correct the error, we must link libfoo.so
correctly:
gcc -Wall -L. -lbar -shared foo.c -o libfoo.so
At this point, ./p
again runs correctly, and ldd libfoo.so
shows a dependency on libbar.so
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With