CMake:如何将INTERFACE_INCLUDE_DIRECTORIES与ExternalProject一起使用?

Sta*_*tal 7 cmake

我正在尝试使用ExternalProject_Add将外部项目作为库添加到我的项目中:

ExternalProject_Add(
        xgboost
        GIT_REPOSITORY https://github.com/dmlc/xgboost.git
        GIT_TAG v0.60
        PREFIX ${CMAKE_CURRENT_BINARY_DIR}
        INSTALL_COMMAND ""
)
Run Code Online (Sandbox Code Playgroud)

另外,我正在定义库目标并将外部项目添加为依赖项:

set(XGBOOST_PREFIX_PATH "${CMAKE_CURRENT_BINARY_DIR}/src")
set(XGBOOST_BINARY_PATH "${XGBOOST_PREFIX_PATH}/xgboost-build")
set(XGBOOST_BINARY_INCLUDE "${XGBOOST_PREFIX_PATH}/xgboost/include;${XGBOOST_PREFIX_PATH}/xgboost/dmlc-core/include;${XGBOOST_PREFIX_PATH}/xgboost/rabit/include")
add_library(libxgboost IMPORTED STATIC GLOBAL)
add_dependencies(libxgboost xgboost)

set_target_properties(libxgboost PROPERTIES
        "IMPORTED_LOCATION" "${XGBOOST_BINARY_PATH}/liblibxgboost.dylib"
        "IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
        "INTERFACE_INCLUDE_DIRECTORIES" "${XGBOOST_BINARY_INCLUDE}"
        )
Run Code Online (Sandbox Code Playgroud)

在另一个CMakeLists.txt中:

add_library(somelib STATIC SomeLib.cpp)
target_include_directories(somelib PUBLIC libxgboost)
target_link_libraries(somelib libxgboost)
Run Code Online (Sandbox Code Playgroud)

问题是cmake INTERFACE_INCLUDE_DIRECTORIES不允许导出不存在的包含目录。

还有其他方法可以使所有依赖libxgboost的目标都自动包含头文件吗?

更新:

错误信息:

CMake Error in somelib/CMakeLists.txt:
  Imported target "libxgboost" includes non-existent path

    "build/xgboost/src/xgboost/include"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.
Run Code Online (Sandbox Code Playgroud)

Sta*_*tal 6

我将发布最终版本,CMakeLists.txt以将xgboost包含到您的项目中,这可能对某人有用。上述问题的解决方案是在cmake配置阶段创建目录(注意:我正在使用OSX来构建目录,因此您需要使用liblibxgboost.so的GNU / Linux的替代liblibxgboost.dylib):

include(ExternalProject)

ExternalProject_Add(
        xgboost
        GIT_REPOSITORY https://github.com/dmlc/xgboost.git
        GIT_TAG v0.60
        PREFIX ${CMAKE_CURRENT_BINARY_DIR}
        INSTALL_COMMAND ""
)

set(XGBOOST_PREFIX_PATH "${CMAKE_CURRENT_BINARY_DIR}/src")
set(XGBOOST_BINARY_PATH "${XGBOOST_PREFIX_PATH}/xgboost-build")

set(XGBOOST_LIB_INCLUDE "${XGBOOST_PREFIX_PATH}/xgboost/include")
set(DMLC_LIB_INCLUDE "${XGBOOST_PREFIX_PATH}/xgboost/dmlc-core/include")
set(RABIT_LIB_INCLUDE "${XGBOOST_PREFIX_PATH}/xgboost/rabit/include")
set(XGBOOST_BINARY_INCLUDE "${XGBOOST_LIB_INCLUDE};${DMLC_LIB_INCLUDE};${RABIT_LIB_INCLUDE}")

# Hack to make it work, otherwise INTERFACE_INCLUDE_DIRECTORIES will not be propagated
file(MAKE_DIRECTORY ${XGBOOST_LIB_INCLUDE})
file(MAKE_DIRECTORY ${DMLC_LIB_INCLUDE})
file(MAKE_DIRECTORY ${RABIT_LIB_INCLUDE})

add_library(libxgboost IMPORTED STATIC GLOBAL)
add_dependencies(libxgboost xgboost)

set_target_properties(libxgboost PROPERTIES
        "IMPORTED_LOCATION" "${XGBOOST_BINARY_PATH}/liblibxgboost.dylib"
        "INTERFACE_INCLUDE_DIRECTORIES" "${XGBOOST_BINARY_INCLUDE}"
)
Run Code Online (Sandbox Code Playgroud)

  • 我希望CMake能够更好地支持这一点。似乎有点hack。没有办法以某种方式处理依赖关系吗?例如,您可以设置不存在的库的IMPORTED_LOCATION。使INTERFACE_INCLUDE_DIRECTORIES不同似乎是不一致的。 (2认同)
  • @JeffTrull 我希望它以更好的方式支持它。但这是我找到的唯一方法,但并不意味着它是唯一存在的方法。我是 cmake 的新手,所以我可能会在这里遗漏一些东西。 (2认同)
  • FWIW,“file(MAKE_DIRECTORY ...)”也是人们在 CMake 错误跟踪器上提出的:https://gitlab.kitware.com/cmake/cmake/issues/15052 (2认同)