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

时间:2017-08-04 22:15:27

标签: 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 ""
)

此外,我定义了库目标并将外部项目添加为依赖项:

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}"
        )

在另一个CMakeLists.txt中:

add_library(somelib STATIC SomeLib.cpp)
target_include_directories(somelib PUBLIC libxgboost)
target_link_libraries(somelib libxgboost)

问题是cmake INTERFACE_INCLUDE_DIRECTORIES不允许导出包括不存在的dir。

是否还有其他方法可以自动包含依赖于 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.

2 个答案:

答案 0 :(得分:3)

我发布最终CMakeLists.txt以将xgboost包含到您的项目中,它可能对某人有用,上述问题的解决方案是在cmake配置阶段创建目录(注意:我使用OSX来构建它,所以你需要使用liblibxgboost.so代替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}" ) }:

coords = item[0]

答案 1 :(得分:0)

请注意,可以结合使用 FetchContentExternalProject_Add 来实现以下目的:

  • FetchContent 将在配置时提供源代码,从而绕过 INTERFACE_INCLUDE_DIRECTORIES 不存在的问题。
  • ExternalProject_Add 将在构建时
  • 使用FetchContent下载的源代码进行构建

以下是构建 libpqxx 的示例:

include(FetchContent)
include(ExternalProject)

find_package(PostgreSQL)

# Using FetchContent means we will download libpqxx at configure-time

FetchContent_Declare(libpqxx_ext
    GIT_REPOSITORY
        https://github.com/jtv/libpqxx
    GIT_TAG
        tags/7.4.1
    )

FetchContent_GetProperties(libpqxx_ext)

if(NOT libpqxx_ext_POPULATED)
  FetchContent_Populate(libpqxx_ext)
endif()

set(LIB_PQXX_SRC_DIR ${CMAKE_BINARY_DIR}/_deps/libpqxx_ext-src)

# Build libpqxx

ExternalProject_Add(libpqxx_ext
    SOURCE_DIR
        ${libpqxx_ext_SOURCE_DIR}
    PREFIX
        ext
    BINARY_DIR
        build
    CMAKE_ARGS
        -DSKIP_BUILD_TEST=on
    INSTALL_COMMAND
        ""
    BUILD_ALWAYS
        OFF
    )

set(LIB_PQXX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/build/src)

# Make the libpxqq artifacts available to our project

add_library(libpqxx STATIC IMPORTED GLOBAL)

set_target_properties(libpqxx
    PROPERTIES

    INTERFACE_INCLUDE_DIRECTORIES
        ${LIB_PQXX_SRC_DIR}/include
    IMPORTED_LOCATION
        ${LIB_PQXX_BUILD_DIR}/libpqxx.a
    INTERFACE_LINK_LIBRARIES
        ${PostgreSQL_LIBRARIES})

add_dependencies(libpqxx libpqxx_ext)