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 удалят
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 -
Выполняется после выполнения всех остальных правил в целевом объекте.
Проекты всегда должны указывать один из вышеперечисленных трёх ключевых запросов при использовании формы 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 Многоконфигурационный
Новое в версии 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.24/command/add_custom_command.html