Get List of Static Libraries Used in an Executable

Get list of static libraries used in an executable

ldd <exe filename> shows dynamically linked libraries

nm <exe filename> shows the symbols in the file.

To see which symbols come from static libraries requires running nm against those libraries to get a list of the symbols (functions, etc.) in them, then comparing them to what your list of symbols from nm <exe filename>.

You compare lists with the comm command. See man comm for details.

This was taken from this forum here.

How to list dependencies of c/c++ static library?

A static library have no such list of dependencies.

A static library is nothing more than an archive of object files. And as object files doesn't know what libraries they depend on, neither can a static library.

Do all functions from a static library get linked into the final executable?

Traditionally, when you link with a static library, each object file in the library that satisfies a currently unsatisfied reference will be included in the executable. Any references from the selected object files within the library will also be picked up, repeating until there are no more object files that can satisfy any unsatisfied references. The linking process then moves on to the next library in the list.

If there are still unresolved reference when it reaches the end of the last library, the linker generates error messages about undefined external references.

How to show all shared libraries used by executables in Linux?

  1. Use ldd to list shared libraries for each executable.
  2. Cleanup the output
  3. Sort, compute counts, sort by count

To find the answer for all executables in the "/bin" directory:

find /bin -type f -perm /a+x -exec ldd {} \; \
| grep so \
| sed -e '/^[^\t]/ d' \
| sed -e 's/\t//' \
| sed -e 's/.*=..//' \
| sed -e 's/ (0.*)//' \
| sort \
| uniq -c \
| sort -n

Change "/bin" above to "/" to search all directories.

Output (for just the /bin directory) will look something like this:

  1 /lib64/libexpat.so.0
1 /lib64/libgcc_s.so.1
1 /lib64/libnsl.so.1
1 /lib64/libpcre.so.0
1 /lib64/libproc-3.2.7.so
1 /usr/lib64/libbeecrypt.so.6
1 /usr/lib64/libbz2.so.1
1 /usr/lib64/libelf.so.1
1 /usr/lib64/libpopt.so.0
1 /usr/lib64/librpm-4.4.so
1 /usr/lib64/librpmdb-4.4.so
1 /usr/lib64/librpmio-4.4.so
1 /usr/lib64/libsqlite3.so.0
1 /usr/lib64/libstdc++.so.6
1 /usr/lib64/libz.so.1
2 /lib64/libasound.so.2
2 /lib64/libblkid.so.1
2 /lib64/libdevmapper.so.1.02
2 /lib64/libpam_misc.so.0
2 /lib64/libpam.so.0
2 /lib64/libuuid.so.1
3 /lib64/libaudit.so.0
3 /lib64/libcrypt.so.1
3 /lib64/libdbus-1.so.3
4 /lib64/libresolv.so.2
4 /lib64/libtermcap.so.2
5 /lib64/libacl.so.1
5 /lib64/libattr.so.1
5 /lib64/libcap.so.1
6 /lib64/librt.so.1
7 /lib64/libm.so.6
9 /lib64/libpthread.so.0
13 /lib64/libselinux.so.1
13 /lib64/libsepol.so.1
22 /lib64/libdl.so.2
83 /lib64/ld-linux-x86-64.so.2
83 /lib64/libc.so.6

Edit - Removed "grep -P"

GCC: list a statically linked libraries

An executable stores no trace of any static libraries it pulled object files from. Mostly these libraries are explicitly specified when linking, though. The compiler only pulls in a few standard static libraries. For gcc you can see various information including the actual command line passed to the linker using the -v option (it seems some implementations want to use --verbose and for the linker -Wl,--verbose). This output should show all implicitly linked libraries like -lgcc and -lstdc++.

Note that you should link using the language specific frontend and the same compiler flags as when compiling. Your problem description sounds as if you use -pthread with g++ when compiling but you tried to link using gcc without the -pthread flags (there are a few different threading related flags; from the description it is impossible to tell which one was used).

Just to deal with the insults, here is an example output when using the -v option on my computer:

ThreadGard:stackoverflow kuehl$ cat hello.cpp 
#include <iostream>

