⛄️ Почему find_package(Foo) ищет в двух режимах?
Многие думают, что find_package — это «одна команда, один поиск». На деле под капотом работает диспетчер двух разных механизмов, и путаница между ними — частая причина «package not found» при идеально установленной библиотеке.
🔍 Когда вы пишете find_package(Foo), CMake по умолчанию сначала запускает Module mode: ищет файл FindFoo.cmake сперва в CMAKE_MODULE_PATH, а затем во встроенных модулях самого CMake. Это скрипт-разведчик, который через find_path/find_library сам ищет заголовки и библиотеки на диске.
⚡️ Если модуль не найден, включается Config mode: CMake ищет FooConfig.cmake или foo-config.cmake — файл, который поставляет сам пакет и который точно знает, где что лежит.
❗️ Важно: это последовательный поиск с откатом, а не параллельный. И порядок можно перевернуть — с CMake 3.15 переменная CMAKE_FIND_PACKAGE_PREFER_CONFIG=ON заставляет сначала пробовать Config.
❗️ Ключевое различие: FindFoo.cmake пишет кто угодно, кроме автора пакета — потребитель, сторонний разработчик или сами разработчики CMake (так поставляются FindThreads, FindOpenSSL и т.д.), и он угадывает расположение. А FooConfig.cmake поставляет сам автор библиотеки, и он обычно отдаёт готовые импортированные таргеты (Foo::Foo) с уже прописанными путями, флагами и зависимостями. Поэтому Config mode почти всегда надёжнее.
💡 На практике: если современная библиотека (через install(EXPORT)) не находится — проверьте не CMAKE_MODULE_PATH, а CMAKE_PREFIX_PATH, потому что искать нужно именно Config-файл.
Многие думают, что find_package — это «одна команда, один поиск». На деле под капотом работает диспетчер двух разных механизмов, и путаница между ними — частая причина «package not found» при идеально установленной библиотеке.
🔍 Когда вы пишете find_package(Foo), CMake по умолчанию сначала запускает Module mode: ищет файл FindFoo.cmake сперва в CMAKE_MODULE_PATH, а затем во встроенных модулях самого CMake. Это скрипт-разведчик, который через find_path/find_library сам ищет заголовки и библиотеки на диске.
⚡️ Если модуль не найден, включается Config mode: CMake ищет FooConfig.cmake или foo-config.cmake — файл, который поставляет сам пакет и который точно знает, где что лежит.
❗️ Важно: это последовательный поиск с откатом, а не параллельный. И порядок можно перевернуть — с CMake 3.15 переменная CMAKE_FIND_PACKAGE_PREFER_CONFIG=ON заставляет сначала пробовать Config.
find_package(Foo) # сначала Module, потом Config
find_package(Foo CONFIG) # только Config mode
find_package(Foo MODULE) # только Module mode
❗️ Ключевое различие: FindFoo.cmake пишет кто угодно, кроме автора пакета — потребитель, сторонний разработчик или сами разработчики CMake (так поставляются FindThreads, FindOpenSSL и т.д.), и он угадывает расположение. А FooConfig.cmake поставляет сам автор библиотеки, и он обычно отдаёт готовые импортированные таргеты (Foo::Foo) с уже прописанными путями, флагами и зависимостями. Поэтому Config mode почти всегда надёжнее.
💡 На практике: если современная библиотека (через install(EXPORT)) не находится — проверьте не CMAKE_MODULE_PATH, а CMAKE_PREFIX_PATH, потому что искать нужно именно Config-файл.
Просмотры: 141