LTO with LLVM and CMake

Viewed 16670

I am trying to apply Link Time Optimization with LLVM on a CMake Project, that creates a shared library. My question is pretty much the same as this one:

Switching between GCC and Clang/LLVM using CMake.

However, the answers do not seem to be applicable anymore, since llvm-ld is not present in the new versions. On the command line, I run the following commands to get LTO (Assuming there are only 2 .cpp files):

Compile to byte code:

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

Link byte code:

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

Optimize byte code:

opt -O3 unoptimized.bc -o optimized.bc

Convert byte code to shared object:

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

Could somebody please tell me how to have CMake run the additional steps?

3 Answers

check_ipo_supported() resulted for me in "Policy CMP0069 is not set" error on CMake 3.9.1.

Per its help, CMake up to 3.8 only supported Intel compiler's LTO. It didn't work on XCode 9's clang for me either.

What worked, in the end:

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

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

Looks like add_executable() needs to be after cmake_policy(SET CMP0069 NEW).

LTO cache

target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache") did no harm.

Pick your command-line option depending on your linker.

More brutal option

According to @ChandlerCarruth's answer:

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