将依赖传播到基于头文件的ExternalProject,使用cmake。

4
我正在尝试使用CMake(Microsoft/GSL)构建一个仅包含头文件的库,以便我可以使用像GSL_INCLUDE_DIRSGSL_LIBRARIES这样的变量来链接到目标并传播适当的依赖关系。
我正在处理的项目有大量子目录,所有外部项目都在它们自己的子目录中构建,因此变量非常重要。
我正在使用CMake 3.2.3
通常情况下(对于实际具有.lib或.a的库),我会执行以下操作:
SET(TARGET_NAME gsl)

include(ExternalProject)
ExternalProject_Add(
    ${TARGET_NAME}-ext
    URL "http://target/url"
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND ""
)   # download/unzip the header-only project

# Specify include dir
SET(${TARGET_NAME}_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/include CACHE STRING "${TARGET_NAME} include directory")

# Library
add_library(${TARGET_NAME} SHARED IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES 
    IMPORTED_LOCATION "some/path/to/some/lib"
)
add_dependencies(${TARGET_NAME} ${TARGET_NAME}-ext)
SET(${TARGET_NAME}_LIBRARIES ${TARGET_NAME} CACHE STRING "${TARGET_NAME} library location")

MARK_AS_ADVANCED(${TARGET_NAME_UPPER}_DIR ${TARGET_NAME_UPPER}_INCLUDE_DIRS ${TARGET_NAME_UPPER}_LIBRARIES)

这里的问题是头文件库没有可以设置导入路径的库,因此我不能使用“IMPORTED”库。如果根本不使用库,则无法在其他模块中设置对GSL的依赖关系,而不需要每次都构建(即下载/解压缩),这是我不想做的。一个“custom_target”也会有同样的问题,所以这是行不通的。
我认为我想要的是一个接口库,类似于:
add_library(${TARGET_NAME} INTERFACE)
add_dependencies(${TARGET_NAME} ${TARGET_NAME}-ext)

但是CMake抱怨说

CMakeLists.txt的第33行出现错误(add_dependencies): add_dependencies不能将目标级别的依赖项添加到接口库 目标“gsl”。

有没有办法使用接口库(或其他东西)来传播对外部项目的依赖关系?


请澄清:“构建一个仅包含头文件的库”,因为它们不会构建为.lib、.so或.dll文件。直接使用它们或设置适当的包含路径。 - knivil
@knivil 我更新了问题标题,删除了“build”一词。话虽如此,我认为在问题中相对清楚地表明了我想使用cmake来下载/解压缩仅包含头文件的库,但是只有在依赖项需要时才调用外部项目。 - Nicolas Holthaus
导入库的错误信息看起来是虚假的。你的cmake版本是否真正支持INTERFACE库?TARGET_NAME的值是多少? - pmr
@pmr更新了问题,包括实际目标名称和完整的错误消息。这不是虚假的。我正在使用cmake版本3.2.3,据我所知,接口库是在3.0.0中引入的。 - Nicolas Holthaus
此外,我不清楚 add_dependencies 调用的目的是什么。INTERFACE 库不能有依赖关系,因为它本身无需执行任何操作。 - pmr
显示剩余3条评论
1个回答

8

禁止依赖于INTERFACE库是CMake 3.3版本中纠正的疏忽。升级到最新稳定版后,我能够使用问题描述中的方法,它完全符合预期。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接