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, они будут выполняться в порядке, но не обязательно комбинироваться в состоятельный shell или пакетный скрипт. (Для запуска полного скрипта используйте команду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это помещает команду вconsoleпулpool. -
VERBATIM -
Все аргументы команд будут правильно экранированы для инструмента сборки, чтобы вызванная команда получала каждый аргумент без изменений. Обратите внимание, что один уровень экранирования все еще используется процессором языка CMake перед тем, как add_custom_command даже увидит аргументы. Рекомендуется использовать
VERBATIM, так как это обеспечивает правильное поведение. КогдаVERBATIMне задано, поведение зависит от платформы, поскольку нет защиты от специальных символов, специфичных для инструмента. -
WORKING_DIRECTORY -
Выполнить команду с заданным текущим рабочим каталогом. Если это относительный путь, он будет интерпретироваться относительно каталога дерева сборки, соответствующего текущему каталогу исходных файлов.
Новая в версии 3.13: Аргументы для
WORKING_DIRECTORYмогут использоватьgenerator expressions. -
DEPFILE -
Новая в версии 3.7.
Укажите
.ddepfile для генераторовNinja,Xcodeи Makefile. Depfile может использовать «выражения генератора» со синтаксисом$<...>. Обратитесь к руководствуgenerator-expressions(7)для доступных выражений. Файл.dсодержит зависимости, обычно создаваемые самой пользовательской командой.Использование
DEPFILEс другими генераторами, кромеNinja,Xcodeили Makefile, является ошибкой.Новая в версии 3.20: Добавлена поддержка Генераторов Makefile.
Новая в версии 3.21: Добавлена поддержка генераторов Visual Studio (VS 2012 и выше), генератора
Xcodeиgenerator expressions.Если аргумент
DEPFILEотносительный, он должен быть относительным кCMAKE_CURRENT_BINARY_DIR, а все относительные пути внутриDEPFILEтакже должны быть относительными кCMAKE_CURRENT_BINARY_DIR(см. политикуCMP0116. Эта политика всегдаNEWдля Генераторов Makefile, Генераторов Visual Studio и генератораXcode.Примечание
Для Генераторов 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 -
Выполняется после выполнения всех других правил в целевом объекте.
Примечание
Поскольку генераторские выражения могут использоваться в пользовательских командах, можно определить строки или целые пользовательские команды, которые вычисляются в пустые строки для определенных конфигураций. Для генераторов 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.21/command/add_custom_command.html