nm 获取整个存档的未定义符号,而不是单独的目标文件

fla*_*uin 5 c c++ gcc static-libraries

我有两个文件:

foo.cint foo() { extern int bar(); return bar(); }

bar.cint bar() { extern int missing(); return missing() + 42; }

我编译它们并组成.a静态库:

$ gcc -c foo.c bar.c
$ ar rcs libfoobar.a foo.o bar.o
Run Code Online (Sandbox Code Playgroud)

我想找到整个档案中缺少(未定义)的符号。但我仍然得到bar未定义的信息,尽管它存在于foo.o

$ nm -u libfoobar.a
foo.o:
    U bar
bar.o:
    U missing
Run Code Online (Sandbox Code Playgroud)

如何bar从输出中省略并仅显示missing

fuz*_*fuz 4

将整个存档链接到单个目标文件中并检查:

ar -x libfoo.a      # unpack libfoo.a
ld -r -o tmp.o *.o  # link all objects into tmp.o
nm -u tmp.o         # find undefined symbols in tmp.o
rm *.o              # remove tmp.o as well as the contents of libfoo.a
Run Code Online (Sandbox Code Playgroud)

当链接器解析它可以在 请求的部分链接中找到的所有符号时,这应该会给出所需的结果-r

请注意,为了获得最佳结果,当前工作目录不应包含任何目标文件。

您可以使用以下脚本获得更一致的结果:

# use: script libfoo.a
tmp=${TEMPDIR:-/tmp}/undefsyms.$$
mkdir $tmp
cp $1 $tmp/lib.a
cd $tmp
ar -x lib.a
ld -r -o $$.o *.o
nm -u $$.o
rm *
cd ..
rmdir $tmp
Run Code Online (Sandbox Code Playgroud)

如果您对此目的解压和链接库感到不舒服,请使用此脚本,该脚本使用命令行实用程序来使用join实用程序计算您需要的信息:

if [ $# -lt 1 ]
then
    echo Usage: $0 library.a
    exit 1
fi

lib=$1

postproc() { cut -w -f 2-3 | sort -u; }
allsyms() { nm -g -P -A $lib | postproc; }
undefsyms() { nm -g -P -A -u $lib | postproc; }
defsyms() { allsyms | grep -v 'U$'; }

comm -2 -3 <(undefsyms | cut -w -f 1) <(defsyms | cut -w -f 1)
Run Code Online (Sandbox Code Playgroud)