现代CMake将add_compile_definitions替换为target_compile_definitions方案咨询
方案说明
不需要为每个模块重复添加判断逻辑,利用CMake的目标属性传递机制即可实现宏定义的统一管理和自动传递,推荐两种常用的最优方案:
方案1:使用全局接口配置目标统一管理(适合多目标共享的编译配置场景)
你可以创建一个仅用于传递编译属性的INTERFACE类型接口库,所有需要对应宏的目标只要链接这个接口库就能自动继承配置,仅需修改一处即可全局生效:
- 在根目录
CMakeLists.txt中定义接口配置目标:
# 创建无源码的接口库,仅用于传递编译属性 add_library(build_config INTERFACE) # 把原有的条件判断逻辑迁移到这个接口目标上 if(你的判断条件_A) target_compile_definitions(build_config INTERFACE SOME_TARGET_A_SPECIFIC_DEFINE) elseif(你的判断条件_B) target_compile_definitions(build_config INTERFACE SOME_TARGET_B_SPECIFIC_DEFINE) endif()
- 在所有需要该宏的目标的
CMakeLists.txt中链接这个接口库即可,比如:
# modules/SomeModule/CMakeLists.txt 中添加 target_link_libraries("${module_name}" PRIVATE build_config) # app/TargetA/CMakeLists.txt 中添加 target_link_libraries(TargetA PRIVATE build_config)
方案2:利用目标属性的传递性(适合宏属于特定目标、需要传递给依赖库的场景)
如果宏是目标专属的,只需在定义目标的编译定义时使用PUBLIC/INTERFACE修饰符,所有依赖该目标的库会自动继承对应的宏定义:
# app/TargetA/CMakeLists.txt 中定义目标时使用PUBLIC修饰 add_executable(TargetA ${TARGET_A_SRC}) target_compile_definitions(TargetA PUBLIC SOME_TARGET_A_SPECIFIC_DEFINE) # modules/SomeModule 只要链接了TargetA,就会自动拿到上面的宏定义,无需额外配置 target_link_libraries("${module_name}" PRIVATE TargetA)
三个修饰符的作用区别:
PRIVATE:编译定义仅对当前目标生效,不会传递给依赖当前目标的其他目标INTERFACE:编译定义仅传递给依赖当前目标的其他目标,当前目标自身不使用PUBLIC:编译定义对当前目标生效,同时传递给所有依赖当前目标的其他目标
内容的提问来源于stack exchange,提问作者user8694474
相关产品推荐
相关产品推荐

