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.
Указать зависимость
.dдля генератораNinjaи Генераторы Makefile. Файл.dсодержит зависимости, обычно выводимые самой пользовательской командой. ИспользованиеDEPFILEс другими генераторами, кромеNinjaили Генераторы Makefile, является ошибкой.Новое в версии 3.20: Добавлена поддержка Генераторов Makefile.
Если аргумент
DEPFILEотносительный, он должен быть относительным кCMAKE_CURRENT_BINARY_DIR, и любые относительные пути внутриDEPFILEтакже должны быть относительными кCMAKE_CURRENT_BINARY_DIR(см. политикуCMP0116. Эта политика всегдаNEWдля Генераторов Makefile).Примечание
Для Генераторов Makefile этот параметр нельзя указать одновременно с параметром
IMPLICIT_DEPENDS.
Примеры: Генерация файлов
Пользовательские команды могут использоваться для генерации исходных файлов. Например, код:
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 -
Выполняется после выполнения всех других правил в пределах целевого объекта.
Примечание
Поскольку выражения генератора могут использоваться в пользовательских командах, возможно определение COMMAND строк или целых пользовательских команд, которые вычисляются как пустые строки для определенных конфигураций. Для генераторов Visual Studio 2010 (и новее) эти строки команд или пользовательские команды будут опушены для конкретной конфигурации, и не будет добавляться "пустая-строка-команда".
Это позволяет добавить отдельные события построения для каждой конфигурации.
Примеры: События построения
Событие 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–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.20/command/add_custom_command.html