How to list all externally-undefined symbols of a static library on Linux?
Asked Answered
E

2

12

I have a static library libfoo.a, which is just a compression of multiple .o files. I am looking for a way to list all symbols that

  • appear in the static library as UND
  • have no definition in this static library

So that I can find out all external symbol dependencies of this library.

Entanglement answered 19/7, 2018 at 16:31 Comment(0)
C
14

You can use this method:

ld -r -o deleteme.o --whole-archive libfoo.a
nm -C --undefined-only deleteme.o       # `-C` if you might have C++ archive members
rm deleteme.o

Demo:

one.c

extern void two(void);

void one()
{
    two();
}

two.c

extern void three(void);

void two()
{
    three();
}

Make a static library libonetwo.a:

$ gcc -Wall -c one.c two.c
$ ar rcs libonetwo.a one.o two.o

nm parses the static library as if it were just a commandline list of its members:

$ nm --undefined-only libonetwo.a 

one.o:
                 U _GLOBAL_OFFSET_TABLE_
                 U two

two.o:
                 U _GLOBAL_OFFSET_TABLE_
                 U three

So incrementally link them all into a temporary object file:

$ ld -r -o deleteme.o --whole-archive libonetwo.a

Then see the residual undefined symbols of that object file and delete it:

$ nm --undefined-only deleteme.o && rm deleteme.o 
                 U _GLOBAL_OFFSET_TABLE_
                 U three
Corcyra answered 20/7, 2018 at 8:16 Comment(0)
P
4

There is no single command (that I know of) that will do that.

But it's trivial to construct two commands, one for all undefined, and one for all defined symbols, and then show only the difference between them.

comm -13 \
 <(nm libfoobar.a | egrep ' [BDTW] ' | sed -e 's/.* [BDTW] //' | sort -u) \
 <(nm libfoobar.a | grep ' U ' | sed -e 's/.* U //' | sort -u)

First nm prints only defined symbols. Second nm prints only undefined symbols (which may be defined in another file in the same library).

The comm -13 prints only lines from second nm which do not occur in the output from the first nm.

Pitzer answered 20/7, 2018 at 4:50 Comment(1)
Why the first grep command only looks for 'B', 'D', 'T' and 'W' symbol types in the output of the nm? What about other symbol types reported by nm command, for example 'C', 'G', 'I', 'R' etc?Showpiece

© 2022 - 2024 — McMap. All rights reserved.