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 -
Новая в версии 3.2.
Укажите файлы, которые, как ожидается, будет создавать команда, но время изменения которых может быть, а может и не быть, новее, чем время изменения зависимостей. Если имя побочного продукта — это относительный путь, он будет интерпретирован относительно каталога дерева сборки, соответствующего текущему каталогу исходного кода. Каждый файл побочного продукта будет помечен свойством исходного файла
GENERATEDавтоматически.Явное указание побочных продуктов поддерживается генератором
Ninja, чтобы сообщить инструменту сборкиninjaкак перегенерировать побочные продукты, если они отсутствуют. Это также полезно, когда другие правила сборки (например, пользовательские команды) зависят от побочных продуктов. Ninja требует правила сборки для любого сгенерированного файла, от которого зависит другое правило, даже если существуют зависимости только по порядку, чтобы убедиться, что побочные продукты будут доступны до сборки их зависимостей.Генераторы Makefile Generators удалят
BYPRODUCTSи другие файлыGENERATEDво времяmake clean.Новая в версии 3.20: Аргументы для
BYPRODUCTSмогут использовать ограниченный наборgenerator expressions. Зависимые от целевых выражения не разрешены. -
COMMAND -
Укажите командную строку(и) для выполнения во время сборки. Если указано более одной
COMMAND, они будут выполняться в порядке, но не обязательно объединяться в состоятельный интерпретатор оболочки или пакетную скрипт. (Чтобы запустить полную скрипт, используйте командуconfigure_file()или командуfile(GENERATE)для ее создания, а затем укажите запускCOMMAND). Опциональный аргументARGSпредназначен для обратной совместимости и будет проигнорирован.Если
COMMANDуказывает имя целевого исполняемого файла (созданное командойadd_executable()), он будет автоматически заменен местоположением созданного во время сборки исполняемого файла, если выполняется одно из следующих условий:- Целевой файл не компилируется в другой среде (т. е. переменная
CMAKE_CROSSCOMPILINGне установлена в значение true). -
Новая в версии 3.6: Целевой файл компилируется в другой среде и эмулятор предоставляется (т. е. свойство целевого файла
CROSSCOMPILING_EMULATORустановлено). В этом случае содержимоеCROSSCOMPILING_EMULATORбудет добавлено в начало команды перед местоположением исполняемого файла цели.
Если ни одно из вышеперечисленных условий не выполняется, предполагается, что имя команды — это программа, которую необходимо найти в
PATHво время сборки.Аргументы для
COMMANDмогут использоватьgenerator expressions. Используйте выражение генератораTARGET_FILE, чтобы сослаться на местоположение целевого объекта позже в командной строке (т. е. в качестве аргумента команды, а не как команды для выполнения).Всякий раз, когда одно из следующих выражений генератора, основанных на целевом объекте, используется как команда для выполнения или упоминается в аргументе команды, автоматически добавляется зависимость на уровне целевого объекта, чтобы указанный целевой объект был построен перед любым целевым объектом, использующим эту пользовательскую команду (см. политику
CMP0112).TARGET_FILETARGET_LINKER_FILETARGET_SONAME_FILETARGET_PDB_FILE
Эта зависимость на уровне целевого объекта НЕ добавляет зависимость на уровне файла, которая заставила бы пользовательскую команду повторно выполняться всякий раз, когда исполняемый файл перекомпилируется. Перечислите имена целевых объектов с помощью опции
DEPENDSдля добавления таких зависимостей на уровне файлов. - Целевой файл не компилируется в другой среде (т. е. переменная
-
COMMENT -
Отобразить данное сообщение перед выполнением команд во время сборки.
-
DEPENDS -
Укажите файлы, от которых зависит команда. Каждый аргумент преобразуется в зависимость следующим образом:
- Если аргумент является именем целевого объекта (созданного командой
add_custom_target(),add_executable()илиadd_library()), создается зависимость на уровне целевого объекта, чтобы убедиться, что целевой объект построен до любого целевого объекта, использующего эту пользовательскую команду. Кроме того, если целевой объект является исполняемым файлом или библиотекой, создается зависимость на уровне файла, чтобы пользовательская команда повторно выполнялась всякий раз, когда целевой объект перекомпилируется. - Если аргумент — это абсолютный путь, создается зависимость на уровне файла от этого пути.
- Если аргумент — имя исходного файла, который был добавлен в целевой объект или для которого было установлено свойство исходного файла, создается зависимость на уровне файла от этого исходного файла.
- Если аргумент — относительный путь, который существует в текущем каталоге исходного кода, создается зависимость на уровне файла от этого файла в текущем каталоге исходного кода.
- В противном случае создается зависимость на уровне файла от этого пути относительно текущего каталога двоичных файлов.
Если какая-либо зависимость является
OUTPUTдругой пользовательской команды в той же директории (файлCMakeLists.txt), CMake автоматически включает другую пользовательскую команду в целевой объект, в котором построена эта команда.Новая в версии 3.16: Добавляется зависимость на уровне целевого объекта, если любая зависимость указана как
BYPRODUCTSцелевого объекта или любого из его событий сборки в той же директории, чтобы гарантировать, что побочные продукты будут доступны.Если
DEPENDSне указано, команда будет выполняться всякий раз, когдаOUTPUTотсутствует; если команда фактически не создаетOUTPUT, правило всегда будет выполняться.Новая в версии 3.1: Аргументы для
DEPENDSмогут использоватьgenerator expressions. - Если аргумент является именем целевого объекта (созданного командой
-
COMMAND_EXPAND_LISTS -
Новая в версии 3.8.
Списки в аргументах
COMMANDбудут расширены, включая те, которые созданы с помощьюgenerator expressions, что позволяет использовать аргументыCOMMAND, такие как${CC} "-I$<JOIN:$<TARGET_PROPERTY:foo,INCLUDE_DIRECTORIES>,;-I>" foo.cc, для правильного расширения. -
IMPLICIT_DEPENDS -
Запрос сканирования неявных зависимостей входного файла. Указанный язык определяет язык программирования, для которого следует использовать соответствующий сканер зависимостей. В настоящее время поддерживаются только сканеры зависимостей языков
CиCXX. Язык должен быть указан для каждого файла в спискеIMPLICIT_DEPENDS. Обнаруженные зависимости из сканирования добавляются к тем, которые принадлежат пользовательской команде во время сборки. Обратите внимание, что опцияIMPLICIT_DEPENDSв настоящее время поддерживается только для генераторов Makefile и будет проигнорирована другими генераторами.Примечание
Эту опцию нельзя указать одновременно с опцией
DEPFILE. -
JOB_POOL
-
Добавлена в версии 3.15.
Укажите
poolдля генератораNinja. Несовместимо сUSES_TERMINAL, что подразумевает пулconsole. Использование пула, не определённого вJOB_POOLS, приводит к ошибке в ninja во время сборки. -
MAIN_DEPENDENCY -
Укажите основной входной файл для команды. Это обрабатывается так же, как любое значение, заданное для опции
DEPENDS, но также указывает генераторам Visual Studio, где разместить пользовательскую команду. Каждый исходный файл может иметь не более одной команды, определяющей его как основную зависимость. Команда компиляции (т.е. для библиотеки или исполняемого файла) учитывается как неявная главная зависимость, которая безмолвно перезаписывается указанием пользовательской команды. -
OUTPUT -
Укажите выходные файлы, которые должна создать команда. Если имя выходного файла является относительным путем, оно будет интерпретироваться относительно каталога дерева сборки, соответствующего текущему каталогу исходных файлов. Каждый выходной файл будет автоматически помечен свойством исходного файла
GENERATED. Если результат пользовательской команды фактически не создается как файл на диске, он должен быть помечен свойством исходного файлаSYMBOLIC.Добавлена в версии 3.20: Аргументы к
OUTPUTмогут использовать ограниченный наборgenerator expressions. Зависимые от целевых выражения не допускаются. -
USES_TERMINAL -
Добавлена в версии 3.2.
Команда получит прямой доступ к терминалу, если это возможно. С генератором
Ninjaэто помещает команду в пулconsolepool. -
VERBATIM -
Все аргументы команд будут правильно экранированы для инструмента сборки, чтобы вызываемая команда получала каждый аргумент без изменений. Обратите внимание, что один уровень экранирования всё ещё используется процессором языка CMake перед тем, как add_custom_command увидит аргументы. Рекомендуется использовать
VERBATIM, так как это обеспечивает правильное поведение. ЕслиVERBATIMне задан, поведение зависит от платформы, так как нет защиты от специфичных для инструмента специальных символов. -
WORKING_DIRECTORY -
Выполнить команду с заданным текущим каталогом. Если это относительный путь, он будет интерпретироваться относительно каталога дерева сборки, соответствующего текущему каталогу исходных файлов.
Добавлена в версии 3.13: Аргументы к
WORKING_DIRECTORYмогут использоватьgenerator expressions. -
DEPFILE -
Добавлена в версии 3.7.
Укажите depfile, содержащий зависимости для пользовательской команды. Обычно он генерируется самой пользовательской командой. Этот ключевое слово может быть использовано только в том случае, если генератор его поддерживает, как описано ниже.
Ожидаемый формат, совместимый с тем, что генерируется
gccс опцией-M, независим от генератора или платформы.Формальная синтаксическая конструкция, определённая с использованием обозначения BNF с обычными расширениями, следующая:
depfile ::= rule* rule ::= targets (`:` (separator dependencies?)?)? eol targets ::= target (separator target)* separator* target ::= pathname dependencies ::= dependency (separator dependency)* separator* dependency ::= pathname separator ::= (space | line_continue)+ line_continue ::= '\' eol space ::= ' ' | '\t' pathname ::= character+ character ::= std_character | dollar | hash | whitespace std_character ::= <any character except '$', '#' or ' '> dollar ::= '$$' hash ::= '\#' whitespace ::= '\ ' eol ::= '\r'? '\n'
Примечание
В рамках
pathname, все слэши и обратные слэши интерпретируются как разделители каталогов.Добавлена в версии 3.7: Генератор
NinjaподдерживаетDEPFILEс момента добавления ключевого слова.Добавлена в версии 3.17: Добавлен генератор
Ninja Multi-Config, который включал поддержку ключевого словаDEPFILE.Добавлена в версии 3.20: Добавлена поддержка Генераторы Makefile.
Примечание
DEPFILEне может быть указан одновременно с опциейIMPLICIT_DEPENDSдля Генераторов Makefile.Добавлена в версии 3.21: Добавлена поддержка Генераторов Visual Studio с VS 2012 и выше, и для генератора
Xcode. Также была добавлена поддержкаgenerator expressions.Использование
DEPFILEс генераторами, не перечисленными выше, является ошибкой.Если аргумент
DEPFILEотносительный, он должен быть относительным кCMAKE_CURRENT_BINARY_DIR, а любые относительные пути внутриDEPFILEтакже должны быть относительными кCMAKE_CURRENT_BINARY_DIR. См. политикуCMP0116, которая всегдаNEWдля Генераторов Makefile, Генераторов Visual Studio и генератораXcode.
Примеры: Генерация файлов
Пользовательские команды могут использоваться для генерации исходных файлов. Например, код:
add_custom_command(
OUTPUT out.c
COMMAND someTool -i ${CMAKE_CURRENT_SOURCE_DIR}/in.txt
-o out.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/in.txt
VERBATIM)
add_library(myLib out.c)
добавляет пользовательскую команду для запуска someTool для генерации out.c и затем компиляции сгенерированного исходного кода как части библиотеки. Правило генерации будет перевыполняться всякий раз, когда in.txt изменяется.
Добавлена в версии 3.20: Можно использовать выражения генератора для указания выходных данных по конфигурации. Например, код:
add_custom_command(
OUTPUT "out-$<CONFIG>.c"
COMMAND someTool -i ${CMAKE_CURRENT_SOURCE_DIR}/in.txt
-o "out-$<CONFIG>.c"
-c "$<CONFIG>"
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/in.txt
VERBATIM)
add_library(myLib "out-$<CONFIG>.c")
добавляет пользовательскую команду для запуска someTool для генерации out-<config>.c, где <config> — конфигурация сборки, а затем компиляции сгенерированного исходного кода как части библиотеки.
События сборки
Вторая сигнатура добавляет пользовательскую команду к цели, такой как библиотека или исполняемый файл. Это полезно для выполнения операции до или после построения цели. Команда становится частью цели и будет выполняться только при построении самой цели. Если цель уже построена, команда не будет выполнена.
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 -
Выполняется после выполнения всех других правил в рамках цели.
Примечание
Так как выражения генератора могут использоваться в пользовательских командах, можно определить строки или целые пользовательские команды, которые приводят к пустым строкам для определённых конфигураций. Для генераторов Visual Studio 2010 (и новее) эти строки команд или пользовательские команды будут пропущены для конкретной конфигурации, и не будет добавлена «команда с пустой строкой».
Это позволяет добавлять отдельные события сборки для каждой конфигурации.
Новое в версии 3.21: Поддержка выражений генератора, зависящих от целевого объекта.
Примеры: События сборки
Событие POST_BUILD может использоваться для пост-обработки двоичного файла после линковки. Например, код:
add_executable(myExe myExe.c)
add_custom_command(
TARGET myExe POST_BUILD
COMMAND someHasher -i "$<TARGET_FILE:myExe>"
-o "$<TARGET_FILE:myExe>.hash"
VERBATIM)
выполнит someHasher для создания файла .hash рядом с исполняемым файлом после линковки.
Новое в версии 3.20: Можно использовать выражения генератора для указания побочных продуктов по конфигурациям. Например, код:
add_library(myPlugin MODULE myPlugin.c)
add_custom_command(
TARGET myPlugin POST_BUILD
COMMAND someHasher -i "$<TARGET_FILE:myPlugin>"
--as-code "myPlugin-hash-$<CONFIG>.c"
BYPRODUCTS "myPlugin-hash-$<CONFIG>.c"
VERBATIM)
add_executable(myExe myExe.c "myPlugin-hash-$<CONFIG>.c")
выполнит someHasher после линковки myPlugin, например, для создания файла .c содержащего код для проверки хеша myPlugin, который исполняемый файл myExe может использовать для проверки перед загрузкой.
Ninja Multi-Config
Новое в версии 3.20: add_custom_command поддерживает возможности кросс-конфигурации генератора Ninja Multi-Config. Для получения дополнительной информации см. документацию по генератору.
© 2000–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.23/command/add_custom_command.html