Spec-Zone.ru › CMake 3.21

FetchContent

Новое в версии 3.11.

  • Обзор
  • Команды

    • Объявление деталей контента
    • Заполнение контента
  • Примеры

Обзор

Этот модуль позволяет заполнять контент во время настройки с помощью любого метода, поддерживаемого модулем ExternalProject. В то время как ExternalProject_Add() загружает контент во время сборки, модуль FetchContent делает контент доступным немедленно, позволяя шагу конфигурации использовать контент в командах, таких как add_subdirectory(), include() или file().

Подробности заполнения контента обычно определяются отдельно от команды, выполняющей фактическое заполнение. Это разделение гарантирует, что все детали зависимостей будут определены до того, как что-либо попытается использовать эти детали для заполнения контента. Это особенно важно в более сложных иерархиях проектов, где зависимости могут быть совместно использованы между несколькими проектами.

Ниже приведён типичный пример объявления деталей контента:

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)

В большинстве типовых случаев заполнение контента может быть выполнено одной командой, например:

FetchContent_MakeAvailable(googletest)

Вышеприведённая команда не только заполняет контент, но также добавляет его в основную сборку (если это возможно), чтобы основная сборка могла использовать цели заполненного проекта и т. д. В некоторых случаях основному проекту может потребоваться более точный контроль над заполнением или может потребоваться явное определение шагов заполнения (например, если необходимо поддерживать версии CMake, более ранние чем 3.14). Типичный шаблон таких пользовательских шагов выглядит так:

FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
  FetchContent_Populate(googletest)
  add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
endif()

Независимо от используемого метода заполнения, при использовании шаблона «объявить-заполнить» с иерархической структурой проекта, проекты на более высоких уровнях иерархии могут переопределять детали заполнения контента, указанные на более низких уровнях проекта. Возможность обнаруживать, был ли контент уже заполнен, гарантирует, что даже если несколько дочерних проектов хотят, чтобы определённый контент был доступен, первым заполнивший его побеждает. Другие дочерние проекты просто могут использовать уже доступный контент вместо повторного заполнения для себя. См. раздел Примеры, демонстрирующий эту ситуацию.

Модуль FetchContent также поддерживает определение и заполнение контента в одном вызове без проверки, был ли контент уже заполнен где-либо ещё в проекте. Это более низкоуровневая операция, и обычно модуль не используется таким образом, но иногда он полезен в качестве части реализации какой-либо более сложной функции или для заполнения некоторого контента в режиме сценариев CMake.

Изменено в версии 3.14: FetchContent команды могут получить доступ к терминалу. Это необходимо для работы запросов пароля и отображения прогресса в реальном времени.

Команды

Объявление деталей контента

FetchContent_Declare
FetchContent_Declare(<name> <contentOptions>...)

Функция FetchContent_Declare() записывает параметры, описывающие способ заполнения указанного контента, но если такие детали уже были записаны ранее в этом проекте (независимо от того, где в иерархии проекта), этот и все последующие вызовы для того же контента <name> игнорируются. Этот подход «первый записавший - побеждает» позволяет иерархическим проектам иметь родительские проекты, переопределяющие детали контента дочерних проектов.

Контент <name> может быть любой строкой без пробелов, но хорошей практикой было бы использовать только буквы, цифры и нижние подчеркивания. Название будет обрабатываться без учёта регистра и должно быть очевидным для представляемого контента, часто являясь именем дочернего проекта или значением, заданным в его команде project() (если это проект CMake). Для известных публичных проектов имя должно, как правило, соответствовать официальному имени проекта. Выбор необычного имени делает маловероятным, что другие проекты, нуждающиеся в том же контенте, будут использовать то же имя, что приводит к многократному заполнению контента.

<contentOptions> может быть любым из параметров загрузки или обновления/патча, которые понимает команда ExternalProject_Add(). Шаги конфигурации, сборки, установки и тестирования явно отключены, и поэтому параметры, связанные с ними, будут проигнорированы. Параметр SOURCE_SUBDIR является исключением, см. FetchContent_MakeAvailable() для получения подробностей о том, как это влияет на поведение.

В большинстве случаев <contentOptions> будет просто несколькими параметрами, определяющими метод загрузки и детали метода, такие как тег коммита или хэш архива. Например:

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)

