I am trying to enable link time optimization in g++. My program compiles fine without the -flto
option. When I add it to my Makefile the object files compile without errors, e.g.
g++ main.cpp -I ../includes -std=c++0x -fopenmp -Wall -pedantic -Wno-vla -flto -D INFO_ -c -o .obj/main.o
But when it comes to link the program:
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
I get a lot of errors like these:
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)
I can't figure out what is going wrong. I compile all my object files using -flto
. The libs, namely Boost and GMP, are compiled without -flto
option. Is this causing the error? The gcc manual says that its ok to mix object files compiled with & without -flto
option. Or am I missing something else, for example what is this plugin the error is speaking about?
I am using G++ 4.6.3 on Debian Wheezy.
UPDATE:
As adviced in the comments I made a minimal example. The code of my test program is only this:
#include "boost/program_options.hpp"
int main ( int argC, char* argV[] )
{
return 0;
}
When I compile it using:
g++ -o test -I ../includes -Wall -std=c++0x test.cpp -flto -fwhole-program -static
it gives similar errors as described above. If I omit the -static, -flto OR std=c++0x option it compiles without errors. The -fwhole-program option does not change the result. I now also tested with G++ 4.7, same error.
Any suggestions? Is this really a compiler error, or am I still doing something wrong?
Since I found no evidence, that there is something wrong with my code, I have posted a Boost bugreport. It was reproduced by other boost users as well, therefore I think it is actually a bug within boost or the g++. By now there was no response from the Boost maintainer. I'll update this post when there is one.
Update
It seems like the g++ linker-plugin is causing the problem (Still I have no idea why). Therefore a possible work around is to disable the linker-plugin by using
-fno-use-linker-plugin
.-flto
flag must be present in both compile and linker command lines in order to work.-fwhole-program
, on the other hand, is not needed at all. LTO will not work with translation units that were not compiled with LTO support, by the way.Something within the library references the typeinfo of the that particular class (typically things like a "catch" statement for that particular exception or a "dynamic_cast"). Hence the "referenced in section" in your error message.
However, for the typeinfo to be generated, a non-inline non-pure virtual function has to be present in one of the compilation units. If the function is defined within the class definition, this does not count (it is inlined and treated as inlined for linkage, even if you pass "-fno-default-inline").
So, the dynamic_cast or catch statement is probably not working as the author intended; the issue just was never noticed until LTO was attempted on the header.
So, I'd call it a BOOST error and/or a shortcoming of g++.