CMake如何处理依赖项资源文件?适配CMake3.16及以上版本方案问询
CMake资源依赖自动传播解决方案
以下方案优先适配CMake 3.16版本,同时提供高版本优化方案。
核心前提说明
CMake 3.16原生没有内置的资源文件自动传播机制,RESOURCE属性仅作用于当前目标的安装逻辑,不会自动传递给依赖该目标的上层项目。目前最轻量的实现方案不需要完整编写自定义Config.cmake,仅需要给静态库A新增一行自定义属性配置即可。
适配CMake 3.16的实现方案
第一步:修改静态库A的配置
在你现有A的CMakeLists.txt配置基础上,新增一行代码,将资源列表挂载到A的自定义目标属性上,该属性会被CMake的导出机制自动携带,无需手动配置导出变量:
# 新增这一行即可,其他现有配置保持不变 set_target_properties(A PROPERTIES A_RESOURCES "${A_RESOURCE_FILES}")
问题1:构建项目B时自动复制A的资源到B的构建目录
在项目B的CMakeLists.txt中,引入依赖A之后,添加如下构建后复制逻辑:
# 获取依赖A的资源列表 get_target_property(A_RESOURCE_LIST A A_RESOURCES) # 遍历资源文件逐一复制到B的构建输出目录下的resources文件夹 foreach(RES_FILE ${A_RESOURCE_LIST}) add_custom_command(TARGET B POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${RES_FILE}" "$<TARGET_FILE_DIR:B>/resources/$<PATH:GET_FILENAME,${RES_FILE}>" COMMENT "Copying dependency resource ${RES_FILE} to B build directory" ) endforeach()
如果有多个依赖需要相同处理,可以把上述逻辑封装为通用CMake函数,传入目标名和依赖名即可复用,无需重复编写代码。
问题2:安装项目B时自动归集所有依赖资源到B的安装目录
在项目B的安装规则部分,新增资源安装逻辑即可:
# 获取依赖A的资源列表 get_target_property(A_RESOURCE_LIST A A_RESOURCES) # 安装A的资源到B的安装路径下的resources目录,路径规则和你现有配置保持一致 install(FILES ${A_RESOURCE_LIST} DESTINATION "${CMAKE_INSTALL_BINDIR}/${PLATFORM_ID}/$<CONFIG>/resources" )
CMake 3.21+ 优化方案
如果后续可以升级CMake版本到3.21及以上,无需给A添加任何自定义属性,直接使用内置的$<TARGET_RESOURCE_FILES>生成器表达式即可获取目标的RESOURCE属性对应文件列表,代码更加简洁:
构建时复制逻辑
add_custom_command(TARGET B POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RESOURCE_FILES:A> "$<TARGET_FILE_DIR:B>/resources/" )
安装时复制逻辑
install(FILES $<TARGET_RESOURCE_FILES:A> DESTINATION "${CMAKE_INSTALL_BINDIR}/${PLATFORM_ID}/$<CONFIG>/resources" )
内容的提问来源于stack exchange,提问作者Bert
相关产品推荐
相关产品推荐

