45

我有最新的 cmake 构建并尝试所有构建配置(Debug、MinSizeRel、RelWithDebugInfo、Release、General)我在生成的 makefile 中看不到任何地方(文本搜索)字符串-lto,所以或者该功能仍然不存在,或者它需要手动转换(在这种情况下,文本搜索 LTO 或链接时间优化)在文档上没有给出任何结果,所以我在官方文档中看不到启用 LTO 的方法。

有没有办法在不指定手动标志的情况下“全局”启用 LTO(对于所有编译器),而这些标志在最坏的情况下只能由 GCC 支持?

4

4 回答 4

92

好消息!CMake v3.9终于支持 LTO了。


例子

这是一个示例代码来展示它是如何工作的:

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()

对于 GCC,这将添加-flto -fno-fat-lto-objects到目标编译命令。


检查编译器支持

模块CheckIPOSupported提供检查编译器是否支持过程间优化(IPO/ LT​​O) :

check_ipo_supported([RESULT <result>] [OUTPUT <output>]
                    [LANGUAGES <lang>...])

如果没有传递参数 (= check_ipo_supported()),则会引发错误以指示它不受支持,否则result变量设置为YESor 或NO。更多细节在模块的文档中描述。


启用 LTO

LTO 可以为单个目标启用,也可以默认为所有目标启用。

单个目标的 LTO

INTERPROCEDURAL_OPTIMIZATION为设置为的目标启用 LTO TRUE。这是通过以下set_property()命令完成的:

set_property(TARGET name-target-here
             PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

默认为 LTO

CMAKE_INTERPROCEDURAL_OPTIMIZATION可以通过设置为默认启用 LTO TRUE

set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)

这将为在此行之后INTERPROCEDURAL_OPTIMIZATION创建的所有目标启用。之前创建的不受影响。


也可以看看

于 2017-11-18T20:30:58.147 回答
15

编辑:截至 2015 年 10 月 28 日在 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     

相关 CMake 问题:https ://gitlab.kitware.com/cmake/cmake/issues/15245


CMakeINTERPROCEDURAL_OPTIMIZATION在目标上有属性,听起来它可能会在某些平台上启用 LTO。

链接:http ://www.cmake.org/cmake/help/v3.0/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.html

要在目标 MyLib 上启用它:

add_library(MyLib ...)
...
set_property(TARGET MyLib PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
于 2015-07-20T17:23:15.167 回答
1

是的,根据源代码,gcc/clang 编译器不支持 LTO。他们只支持英特尔编译器。

我有一些 cmake 3.4.3 的 grep 输出:

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)

如您所见,我们只有英特尔平台模块。

所以我为这个非常有用的功能创建了功能请求:https ://cmake.org/Bug/view.php?id=15939

于 2016-01-28T12:42:23.177 回答
-2

目前 gcc 和 clang 都支持 lto。(参见:https ://clang.llvm.org/docs/CommandGuide/clang.html https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html )您可以通过 cmake 启用它:set ( CMAKE_INTERPROCEDURAL_OPTIMIZATION True)但是您需要版本 cmake >= 3.9,我认为可能会设置一些策略并检查编译器/工具链是否支持 LTO(检查 CMAKE_IPO_AVAILABLE 否则抛出错误)

并为 gcc/clang 设置标志( -flto 和 -ffat-lto-files 用于 fcc >4.7 或 -flto=full/thin 用于 clang)

于 2020-02-27T12:56:07.747 回答