私は clang の初心者なので、ばかげたことをしている可能性があります。しかし、ディストリビューションが提供するパッケージで -flto に対処する質問が見つからない場合は、ここで検索するなど、解決策を探すのに数時間を費やしました。この説明の詳細は Fedora 18 に固有のものですが、Ubuntu 13.04 でも同様の問題が発生しているため、Fedora に固有の問題ではありません。それは私かclangのどちらかです。
clang++ -flto
問題:リンク時の最適化の利点を得るために、単純な hello-world プログラムをコンパイルしようとしています。-flto がなければ正常に動作します。-flto を使用すると、リンクに失敗します。clang -flto -o hello hello.o -v
完全なリンカー コマンド ラインを表示するためにas を呼び出すと、次のようになります。
$ clang++ -flto -o hello hello.o -v
clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
"/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../.. -L/lib -L/usr/lib -plugin /usr/bin/../lib/LLVMgold.so hello.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error loading plugin
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error in plugin cleanup (ignored)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
次の 2 つの問題があるようです。
clang++ はリンカーを として呼び出しますが、
/usr/bin/ld
これはゴールド リンカーではありません。Fedora18 は、ゴールドを としてインストールします/usr/bin/ld.gold
。/usr/local/bin/ld
からへのシンボリックリンクを作成しようとしましたが、それが/usr/bin/ld.gold
であることを確認しましたwhich ld
が/usr/local/bin/ld
、clang++ はそれを使用しません。/usr/bin/ld に固定されているようです。clang++ は、
-plugin /usr/bin/../lib/LLVMgold.so
. それは間違っています。Clang の Fedora ディストリビューションでは/usr/lib64/llvm/LLVMgold.so
.
次の調整を加えて、上記のリンカー行を手動で呼び出してみました。
に置き換え
-plugin /usr/bin/../lib/LLVMgold.so
ます-plugin /usr/lib64/llvm/LLVMgold.so
。これにより、エラー メッセージが表示されますhello.o: file not recognized: File format not recognized
。そのため、非ゴールド リンカはプラグインを認識しているように見えますが、LLVM ビットコードを含む .o を取りません。に置き換え
/usr/bin/ld
ます/usr/bin/ld.gold
。これは機能し、期待どおりに実行される実行可能ファイルを生成します。上記の両方の
--plugin
代わりに-plugin
. この変更に違いはありません。
では、clang -flto を使用するためにシステム提供のパッケージに固執することを好む人にとって最良の方法は何でしょうか? これらをオーバーライドできる構成ファイル、または文書化されていないオプションまたは環境変数があることを願っています。または、パッケージが不足していて、「yum install ...」で修正されることをお勧めします。
リンカを直接呼び出さない方がよいと思います。なぜなら、makefile は、システム オブジェクトとライブラリ (たとえば、crt1.o、crtbegin.o、crtend.o) を認識していなければならないからです。自分で clang をビルドすることもできますが、configure スクリプトには、リンカーとプラグインのパスを構成できるものは何も表示されません。
Fedora 18 を実行しています。コンピューター上のディストリビューション以外のパッケージは、Google Chrome と VMware Tools (VMWare Fusion 内のゲスト) だけです。関連する Fedora パッケージのバージョン (2013 年 4 月 29 日現在、コンピューター全体が「yum 更新」されています):
$ yum list --noplugins installed binutils* clang* llvm* gcc*
Installed Packages
binutils.x86_64 2.23.51.0.1-6.fc18 @updates
binutils-devel.x86_64 2.23.51.0.1-6.fc18 @updates
clang.x86_64 3.2-2.fc18 @updates
clang-devel.x86_64 3.2-2.fc18 @updates
clang-doc.noarch 3.2-2.fc18 @updates
gcc.x86_64 4.7.2-8.fc18 @fedora
gcc-c++.x86_64 4.7.2-8.fc18 @fedora
llvm.x86_64 3.2-2.fc18 @updates
llvm-libs.x86_64 3.2-2.fc18 @updates