How do I enable link time optimization (LTO) with CMake?
Solution 1:
Good news! CMake v3.9 finally supports LTO.
Example
Here's an example code to show how it works:
cmake_minimum_required(VERSION 3.9.4)
include(CheckIPOSupported)
check_ipo_supported(RESULT supported OUTPUT error)
add_executable(example Example.cpp)
if( supported )
message(STATUS "IPO / LTO enabled")
set_property(TARGET example PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(STATUS "IPO / LTO not supported: <${error}>")
endif()
For GCC this adds -flto -fno-fat-lto-objects
to the targets compile commands.
Checking Compiler Support
The Module CheckIPOSupported provides checking whether interprocedural optimization (IPO/LTO) is supported by the compiler or not:
check_ipo_supported([RESULT <result>] [OUTPUT <output>]
[LANGUAGES <lang>...])
If no arguments is passed (= check_ipo_supported()
) an error is raised to indicate it's not supported, otherwise the result
variable is set to either YES
or NO
. More details are described in the documentation of the module.
Enabling LTO
LTO is enabled either for a single target or as default for all targets.
LTO for a single target
To enable LTO for a target set INTERPROCEDURAL_OPTIMIZATION
to TRUE
. This is done by the set_property()
command:
set_property(TARGET name-target-here
PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
LTO as default
It's possible to enable LTO per default by setting CMAKE_INTERPROCEDURAL_OPTIMIZATION
to TRUE
:
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
This will enable INTERPROCEDURAL_OPTIMIZATION
for all targets created after this line. Those created before are not affected.
See also
- CMake issue
- Related Pull Requests
Solution 2:
Edit: as of 28 October, 2015 on CMake IRC
jcelerier | I have a question about INTERPROCEDURAL_OPTIMIZATION
jcelerier | it sounds like it should enable -flto on gcc
+ngladitz | jcelerier: its only implemented for the intel compiler
jcelerier | ngladitz: ah, okay
jcelerier | are there other switches for pgo / lto ?
jcelerier | or must it be done by hand ?
+ngladitz | there currently is no first class support otherwise
Related CMake issue: https://gitlab.kitware.com/cmake/cmake/issues/15245
CMake has the INTERPROCEDURAL_OPTIMIZATION
property on targets, which sounds like it may enable LTO on some platforms.
Link : http://www.cmake.org/cmake/help/v3.0/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.html
To enable it on a target MyLib :
add_library(MyLib ...)
...
set_property(TARGET MyLib PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
Solution 3:
Yep, according to source code there are no support for LTO for gcc/clang compilers. They have some support for Intel compiler only.
I have some grep output for cmake 3.4.3:
grep -HiR 'INTERPROCEDURAL_OPTIMIZATION' *
Help/manual/cmake-properties.7.rst:
/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG
Help/manual/cmake-properties.7.rst:
/prop_dir/INTERPROCEDURAL_OPTIMIZATION
Help/manual/cmake-properties.7.rst:
/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
Help/manual/cmake-properties.7.rst:
/prop_tgt/INTERPROCEDURAL_OPTIMIZATION
Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst:INTERPROCEDURAL_OPTIMIZATION
Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst:INTERPROCEDURAL_OPTIMIZATION_<CONFIG
Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst:This is a
per-configuration version of INTERPROCEDURAL_OPTIMIZATION.
Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst:INTERPROCEDURAL_OPTIMIZATION
Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst:INTERPROCEDURAL_OPTIMIZATION_<CONFIG
Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst:This is a
per-configuration version of INTERPROCEDURAL_OPTIMIZATION.
Modules/Platform/Linux-Intel.cmake: # INTERPROCEDURAL_OPTIMIZATION
Source/cmCommonTargetGenerator.cxx:
if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
Source/cmGeneratorTarget.cxx:
"INTERPROCEDURAL_OPTIMIZATION", config))
Source/cmMakefileLibraryTargetGenerator.cxx:
if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION") &&
Tests/IPO/CMakeLists.txt:set_property(DIRECTORY PROPERTY
INTERPROCEDURAL_OPTIMIZATION 1)
As you can see we have only Intel platform module.
So I have created feature request for this extremely useful feature: https://cmake.org/Bug/view.php?id=15939