find_package
- Типичное использование
- Режимы поиска
- Базовая сигнатура
- Полная сигнатура
- Процедура поиска в режиме Config
- Переменные интерфейса файла пакета
- Транзитивные зависимости CPS
Примечание
Using Dependencies Guide содержит краткое введение в эту общую тему. В нём представлен более широкий обзор того, как команда find_package() вписывается в общую картину, включая её связь с модулем FetchContent. Рекомендуется ознакомиться с этим руководством, прежде чем переходить к приведённым ниже подробностям.
Найти пакет (обычно предоставляемый чем-либо за пределами проекта) и загрузить сведения, относящиеся к этому пакету. Вызовы этой команды также могут перехватываться поставщиками зависимостей.
Типичное использование
Большинство вызовов find_package() обычно имеют следующий вид:
find_package(<PackageName> [<version>] [REQUIRED] [COMPONENTS <components>...])
<PackageName> — единственный обязательный аргумент. <version> часто опускается, а REQUIRED следует указывать, если проект невозможно успешно настроить без пакета. Некоторые более сложные пакеты поддерживают компоненты, которые можно выбрать с помощью ключевого слова COMPONENTS, однако большинство пакетов не обладают таким уровнем сложности.
Описанная выше сокращённая форма основана на базовой сигнатуре. По возможности проектам следует искать пакеты именно с помощью этой формы. Это снижает сложность и максимально расширяет способы, которыми пакет может быть найден или предоставлен.
Для обычного использования find_package() достаточно понимать базовую сигнатуру. Сопровождающим проектов, которые собираются предоставлять файл конфигурации пакета, следует разобраться в общей картине, изложенной в разделе Полная сигнатура и всех последующих разделах этой страницы.
Режимы поиска
Команда может искать пакеты в нескольких режимах:
- Режим Module
-
В этом режиме CMake ищет файл с именем
Find<PackageName>.cmake, сначала в расположениях, перечисленных вCMAKE_MODULE_PATH, а затем среди модулей Find, предоставляемых установкой CMake. Если файл найден, CMake считывает и обрабатывает его. Этот файл отвечает за поиск пакета, проверку версии и вывод необходимых сообщений. Некоторые модули Find лишь ограниченно поддерживают версии или не поддерживают их вовсе; см. документацию соответствующего модуля Find.Файл
Find<PackageName>.cmakeобычно не предоставляется самим пакетом. Как правило, его предоставляет нечто внешнее по отношению к пакету, например операционная система, сам CMake или даже проект, из которого была вызвана командаfind_package(). Поскольку модули Find предоставляются извне, они, как правило, основаны на эвристиках и со временем могут устаревать. Обычно они ищут определённые библиотеки, файлы и другие артефакты пакета.Режим Module поддерживается только базовой сигнатурой команды.
- Режим Config
-
В этом режиме CMake ищет файл, соответствующий одному из следующих шаблонов:
<PackageName>.cps<lowercasePackageName>.cps<lowercasePackageName>-config.cmake<PackageName>Config.cmake
Если найден один из двух последних файлов, CMake также ищет соответственно
<lowercasePackageName>-config-version.cmakeили<PackageName>ConfigVersion.cmake, если указаны сведения о версии (объяснение использования этих отдельных файлов версий см. в разделе Выбор версии в режиме Config). Два последних варианта представляют собой описания пакетов в виде скриптов CMake. Первые два — описания пакетов в формате Common Package Specification (CPS), которые более переносимы и содержат сведения о версии в «базовом» файле. За исключением явно оговорённых случаев, все упоминания «файлов конфигурации», «режима Config», «файлов конфигурации пакета» и т. п. в равной степени относятся как к файлам CPS, так и к файлам скриптов CMake.Примечание
Поиск устроен так, что в большинстве случаев файлы Common Package Specification имеют приоритет над файлами конфигурации в виде скриптов CMake. Указание
CONFIGSисключает файлы CPS из рассмотрения.В режиме Config команде можно передать список имён пакетов для поиска. Расположения, в которых CMake ищет файлы конфигурации и версии, значительно сложнее, чем в режиме Module (см. раздел Процедура поиска в режиме Config).
Файлы конфигурации и версии обычно устанавливаются вместе с пакетом, поэтому они, как правило, надёжнее модулей Find. Обычно они содержат прямые сведения о содержимом пакета, поэтому самим файлам конфигурации или версии не требуется выполнять поиск или использовать эвристики.
Режим Config поддерживается как базовой, так и полной сигнатурой команды.
- Режим перенаправления FetchContent
-
Добавлено в версии 3.24: Вызов
find_package()может быть перенаправлен внутри системы к пакету, предоставляемому модулемFetchContent. Для вызывающего кода такое поведение будет выглядеть аналогично режиму Config, за исключением того, что логика поиска пропускается, а сведения о компонентах не используются. Подробнее см.FetchContent_Declare()иFetchContent_MakeAvailable().
Если команда не перенаправлена к пакету, предоставляемому FetchContent, её аргументы определяют, будет ли использоваться режим Module или Config. При использовании базовой сигнатуры команда сначала выполняет поиск в режиме Module. Если пакет не найден, поиск продолжается в режиме Config. Пользователь может присвоить переменной CMAKE_FIND_PACKAGE_PREFER_CONFIG значение true, чтобы изменить приоритет и указать CMake сначала искать в режиме Config, а затем, если потребуется, перейти к режиму Module. Базовую сигнатуру также можно принудительно ограничить режимом Module с помощью ключевого слова MODULE. При использовании полной сигнатуры команда выполняет поиск только в режиме Config.
Базовая сигнатура
find_package(<PackageName> [<version>] [EXACT] [QUIET] [MODULE]
[REQUIRED|OPTIONAL] [[COMPONENTS] <component>...]
[OPTIONAL_COMPONENTS <component>...]
[REGISTRY_VIEW {64|32|64_32|32_64|HOST|TARGET|BOTH}]
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
[UNWIND_INCLUDE])
Базовая сигнатура поддерживается режимами Module и Config. Ключевое слово MODULE означает, что для поиска пакета можно использовать только режим Module, без перехода к режиму Config.
Независимо от используемого режима устанавливается переменная <PackageName>_FOUND, указывающая, найден ли пакет. Если пакет найден, относящиеся к нему сведения могут предоставляться через другие переменные и импортируемые цели, описанные самим пакетом. Параметр QUIET отключает информационные сообщения, в том числе сообщение о том, что пакет не найден, если он не является REQUIRED. Параметр REQUIRED прерывает обработку с сообщением об ошибке, если пакет не найден.
После ключевого слова COMPONENTS можно перечислить список обязательных для конкретного пакета компонентов. Если удовлетворить требования хотя бы одного из этих компонентов невозможно, пакет в целом считается ненайденным. Если также указан параметр REQUIRED, это считается фатальной ошибкой; в противном случае выполнение продолжается. Для краткости, если указан параметр REQUIRED, ключевое слово COMPONENTS можно опустить и перечислить обязательные компоненты непосредственно после REQUIRED.
Переменную CMAKE_FIND_REQUIRED можно включить, чтобы по умолчанию сделать этот вызов REQUIRED. Это поведение можно переопределить, указав ключевое слово OPTIONAL. Как и в случае с параметром REQUIRED, список компонентов можно указать непосредственно после OPTIONAL; это равнозначно перечислению компонентов после ключевого слова COMPONENTS. Если указано ключевое слово OPTIONAL, предупреждение о ненайденном пакете не выводится.
После OPTIONAL_COMPONENTS можно перечислить дополнительные необязательные компоненты. Если удовлетворить требования этих компонентов невозможно, пакет всё равно может считаться найденным при условии, что удовлетворены требования всех обязательных компонентов.
Набор доступных компонентов и их назначение определяются целевым пакетом:
- Для файлов конфигурации пакетов в виде скриптов CMake целевой пакет формально сам определяет, как интерпретировать переданные сведения о компонентах, однако ему следует придерживаться изложенных выше ожиданий. Для вызовов без указания компонентов единого ожидаемого поведения нет, поэтому целевым пакетам следует чётко описывать, что происходит в таких случаях. Среди распространённых вариантов — предполагать, что нужно найти все компоненты, ни одного компонента или некоторое чётко определённое подмножество доступных компонентов.
- Пакеты Common Package Specification состоят из корневого файла конфигурации и нуля или более дополнений, каждое из которых предоставляет компоненты и может иметь зависимости. CMake всегда пытается загрузить корневой файл конфигурации. Дополнения загружаются, только если их зависимости можно удовлетворить и если они предоставляют запрошенные компоненты либо компоненты не запрашивались. Если зависимости дополнения, предоставляющего обязательный компонент, удовлетворить невозможно, пакет считается ненайденным. В противном случае это дополнение игнорируется.
Добавлено в версии 3.24: Ключевое слово REGISTRY_VIEW указывает, какие представления реестра следует запрашивать. Это ключевое слово имеет смысл только на платформах Windows и игнорируется на всех остальных. Формально целевой пакет сам определяет, как интерпретировать переданные ему сведения о представлении реестра.
Добавлено в версии 3.24: Указание ключевого слова GLOBAL переводит все импортируемые цели в глобальную область видимости импортирующего проекта. Эту возможность также можно включить, задав переменную CMAKE_FIND_PACKAGE_TARGETS_GLOBAL.
Аргумент <version> запрашивает версию, с которой должен быть совместим найденный пакет. Его можно указать в одной из двух форм:
- Одна версия в формате
major[.minor[.patch[.tweak]]], где каждый компонент является числовым значением. - Диапазон версий в формате
versionMin...[<]versionMax, гдеversionMinиversionMaxимеют тот же формат и те же ограничения на целочисленные значения компонентов, что и отдельная версия. По умолчанию обе граничные версии включаются в диапазон. Если указать<, верхняя граница не включается. Диапазоны версий поддерживаются только в CMake 3.19 и новее.
Примечание
За исключением пакетов CPS, поддержка версий в настоящее время реализуется отдельно для каждого пакета. Если указан диапазон версий, а пакет рассчитан только на одну версию, он проигнорирует верхнюю границу диапазона и будет учитывать только нижнюю версию. Пакеты, не использующие CPS и поддерживающие диапазоны версий, реализуют эту поддержку способом, определяемым конкретным пакетом. Подробности и важные оговорки см. в разделе Выбор версии ниже.
Параметр EXACT требует точного совпадения версии. Этот параметр несовместим с указанием диапазона версий.
Если во вложенном вызове из модуля find не указаны <version> и/или список компонентов, соответствующие аргументы автоматически передаются из внешнего вызова (включая флаг EXACT для <version>).
Обсуждение параметра NO_POLICY_SCOPE см. в документации команды cmake_policy().
Добавлено в версии 3.24: Ключевое слово BYPASS_PROVIDER разрешено использовать только при вызове find_package() поставщиком зависимостей. Поставщики могут использовать его для прямого вызова встроенной реализации find_package() и предотвращения повторной маршрутизации этого вызова к самому поставщику. В будущих версиях CMake попытки использовать это ключевое слово не из поставщика зависимостей могут обнаруживаться и завершаться фатальной ошибкой.
Добавлено в версии 4.2: Ключевое слово UNWIND_INCLUDE разрешено использовать только при вызове find_package() внутри родительского вызова find_package(). Если вызову find_package(UNWIND_INCLUDE) не удаётся найти требуемый пакет, начинается состояние «размотки». В этом состоянии дальнейшие вызовы find_package() и include() запрещены, а все родительские команды include() немедленно вызывают return() при достижении их области видимости. Эта «размотка» продолжается, пока не будет выполнен возврат к родительскому find_package().
UNWIND_INCLUDE предназначено только для вызовов find_package(), создаваемых командой install(EXPORT_PACKAGE_DEPENDENCIES), но может быть полезно тем, кто хочет вручную управлять зависимостями аналогичным образом.
Полная сигнатура
find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED|OPTIONAL] [[COMPONENTS] <component>...]
[OPTIONAL_COMPONENTS <component>...]
[CONFIG|NO_MODULE]
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
[NAMES <name>...]
[CONFIGS <config>...]
[HINTS <path>...]
[PATHS <path>...]
[REGISTRY_VIEW {64|32|64_32|32_64|HOST|TARGET|BOTH}]
[PATH_SUFFIXES <suffix>...]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_PACKAGE_REGISTRY]
[NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
[NO_CMAKE_SYSTEM_PATH]
[NO_CMAKE_INSTALL_PREFIX]
[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH])
Параметр CONFIG, его синоним NO_MODULE или использование параметров, не указанных в базовой сигнатуре, принудительно включают чистый режим Config. В чистом режиме Config команда пропускает поиск в режиме Module и сразу переходит к поиску в режиме Config.
В режиме Config команда пытается найти файл конфигурации, предоставленный искомым пакетом. Для хранения каталога, содержащего этот файл, создаётся запись кэша с именем <PackageName>_DIR. По умолчанию команда ищет пакет с именем <PackageName>. Если указан параметр NAMES, вместо <PackageName> используются следующие за ним имена. Эти имена также учитываются при определении возможности перенаправить вызов к пакету, предоставляемому FetchContent.
Для каждого указанного имени пакета команда ищет файл, имя которого соответствует одному из следующих шаблонов:
<PackageName>Config.cmake<lowercasePackageName>-config.cmake<PackageName>.cps<lowercasePackageName>.cps
Набор альтернативных имён файлов конфигурации можно задать с помощью параметра CONFIGS. Процедура поиска в режиме Config описана ниже. После нахождения файла проверяется соответствие любым ограничениям на версию, и, если они соблюдены, CMake считывает и обрабатывает файл конфигурации. Поскольку этот файл предоставляется пакетом, в нём уже известно расположение содержимого пакета. Полный путь к файлу конфигурации сохраняется в переменной CMake <PackageName>_CONFIG.
Примечание
Поскольку файлам CPS запрещено иметь имена, которые не соответствуют имени пакета, указание CONFIGS исключает поиск файлов CPS.
Все файлы конфигурации, рассмотренные CMake при поиске пакета с подходящей версией, сохраняются в переменной <PackageName>_CONSIDERED_CONFIGS, а соответствующие версии — в переменной <PackageName>_CONSIDERED_VERSIONS.
Если файл конфигурации пакета не удаётся найти, CMake выдаст сообщение об ошибке с описанием проблемы, если не указан аргумент QUIET. Если указан REQUIRED, а пакет не найден, возникает фатальная ошибка и выполнение этапа настройки прекращается. Если для <PackageName>_DIR задан каталог, не содержащий файла конфигурации, или если запрошенная версия несовместима с пакетом, найденным в этом каталоге (см. раздел Выбор версии в режиме Config), CMake проигнорирует этот каталог и начнёт поиск заново.
Сопровождающим пакетов, предоставляющим файлы конфигурации, рекомендуется давать им такие имена и устанавливать их в такие места, чтобы описанная ниже процедура поиска в режиме Config находила их без дополнительных параметров.
Процедура поиска в режиме Config
Примечание
При использовании режима Config эта процедура поиска применяется независимо от того, была ли указана полная или базовая сигнатура.
Добавлено в версии 3.24: Все вызовы find_package() (даже в режиме Module) сначала ищут файл конфигурации пакета в каталоге CMAKE_FIND_PACKAGE_REDIRECTS_DIR. Модуль FetchContent или даже сам проект может записывать файлы в это расположение, чтобы перенаправлять вызовы find_package() на содержимое, уже предоставленное проектом. Если в этом расположении файл конфигурации пакета не найден, поиск продолжается по описанной ниже логике.
CMake формирует набор возможных префиксов установки пакета. В каждом префиксе выполняется поиск файла конфигурации в нескольких каталогах. В таблицах ниже приведены каталоги, в которых ведётся поиск. Каждая запись соответствует структурам установки, принятым в Windows (W), UNIX (U) или Apple (A):
Запись | Соглашение |
|---|---|
| W |
| W |
| W |
| W |
| W |
| W |
| W |
| W |
| W |
| W |
| U |
| U |
| U |
| U |
| U |
| U |
| W/U |
| W/U |
| W/U |
В системах с поддержкой macOS FRAMEWORK и BUNDLE выполняется поиск следующих каталогов, содержащих Frameworks или пакеты приложений с файлом конфигурации:
Запись | Соглашение |
|---|---|
| A |
| A |
| A |
| A |
| A |
| A |
| A |
| A |
| A |
Добавлено в версии 4.3.
При поиске по указанным выше путям find_package ищет файлы .cps только в путях поиска, содержащих /cps/, а в остальных случаях ищет только файлы .cmake. (Это относится только к указанным путям и не учитывает содержимое <prefix> или <name>.)
Во всех случаях <name> не учитывает регистр и соответствует любому из указанных имён (<PackageName> или имён, заданных с помощью NAMES).
Если включён хотя бы один компилируемый язык, каталоги lib/<arch> и lib*, зависящие от архитектуры, могут проверяться с учётом целевой архитектуры компилятора в следующем порядке:
-
lib/<arch> -
Поиск выполняется, если задана переменная
CMAKE_LIBRARY_ARCHITECTURE. -
lib64 -
Поиск выполняется на 64-разрядных платформах (
CMAKE_SIZEOF_VOID_Pравно 8), если свойствоFIND_LIBRARY_USE_LIB64_PATHSустановлено вTRUE. -
lib32 -
Поиск выполняется на 32-разрядных платформах (
CMAKE_SIZEOF_VOID_Pравно 4), если свойствоFIND_LIBRARY_USE_LIB32_PATHSустановлено вTRUE. -
libx32 -
Поиск выполняется на платформах, использующих ABI x32, если свойство
FIND_LIBRARY_USE_LIBX32_PATHSустановлено вTRUE. -
lib -
Поиск выполняется всегда.
Изменено в версии 3.24: На платформе Windows запросы к реестру можно включать в каталоги, указанные с помощью ключевых слов HINTS и PATHS, используя специальный синтаксис. Такие спецификации игнорируются на всех остальных платформах.
Добавлено в версии 3.24: Можно указать REGISTRY_VIEW для управления запросами к реестру Windows, заданными в составе PATHS и HINTS.
Указывает, какие представления реестра необходимо запрашивать. Этот параметр имеет смысл только на платформах Windows и игнорируется на остальных. Если параметр не задан, используется представление TARGET, когда политика CMP0134 установлена в NEW. Сведения о представлении по умолчанию, когда политика установлена в OLD, см. в описании CMP0134.
-
64 -
Запросить 64-разрядный реестр. В 32-разрядной Windows всегда возвращает строку
/REGISTRY-NOTFOUND. -
32 -
Запросить 32-разрядный реестр.
-
64_32 -
Запросить оба представления (
64и32) и сформировать путь для каждого. -
32_64 -
Запросить оба представления (
32и64) и сформировать путь для каждого. -
HOST -
Запросить реестр, соответствующий архитектуре хоста:
64в 64-разрядной Windows и32в 32-разрядной Windows. -
TARGET -
Запросить реестр, соответствующий архитектуре, заданной переменной
CMAKE_SIZEOF_VOID_P. Если она не определена, использовать представлениеHOST. -
BOTH -
Запросить оба представления (
32и64). Порядок определяется следующими правилами: если переменнаяCMAKE_SIZEOF_VOID_Pопределена, используйте представление, соответствующее значению этой переменной:-
8:64_32 -
4:32_64
Если переменная
CMAKE_SIZEOF_VOID_Pне определена, используйте архитектуру хоста:- 64-разрядная:
64_32 - 32-разрядная:
32
-
Если указан PATH_SUFFIXES, суффиксы добавляются поочерёдно к каждой записи каталога (W) или (U).
Этот набор каталогов предназначен для совместного использования с проектами, которые устанавливают файлы конфигурации в свои деревья установки. Каталоги, отмеченные выше как (W), предназначены для установки в Windows, где префикс может указывать на верхний уровень каталога установки приложения. Каталоги, отмеченные как (U), предназначены для установки в UNIX, где префикс является общим для нескольких пакетов. Это всего лишь соглашение, поэтому во всех платформах поиск по-прежнему выполняется во всех каталогах (W) и (U). Каталоги, отмеченные как (A), предназначены для установки на платформах Apple. Порядок предпочтения определяется переменными CMAKE_FIND_FRAMEWORK и CMAKE_FIND_APPBUNDLE.
Предупреждение
Если установить CMAKE_FIND_FRAMEWORK или CMAKE_FIND_APPBUNDLE в значение, отличное от FIRST (используемого по умолчанию), CMake будет искать файлы Common Package Specification в порядке, отличающемся от указанного в спецификации.
Набор префиксов установки формируется в несколько этапов. Если указан NO_DEFAULT_PATH, включаются все параметры NO_*.
-
Поиск префиксов, относящихся только к текущему искомому
<PackageName>. См. политикуCMP0074.Добавлено в версии 3.12.
В частности, поиск выполняется в префиксах, заданных следующими переменными, в указанном порядке:
-
переменная CMake
<PackageName>_ROOT, где<PackageName>— имя пакета с сохранением регистра. -
переменная CMake
<PACKAGENAME>_ROOT, где<PACKAGENAME>— имя пакета в верхнем регистре. См. политикуCMP0144.Добавлено в версии 3.27.
-
переменная среды
<PackageName>_ROOT, где<PackageName>— имя пакета с сохранением регистра. -
переменная среды
<PACKAGENAME>_ROOT, где<PACKAGENAME>— имя пакета в верхнем регистре. См. политикуCMP0144.Добавлено в версии 3.27.
Переменные корневых каталогов пакетов поддерживаются в виде стека, поэтому при вызове из модуля поиска после путей текущего пакета также выполняется поиск по корневым путям из родительского модуля поиска. Этот поиск можно пропустить, передав
NO_PACKAGE_ROOT_PATHили установив переменнуюCMAKE_FIND_USE_PACKAGE_ROOT_PATHвFALSE. -
переменная CMake
-
Поиск путей, указанных в специальных переменных кэша CMake. Предполагается, что они задаются в командной строке с помощью
-DVAR=VALUE. Значения интерпретируются как списки, разделённые точками с запятой. Этот этап можно пропустить, передавNO_CMAKE_PATHили установив переменнуюCMAKE_FIND_USE_CMAKE_PATHвFALSE: -
Поиск путей, указанных в специальных переменных среды CMake. Предполагается, что они задаются в конфигурации командной оболочки пользователя, поэтому в них используется стандартный для хоста разделитель путей (
;в Windows и:в UNIX). Этот этап можно пропустить, передавNO_CMAKE_ENVIRONMENT_PATHили установив переменнуюCMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATHвFALSE:<PackageName>_DIRCMAKE_PREFIX_PATHCMAKE_FRAMEWORK_PATHCMAKE_APPBUNDLE_PATH
- Поиск путей, указанных параметром
HINTS. Это должны быть пути, вычисленные посредством анализа системы, например подсказка, полученная на основе расположения уже найденного элемента. Жёстко заданные предположительные пути следует указывать параметромPATHS. -
Поиск в стандартных переменных среды системы. Этот этап можно пропустить, передав
NO_SYSTEM_ENVIRONMENT_PATHили установив переменнуюCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATHвFALSE. Записи путей, оканчивающиеся на/binили/sbin, автоматически преобразуются в родительские каталоги:PATH
-
Поиск путей, сохранённых в реестре пакетов пользователя CMake. Этот этап можно пропустить, передав
NO_CMAKE_PACKAGE_REGISTRY, установив переменнуюCMAKE_FIND_USE_PACKAGE_REGISTRYвFALSEили установив устаревшую переменнуюCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRYвTRUE.Подробные сведения о реестре пакетов пользователя см. в руководстве
cmake-packages(7). -
Поиск переменных CMake, определённых в файлах платформы для текущей системы. Поиск в
CMAKE_INSTALL_PREFIXиCMAKE_STAGING_PREFIXможно пропустить, передавNO_CMAKE_INSTALL_PREFIXили установив переменнуюCMAKE_FIND_USE_INSTALL_PREFIXвFALSE. Поиск во всех этих расположениях можно пропустить, передавNO_CMAKE_SYSTEM_PATHили установив переменнуюCMAKE_FIND_USE_CMAKE_SYSTEM_PATHвFALSE:Пути платформы, содержащиеся в этих переменных, указывают на расположения, в которых обычно находится установленное программное обеспечение. Например,
/usr/localдля платформ на базе UNIX. -
Поиск путей, сохранённых в системном реестре пакетов CMake. Этот этап можно пропустить, передав
NO_CMAKE_SYSTEM_PACKAGE_REGISTRY, установив переменнуюCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRYвFALSEили установив устаревшую переменнуюCMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRYвTRUE.Подробные сведения о системном реестре пакетов см. в руководстве
cmake-packages(7). - Поиск путей, указанных параметром
PATHS. Обычно это жёстко заданные предположительные пути.
Переменные CMAKE_IGNORE_PATH, CMAKE_IGNORE_PREFIX_PATH, CMAKE_SYSTEM_IGNORE_PATH и CMAKE_SYSTEM_IGNORE_PREFIX_PATH также могут привести к игнорированию некоторых из перечисленных выше расположений.
Поиск по путям выполняется в описанном выше порядке. Используется первый найденный подходящий файл конфигурации пакета, даже если в расположении, находящемся далее в списке путей поиска, есть более новая версия пакета.
Для путей поиска с шаблонами подстановки (*) каталоги, соответствующие шаблону, по умолчанию проверяются в естественном порядке по убыванию. Это поведение можно изменить, задав соответствующим образом переменные CMAKE_FIND_PACKAGE_SORT_ORDER и CMAKE_FIND_PACKAGE_SORT_DIRECTION. Эти переменные определяют порядок, в котором CMake рассматривает соответствия шаблону. Например, если файловая система содержит файлы конфигурации пакета
<prefix>/example-1.2/example-config.cmake <prefix>/example-1.10/example-config.cmake <prefix>/share/example-2.0/example-config.cmake
то find_package(example) (если вышеупомянутые переменные не заданы) выберет example-1.10 (при условии, что и example-1.2, и example-1.10 являются подходящими). Однако обратите внимание, что find_package не найдёт example-2.0, поскольку один из двух других вариантов будет найден раньше.
Чтобы управлять порядком поиска find_package по каталогам, соответствующим шаблону подстановки, используйте CMAKE_FIND_PACKAGE_SORT_ORDER и CMAKE_FIND_PACKAGE_SORT_DIRECTION. Например, чтобы в приведённом выше примере выбрать example-1.2, можно установить
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) set(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
перед вызовом find_package.
Добавлено в версии 3.16: Добавлены переменные CMAKE_FIND_USE_<CATEGORY> для глобального отключения различных расположений поиска.
Изменено в версии 4.0: Переменные CMAKE_FIND_PACKAGE_SORT_ORDER и CMAKE_FIND_PACKAGE_SORT_DIRECTION теперь также управляют порядком, в котором find_package выполняет поиск в каталогах, соответствующих шаблону подстановки в путях поиска <prefix>/<name>.framework/Versions/*/Resources/ и <prefix>/<name>.framework/Versions/*/Resources/CMake. В предыдущих версиях CMake этот порядок не был определён.
Изменено в версии 4.2: Если найдено несколько подходящих совпадений, find_package теперь по умолчанию выбирает версию с самым поздним номером. В предыдущих версиях CMake результат не был определён. В связи с этим значение по умолчанию для CMAKE_FIND_PACKAGE_SORT_ORDER изменено с NONE на NATURAL, а для CMAKE_FIND_PACKAGE_SORT_DIRECTION теперь по умолчанию используется DEC (по убыванию) вместо ASC (по возрастанию).
Переменная CMake CMAKE_FIND_ROOT_PATH задаёт один или несколько каталогов, которые добавляются в начало всех остальных каталогов поиска. Фактически это «переносит корень» всего поиска в указанные расположения. Пути, являющиеся потомками CMAKE_STAGING_PREFIX, исключаются из такого переноса корня, поскольку эта переменная всегда указывает на путь в хост-системе. По умолчанию переменная CMAKE_FIND_ROOT_PATH пуста.
Переменную CMAKE_SYSROOT также можно использовать для указания ровно одного каталога в качестве префикса. Задание CMAKE_SYSROOT имеет и другие последствия. Дополнительные сведения см. в документации по этой переменной.
Эти переменные особенно полезны при кросс-компиляции: они позволяют указать корневой каталог целевой среды, где CMake также будет выполнять поиск. По умолчанию сначала выполняется поиск в каталогах, перечисленных в CMAKE_FIND_ROOT_PATH, затем в каталоге CMAKE_SYSROOT, а после этого — в каталогах без перенесённого корня. Поведение по умолчанию можно изменить, задав переменную CMAKE_FIND_ROOT_PATH_MODE_PACKAGE. Это поведение можно вручную переопределить для отдельного вызова с помощью параметров:
-
CMAKE_FIND_ROOT_PATH_BOTH -
Выполнить поиск в описанном выше порядке.
-
NO_CMAKE_FIND_ROOT_PATH -
Не использовать переменную
CMAKE_FIND_ROOT_PATH. -
ONLY_CMAKE_FIND_ROOT_PATH -
Выполнять поиск только в каталогах с перенесённым корнем и каталогах внутри
CMAKE_STAGING_PREFIX.
Порядок поиска по умолчанию подходит для распространённых случаев использования: от наиболее специфичного к наименее специфичному. Проекты могут переопределить порядок, просто вызвав команду несколько раз и используя параметры NO_*:
find_package (<PackageName> PATHS <paths>... NO_DEFAULT_PATH) find_package (<PackageName>)
Как только один из вызовов завершится успешно, переменной результата будет присвоено значение, которое сохранится в кэше, поэтому дальнейшие вызовы не будут выполнять поиск.
По умолчанию переменная результата содержит путь, по которому найден файл. Перед вызовом find_package можно установить переменную CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS в TRUE, чтобы разрешить символические ссылки и сохранить настоящий путь к файлу.
Любой вызов find_package, не являющийся REQUIRED, можно отключить или сделать обязательным:
- Установка переменной
CMAKE_DISABLE_FIND_PACKAGE_<PackageName>вTRUEотключает пакет. Это также отключает перенаправление к пакету, предоставленномуFetchContent. - Установка переменной
CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>вTRUEделает пакет обязательным.
Одновременная установка обеих переменных в TRUE приводит к ошибке.
Переменная CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> имеет приоритет над ключевым словом OPTIONAL при определении того, является ли пакет обязательным.
Выбор версии в режиме Config
Примечание
При использовании режима Config этот процесс выбора версии применяется независимо от того, была ли указана полная или базовая сигнатура.
Если указан аргумент <version>, режим Config найдёт только ту версию пакета, которая заявляет о совместимости с запрошенной версией (см. описание формата). Если указан параметр EXACT, можно найти только версию пакета, заявляющую о точном совпадении с запрошенной версией. CMake не устанавливает соглашений о значении номеров версий.
Сценарии CMake
Для файлов конфигурации пакетов в виде сценариев CMake номера версий пакетов проверяются с помощью файлов «версии», предоставляемых самими пакетами или FetchContent. Для файла конфигурации пакета-кандидата <config-file>.cmake соответствующий файл версии находится рядом с ним и называется либо <config-file>-version.cmake, либо <config-file>Version.cmake. Если такой файл версии отсутствует, считается, что файл конфигурации несовместим с любой запрошенной версией. Базовый файл версии с универсальным кодом сопоставления версий можно создать с помощью модуля CMakePackageConfigHelpers. Найденный файл версии загружается для проверки запрошенного номера версии. Файл версии загружается во вложенную область видимости, в которой определены следующие переменные:
-
PACKAGE_FIND_NAME -
The
<PackageName> -
PACKAGE_FIND_VERSION -
Полная запрошенная строка версии
-
PACKAGE_FIND_VERSION_MAJOR -
Основная версия, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MINOR -
Дополнительная версия, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_PATCH -
Версия исправления, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_TWEAK -
Версия доработки, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_COUNT -
Количество компонентов версии, от 0 до 4
Если указан диапазон версий, переменные версии выше будут содержать значения, основанные на нижней границе диапазона версий. Это необходимо для сохранения совместимости с пакетами, которые не были реализованы с учетом диапазонов версий. Кроме того, диапазон версий описывается следующими переменными:
-
PACKAGE_FIND_VERSION_RANGE -
Полная запрошенная строка диапазона версий
-
PACKAGE_FIND_VERSION_RANGE_MIN -
Указывает, должна ли нижняя граница диапазона версий включаться или исключаться. В настоящее время единственное поддерживаемое значение этой переменной —
INCLUDE. -
PACKAGE_FIND_VERSION_RANGE_MAX -
Указывает, должна ли верхняя граница диапазона версий включаться или исключаться. Поддерживаемые значения этой переменной:
INCLUDEиEXCLUDE. -
PACKAGE_FIND_VERSION_MIN -
Полная запрошенная строка версии нижней границы диапазона
-
PACKAGE_FIND_VERSION_MIN_MAJOR -
Основная версия нижней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MIN_MINOR -
Дополнительная версия нижней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MIN_PATCH -
Версия исправления нижней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MIN_TWEAK -
Версия доработки нижней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MIN_COUNT -
Количество компонентов версии нижней границы, от 0 до 4
-
PACKAGE_FIND_VERSION_MAX -
Полная запрошенная строка версии верхней границы диапазона
-
PACKAGE_FIND_VERSION_MAX_MAJOR -
Основная версия верхней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MAX_MINOR -
Дополнительная версия верхней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MAX_PATCH -
Версия исправления верхней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MAX_TWEAK -
Версия доработки верхней границы, если она запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MAX_COUNT -
Количество компонентов версии верхней границы, от 0 до 4
Независимо от того, указана ли одна версия или диапазон версий, будет определена переменная PACKAGE_FIND_VERSION_COMPLETE, содержащая полную запрошенную строку версии в указанном виде.
Файл версии проверяет, соответствует ли он запрошенной версии, и задает следующие переменные:
-
PACKAGE_VERSION -
Полная предоставленная строка версии
-
PACKAGE_VERSION_EXACT -
Истина, если версия полностью совпадает
-
PACKAGE_VERSION_COMPATIBLE -
Истина, если версия совместима
-
PACKAGE_VERSION_UNSUITABLE -
Истина, если версия не подходит ни в каком качестве
Эти переменные проверяются командой find_package, чтобы определить, предоставляет ли файл конфигурации приемлемую версию. Они недоступны после возврата вызова find_package. Если версия приемлема, задаются следующие переменные:
-
<PackageName>_VERSION -
Полная предоставленная строка версии
-
<PackageName>_VERSION_MAJOR -
Основная версия, если она предоставлена, иначе 0
-
<PackageName>_VERSION_MINOR -
Дополнительная версия, если она предоставлена, иначе 0
-
<PackageName>_VERSION_PATCH -
Версия исправления, если она предоставлена, иначе 0
-
<PackageName>_VERSION_TWEAK -
Версия доработки, если она предоставлена, иначе 0
-
<PackageName>_VERSION_COUNT -
Количество компонентов версии, от 0 до 4
и загружается соответствующий файл конфигурации пакета.
Примечание
Хотя точное поведение при сопоставлении версий определяется отдельным пакетом, многие пакеты используют write_basic_package_version_file() для предоставления этой логики. Сценарии проверки версии, создаваемые этой командой, имеют некоторые важные особенности при работе с диапазонами версий:
- Верхняя граница диапазона версий является жестким ограничением для принимаемых версий. Поэтому запрос версии
1.4.0может быть удовлетворен пакетом версии1.6.0, который объявляет совместимость в пределах «той же основной версии», однако тот же пакет будет отклонен, если запрошенный диапазон версий —1.4.0...1.5.0. - Обе границы диапазона версий должны соответствовать объявленному уровню совместимости пакета. Например, если пакет объявляет совместимость в пределах «той же основной и дополнительной версии», запрос диапазона версий
1.4.0...<1.5.5или1.4.0...1.5.0приведет к отклонению этого пакета, даже если версия пакета —1.4.1.
В результате невозможно использовать диапазон версий, чтобы расширить диапазон принимаемых совместимых версий пакета.
Общая спецификация пакетов
Для файлов конфигурации пакетов Общей спецификации пакетов CMake проверяет номера версий пакетов согласно набору распознаваемых схем версий. В настоящее время распознаются следующие схемы:
-
simple -
Номера версий представляют собой кортеж целых чисел, за которым может следовать необязательный завершающий сегмент, который не учитывается при сравнении версий.
-
custom -
Механизм интерпретации номеров версий не определен. Для принятия пакета строки версий должны полностью совпадать.
Подробное описание каждой схемы и способов выполнения сравнений для каждой из них см. в разделе version_schema. Обратите внимание, что спецификация может включать схемы, которые не поддерживаются CMake.
Помимо version пакета, CPS позволяет пакетам при необходимости указывать compat_version — самую раннюю версию, с которой пакет совместим. Иными словами, пакет гарантирует, что потребитель, которому нужна compat_version, сможет использовать этот пакет, даже если фактическая версия пакета новее. Если значение не указано, compat_version неявно равна версии пакета, то есть обратная совместимость не обеспечивается.
Если пакет использует распознаваемую схему, CMake определяет, является ли пакет приемлемым, согласно следующим правилам:
- Если указано
EXACTили пакет не предоставляетcompat_version,versionпакета должна совпадать с запрошенной версией. -
В противном случае:
versionпакета должна быть больше или равна запрошенной (минимальной) версии, иcompat_versionпакета должна быть меньше или равна запрошенной (минимальной) версии, и- если указана запрошенная максимальная версия, она должна быть больше (или равна — в зависимости от того, задана ли максимальная версия как включительная или исключительная)
versionпакета.
Примечание
Этот способ сопоставления диапазонов выбран для максимально точного соответствия поведению write_basic_package_version_file(), хотя и без случая, когда чрезмерно широкий диапазон не соответствует ничему.
Для пакетов, использующих схему версий simple, если версия приемлема, задаются следующие переменные:
-
<PackageName>_VERSION -
Полная предоставленная строка версии
-
<PackageName>_VERSION_MAJOR -
Основная версия, если она предоставлена, иначе 0
-
<PackageName>_VERSION_MINOR -
Дополнительная версия, если она предоставлена, иначе 0
-
<PackageName>_VERSION_PATCH -
Версия исправления, если она предоставлена, иначе 0
-
<PackageName>_VERSION_TWEAK -
Версия доработки, если она предоставлена, иначе 0
-
<PackageName>_VERSION_COUNT -
Количество компонентов версии, неотрицательное число
Переменные интерфейса файла пакета
При загрузке модуля поиска или файла конфигурации пакета в виде сценария CMake команда find_package определяет переменные, предоставляющие сведения об аргументах вызова (и восстанавливает их исходные значения перед возвратом):
-
CMAKE_FIND_PACKAGE_NAME -
Искомый
<PackageName> -
<PackageName>_FIND_REQUIRED -
Истина, если был указан параметр
REQUIRED -
<PackageName>_FIND_QUIETLY -
Истина, если был указан параметр
QUIET -
<PackageName>_FIND_REGISTRY_VIEW -
Запрошенный вид, если был указан параметр
REGISTRY_VIEW -
<PackageName>_FIND_VERSION -
Полная запрошенная строка версии
-
<PackageName>_FIND_VERSION_MAJOR -
Основная версия, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MINOR -
Дополнительная версия, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_PATCH -
Версия исправления, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_TWEAK -
Версия доработки, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_COUNT -
Количество компонентов версии, от 0 до 4
-
<PackageName>_FIND_VERSION_EXACT -
Истина, если был указан параметр
EXACT -
<PackageName>_FIND_COMPONENTS -
Список указанных компонентов (обязательных и необязательных)
-
<PackageName>_FIND_REQUIRED_<c> -
Истина, если компонент
<c>является обязательным, ложь, если компонент<c>является необязательным
Если указан диапазон версий, переменные версии выше будут содержать значения, основанные на нижней границе диапазона версий. Это необходимо для сохранения совместимости с пакетами, которые не были реализованы с учетом диапазонов версий. Кроме того, диапазон версий описывается следующими переменными:
-
<PackageName>_FIND_VERSION_RANGE -
Полная запрошенная строка диапазона версий
-
<PackageName>_FIND_VERSION_RANGE_MIN -
Указывает, включается или исключается нижняя граница диапазона версий. В настоящее время
INCLUDE— единственное поддерживаемое значение. -
<PackageName>_FIND_VERSION_RANGE_MAX -
Указывает, включается или исключается верхняя граница диапазона версий. Возможные значения этой переменной:
INCLUDEилиEXCLUDE. -
<PackageName>_FIND_VERSION_MIN -
Полная запрошенная строка версии нижней границы диапазона
-
<PackageName>_FIND_VERSION_MIN_MAJOR -
Основная версия нижней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MIN_MINOR -
Дополнительная версия нижней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MIN_PATCH -
Версия исправления нижней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MIN_TWEAK -
Версия доработки нижней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MIN_COUNT -
Количество компонентов версии нижней границы, от 0 до 4
-
<PackageName>_FIND_VERSION_MAX -
Полная запрошенная строка версии верхней границы диапазона
-
<PackageName>_FIND_VERSION_MAX_MAJOR -
Основная версия верхней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MAX_MINOR -
Дополнительная версия верхней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MAX_PATCH -
Версия исправления верхней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MAX_TWEAK -
Версия доработки верхней границы, если она запрошена, иначе 0
-
<PackageName>_FIND_VERSION_MAX_COUNT -
Количество компонентов версии верхней границы, от 0 до 4
Независимо от того, указана ли одна версия или диапазон версий, будет определена переменная <PackageName>_FIND_VERSION_COMPLETE, содержащая полную запрошенную строку версии в указанном виде.
В режиме Module загруженный модуль поиска отвечает за выполнение запроса, описанного этими переменными; подробности см. в документации модуля поиска. В режиме Config команда find_package автоматически обрабатывает параметры REQUIRED, QUIET и <version>, но оставляет за файлом конфигурации пакета обработку компонентов способом, подходящим для этого пакета. Файл конфигурации пакета может задать <PackageName>_FOUND равной false, чтобы сообщить find_package, что требования к компонентам не выполнены.
Транзитивные требования CPS
Описание пакета в Общей спецификации пакетов состоит из одного или нескольких компонентов, которые, в свою очередь, могут зависеть от других компонентов — внутренних или внешних по отношению к пакету. Если требуются внешние компоненты, предоставляющий их пакет указывается в качестве требования на уровне пакета. Кроме того, набор требуемых компонентов обычно указывается в этом требовании к внешнему пакету.
Если в описании пакета в виде сценария CMake для обработки транзитивных зависимостей использовалась бы команда find_dependency(), то для CPS CMake обрабатывает транзитивные зависимости с помощью внутреннего вложенного вызова find_package. Этот вызов может разрешать зависимости пакетов CPS через либо другой пакет CPS, либо пакет, описанный сценарием CMake. Способ обработки зависимостей компонентов CPS имеет некоторые особенности.
Если кандидатом для разрешения транзитивной зависимости является другой пакет CPS, всё просто: COMPONENTS и «компоненты» CPS напрямую сопоставимы (и фактически являются синонимами «импортированных целей» CMake). Однако пакеты, описанные сценариями CMake, обычно проверяют, были ли найдены требуемые компоненты, даже если в описании пакета отдельные компоненты не указаны. Кроме того, даже те пакеты, в которых компоненты описаны, обычно не связывают их с импортированными целями так же, как это принято в CPS. Поэтому передача набора компонентов, объявленных обязательными пакетом CPS, в COMPONENTS приводила бы к ложным ошибкам при разрешении зависимостей.
Чтобы решить эту проблему, если кандидатом для разрешения транзитивной зависимости CPS является пакет, описанный сценарием CMake, CMake передает требуемые компоненты, объявленные потребляющим пакетом CPS, как OPTIONAL_COMPONENTS и выполняет отдельную внутреннюю проверку, что пакет-кандидат предоставил требуемые импортированные цели. Эти цели должны называться <PackageName>::<ComponentName> в соответствии с соглашением CPS, иначе при проверке пакет будет считаться ненайденным.
© 2000–2026 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/latest/command/find_package.html