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 удалят
BYPRODUCTSи другие файлыGENERATEDво времяmake clean. -
COMMAND -
Укажите командную строку(и) для выполнения во время сборки. Если указано более одной
COMMAND, они будут выполнены в порядке, но не обязательно составлены в состояние shell или пакетный скрипт. (Чтобы запустить полный скрипт, используйте командуconfigure_file()или командуfile(GENERATE)для его создания, а затем укажитеCOMMANDдля его запуска.) Необязательный аргументARGSпредназначен для обратной совместимости и будет проигнорирован.Если
COMMANDуказывает имя целевого исполняемого файла (созданного командойadd_executable()), он будет автоматически заменён местоположением созданного во время сборки исполняемого файла, если одно из следующих условий истинно:- Целевой файл не компилируется в кросс-платформенном режиме (т.е. переменная
CMAKE_CROSSCOMPILINGне установлена в значение true). - Целевой файл компилируется в кросс-платформенном режиме и эмулятор предоставлен (т.е. свойство целевого файла
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 автоматически включает другую пользовательскую команду в цель, в которой построена эта команда. Добавляется зависимость на уровне цели, если любая зависимость указана как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.19/command/add_custom_command.html