如何通过 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)

任意顺序:


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)

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)