15

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 を使用しています。

アップデート:

コメントでアドバイスされているように、最小限の例を作成しました。私のテストプログラムのコードはこれだけです:

#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でもテストしましたが、同じエラーです。

助言がありますか?これは本当にコンパイルエラーですか、それともまだ何か間違っていますか?

4

3 に答える 3

13

コードに何か問題があるという証拠が見つからなかったので、Boost バグレポートを投稿しました。他のブーストユーザーも同様に再現したため、実際にはブーストまたは g++ 内のバグであると思います。現在のところ、Boost のメンテナーからの返答はありません。記事があれば更新します。

アップデート

g++ リンカー プラグインが問題を引き起こしているようです (理由はまだわかりません)。したがって、考えられる回避策は、を使用してリンカー プラグインを無効にすること-fno-use-linker-pluginです。

于 2012-06-25T13:33:53.563 に答える
3

ライブラリ内の何かが、その特定のクラスの typeinfo を参照します (通常、その特定の例外の「catch」ステートメントや「dynamic_cast」など)。したがって、エラーメッセージの「セクションで参照」。

ただし、typeinfo を生成するには、非インライン非純粋仮想関数がコンパイル単位の 1 つに存在する必要があります。関数がクラス定義内で定義されている場合、これはカウントされません ("-fno-default-inline" を渡したとしても、インライン化され、リンケージのためにインライン化されたものとして扱われます)。

したがって、dynamic_cast または catch ステートメントは、作成者が意図したとおりに機能していない可能性があります。この問題は、ヘッダーで LTO が試行されるまで気づかれませんでした。

したがって、私はこれを BOOST エラーおよび/または g++ の欠点と呼んでいます。

于 2012-07-20T15:57:14.447 に答える
1

-fltoフラグが機能するには、コンパイルとリンカーの両方のコマンド ラインに存在する必要があります。-fwhole-program一方、まったく必要ありません。ちなみに、LTO は、LTO サポートでコンパイルされていない翻訳単位では機能しません。

于 2012-04-06T23:03:31.317 に答える