如何在 Linux 上列出静态库的所有外部未定义符号?

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

我有一个静态库libfoo.a,它只是多个.o文件的压缩。我正在寻找一种方法来列出所有

的符号

这样我就可以找出这个库的所有外部符号依赖。

没有一个命令(据我所知)可以做到这一点。

但是构建两个命令,一个用于所有未定义的,一个用于所有已定义的符号,然后只显示它们之间的区别是微不足道的。

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

首先 nm 只打印定义的符号。第二个 nm 仅打印未定义的符号(可能在同一库的另一个文件中定义)。

comm -13 仅打印第二个 nm 中未出现在第一个 nm.

输出中的行

你可以使用这个方法:

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

演示:

one.c

extern void two(void);

void one()
{
    two();
}

two.c

extern void three(void);

void two()
{
    three();
}

制作静态库libonetwo.a:

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

nm 解析静态库,就好像它只是其成员的命令行列表一样:

$ nm --undefined-only libonetwo.a 

one.o:
                 U _GLOBAL_OFFSET_TABLE_
                 U two

two.o:
                 U _GLOBAL_OFFSET_TABLE_
                 U three

所以逐步 link 将它们全部放入一个临时对象文件中:

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

然后查看那个目标文件残留的未定义符号,删除:

$ nm --undefined-only deleteme.o && rm deleteme.o 
                 U _GLOBAL_OFFSET_TABLE_
                 U three