FetchContent_Declare(
  myCompanyIcons
  URL      https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
  URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
)

FetchContent_Declare(
  myCompanyCertificates
  SVN_REPOSITORY svn+ssh://svn.mycompany.com/srv/svn/trunk/certs
  SVN_REVISION   -r12345
)

В случаях, когда контент загружается из удалённого местоположения, и вы не контролируете этот сервер, рекомендуется использовать хэш для GIT_TAG вместо имени ветки или тега. Хэш коммита более безопасен и помогает подтвердить, что загруженный контент соответствует вашим ожиданиям.

Заполнение контента

В большинстве распространённых случаев заполнение означает предоставление контента основной сборке в соответствии с ранее объявленными подробностями для этой зависимости. Существует два основных шаблона заполнения контента, один основан на вызове FetchContent_GetProperties() и FetchContent_Populate() для более точного управления, а другой — на вызове FetchContent_MakeAvailable() для более простого и автоматизированного подхода. Первый обычно следует этому каноническому шаблону:

# Check if population has already been performed
FetchContent_GetProperties(<name>)
string(TOLOWER "<name>" lcName)
if(NOT ${lcName}_POPULATED)
  # Fetch the content using previously declared details
  FetchContent_Populate(<name>)

  # Set custom variables, policies, etc.
  # ...

  # Bring the populated content into the build
  add_subdirectory(${${lcName}_SOURCE_DIR} ${${lcName}_BINARY_DIR})
endif()

Этот шаблон настолько распространён, что в тех случаях, когда не нужны пользовательские шаги между вызовами FetchContent_Populate() и add_subdirectory(), эквивалентная логика может быть получена вызовом FetchContent_MakeAvailable() вместо этого. Если это соответствует потребностям проекта, FetchContent_MakeAvailable() следует предпочесть, поскольку он проще и предоставляет дополнительные возможности по сравнению с вышеприведённым шаблоном.

FetchContent_Populate
FetchContent_Populate( <name> )

В большинстве случаев единственным аргументом, передаваемым FetchContent_Populate(), является <name>. В этом случае команда предполагает, что подробности о содержимом были записаны в предыдущем вызове FetchContent_Declare(). Данные сохраняются в глобальной переменной, поэтому они не зависят от таких факторов, как область видимости переменных или каталогов. Поэтому не имеет значения, где в проекте ранее были объявлены данные, до тех пор, пока они были объявлены до вызова FetchContent_Populate(). Эти сохранённые данные затем используются для построения вызова ExternalProject_Add() в частном подпроекте для немедленного заполнения содержимого. Реализация ExternalProject_Add() гарантирует, что если содержимое уже было заполнено в предыдущем запуске CMake, оно будет повторно использовано, а не перезаполнено. В распространённом случае, когда заполнение включает загрузку содержимого, затраты на загрузку производятся только один раз.

Внутренняя глобальная переменная фиксирует, когда определённый запрос на заполнение содержимого был обработан. Если FetchContent_Populate() вызывается более одного раза для одного и того же имени содержимого в ходе конфигурации, второй вызов завершится ошибкой. Проекты могут и должны проверить, была ли обработка заполнения содержимого уже выполнена с помощью команды FetchContent_GetProperties() перед вызовом FetchContent_Populate().

FetchContent_Populate() установит три переменные в области видимости вызывающего; <lcName>_POPULATED, <lcName>_SOURCE_DIR и <lcName>_BINARY_DIR, где <lcName> — строка <name> в нижнем регистре. <lcName>_POPULATED всегда будет установлено в True вызовом. <lcName>_SOURCE_DIR — это местоположение, где содержимое может быть найдено по возвращении (оно уже будет заполнено), а <lcName>_BINARY_DIR — это каталог, предназначенный для использования в качестве соответствующего каталога сборки. Основной случай использования двух переменных каталога — вызов add_subdirectory() сразу после заполнения, например:

FetchContent_Populate(FooBar ...)
add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR})

Значения трёх переменных также могут быть получены из любой точки иерархии проекта с помощью команды FetchContent_GetProperties().

Несколько переменных кэша влияют на поведение всех операций заполнения содержимого, выполненных с помощью данных, сохранённых из вызова FetchContent_Declare():

FETCHCONTENT_BASE_DIR

