c++ g++使用-flto选项时出错

lf3rwulv  于 2024-01-09  发布在  其他
关注(0)|答案(4)|浏览(365)

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

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

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

  1. 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


我犯了很多这样的错误:

  1. includes/gmp_lib_deb/lib/libgmpxx.a ../includes/gmp_lib_deb/lib/libgmp.a -o BeeBench
  2. `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)
  3. `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)
  4. `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。

更新:

正如在评论中建议的那样,我做了一个最小的例子。我的测试程序的代码只有这样:

  1. #include "boost/program_options.hpp"
  2. int main ( int argC, char* argV[] )
  3. {
  4. return 0;
  5. }


当我编译它使用:

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


它给出了类似的错误如上所述.如果我省略了-static,-flto OR std=c0x选项,它编译没有错误. -fwhole-program选项不会改变结果.我现在也用G 4.7测试,同样的错误.
有什么建议吗?这真的是一个编译器错误,还是我仍然做错了什么?

pxq42qpu

pxq42qpu1#

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

更新

看起来是g++ linker-plugin导致了这个问题(我仍然不知道为什么)。因此,一个可能的解决方法是使用-fno-use-linker-plugin禁用linker-plugin。

c7rzv4ha

c7rzv4ha2#

库中的某个东西引用了那个特定类的typeinfo(通常是像那个特定异常的“catch”语句或“dynamic_cast”)。因此,错误消息中的“referenced in section”。
然而,要生成typeinfo,一个非内联的非纯虚函数必须存在于一个编译单元中。如果函数在类定义中定义,这不算(它是内联的,并被视为内联的链接,即使你传递“-fno-default-inline”)。
因此,dynamic_cast或catch语句可能没有按照作者的意图工作;这个问题直到在头上尝试LTO才被注意到。
所以,我称之为BOOST错误和/或g++的缺点。

fcy6dtqo

fcy6dtqo3#

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

niknxzdl

niknxzdl4#

12年后。“-flto”必须同时作为编译器和链接器标志出现。你还需要“-ffat-lto-objects”编译器标志。

相关问题