gpt4 book ai didi

c++ - 如何编写支持 LTO 的代码?

转载 作者:太空宇宙 更新时间:2023-11-04 05:23:54 26 4
gpt4 key购买 nike

在编写代码或构建脚本以使用 LTO 进行编译时需要牢记哪些注意事项和陷阱?

这个问题背后的动机是为了更好地理解为什么某些项目在启用 LTO 时编译不干净。特别是,我无法构建 ICU在启用 LTO 的情况下,既不在 MSVC 中也不在 GCC 中。在其他情况下,我可以使用给定的工具链版本启用 LTO,但不能使用另一个(更新的)版本;例如,libiconv 会发生这种情况.

在我遇到的所有失败案例中,都涉及由于未解析符号导致的链接失败。

为什么会发生这种情况?这是工具链、构建脚本或源代码的问题吗?

最佳答案

这个答案总结了我在 GCC 和 MSVC 中构建启用了 LTO 的项目时所涉及的一些复杂问题的发现。

海合会

首先,根据 GCC Wiki ,为了正确构建启用了 LTO 的项目,您必须:

  1. 确保使用 gcc-ar 而不是 binutils ar;
  2. 确保使用 gcc-ranlib 而不是 binutils ranlib;
  3. 确保使用 gcc-nm 而不是 binutils nm;
  4. 使用 -flto 编译链接。

这意味着在传统的./configure && make循环中,必须介意设置AR=RANLIB=NM= 相关时。主要是这样;但是,这些步骤很容易被忽略,因为需要更改 eg 的值。 AR 并不常见。

现在的问题:

在 GCC 4.8 及更早版本中,编译器默认生成胖目标文件。这意味着即使后编译工具(链接器、存档器等)无法识别 LTO 对象,它们也能正常工作(但不会实际执行 LTO)。

在 GCC 4.9 及更高版本中,编译器默认发出 slim 对象文件,这意味着编译后工具必须识别 LTO 对象,否则工具将失败。这解释了为什么有时 LTO 构建在使用 GCC 4.8 时通过,但在使用 GCC 4.9 及更高版本时失败。

我还注意到构建脚本并不总是在需要时将某些配置指令的值正确传递给子脚本。例如,在 MinGW-w64 中使用 LTO 构建静态 libiconv 时,configure 脚本仍然使用 ar 而不是 配置内部 libtool gcc-ar,即使被告知 AR=gcc-ar

LTO 构建往往会发现隐藏的错误,特别是由 static init order fiasco 引起的错误.它们还会妨碍其他优化,例如 ICF(由 Gold 执行)。

最后,LTO 机器中显然仍然存在一些错误。当尝试使用启用了 LTO 和其他优化的 MinGW-w64 编译 ICU 时,我遇到了 this bug和内部编译器错误(internal compiler error: in splice_child_die, at dwarf2out.c,可能与使用 -g 和 LTO 有关)。

所有这一切都意味着,由于工具链中的一些缺陷,使用 LTO 构建一个随机项目仍然很重要。有些项目会成功构建,有些则不会。

MSVC

在MSVC中使用LTO编译(也就是LTCG),编译时必须使用/GL,链接时必须使用/LTCG,就是这样.

尽管如此,当在 MSVC 中启用 LTCG 时,编译器不会发出传统的 COFF 对象。它发出一个 special kind of object file包含其 header (ANON_OBJECT_HEADER_BIGOBJ) 与 COFF header (IMAGE_FILE_HEADER) 不同的 IR。这显然在构建项目时应该没有任何区别,因为这些细节留给工具链来处理。

现在,为什么在 MSVC 中启用 LTCG 后 ICU 无法正确构建?

ICU 有一个名为 pkgdata 的工具,它可以为给定的体系结构生成目标代码。在构建过程中,该工具用于构建包中的其他实用程序。但是,pkgdata 会尝试通过检查给定的引用对象文件来猜测目标体系结构。在 Windows 中,该工具采用 COFF header ,并且在 32 位构建中它错误地确定目标是 64 位架构(由于 pkg_genc.c:getArchitecture() 中的草率逻辑) .因此 MSVC 32 位 LTCG 构建失败。

关于c++ - 如何编写支持 LTO 的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42230141/

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