В большинстве случаев сохранённые данные не содержат каких-либо параметров, относящихся к каталогам, используемым для внутреннего подпроекта, конечным областям исходного и скомпилированного кода. Обычно лучше оставить эти решения модулю FetchContent для обработки от имени проекта. Переменная кэша FETCHCONTENT_BASE_DIR управляет точкой, в которой собираются все каталоги заполнения содержимого, но в большинстве случаев разработчикам не нужно будет изменять это. По умолчанию расположение — ${CMAKE_BINARY_DIR}/_deps, но если разработчики изменят это значение, они должны стремиться сохранять путь коротким и чуть ниже верхнего уровня дерева сборки, чтобы избежать проблем с длиной пути в Windows.

FETCHCONTENT_QUIET

Выходные данные логов во время заполнения могут быть весьма подробными, что делает этап конфигурации довольно шумным. Этот параметр кэша (ON по умолчанию) скрывает все выходные данные заполнения, за исключением случаев возникновения ошибок. Если возникают проблемы с зависанием загрузок, временное отключение этого параметра может помочь в диагностике, какой запрос на заполнение содержимого вызывает проблему.

FETCHCONTENT_FULLY_DISCONNECTED

При включении этого параметра не предпринимается попыток загрузить или обновить какое-либо содержимое. Предполагается, что всё содержимое уже было заполнено в предыдущем запуске или каталоги исходных файлов указывают на существующее содержимое, предоставленное разработчиком вручную (используя параметры, описанные ниже). Если разработчик знает, что изменения в каких-либо данных содержимого не вносились, включение этого параметра может значительно ускорить этап конфигурации. По умолчанию он ON.

FETCHCONTENT_UPDATES_DISCONNECTED

Это менее жёсткий контроль загрузки/обновления по сравнению с FETCHCONTENT_FULLY_DISCONNECTED. Вместо того, чтобы полностью игнорировать логику загрузки и обновления, FETCHCONTENT_UPDATES_DISCONNECTED отключает только этап обновления. Следовательно, если содержимое не было загружено ранее, оно всё равно будет загружено при включении этого параметра. Это может ускорить этап конфигурации, но не так сильно, как FETCHCONTENT_FULLY_DISCONNECTED. По умолчанию он OFF.

В дополнение к вышеперечисленным переменным кэша, для каждого имени содержимого также определены следующие переменные кэша (<ucName> — это заглавная версия <name>):

FETCHCONTENT_SOURCE_DIR_<ucName>

Если это установлено, то для указанного содержимого не выполняются действия по загрузке или обновлению, и переменная <lcName>_SOURCE_DIR возвращается вызывающей стороне, указывая на это местоположение. Это даёт разработчикам возможность иметь отдельный контрольный пункт содержимого, который они могут свободно изменять без вмешательства сборки. Сборка просто использует этот существующий исходный код, но при этом по-прежнему определяет <lcName>_BINARY_DIR для указания внутренней области сборки. Разработчикам настоятельно рекомендуется использовать этот механизм, а не редактировать исходный код, заполненный по умолчанию, поскольку изменения в исходном коде по умолчанию могут быть потеряны, когда данные содержимого проекта меняются.

FETCHCONTENT_UPDATES_DISCONNECTED_<ucName>

Это эквивалент FETCHCONTENT_UPDATES_DISCONNECTED для каждого содержимого. Если глобальный параметр или этот параметр ON, то обновления будут отключены для указанного содержимого. Отключение обновлений для отдельных элементов содержимого может быть полезно для содержимого, данные которого редко изменяются, при этом оставляя другие часто изменяемые элементы с включёнными обновлениями.

Команда FetchContent_Populate() также поддерживает синтаксис, позволяющий указать данные содержимого непосредственно, а не используя сохранённые данные. Это более низкий уровень, и использование этого формата следует избегать в пользу использования сохранённых данных содержимого, как описано выше. Тем не менее, в определённых ситуациях это может быть полезно для вызова заполнения содержимого как изолированной операции (обычно как части реализации какой-либо другой функции более высокого уровня или при использовании CMake в режиме скрипта):

FetchContent_Populate( <name>
  [QUIET]
  [SUBBUILD_DIR <subBuildDir>]
  [SOURCE_DIR <srcDir>]
  [BINARY_DIR <binDir>]
  ...
)

