LTO with LLVM and CMake
LTO with LLVM and CMake
我正在尝试在创建共享库的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运行其他步骤吗?
Clang 并启用 LTO 的正确方法是在编译和链接时对clang
命令行使用 -flto
标志。
此外,您需要在一个带有链接器的平台上工作,该链接器要么直接支持 LTO(通常是 Apple 的平台),要么具有 LLVM 链接器插件(Linux 使用黄金链接器,但我认为有些人已经获得了 BFD 链接器来支持链接器插件)。如果您使用的是链接器插件,则需要确保已安装 LLVM 并安装了该插件。如果是这样,Clang 将自动添加必要的链接器命令行选项,以便在与 -flto
链接时使用该插件,即使对于共享对象也是如此。
此外,LLVM项目正在开发一个新的链接器(LLD),它将在其支持的所有平台上开箱即用地支持LTO,但这还处于早期阶段。目前,我知道有人在Windows和Linux上测试其LTO支持,它似乎运行良好,但仍然缺少许多功能。
check_ipo_supported()
导致我在 CMake 3.9.1 上出现"未设置策略CMP0069"错误。
根据其帮助,CMake 高达 3.8 仅支持英特尔编译器的 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 ()
在 Cmake 3.9 及更高版本上启用(瘦)lto 应该很简单:
include(CheckIPOSupported)
check_ipo_supported()
set_target_properties(myProject PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
可以完成单个全局set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
设置,而不是每个项目set_target_properties
。
为了加快重新编译的速度,可以设置 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.so
的符号链接才能/usr/lib/llvm-4.0/lib/LLVMgold.so
。
- BoostPython and CMake
- Qt, cmake and qhelpgenerator
- Catch2 with CMake and Visual Studio
- clang-cl and CMAKE
- CMake and pugixml
- 如何在Visual Studio 2019中使用cmake项目进行"Edit and Continue"构建?
- CMake find_package and NO_SYSTEM_ENVIRONMENT_PATH
- 使用cmake and vs在Windows上的现有代码中生成DLL
- 在 CMake for Visual Studio 2010 中定义宏"disallow copy and assign"
- CMake link atlas and llapack
- QtCreator 4 and CMake parameters
- CMake for Tesseract and OpenCV
- LTO with LLVM and CMake
- CMake and wxWidgets 2.9.5
- CMake and Window .Lib Files
- C++ OpenGL Project Setup using GLEW, assimp, SDL2 and CMake
- CMake and MsVS-NuGet
- cmake and GenerateExportHeader
- CMake and Config/Modules find_package
- CMAKE and MKOCTFILE