Trevor Hickey
Trevor Hickey

Reputation: 37816

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.

Upvotes: 12

Views: 1613

Answers (4)

Mats Petersson
Mats Petersson

Reputation: 129344

There are some really good answers above. A further note would be "what difference does it really make". Already mentioned is the cost of maintenance (e.g. problems when someone installs a fresh operating system, which doesn't have Lib3, so the user has to go find lib3 somewhere and install it, and because lib3 also needs lib17 which you also isn't installed, it adds more work for the user).

But also, when you load the binary, if you have linked against shared libraries that aren't actually used, the system will still go look for those libraries, and refuse to load if they are not present - this adds time, and install nightmare.

Once the code is loaded, it should have no additional runtime penalty.

Having said that, there are sometimes arguments for linking against unused libraries. Say your code has an option USE_FOO, where the FOO feature is only included based on some arbitrary choice when building (e.g. "is this on Linux kernel > 3.0" or "Does the system have a fancy graphics card"), and FOO uses Lib1 to do it's business, it can make the build system (makefile or similar) a little simpler to always link against lib1, even if you don't actually need it when USE_FOO is not set.

But in general, don't link against libraries not needed. It causes more dependencies, and that's never a good thing.

Upvotes: 0

reechard
reechard

Reputation: 882

Absolutely yes. The downside is that others (or you in the future) will assume the libraries are needed for some reason. Most people will not take the time to pare down a program's dependencies, and so the list of them grows and grows.

The cost has nothing to do with the compiled code, but everything to do with maintaining and porting programs.

Upvotes: 0

manav m-n
manav m-n

Reputation: 11394

It depends whether you are linking static libraries or shared libraries. If you are linking static libraries then the executable size would increase with each addition. Linking to shared libraries, doesn't not increases executable size greatly, only library symbols are added.

Upvotes: 0

Dietrich Epp
Dietrich Epp

Reputation: 213318

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.

Upvotes: 16

Related Questions