Этот формат имеет ряд ключевых отличий от ситуации, когда предоставлен только <name>:

  • Предполагается, что все необходимые данные заполнения были предоставлены напрямую в вызове FetchContent_Populate(). Любые сохранённые данные для <name> игнорируются.
  • Не проверяется, было ли содержимое для <name> уже заполнено.
  • Не устанавливается глобальная переменная для записи о том, что заполнение произошло.
  • Глобальные переменные не записывают каталоги исходных и двоичных файлов для заполненного содержимого.
  • Переменные кэша FETCHCONTENT_FULLY_DISCONNECTED и FETCHCONTENT_UPDATES_DISCONNECTED игнорируются.

Переменные <lcName>_SOURCE_DIR и <lcName>_BINARY_DIR всё равно возвращаются вызывающей стороне, но поскольку эти расположения не сохраняются как глобальные переменные при использовании этого формата, они доступны только в области вызова и ниже, а не во всей иерархии проекта. Переменная <lcName>_POPULATED не устанавливается в области вызывающей стороны в этом формате.

Поддерживаемые параметры для FetchContent_Populate() такие же, как и для FetchContent_Declare(). Те несколько параметров, показанных выше, либо специфичны для FetchContent_Populate(), либо их поведение немного отличается от того, как ExternalProject_Add() их обрабатывает.

QUIET

Параметр QUIET можно указать для скрытия вывода, связанного с заполнением указанного содержимого. Если заполнение завершается неудачей, вывод будет отображаться независимо от того, был ли этот параметр указан или нет, чтобы можно было диагностировать причину ошибки. Глобальная переменная кэша FETCHCONTENT_QUIET не влияет на вызовы FetchContent_Populate() , где данные содержимого предоставляются напрямую.

SUBBUILD_DIR

Аргумент SUBBUILD_DIR можно указать, чтобы изменить расположение подпроекта, созданного для выполнения заполнения. Значение по умолчанию — ${CMAKE_CURRENT_BINARY_DIR}/<lcName>-subbuild, и вряд ли потребуется переопределять это значение. Если указан относительный путь, он будет интерпретироваться как относительный к CMAKE_CURRENT_BINARY_DIR. Этот параметр не следует путать с параметром SOURCE_SUBDIR, который влияет только на команду FetchContent_MakeAvailable().

SOURCE_DIR, BINARY_DIR

Аргументы SOURCE_DIR и BINARY_DIR поддерживаются командой ExternalProject_Add(), но разные значения по умолчанию используются командой FetchContent_Populate(). SOURCE_DIR по умолчанию ${CMAKE_CURRENT_BINARY_DIR}/<lcName>-src, а BINARY_DIR по умолчанию ${CMAKE_CURRENT_BINARY_DIR}/<lcName>-build. Если указан относительный путь, он будет интерпретироваться как относительный к CMAKE_CURRENT_BINARY_DIR.

В дополнение к вышеуказанным явным параметрам, любые другие нераспознанные параметры передаются без изменений команде ExternalProject_Add() для выполнения этапов загрузки, применения исправлений и обновления. Следующие параметры запрещены (они отключены командой FetchContent_Populate()):

  • CONFIGURE_COMMAND
  • BUILD_COMMAND
  • INSTALL_COMMAND
  • TEST_COMMAND

Если использовать FetchContent_Populate() в режиме скрипта CMake, следует учитывать, что реализация создаёт подмодуль, поэтому требуется генератор CMake и инструмент сборки. Если эти компоненты не могут быть найдены по умолчанию, то необходимо соответствующим образом установить переменные CMAKE_GENERATOR и/или CMAKE_MAKE_PROGRAM в командной строке при вызове скрипта.

Новое в версии 3.18: Добавлена поддержка опций DOWNLOAD_NO_EXTRACT и SOURCE_SUBDIR.

FetchContent_GetProperties

При использовании сохранённых данных о содержимом, вызов FetchContent_Populate() записывает информацию в глобальные свойства, которые могут быть запрошены в любое время. Эта информация включает исходный и бинарный каталоги, связанные с содержимым, а также информацию о том, была ли обработка содержимого выполнена во время текущего этапа конфигурации.

