12

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.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271

4 Answers4

16

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.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • Thanks for --as-needed! Never seen before. But on the other hand this cries for a warning: "Link unused library". – Klaus Dec 21 '12 at 12:29
  • 1
    @Klaus: I'm not so sure. It's normally quite harmless to link against unneeded libraries, *sometimes* you need to link against unused libraries, and it's an enormous amount of work to remove unused libraries from the command line. Think about whether you have to use `-lm`, `-lrt`, or `-lpthread` depending on platform, and look at the output of (for example) `pkg-config --libs gtkglext-1.0` (on my system, it spits out 25 libraries and 2 other linker flags). – Dietrich Epp Dec 21 '12 at 17:18
0

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.

manav m-n
  • 11,136
  • 23
  • 74
  • 97
0

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.

reechard
  • 861
  • 6
  • 22
0

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.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227