g ++错误使用-flto选项

时间:2012-04-06 22:53:10

标签: c++ boost linker g++

我正在尝试在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编译所有目标文件。 libs,即Boost和GMP,编译时没有-flto选项。这会导致错误吗? gcc手册说可以混合用&amp;编译的目标文件。没有-flto选项。或者我错过了其他的东西,例如错误所说的插件是什么?

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

更新

正如评论中所提出的,我做了一个最小的例子。我的测试程序的代码只有这个:

#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 OR std = c ++ 0x选项,则编译时没有错误。 -fwhole-program选项不会更改结果。我现在也用G ++ 4.7进行了测试,同样的错误。

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

3 个答案:

答案 0 :(得分:13)

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

更新

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

答案 1 :(得分:3)

库中的某些内容引用该特定类的typeinfo(通常类似于该特定异常的“catch”语句或“dynamic_cast”)。因此,您的错误消息中的“引用部分”。

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

因此,dynamic_cast或catch语句可能不像作者想要的那样工作;在尝试对标题进行LTO之前,这个问题从未被注意到。

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

答案 2 :(得分:0)

编译和链接器命令行中必须存在

-flto标志才能工作。另一方面,-fwhole-program根本不需要。顺便说一句,LTO不适用于没有使用LTO支持编译的翻译单元。