CMake: how to use INTERFACE_INCLUDE_DIRECTORIES wi

2020-05-21 05:14发布

问题:

I'm trying to add external project as a library to my project using ExternalProject_Add:

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

Also, I'm defining library target and adding external project as a dependency:

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

in another CMakeLists.txt:

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

The problem is that cmake INTERFACE_INCLUDE_DIRECTORIES doesn't allow to export include dir which does not exist.

Is there any other way to make header files being included automatically for all targets which depend on libxgboost ?

UPDATE:

Error message:

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.

回答1:

I'll post the final CMakeLists.txt to include xgboost into your project, it might be useful for someone, the solution to the problem above is to create directories during cmake configure phase (NOTE: I'm using OSX to build that, so you would need to use liblibxgboost.so for GNU/Linux instead of 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}"
)


标签: cmake