2016-03-10 34 views
11

Próbuję zastosować Link Time Optimization z LLVM w projekcie CMake, który tworzy wspólną bibliotekę. Moje pytanie jest prawie takie samo jak to:LTO z LLVM i CMake

Switching between GCC and Clang/LLVM using CMake.

Jednak odpowiedzi wydają się już nie mieć zastosowania, ponieważ llvm-ld nie występuje w nowych wersjach. W wierszu polecenia uruchomić następujące polecenia, aby uzyskać LTO (Zakładając, że istnieją tylko 2 .cpp pliki):

kompilacji do kodu bajtowego:

clang++ -c FirstClass.cpp -O3 -flto -o FirstClass.bc 
clang++ -c SecondClass.cpp -O3 -flto -o SecondClass.bc 

link kod bajtowy:

llvm-link FirstClass.bc SecondClass.bc -o unoptimized.bc 

Zoptymalizuj kod bajtu:

opt -O3 unoptimized.bc -o optimized.bc 

Konwertuj kod bajtowy na obiekt współdzielony:

clang++ -shared optimized.bc -o libTest.so 

Czy ktoś mógłby mi powiedzieć, w jaki sposób CMake powinien wykonać dodatkowe czynności?

+2

To może być zadanie dla [ 'add_custom_command'] (https://cmake.org/cmake/help/v3 .0/command/add_custom_command.html) cmake ... Coś jak 'add_custom_command (OUTPUT libTest.so COMMAND clang ++ -shared optimized.bc -o libTest.so MAIN_DEPENDENCY optimized.bc)' Zobacz http://stackoverflow.com/ pytania/13470499/cmake-add-custom-command-with-dependencies-from-a-different-directory – francis

Odpowiedz

6

Prawidłowy sposób korzystania dzyń i umożliwić LTO jest z flagą -flto do linii poleceń clang zarówno podczas kompilacji i czasu łącza.

Ponadto musisz pracować na platformie z łącznikiem, który bezpośrednio obsługuje LTO (ogólnie platformy Apple) lub posiada wtyczkę LLVM linker (Linux używa łącznika Gold, ale myślę, że niektórzy dostali Łącznik BFD do obsługi wtyczki linkera). Jeśli używasz wtyczki linkera, musisz się upewnić, że twoja instalacja LLVM zbudowała i zainstalowała wtyczkę. Jeśli tak, Clang automatycznie doda niezbędne opcje wiersza poleceń linkera, aby użyć wtyczki podczas łączenia z -flto, nawet dla obiektów współdzielonych.

Ponadto, projekt LLVM pracuje nad nowym łącznikiem (LLD), który będzie obsługiwał LTO po rozpakowaniu na wszystkich platformach, które obsługuje, ale wciąż jest dość wczesny. Obecnie wiem, że ludzie testują wsparcie LTO w systemach Windows i Linux i wygląda na to, że działa dobrze, ale wciąż brakuje wielu funkcji.

1

Włączenie (cienki) LTO na CUpewnij 3.9 i nowsze powinny być proste:

include(CheckIPOSupported) 
check_ipo_supported() 
set_target_properties(myProject PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) 

Zamiast set_target_properties jeden projekt, jeden globalny ustawienie set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) można zrobić.

W celu przyspieszenia recompiles, pamięć podręczna dla LTO można ustawić:

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) 

Zmusza gold jako łącznika, w celu korzystania z odpowiednich opcji wiersza poleceń. Może wymagać dowiązania symbolicznego od /usr/lib/LLVMgold.so do /usr/lib/llvm-4.0/lib/LLVMgold.so.

2

check_ipo_supported() za mnie w "Policy CMP0069 nie ustawiono" błąd na CMake 3.9.1.

Za jego pomoc, CMake do 3.8 tylko obsługiwane LTO kompilatora Intel. Nie zadziałało to również na klang XCode 9.

Co działa, w końcu:

cmake_policy(SET CMP0069 NEW) 
include(CheckIPOSupported) 
check_ipo_supported() 

add_executable(Foobar SOURCES) 
set_target_properties(Foobar PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) 

Wygląda add_executable() musi być po cmake_policy(SET CMP0069 NEW).

LTO cache

target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache") zrobił żadnej krzywdy.

Wybierz opcję wiersza polecenia: depending on your linker.

opcja bardziej brutalne

Według @ ChandlerCarruth na odpowiedź:

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