共有ライブラリを作成するCMakeプロジェクトでLLVMを使用してリンク時間最適化を適用しようとしています。私の質問はこれとほとんど同じです:
CMakeを使用したGCCとClang/LLVMの切り替え 。
ただし、llvm-ld
は新しいバージョンには存在しないため、回答はもう適用されないようです。コマンドラインで次のコマンドを実行してLTOを取得します(.cpp
ファイルが2つしかない場合)。
バイトコードにコンパイルします。
clang++ -c FirstClass.cpp -O3 -flto -o FirstClass.bc
clang++ -c SecondClass.cpp -O3 -flto -o SecondClass.bc
リンクバイトコード:
llvm-link FirstClass.bc SecondClass.bc -o unoptimized.bc
バイトコードを最適化する:
opt -O3 unoptimized.bc -o optimized.bc
バイトコードを共有オブジェクトに変換します。
clang++ -shared optimized.bc -o libTest.so
CMakeに追加のステップを実行させる方法を誰かに教えてもらえますか?
Clangを使用してLTOを有効にする正しい方法は、コンパイル時にclang
コマンドラインに-flto
フラグを使用して、リンク時におよびリンクすることです。
さらに、LTOを直接サポートするリンカー(Appleのプラットフォーム一般)を備えたプラットフォーム、またはLLVMリンカープラグイン(Goldリンカーを使用するLinux)を備えたプラットフォームで作業する必要がありますが、BFDリンカーをサポートするようになっているものもあると思いますリンカープラグインも)。リンカープラグインを使用している場合は、LLVMのインストールがプラグインをビルドしてインストールしたことを確認する必要があります。その場合、Clangは、共有オブジェクトの場合でも、-flto
とリンクするときにプラグインを使用するために必要なリンカーコマンドラインオプションを自動的に追加します。
また、LLVMプロジェクトは、サポートするすべてのプラットフォームでそのままLTOをサポートする新しいリンカー(LLD)に取り組んでいますが、まだかなり初期の段階です。現在、私はWindowsとLinuxでLTOサポートをテストしている人々を知っています。それはうまく機能しているように見えますが、それでも多くの機能がありません。
check_ipo_supported()
の結果、CMake 3.9.1で「 Policy CMP0069 is not set」エラーが発生しました。
その助けによれば、CMake 3.8まではIntelコンパイラのLTOのみをサポートしていました。 XCode 9のclangでも動作しませんでした。
結局のところ、うまくいったこと:
_cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported)
check_ipo_supported()
add_executable(Foobar SOURCES)
set_target_properties(Foobar PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
_
add_executable()
はcmake_policy(SET CMP0069 NEW)
の後に置く必要があるようです。
LTOキャッシュ
target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache")
は害を及ぼしませんでした。
コマンドラインオプションを選択します リンカーによって異なります 。
もっと残忍なオプション
@ChandlerCarruthの答えによると:
_if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
target_link_libraries(Foobar -flto)
endif ()
_
Cmake 3.9以降で(シン)ltoを有効にするのは簡単です。
_include(CheckIPOSupported)
check_ipo_supported()
set_target_properties(myProject PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
_
プロジェクトごとに_set_target_properties
_の代わりに、set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
の単一のグローバル設定を行うことができます。
再コンパイルを高速化するために、LTOのキャッシュを設定できます。
_function(append value)
foreach(variable ${ARGN})
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
endforeach(variable)
endfunction()
append("-Fuse-ld=gold -Wl,--no-threads,--plugin-opt,cache-dir=${PROJECT_BINARY_DIR}/lto.cache" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
_
これにより、正しいコマンドラインオプションを使用するために、gold
がリンカとして強制されます。 _/usr/lib/LLVMgold.so
_から_/usr/lib/llvm-4.0/lib/LLVMgold.so
_へのシンボリックリンクが必要な場合があります。