我只是想知道是否有一种有效的技术来解决gcc中未定义的符号问题。有时我的一个项目无法链接,我通常会花很多时间找到原因。通常它是深度隐藏的makefile中的拼写错误,不正确的环境变量或类似的东西。如果您的构建突然以“未定义的符号”死亡,并且为什么不明显,您使用什么方法?
答案 0 :(得分:24)
说这是我的开始配置:
/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
bar.o: In function `baz()':
bar.cpp:(.text+0xd): undefined reference to `Foo::bar()'
collect2: ld returned 1 exit status
我首先用grep查找所有.o和.lib文件的缺失符号。
$ grep 'Foo.*bar' *.o *.lib *.so
Binary file bar.o matches
Binary file foo.o matches
然后我使用nm
工具检查每个目标文件,如果那里的符号丢失或实现。
$ nm foo.o
00000000 T _ZN3Foo3barEv
$ nm bar.o
00000000 T _Z3bazv
U _ZN3Foo3barEv
U __gxx_personality_v0
现在我知道Foo :: bar()是在foo.o中实现的,可以将此文件链接到可执行文件中。所以下一部分是检查为什么foo.o不包含在链接命令中。
有时您找不到任何实施符号。通常情况下,实现单元未构建,或者不包含符号(#ifdef
,符号可见性)。在这种情况下,我搜索定义了符号的.cpp文件,运行make $file.o
生成文件,然后检查文件。当smbol在那里时,我继续构建放置此文件的库或可执行文件。