CMake能否根据下游依赖自动添加-ffat-lto-objects编译选项?
用CMake自动为库添加
-ffat-lto-objects的条件编译 针对你提到的大型项目中难以追踪哪些库需要生成fat LTO对象的问题,有两种实用的CMake解决方案,可根据项目需求选择:
方案一:全局条件编译(简单高效)
如果不想花费精力追踪链接依赖关系,可直接给所有启用LTO的库自动添加-ffat-lto-objects选项。fat LTO对象同时包含普通目标码和LTO中间码,兼容LTO和非LTO链接场景,唯一代价是编译时间略有增加,但省去了手动排查的麻烦。
在CMakeLists.txt中添加以下代码:
# 仅对启用LTO的目标添加-ffat-lto-objects编译选项 add_compile_options($<$<BOOL:$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION>>:-ffat-lto-objects>)
说明
- 该代码利用CMake的生成器表达式,自动判断目标是否启用了LTO(通过
INTERPROCEDURAL_OPTIMIZATION目标属性),满足条件则注入编译选项。 - 要求CMake 3.9+(支持
TARGET_PROPERTY生成器表达式),GCC 4.9+(支持-ffat-lto-objects)。
方案二:基于链接依赖的精准检测(编译更高效)
如果希望仅给确实被非LTO目标链接的库添加选项,可通过追踪目标间的链接关系实现。需要两步配置:
1. 记录链接依赖关系
替换项目中所有target_link_libraries为自定义函数,用于记录每个库被哪些目标链接:
function(my_target_link_libraries target) # 调用原生链接逻辑 target_link_libraries(${target} ${ARGN}) # 遍历链接的库,记录当前目标为其依赖者 foreach(lib IN LISTS ARGN) if(TARGET ${lib}) set_property(GLOBAL APPEND PROPERTY LINKED_BY_${lib} ${target}) endif() endforeach() endfunction()
2. 检测并添加条件编译选项
在所有目标定义完成后(比如所有add_subdirectory调用结束后),遍历所有库目标,检查是否有非LTO目标依赖它,若有则添加-ffat-lto-objects:
function(check_target_needs_fat_lto target) # 若目标本身未启用LTO,无需添加fat选项 get_target_property(target_lto ${target} INTERPROCEDURAL_OPTIMIZATION) if(NOT target_lto) return() endif() # 获取所有链接该库的目标 get_property(linking_targets GLOBAL PROPERTY LINKED_BY_${target}) foreach(linking_target IN LISTS linking_targets) # 检查依赖目标是否未启用LTO get_target_property(linking_lto ${linking_target} INTERPROCEDURAL_OPTIMIZATION) if(NOT linking_lto) target_compile_options(${target} PRIVATE -ffat-lto-objects) return() endif() endforeach() endfunction() # 遍历所有库目标执行检测 get_cmake_property(all_targets BUILDSYSTEM_TARGETS) foreach(target IN LISTS all_targets) get_target_property(target_type ${target} TYPE) if(target_type STREQUAL "STATIC_LIBRARY" OR target_type STREQUAL "SHARED_LIBRARY") check_target_needs_fat_lto(${target}) endif() endforeach()
说明
- 该方案仅给被非LTO目标链接的LTO库添加选项,编译时间更短,但需要修改项目中所有链接逻辑,依赖CMake 3.13+(支持
BUILDSYSTEM_TARGETS属性)。 - 若库被多个目标链接,只要其中一个是未启用LTO的,就会添加fat选项,确保兼容性。
内容的提问来源于stack exchange,提问作者NoSenseEtAl
相关产品推荐
相关产品推荐

