gpt4 book ai didi

c++ - 了解 g++ 链接器失败

转载 作者:太空狗 更新时间:2023-10-29 12:01:44 25 4
gpt4 key购买 nike

给定一个可以检查的静态库

$nm libgtest.a

为什么以下构建无法找到符号?

g++ -ISomePathToGTest -lgtest SomeUnitTests.cpp

许多 undefined reference 之一如下所示:

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,为什么会失败?

最佳答案

为了清晰起见,简化您的命令行:

g++ -ISomePathToGTest -lgtest SomeUnitTests.cpp

调用 g++ 工具驱动程序来执行以下操作:

  1. 调用GNU C++编译器cc1plusSomeUnitTests.cpp编译为一个临时的汇编语言文件,命令行基本如下:

    cc1plus -ISomePathToGTest SomeUnitTests.cpp -o/tmp/aaaa.s

  2. 调用GNU汇编程序asaaaa.s汇编成一个临时目标文件,命令行基本如下:

    as -ISomePathToGTest -o/tmp/bbbb.o/tmp/aaaa.s

  3. 调用 GNU 链接器 ldbbbb.o 链接到指定的和默认库,命令行本质上是这样的:

    ld -L/default/library/search/paths... -lgtest/tmp/bbbb.o -lstdc++ -lother -ldfault -llibraries...

在链接器命令行中,目标文件和指定库的顺序反射(reflect)相应的源文件和指定的库在你的原始命令行:因为目标文件和库的顺序很重要到链接器,并且 g++ 的工作假设你知道这个,那个命令行表达了你想要的顺序。

目标文件和库的顺序对链接器很重要,因为它会搜索一个库来找到一些符号 foo 的定义,如果并且仅当它已经看到的某个目标文件(或库)使对 foo 的 undefined reference ;如果它在库中找到定义那么它将不会在以后的库中搜索它的其他定义。

这样做的结果是必须在所有对象之后提及库引用它的文件或 undefined reference 将确保。在链接器不检查命令行的链接 libgtest根本没有,因为到目前为止还没有看到目标文件,也没有要解析的 undefined symbol 。当目标文件 /tmp/bbbb.o 是随后检查,其 undefined reference 只能在随后的默认库中获取定义,保留所有引用libgest 的未解析符号。

现在您看到了为什么将 -lgtest 移动到末尾的问题的答案命令行“更改链接顺序”。这是因为你就是这样请求:您请求的不是库对象文件(失败),而是对象文件库(成功)。

这里是 the linker's commandline manual .-l namespec 的文档是相关项目。

关于c++ - 了解 g++ 链接器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32909336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com