Должен ли я изменить CMAKE_MODULE_PATH в PackageConfig.cmake - PullRequest
2 голосов
/ 10 января 2020

Я пишу файл MyPackageConfig для моего проекта с экспортированными целями, чтобы другие проекты могли легко найти MyPackage и его зависимости. Это выглядит так:

include(CMakeFindDependencyMacro)

find_dependency(LIB1_WITHOUT_CMAKE_CONFIG)
find_dependency(LIB2_WITH_CMAKE_CONFIG)

include (Some/Install/Dir/MyPackageTargets.cmake)

Мне интересно, будет ли разумно добавить следующие строки в MyPackageConfig.cmake до вызова find_dependency

# Find target dependencies
# Allows packages linking with MyPackage to use the find modules that
# MyPackage used to find it's dependencies. Since this path is appended to
# the existing module path, the calling package's module path will take
# precedence

list(APPEND CMAKE_MODULE_PATH @CMAKE_INSTALL_PREFIX@/lib/cmake/MyPackage/modules)

# Allows packages linking with MyPackage to find MyPacakge's dependencies if
# they don't already have them. Since this path (or these paths) are
# appended to the existing prefix path, the calling package's prefix
# path will take precedence

list(APPEND CMAKE_PREFIX_PATH @CMAKE_PREFIX_PATH@)

find_dependency(LIB1_WITHOUT_CMAKE_CONFIG)
find_dependency(LIB2_WITH_CMAKE_CONFIG)

Хорошая идея? Нет?

Более подробное объяснение моего обоснования:

  1. Как YourPackage, использующий MyPackage, находит LIB1?

    (i). Вы можете написать свой собственный FindLIB1.cmake, но это дублирование усилий

    (ii). Я мог бы установить свой FindLIB1.cmake вместе с MyPackageConfig.cmake в директории Modules. Но вам придется включить этот путь в путь к модулю.

    Мое предложение: добавьте строку перед find_dependency(LIB1_WITHOUT_CMAKE_CONFIG), изменив путь к модулю следующим образом:

  list(APPEND CMAKE_MODULE_PATH  @CMAKE_INSTALL_PREFIX@/lib/cmake/mstk/modules)

Это гарантирует, что если у вас есть FindLIB1.cmake, он будет использоваться, но если вы его не найдете, мой будет найден и использован.

Как вы узнаете, где находятся LIB1 и LIB2 (включая файл конфигурации LIB2)?

Добавив строку

 list(APPEND CMAKE_PREFIX_PATH @CMAKE_PREFIX_PATH@)

Я говорю ваш пакет, в котором я искал и нашел мои зависимости (но только если у вас их еще не было в указанном вами CMAKE_PREFIX_PATH)

1 Ответ

1 голос
/ 10 января 2020

Да, вы можете изменить переменные, такие как CMAKE_MODULE_PATH или CMAKE_PREFIX_PATH для целей вашего скрипта конфигурации.

Любой "хороший" проект должен быть подготовлен к добавлению / добавлению CMAKE_PREFIX_PATH, потому что эта переменная обычно может быть установлен пользователем (при вызове cmake). Что касается CMAKE_MODULE_PATH, имена модулей в разных каталогах редко конфликтуют.

Некоторые подсказки:

  1. Вы можете восстановить переменные в конце вашего сценария. Таким образом, вы не будете влиять на вызывающий код при изменении переменных:

    # Store old value of the variable
    set(old_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
    # Change variable, use it, ...
    # ...
    # Restore the variable at the end
    set(CMAKE_MODULE_PATH ${old_CMAKE_MODULE_PATH})
    

    Обратите внимание, однако, что find_dependency возвращается из сценария, если (внутренний) пакет не найден, поэтому восстановление переменной приведет к не срабатывать в этом случае. Но обычно find_package() вызывается с ключевым словом REQUIRED , поэтому невозможность найти внутренний пакет будет фатальной.

  2. Вместо изменения CMAKE_PREFIX_PATH вы можете установить другие переменные , которые влияют только на указанный c сценарий поиска и не влияют на других. Например, многие скрипты поиска используют XXX_ROOT переменные для подсказки о местоположении.

    Для самого скрипта поиска конфигурации вы можете использовать PATHS или HINTS опции find_package():

    # Was:
    #- list(APPEND CMAKE_PREFIX_PATH @CMAKE_PREFIX_PATH@)
    #- find_dependency(LIB2_WITH_CMAKE_CONFIG)
    # Replace with:
    find_dependency(LIB2_WITH_CMAKE_CONFIG
        PATHS @CMAKE_PREFIX_PATH@ # Where to find config script
        NO_DEFAULT_PATH # Do not search other places
    )
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...