Search code examples
c++linuxwindowscmakeeigen3

Error with Eigen in cross-platform project


I'm developing a dynamic library that will be linked on both Windows and Linux softwares. In order to simplify the build operation I decided to use cmake.

The library has the following structure:

MyProject
└ Subproject_1
| └ ...
| └ CMakeLists.txt
└ Subproject_2
| └ ...
| └ CMakeLists.txt
└ ...
└ CMakeLists.txt

In the Subproject_1 I used Eigen 3.3 (I downloaded the latest release) and OpenCV 3.3.0.

The main CMakeLists file is this

cmake_minimum_required (VERSION 2.8)
SET(CMAKE_CXX_STANDARD 11)
project (MyProject)

## Output directory configuration
SET(out_dir ./)
SET(EXECUTABLE_OUTPUT_PATH ${out_dir}../lib/ CACHE PATH "Build directory" FORCE)
SET(LIBRARY_OUTPUT_PATH ${out_dir}../lib/ CACHE PATH "Build directory" FORCE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${out_dir}../lib)
SET(CMAKE_BUILD_FILES_DIRECTORY ${out_dir})
SET(CMAKE_BUILD_DIRECTORY ${out_dir})
SET(CMAKE_BINARY_DIR  ${out_dir})
SET(CMAKE_CACHEFILE_DIR ${out_dir})

SET(opencv_path "")
if (WIN32 OR MSVC OR MSYS OR MINGW)
  SET(opencv_path "../opencv-3.3.0/build64/")
endif()
message("Setted OpenCV path to '" ${opencv_path} "'")

find_package(OpenCV REQUIRED PATHS ${opencv_path}
    opencv_core opencv_features2d opencv_flann opencv_highgui opencv_imgcodecs opencv_imgproc opencv_photo opencv_plot opencv_xfeatures2d opencv_ml opencv_video
)

# Additional dependencies
include_directories(
  ${OPENCV_INCLUDE_DIRS}
  "../eigen/"
  "Subprojects_1/include"
  "Subprojects/include"
)

## Subprojects
add_subdirectory ("Subproject_1")
add_subdirectory ("Subproject_2")

while the Subproject_1 CMakeLists file is

cmake_minimum_required (VERSION 2.8)
project(Subproject_1)

file (GLOB core_file "include/*.h" "src/*.cpp")
add_library(library SHARED ${core_file})
target_link_libraries(library 
  ${OpenCV_LIBRARIES}
)

Now, when I compile the project on Windows all work properly, but if I try to compile it on Ubuntu 16.04 LTS I have this errors:

... error: cannot declare reference to ‘Eigen::MatrixXi& {aka class Eigen::Matrix<int, -1, -1>&}’, which is not a typedef or a template type argument
   static void bitwiseAND(const Eigen::MatrixXi& m1, const Eigen::MatrixXi& m2, Eigen::MatrixXi& and);
                                                                                                 ^

... error: cannot declare reference to ‘Eigen::MatrixXi& {aka class Eigen::Matrix<int, -1, -1>&}’, which is not a typedef or a template type argument
   static void bitwiseNOT(const Eigen::MatrixXi& m, Eigen::MatrixXi& not);
                                                                     ^

I'm pretty sure that the problem is not due to cmake, but I didn't find anything on Google or here that help me to solve it. Furthermore, I tried to follow the Eigen official instructions but they not works for me on Windows.

To be precise, I'm using:

  • on Windows: Visual Studio 2017, make version 3.8 and Ninja
  • on Ubuntu: make version 4.1

The library and the Eigen files are the same on the two OSs since I'm sharing the workspace directory containing the two repositories, and I've already tried to use Ninja also on Ubuntu.

Every suggestion is welcome


Solution

  • You must avoid using not and and as variable names under Linux, you should just rename them to something else for your code to compile.

    They are actually C++ keywords (see here), which causes problems under Linux. Visual Studio does not recognize them, which explains why the compilation works under Windows. See this SO question for details.