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.
Укажите файл зависимостей
.d, который содержит зависимости для пользовательской команды. Обычно он генерируется самой пользовательской командой. Этот ключевой параметр может быть использован только если генератор его поддерживает, как указано ниже.Новое в версии 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 -
Выполняется после выполнения всех остальных правил в рамках объекта.
Примечание
Поскольку выражения генератора могут использоваться в пользовательских командах, возможно определить строки COMMAND или целые пользовательские команды, которые вычисляются как пустые строки для определенных конфигураций. Для генераторов 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–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.22/command/add_custom_command.html