I have a make file for a program that links to libdl.so with the following line -ldl. There are no calls to dlopen or any of the related functions. What is the effect of linking to this library in this way even though you do not use any of the functions?
问题:
回答1:
You'll have to read the documentation for your linker. From info ld
on my Linux/ELF/GNU Binutils system (emphasis added):
`--as-needed' `--no-as-needed' This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the `--as-needed' option. Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not. `--as-needed' causes a DT_NEEDED tag to only be emitted for a library that satisfies an undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries linked up to that point, an undefined symbol reference from another dynamic library. `--no-as-needed' restores the default behaviour.
You can check yourself by running ldd
on a test program. On a simple test program, I get:
linux-vdso.so.1 => (0x00007fffd8305000)
libc.so.6 => /lib/libc.so.6 (0x00007f646c669000)
/lib/ld-linux-x86-64.so.2 (0x00007f646c9ca000)
However, if I link with -ldl
, I get this:
linux-vdso.so.1 => (0x00007fff644f1000)
libdl.so.2 => /lib/libdl.so.2 (0x00007fb9b1375000)
libc.so.6 => /lib/libc.so.6 (0x00007fb9b1014000)
/lib/ld-linux-x86-64.so.2 (0x00007fb9b1579000)
Even though libdl
isn't used by my program. However, if I run GCC with -Wl,--as-needed
, libdl
will not be linked in. According to my tests, this only works if -Wl,--as-needed
is listed on the command line before -ldl
.
What are the effects? It means that your binary won't run on systems without the shared library, even though you don't use it. It also means that your binary will break if you upgrade the shared library and uninstall the old one. It's not a big deal because binary compatibility is a bear anyway, but I see no reason not to turn on -Wl,--as-needed
for projects in general.
回答2:
I have coded a small application which uses nothing but STL. It has 8275 bytes of size without linking to any specific libraries:
linux-gate.so.1 => (0x00e1e000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x0015a000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x0044b000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00741000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00250000)
/lib/ld-linux.so.2 (0x00a75000)
Now, when I compile it and link it with boost_thread, it grows to 8290 bytes:
linux-gate.so.1 => (0x009d9000)
libboost_thread.so.1.40.0 => /usr/lib/libboost_thread.so.1.40.0 (0x00e59000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x003a3000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00bc5000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00f8a000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00bf0000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x00dd8000)
/lib/ld-linux.so.2 (0x00ba3000)
Note that there is no function call on my code to features of boost_thread. However, boost_thread is added anyway as a dependency of my application (as you can see on the output of ldd).
回答3:
Linking to a shared library is different than linking a static library. The main differences were explained already by @Dietrich Epp, but there's another important detail. Shared libraries define functions void _init()
and void _fini(void)
which are called upon loading/unloading a shared library; if you don't define them yourself the linker will add default stubs.
Those will be called also if you link your program against a shared library, but don't reference any symbol from the library (and don't add --as-needed linker flag).
回答4:
Most linkers will simply omit the unused objects from the final binary, exactly as if you hadn't linked with the library in the first place.