如何将CMake变量设置为目标的URL?树内外构建依赖问题问询
解决树外CMake项目依赖未构建完成的树内库的变量配置问题
没问题,这种场景下确实有几个实用的方案可以帮你把CMake变量关联到树内目标的输出信息,不用等库构建完成。下面是具体的实现方法:
1. 用生成器表达式直接关联目标属性
生成器表达式是CMake在生成构建系统阶段求值的,而非配置阶段,所以哪怕树内的库还没开始构建,也能正确获取到目标的输出路径、包含目录等信息。
假设你的树内库目标名为mylib,可以在树外项目里这样设置变量:
# 获取库文件的完整路径(自动适配平台和构建类型) set(MYLIB_LIBRARY $<TARGET_FILE:mylib>) # 获取库的接口包含目录 set(MYLIB_INCLUDE_DIR $<TARGET_PROPERTY:mylib,INTERFACE_INCLUDE_DIRECTORIES>)
这些变量会在生成Makefile或VS工程时自动替换为实际的路径,完全不需要提前构建库,而且能适配Debug/Release、Windows/Unix等不同环境的差异。
2. 导出树内目标的配置文件,树外项目通过find_package导入
如果你的项目需要长期维护,这种方法更规范,也更灵活。
首先在树内库的CMakeLists.txt中添加导出配置的代码:
# 安装目标并导出配置 install(TARGETS mylib EXPORT MyLibConfig LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin INCLUDES DESTINATION include) # 导出配置文件到指定目录 install(EXPORT MyLibConfig DESTINATION cmake)
之后树外项目只需要通过find_package导入目标,再从目标属性提取变量即可:
find_package(MyLib REQUIRED) # 从导入的目标提取变量 set(MYLIB_LIBRARY $<TARGET_FILE:MyLib::mylib>) set(MYLIB_INCLUDE_DIR $<TARGET_PROPERTY:MyLib::mylib,INTERFACE_INCLUDE_DIRECTORIES>)
这种方法不仅能解决变量依赖的问题,还能自动处理库的依赖传递、构建类型匹配等细节,是CMake推荐的跨项目依赖方式。
3. 手动指定预期路径(应急方案,不推荐)
如果上面两种方法暂时无法使用,你也可以手动硬编码库的预期输出路径,但这种方法灵活性差,容易出错,仅适合临时测试:
# 示例:Unix系统Debug构建的路径 set(MYLIB_LIBRARY ${CMAKE_SOURCE_DIR}/path/to/mylib/build/Debug/libmylib.so) # 示例:Windows系统Release构建的路径 # set(MYLIB_LIBRARY ${CMAKE_SOURCE_DIR}/path/to/mylib/build/Release/mylib.lib) # 手动指定包含目录 set(MYLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/path/to/mylib/include)
注意:这种方法需要你手动同步树内库的构建路径、构建类型,一旦树内项目的输出位置变更,树外项目的变量也需要手动修改,维护成本很高。
额外注意事项
- 确保树内和树外项目使用相同的构建类型(比如都是Debug或都是Release),否则生成的库路径可能不匹配;
- 生成器表达式需要CMake 2.8.12及以上版本支持,如果你使用的是旧版本,可能需要升级CMake。
内容的提问来源于stack exchange,提问作者Abruzzo Forte e Gentile
相关产品推荐
相关产品推荐

