如何让CMake对象库继承主程序的编译链接配置?
CMake对象库继承主程序编译配置的解决方法
针对你遇到的对象库SEPFILE_OBJS无法继承主程序MY_PROGRAM编译配置的问题,给你几个不用重复写配置的实用方案:
方案一:用INTERFACE库统一管理公共配置
这是大型项目最规范的做法,能避免重复维护配置逻辑:
- 新建一个INTERFACE类型的库,专门存储主程序的公共编译配置(包含路径、编译选项、预定义宏等)
- 把主程序原来的
target_include_directories、target_compile_options等配置(包括带条件逻辑的部分)迁移或复制到这个INTERFACE库 - 让主程序和对象库都链接这个INTERFACE库,自动继承所有配置
示例代码:
# 创建存储公共配置的INTERFACE库 add_library(MY_PROGRAM_COMMON_CONFIG INTERFACE) # 复制主程序的包含路径 target_include_directories(MY_PROGRAM_COMMON_CONFIG INTERFACE ${PROJECT_SOURCE_DIR}/include # 替换成你主程序实际用到的包含路径,含条件判断的直接保留逻辑 ) # 复制主程序的编译选项 target_compile_options(MY_PROGRAM_COMMON_CONFIG INTERFACE -Wall -Wextra # 替换成你的编译选项,带条件的配置直接搬过来 ) # 复制预定义宏 target_compile_definitions(MY_PROGRAM_COMMON_CONFIG INTERFACE $<$<CONFIG:Debug>:DEBUG_MODE> # 带条件的宏定义同样保留原有逻辑 ) # 主程序链接配置库 target_link_libraries(MY_PROGRAM PRIVATE MY_PROGRAM_COMMON_CONFIG) # 对象库链接配置库,自动继承所有编译配置 target_link_libraries(SEPFILE_OBJS PRIVATE MY_PROGRAM_COMMON_CONFIG)
方案二:直接提取主程序配置属性到对象库
如果不想调整原有项目结构,可以用get_target_property提取主程序已有的配置,直接应用到对象库:
# 提取主程序的包含路径并添加到对象库 get_target_property(MY_PROGRAM_INCLUDES MY_PROGRAM INCLUDE_DIRECTORIES) if(MY_PROGRAM_INCLUDES) target_include_directories(SEPFILE_OBJS PRIVATE ${MY_PROGRAM_INCLUDES}) endif() # 提取编译选项 get_target_property(MY_PROGRAM_COMPILE_OPTS MY_PROGRAM COMPILE_OPTIONS) if(MY_PROGRAM_COMPILE_OPTS) target_compile_options(SEPFILE_OBJS PRIVATE ${MY_PROGRAM_COMPILE_OPTS}) endif() # 提取预定义宏 get_target_property(MY_PROGRAM_DEFINITIONS MY_PROGRAM COMPILE_DEFINITIONS) if(MY_PROGRAM_DEFINITIONS) target_compile_definitions(SEPFILE_OBJS PRIVATE ${MY_PROGRAM_DEFINITIONS}) endif()
注意:该方法仅能提取主程序通过target_*系列命令设置的属性,全局的include_directories等配置本来就会被对象库继承,无需额外处理。
方案三:利用CMake配置传递性(限CMake 3.19+)
如果主程序的编译配置都是用PUBLIC或INTERFACE关键字设置的,可以直接让对象库链接主程序,从而继承这些公共配置:
target_link_libraries(SEPFILE_OBJS PRIVATE MY_PROGRAM)
局限性:可执行文件的PRIVATE属性不会被传递,只有主程序用PUBLIC/INTERFACE设置的配置才会被对象库继承,适合配置简单的场景。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

