Apart from a longer compile time, is there any downside to linking against an unused library?
for example, is there any difference in the executable of a program that is compiled one of two ways:
g++ -o main main.cpp
g++ -o main main.cpp -llib1 -llib2 -llib3 -lmore
*no library files were actually needed to build main.
I believe it makes no difference because the file sizes are the same, but I'm asking for confirmation.
If you statically link many libraries in you'll end up with a much bigger executable. So the executable can easily exceed the size of the source code, but the individual object files (pre-linking) that go with the code just compiled may be smaller.
Static linking increases the file size of your program, and it may increase the code size in memory if other applications, or other copies of your application, are running on the system. This option forces the linker to place the library procedures your program references into the program's object file.
If the library is linked statically into the program, that means that when the program is built, the result is an executable file that includes both the result of compiling program's source code (the main function and any other function in the program), and the functions from the library such as printf (which the ...
The libraries are physically loaded into the computer's memory instead and during the linking stage of compilation, only the address in the memory of the library function is added in the final executable file. The physical code itself is located at that address.
It depends.
If liblib1.a
, liblib2.a
, and liblib3.a
are static libraries, and no symbols are used from them, then there will be no difference.
If liblib1.so
, liblib2.so
, or liblib3.so
are shared libraries, then they will be loaded at runtime whether or not they are used. You can use the linker flag --as-needed
to change this behavior, and this flag is recommended.
To check which shared libraries your binary directly loads at runtime, on an ELF system you can use readelf
.
$ cat main.c int main() { return 0; } $ gcc main.c $ readelf -d a.out | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] $ gcc -lpng main.c $ readelf -d a.out | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libpng12.so.0] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
You can see that on my system, -lpng
links against libpng12.so.0
, whether or not symbols from it are actually used. The --as-needed
linker flag fixes this:
$ gcc -Wl,--as-needed -lpng main.c $ readelf -d a.out | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
The --as-needed
flag must be specified before the libraries. It only affects libraries which appear after it. So gcc -lpng -Wl,--as-needed
doesn't work.
The ldd
command lists not only the libraries your binary directly links against, but also all the indirect dependencies. This can change depending on how those libraries were compiled. Only readelf
will show you your direct dependencies, and only ldd
will show you indirect dependencies.
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