add_custom_rule¶
Added in version 4.5.
Add a custom template rule to the generated build system.
Synopsis¶
Generating Files add_custom_rule(<name> OUTPUT <output1> [<output2> ...] COMMAND <command1> [<args1>...] [...]) Derived Rule add_custom_rule(<name> FROM_RULE <rule> [...])
Generating Files¶
- add_custom_rule(<name> OUTPUT <output1> [<output2> ...] COMMAND <command1> [<args1>...] [...])¶
Add a custom template rule to produce an output:
add_custom_rule(<name> OUTPUT <output1> [<output2> ...] COMMAND <command1> [<args1>...] [COMMAND <command2> [<args2>...]] ... [DEPENDS <depends>...] [BYPRODUCTS <files>...] [DEPFILE <depfile>] [CONFIGURATOR [FOR_FILE_SET <configurator>] [FOR_SOURCE <configurator>]] [GLOBAL])
This defines a template rule
<name>to generate specifiedOUTPUTfile(s). Rule names defined in all uppercase are reserved for CMake's own built-in rules.The association of source files with the template rule is done by creating file sets of type
<name>. For each file of the file set, acustom commandwill be created in the same directory as the target owning the file set and the output files of this custom command will be declared as part of a file set attached to the same target. The type of this file set, as well as its name, are controlled by theOUTPUT_FILE_SETrule property. This output file set will have the same scope (PRIVATE,PUBLIC, orINTERFACE) as the input file set.To parameterize the template, some patterns are defined which can be used as part of the
add_custom_rulearguments as well as the rule's properties. These patterns will be instantiated for each source file. The supported patterns are:Note
The instantiation of the patterns are done in the context of the directory where the file set was created.
These patterns cannot be changed by the functions specified by the
CONFIGURATORoption.<RULE>Name of the rule used as template.
<TARGET>Name of the target to which the file set of sources is attached.
<FILE_SET>Name of the file set used for the rule instantiation.
<SOURCE_DIR>The value of the
CMAKE_SOURCE_DIRvariable.<BINARY_DIR>The value of the
CMAKE_BINARY_DIRvariable.<CURRENT_SOURCE_DIR>The path to the source directory of the file set creation.
<CURRENT_BINARY_DIR>The path to the binary directory of the file set creation.
<SOURCE>The full path of the current source file being processed.
<INPUT_DIR>The directory of the current source file being processed.
<FILE_NAME>The file name of the current source file being processed.
<BASE_NAME>The stem name (i.e. without directory and extension) of the source file being processed.
<INCLUDE_DIRECTORIES>Content, in this order, of the
INCLUDE_DIRECTORIESfile set property,INCLUDE_DIRECTORIESsource property, andINCLUDE_DIRECTORIESrule property.Because CMake is not aware of the tool involved by the rule, there is no specific processing regarding this pattern. This is the user's responsibility to format, using
generator expressions, the content of pattern to be compatible with the tool.For example, if the tool requires the flag
-inc:to identify an include directory, the following can be specified as part of theCOMMANDoption:$<LIST:TRANSFORM,<INCLUDE_DIRECTORIES>,PREPEND,-inc:>
<COMPILE_DEFINITIONS>Content, in this order, of the
COMPILE_DEFINITIONSrule property,COMPILE_DEFINITIONSsource property, andCOMPILE_DEFINITIONSfile set property.Because CMake is not aware of the tool involved by the rule, there is no specific processing regarding this pattern. This is the user's responsibility to format, using
generator expressions, the content of pattern to be compatible with the tool.For example, if the tool requires the flag
-def:to identify a compile definition, the following can be specified as part of theCOMMANDoption:$<LIST:TRANSFORM,<COMPILE_DEFINITIONS>,PREPEND,-def:>
<COMPILE_OPTIONS>Content, in this order, of the
COMPILE_OPTIONSrule property,COMPILE_OPTIONSsource property, and:prop_fs:COMPILE_OPTIONS file set property.
The options, which have the same semantics as those of the
add_custom_command()command, are:OUTPUTSpecify the output files the command is expected to produce. Each output file will be marked with the
GENERATEDsource file property automatically. At least oneOUTPUTmust be given.COMMANDSpecify the command-line(s) to execute at build time. At least one
COMMANDmust be given.DEPENDSSpecify files on which the command depends.
BYPRODUCTSSpecify the files the command is expected to produce but whose modification time may or may not be newer than the dependencies.
DEPFILESpecify a depfile which holds dependencies for the custom command. It is usually emitted by the custom command itself.
CONFIGURATORSpecify one or two CMake functions which will be called at the generation step, in the context of the file set directory, before the effective instantiation and custom commands definition.
Note
The rule properties are all read-only during the execution of the configurators. Moreover, it is strongly discouraged to change the target properties.
FOR_FILE_SETThe specified function will be called once per file set. The expected signature is the following:
- configurator(rule target fileset outputFileset patterns)¶
The arguments provide the names of the effective artifacts involved in the current rule instantiation.
The
patternsargument holds the name of the variable which can be used to enrich the list of patterns. The expected value is a semicolon-separated list of items having the syntaxPATTERN=VALUEorPATTERN=. More precisely, each item must match the regular expression(^[A-Z][A-Z0-9_]+)=(.*)$. Items which does not this regular expression will be ignored.FOR_SOURCEThe specified function will be called for each file of the file set. The expected signature is the following:
- configurator(rule target fileset outputFileset source patterns)¶
The arguments provide the names of the effective artifacts involved in the current rule instantiation.
The
patternsargument holds the name of the variable which can be used to enrich the list of patterns. The expected value is a semicolon-separated list of items having the syntaxPATTERN=VALUEorPATTERN=. More precisely, each item must match the regular expression(^[A-Z][A-Z0-9_]+)=(.*)$. Items which does not this regular expression will be ignored.Note
The source configurator is evaluated after the file set one. So, the changes done by it will overwrite any changes done by the file set configurator.
Note
Any patterns specified through The
RULE_PATTERNSfile set and<RULE>_PATTERNSsource file properties will take precedence over, respectively, the file set and the source configurators.GLOBALMake the rule name globally visible. Without this keyword, the rule will only be visible in the directory where it was created as well as the sub-directories.
Example¶
Define a rule to compile swig files:
function(fileset_configurator rule target fileset patterns)
# define <OUTFILE_DIR> pattern
set(${patterns} "OUTFILE_DIR=<CURRENT_BINARY_DIR>" PARENT_SCOPE)
endfunction()
function(source_configurator rule target fileset source patterns)
# define flag to handle C++
get_property(cxx SOURCE "${source}" TARGET_DIRECTORY "${target}" PROPERTY CPLUSPLUS)
if (cxx)
set_property(SOURCE "${source}" TARGET_DIRECTORY "${target}"
APPEND PROPERTY COMPILE_OPTIONS -c++)
endif()
endfunction()
set(OUTFILE_EXT "$<IF:$<BOOL:$<SOURCE_PROPERTY:<SOURCE>,TARGET_DIRECTORY:<TARGET>,CPLUSPLUS>>,.cxx,.c>")
set(SWIG_LANGUAGE "-$<STRING:TOLOWER,$<FILE_SET_PROPERTY:<FILE_SET>,TARGET:<TARGET>,LANGUAGE>>")
add_custom_rule(swig
OUTPUT "<OUTFILE_DIR>/<BASE_NAME>${OUTFILE_EXT}"
COMMAND ${SWIG_EXECUTABLE} "<SOURCE>"
"<OUTFILE_DIR>/<BASE_NAME>${OUTFILE_EXT}"
${SWIG_LANGUAGE}
<COMPILE_OPTIONS>
CONFIGURATOR FOR_FILE_SET fileset_configurator FOR_SOURCE source_configurator)
And, by defining a file set of type swig, we can compile swig sources:
add_library(swig_example)
target_sources(swig_example PRIVATE FILE_SET swig_srcs TYPE swig
FILES file1.i file2.i)
# define the target language
set_property(FILE_SET swig_srcs TARGET swig_example PROPERTY LANGUAGE python)
# define swig c++ mode
set_property(SOURCE file1.i file2.i PROPERTY CPLUSPLUS ON)
Derived Rule¶
- add_custom_rule(<name> FROM_RULE <rule> [...])¶
Create a new template rule
<name>inheriting a snapshot of all the characteristics of the<rule>, including the properties except theGLOBALone. Rule names defined in all uppercase are reserved for CMake's own built-in rules.add_custom_rule(<name> FROM_RULE <rule> [CONFIGURATOR [FOR_FILE_SET <configurator> [CHAIN|OVERRIDE]] [FOR_SOURCE <configurator> [CHAIN|OVERRIDE]]] [GLOBAL])
Properties attached to this new rule can be freely customized, independently of the rule we inherited from.
The options are:
FROM_RULESpecify the rule from which this new rule will inherit.
CONFIGURATORSpecify one or two CMake functions which will be called at the generation step before the effective instantiation and custom commands definition.
Note
The rule properties are all read-only during the execution of the configurators. Moreover, it is strongly discouraged to change the target properties.
FOR_FILE_SETThe specified function will be called once per file set. The expected signature is the following:
- configurator(rule target fileset outputFileset patterns)
The arguments provide the names of the effective artifacts involved in the current rule instantiation.
The
patternsargument holds the name of the variable which can be used to enrich the list of patterns.FOR_SOURCEThe specified function will be called for each file of the file set. The expected signature is the following:
- configurator(rule target fileset outputFileset source patterns)
The arguments provide the names of the effective artifacts involved in the current rule instantiation.
The
patternsargument holds the name of the variable which can be used to enrich the list of patterns.
For these two sub-options, there are two possible configurations:
CHAINThis
<configurator>will be added to the already specified configurators of inherited rules. Configurators will be called in order of their rules' definition.OVERRIDEThe specified
<configurator>will override any other already defined configurators. This is the default.
GLOBALMake the rule name globally visible. Without this keyword, the rule will only be visible in the directory where it was created as well as the sub-directories.
Example¶
By reusing the previous defined rule swig, we can provide a more simple way
to compile swig sources by creating a more specialized rule:
function(python_configurator rule target fileset outputFileset patterns)
# define target language
set_property(FILE_SET ${fileset} TARGET ${target} PROPERTY LANGUAGE python)
endfunction()
function(cxx_configurator rule target fileset outputFileset source patterns)
# define swig c++ mode
set_property(SOURCE "${source}" TARGET_DIRECTORY ${target} PROPERTY CPLUSPLUS ON)
set_property(SOURCE "${source}" TARGET_DIRECTORY ${target}
APPEND PROPERTY COMPILE_OPTIONS -c++)
endfunction()
add_custom_rule(swig_python FROM_RULE swig
CONFIGURATOR FOR_FILE_SET python_configurator CHAIN
FOR_SOURCE cxx_configurator OVERRIDE)
Now, we can define a file set which does not need any specific settings. And
because the CHAIN option was specified for the file set configurator, the
pattern <OUTFILE_DIR> will be defined as well.
add_library(swig_example)
target_sources(swig_example PRIVATE FILE_SET swig_srcs TYPE swig_python
FILES file1.i file2.i)