2016-03-10 132 views
11

我想在CMake項目上應用鏈接時間優化和LLVM,創建一個共享庫。我的問題幾乎與這一個相同:LTO與LLVM和CMake

Switching between GCC and Clang/LLVM using CMake

但是,答案似乎不再適用,因爲llvm-ld不存在於新版本中。在命令行中,我運行以下命令來獲得LTO(假設只有2個.cpp文件):

編譯成字節碼:

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運行額外的步驟?

+2

這可能是['add_custom_command']工作(https://cmake.org/cmake/help/v3 .0/command/add_custom_command.html)cmake ...類似'add_custom_command(OUTPUT libTest.so COMMAND clang ++ -shared optimized.bc -o libTest.so MAIN_DEPENDENCY optimized.bc)'See http://stackoverflow.com/問題/ 13470499/cmake的加定製命令與 - 依賴 - 從-A-不同的目錄 – francis

回答

6

使用Clang並啓用LTO的正確方法是在編譯鏈接時使用命令行的-flto標誌。另外,你需要在一個平臺上開發一個鏈接器,它可以直接支持LTO(通常是Apple的平臺),或者有一個LLVM鏈接器插件(使用Gold鏈接器的Linux,但是我認爲有些人已經獲得了BFD鏈接器也支持鏈接器插件)。如果您使用鏈接器插件,則需要確保安裝了LLVM並安裝了該插件。如果確實如此,Clang將自動添加必要的鏈接器命令行選項,以便在與-flto鏈接時使用插件,即使對於共享對象也是如此。

此外,LLVM項目正在研究一種新的鏈接器(LLD),它將支持所有支持的平臺上的LTO,但它仍然很早。目前我知道人們正在測試Windows和Linux上的LTO支持,而且它似乎運行良好,但仍然遺漏了許多功能。在CMake的3.9

1

啓用(薄)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的符號鏈接。

2

check_ipo_supported()在CMake 3.9.1上導致我出現「Policy CMP0069未設置」錯誤。

根據其幫助,CMake最高只支持3.8英特爾編譯器的LTO。它也不適用於XCode 9的叮噹聲。

什麼工作,到底:

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")沒有傷害。

選擇您的命令行選項depending on your linker

更殘酷的選項

據@ ChandlerCarruth的回答是:

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") 
    target_link_libraries(Foobar -flto) 
endif()