2016-07-20 1 views
1

Несмотря на многолетние кодирования широкомасштабных приложений на C++, я не понимаю, как find_package должен работать в средстве CMake среднего размера, ПРИНИМАЯ, что я хочу самостоятельно создавайте исходный код для зависимых пакетов, а не просто полагайтесь на большие системы, такие как opencv, pcl или boost, которые устанавливаются где-то в системной папке. Я не могу не поверить, что я единственный человек в мире, который поставлял несколько OpenCV и других приложений с открытым исходным кодом, работал с системами мета-сборки, такими как NAnt и SCons, в крупных игровых проектах, но не может понять самые основные вещи о том, как работает CMake, или найти учебник, отвечающий на эти вопросы.Использование CMake для поиска зависимостей в вложенной папке приложения

В прошлом я по существу взломал, не искажая find_package, установив все значения foo_DIR вручную, поскольку CMake жалуется, пока не получу рабочую папку.

Я хотел бы пропустить простой пример, над которым я сейчас работаю, и очень надеюсь, что кто-то может объяснить, что я делаю неправильно.

Во-первых, некоторые предположения: Я хочу построить все как для MacOS, так и для Windows, в идеале через CMakeGUI. MacOS должен создавать XCodeProjects, а Windows должна создавать решения Visual Studio.

Где есть зависимости, я хочу их самостоятельно скомпилировать, поэтому у меня есть отладочные символы и вы можете изменить источник зависимости (или, по крайней мере, отладить его). В системные папки нет установки предварительно созданных двоичных файлов, то есть нет использование sudo port install opencv/pcl и т. д. на Mac. У меня есть несколько проектов, и я предпочитаю сохранить проект и его зависимости в одной папке. Для целей конкретного примера, предположим, что я строю этот проект, хотя это произвольный выбор, чтобы проиллюстрировать процесс и путаницы я страдаю:

https://github.com/krips89/opendetection

Этот список зависимостей, которые я намеренно переупорядоченные здесь так что я могу взять их в порядке, а именно:

find_package(OpenCV REQUIRED) 
find_package(Eigen REQUIRED) 
find_package(Boost 1.40 COMPONENTS program_options REQUIRED) 
find_package(PCL REQUIRED) 
find_package(VTK REQUIRED) 

Я хотел бы, чтобы все из этих зависимостей, загруженных и сконфигурированных в одном пути (скажем, C: \ SRC на Windows, и ~ \ SRC на Mac для простоты), НЕ в системном пути. Предположим, что фактическая папка является подпапкой для этого проекта и не является подпапкой для всех проектов. Это также должно предусматривать параллельную установку нескольких проектов на одном компьютере.

Принимая это один шаг за один раз:

(1) Я клонировать OpenCV от https://github.com/opencv/opencv, синхронизации помечать 3.1, настройки в папку opencv_build папки, сборки и установки в opencv_install. Я так много раз делал это довольно просто. (2) Как и выше, но для собственного (хотя создание для eigen на самом деле ничего не делает, это библиотека шаблонов. Я устанавливаю в папку eigen_install

Взяв каталог, вы увидите серию папок для загруженных зависимостей. предполагается, конвенции, где, и исходные операции РЕПО, и их следующие _build папки являются «где строить двоичные файлы» папки в CMakeGui.

$ ls 
boost_1_40_0 opencv opendetection_build 
eigen opencv-build opendetection_data 
eigen_build opencv_contrib pcl 
eigen_install opendetection 

Все хорошо до сих пор, теперь давайте попробуем настроить opendetection и создать решение в opendetection_build и найдите зависимости pendetection из папки ~/src, то есть для пихты две зависимости, я надеюсь найти opencv и eigen в папках opencv-build и собственной сборки.

OpenCV сразу выходит из строя, как и следовало ожидать, говоря:

Could not find a package configuration file provided by "OpenCV" with any of the following names: 

OpenCVConfig.cmake 
opencv-config.cmake 

Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set "OpenCV_DIR" to a directory containing one of the above files. If "OpenCV" provides a separate development package or SDK, be sure it has been installed. 

Это хорошо, потому что я хочу, чтобы явно указать CMake искать зависимых пакетов под моей папке ~/Src. Вопрос: Является ли использование CMAKE_PREFIX_PATH =/users/foo/src рекомендуемым способом выполнения того, что я хочу, - поиск всех подпакетов по определенному пути?

