Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ error using -flto option

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?

like image 234
Haatschii Avatar asked Apr 06 '12 22:04

Haatschii


2 Answers

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.

like image 174
Haatschii Avatar answered Oct 11 '22 01:10

Haatschii


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

like image 38
Brian Bockelman Avatar answered Oct 11 '22 01:10

Brian Bockelman