我尝试使用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.
答案 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)
请注意,可以结合使用 FetchContent
和 ExternalProject_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)