如何通过 FetchContent 将 Eigen 库添加到 cmake C++ 项目
How to add Eigen library to a cmake c++ project via FetchContent
通过
添加本征
FetchContent_Declare(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.3.9
)
FetchContent_GetProperties(eigen)
if(NOT eigen_POPULATED)
FetchContent_Populate(eigen)
add_subdirectory(${eigen_SOURCE_DIR} ${eigen_BINARY_DIR})
endif()
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
给我错误
CMake Error at o/b/x64-Debug/_deps/eigen-build/Eigen3Config.cmake:20 (include):
The file
D:/XXX/o/b/x64-Debug/_deps/eigen-build/Eigen3Targets.cmake
was generated by the export() command. It may not be used as the argument
to the include() command. Use ALIAS targets instead to refer to targets by
alternative names. D:\XXX\o/b/x64-Debug/_deps/eigen-build/Eigen3Config.cmake 20
但是手动下载 Eigen 并添加它工作正常
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/eigen")
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
有什么想法吗?
好吧,我放弃了 FetchContent,我也尝试了这个 Local install Eigen in CMAKE not finding target 但这对我也不起作用。
我现在使用 ExternalProject (https://github.com/qulacs/qulacs/blob/master/CMakeLists.txt) 来获取和链接特征值
include(ExternalProject)
set(EIGEN_BUILD_DIR ${CMAKE_BINARY_DIR}/eigen)
set(EIGEN_INSTALL_DIR ${CMAKE_SOURCE_DIR}/include/eigen3)
set(EIGEN_INCLUDE_DIR ${EIGEN_INSTALL_DIR})
ExternalProject_Add(
eigen
URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz
PREFIX ${EIGEN_BUILD_DIR}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND
${CMAKE_COMMAND} -E copy_directory ${EIGEN_BUILD_DIR}/src/eigen/Eigen ${EIGEN_INCLUDE_DIR}/Eigen
&& ${CMAKE_COMMAND} -E copy_directory ${EIGEN_BUILD_DIR}/src/eigen/unsupported ${EIGEN_INCLUDE_DIR}/unsupported
TEST_COMMAND ""
)
include_directories(SYSTEM ${EIGEN_INCLUDE_DIR})
另外add_dependencies必须使用
add_executable(test1 "test1.cpp")
add_dependencies(test1 eigen)
任意顺序:
Eigen 仅提供 ALIAS
master 上的目标
参考:https://gitlab.com/libeigen/eigen/-/commit/cf0b5b0344a3bfcf410e95bf22289015a2daf34b#9a2aa4db38d3115ed60da621e012c0efc0172aae_671_599
FetchContent 用法可能是
include(FetchContent)
FetchContent_Declare(
Eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG master
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
set(EIGEN_BUILD_DOC OFF)
# note: To disable eigen tests,
# you should put this code in a add_subdirectory to avoid to change
# BUILD_TESTING for your own project too since variables are directory
# scoped
set(BUILD_TESTING OFF)
set(EIGEN_BUILD_PKGCONFIG OFF)
set( OFF)
FetchContent_MakeAvailable(Eigen)
...
target_link_libraries(YourTarget PRIVATE Eigen3::Eigen)
- 对于
find_package()
和FetchContent()/add_subdirectory()
请看
https://gitlab.kitware.com/cmake/cmake/-/issues/17735
Fetchcontent 很棒,但它有一个副作用,即您的工作区因依赖项的所有目标而变得杂乱无章。如果您不喜欢这样,那么 ExternalProject_Add
似乎是一个合理的解决方案。在您的情况下,以下应该有效:
include(ExternalProject)
set(EIGEN_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eigen-install/")
ExternalProject_Add(
eigen
URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eigen-src"
BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eigen-build"
INSTALL_DIR "${EIGEN_INSTALL_DIR}"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=Release
)
file(MAKE_DIRECTORY ${EIGEN_INSTALL_DIR}/include) # avoid race condition
add_library(eigenlib INTERFACE IMPORTED GLOBAL)
add_dependencies(eigenlib eigen)
target_compile_features(eigenlib INTERFACE cxx_std_14)
set_target_properties(eigenlib PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${EIGEN_INSTALL_DIR}/include/eigen3
)
请注意,依赖项已 link 编辑到接口库 eigenlib
,您可以随后 link 到您自己的目标,如下所示:
add_library(linalg INTERFACE)
target_include_directories(linalg
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_link_libraries(linalg INTERFACE eigenlib)
通过
添加本征FetchContent_Declare(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.3.9
)
FetchContent_GetProperties(eigen)
if(NOT eigen_POPULATED)
FetchContent_Populate(eigen)
add_subdirectory(${eigen_SOURCE_DIR} ${eigen_BINARY_DIR})
endif()
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
给我错误
CMake Error at o/b/x64-Debug/_deps/eigen-build/Eigen3Config.cmake:20 (include):
The file
D:/XXX/o/b/x64-Debug/_deps/eigen-build/Eigen3Targets.cmake
was generated by the export() command. It may not be used as the argument
to the include() command. Use ALIAS targets instead to refer to targets by
alternative names. D:\XXX\o/b/x64-Debug/_deps/eigen-build/Eigen3Config.cmake 20
但是手动下载 Eigen 并添加它工作正常
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/eigen")
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
有什么想法吗?
好吧,我放弃了 FetchContent,我也尝试了这个 Local install Eigen in CMAKE not finding target 但这对我也不起作用。
我现在使用 ExternalProject (https://github.com/qulacs/qulacs/blob/master/CMakeLists.txt) 来获取和链接特征值
include(ExternalProject)
set(EIGEN_BUILD_DIR ${CMAKE_BINARY_DIR}/eigen)
set(EIGEN_INSTALL_DIR ${CMAKE_SOURCE_DIR}/include/eigen3)
set(EIGEN_INCLUDE_DIR ${EIGEN_INSTALL_DIR})
ExternalProject_Add(
eigen
URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz
PREFIX ${EIGEN_BUILD_DIR}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND
${CMAKE_COMMAND} -E copy_directory ${EIGEN_BUILD_DIR}/src/eigen/Eigen ${EIGEN_INCLUDE_DIR}/Eigen
&& ${CMAKE_COMMAND} -E copy_directory ${EIGEN_BUILD_DIR}/src/eigen/unsupported ${EIGEN_INCLUDE_DIR}/unsupported
TEST_COMMAND ""
)
include_directories(SYSTEM ${EIGEN_INCLUDE_DIR})
另外add_dependencies必须使用
add_executable(test1 "test1.cpp")
add_dependencies(test1 eigen)
任意顺序:
Eigen 仅提供
ALIAS
master 上的目标
参考:https://gitlab.com/libeigen/eigen/-/commit/cf0b5b0344a3bfcf410e95bf22289015a2daf34b#9a2aa4db38d3115ed60da621e012c0efc0172aae_671_599FetchContent 用法可能是
include(FetchContent)
FetchContent_Declare(
Eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG master
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
set(EIGEN_BUILD_DOC OFF)
# note: To disable eigen tests,
# you should put this code in a add_subdirectory to avoid to change
# BUILD_TESTING for your own project too since variables are directory
# scoped
set(BUILD_TESTING OFF)
set(EIGEN_BUILD_PKGCONFIG OFF)
set( OFF)
FetchContent_MakeAvailable(Eigen)
...
target_link_libraries(YourTarget PRIVATE Eigen3::Eigen)
- 对于
find_package()
和FetchContent()/add_subdirectory()
请看 https://gitlab.kitware.com/cmake/cmake/-/issues/17735
Fetchcontent 很棒,但它有一个副作用,即您的工作区因依赖项的所有目标而变得杂乱无章。如果您不喜欢这样,那么 ExternalProject_Add
似乎是一个合理的解决方案。在您的情况下,以下应该有效:
include(ExternalProject)
set(EIGEN_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eigen-install/")
ExternalProject_Add(
eigen
URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eigen-src"
BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eigen-build"
INSTALL_DIR "${EIGEN_INSTALL_DIR}"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=Release
)
file(MAKE_DIRECTORY ${EIGEN_INSTALL_DIR}/include) # avoid race condition
add_library(eigenlib INTERFACE IMPORTED GLOBAL)
add_dependencies(eigenlib eigen)
target_compile_features(eigenlib INTERFACE cxx_std_14)
set_target_properties(eigenlib PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${EIGEN_INSTALL_DIR}/include/eigen3
)
请注意,依赖项已 link 编辑到接口库 eigenlib
,您可以随后 link 到您自己的目标,如下所示:
add_library(linalg INTERFACE)
target_include_directories(linalg
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_link_libraries(linalg INTERFACE eigenlib)