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.
Note that it is possible to combine FetchContent
and ExternalProject_Add
to achieve the following:
FetchContent
will make the source available at configure time, thereby bypassing the issue that the INTERFACE_INCLUDE_DIRECTORIES
doesn't exist.ExternalProject_Add
will use the source downloaded by FetchContent
to build at build time
Here is an example building 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)
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}"
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With