Using Eigen Lib in my Cmake project?
Asked Answered
S

3

1

I am having difficulty using a header-only library (Eigen) in my CMake project. When i take off all the portion related to Eigen library it compiles, but not sure how to build with (Eigen). Note that Eigen has a CmakeLists.txt in Eigen folder, and it has /src folder having (*.h and *.cpp) related to Matrix operation etc...

The structure of my program is as follow

Myproject (folder) is composed of :

  • CmakeLists.txt
  • /Build
  • /Source

The Source folder has bunch of my files (*.h and *.cpp) and the /Eigen (folder).

what i did is :

FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
LIST(APPEND CMAKE_CXX_FLAGS 
    "-std=c++0x
     -pthread 
     ${CMAKE_CXX_FLAGS} 
     -g 
    -Wall -Wextra ")

ADD_LIBRARY(Eigen ${CMAKE_SOURCE_DIR}/Eigen)
TARGET_INCLUDE_DIRECTORIES(Eigen INTERFACE
 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
 $<INSTALL_INTERFACE:include/Eigen>
)

INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
ADD_DEFINITIONS(${GTK3_CFLAGS_OTHERS})
INCLUDE_DIRECTORIES(include)
ADD_LIBRARY(RTT 
        Def.cpp 
        Def.h       
        krnel.cpp 
        krnel.h 
        Mesh.cpp 
        Mesh.h 
        Mcom.cpp 
        Mcom.h 
        timer.h 
        Identifier.h)       

ADD_EXECUTABLE(Rdrtst main.cpp)
TARGET_LINK_LIBRARIES(Rdrtst RTT ${GTK3_LIBRARIES} Eigen)

When i cd to /Build and type (Cmake ../Source )

I get the following :

[/../Build]$ cmake ../Source
-- Configuring done
CMake Error: Cannot determine link language for target "Eigen".
CMake Error: CMake can not determine linker language for target:Eigen
-- Generating done
-- Build files have been written to: /../../MyProject/Build

The eigen folder has the CMakeLists.txt with the following content :

include(RegexUtils)
test_escape_string_as_regex()

file(GLOB Eigen_directory_files "*")

escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

foreach(f ${Eigen_directory_files})
  if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/src")
    list(APPEND Eigen_directory_files_to_install ${f})
  endif()
endforeach(f ${Eigen_directory_files})

install(FILES
  ${Eigen_directory_files_to_install}
  DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
  )

add_subdirectory(src)
Sleigh answered 1/2, 2015 at 19:51 Comment(0)
E
1

You are trying to include Eigen as a compiled library. However, as you have stated, Eigen is really a header only library and does not need to be compiled, just included. There should be no .cpp files at all.

Remove the line

ADD_LIBRARY(Eigen ${CMAKE_SOURCE_DIR}/Eigen)

as that is meant for static or shared libraries. Now that you're not building Eigen, you can remove the line

TARGET_INCLUDE_DIRECTORIES(Eigen ...

The Eigen CMakeLists file really just copies the Eigen header files to an include directory and doesn't compile anything. See this link for an example of how to use Eigen with CMake.

Enfeoff answered 2/2, 2015 at 9:37 Comment(14)
I did exactly what's instructed in the link, but Cmake output (cmake .. in the build folder) says "Could not find a package configuration file provided by Eigen" . When i downloaded from the Eigen websites the library, i used only the Eigen folder of the unzipped downloaded folder in my Source directory, i used a file FindEigen.cmake and copied it in a cmake folder that i created under the Source folder (the same folder having the Eigen folder). Obviously i'm missing somethingSleigh
Can somebody rescue with this ?Sleigh
@SamGomari Less verbose than what I said, but essentially the same. Stop trying to build Eigen. It just needs to be included. Make sure it's in one of the include paths.Enfeoff
say Eigen folder (has /src folder) which is included in my /Source folder, i did this , it didn't work INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/Eigen)Sleigh
: Should i delete the CMakeLists.txt file that's in the Eigen folderSleigh
@SamGomari You have a line like #included "Eigen/Core" which in turn includes files in the /src directory. Don't place the /src in your /Source, place the entire Eigen directory.Enfeoff
Sounds good , appreciated... but while Cmake doesn't complain, make does , it complains with the following error: Build files have been written to: /home/rgn/Documents/Backup/ps/ral/Build Source/CMakeFiles/RTT.dir/flags.make:6: *** recipe commences before first target. Stop. make[1]: *** [Source/CMakeFiles/RTT.dir/all] Error 2 make: *** [all] Error 2Sleigh
@SamGomari Try looking at the error messages make can give. These questions might also be of help.Enfeoff
the make is generated by Cmake, and it doesn't look it has issues. However, the make itself contains some unfamiliar (far from being an expert in make) code for compilation. BTW, to include Eigen , i used NCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/Eigen) , is this correct ?Sleigh
@SamGomari I'm not quite sure what your project looks like, so my only recommendation is to start with a 'Hello world' example before using (C)make. Try the one on the Eigen site. Note that here the -I /path/to/eigen/ should be something like -I /sourcePath/ and not -I /sourcePath/Eigen.Enfeoff
@ AviGinsburg i only found a fix around it, but not the solution, what did for fix, is copy the Eigen folder to /usr/local/include ....then cmake works (out source build). But what i wanted to do is use the Eigen folder (that has all *.h and resides in /Source) instead of it "like installed" . Can you help with this , pls ?Sleigh
@SamGomari Did you ever add INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) to your cmake file?Enfeoff
@ AviGinsburg , i removed the Eigen folder from /usr/local/include and added the INCLUDE_DIRECTORIES($(CMAKE_SOURCE_DIR}) to the CMakeLists.txt in the /Source folder. But it didn't work.... ?????Sleigh
@SamGomari After trying it myself (and reading this answer), I found the issue to be: INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) should be replaced with INCLUDE_DIRECTORIES("./"). Kind of annoying. Let me know if that worked.Enfeoff
H
1

You just need the correct path in INCLUDE_DIRECTORIES (also make sure to include the correct folder or subfolder, depending if in your c++ file you are using #include Eigen/something.h or #include something.h ) So, remove the lines ADD_LIBRARY(Eigen ... and TARGET_LINK_LIBRARIES Eigen.

For troubleshooting, you can also include the absolute path of the Eigen folder , and then when you get it working, transform it in a relative path

Holusbolus answered 19/2, 2015 at 23:3 Comment(0)
S
0

This is a late answer, but it might help someone else. These are the precise steps I took in order to include the Eigen lib into my project with CMake files.

First, assuming your project already include the Eigen sub-directory, e.g., at src/third_party/eigen, copy-paste FindEigen3.cmake file into src/cmake.

Second, you might want to edit the FindEigen3.cmake to include your own location hints that you will provide from you CMake file. For example:

find_path( EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
    HINTS "${EIGEN3_ROOT}" "$ENV{EIGEN3_ROOT_DIR}" "${EIGEN3_INCLUDE_DIR_HINTS}"
    # ... leave the rest as it is
)

Third, "include" the Eigen from your CMakeLists.txt by specifying the hint EIGEN3_ROOT and the location of the FindEigen3.cmake file:

message(STATUS "Trying to include Eigen library")
set(EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package(Eigen3 3.2.0 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
message(STATUS "EIGEN: " ${EIGEN3_VERSION} " (internal)")

Forth, start using Eigen from within your project:

#include <Eigen/Dense>
using Eigen::MatrixXd;
// ...
MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
std::cout << m << std::endl;
Somniferous answered 3/1, 2017 at 17:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.