Find package Eigen3 for CMake

2019-01-17 21:29发布

CMake cannot find my Eigen3 package. I set an environment variable called

EIGEN3_INCLUDE_DIR

pointing to the path where FindEigen3.cmake is.

Then in the CMakelists.txt I wrote:

find_package( Eigen3 REQUIRED )
include_directories( EIGEN3_INCLUDE_DIR )

I get next message of error:

CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:91 (MESSAGE):
  Could NOT find Eigen3 (missing: EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
  (Required is at least version "2.91.0")
Call Stack (most recent call first):
  C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:252 (_FPHSA_FAILURE_MESSAGE)
  C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindEigen3.cmake:76 (find_package_handle_standard_args)
  test/test_quaternion/CMakeLists.txt:25 (find_package)

Any idea on what I am missing or doing wrong?

标签: cmake eigen
7条回答
2楼-- · 2019-01-17 22:09

First, make sure Eigen is properly installed. Refer to the INSTALL file that comes with the tarball.

Second, copy the cmake/FindEigen3.cmake file from the tarball to the directory containing your CMakeLists.txt.

In your CMakeLists.txt add:

set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})

Now you should be able to do e.g. #include <Eigen/Core>.

All of this comes (mostly) from this source.

This approach has the advantage over e.g. include_directories("$ENV{EIGEN3_INCLUDE_DIR}") that it the uses CMake's standard mechanism for finding external dependencies, making it easier for someone else (or your future self) to pick up the project, possibly on another platform.

(However, it would be nice if Eigen itself installed an EigenConfig.cmake file, making it accessible through the find_package mechanism without any extra paths.)

查看更多
家丑人穷心不美
3楼-- · 2019-01-17 22:14

Eigen >= 3.3 has direct CMake integration, so it seems yours isn't set up correctly.

Assume Eigen has been installed to /opt/eigen/3.3 with default settings. Append or prepend the the location /opt/eigen/3.3/share/eigen3/cmake to the environment variable CMAKE_PREFIX_PATH e.g in bash:

export CMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH:/opt/eigen/3.3/share/eigen3/cmake"

Then CMake should pick it up.


If you are writing your own CMakeLists.txt that uses Eigen I suggest using code like this:

find_package (Eigen3 3.3 REQUIRED)
add_executable (example example.cpp)
target_link_libraries (example Eigen3::Eigen)

You should not use include_directories since CMake 3 was released -- the targets approach should be preferred whenever available.

查看更多
可以哭但决不认输i
4楼-- · 2019-01-17 22:27

Another simple way is:

if the Eigen library is in /opt/eigen/3.3/Eigen

include_directories(/opt/eigen/3.3)

which is equivalent to what Jai suggested

set(EIGEN_DIR "/opt/eigen/3.3")
include_directories(${EIGEN_DIR})
查看更多
混吃等死
5楼-- · 2019-01-17 22:28

I found another solution here (which referred to here) which uses the pkg-config file :

find_package(PkgConfig)
pkg_search_module(Eigen3 REQUIRED eigen3)
查看更多
ら.Afraid
6楼-- · 2019-01-17 22:28

If you have not added Eigen Library to environment variable then do the following in CMakeLists.txt:

cmake_minimum_required(VERSION 3.9)
project(ProjectName)

set(CMAKE_CXX_STANDARD 11)

# set EIGEN_DIR variable to Eigen Library Path
set(EIGEN_DIR "C:\\Eigendir\\Eigen")

# include the directory
include_directories(${EIGEN_DIR})

add_executable(ProjectName main.cpp)

target_link_libraries(ProjectName ${EIGEN_DIR})
查看更多
在下西门庆
7楼-- · 2019-01-17 22:30

Since Eigen3 is completely header only, all you ever need is the path to the include directory. And this one, you are already defining manually anyway. So there is no real need for a FindEigen3.cmake or FIND_PACKAGE call.

Simply use

INCLUDE_DIRECTORIES ( "$ENV{EIGEN3_INCLUDE_DIR}" )

or

SET( EIGEN3_INCLUDE_DIR "$ENV{EIGEN3_INCLUDE_DIR}" )
IF( NOT EIGEN3_INCLUDE_DIR )
    MESSAGE( FATAL_ERROR "Please point the environment variable EIGEN3_INCLUDE_DIR to the include directory of your Eigen3 installation.")
ENDIF()
INCLUDE_DIRECTORIES ( "${EIGEN3_INCLUDE_DIR}" )

A few notes:

  1. If you want to access the content of a CMake variable, make sure to use ${...}
  2. $ENV{....} accesses environment variables.
  3. The second example will stop with an error if the environment variable is not set (and, thus, EIGEN3_INCLUDE_DIR cmake variable is empty)
  4. Be careful to use quotation marks around (evaluated) variables if they could contain whitespace. Otherwise, CMake will interpret it as a list.
  5. If you want to use custom find modules, make sure to either place them in you CMake installation or, as @Fraser pointed out above, make sure to point CMAKE_MODULE_PATH to the directory where it is. Not sure, but it could be that CMake checks the current directory as well automatically (where your CMakeLists.txt resides. Anyhow, setting EIGEN3_INCLUDE_DIR is totally unrelated to the location of FindEigen3.cmake
  6. However, it could be that your FindEigen3 script evaluates this variable to determine the location of your Eigen3 installation.
  7. Alternatively, self-built CMake-based projects often provide a <PackageName>Config.cmake. If you point a variable called <PackageName>_DIR to the directory containing this file, you can use FIND_PACKAGE( <PackageName> ...) as normal. See documentation of FIND_PACKAGE for details.
查看更多
登录 后发表回答