Cmake включает в себя различные модули распространения (т. е. размещенные внутри каталога Modules/
установки cmake; например, /usr/share/cmake-3.5/Modules/FindBoost.cmake
).
Это создает проблемы при разработке кода, который включает внутренние библиотеки с именами, конфликтующими с этими модулями распространения, поскольку find_package(Xyz)
находит модуль распространения (/usr/share/cmake-3.5/Modules/FindXyz.cmake
), а не пользовательский модуль (/home/user/opt/lib/cmake/Xyz-config.cmake
). Пробовал ставить CMAKE_FIND_ROOT_PATH
и CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY
, но безрезультатно.
Как я могу заставить cmake исключить свои собственные модули распространения при оценке find_package()
?
@Tsyvarev О, отлично! Большое спасибо, пропустил. Хотите добавить в качестве ответа, чтобы я мог принять? В идеале я не хочу менять способ вызова find_package(), поскольку у меня может не быть доступа к этому (например, к стороннему репозиторию). Ваш комментарий привел меня к CMAKE_FIND_PACKAGE_PREFER_CONFIG
, и я уверен, что это то, что я хочу.
@Tsyvarev А, очень интересно, спасибо! Ваши комментарии решают мои разочарования и очень ценятся! Если вы вставите их в ответ, я отмечу их как принятые.
Хм, на самом деле переменная Boost_NO_BOOST_CMAKE
имеет противоположный эффект: будучи включенной, она запрещает скрипту FindBoost.cmake
, поставляемому с CMake, искать скрипт конфигурации (boost-config.cmake
). Я удалил свой предыдущий комментарий, так как он был неправильным.
Как автор проекта, вы можете счесть «устаревший» скрипт поиска (FindXXX.cmake
) неподходящим для вас и предпочесть вместо него использовать «современный» скрипт конфигурации (XXXConfig.cmake
или config-xxx.cmake
). В этом случае вы можете передать дополнительную опцию CONFIG
или NO_MODULE
в find_package
:
find_package(Boost NO_MODULE)
Это предотвратит поиск скрипта FindBoost.cmake
CMake и заставит его искать BoostConfig.cmake
(или config-boost.cmake
).
Если скрипт конфигурации не может быть найден с параметром NO_MODULE
или CONFIG
, то CMake сообщит об ошибке, даже если соответствующий скрипт поиска существует.
Кроме того, вы можете установить переменную CMAKE_FIND_PACKAGE_PREFER_CONFIG
:
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
поэтому CMake сначала проверит скрипт конфигурации. Но если этот скрипт отсутствует, то CMake попытается использовать скрипт поиска.
Как пользователь проекта, вы можете найти скрипт конфигурации для какого-то пакета лучше, чем скрипт поиска... но в этом случае лучше ничего не менять: возможно, проект, который вы используете, может работать только со скриптом поиска, и не может работать с конфигом один. (Например, в проекте используются переменные, созданные скриптом поиска для ссылки на библиотеки, но скрипты конфигурации обычно создают ИМПОРТНЫЕ цели).
Спасибо; очень интересный момент относительно того, почему пользователи могут не захотеть этого делать.
Обратите внимание, что мой ответ касается выбора между сценариями поиска (FindXXX.cmake
) и сценариями конфигурации (XXXConfig.cmake
). А точнее, о выборе между режимами MODULE и CONFIG find_package
. Мой ответ НЕ касается выбора между несколькими установками пакета. Как пользователь проекта, для которого требуется какой-либо пакет, вы можете захотеть, чтобы CMake нашел конкретную установку этого пакета вместо «по умолчанию» (системной). А CMake предоставляет четко определенные механизмы для выражения ваших предпочтений. Но эти механизмы — отдельная история.
Просто передайте
CONFIG
илиNO_MODULE
наfind_package
звонок. Так что он не будет искатьFindXXX.cmake
модуль.