Я пытаюсь заставить кросс-платформенную систему сборки работать с использованием CMake. Теперь у программного обеспечения есть несколько зависимостей. Я сам скомпилировал их и установил в своей системе.
Некоторые примеры файлов, которые были установлены:
-- Installing: /usr/local/share/SomeLib/SomeDir/somefile
-- Installing: /usr/local/share/SomeLib/SomeDir/someotherfile
-- Installing: /usr/local/lib/SomeLib/somesharedlibrary
-- Installing: /usr/local/lib/SomeLib/cmake/FindSomeLib.cmake
-- Installing: /usr/local/lib/SomeLib/cmake/HelperFile.cmake
Теперь в CMake есть файл, find_package()
который открывает Find*.cmake
файл и ищет библиотеку в системе и определяет некоторые переменные, например, SomeLib_FOUND
и т. Д.
Мой CMakeLists.txt содержит что-то вроде этого:
set(CMAKE_MODULE_PATH "/usr/local/lib/SomeLib/cmake/;${CMAKE_MODULE_PATH}")
find_package(SomeLib REQUIRED)
Первая команда определяет, где CMake ищет после, Find*.cmake
и я добавил каталог, SomeLib
где FindSomeLib.cmake
можно найти, поэтому find_package()
работает как положено.
Но это немного странно, потому что одна из причин, по которой это происходит, find_package()
заключается в том, чтобы уйти от жестко-закодированных путей без кроссплатформенности.
Как это обычно делается? Должен ли я скопировать cmake/
каталог SomeLib
в мой проект и установить CMAKE_MODULE_PATH
относительно?
Ответы:
Команда
find_package
имеет два режима:Module
режим иConfig
режим. Вы пытаетесь использоватьModule
режим, когда вам действительно нуженConfig
режим.Модульный режим
Find<package>.cmake
файл находится в вашем проекте. Что-то вроде этого:CMakeLists.txt
содержание:Обратите внимание, что это
CMAKE_MODULE_PATH
имеет высокий приоритет и может быть полезно, когда вам нужно переписать стандартныйFind<package>.cmake
файл.Режим настройки (установка)
<package>Config.cmake
файл находится снаружи и создается поinstall
команде другого проекта (Foo
например).foo
библиотека:Упрощенная версия конфигурационного файла:
По умолчанию проект установлен в
CMAKE_INSTALL_PREFIX
каталоге:Режим конфигурации (использование)
Используйте
find_package(... CONFIG)
для включенияFooConfig.cmake
с импортированной цельюfoo
:Обратите внимание, что импортируемая цель легко настраивается. Смотри мой ответ .
Обновить
источник
configure_package_config_file
. Кстати, если у вас есть какие-либо другие предложения, вы можете отправить мне запрос.bin/lib
(попробуйте установить исполняемый файл и запустить его в Windows). И пространства имен выглядят очень красиво, поэтому я тоже буду их сохранять :) Также я добавилmonolithic
сборку.Если вы работаете
cmake
над созданиемSomeLib
себя (скажем, как часть надстройки), подумайте об использовании реестра пользовательских пакетов . Это не требует жестко закодированных путей и является кроссплатформенным. В Windows (включая mingw64) он работает через реестр. Если вы посмотрите, как список префиксов установки создается с помощьюCONFIG
режима команды find_packages () , вы увидите, что реестр пользовательских пакетов является одним из элементов.Краткое руководство
Свяжите цели,
SomeLib
которые вам нужны, вне этого внешнего проекта, добавив их в набор экспорта вCMakeLists.txt
файлах, где они созданы:Создайте
XXXConfig.cmake
файл дляSomeLib
в ее${CMAKE_CURRENT_BUILD_DIR}
и сохранить это место в реестре пользоваегося пакета путем добавления двух вызовов на экспорт () кCMakeLists.txt
связанному сSomeLib
:find_package(SomeLib REQUIRED)
Введите вашу команду вCMakeLists.txt
файле проекта, который зависит от того,SomeLib
не будут ли " непросплатформенные жестко заданные пути" работать сCMAKE_MODULE_PATH
.Когда это может быть правильный подход
Этот подход, вероятно, лучше всего подходит для ситуаций, когда вы никогда не будете использовать свое программное обеспечение ниже каталога сборки (например, вы кросс-компилируете и никогда ничего не устанавливаете на своем компьютере, или вы создаете программное обеспечение только для запуска тестов в каталог сборки), поскольку он создает ссылку на файл .cmake в выходных данных «сборки», которые могут быть временными.
Но если вы никогда не выполняете установку
SomeLib
в своем рабочем процессе, вызовEXPORT(PACKAGE <name>)
позволяет избежать жестко заданного пути. И, конечно, если вы устанавливаетеSomeLib
, вы, вероятно, знаете свою платформуCMAKE_MODULE_PATH
и т. Д., Так что отличный ответ @ user2288008 поможет вам.источник
Вам не нужно указывать путь модуля как таковой. CMake поставляется со своим собственным набором встроенных скриптов find_package, и их местоположение находится в CMAKE_MODULE_PATH по умолчанию.
Более нормальный вариант использования для зависимых проектов, которые были CMakeified, будет состоять в том, чтобы использовать команду CMake external_project, а затем включить файл Use [Project] .cmake из подпроекта. Если вам просто нужен скрипт Find [Project] .cmake, скопируйте его из подпроекта и в исходный код вашего собственного проекта, и тогда вам не нужно будет дополнять CMAKE_MODULE_PATH, чтобы найти подпроект на системном уровне.
источник
their location is in the default CMAKE_MODULE_PATH
по умолчаниюCMAKE_MODULE_PATH
пустоCMAKE_MODULE_PATH
Windows пусто.Если вы не доверяете CMake иметь этот модуль, тогда - да, сделайте это - вроде: Скопируйте
find_SomeLib.cmake
и его зависимости в вашcmake/
каталог. Это то, что я делаю как запасной вариант. Это уродливое решение, хотя.Обратите внимание, что
FindFoo.cmake
каждый из модулей является своего рода мостом между зависимостью от платформы и независимостью от платформы - они ищут в различных местах, зависящих от платформы, чтобы найти пути в переменных, имена которых не зависят от платформы.источник