Using Eigen Lib in my Cmake project?

2019-03-02 14:24发布

问题:

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)

回答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.



回答2:

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



回答3:

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;


标签: c++ cmake eigen