Найти пакет 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)
Любая идея о том, что мне не хватает или что-то не так?
Ответы
Ответ 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})