Search code examples
c++shared-librarieslddbuild-dependencies

Script to Quickly Determine What Source Code Causes Unnecessary .so's to link


Context: I have a program which transfers an executable over a network. This executable is way too large, so I ran ldd -u bigFoo.so on its associated shared object. This revealed that I had a large number of unused shared object files which were occupying over a gig.

Question: Given a piece of C++ source code foo.cc which is compiled and linked into bigFoo.so, and unused.so (revealed by ldd -u) which is linked into bigFoo.so, is there a script or sequence of shell commands which can quickly determine what calls in foo.cc cause linkage of unused.so?


Solution

  • Recompile after adding the option -Wl,-M to your CXXFLAGS. Search for 'Archive member included...', The following lines will show what libraries where included in the file, and what functions requested them.

    An example:

    gcc -std=gnu99  -O0 -Wall -Wextra -Wunused -Wl,-M -c showmmap.c -o showmmap.o
    gcc -std=gnu99  -O0 -Wall -Wextra -Wunused -Wl,-M    showmmap.o -o showmmap
    Archive member included to satisfy reference by file (symbol)
    
    /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
                                  /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o (__libc_csu_init)
    /usr/lib/x86_64-linux-gnu/libc_nonshared.a(fstat.oS)
                                  showmmap.o (fstat)
    
    Discarded input sections
    --------8<--snip--->8-----
    

    I had to dig around in my archives to find something that pulled in other libraries. In this example, you can see that __libc_csu_init and fstat are functions which requested other archive members to be included.

    The output of the -Wl,-M option is rather... voluminous, be sure to pipe the output to a file or through less

    What I've shown here is but a teeny snippet from the very head of the output. Your output should be longer, considering you likely have many library routines included.