【发布时间】:2017-02-14 15:33:11
【问题描述】:
在编写代码或构建脚本以使用 LTO 进行编译时需要牢记哪些注意事项和陷阱?
这个问题背后的动机是为了更好地理解为什么某些项目在启用 LTO 时编译不干净。特别是,我无法在启用 LTO 的情况下构建ICU,无论是在 MSVC 还是在 GCC 中。在其他情况下,我可以使用给定的工具链版本启用 LTO,但不能使用另一个(更新的)版本;例如,libiconv 会发生这种情况。
在我遇到的所有失败案例中,都涉及由于未解析符号导致的链接失败。
为什么会发生这种情况?这是工具链、构建脚本还是源代码的问题?
【问题讨论】:
-
我从未遇到过在 MSVC 中启用 LTCG 时无法编译的项目。当您尝试在 MSVC 中构建 ICU 时,您收到了哪些错误消息?当您翻转 LTCG 开关时,您用于编译优化构建的相同设置也应该起作用。事实上,LTCG 是默认开启的,用于内置项目模板中的优化构建。
-
封装。减少全局变量的数量。减少函数中的外部依赖。酌情使用
const。 -
@CodyGray:我在链接时得到未定义的符号(
_uconvmsg_dat在某些情况下,_icudt58_dat在其他情况下)。我为此使用了几个构建标志 (/MT /Oxy- /fp:fast /Zi),但是构建总是在没有 LTCG 的情况下通过 (/GL和/LTCG)。 -
@CodyGray:我添加了一个答案,解释了为什么 ICU 在启用 LTCG 的情况下无法在 MSVC(32 位)中正确构建,您可能有兴趣了解原因。在这种情况下,这确实是包的缺陷,而不是工具链的缺陷。
标签: c++ c gcc visual-c++ lto