给定一个静态库,您可以使用
进行检查$nm libgtest.a
为什么以下版本无法找到符号?
g++ -ISomePathToGTest -lgtest SomeUnitTests.cpp
许多未定义的引用中的一个看起来像这样:
SomeUnitTests.cpp:(.text+0x28): undefined reference to `testing::InitGoogleTest(int*, char**)'
但我在上面的'nm'命令中有这些行:
000000000000ffca T _ZN7testing14InitGoogleTestEPiPPc
000000000000ffca T _ZN7testing14InitGoogleTestEPiPPw
根据nm的手册,'T'表示该系统位于我正在检查的库的文本部分。我确定它不会从其他任何地方挑选这个库,并且它正在使用该构建命令找到这个库。
像这样构建SomeUnitTests.cpp的对象:
g++ -c -ISomePathToGTest SomeUnitTests.cpp
使用nm检查它只显示以下条目,以便在InitGoogleTest上搜索:
U _ZN7testing14InitGoogleTestEPiPPc
那么,它们应该匹配吗?但是,关注链接器如何匹配符号而不是我正在使用gtest,为什么它会失败?
答案 0 :(得分:3)
为了清晰起见,简化您的命令行:
g++ -ISomePathToGTest -lgtest SomeUnitTests.cpp
调用g++
tooldriver执行以下操作:
调用GNU C ++编译器cc1plus
将SomeUnitTests.cpp
编译为
一个临时汇编语言文件,其命令行基本上类似于:
cc1plus -ISomePathToGTest SomeUnitTests.cpp -o /tmp/aaaa.s
调用GNU汇编程序as
汇总aaaa.s
临时目标文件,命令行基本上类似于:
as -ISomePathToGTest -o /tmp/bbbb.o /tmp/aaaa.s
调用GNU链接器ld
以将bbbb.o
与指定链接
和默认库,命令行基本上像:
ld -L/default/library/search/paths... -lgtest /tmp/bbbb.o -lstdc++ -lother -ldefault -llibraries...
在链接器命令行中,对象文件和指定库的排序
反映了相应的源文件和您指定的库中的库
原始命令行:因为对象文件和库的排序很重要
对于链接器,g++
的工作假设你知道这一点,那就是
命令行表达你想要的顺序。
目标文件和库的排序对链接器很重要,因为
它将搜索库以查找某些符号foo
的定义
并且只有当它已经看到一些目标文件(或库)时才会生成
对foo
的未定义引用;如果它在库中找到定义
那么它不会在以后的库中搜索它的其他定义。
这样做的结果是必须在所有对象之后提及库
引用它的文件或未定义的引用将确保。在
链接器不会检查命令行libgtest
的链接
在所有,因为到目前为止没有看到任何目标文件,也没有
要解决的未定义符号。目标文件/tmp/bbbb.o
是
随后检查,其未定义的引用只能
获取后面的默认库中的定义,保留所有引用
libgest
未解决的符号。
现在,您可以看到为什么将-lgtest
移至结尾的问题的答案
命令行"更改链接顺序"。这是因为是你的意思
要求:而不是库对象文件(失败),你要求对象文件库(成功)。
这是the linker's commandline manual。
-l namespec
的文档是相关项目。