После этого CMake находит OpenCV (хорошо) и устанавливает OpenCV_DIR =/Users/foo/src/opencv-build.

Вопрос: Учитывая, что я сделал «установкой» в OpenCV установить (с помощью CMAKE_INSTALL_PREFIX и строительство Установить Мишень OpenCV, она не должна найти OpenCV в папке OpenCV установить не OpenCV-строить

?

Переходя к собственному, я сконфигурировал и построил собственный и установил его в ~/src/eigen-install, который, поскольку он является подпапкой CMAKE_PREFIX_PATH (~/src), я могу ожидать, что ее можно найти. Кажется, кто-нибудь объяснит мне, что я не понимаю? Особенно учитывая, что Eigen в библиотеке шаблонов и что в CMAKE_PREFIX_PATH есть как минимум три папки (eigen, eigen_build и eigen_install), которые я бы подумал, что CMake найдет что-то внутри, я полагаю, что я должен делать что-то неправильно здесь. Я ЗНАЮ из прошлого expe Я могу вручную установить EIGEN_INCLUDE_DIR вручную в CMakeGUI и продолжить хакерство, но это кажется неправильным.

Я более чем готов написать веб-страницу, объясняющую это для будущих людей, как тупой, как я, если он еще не существует, хотя я не могу понять, как использование CMake для базовой конфигурации проекта и генерации, по-видимому, настолько очевидный для всех, но такой непрозрачный для меня. Я действительно использовал CMake в течение нескольких лет, обычно вручную настраивая Boost_INCLUDE_Dir, Foo_INCLUDE_PATH и т. Д. Вручную, но, разумеется, это неправильное решение. Как правило, потратив пару дней на борьбу с различными пакетами, чтобы создать решение, вручную установив INCLUDE PATHS, LIBRARY PATHS и другие варианты, я просто решаю решение и не трогаю CMake еще раз. Но я хотел бы понять, чего мне не хватает в find_package для моего (конечно, не редкостного) случая использования для управления моими зависимостями проекта, а не просто с помощью установки sudo port * и установки случайных версий проектов в мои глобальные системные папки.

ответ

2

Как указано в сообщении об ошибке, CMAKE_PREFIX_PATH должен быть установлен в установочный префикс пакета. Например, если пакет был создан с использованием CMake, это значение CMAKE_INSTALL_PREFIX переменной, если пакет был создан с использованием Autotools, это значение параметра --prefix, используемого для его настройки, и так далее.

CMake не ищет каждый каталог под CMAKE_PREFIX_PATH. Вот почему указание /users/foo/src бесполезно, если у вас установлен пакет на /users/foo/src/eigen-install.

Вместо этого, вы можете установить все 3d сторонние пакеты в /users/foo/src/install, и использовать этот путь, CMAKE_PREFIX_PATH в вашем главном проекте.

+0

Это самый яркий комментарий, который я еще слышал, и полностью объясняет поведение. Но чтобы уточнить, есть ли в CMake способ * нет * для достижения того, чего я хочу, с чисто разделенными установками? Конечно, теперь я могу сделать свою собственную «установочную» подпапку, но я не понимаю, почему я хотел бы это сделать и установить все, чтобы «установить». Папка с VTK, opencv, pcl и т. Д., Все сбрасываемые в нее, является довольно интересной папкой, и тогда нет способа очистить-перестроить подпакет, если я, например, захочу его обновить. –

+0

'Нет ли способа в CMake для достижения того, что я хочу, с чисто разделенными установками?' - Возможно, но вам нужно явно указать все установочные префиксы в этом случае. Например, вы можете собрать все их в 'CMAKE_PREFIX_PATH' (эта переменная может фактически быть * списком *). 'тогда нет способа очистить-rebuild sub-package, если я, например, захочу его обновить.' - Обычно «make uninstall» чисто удаляет файлы пакета из каталога установки и не касается других пакетов в том же каталоге. Поэтому наличие одного установочного префикса не препятствует переустановке отдельных пакетов. – Tsyvarev

+0

Спасибо. В целом я доверяю людям писать сценарии удаления меньше, чем я доверяю удалению папки, на которую они писали, но ваши предложения дают мне все, что нужно для работы. Я немного смущен тем, почему OpenCV * был * найден (хотя и в произвольной подпапке.) Означает ли это, что OpenCV переопределило поведение find_package и является ли такой переопределением общим? –

Смежные вопросы