Подтвердить что ты не робот

Найти пакет Eigen3 для CMake

CMake не может найти мой пакет Eigen3. Я установил переменную среды, называемую

EIGEN3_INCLUDE_DIR

указывая на путь, где FindEigen3.cmake.

Затем в файле CMakelists.txt я написал:

find_package( Eigen3 REQUIRED )
include_directories( EIGEN3_INCLUDE_DIR )

Я получаю следующее сообщение об ошибке:

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)

Любая идея о том, что мне не хватает или что-то не так?

4b9b3361

Ответ 1

Поскольку Eigen3 является полностью только заголовком, все, что вам когда-либо понадобится, это путь к каталогу include. И этот, вы все равно определяете вручную. Поэтому нет необходимости в вызове FindEigen3.cmake или FIND_PACKAGE.

Просто используйте

INCLUDE_DIRECTORIES ( "$ENV{EIGEN3_INCLUDE_DIR}" )

или

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}" )

Несколько примечаний:

  • Если вы хотите получить доступ к содержимому переменной CMake, обязательно используйте ${...}
  • $ENV{....} обращается к переменным среды.
  • Второй пример остановится с ошибкой, если переменная окружения не установлена ​​(и, таким образом, EIGEN3_INCLUDE_DIR cmake-переменная пуста)
  • Будьте осторожны, чтобы использовать кавычки вокруг (оцениваемых) переменных, если они могут содержать пробелы. В противном случае CMake интерпретирует его как список.
  • Если вы хотите использовать пользовательские модули поиска, обязательно разместите их в вашей CMake-установке или, как указано выше, @Fraser, обязательно укажите CMAKE_MODULE_PATH в каталог, где он находится. Не уверен, но может быть, что CMake также автоматически проверяет текущий каталог (где находится ваш CMakeLists.txt. В любом случае установка EIGEN3_INCLUDE_DIR полностью не связана с расположением FindEigen3.cmake
  • Однако может оказаться, что ваш FindEigen3 script оценивает эту переменную для определения местоположения вашей установки Eigen3.
  • В качестве альтернативы, собственные проекты на основе CMake часто предоставляют <PackageName>Config.cmake. Если вы укажете переменную с именем <PackageName>_DIR в каталог, содержащий этот файл, вы можете использовать FIND_PACKAGE( <PackageName> ...) как обычно. Подробнее см. документацию FIND_PACKAGE.

Ответ 2

Сначала убедитесь, что Eigen правильно установлен. Обратитесь к файлу INSTALL, который поставляется с архивом.

Во-вторых, скопируйте файл cmake/FindEigen3.cmake из tarball в каталог, содержащий ваш CMakeLists.txt.

В вашем CMakeLists.txt добавить:

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

Теперь вы должны быть в состоянии сделать, например. #include <Eigen/Core>.

Все это происходит (главным образом) из этого .

Этот подход имеет преимущество перед, например, include_directories("$ENV{EIGEN3_INCLUDE_DIR}"), что он использует стандартный механизм CMake для поиска внешних зависимостей, что облегчает кому-то другому (или вашему будущему себе) возможность поднять проект, возможно, на другой платформе.

(Однако было бы неплохо, если бы сам Eigen установил файл EigenConfig.cmake, сделав его доступным через механизм find_package без каких-либо дополнительных путей.)

Ответ 3

Eigen> = 3.3 имеет прямую интеграцию с CMake, так что, похоже, у вас неправильно настроена.

Предположим, что Eigen был установлен в /opt/eigen/3.3 с настройками по умолчанию. Добавьте или добавьте местоположение /opt/eigen/3.3 к переменной окружения CMAKE_PREFIX_PATH например, в bash:

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

Тогда CMake должен забрать его.


Если вы пишете свой собственный CMakeLists.txt, использующий Eigen, я предлагаю использовать код, подобный следующему:

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

Вы не должны использовать include_directories так как был выпущен CMake 3 - подход к целям должен быть предпочтительным, когда он доступен.

Ответ 4

Я нашел другое решение здесь (которое упоминалось здесь), который использует файл pkg-config:

find_package(PkgConfig)
pkg_search_module(Eigen3 REQUIRED eigen3)

Ответ 5

Вы можете попробовать установить CMAKE_MODULE_PATH в папку подкаталога Eigen с именем "cmake":

cmake . -DCMAKE_MODULE_PATH=<Eigen root dir>/cmake/

Ответ 6

Если вы не добавили Eigen Library в переменную окружения, выполните следующие действия в 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

Другой простой способ, который не требует добавления переменной окружения, - это просто найти eigen с помощью функции cmake find_path https://cmake.org/cmake/help/v3.6/command/find_path.html. Пример кода находит каталог "Eigen" в путях "/usr/include/" и "/usr/local/include" с дополнительным поиском в подкаталоге "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}" )

Ответ 8

Еще один простой способ:

если библиотека Eigen находится в /opt/eigen/3.3/Eigen

include_directories(/opt/eigen/3.3)

что эквивалентно тому, что предложил Джай

set(EIGEN_DIR "/opt/eigen/3.3")
include_directories(${EIGEN_DIR})