FetchContent_GetProperties( <name>
  [SOURCE_DIR <srcDirVar>]
  [BINARY_DIR <binDirVar>]
  [POPULATED <doneVar>]
)

Опции SOURCE_DIR, BINARY_DIR и POPULATED могут быть использованы для указания свойств, которые должны быть извлечены. Каждая опция принимает значение, которое является именем переменной, в которой следует сохранить это свойство. Однако в большинстве случаев указывается только <name>, в результате вызов установит те же переменные, что и вызов FetchContent_Populate(name). Это позволяет использовать следующий канонический шаблон, который гарантирует, что соответствующие переменные всегда будут определены, независимо от того, была ли обработка выполнена в другой части проекта:

FetchContent_GetProperties(foobar)
if(NOT foobar_POPULATED)
  FetchContent_Populate(foobar)
  ...
endif()

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

FetchContent_MakeAvailable
FetchContent_MakeAvailable( <name1> [<name2>...] )

Новое в версии 3.14.

Эта команда реализует общий шаблон, обычно необходимый для большинства зависимостей. Она итерируется по каждой из перечисленных зависимостей и для каждой из них примерно следует каноническому шаблону, представленному в начале этого раздела. Важное отличие заключается в том, что add_subdirectory() будет вызываться только для обработанного содержимого, если в его исходном каталоге верхнего уровня существует файл CMakeLists.txt. Это позволяет использовать команду для зависимостей, которые делают загруженное содержимое доступным в известном месте, но не требуют или не поддерживают непосредственного добавления в сборку.

Опция SOURCE_SUBDIR может быть указана в объявленных деталях, чтобы указать FetchContent_MakeAvailable() искать файл CMakeLists.txt в подкаталоге ниже верхнего уровня (то есть таким же образом, как SOURCE_SUBDIR используется командой ExternalProject_Add()). SOURCE_SUBDIR всегда должен быть относительным путём. Смотрите следующий раздел для примера использования этой опции.

Примеры

В этом первом довольно простом примере гарантируется, что некоторые популярные тестовые фреймворки доступны основной сборке:

include(FetchContent)
FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)
FetchContent_Declare(
  Catch2
  GIT_REPOSITORY https://github.com/catchorg/Catch2.git
  GIT_TAG        de6fe184a9ac1a06895cdd1c9b437f0a0bdf14ad # v2.13.4
)

# After the following call, the CMake targets defined by googletest and
# Catch2 will be defined and available to the rest of the build
FetchContent_MakeAvailable(googletest Catch2)

Если файл CMakeLists.txt подпроекта не находится в корне его исходного дерева, можно использовать опцию SOURCE_SUBDIR для указания FetchContent местоположения этого файла. Следующий пример демонстрирует, как использовать эту опцию, а также задаёт переменную, имеющую смысл для подпроекта перед его включением в основную сборку:

include(FetchContent)
FetchContent_Declare(
  protobuf
  GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
  GIT_TAG        ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0
  SOURCE_SUBDIR  cmake
)
set(protobuf_BUILD_TESTS OFF)
FetchContent_MakeAvailable(protobuf)

В более сложных иерархиях проектов отношения зависимости могут быть более сложными. Рассмотрим иерархию, где projA является проектом верхнего уровня, и он напрямую зависит от проектов projB и projC. Оба проекта projB и projC могут быть собраны автономно, и оба также зависят от другого проекта projD. projB дополнительно зависит от projE. Этот пример предполагает, что все пять проектов доступны на корпоративном сервере Git.

projA:

include(FetchContent)
FetchContent_Declare(
  projB
  GIT_REPOSITORY git@mycompany.com:git/projB.git
  GIT_TAG        4a89dc7e24ff212a7b5167bef7ab079d
)
FetchContent_Declare(
  projC
  GIT_REPOSITORY git@mycompany.com:git/projC.git
  GIT_TAG        4ad4016bd1d8d5412d135cf8ceea1bb9
)
FetchContent_Declare(
  projD
  GIT_REPOSITORY git@mycompany.com:git/projD.git
  GIT_TAG        origin/integrationBranch
)
FetchContent_Declare(
  projE
  GIT_REPOSITORY git@mycompany.com:git/projE.git
  GIT_TAG        v2.3-rc1
)

