Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is an executable built differently if linked against a library that's not used?

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.

like image 933
Trevor Hickey Avatar asked Dec 21 '12 04:12

Trevor Hickey


People also ask

Does linking affect size of executable?

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.

What happens when you link a static library?

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.

Is a library an executable program?

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 ...

How does linking libraries work?

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.


1 Answers

It depends.

  1. If liblib1.a, liblib2.a, and liblib3.a are static libraries, and no symbols are used from them, then there will be no difference.

  2. 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]

Notes

  1. 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.

  2. 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.

like image 185
Dietrich Epp Avatar answered Sep 28 '22 07:09

Dietrich Epp