add_custom_command
Добавить пользовательское правило сборки в сгенерированную систему сборки.
Существует два основных варианта сигнатур для add_custom_command.
Генерация файлов
Первый вариант сигнатуры предназначен для добавления пользовательской команды для создания выходного файла:
add_custom_command(OUTPUT output1 [output2 ...]
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[MAIN_DEPENDENCY depend]
[DEPENDS [depends...]]
[BYPRODUCTS [files...]]
[IMPLICIT_DEPENDS <lang1> depend1
[<lang2> depend2] ...]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[DEPFILE depfile]
[JOB_POOL job_pool]
[VERBATIM] [APPEND] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS])
Это определяет команду для генерации указанного OUTPUT файла(ов). Цель, созданная в той же директории (CMakeLists.txt файл), которая указывает любой вывод пользовательской команды как исходный файл, получает правило для генерации файла с помощью команды во время сборки. Не перечисляйте вывод более чем в одной независимой цели, которая может собираться параллельно, иначе два экземпляра правила могут конфликтовать (вместо этого используйте команду add_custom_target() для управления командой и сделайте остальные цели зависимыми от этой). В терминах makefile это создаёт новую цель в следующем формате:
OUTPUT: MAIN_DEPENDENCY DEPENDS
COMMAND
Параметры:
-
APPEND -
Добавить значения опций
COMMANDиDEPENDSк пользовательской команде для первого указанного вывода. Должна была быть предыдущая вызов этой команды с тем же выводом. ОпцииCOMMENT,MAIN_DEPENDENCY, иWORKING_DIRECTORYв настоящее время игнорируются, когда задан параметр APPEND, но могут быть использованы в будущем. -
BYPRODUCTS -
Укажите файлы, которые команда должна создать, но время изменения которых может быть или не быть новее, чем у зависимостей. Если имя побочного продукта является относительным путем, оно будет интерпретировано относительно каталога дерева сборки, соответствующего текущему каталогу исходного кода. Каждый файл побочного продукта будет автоматически помечен свойством файла исходного кода
GENERATED.Явное указание побочных продуктов поддерживается генератором
Ninjaдля того, чтобы сообщить инструменту сборкиninjaо том, как перегенерировать побочные продукты, если они отсутствуют. Это также полезно, когда другие правила сборки (например, пользовательские команды) зависят от побочных продуктов. Ninja требует правила сборки для любого сгенерированного файла, от которого зависит другое правило, даже если существуют только зависимости по порядку, чтобы гарантировать, что побочные продукты будут доступны до сборки их зависимых.Генераторы Makefile Generators удалят
BYPRODUCTSи другие файлыGENERATEDво времяmake clean. -
COMMAND -
Укажите командную строку(и) для выполнения во время сборки. Если указано более одной
COMMAND, они будут выполнены в порядке следования, но не обязательно составлены в состоятельный командный интерпретатор или пакетный скрипт. (Для запуска полного сценария используйте командуconfigure_file()или командуfile(GENERATE)для его создания, а затем укажитеCOMMANDдля запуска.) Необязательный аргументARGSпредназначен для обратной совместимости и будет проигнорирован.Если
COMMANDуказывает имя целевого исполняемого файла (созданного командойadd_executable()), он будет автоматически заменён расположением созданного во время сборки исполняемого файла, если выполняется хотя бы одно из следующих условий:- Целевой файл не компилируется в кросс-платформенной среде (т.е. переменная
CMAKE_CROSSCOMPILINGне установлена в true). - Целевой файл компилируется в кросс-платформенной среде и предоставляется эмулятор (т.е. его свойство целевого файла
CROSSCOMPILING_EMULATORустановлено). В этом случае содержимоеCROSSCOMPILING_EMULATORбудет добавлено в начало команды перед расположением целевого исполняемого файла.
Если ни одно из вышеперечисленных условий не выполняется, предполагается, что имя команды — это программа, которую нужно найти в
PATHво время сборки.Аргументы к
COMMANDмогут использоватьgenerator expressions. Используйте выражение генератораTARGET_FILEдля ссылки на расположение целевого файла позже в командной строке (т.е. в качестве аргумента команды, а не как команды для выполнения).Всякий раз, когда целевой файл используется как команда для выполнения или упоминается в выражении генератора в качестве аргумента команды, автоматически добавляется зависимость уровня целевого файла, чтобы указанный целевой файл был построен до любого целевого файла, использующего эту пользовательскую команду. Однако это НЕ добавляет зависимость на уровне файла, которая заставила бы пользовательскую команду повторно запускаться всякий раз, когда исполняемый файл перекомпилируется. Перечислите имена целевых файлов с опцией
DEPENDSдля добавления таких зависимостей на уровне файла. - Целевой файл не компилируется в кросс-платформенной среде (т.е. переменная
-
COMMENT -
Отобразить заданное сообщение перед выполнением команд во время сборки.
-
DEPENDS -
Укажите файлы, от которых зависит команда. Каждый аргумент преобразуется в зависимость следующим образом:
- Если аргумент — имя целевого файла (созданного командой
add_custom_target(),add_executable()илиadd_library()), создаётся зависимость уровня целевого файла, чтобы гарантировать, что целевой файл будет построен до любого целевого файла, использующего данную пользовательскую команду. Кроме того, если целевой файл является исполняемым файлом или библиотекой, создаётся зависимость на уровне файла, чтобы заставить пользовательскую команду повторно запускаться всякий раз, когда целевой файл перекомпилируется. - Если аргумент — абсолютный путь, создаётся зависимость на уровне файла на этом пути.
- Если аргумент — имя файла исходного кода, добавленного в целевой файл или для которого установлено свойство файла исходного кода, создаётся зависимость на уровне файла для этого файла исходного кода.
- Если аргумент — относительный путь и он существует в текущем каталоге исходного кода, создаётся зависимость на уровне файла для этого файла в текущем каталоге исходного кода.
- В противном случае, создаётся зависимость на уровне файла на этом пути относительно текущего каталога бинарных файлов.
Если какая-либо зависимость является
OUTPUTдругой пользовательской команды в том же каталоге (файлCMakeLists.txt), CMake автоматически включает другую пользовательскую команду в целевой файл, в котором построена эта команда. Добавляется зависимость уровня целевого файла, если любая зависимость указана какBYPRODUCTSцелевого файла или любого из его событий сборки в том же каталоге, чтобы убедиться, что побочные продукты будут доступны.Если
DEPENDSне указано, команда будет выполняться всякий раз, когдаOUTPUTотсутствует; если команда фактически не создаётOUTPUT, правило всегда будет выполняться.Аргументы к
DEPENDSмогут использоватьgenerator expressions. - Если аргумент — имя целевого файла (созданного командой
-
COMMAND_EXPAND_LISTS -
Списки в аргументах
COMMANDбудут расширяться, включая те, которые созданы с помощьюgenerator expressions, что позволяет использовать аргументыCOMMAND, такие как${CC} "-I$<JOIN:$<TARGET_PROPERTY:foo,INCLUDE_DIRECTORIES>,;-I>" foo.cc, для правильного расширения. -
IMPLICIT_DEPENDS -
Запрос сканирования неявных зависимостей входного файла. Указанный язык определяет язык программирования, сканер зависимостей которого следует использовать. В настоящее время поддерживаются только сканеры языков
CиCXX. Язык должен быть указан для каждого файла в спискеIMPLICIT_DEPENDS. Зависимости, обнаруженные в результате сканирования, добавляются к тем, которые существуют у пользовательской команды во время сборки. Обратите внимание, что опцияIMPLICIT_DEPENDSв настоящее время поддерживается только для генераторов Makefile и будет проигнорирована другими генераторами. -
JOB_POOL -
Укажите
poolдля генератораNinja. Несовместимо сUSES_TERMINAL, что подразумевает пулconsole. Использование пула, который не определён с помощьюJOB_POOLS, приводит к ошибке ninja во время сборки. -
MAIN_DEPENDENCY -
Укажите первичный файл исходного кода для команды. Это рассматривается так же, как любое значение, переданное в опцию
DEPENDS, но также подразумевает для генераторов Visual Studio, где повесить пользовательскую команду. Каждый файл исходного кода может иметь не более одной команды, указывающей его в качестве основной зависимости. Команда компиляции (т. е. для библиотеки или исполняемого файла) считается неявной основной зависимостью, которая будет скрыто перезаписана указанием пользовательской команды. -
OUTPUT -
Укажите выходные файлы, которые команда должна создать. Если имя выходного файла является относительным путем, оно будет интерпретировано относительно каталога дерева сборки, соответствующего текущему каталогу исходного кода. Каждый выходной файл будет автоматически помечен свойством файла исходного кода
GENERATED. Если результат выполнения пользовательской команды не фактически создаётся как файл на диске, он должен быть помечен свойством файла исходного кодаSYMBOLIC. -
USES_TERMINAL -
Команда получит прямой доступ к терминалу, если это возможно. С генератором
Ninjaэто помещает команду вconsolepool. -
VERBATIM
-
Все аргументы команд будут корректно экранированы для инструмента сборки, чтобы вызванная команда получала каждый аргумент без изменений. Обратите внимание, что один уровень экранирования всё ещё используется процессором языка CMake перед тем, как add_custom_command увидит аргументы. Рекомендуется использовать
VERBATIM, так как это обеспечивает правильное поведение. ЕслиVERBATIMне указан, поведение зависит от платформы, так как нет защиты от специфичных для инструмента специальных символов. -
WORKING_DIRECTORY -
Выполнить команду с заданным текущим каталогом. Если это относительный путь, он будет интерпретирован относительно каталога сборки, соответствующего текущему каталогу исходных файлов.
Аргументы для
WORKING_DIRECTORYмогут использоватьgenerator expressions. -
DEPFILE -
Указать
.ddepfile для генератораNinja. Файл.dсодержит зависимости, обычно генерируемые самой пользовательской командой. ИспользованиеDEPFILEс генераторами, отличными от Ninja, является ошибкой.
События сборки
Второй вариант сигнатуры добавляет пользовательскую команду к цели, такой как библиотека или исполняемый файл. Это полезно для выполнения операции перед или после построения цели. Команда становится частью цели и будет выполняться только при построении самой цели. Если цель уже построена, команда не будет выполняться.
add_custom_command(TARGET <target>
PRE_BUILD | PRE_LINK | POST_BUILD
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[BYPRODUCTS [files...]]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[VERBATIM] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS])
Это определяет новую команду, которая будет связана со сборкой указанной <target>. <target> должна быть определена в текущем каталоге; цели, определённые в других каталогах, могут не быть указаны.
Время выполнения команды определяется следующим:
-
PRE_BUILD -
В генераторах Visual Studio выполняется до выполнения любых других правил в рамках цели. В других генераторах выполняется непосредственно перед
PRE_LINKкомандами. -
PRE_LINK -
Выполняется после компиляции исходных файлов, но перед компоновкой двоичного файла или запуском инструмента библиотекаря или архиватора для статической библиотеки. Это не определено для целей, созданных командой
add_custom_target(). -
POST_BUILD -
Выполняется после выполнения всех остальных правил в рамках цели.
Примечание
Поскольку в пользовательских командах можно использовать выражения генератора, можно определить строки COMMAND или целые пользовательские команды, которые вычисляются как пустые строки для некоторых конфигураций. Для генераторов Visual Studio 2010 (и новее) эти строки команд или пользовательские команды будут опушены для конкретной конфигурации, и «команда-пустая-строка» не будет добавлена.
Это позволяет добавлять отдельные события сборки для каждой конфигурации.
© 2000–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.17/command/add_custom_command.html