24

我正在尝试在创建共享库的 CMake 项目上使用 LLVM 应用链接时间优化。我的问题和这个问题差不多:

使用 CMake 在 GCC 和 Clang/LLVM 之间切换

但是,答案似乎不再适用,因为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 运行其他步骤吗?

4

3 回答 3

18

使用 Clang 和启用 LTO 的正确方法是在编译链接时使用命令行的-flto标志。clang

此外,您将需要在具有直接支持 LTO(通常是 Apple 的平台)或具有 LLVM 链接器插件(使用 Gold 链接器的 Linux,但我认为有些已经获得 BFD 链接器支持)的链接器的平台上工作链接器插件也是如此)。如果您使用的是链接器插件,则需要确保您安装的 LLVM 已构建并安装了该插件。如果是这样,Clang 将自动添加必要的链接器命令行选项以在与 链接时使用插件-flto,即使对于共享对象也是如此。

此外,LLVM 项目正在开发一个新的链接器 (LLD),它将在它支持的所有平台上开箱即用地支持 LTO,但它仍处于早期阶段。目前我知道有人在 Windows 和 Linux 上测试它的 LTO 支持,它似乎运行良好,但仍然缺少许多功能。

于 2016-05-31T06:16:48.070 回答
3

check_ipo_supported()导致我在CMake 3.9.1 上出现“未设置策略 CMP0069 ”错误。

根据它的帮助,最高 3.8 的 CMake 仅支持英特尔编译器的 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")没有伤害。

根据您的链接器选择您的命令行选项。

更残酷的选择

根据@ChandlerCarruth 的回答:

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
    target_link_libraries(Foobar -flto)
endif ()
于 2017-10-27T00:35:32.470 回答
2

在 Cmake 3.9 和更高版本上启用(瘦)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.soto的符号链接/usr/lib/llvm-4.0/lib/LLVMgold.so

于 2017-07-31T19:38:47.850 回答