int main()
{
std::cout << "hello, world\n";
return 0;
}
ThreadGard:stackoverflow kuehl$ g++ -v -static hello.cpp
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/gcc-4.9.2/libexec/gcc/x86_64-apple-darwin13.4.0/4.9.2/lto-wrapper
Target: x86_64-apple-darwin13.4.0
Configured with: ../gcc-4.9.2/configure --prefix=/opt/gcc-4.9.2 --with-gmp=/opt/gcc-infrastructure --with-mpfr=/opt/gcc-infrastructure --enable-decimal-float=bid --enable-lto --enable-languages=c,c++
Thread model: posix
gcc version 4.9.2 (GCC)
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.4' '-v' '-static' '-mtune=core2'
/opt/gcc-4.9.2/libexec/gcc/x86_64-apple-darwin13.4.0/4.9.2/cc1plus -quiet -v -D__STATIC__ hello.cpp -quiet -dumpbase hello.cpp -mmacosx-version-min=10.9.4 -mtune=core2 -auxbase hello -version -o /var/folders/b_/64plfvs936v5ylx36qwc8rg00000gp/T//ccrt7fXS.s
GNU C++ (GCC) version 4.9.2 (x86_64-apple-darwin13.4.0)
compiled by GNU C version 4.9.2, GMP version 5.0.5, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../../x86_64-apple-darwin13.4.0/include"
#include "..." search starts here:
#include <...> search starts here:
/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../../include/c++/4.9.2
/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../../include/c++/4.9.2/x86_64-apple-darwin13.4.0
/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../../include/c++/4.9.2/backward
/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/include
/usr/local/include
/opt/gcc-4.9.2/include
/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/include-fixed
/usr/include
/System/Library/Frameworks
/Library/Frameworks
End of search list.
GNU C++ (GCC) version 4.9.2 (x86_64-apple-darwin13.4.0)
compiled by GNU C version 4.9.2, GMP version 5.0.5, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: fea0def5b69cf8ae349b2f1faf4b1d23
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.4' '-v' '-static' '-mtune=core2'
as -arch x86_64 -force_cpusubtype_ALL -static -o /var/folders/b_/64plfvs936v5ylx36qwc8rg00000gp/T//ccPF77oR.o /var/folders/b_/64plfvs936v5ylx36qwc8rg00000gp/T//ccrt7fXS.s
COMPILER_PATH=/opt/gcc-4.9.2/libexec/gcc/x86_64-apple-darwin13.4.0/4.9.2/:/opt/gcc-4.9.2/libexec/gcc/x86_64-apple-darwin13.4.0/4.9.2/:/opt/gcc-4.9.2/libexec/gcc/x86_64-apple-darwin13.4.0/:/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/:/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/
LIBRARY_PATH=/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/:/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../:/usr/lib/
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.4' '-v' '-static' '-mtune=core2'
/opt/gcc-4.9.2/libexec/gcc/x86_64-apple-darwin13.4.0/4.9.2/collect2 -static -arch x86_64 -macosx_version_min 10.9.4 -weak_reference_mismatches non-weak -o a.out -lcrt0.o -L/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2 -L/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../.. /var/folders/b_/64plfvs936v5ylx36qwc8rg00000gp/T//ccPF77oR.o /opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../libstdc++.a -no_compact_unwind -no_pie -lgcc_eh -lgcc -v
collect2 version 4.9.2
/usr/bin/ld -static -arch x86_64 -macosx_version_min 10.9.4 -weak_reference_mismatches non-weak -o a.out -lcrt0.o -L/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2 -L/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../.. /var/folders/b_/64plfvs936v5ylx36qwc8rg00000gp/T//ccPF77oR.o /opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../libstdc++.a -no_compact_unwind -no_pie -lgcc_eh -lgcc -v
@(#)PROGRAM:ld PROJECT:ld64-241.9
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7m armv7em
Library search paths:
/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2
/opt/gcc-4.9.2/lib
/usr/lib
/usr/local/lib
Framework search paths:
/Library/Frameworks/
/System/Library/Frameworks/
ld: library not found for -lcrt0.o
collect2: error: ld returned 1 exit status

There are not all static libraries installed to make it actually link. However, that's besides the point as the output clearly lists the linker invocation:

/usr/bin/ld -static -arch x86_64 -macosx_version_min 10.9.4 -weak_reference_mismatches non-weak -o a.out -lcrt0.o -L/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2 -L/opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../.. /var/folders/b_/64plfvs936v5ylx36qwc8rg00000gp/T//ccPF77oR.o /opt/gcc-4.9.2/lib/gcc/x86_64-apple-darwin13.4.0/4.9.2/../../../libstdc++.a -no_compact_unwind -no_pie -lgcc_eh -lgcc -v

(with some emphasis added to make it easier for readers - it seems to be necessary)

Can I get a report of ALL the libraries linked when building my C++ executable (gcc)? (including statically linked)

I had similar problem and found solution: add -Wl,--verbose option when linking. It will switch linker to verbose mode:

gcc -o test main.o -ltest -L. -Wl,--verbose

Here is example output:

GNU ld (GNU Binutils) 2.23.52.20130604
Supported emulations:
i386pep
i386pe
using internal linker script:
==================================================
/* Default linker script, for normal executables */
[many lines here]
==================================================
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o
attempt to open main.o succeeded
main.o
attempt to open ./libtest.dll.a failed
attempt to open ./test.dll.a failed
attempt to open ./libtest.a succeeded
(./libtest.a)test.o
[more lines here]
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o

Update: You can also use -Wl,--trace option instead of -Wl,--verbose. It will also give you list of libraries, but is less verbose.

Update 2: -Wl,--trace does not display libraries included indirectly. Example: you link with libA, and libA was linked with libB. If you want to see that libB is needed too, you must use -Wl,--verbose.

How to check the static library dependencies in Windows?

MSVC at least has a mechanism for implicit dependencies, done through the #pragma comment(lib, ...) directive. Check the headers for the static library and make sure that there is no such.

Also, if using a static library provided through 'vcpkg' and you have done "vcpkg integrate install" an MSBuild file is added to the project build system that automatically imports everything that vcpkg generates.

Also, link.exe has a /VERBOSE:LIB option that will print out the libraries that are searched, though it won't tell you why that particular library was added to the build.

Determining which static libraries are linked unnecessarily

Building on top of the information provided by @ThomasMatthews in a comment to the question:

Run the linker with the -M option and pipe its output to the following script:

get_used_libs

#!/bin/bash

sed -e '/^Discarded input sections$/,$ d' \
-e '/^Archive member included to satisfy reference by file (symbol)$/ d' \
-e '/^As-needed library included to satisfy reference by file (symbol)$/ d' \
-e '/^Discarded input sections$/ d' \
-e '/^$/ d; /^\s/ d; s/\s\+.\+//; s/(.\+//' \
| sort -u

It will return the list of the libraries that were necessary for your program to link.

Disclaimer: The script was only tested on output from GNU ld (GNU Binutils for Ubuntu) 2.25.1 on a toy program.



Related Topics



Leave a reply



Submit