nm 获取整个存档的未定义符号,而不是单独的目标文件
nm get undefined symbols for whole archive, not separate object files
我有两个文件:
foo.c
: int foo() { extern int bar(); return bar(); }
bar.c
: int bar() { extern int missing(); return missing() + 42; }
我编译它们并组成.a
静态库:
$ gcc -c foo.c bar.c
$ ar rcs libfoobar.a foo.o bar.o
我想找出整个存档中缺少(未定义)的符号。但我仍然得到 bar
未定义,而它存在于 foo.o
:
$ nm -u libfoobar.a
foo.o:
U bar
bar.o:
U missing
如何从输出中省略 bar
并仅显示 missing
?
存档工具只是创建……好吧,一个存档。它不是链接器。引用由您的链接器解析,此过程将在 bar.o
中找到 foo.o
对 bar
的引用。存档器不能这样做,nm
也不会这样做 - 它只是 运行 自己独立地覆盖存档内的每个对象。
Link 将整个存档放入单个目标文件并检查:
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
这应该会给出预期的结果,因为 linker 解析了它可以在 -r
请求的部分 link 中找到的所有符号。
请注意,为获得最佳效果,当前工作目录不应包含任何目标文件。
您可以使用以下脚本获得更一致的结果:
# use: script libfoo.a
tmp=${TEMPDIR:-/tmp}/undefsyms.$$
mkdir $tmp
cp $tmp/lib.a
cd $tmp
ar -x lib.a
ld -r -o $$.o *.o
nm -u $$.o
rm *
cd ..
rmdir $tmp
如果您为此目的对库进行解包和 link 感到不自在,请使用此脚本,该脚本使用命令行实用程序计算您需要的信息,使用 join
实用程序:
if [ $# -lt 1 ]
then
echo Usage: [=12=] library.a
exit 1
fi
lib=
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)
我有两个文件:
foo.c
: int foo() { extern int bar(); return bar(); }
bar.c
: int bar() { extern int missing(); return missing() + 42; }
我编译它们并组成.a
静态库:
$ gcc -c foo.c bar.c
$ ar rcs libfoobar.a foo.o bar.o
我想找出整个存档中缺少(未定义)的符号。但我仍然得到 bar
未定义,而它存在于 foo.o
:
$ nm -u libfoobar.a
foo.o:
U bar
bar.o:
U missing
如何从输出中省略 bar
并仅显示 missing
?
存档工具只是创建……好吧,一个存档。它不是链接器。引用由您的链接器解析,此过程将在 bar.o
中找到 foo.o
对 bar
的引用。存档器不能这样做,nm
也不会这样做 - 它只是 运行 自己独立地覆盖存档内的每个对象。
Link 将整个存档放入单个目标文件并检查:
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
这应该会给出预期的结果,因为 linker 解析了它可以在 -r
请求的部分 link 中找到的所有符号。
请注意,为获得最佳效果,当前工作目录不应包含任何目标文件。
您可以使用以下脚本获得更一致的结果:
# use: script libfoo.a
tmp=${TEMPDIR:-/tmp}/undefsyms.$$
mkdir $tmp
cp $tmp/lib.a
cd $tmp
ar -x lib.a
ld -r -o $$.o *.o
nm -u $$.o
rm *
cd ..
rmdir $tmp
如果您为此目的对库进行解包和 link 感到不自在,请使用此脚本,该脚本使用命令行实用程序计算您需要的信息,使用 join
实用程序:
if [ $# -lt 1 ]
then
echo Usage: [=12=] library.a
exit 1
fi
lib=
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)