add_custom_rule --------------- .. versionadded:: 4.5 Add a custom template rule to the generated build system. Synopsis ^^^^^^^^ .. parsed-literal:: `Generating Files`_ add_custom_rule( `OUTPUT`_ [ ...] COMMAND [...] [...]) `Derived Rule`_ add_custom_rule( `FROM_RULE`_ [...]) Generating Files ^^^^^^^^^^^^^^^^ .. signature:: add_custom_rule( OUTPUT [ ...] COMMAND [...] [...]) :target: OUTPUT Add a custom template rule to produce an output: .. code-block:: cmake add_custom_rule( OUTPUT [ ...] COMMAND [...] [COMMAND [...]] ... [DEPENDS ...] [BYPRODUCTS ...] [DEPFILE ] [CONFIGURATOR [FOR_FILE_SET ] [FOR_SOURCE ]] [GLOBAL]) This defines a template rule ```` to generate specified ``OUTPUT`` file(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 :ref:`file sets ` of type ````. For each file of the file set, a :command:`custom command ` will 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 the :prop_rule:`OUTPUT_FILE_SET` rule property. This output file set will have the same scope (``PRIVATE``, ``PUBLIC``, or ``INTERFACE``) as the input file set. To parameterize the template, some patterns are defined which can be used as part of the ``add_custom_rule`` arguments as well as the :ref:`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 ``CONFIGURATOR`` option. ```` Name of the rule used as template. ```` Name of the target to which the file set of sources is attached. ```` Name of the file set used for the rule instantiation. ```` The value of the :variable:`CMAKE_SOURCE_DIR` variable. ```` The value of the :variable:`CMAKE_BINARY_DIR` variable. ```` The path to the source directory of the file set creation. ```` The path to the binary directory of the file set creation. ```` The full path of the current source file being processed. ```` The directory of the current source file being processed. ```` The file name of the current source file being processed. ```` The stem name (i.e. without directory and extension) of the source file being processed. ```` Content, in this order, of the :prop_fs:`INCLUDE_DIRECTORIES` file set property, :prop_sf:`INCLUDE_DIRECTORIES` source property, and :prop_rule:`INCLUDE_DIRECTORIES` rule 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 :manual:`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 the ``COMMAND`` option: .. code-block:: cmake $,PREPEND,-inc:> ```` Content, in this order, of the :prop_rule:`COMPILE_DEFINITIONS` rule property, :prop_sf:`COMPILE_DEFINITIONS` source property, and :prop_fs:`COMPILE_DEFINITIONS` file 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 :manual:`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 the ``COMMAND`` option: .. code-block:: cmake $,PREPEND,-def:> ```` Content, in this order, of the :prop_rule:`COMPILE_OPTIONS` rule property, :prop_sf:`COMPILE_OPTIONS` source property, and:prop_fs:`COMPILE_OPTIONS` file set property. The options, which have the same semantics as those of the :command:`add_custom_command` command, are: ``OUTPUT`` Specify the output files the command is expected to produce. Each output file will be marked with the :prop_sf:`GENERATED` source file property automatically. At least one ``OUTPUT`` must be given. ``COMMAND`` Specify the command-line(s) to execute at build time. At least one ``COMMAND`` must be given. ``DEPENDS`` Specify files on which the command depends. ``BYPRODUCTS`` Specify the files the command is expected to produce but whose modification time may or may not be newer than the dependencies. ``DEPFILE`` Specify a depfile which holds dependencies for the custom command. It is usually emitted by the custom command itself. ``CONFIGURATOR`` Specify 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_SET`` The specified function will be called once per file set. The expected signature is the following: .. signature:: configurator(rule target fileset outputFileset patterns) The arguments provide the names of the effective artifacts involved in the current rule instantiation. The ``patterns`` argument holds the name of the variable which can be used to enrich the list of patterns. The expected value is a :ref:`semicolon-separated list ` of items having the syntax ``PATTERN=VALUE`` or ``PATTERN=``. 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_SOURCE`` The specified function will be called for each file of the file set. The expected signature is the following: .. signature:: configurator(rule target fileset outputFileset source patterns) The arguments provide the names of the effective artifacts involved in the current rule instantiation. The ``patterns`` argument holds the name of the variable which can be used to enrich the list of patterns. The expected value is a :ref:`semicolon-separated list ` of items having the syntax ``PATTERN=VALUE`` or ``PATTERN=``. 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 :prop_fs:`RULE_PATTERNS` file set and :prop_sf:`_PATTERNS` source file properties will take precedence over, respectively, the file set and the source configurators. ``GLOBAL`` Make 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: .. code-block:: cmake function(fileset_configurator rule target fileset patterns) # define pattern set(${patterns} "OUTFILE_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 "$,TARGET_DIRECTORY:,CPLUSPLUS>>,.cxx,.c>") set(SWIG_LANGUAGE "-$,TARGET:,LANGUAGE>>") add_custom_rule(swig OUTPUT "/${OUTFILE_EXT}" COMMAND ${SWIG_EXECUTABLE} "" "/${OUTFILE_EXT}" ${SWIG_LANGUAGE} CONFIGURATOR FOR_FILE_SET fileset_configurator FOR_SOURCE source_configurator) And, by defining a file set of type ``swig``, we can compile swig sources: .. code-block:: cmake 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 ^^^^^^^^^^^^ .. signature:: add_custom_rule( FROM_RULE [...]) :target: FROM_RULE Create a new template rule ```` inheriting a snapshot of all the characteristics of the ````, including the properties except the ``GLOBAL`` one. Rule names defined in all uppercase are reserved for CMake's own built-in rules. .. code-block:: cmake add_custom_rule( FROM_RULE [CONFIGURATOR [FOR_FILE_SET [CHAIN|OVERRIDE]] [FOR_SOURCE [CHAIN|OVERRIDE]]] [GLOBAL]) Properties attached to this new rule can be freely customized, independently of the rule we inherited from. The options are: ``FROM_RULE`` Specify the rule from which this new rule will inherit. ``CONFIGURATOR`` Specify 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_SET`` The specified function will be called once per file set. The expected signature is the following: .. signature:: configurator(rule target fileset outputFileset patterns) The arguments provide the names of the effective artifacts involved in the current rule instantiation. The ``patterns`` argument holds the name of the variable which can be used to enrich the list of patterns. ``FOR_SOURCE`` The specified function will be called for each file of the file set. The expected signature is the following: .. signature:: configurator(rule target fileset outputFileset source patterns) The arguments provide the names of the effective artifacts involved in the current rule instantiation. The ``patterns`` argument 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: ``CHAIN`` This ```` will be added to the already specified configurators of inherited rules. Configurators will be called in order of their rules' definition. ``OVERRIDE`` The specified ```` will override any other already defined configurators. This is the default. ``GLOBAL`` Make 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: .. code-block:: cmake 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 ```` will be defined as well. .. code-block:: cmake add_library(swig_example) target_sources(swig_example PRIVATE FILE_SET swig_srcs TYPE swig_python FILES file1.i file2.i) See Also ^^^^^^^^ * :command:`set_property(RULE)` * :command:`get_property(RULE)` * :command:`target_sources` * :command:`add_custom_command`