【问题标题】:g++ error using -flto option使用 -flto 选项的 g++ 错误
【发布时间】:2012-04-20 11:08:42
【问题描述】:

我正在尝试在 g++ 中启用链接时间优化。我的程序在没有-flto 选项的情况下编译得很好。当我将它添加到我的 Makefile 时,目标文件编译时不会出错,例如

g++ main.cpp -I ../includes -std=c++0x -fopenmp -Wall -pedantic -Wno-vla -flto -D INFO_ -c -o .obj/main.o

但是当涉及到链接程序时:

g++ -fwhole-program -I ../includes -std=c++0x -fopenmp -Wall -pedantic -Wno-vla -flto -D INFO_ .obj/main.o .obj/atom.o .obj/bee.o .obj/colony.o ../includes/.obj/error.o ../includes/.obj/CmdLine.o ../includes/boost_lib_deb/libboost_program_options.a ../includes/gmp_lib_deb/lib/libgmpxx.a ../includes/gmp_lib_deb/lib/libgmp.a -o BeeBench

我收到很多这样的错误:

includes/gmp_lib_deb/lib/libgmpxx.a ../includes/gmp_lib_deb/lib/libgmp.a -o BeeBench
`typeinfo for boost::program_options::too_many_positional_options_error' referenced in section `.rodata._ZTVN5boost15program_options33too_many_positional_options_errorE[vtable for boost::program_options::too_many_positional_options_error]' of ../includes/boost_lib_deb/libboost_program_options.a(cmdline.o): defined in discarded section `.gnu.linkonce.t._ZTIN5boost15program_options33too_many_positional_options_errorE' of .obj/main.o (symbol from plugin)

`typeinfo for boost::program_options::too_many_positional_options_error' referenced in section `.rodata._ZTIN5boost16exception_detail19error_info_injectorINS_15program_options33too_many_positional_options_errorEEE[typeinfo for boost::exception_detail::error_info_injector<boost::program_options::too_many_positional_options_error>]' of ../includes/boost_lib_deb/libboost_program_options.a(cmdline.o): defined in discarded section `.gnu.linkonce.t._ZTIN5boost15program_options33too_many_positional_options_errorE' of .obj/main.o (symbol from plugin)
`typeinfo for boost::program_options::invalid_command_line_style' referenced in section `.rodata._ZTVN5boost15program_options26invalid_command_line_styleE[vtable for boost::program_options::invalid_command_line_style]' of ../includes/boost_lib_deb/libboost_program_options.a(cmdline.o): defined in discarded section `.gnu.linkonce.t._ZTIN5boost15program_options26invalid_command_line_styleE' of .obj/main.o (symbol from plugin)

我不知道出了什么问题。我使用-flto 编译我的所有目标文件。这些库,即 Boost 和 GMP,在编译时没有 -flto 选项。这是导致错误吗? gcc 手册说可以混合使用 & 不使用 -flto 选项编译的目标文件。或者我是否遗漏了其他内容,例如错误所说的这个插件是什么?

我在 Debian Wheezy 上使用 G++ 4.6.3。

更新:

按照 cmets 中的建议,我做了一个最小的示例。我的测试程序的代码只有这样:

#include "boost/program_options.hpp"

int main ( int argC, char* argV[] )
{
    return 0;
}

当我编译它时:

g++ -o test -I ../includes -Wall -std=c++0x test.cpp -flto -fwhole-program -static

它给出了与上述类似的错误。如果我省略 -static、-flto 或 std=c++0x 选项,它编译时不会出错。 -fwhole-program 选项不会改变结果。我现在也用 G++ 4.7 测试过,同样的错误。

有什么建议吗?这真的是编译器错误,还是我仍然做错了什么?

【问题讨论】:

  • 可能是编译器错误。您是否尝试过创建一个使用 Boost.ProgramOptions 的最小测试用例?
  • 不幸的是,我无法在我目前拥有的任何机器上重现这些错误 - 其中一个会引发不同的链接器错误,因为它没有静态可链接库,第二个是 Mac,其中GCC 根本不喜欢静态链接。我会在我自己的 Linux 机器上尝试的时候。

标签: c++ boost linker g++


【解决方案1】:

由于我没有发现任何证据表明我的代码有问题,因此我发布了Boost bugreport。它也被其他 boost 用户复制,因此我认为它实际上是 boost 或 g++ 中的一个错误。到目前为止,Boost 维护者没有任何回应。有的话我会更新这篇文章的。

更新

似乎是 g++ 链接器插件导致了问题(我仍然不知道为什么)。因此,一种可能的解决方法是使用-fno-use-linker-plugin 禁用链接器插件。

【讨论】:

  • 不会 -fno-use-linker-plugin 否定 -flto 选项,因此与不使用 -flto 的效果相同?
  • @GoswinvonBrederlow:不。请参阅gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 中的 -flto。但是它指出,如果链接器插件被停用 -fwhole-program 应该被使用。
  • @Haatschii ...但它也说whole-program应该lto一起使用。
  • @KyleStrand:有趣的是,自从我问了这个问题后,这实际上发生了变化。在gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options.html 中,它在 LTO 部分明确指出如果没有可用的链接器插件,则启用-whole-program
  • @Haatschii 有趣。我想可能是这样,但你几个月前才写了那条评论。
【解决方案2】:

库中的某些内容引用了该特定类的类型信息(通常是针对该特定异常的“catch”语句或“dynamic_cast”)。因此,您的错误消息中会出现“在部分中引用”。

但是,要生成 typeinfo,非内联非纯虚函数必须存在于其中一个编译单元中。如果函数是在类定义中定义的,则不计算在内(它被内联并被视为内联链接,即使您传递了“-fno-default-inline”)。

因此,dynamic_cast 或 catch 语句可能无法按作者的预期工作;直到在标头上尝试 LTO 之前,这个问题才被注意到。

所以,我称之为 BOOST 错误和/或 g++ 的缺点。

【讨论】:

    【解决方案3】:

    -flto 标志必须同时出现在编译和链接器命令行中才能工作。另一方面,-fwhole-program 根本不需要。顺便说一下,LTO 不适用于未在 LTO 支持下编译的翻译单元。

    【讨论】:

    • 正如我在问题中所写的 -flto 出现在两个 g++ 调用中。在没有 -fwhole-program 的情况下编译时会发生同样的错误,顺便说一下,据我所知这很有用,因为我没有使用链接器插件(顺便说一句,它仍然会产生相同的错误)。
    猜你喜欢
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多