# Order is important, see notes in the discussion further below
FetchContent_MakeAvailable(projD projB projC)

projB:

include(FetchContent)
FetchContent_Declare(
  projD
  GIT_REPOSITORY git@mycompany.com:git/projD.git
  GIT_TAG        20b415f9034bbd2a2e8216e9a5c9e632
)
FetchContent_Declare(
  projE
  GIT_REPOSITORY git@mycompany.com:git/projE.git
  GIT_TAG        68e20f674a48be38d60e129f600faf7d
)

FetchContent_MakeAvailable(projD projE)

projC:

include(FetchContent)
FetchContent_Declare(
  projD
  GIT_REPOSITORY git@mycompany.com:git/projD.git
  GIT_TAG        7d9a17ad2c962aa13e2fbb8043fb6b8a
)

# This particular version of projD requires workarounds
FetchContent_GetProperties(projD)
if(NOT projd_POPULATED)
  FetchContent_Populate(projD)

  # Copy an additional/replacement file into the populated source
  file(COPY someFile.c DESTINATION ${projd_SOURCE_DIR}/src)

  add_subdirectory(${projd_SOURCE_DIR} ${projd_BINARY_DIR})
endif()

Следует обратить внимание на несколько ключевых моментов:

  • projB и projC определяют различные данные о содержимом для projD, но projA также определяет набор данных о содержимом для projD. Так как projA определит их первым, данные из projB и projC не будут использованы. Переопределяющие данные, определённые projA, не обязательно должны совпадать с данными из projB или projC, но проект верхнего уровня должен обеспечить, чтобы определённые им данные всё ещё имели смысл для дочерних проектов.
  • В вызове FetchContent_MakeAvailable() проекта projA, projD перечислен раньше projB и projC, чтобы гарантировать, что projA контролирует способ обработки projD.
  • Хотя projA определяет данные о содержимом для projE, ему не нужно явно вызывать FetchContent_MakeAvailable(projE) или FetchContent_Populate(projD) сам. Вместо этого он оставляет это дочерним projB. Для проектов верхнего уровня часто достаточно просто определить переопределяющие данные о содержимом и предоставить дочерним проектам фактическое заполнение. Это позволяет избежать ненужного повторения одних и тех же действий на каждом уровне иерархии проекта.

Проектам не всегда нужно добавлять обработанное содержимое в сборку. Иногда проект просто хочет сделать загруженное содержимое доступным в предсказуемом месте. Следующий пример гарантирует, что набор стандартных файлов инструментария компании (и, возможно, даже сами бинарные файлы инструментария) доступны достаточно рано, чтобы использоваться в той же сборке.

cmake_minimum_required(VERSION 3.14)

include(FetchContent)
FetchContent_Declare(
  mycom_toolchains
  URL  https://intranet.mycompany.com//toolchains_1.3.2.tar.gz
)
FetchContent_MakeAvailable(mycom_toolchains)

project(CrossCompileExample)

Проект можно настроить для использования одного из загруженных наборов инструментов:

cmake -DCMAKE_TOOLCHAIN_FILE=_deps/mycom_toolchains-src/toolchain_arm.cmake /path/to/src

Когда CMake обрабатывает файл CMakeLists.txt, он загрузит и распакует архив в _deps/mycompany_toolchains-src относительно каталога сборки. Переменная CMAKE_TOOLCHAIN_FILE не используется до тех пор, пока не будет достигнута команда project(), в этот момент CMake ищет указанный файл инструментария относительно каталога сборки. Так как архив уже был загружен и распакован к тому моменту, файл инструментария будет на месте, даже в первый раз, когда cmake запускается в каталоге сборки.

Наконец, следующий пример демонстрирует, как загрузить и распаковать архив firmware с помощью CMake's script mode. Вызов FetchContent_Populate() указывает все данные о содержимом, и распакованное firmware будет размещено в каталоге firmware ниже текущего каталога работы.

getFirmware.cmake:

# NOTE: Intended to be run in script mode with cmake -P
include(FetchContent)
FetchContent_Populate(
  firmware
  URL        https://mycompany.com/assets/firmware-1.23-arm.tar.gz
  URL_HASH   MD5=68247684da89b608d466253762b0ff11
  SOURCE_DIR firmware
)

© 2000–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.21/module/FetchContent.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API