Find package Eigen3 for CMake
Asked Answered
P

13

39

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?

Presentable answered 3/9, 2012 at 13:48 Comment(0)
R
44

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.
Rachael answered 4/9, 2012 at 7:40 Comment(5)
Yes, this the answer I was looking for. The key is the $ENV, thanks man. I learned a lot with this post.Presentable
Missing closing parenthesis after MESSAGE( FATAL_ERROR "Please point the environment variable EIGEN3_INCLUDE_DIR to the include directory of your Eigen3 installation."Sleepless
What is the Eigen3 Include Directory?Retake
How to set EIGEN3_INCLUDE_DIR?Farmyard
If EIGEN3_INCLUDE_DIR is not defined in environment variables, the method will not workMiniskirt
U
30

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 to the environment variable CMAKE_PREFIX_PATH e.g in bash:

export CMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH:/opt/eigen/3.3"

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.

Uncalledfor answered 7/9, 2018 at 22:12 Comment(4)
That's the only answer here which is almost right... The only thing is that you need to prepend '/opt/eigen/3.3' to the CMAKE_PREFIX_PATH, and not a complete path to where cmake files are stored. This way you only need a single prefix path for all libs installed to some fake root path.Disqualify
@Disqualify I verified that this worked, and incorporated your feedback.Uncalledfor
Can I ask why one should not use include_directories ? Isn't Eigen a header only library?Eudemon
"Can I ask why one should not use include_directories ? Isn't Eigen a header only library?" It still has requirements such as C++11+ and may need to link to libm on certain platforms. However, I think you misunderstood the note about include_directories -- that changes global state, instead of a per-target state.Uncalledfor
D
11

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.)

Donahoe answered 2/4, 2015 at 23:21 Comment(5)
No, Eigen should install cmake config package files. cmake.org/cmake/help/v3.0/manual/…Zillion
It probably should, but it's not a full remedy. If Eigen wasn't installed, the error messages would be more cryptic, mostly revolving around CMake not being able to find the FindEigen3.cmake file itself. ...which might prompt you to include the file in your package anyway. Post edited.Donahoe
You're mixing up concepts. According to the doc I linked to (and wrote), Eigen would install EigenConfig.cmake, not FindEigen.cmake.Zillion
@steveire: Yes, I was a bit sloppy with the concepts. Regarding the inclusion of an Eigen module in CMake, this page makes it abundantly clear that CMake-based packages should provide their own package configuration files rather than a find module in CMake. Thanks for taking the time to get this right. Post edited.Donahoe
Also, using the CONFIG option with find_package for CMake-based packages (with package configuration files) makes the error message a bit more concise when no package is found.Donahoe
I
4

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

find_package(PkgConfig)
pkg_search_module(Eigen3 REQUIRED eigen3)
Innerdirected answered 22/11, 2015 at 0:29 Comment(0)
Q
4

As a detailed explanation of the note 7 from the top answer of Johannes. By using the "Config mode" rather than "Module mode" of CMake find_packate(), only writing

find_package( Eigen3 REQUIRED )
include_directories( EIGEN3_INCLUDE_DIR )

in CMakeLists.txt is enough.

Please refer to the INSTALL guidance text file contained in the eigen source code directory (eg. extracted from eigen-3.3.7.tar.gz downloaded from official website), which said:

Method 2. Installing using CMake
********************************

Let's call this directory 'source_dir' (where this INSTALL file is).
Before starting, create another directory which we will call 'build_dir'.

Do:

  cd build_dir
  cmake source_dir   
  make install

The "make install" step may require administrator privileges.

You can adjust the installation destination (the "prefix")
by passing the -DCMAKE_INSTALL_PREFIX=myprefix option to cmake, as is
explained in the message that cmake prints at the end.

Just like installing usual CMake projects to your machine.

The difference from directly including the /usr/include/eigne3 or /usr/local/include/eigen3 directory is that, a configuration directory called eigen3/cmake will also be installed to /usr/share or usr/local/share. This configuration directory contains the Eigen3Config.cmake file, which can automatically be found by CMake to locate the eigen3 directory.

Queue answered 1/1, 2020 at 11:46 Comment(0)
T
3

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})
Tenor answered 28/4, 2018 at 20:46 Comment(0)
D
2

Another simple way that doesn't require adding an environment variable is to simply find eigen with the cmake find_path function https://cmake.org/cmake/help/v3.6/command/find_path.html. The example code finds the directory "Eigen" in paths "/usr/include/" and "/usr/local/include" with an additional search in subdirectory "eigen3".

find_path(EIGEN3_INCLUDE_DIRS "Eigen" paths "/usr/include" "/usr/local/include" path_suffixes "eigen3")
message(${EIGEN3_INCLUDE_DIRS})
if ( NOT EIGEN3_INCLUDE_DIRS )
    message(FATAL_ERROR "CMake variable EIGEN3_INCLUDE_DIRS not found.")
endif()
include_directories ( "${EIGEN3_INCLUDE_DIRS}" )
Dysgenics answered 7/9, 2019 at 2:50 Comment(0)
C
1

You could try setting the CMAKE_MODULE_PATH to the location of Eigen subdirectory named "cmake":

cmake . -DCMAKE_MODULE_PATH=<Eigen root dir>/cmake/
Changteh answered 4/9, 2012 at 0:46 Comment(1)
And how can I write this in the cmakelists, instead of as a command line?Presentable
H
1

I had a similar problem when run cmake .. && make on Google Colab on a project clone from github. I fixed it by editing CMakeLists.txt file and adding this line to it:

set(EIGEN3_INCLUDE_DIR "/usr/include/eigen3")

As you can see, my eigen3 was in /usr/include/eigen3 path (and I had installed it using !sudo apt-get install build-essential cmake libeigen3-dev)

Hayleyhayloft answered 3/10, 2020 at 21:0 Comment(0)
D
1

This worked:

  • Changed c++11 to c++14
  • Changed find_package(Eigen3 QUIET) to find_package(Eigen3 CONFIG)
Dusen answered 11/4, 2022 at 13:25 Comment(0)
P
0

When installing on Kubuntu 20.04 following steps from INSTALL:

Do:

cd build_dir cmake source_dir make install

using -DCMAKE_INSTALL_PREFIX=/usr/local/eigen-3.4.0 and sudo FindEigen3.cmake is not installed. However, using

set(Eigen3_DIR "/usr/local/eigen/share/eigen3/cmake")

seem to work. FindEigen3.cmake is in the build directory but it is not copied to the installation directory tree.

Pliam answered 30/8, 2021 at 15:57 Comment(0)
M
-1

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})
Mourant answered 5/12, 2018 at 20:31 Comment(0)
M
-1

You need to read official documentation:

  • Click here
  • After install Eigen from tar and compile it correctly.
  • CMakeLists.txt will looks like this:
    find_package(Eigen3 3.3 REQUIRED NO_MODULE)
    add_executable(${PROJECT_NAME} something.cpp)
    target_link_libraries(${PROJECT_NAME} Eigen3::Eigen)

It will be fine work.

Muscadel answered 2/2, 2023 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.