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

时间:2018-07-19 16:31:58

标签: static-libraries binaryfiles elf object-files

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

  • 在静态库中显示为UND
  • 在此静态库中没有定义

以便我可以找到该库的所有外部符号依赖项。

2 个答案:

答案 0 :(得分:3)

您可以使用此方法:

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

因此,将它们全部逐步链接到一个临时目标文件中:

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

然后查看该目标文件的剩余未定义符号并将其删除:

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

答案 1 :(得分:2)

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

但是构造两个命令很简单,一个用于所有未定义的命令,一个用于所有已定义符号的命令,然后仅显示它们之间的差异。

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的输出中。