diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst index f335e1f1bb..809cf7349c 100644 --- a/Help/guide/ide-integration/index.rst +++ b/Help/guide/ide-integration/index.rst @@ -40,7 +40,7 @@ CMake supports a file format called ``CMakePresets.json``, and its user-specific counterpart, ``CMakeUserPresets.json``. This file contains information on the various configure presets that a user may want. Each preset may have a different compiler, build flags, etc. The details of this format are -explained in the :manual:`cmake(1)` manual. +explained in the :manual:`cmake-presets(7)` manual. IDE vendors are encouraged to read and evaluate this file the same way CMake does, and present the user with the presets listed in the file. Users should be @@ -71,12 +71,12 @@ them as :option:`-D ` flags would cause the command line length limit of the platform to be exceeded, the IDE should instead construct a temporary cache script and pass it with the :option:`-C ` flag. -While reading, parsing, and evaluating the contents of ``CMakePresets.json`` is +While reading, parsing, and evaluating the contents of CMake presets files is straightforward, it is not trivial. In addition to the documentation, IDE vendors may also wish to refer to the CMake source code and test cases for a better understanding of how to implement the format. :download:`This file <../../manual/presets/schema.json>` provides a -machine-readable JSON schema for the ``CMakePresets.json`` format that IDE +machine-readable JSON schema for the CMake presets file format that IDE vendors may find useful for validation and providing editing assistance. Configuring diff --git a/Help/guide/tutorial/Configuration and Cache Variables.rst b/Help/guide/tutorial/Configuration and Cache Variables.rst index ec930903c6..7da09ed625 100644 --- a/Help/guide/tutorial/Configuration and Cache Variables.rst +++ b/Help/guide/tutorial/Configuration and Cache Variables.rst @@ -506,6 +506,12 @@ available. Command line flags can be mixed with presets. Command line flags have precedence over values found in a preset. +.. note:: + On CMake 4.4 and newer, CMake can also load presets from any file specified + with :option:`cmake --presets-file`. This can be useful when reusing settings + across multiple projects, since it avoids having to duplicate them in + separate ``CMakePresets.json`` files for each project. + Presets also support limited macros, variables that can be brace-expanded inside the preset. The only one of interest to us is the ``${sourceDir}`` macro, which expands to the root directory of the project. We can use this to set our @@ -557,7 +563,7 @@ All future configuration changes will be via the ``CMakePresets.json`` file. Build and Run ------------- -We can now use the preset file to manage our configuration. +We can now use the presets file to manage our configuration. .. code-block:: console diff --git a/Help/guide/user-interaction/index.rst b/Help/guide/user-interaction/index.rst index f11b23dd78..12d6b848dd 100644 --- a/Help/guide/user-interaction/index.rst +++ b/Help/guide/user-interaction/index.rst @@ -425,7 +425,7 @@ saving presets for commonly-used configure settings. These presets can set the build directory, generator, cache variables, environment variables, and other command-line options. All of these options can be overridden by the -user. The full details of the ``CMakePresets.json`` format +user. The full details of the CMake presets format are listed in the :manual:`cmake-presets(7)` manual. Using presets on the command-line diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 4c672135ce..d5f7c9872f 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -1,4 +1,4 @@ -.. cmake-manual-description: CMakePresets.json +.. cmake-manual-description: CMake Presets Reference cmake-presets(7) **************** @@ -16,8 +16,12 @@ One problem that CMake users often face is sharing settings with other people for common ways to configure a project. This may be done to support CI builds, or for users who frequently use the same build. CMake supports two main files, ``CMakePresets.json`` and ``CMakeUserPresets.json``, that allow users to -specify common configure options and share them with others. CMake also -supports files included with the ``include`` field. +specify common configure options and share them with others. + +.. presets-versionadded:: 4 + + CMake also supports files included with the :preset:`include` field. See + `Includes`_ for more details. ``CMakePresets.json`` and ``CMakeUserPresets.json`` live in the project's root directory. They both have exactly the same format, and both are optional @@ -31,6 +35,13 @@ their own local build details. project is using Git, ``CMakePresets.json`` may be tracked, and ``CMakeUserPresets.json`` should be added to the ``.gitignore``. +.. versionadded:: 4.4 + + CMake also supports specifying a file from which to read presets via the + :cmake-option:`--presets-file` option. If this option is specified, neither + of ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present, and any presets defined in those files will be ignored/unavailable. + Format ====== @@ -41,7 +52,7 @@ The files are a JSON document with an object as the root: .. presets-versionadded:: 10 - Preset files may include comments using the key ``$comment`` at any level + Presets files may include comments using the key ``$comment`` at any level within the JSON object to provide documentation. The root object recognizes the following fields: @@ -51,14 +62,15 @@ The root object recognizes the following fields: Includes ^^^^^^^^ -``CMakePresets.json`` and ``CMakeUserPresets.json`` can include other files -with the ``include`` field in file version ``4`` and later. Files included -by these files can also include other files. If ``CMakePresets.json`` and -``CMakeUserPresets.json`` are both present, ``CMakeUserPresets.json`` -implicitly includes ``CMakePresets.json``, even with no ``include`` field, -in all versions of the format. +.. presets-versionadded:: 4 -If a preset file contains presets that inherit from presets in another file, +CMake presets files can include other files with the :preset:`include` field. +Files included in this manner can also include other files. If +``CMakePresets.json`` and ``CMakeUserPresets.json`` are both present, +``CMakeUserPresets.json`` implicitly includes ``CMakePresets.json``, even with +no :preset:`include` field, in all versions of the format. + +If a presets file contains presets that inherit from presets in another file, the file must include the other file either directly or indirectly. Include cycles are not allowed among files. If ``a.json`` includes ``b.json``, ``b.json`` cannot include ``a.json``. However, a file may be @@ -70,14 +82,14 @@ include files from anywhere. .. presets-versionchanged:: 7 - The ``include`` field supports `macro expansion`_, but only ``$penv{}`` macro - expansion. + The :preset:`include` field supports `macro expansion`_, but only ``$penv{}`` + macro expansion. .. presets-versionchanged:: 9 - The ``include`` field supports `macro expansion`_, except for ``$env{}`` and - preset-specific macros (i.e., those derived from the fields inside a preset's - definition like ``presetName``). + The :preset:`include` field supports `macro expansion`_, except for + ``$env{}`` and preset-specific macros (i.e., those derived from the fields + inside a preset's definition like ``presetName``). .. _`Configure Preset`: @@ -268,12 +280,12 @@ Recognized macros include: ``${fileDir}`` .. presets-versionadded:: 4 - Path to the directory containing the preset file which defines the preset + Path to the directory containing the presets file which defines the preset being used. .. presets-versionchanged:: 12 - This macro *always* expands to the directory of the current preset file + This macro *always* expands to the directory of the current presets file containing the macro, regardless of the preset being used. For example, consider the following scenario. @@ -296,7 +308,7 @@ Recognized macros include: .. note:: Since the ``${fileDir}`` macro in version 12 is expanded in the context - of the current preset file, it is the version of the current file, rather + of the current presets file, it is the version of the current file, rather than the version of the root file containing the preset being used, which enables this alternative behavior. @@ -351,9 +363,8 @@ Recognized macros include: Versions ======== -The JSON schema of ``CMakePresets.json`` and ``CMakeUserPresets.json`` -follows a version scheme where new versions are added and allowed in newer -versions of CMake. +The JSON schema of CMake presets files follows a version scheme where new +versions are added and allowed in newer versions of CMake. A list of the supported versions along with the version of CMake in which they were added and a summary of the new features and changes is given below. @@ -431,7 +442,7 @@ they were added and a summary of the new features and changes is given below. * Changes to `Includes`_ - * The ``include`` field now supports ``$penv{}`` `macro expansion`_. + * The :preset:`include` field now supports ``$penv{}`` `macro expansion`_. ``8`` .. versionadded:: 3.28 @@ -443,7 +454,8 @@ they were added and a summary of the new features and changes is given below. * Changes to `Includes`_ - * The ``include`` field now supports other types of `macro expansion`_. + * The :preset:`include` field now supports other types of + `macro expansion`_. ``10`` .. versionadded:: 3.31 @@ -480,7 +492,7 @@ they were added and a summary of the new features and changes is given below. * Changes to `Macro Expansion`_ * The `${fileDir} `_ macro now always expands to - the directory of preset file containing the ``${fileDir}`` macro, + the directory of presets file containing the ``${fileDir}`` macro, regardless of whether it is inherited by another preset in a different directory. @@ -493,4 +505,4 @@ Schema ====== :download:`This file ` provides a machine-readable -JSON schema for the ``CMakePresets.json`` format. +JSON schema for the CMake presets file format. diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index eef6f6dc39..7b7680fba5 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -686,12 +686,15 @@ Options .. option:: --preset , --preset= - Reads a :manual:`preset ` from ``CMakePresets.json`` and - ``CMakeUserPresets.json`` files, which must be located in the same directory - as the top level ``CMakeLists.txt`` file. The preset may specify the - generator, the build directory, a list of variables, and other arguments to - pass to CMake. At least one of ``CMakePresets.json`` or - ``CMakeUserPresets.json`` must be present. + Reads a :manual:`preset ` from CMake presets files. + ``CMakePresets.json`` and ``CMakeUserPresets.json`` are the default files, + which must be located in the same directory as the top level + ``CMakeLists.txt`` file. A file can also be specified with + :cmake-option:`--presets-file`. + + The preset may specify the generator, the build directory, a list of + variables, and other arguments to pass to CMake. + The :manual:`CMake GUI ` also recognizes and supports ``CMakePresets.json`` and ``CMakeUserPresets.json`` files. For full details on these files, see :manual:`cmake-presets(7)`. @@ -699,25 +702,49 @@ Options The presets are read before all other command line options, although the :cmake-option:`-S` option can be used to specify the source directory containing the ``CMakePresets.json`` and ``CMakeUserPresets.json`` files. - If :cmake-option:`-S` is not given, the current directory is assumed to - be the top level source directory and must contain the presets files. The - options specified by the chosen preset (variables, generator, etc.) can all - be overridden by manually specifying them on the command line. For example, - if the preset sets a variable called ``MYVAR`` to ``1``, but the user sets - it to ``2`` with a ``-D`` argument, the value ``2`` is preferred. + If neither :cmake-option:`-S` nor :cmake-option:`--presets-file` are given, + the current working directory is assumed to be the top level source directory + and must contain ``CMakePresets.json`` and/or ``CMakeUserPresets.json``. + + The options specified by the chosen preset (variables, generator, etc.) + can all be overridden by manually specifying them on the command line. + For example, if the preset sets a variable called ``MYVAR`` to ``1``, + but the user sets it to ``2`` with a :cmake-option:`-D` argument, + the value ``2`` is preferred. .. versionadded:: 3.21 - The ``-B`` option may optionally be specified with a different binary - directory than the one specified by the ``binaryDir`` key of the - configure preset. + The :cmake-option:`-B` option may optionally be specified with a different + binary directory than the one specified by the + :preset:`configurePresets.binaryDir` field. + + .. versionchanged:: 4.4 + If :cmake-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present. In prior versions, the presence of these files in the top-level + source directory (whether via :cmake-option:`-S` or the current working + directory) was strictly required. + +.. option:: --presets-file , --presets-file= + + .. versionadded:: 4.4 + + Reads :manual:`presets ` from the given ````. The + specified path may be absolute or relative to the current working directory. + If ``--presets-file`` is given, presets defined in ``CMakePresets.json`` and + ``CMakeUserPresets.json`` will be ignored. .. option:: --list-presets[=] Lists the available presets of the specified ````. Valid values for ```` are ``configure``, ``build``, ``test``, ``package``, or ``all``. - If ```` is omitted, ``configure`` is assumed. The current working - directory must contain CMake preset files unless the :cmake-option:`-S` - option is used to specify a different top level source directory. + If ```` is omitted, ``configure`` is assumed. + + .. versionchanged:: 4.4 + If :cmake-option:`--presets-file` is specified, the presets defined in the + given ```` will be listed. Otherwise, the top-level source directory + (whether via :cmake-option:`-S` or the current working directory) must + contain ``CMakePresets.json`` and/or ``CMakeUserPresets.json``. + In prior versions, the latter was strictly required. .. option:: --debugger @@ -793,9 +820,10 @@ following options: .. option:: --preset , --preset= - Use a build preset to specify build options. The project binary directory - is inferred from the ``configurePreset`` key unless a directory is specified - after ``--build``. See :manual:`preset ` for more details. + Use a build :manual:`preset ` to specify build options. + The project binary directory is inferred from the + :preset:`buildPresets.configurePreset` key unless a directory is specified + after ``--build``. .. versionadded:: 4.3 ``cmake --build`` now supports specifying a build directory and @@ -803,7 +831,19 @@ following options: .. versionchanged:: 4.4 ``cmake --build --preset`` no longer needs to be called from the - directory containing the CMake presets files. + directory containing ``CMakePresets.json`` or ``CMakeUserPresets.json``. + If :cmake-build-option:`--presets-file` is specified, CMake will use that + file; otherwise, the presets file(s) can be inferred from the current + build directory's ``CMakeCache.txt``. + +.. option:: --presets-file , --presets-file= + + .. versionadded:: 4.4 + + Reads :manual:`presets ` from the given ````. The + specified path may be absolute or relative to the current working directory. + If ``--presets-file`` is given, presets defined in ``CMakePresets.json`` and + ``CMakeUserPresets.json`` will be ignored. .. option:: --list-presets @@ -811,7 +851,10 @@ following options: .. versionchanged:: 4.4 ``cmake --build --list-presets`` no longer needs to be called from - the directory containing the CMake presets files. + the directory containing ``CMakePresets.json`` or ``CMakeUserPresets.json``. + If :cmake-build-option:`--presets-file` is specified, only presets defined + in the given ```` will be listed; otherwise, the presets file(s) are + inferred from the current build directory's ``CMakeCache.txt``. .. option:: -j [], --parallel [] @@ -1909,10 +1952,8 @@ The options are: .. option:: --preset , --preset= - Use a workflow preset to specify a workflow. The project binary directory - is inferred from the initial configure preset. The current working directory - must contain CMake preset files. - See :manual:`preset ` for more details. + Use a workflow :manual:`preset ` to specify a workflow. + The project binary directory is inferred from the initial configure preset. .. versionchanged:: 3.31 When following immediately after the ``--workflow`` option, @@ -1923,10 +1964,31 @@ The options are: $ cmake --workflow my-preset + .. versionchanged:: 4.4 + If :cmake-workflow-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present. Otherwise, they are required to be present in the top level + source directory. In prior versions, this was strictly required. + +.. option:: --presets-file , --presets-file= + + .. versionadded:: 4.4 + + Reads :manual:`presets ` from the given ````. The + specified path may be absolute or relative to the current working directory. + If ``--presets-file`` is given, presets defined in ``CMakePresets.json`` and + ``CMakeUserPresets.json`` will be ignored. + .. option:: --list-presets - Lists the available workflow presets. The current working directory must - contain CMake preset files. + Lists the available workflow presets. + + .. versionchanged:: 4.4 + If :cmake-workflow-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present, and only presets defined in the given ```` will be listed. + Otherwise, they are required to be present in the top level source + directory. In prior versions, this was strictly required. .. option:: --fresh diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst index b6ac33177f..686d153ed4 100644 --- a/Help/manual/cpack.1.rst +++ b/Help/manual/cpack.1.rst @@ -120,13 +120,37 @@ Options Override/define :variable:`CPACK_PACKAGE_VENDOR`. -.. option:: --preset +.. option:: --preset , --preset= - Use a preset from :manual:`cmake-presets(7)`. + Use a package :manual:`preset ` to specify package + options. The project binary directory is inferred from the + :preset:`packagePresets.configurePreset` key. + + .. versionchanged:: 4.4 + If :cpack-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present. Otherwise, they are required to be present in the top level + source directory. In prior versions, this was strictly required. + +.. option:: --presets-file , --presets-file= + + .. versionadded:: 4.4 + + Reads :manual:`presets ` from the given ````. The + specified path may be absolute or relative to the current working directory. + If ``--presets-file`` is given, presets defined in ``CMakePresets.json`` and + ``CMakeUserPresets.json`` will be ignored. .. option:: --list-presets - List presets from :manual:`cmake-presets(7)`. + Lists the available package presets. + + .. versionchanged:: 4.4 + If :cpack-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present, and only presets defined in the given ```` will be listed. + Otherwise, they are required to be present in the top level source + directory. In prior versions, this was strictly required. .. include:: include/OPTIONS_HELP.rst diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index dba20c1028..c64fd81173 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -69,20 +69,41 @@ The options for running tests are: .. option:: --preset , --preset= - Use a test preset to specify test options. The project binary directory - is inferred from the ``configurePreset`` key. The current working directory - must contain CMake preset files. - See :manual:`preset ` for more details. + Use a test :manual:`preset ` to specify test options. The + project binary directory is inferred from the + :preset:`testPresets.configurePreset` key. .. versionadded:: 3.30 - The ``--test-dir`` option may optionally be specified with a different - binary directory than the one specified by the ``configurePreset`` key - of the test preset. + The :ctest-option:`--test-dir` option may be specified with a different + binary directory than the one specified by the + :preset:`testPresets.configurePreset` key. + + .. versionchanged:: 4.4 + If :ctest-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present. Otherwise, they are required to be present in the top level + source directory. In prior versions, this was strictly required. + +.. option:: --presets-file , --presets-file= + + .. versionadded:: 4.4 + + Reads :manual:`presets ` from the given ````. The + specified path may be absolute or relative to the current working directory. + If ``--presets-file`` is given, presets defined in ``CMakePresets.json`` and + ``CMakeUserPresets.json`` will be ignored. .. option:: --list-presets Lists the available test presets. The current working directory must contain - CMake preset files. + ``CMakePresets.json`` and/or ``CMakeUserPresets.json``. + + .. versionchanged:: 4.4 + If :ctest-option:`--presets-file` is specified, neither of + ``CMakePresets.json`` nor ``CMakeUserPresets.json`` are required to be + present, and only presets defined in the given ```` will be listed. + Otherwise, they are required to be present in the top level source + directory. In prior versions, this was strictly required. .. option:: -C , --build-config diff --git a/Help/manual/presets/buildPresets-properties.rst b/Help/manual/presets/buildPresets-properties.rst index 842ee40e45..1256280e34 100644 --- a/Help/manual/presets/buildPresets-properties.rst +++ b/Help/manual/presets/buildPresets-properties.rst @@ -18,9 +18,10 @@ An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the :cmake-build-option:`--preset` argument and does not have to have a - valid ``configurePreset``, even from inheritance. ``hidden`` - presets are intended to be used as a base for other presets to - inherit via the ``inherits`` field. + valid :preset:`buildPresets.configurePreset`, even from + inheritance. ``hidden`` presets are intended to be used as a base + for other presets to inherit via the + :preset:`buildPresets.inherits` field. .. _`CMakePresets.buildPresets.inherits`: @@ -136,7 +137,7 @@ .. versionchanged:: 4.3 This field does not accept negative integer values, regardless of - the version in the preset file. + the version in the presets file. .. _`CMakePresets.buildPresets.targets`: diff --git a/Help/manual/presets/execution-properties.rst b/Help/manual/presets/execution-properties.rst index ebe80fce91..8e3d4a0f86 100644 --- a/Help/manual/presets/execution-properties.rst +++ b/Help/manual/presets/execution-properties.rst @@ -29,7 +29,7 @@ .. versionchanged:: 4.3 This field does not accept negative integer values, - regardless of the version in the preset file. + regardless of the version in the presets file. .. _`CMakePresets.testPresets.execution.resourceSpecFile`: diff --git a/Help/manual/presets/packagePresets-properties.rst b/Help/manual/presets/packagePresets-properties.rst index 2c21b53789..863500f80c 100644 --- a/Help/manual/presets/packagePresets-properties.rst +++ b/Help/manual/presets/packagePresets-properties.rst @@ -17,9 +17,10 @@ An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the :cpack-option:`--preset` argument and does not have to have a valid - ``configurePreset``, even from inheritance. ``hidden`` presets are - intended to be used as a base for other presets to inherit via the - ``inherits`` field. + :preset:`packagePresets.configurePreset`, even from + inheritance. ``hidden`` presets are intended to be used as a base + for other presets to inherit via the + :preset:`packagePresets.inherits` field. .. _`CMakePresets.packagePresets.inherits`: diff --git a/Help/manual/presets/schema.yaml b/Help/manual/presets/schema.yaml index fe56d73903..c66bab0f42 100644 --- a/Help/manual/presets/schema.yaml +++ b/Help/manual/presets/schema.yaml @@ -963,9 +963,10 @@ properties: An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the :cmake-build-option:`--preset` argument and does not have to have a - valid ``configurePreset``, even from inheritance. ``hidden`` - presets are intended to be used as a base for other presets to - inherit via the ``inherits`` field. + valid :preset:`buildPresets.configurePreset`, even from + inheritance. ``hidden`` presets are intended to be used as a base + for other presets to inherit via the + :preset:`buildPresets.inherits` field. inherits: *preset-inherits condition: *condition vendor: *preset-vendor @@ -1033,7 +1034,7 @@ properties: .. versionchanged:: 4.3 This field does not accept negative integer values, regardless of - the version in the preset file. + the version in the presets file. minimum: 0 targets: anyOf: @@ -1181,9 +1182,10 @@ properties: An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the :ctest-option:`--preset` argument and does not have to have a valid - ``configurePreset``, even from inheritance. ``hidden`` presets are - intended to be used as a base for other presets to inherit via the - ``inherits`` field. + :preset:`testPresets.configurePreset`, even from + inheritance. ``hidden`` presets are intended to be used as a base + for other presets to inherit via the + :preset:`testPresets.inherits` field. inherits: *preset-inherits condition: *condition vendor: *preset-vendor @@ -1629,7 +1631,7 @@ properties: .. versionchanged:: 4.3 This field does not accept negative integer values, - regardless of the version in the preset file. + regardless of the version in the presets file. minimum: 0 resourceSpecFile: type: string @@ -1819,9 +1821,10 @@ properties: An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the :cpack-option:`--preset` argument and does not have to have a valid - ``configurePreset``, even from inheritance. ``hidden`` presets are - intended to be used as a base for other presets to inherit via the - ``inherits`` field. + :preset:`packagePresets.configurePreset`, even from + inheritance. ``hidden`` presets are intended to be used as a base + for other presets to inherit via the + :preset:`packagePresets.inherits` field. inherits: *preset-inherits condition: *condition vendor: *preset-vendor diff --git a/Help/manual/presets/testPresets-properties.rst b/Help/manual/presets/testPresets-properties.rst index 293d88fdd7..6e71ab4f71 100644 --- a/Help/manual/presets/testPresets-properties.rst +++ b/Help/manual/presets/testPresets-properties.rst @@ -17,9 +17,10 @@ An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the :ctest-option:`--preset` argument and does not have to have a valid - ``configurePreset``, even from inheritance. ``hidden`` presets are - intended to be used as a base for other presets to inherit via the - ``inherits`` field. + :preset:`testPresets.configurePreset`, even from + inheritance. ``hidden`` presets are intended to be used as a base + for other presets to inherit via the + :preset:`testPresets.inherits` field. .. _`CMakePresets.testPresets.inherits`: diff --git a/Help/release/3.23.rst b/Help/release/3.23.rst index 20e43c5062..ece6941ccb 100644 --- a/Help/release/3.23.rst +++ b/Help/release/3.23.rst @@ -19,7 +19,7 @@ Presets which allows the files to include other files. * :manual:`cmake-presets(7)` files now support a ``${fileDir}`` macro, which - contains the directory containing the preset file. + contains the directory containing the presets file. * :manual:`cmake-presets(7)` gained support for specifying the ``resolvePackageReferences`` command line option in a build preset to control diff --git a/Help/release/dev/presets-file-arg.rst b/Help/release/dev/presets-file-arg.rst new file mode 100644 index 0000000000..7cfc969034 --- /dev/null +++ b/Help/release/dev/presets-file-arg.rst @@ -0,0 +1,11 @@ +presets-file-arg +---------------- + +* :manual:`cmake(1)`, :manual:`ctest(1)`, and :manual:`cpack(1)` gained + ``--presets-file`` arguments to support loading + :manual:`presets ` from the specified file instead of + ``CMakePresets.json`` and/or ``CMakeUserPresets.json``. See + :option:`cmake --presets-file`, + :option:`cmake --build --presets-file `, + :option:`cmake --workflow --presets-file `, + :option:`ctest --presets-file`, and :option:`cpack --presets-file` for details. diff --git a/Help/release/dev/presets-fileDir.rst b/Help/release/dev/presets-fileDir.rst index 45f41d29a5..6ee8603c9f 100644 --- a/Help/release/dev/presets-fileDir.rst +++ b/Help/release/dev/presets-fileDir.rst @@ -3,5 +3,5 @@ presets-fileDir * :manual:`cmake-presets(7)` files now support schema version 12. The :ref:`${fileDir} ` macro now always expands to the - directory of the preset file containing the ``${fileDir}`` macro, regardless + directory of the presets file containing the ``${fileDir}`` macro, regardless of whether it is inherited by another preset in a different directory. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e7a0aef7d9..a5910ef815 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -125,6 +125,7 @@ add_library( cmCLocaleEnvironmentScope.cxx cmCMakePath.h cmCMakePath.cxx + cmCMakePresetsArgs.h cmCMakePresetsErrors.cxx cmCMakePresetsErrors.h cmCMakePresetsGraph.cxx diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index a7ed74bcba..c595378191 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -19,6 +19,7 @@ #include "cmsys/Encoding.hxx" +#include "cmCMakePresetsArgs.h" #include "cmCMakePresetsGraph.h" #include "cmCPackGenerator.h" #include "cmCPackGeneratorFactory.h" @@ -46,7 +47,7 @@ cmDocumentationEntry const cmDocumentationName = { cmDocumentationEntry const cmDocumentationUsage = { {}, " cpack [options]" }; -cmDocumentationEntry const cmDocumentationOptions[14] = { +cmDocumentationEntry const cmDocumentationOptions[] = { { "-G ", "Override/define CPACK_GENERATOR" }, { "-C ", "Specify the project configuration(s)" }, { "-D =", "Set a CPack variable." }, @@ -60,6 +61,7 @@ cmDocumentationEntry const cmDocumentationOptions[14] = { { "-B ", "Override/define CPACK_PACKAGE_DIRECTORY" }, { "--vendor ", "Override/define CPACK_PACKAGE_VENDOR" }, { "--preset", "Read arguments from a package preset" }, + { "--presets-file", "Load package presets from the given file" }, { "--list-presets", "List available package presets" } }; @@ -130,8 +132,7 @@ int main(int argc, char const* const* argv) std::string cpackProjectVendor; std::string cpackConfigFile; - std::string preset; - bool listPresets = false; + cmCMakePresetsArgs presetsArgs; std::map definitions; @@ -162,6 +163,12 @@ int main(int argc, char const* const* argv) return true; }; + auto const presetFileLambda = [&presetsArgs](std::string const& value, + cmake*, cmMakefile*) -> bool { + presetsArgs.PresetsFile = cmSystemTools::ToNormalizedPathOnDisk(value); + return true; + }; + using CommandArgument = cmCommandLineArgument; @@ -201,9 +208,11 @@ int main(int argc, char const* const* argv) CommandArgument::setToValue(cpackProjectVendor) }, CommandArgument{ "--preset", "No preset specified for --preset", CommandArgument::Values::One, - CommandArgument::setToValue(preset) }, + CommandArgument::setToValue(presetsArgs.PresetName) }, CommandArgument{ "--list-presets", CommandArgument::Values::Zero, - CommandArgument::setToTrue(listPresets) }, + CommandArgument::setToTrue(presetsArgs.ListPresets) }, + CommandArgument{ "--presets-file", "No file specified for --presets-file", + CommandArgument::Values::One, presetFileLambda }, CommandArgument{ "-D", CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, [&log, &definitions](std::string const& arg, cmake*, @@ -249,7 +258,7 @@ int main(int argc, char const* const* argv) generators.SetLogger(&log); // Set up presets - if (!preset.empty() || listPresets) { + if (presetsArgs.HasPresetsArg()) { auto const workingDirectory = cmSystemTools::GetLogicalWorkingDirectory(); auto const presetGeneratorsPresent = @@ -262,7 +271,8 @@ int main(int argc, char const* const* argv) }; cmCMakePresetsGraph presetsGraph; - auto result = presetsGraph.ReadProjectPresets(workingDirectory); + auto result = presetsGraph.ReadProjectPresets(workingDirectory, + presetsArgs.PresetsFile); if (result != true) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Could not read presets from " @@ -271,13 +281,13 @@ int main(int argc, char const* const* argv) return 1; } - if (listPresets) { + if (presetsArgs.ListPresets) { presetsGraph.PrintPackagePresetList(presetGeneratorsPresent); return 0; } - auto resolveResult = - presetsGraph.ResolvePreset(preset, presetsGraph.PackagePresets); + auto resolveResult = presetsGraph.ResolvePreset( + presetsArgs.PresetName, presetsGraph.PackagePresets); auto resolveError = cmCMakePresetsGraph::FormatPresetError< cmCMakePresetsGraph::PackagePreset>(resolveResult.StatusCode, resolveResult.ErrorPresetName, diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 7bbf5a366c..6546088e6a 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -81,7 +81,7 @@ std::unique_ptr cmCTestBuildCommand::InitializeHandler( mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY"); cmCMakePresetsGraph presetsGraph; - if (!presetsGraph.ReadProjectPresets(sourceDirectory)) { + if (!presetsGraph.ReadProjectPresets(sourceDirectory, "")) { status.SetError( cmStrCat("Could not read presets from \"", sourceDirectory, "\": ", presetsGraph.parseState.GetErrorMessage())); diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index bede3b1d16..3e9e1dc7b6 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -64,7 +64,7 @@ bool ConstructConfigureCommand(cmExecutionStatus& status, cmMakefile& mf, if (!presetName.empty()) { cmCMakePresetsGraph presetsGraph; - if (!presetsGraph.ReadProjectPresets(sourceDirectory)) { + if (!presetsGraph.ReadProjectPresets(sourceDirectory, "")) { status.SetError( cmStrCat("Could not read presets from \"", sourceDirectory, "\": ", presetsGraph.parseState.GetErrorMessage())); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 9e11197188..eb743bc1e4 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -541,7 +541,8 @@ void QCMake::setUpEnvironment() const void QCMake::loadPresets() { auto result = this->CMakePresetsGraph.ReadProjectPresets( - this->SourceDirectory.toStdString(), true); + this->SourceDirectory.toStdString(), "", + cmCMakePresetsGraph::ReadOption::AllowNoFiles); if (!result) { emit this->presetLoadError( this->SourceDirectory, diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index 32c964cb4d..9be5259e81 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -111,7 +111,7 @@ public slots: cmDiagnostics::DiagnosticAction); /// check if project IDE open is possible and emit openPossible signal void checkOpenPossible(); - /// Reload the preset files and tree + /// Reload the presets files and tree void loadPresets(); public: diff --git a/Source/cmCMakePresetsArgs.h b/Source/cmCMakePresetsArgs.h new file mode 100644 index 0000000000..7228c9dc01 --- /dev/null +++ b/Source/cmCMakePresetsArgs.h @@ -0,0 +1,78 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ +#pragma once + +#include + +class cmCMakePresetsArgsBase +{ +public: + virtual ~cmCMakePresetsArgsBase() = default; + + virtual bool HasPresetsArg() const { return !this->PresetName.empty(); }; + virtual void Clear() { this->PresetName.clear(); } + + std::string PresetName; + std::string PresetsFile; + +protected: + cmCMakePresetsArgsBase() = default; +}; + +class cmCMakePresetsArgs : public cmCMakePresetsArgsBase +{ +public: + bool HasPresetsArg() const override + { + return this->cmCMakePresetsArgsBase::HasPresetsArg() || this->ListPresets; + } + + void Clear() override + { + this->cmCMakePresetsArgsBase::Clear(); + this->ListPresets = false; + } + + bool ListPresets = false; +}; + +class cmCMakePresetsConfigureArgs : public cmCMakePresetsArgsBase +{ +public: + enum class ListPresetsOption + { + None, + Configure, + Build, + Test, + Package, + Workflow, + All, + }; + + bool HasPresetsArg() const override + { + return this->cmCMakePresetsArgsBase::HasPresetsArg() || + this->ListPresets != ListPresetsOption::None; + } + + void Clear() override + { + this->cmCMakePresetsArgsBase::Clear(); + this->ListPresets = ListPresetsOption::None; + } + + ListPresetsOption ListPresets = ListPresetsOption::None; +}; + +class cmCMakePresetsWorkflowArgs : public cmCMakePresetsArgs +{ +public: + void Clear() override + { + this->cmCMakePresetsArgs::Clear(); + this->Fresh = false; + } + + bool Fresh = false; +}; diff --git a/Source/cmCMakePresetsErrors.cxx b/Source/cmCMakePresetsErrors.cxx index 6b454aca04..8f82e66de2 100644 --- a/Source/cmCMakePresetsErrors.cxx +++ b/Source/cmCMakePresetsErrors.cxx @@ -197,7 +197,7 @@ void PASSTHROUGH_ARGS_UNSUPPORTED(cmJSONState* state) void CYCLIC_INCLUDE(std::string const& file, cmJSONState* state) { - state->AddError(cmStrCat("Cyclic include among preset files: ", file)); + state->AddError(cmStrCat("Cyclic include among presets files: ", file)); } void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state) diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index 7e57854753..212a97b71b 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -1142,12 +1142,13 @@ std::string cmCMakePresetsGraph::GetUserFilename(std::string const& sourceDir) } bool cmCMakePresetsGraph::ReadProjectPresets(std::string const& sourceDir, - bool allowNoFiles) + std::string const& presetsFile, + ReadOption readFilesOption) { this->SourceDir = cmSystemTools::CollapseFullPath(sourceDir); this->ClearPresets(); - if (!this->ReadProjectPresetsInternal(allowNoFiles)) { + if (!this->ReadProjectPresetsInternal(presetsFile, readFilesOption)) { this->ClearPresets(); return false; } @@ -1183,33 +1184,46 @@ std::string cmCMakePresetsGraph::GetGeneratorForPreset( return {}; } -bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles) +bool cmCMakePresetsGraph::ReadProjectPresetsInternal( + std::string const& presetsFile, ReadOption readFilesOption) { bool haveOneFile = false; File* file; - std::string filename = GetUserFilename(this->SourceDir); + std::string filename; std::vector inProgressFiles; - if (cmSystemTools::FileExists(filename)) { - if (!this->ReadJSONFile(filename, RootType::User, ReadReason::Root, - inProgressFiles, file, this->errors)) { - return false; - } - haveOneFile = true; - } else { - filename = GetFilename(this->SourceDir); + if (!presetsFile.empty()) { + filename = presetsFile; if (cmSystemTools::FileExists(filename)) { - if (!this->ReadJSONFile(filename, RootType::Project, ReadReason::Root, + if (!this->ReadJSONFile(filename, RootType::Any, ReadReason::Root, inProgressFiles, file, this->errors)) { return false; } haveOneFile = true; } + } else { + filename = GetUserFilename(this->SourceDir); + if (cmSystemTools::FileExists(filename)) { + if (!this->ReadJSONFile(filename, RootType::User, ReadReason::Root, + inProgressFiles, file, this->errors)) { + return false; + } + haveOneFile = true; + } else { + filename = GetFilename(this->SourceDir); + if (cmSystemTools::FileExists(filename)) { + if (!this->ReadJSONFile(filename, RootType::Project, ReadReason::Root, + inProgressFiles, file, this->errors)) { + return false; + } + haveOneFile = true; + } + } } assert(inProgressFiles.empty()); if (!haveOneFile) { - if (allowNoFiles) { + if (readFilesOption == ReadOption::AllowNoFiles) { return true; } cmCMakePresetsErrors::FILE_NOT_FOUND(filename, &this->parseState); diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h index 209fd647ca..74063e4113 100644 --- a/Source/cmCMakePresetsGraph.h +++ b/Source/cmCMakePresetsGraph.h @@ -453,8 +453,15 @@ public: return preset.OriginFile->Version; } - bool ReadProjectPresets(std::string const& sourceDir, - bool allowNoFiles = false); + enum class ReadOption + { + RequireFiles, + AllowNoFiles, + }; + + bool ReadProjectPresets( + std::string const& sourceDir, std::string const& presetsFile, + ReadOption readFilesOption = ReadOption::RequireFiles); std::string GetGeneratorForPreset(std::string const& presetName) const; @@ -472,6 +479,7 @@ public: private: enum class RootType { + Any, Project, User, }; @@ -482,7 +490,8 @@ private: Included, }; - bool ReadProjectPresetsInternal(bool allowNoFiles); + bool ReadProjectPresetsInternal(std::string const& presetsFile, + ReadOption readFilesOption); bool ReadJSONFile(std::string const& filename, RootType rootType, ReadReason readReason, std::vector& inProgressFiles, File*& file, std::string& errMsg); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e57bd9df68..9bec12f3a6 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -42,6 +42,7 @@ #include "cm_parse_date.h" +#include "cmCMakePresetsArgs.h" #include "cmCMakePresetsGraph.h" #include "cmCTestBuildAndTest.h" #include "cmCTestScriptHandler.h" @@ -1501,13 +1502,13 @@ bool cmCTest::AddVariableDefinition(std::string const& arg) return false; } -bool cmCTest::SetArgsFromPreset(std::string const& presetName, - bool listPresets) +bool cmCTest::SetArgsFromPreset(cmCMakePresetsArgs const& args) { auto const workingDirectory = cmSystemTools::GetLogicalWorkingDirectory(); cmCMakePresetsGraph settingsFile; - auto result = settingsFile.ReadProjectPresets(workingDirectory); + auto result = + settingsFile.ReadProjectPresets(workingDirectory, args.PresetsFile); if (result != true) { cmSystemTools::Error(cmStrCat("Could not read presets from ", workingDirectory, ":\n", @@ -1515,13 +1516,13 @@ bool cmCTest::SetArgsFromPreset(std::string const& presetName, return false; } - if (listPresets) { + if (args.ListPresets) { settingsFile.PrintTestPresetList(); return true; } auto resolveResult = - settingsFile.ResolvePreset(presetName, settingsFile.TestPresets); + settingsFile.ResolvePreset(args.PresetName, settingsFile.TestPresets); auto resolveError = cmCMakePresetsGraph::FormatPresetError( resolveResult.StatusCode, resolveResult.ErrorPresetName, @@ -1801,8 +1802,7 @@ int cmCTest::Run(std::vector const& args) bool processSteps = false; bool SRArgumentSpecified = false; std::vector> runScripts; - bool listPresets = false; - std::string presetName; + cmCMakePresetsArgs presetsArgs; // copy the command line cm::append(this->Impl->InitialCommandLineArguments, args); @@ -1990,14 +1990,21 @@ int cmCTest::Run(std::vector const& args) auto const presetArguments = std::vector{ CommandArgument{ "--list-presets", CommandArgument::Values::Zero, - [&listPresets](std::string const&) -> bool { - listPresets = true; + [&presetsArgs](std::string const&) -> bool { + presetsArgs.ListPresets = true; return true; } }, CommandArgument{ "--preset", "'--preset' requires an argument", CommandArgument::Values::One, - [&presetName](std::string const& presetArg) -> bool { - presetName = presetArg; + [&presetsArgs](std::string const& presetArg) -> bool { + presetsArgs.PresetName = presetArg; + return true; + } }, + CommandArgument{ "--presets-file", "'--presets-file' requires an argument", + CommandArgument::Values::One, + [&presetsArgs](std::string const& presetFileArg) -> bool { + presetsArgs.PresetsFile = + cmSystemTools::ToNormalizedPathOnDisk(presetFileArg); return true; } } }; @@ -2490,9 +2497,9 @@ int cmCTest::Run(std::vector const& args) } } - if (listPresets || !presetName.empty()) { - bool success = this->SetArgsFromPreset(presetName, listPresets); - if (listPresets) { + if (presetsArgs.HasPresetsArg()) { + bool success = this->SetArgsFromPreset(presetsArgs); + if (presetsArgs.ListPresets) { return static_cast(!success); } if (!success) { @@ -2607,8 +2614,8 @@ int cmCTest::Run(std::vector const& args) } } - // TestProgressOutput only supported if console supports it and not logging - // to a file + // TestProgressOutput only supported if console supports it and not + // logging to a file this->Impl->TestProgressOutput = this->Impl->TestProgressOutput && !this->Impl->OutputLogFile && this->ProgressOutputSupportedByConsole(); #ifdef _WIN32 diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 46c88b7ffc..8dce3476d3 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -20,6 +20,7 @@ #include "cmProcessOutput.h" class cmake; +class cmCMakePresetsArgs; class cmGeneratedFileStream; class cmInstrumentation; class cmMakefile; @@ -452,7 +453,7 @@ private: bool AddVariableDefinition(std::string const& arg); /** set command line arguments read from a test preset */ - bool SetArgsFromPreset(std::string const& presetName, bool listPresets); + bool SetArgsFromPreset(cmCMakePresetsArgs const& args); /** returns true iff the console supports progress output */ static bool ProgressOutputSupportedByConsole(); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index a51374fc80..2918cd1136 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -86,6 +86,7 @@ # include # include +# include "cmCMakePresetsArgs.h" # include "cmConfigureLog.h" # include "cmFileAPI.h" # include "cmGraphVizWriter.h" @@ -1014,9 +1015,9 @@ void cmake::SetArgs(std::vector const& args) #if !defined(CMAKE_BOOTSTRAP) std::string profilingFormat; std::string profilingOutput; - std::string presetName; - ListPresets listPresets = ListPresets::None; + cmCMakePresetsConfigureArgs presetsArgs; + using ListPresets = cmCMakePresetsConfigureArgs::ListPresetsOption; #endif auto EmptyStringArgLambda = [](std::string const&, cmake* state) -> bool { @@ -1429,24 +1430,31 @@ void cmake::SetArgs(std::vector const& args) arguments.emplace_back("--preset", "No preset specified for --preset", CommandArgument::Values::One, [&](std::string const& value, cmake*) -> bool { - presetName = value; + presetsArgs.PresetName = value; return true; }); + arguments.emplace_back( + "--presets-file", "No file specified for --presets-file", + CommandArgument::Values::One, + [&presetsArgs](std::string const& value, cmake*) -> bool { + presetsArgs.PresetsFile = cmSystemTools::ToNormalizedPathOnDisk(value); + return true; + }); arguments.emplace_back( "--list-presets", CommandArgument::Values::ZeroOrOne, [&](std::string const& value, cmake*) -> bool { if (value.empty() || value == "configure") { - listPresets = ListPresets::Configure; + presetsArgs.ListPresets = ListPresets::Configure; } else if (value == "build") { - listPresets = ListPresets::Build; + presetsArgs.ListPresets = ListPresets::Build; } else if (value == "test") { - listPresets = ListPresets::Test; + presetsArgs.ListPresets = ListPresets::Test; } else if (value == "package") { - listPresets = ListPresets::Package; + presetsArgs.ListPresets = ListPresets::Package; } else if (value == "workflow") { - listPresets = ListPresets::Workflow; + presetsArgs.ListPresets = ListPresets::Workflow; } else if (value == "all") { - listPresets = ListPresets::All; + presetsArgs.ListPresets = ListPresets::All; } else { cmSystemTools::Error( "Invalid value specified for --list-presets.\n" @@ -1573,7 +1581,7 @@ void cmake::SetArgs(std::vector const& args) #ifdef CMAKE_BOOTSTRAP false; #else - !presetName.empty(); + !presetsArgs.PresetName.empty(); #endif if (this->State->GetRole() == cmState::Role::Project && !haveSourceDir && @@ -1593,8 +1601,8 @@ void cmake::SetArgs(std::vector const& args) } #if !defined(CMAKE_BOOTSTRAP) - if (listPresets != ListPresets::None || !presetName.empty()) { - this->SetArgsFromPreset(presetName, listPresets, haveBArg); + if (presetsArgs.HasPresetsArg()) { + this->SetArgsFromPreset(presetsArgs, haveBArg); } #endif } @@ -2009,11 +2017,14 @@ bool cmake::CreateAndSetGlobalGenerator(std::string const& name) } #ifndef CMAKE_BOOTSTRAP -bool cmake::SetArgsFromPreset(std::string const& presetName, - ListPresets listPresets, bool haveBinaryDirArg) +bool cmake::SetArgsFromPreset(cmCMakePresetsConfigureArgs const& args, + bool haveBinaryDirArg) { + using ListPresets = cmCMakePresetsConfigureArgs::ListPresetsOption; + cmCMakePresetsGraph presetsGraph; - auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory()); + auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory(), + args.PresetsFile); if (result != true) { std::string errorMsg = cmStrCat("Could not read presets from ", this->GetHomeDirectory(), ":\n", @@ -2022,19 +2033,28 @@ bool cmake::SetArgsFromPreset(std::string const& presetName, return false; } - if (listPresets != ListPresets::None) { - if (listPresets == ListPresets::Configure) { - this->PrintPresetList(presetsGraph); - } else if (listPresets == ListPresets::Build) { - presetsGraph.PrintBuildPresetList(); - } else if (listPresets == ListPresets::Test) { - presetsGraph.PrintTestPresetList(); - } else if (listPresets == ListPresets::Package) { - presetsGraph.PrintPackagePresetList(); - } else if (listPresets == ListPresets::Workflow) { - presetsGraph.PrintWorkflowPresetList(); - } else if (listPresets == ListPresets::All) { - presetsGraph.PrintAllPresets(); + if (args.ListPresets != ListPresets::None) { + switch (args.ListPresets) { + case ListPresets::Configure: + this->PrintPresetList(presetsGraph); + break; + case ListPresets::Build: + presetsGraph.PrintBuildPresetList(); + break; + case ListPresets::Test: + presetsGraph.PrintTestPresetList(); + break; + case ListPresets::Package: + presetsGraph.PrintPackagePresetList(); + break; + case ListPresets::Workflow: + presetsGraph.PrintWorkflowPresetList(); + break; + case ListPresets::All: + presetsGraph.PrintAllPresets(); + break; + default: + break; } this->State->SetRoleToHelpForListPresets(); @@ -2042,7 +2062,7 @@ bool cmake::SetArgsFromPreset(std::string const& presetName, } auto resolveResult = - presetsGraph.ResolvePreset(presetName, presetsGraph.ConfigurePresets); + presetsGraph.ResolvePreset(args.PresetName, presetsGraph.ConfigurePresets); using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; using S = cmCMakePresetsGraph::PresetResolveStatus; auto resolveError = cmCMakePresetsGraph::FormatPresetError( @@ -3897,13 +3917,14 @@ std::vector cmake::GetDebugConfigs() int cmake::Build(cmBuildArgs buildArgs, std::vector targets, std::vector nativeOptions, - cmBuildOptions& buildOptions, std::string const& presetName, - bool listPresets, std::vector const& args) + cmBuildOptions& buildOptions, + cmCMakePresetsArgs const& presetsArgs, + std::vector const& args) { buildArgs.timeout = cmDuration::zero(); #if !defined(CMAKE_BOOTSTRAP) - if (!presetName.empty() || listPresets) { + if (presetsArgs.HasPresetsArg()) { // If the binary directory was specified, use it to find // the source directory so we can locate the presets file. if (!buildArgs.binaryDir.empty() && @@ -3916,7 +3937,8 @@ int cmake::Build(cmBuildArgs buildArgs, std::vector targets, cmSystemTools::GetLogicalWorkingDirectory()); } cmCMakePresetsGraph settingsFile; - auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); + auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory(), + presetsArgs.PresetsFile); if (result != true) { cmSystemTools::Error( cmStrCat("Could not read presets from ", this->GetHomeDirectory(), @@ -3924,13 +3946,13 @@ int cmake::Build(cmBuildArgs buildArgs, std::vector targets, return 1; } - if (listPresets) { + if (presetsArgs.ListPresets) { settingsFile.PrintBuildPresetList(); return 0; } - auto resolveResult = - settingsFile.ResolvePreset(presetName, settingsFile.BuildPresets); + auto resolveResult = settingsFile.ResolvePreset(presetsArgs.PresetName, + settingsFile.BuildPresets); auto resolveError = cmCMakePresetsGraph::FormatPresetError( resolveResult.StatusCode, resolveResult.ErrorPresetName, @@ -4261,8 +4283,7 @@ std::function buildWorkflowStep( } #endif -int cmake::Workflow(std::string const& presetName, - WorkflowListPresets listPresets, WorkflowFresh fresh) +int cmake::Workflow(cmCMakePresetsWorkflowArgs const& args) { int exitStatus = 0; #ifndef CMAKE_BOOTSTRAP @@ -4270,7 +4291,8 @@ int cmake::Workflow(std::string const& presetName, this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory()); cmCMakePresetsGraph settingsFile; - auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); + auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory(), + args.PresetsFile); if (result != true) { cmSystemTools::Error(cmStrCat("Could not read presets from ", this->GetHomeDirectory(), ":\n", @@ -4278,24 +4300,24 @@ int cmake::Workflow(std::string const& presetName, return 1; } - if (listPresets == WorkflowListPresets::Yes) { + if (args.ListPresets) { settingsFile.PrintWorkflowPresetList(); return 0; } - auto presetPair = settingsFile.WorkflowPresets.find(presetName); + auto presetPair = settingsFile.WorkflowPresets.find(args.PresetName); if (presetPair == settingsFile.WorkflowPresets.end()) { cmSystemTools::Error(cmStrCat("No such workflow preset in ", - this->GetHomeDirectory(), ": \"", presetName, - '"')); + this->GetHomeDirectory(), ": \"", + args.PresetName, '"')); settingsFile.PrintWorkflowPresetList(); return 1; } if (presetPair->second.Unexpanded.Hidden) { cmSystemTools::Error(cmStrCat("Cannot use hidden workflow preset in ", - this->GetHomeDirectory(), ": \"", presetName, - '"')); + this->GetHomeDirectory(), ": \"", + args.PresetName, '"')); settingsFile.PrintWorkflowPresetList(); return 1; } @@ -4303,15 +4325,16 @@ int cmake::Workflow(std::string const& presetName, auto const& expandedPreset = presetPair->second.Expanded; if (!expandedPreset) { cmSystemTools::Error(cmStrCat("Could not evaluate workflow preset \"", - presetName, "\": Invalid macro expansion")); + args.PresetName, + "\": Invalid macro expansion")); settingsFile.PrintWorkflowPresetList(); return 1; } if (!expandedPreset->ConditionResult) { cmSystemTools::Error(cmStrCat("Cannot use disabled workflow preset in ", - this->GetHomeDirectory(), ": \"", presetName, - '"')); + this->GetHomeDirectory(), ": \"", + args.PresetName, '"')); settingsFile.PrintWorkflowPresetList(); return 1; } @@ -4347,13 +4370,14 @@ int cmake::Workflow(std::string const& presetName, if (!configurePreset) { return 1; } - std::vector args{ cmSystemTools::GetCMakeCommand(), - "--preset", step.PresetName }; - if (fresh == WorkflowFresh::Yes) { - args.emplace_back("--fresh"); + std::vector configureCmdArgs{ + cmSystemTools::GetCMakeCommand(), "--preset", step.PresetName + }; + if (args.Fresh) { + configureCmdArgs.emplace_back("--fresh"); } steps.emplace_back(stepNumber, "configure"_s, step.PresetName, - buildWorkflowStep(args)); + buildWorkflowStep(configureCmdArgs)); } break; case cmCMakePresetsGraph::WorkflowPreset::WorkflowStep::Type::Build: { auto const* buildPreset = this->FindPresetForWorkflow( diff --git a/Source/cmake.h b/Source/cmake.h index c2a0f05345..900cbb44f1 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -48,6 +48,9 @@ class cmDebuggerAdapter; #endif class cmExternalMakefileProjectGeneratorFactory; +class cmCMakePresetsArgs; +class cmCMakePresetsConfigureArgs; +class cmCMakePresetsWorkflowArgs; class cmFileAPI; class cmInstrumentation; class cmFileTimeCache; @@ -254,19 +257,8 @@ public: bool CreateAndSetGlobalGenerator(std::string const& name); #ifndef CMAKE_BOOTSTRAP - enum class ListPresets - { - None, - Configure, - Build, - Test, - Package, - Workflow, - All, - }; - - bool SetArgsFromPreset(std::string const& presetName, - ListPresets listPresets, bool haveBinaryDirArg); + bool SetArgsFromPreset(cmCMakePresetsConfigureArgs const& args, + bool haveBinaryDirArg); void PrintPresetList(cmCMakePresetsGraph const& graph) const; #endif @@ -627,8 +619,9 @@ public: //! run the --build option int Build(cmBuildArgs buildArgs, std::vector targets, std::vector nativeOptions, - cmBuildOptions& buildOptions, std::string const& presetName, - bool listPresets, std::vector const& args); + cmBuildOptions& buildOptions, + cmCMakePresetsArgs const& presetsArgs, + std::vector const& args); enum class DryRun { @@ -640,18 +633,7 @@ public: bool Open(std::string const& dir, DryRun dryRun); //! run the --workflow option - enum class WorkflowListPresets - { - No, - Yes, - }; - enum class WorkflowFresh - { - No, - Yes, - }; - int Workflow(std::string const& presetName, WorkflowListPresets listPresets, - WorkflowFresh fresh); + int Workflow(cmCMakePresetsWorkflowArgs const& args); void UnwatchUnusedCli(std::string const& var); void WatchUnusedCli(std::string const& var); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 7b325ee352..d7f0c8858c 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -44,6 +44,7 @@ #include "cmcmd.h" #ifndef CMAKE_BOOTSTRAP +# include "cmCMakePresetsArgs.h" # include "cmDocumentation.h" #endif @@ -75,6 +76,8 @@ cmDocumentationEntry const cmDocumentationUsageNote = { cmDocumentationEntry const cmDocumentationOptions[] = { { "--preset ,--preset=", "Specify a configure preset." }, + { "--presets-file ,--presets-file=", + "Specify the path to a presets file." }, { "--list-presets[=]", "List available presets." }, { "--workflow []", "Run a workflow preset." }, { "-E", "CMake command mode. Run \"cmake -E\" for a summary of commands." }, @@ -474,8 +477,7 @@ int do_build(int ac, char const* const* av) bool foundNonClean = false; PackageResolveMode resolveMode = PackageResolveMode::Default; buildArgs.verbose = cmSystemTools::HasEnv("VERBOSE"); - std::string presetName; - bool listPresets = false; + cmCMakePresetsArgs presetsArgs; auto jLambda = extract_job_number_lambda_builder(buildArgs.binaryDir, buildArgs.jobs, "-j"); @@ -516,6 +518,10 @@ int do_build(int ac, char const* const* av) buildArgs.verbose = true; return true; }; + auto presetFileLambda = [&](std::string const& value) -> bool { + presetsArgs.PresetsFile = cmSystemTools::ToNormalizedPathOnDisk(value); + return true; + }; using CommandArgument = cmCommandLineArgument; @@ -523,9 +529,11 @@ int do_build(int ac, char const* const* av) std::vector arguments = { CommandArgument{ "--preset", "No preset specified for --preset", CommandArgument::Values::One, - CommandArgument::setToValue(presetName) }, + CommandArgument::setToValue(presetsArgs.PresetName) }, + CommandArgument{ "--presets-file", "No file specified for --presets-file", + CommandArgument::Values::One, presetFileLambda }, CommandArgument{ "--list-presets", CommandArgument::Values::Zero, - CommandArgument::setToTrue(listPresets) }, + CommandArgument::setToTrue(presetsArgs.ListPresets) }, CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, CommandArgument::RequiresSeparator::No, jLambda }, CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne, @@ -622,7 +630,7 @@ int do_build(int ac, char const* const* av) } } - if (buildArgs.binaryDir.empty() && presetName.empty() && !listPresets) { + if (buildArgs.binaryDir.empty() && !presetsArgs.HasPresetsArg()) { /* clang-format off */ std::cerr << "Usage: cmake --build " @@ -633,6 +641,8 @@ int do_build(int ac, char const* const* av) " = Project binary directory to be built.\n" " --preset , --preset=\n" " = Specify a build preset.\n" + " --presets-file , --presets-file=\n" + " = Specify the path to a presets file.\n" " --list-presets[=]\n" " = List available build presets.\n" " --parallel [], -j []\n" @@ -672,7 +682,7 @@ int do_build(int ac, char const* const* av) std::vector cmd; cm::append(cmd, av, av + ac); return cm.Build(buildArgs, std::move(targets), std::move(nativeOptions), - buildOptions, presetName, listPresets, cmd); + buildOptions, presetsArgs, cmd); #endif } @@ -980,11 +990,7 @@ int do_workflow(int ac, char const* const* av) std::cerr << "This cmake does not support --workflow\n"; return -1; #else - using WorkflowListPresets = cmake::WorkflowListPresets; - using WorkflowFresh = cmake::WorkflowFresh; - std::string presetName; - auto listPresets = WorkflowListPresets::No; - auto fresh = WorkflowFresh::No; + cmCMakePresetsWorkflowArgs presetsArgs; using CommandArgument = cmCommandLineArgument; @@ -992,17 +998,18 @@ int do_workflow(int ac, char const* const* av) std::vector arguments = { CommandArgument{ "--preset", "No preset specified for --preset", CommandArgument::Values::One, - CommandArgument::setToValue(presetName) }, + CommandArgument::setToValue(presetsArgs.PresetName) }, + CommandArgument{ "--presets-file", "No file specified for --presets-file", + CommandArgument::Values::One, + [&presetsArgs](std::string const& value) -> bool { + presetsArgs.PresetsFile = + cmSystemTools::ToNormalizedPathOnDisk(value); + return true; + } }, CommandArgument{ "--list-presets", CommandArgument::Values::Zero, - [&listPresets](std::string const&) -> bool { - listPresets = WorkflowListPresets::Yes; - return true; - } }, + CommandArgument::setToTrue(presetsArgs.ListPresets) }, CommandArgument{ "--fresh", CommandArgument::Values::Zero, - [&fresh](std::string const&) -> bool { - fresh = WorkflowFresh::Yes; - return true; - } }, + CommandArgument::setToTrue(presetsArgs.Fresh) } }; std::vector inputArgs; @@ -1029,23 +1036,23 @@ int do_workflow(int ac, char const* const* av) } if (!(matched && parsed)) { if (!matched) { - presetName.clear(); - listPresets = WorkflowListPresets::No; + presetsArgs.Clear(); std::cerr << "Unknown argument " << arg << std::endl; } break; } } - if (presetName.empty() && listPresets == WorkflowListPresets::No) { + if (!presetsArgs.HasPresetsArg()) { /* clang-format off */ std::cerr << "Usage: cmake --workflow \n" "Options:\n" - " --preset = Workflow preset to execute.\n" - " --list-presets = List available workflow presets.\n" - " --fresh = Configure a fresh build tree, removing any " - "existing cache file.\n" + " --preset = Workflow preset to execute.\n" + " --presets-file = Path to a presets file.\n" + " --list-presets = List available workflow presets.\n" + " --fresh = Configure a fresh build tree, removing any " + "existing cache file.\n" ; /* clang-format on */ return 1; @@ -1060,7 +1067,7 @@ int do_workflow(int ac, char const* const* av) cmakemainProgressCallback(msg, prog, &cm); }); - return cm.Workflow(presetName, listPresets, fresh); + return cm.Workflow(presetsArgs); #endif } diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt index f7e346194e..357050f2b2 100644 --- a/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt +++ b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt @@ -1,4 +1,4 @@ ^CMake Error: Could not read presets from [^ ]*/Tests/RunCMake/CMakePresets/IncludeCycle: -Cyclic include among preset files: [^ +Cyclic include among presets files: [^ ]*/CMakeUserPresets\.json$ diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt index 85ddab1870..c106f2996b 100644 --- a/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt +++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt @@ -1,4 +1,4 @@ CMake Error: Could not read presets from [^ ]*/Tests/RunCMake/CMakePresets/IncludeCycle3Files: -Cyclic include among preset files: [^ +Cyclic include among presets files: [^ ]*/CMakePresets\.json diff --git a/Tests/RunCMake/CMakePresets/NoPresetFileArgument-result.txt b/Tests/RunCMake/CMakePresets/NoPresetFileArgument-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetFileArgument-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoPresetFileArgument-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetFileArgument-stderr.txt new file mode 100644 index 0000000000..29d37adc68 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetFileArgument-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: No file specified for --presets-file +CMake Error: Run 'cmake --help' for all supported options\.$ diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFile.cmake b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFile.cmake new file mode 100644 index 0000000000..d15bd8ded8 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFile.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(PRESETS_FILE "UNINITIALIZED" "OtherCMakePresetsFile.json") diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFile.json.in b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFile.json.in new file mode 100644 index 0000000000..af68ee8139 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFile.json.in @@ -0,0 +1,54 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "OtherCMakePresetsFile", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "PRESETS_FILE": "OtherCMakePresetsFile.json" + } + } + ], + "buildPresets": [ + { + "name": "OtherCMakePresetsFile", + "configurePreset": "OtherCMakePresetsFile" + } + ], + "testPresets": [ + { + "name": "OtherCMakePresetsFile", + "configurePreset": "OtherCMakePresetsFile" + } + ], + "packagePresets": [ + { + "name": "OtherCMakePresetsFile", + "configurePreset": "OtherCMakePresetsFile" + } + ], + "workflowPresets": [ + { + "name": "OtherCMakePresetsFile", + "steps": [ + { + "type": "configure", + "name": "OtherCMakePresetsFile" + }, + { + "type": "build", + "name": "OtherCMakePresetsFile" + }, + { + "type": "test", + "name": "OtherCMakePresetsFile" + }, + { + "type": "package", + "name": "OtherCMakePresetsFile" + } + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileCMakePresets.json.in b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileCMakePresets.json.in new file mode 100644 index 0000000000..4b7648d4be --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileCMakePresets.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "OtherCMakePresetsFile", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "PRESETS_FILE": "CMakePresets.json" + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileCMakeUserPresets.json.in b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileCMakeUserPresets.json.in new file mode 100644 index 0000000000..185f46de13 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileCMakeUserPresets.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "OtherCMakePresetsFile", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "PRESETS_FILE": "CMakeUserPresets.json" + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileList-stdout.txt b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileList-stdout.txt new file mode 100644 index 0000000000..7ec3a373c0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileList-stdout.txt @@ -0,0 +1,19 @@ +^Available configure presets: + + "OtherCMakePresetsFile" + +Available build presets: + + "OtherCMakePresetsFile" + +Available test presets: + + "OtherCMakePresetsFile" + +Available package presets: + + "OtherCMakePresetsFile" + +Available workflow presets: + + "OtherCMakePresetsFile"$ diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileRelPath.cmake b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileRelPath.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileSubdir.cmake b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileSubdir.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-result.txt b/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-stderr.txt b/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-stderr.txt new file mode 100644 index 0000000000..668f949d8a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist: +File not found: [^ +]*/FileDoesNotExist\.json$ diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index c816830a9d..8ca58a24a4 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -30,6 +30,33 @@ function(run_cmake_presets name) endif() configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY) + set(_presets_file) + if(CMakePresets_FILE_ARG) + cmake_path(GET RunCMake_TEST_SOURCE_DIR PARENT_PATH CMakePresets_FILE_ARG_DIRECTORY) + cmake_path(APPEND CMakePresets_FILE_ARG_DIRECTORY "_OtherCMakePresetsFiles") + if(NOT RunCMake_TEST_SOURCE_DIR_NO_CLEAN) + file(REMOVE_RECURSE "${CMakePresets_FILE_ARG_DIRECTORY}") + file(MAKE_DIRECTORY "${CMakePresets_FILE_ARG_DIRECTORY}") + endif() + if(CMakePresets_FILE_ARG_RELATIVE) + cmake_path(RELATIVE_PATH + CMakePresets_FILE_ARG_DIRECTORY + BASE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}" + OUTPUT_VARIABLE CMakePresets_FILE_ARG_RELATIVE_PATH + ) + set(_presets_file "--presets-file=${CMakePresets_FILE_ARG_RELATIVE_PATH}/${CMakePresets_FILE_ARG}") + else() + set(_presets_file "--presets-file=${CMakePresets_FILE_ARG_DIRECTORY}/${CMakePresets_FILE_ARG}") + endif() + foreach(_presets_file_arg IN ITEMS ${CMakePresets_FILE_ARG} ${CMakePresets_FILE_ARG_EXTRA_FILES}) + configure_file( + "${RunCMake_SOURCE_DIR}/${_presets_file_arg}.in" + "${CMakePresets_FILE_ARG_DIRECTORY}/${_presets_file_arg}" + @ONLY + ) + endforeach() + endif() + if(NOT CMakePresets_FILE) set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in") endif() @@ -93,6 +120,7 @@ function(run_cmake_presets name) ${_make_program} ${_unused_cli} ${_preset} + ${_presets_file} ${_log_level} ${ARGN} ) @@ -313,6 +341,7 @@ run_cmake_presets(NoSuchPreset) run_cmake_presets(NoPresetArgument --preset) run_cmake_presets(NoPresetArgumentEq --preset= -DA=B) run_cmake_presets(UseHiddenPreset) +run_cmake_presets(NoPresetFileArgument --preset GoodNoArgs --presets-file) # Test CMakeUserPresets.json unset(CMakePresets_FILE) @@ -326,6 +355,30 @@ run_cmake_presets(UserDuplicateInUser) run_cmake_presets(UserDuplicateCross) run_cmake_presets(UserInheritance) +# Test --presets-file= +# should be preferred over CMakePresets.json and CMakeUserPresets.json +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/OtherCMakePresetsFileCMakePresets.json.in") +set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/OtherCMakePresetsFileCMakeUserPresets.json.in") +# must exist +run_cmake_presets(PresetsFileArgNoExist --presets-file=FileDoesNotExist.json) +set(CMakePresets_FILE_ARG OtherCMakePresetsFile.json) +run_cmake_presets(OtherCMakePresetsFile) +# --list-presets should only list the presets defined in +run_cmake_presets(OtherCMakePresetsFileList --list-presets=all) +# can be specified via relative path on the command line +set(CMakePresets_FILE_ARG_RELATIVE 1) +run_cmake_presets(OtherCMakePresetsFileRelPath --preset OtherCMakePresetsFile) +set(CMakePresets_FILE_ARG "subdir/OtherCMakePresetsFileSubdir.json") +set(CMakePresets_FILE_ARG_EXTRA_FILES "subdir/IncludeRelativeToSubdir.json") +# Files included by should have paths evaluated relative to +run_cmake_presets(OtherCMakePresetsFileSubdir) +run_cmake_presets(OtherCMakePresetsFileSubdir --preset=IncludeRelativeToSubdir) +unset(CMakePresets_FILE) +unset(CMakeUserPresets_FILE) +unset(CMakePresets_FILE_ARG) +unset(CMakePresets_FILE_ARG_RELATIVE) +unset(CMakePresets_FILE_ARG_EXTRA_FILES) + # Test listing presets set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListPresets.json.in") run_cmake_presets(ListPresets --list-presets) diff --git a/Tests/RunCMake/CMakePresets/subdir/IncludeRelativeToSubdir.json.in b/Tests/RunCMake/CMakePresets/subdir/IncludeRelativeToSubdir.json.in new file mode 100644 index 0000000000..56db1add0d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/subdir/IncludeRelativeToSubdir.json.in @@ -0,0 +1,10 @@ +{ + "version": 4, + "configurePresets": [ + { + "name": "IncludeRelativeToSubdir", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/subdir/OtherCMakePresetsFileSubdir.json.in b/Tests/RunCMake/CMakePresets/subdir/OtherCMakePresetsFileSubdir.json.in new file mode 100644 index 0000000000..e8a5f7f2ed --- /dev/null +++ b/Tests/RunCMake/CMakePresets/subdir/OtherCMakePresetsFileSubdir.json.in @@ -0,0 +1,13 @@ +{ + "version": 4, + "include": [ + "IncludeRelativeToSubdir.json" + ], + "configurePresets": [ + { + "name": "OtherCMakePresetsFileSubdir", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.cmake b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.json.in b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.json.in new file mode 100644 index 0000000000..474c669199 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.json.in @@ -0,0 +1,16 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "buildPresets": [ + { + "name": "default-from-other-file", + "configurePreset": "default" + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFileListPresets-build-x-stdout.txt b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFileListPresets-build-x-stdout.txt new file mode 100644 index 0000000000..ee586dfec4 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFileListPresets-build-x-stdout.txt @@ -0,0 +1,3 @@ +^Available build presets: + + "default-from-other-file"$ diff --git a/Tests/RunCMake/CMakePresetsBuild/PresetsFileNoArg-build-result.txt b/Tests/RunCMake/CMakePresetsBuild/PresetsFileNoArg-build-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/PresetsFileNoArg-build-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsBuild/PresetsFileNoArg-build-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/PresetsFileNoArg-build-stderr.txt new file mode 100644 index 0000000000..50d4e2b6e4 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/PresetsFileNoArg-build-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No file specified for --presets-file diff --git a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake index 92378d35e9..50a4e8ecf4 100644 --- a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake @@ -26,6 +26,12 @@ function(run_cmake_build_presets name CMakePresetsBuild_CONFIGURE_PRESETS CMakeP configure_file("${CMakePresetsBuild_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY) endif() + set(_presets_file) + if(CMakePresets_FILE_ARG) + set(_presets_file "--presets-file=${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}") + configure_file("${RunCMake_SOURCE_DIR}/${CMakePresets_FILE_ARG}.in" "${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}" @ONLY) + endif() + if(NOT CMakeUserPresets_FILE) set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in") endif() @@ -50,11 +56,11 @@ function(run_cmake_build_presets name CMakePresetsBuild_CONFIGURE_PRESETS CMakeP if(eq) run_cmake_command(${name}-build-${BUILD_PRESET} - ${CMAKE_COMMAND} "--build" ${CMakePresetsBuild_BUILD_DIR_OVERRIDE} "--preset=${BUILD_PRESET}" ${ARGN}) + ${CMAKE_COMMAND} "--build" ${CMakePresetsBuild_BUILD_DIR_OVERRIDE} "--preset=${BUILD_PRESET}" ${_presets_file} ${ARGN}) set(eq 0) else() run_cmake_command(${name}-build-${BUILD_PRESET} - ${CMAKE_COMMAND} "--build" ${CMakePresetsBuild_BUILD_DIR_OVERRIDE} "--preset" "${BUILD_PRESET}" ${ARGN}) + ${CMAKE_COMMAND} "--build" ${CMakePresetsBuild_BUILD_DIR_OVERRIDE} "--preset" "${BUILD_PRESET}" ${_presets_file} ${ARGN}) set(eq 1) endif() endforeach() @@ -74,9 +80,17 @@ run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvi run_cmake_build_presets(InvalidConfigurePreset "default" "badConfigurePreset" "") run_cmake_build_presets(Condition "default" "enabled;disabled" "") +set(CMakePresets_FILE_ARG "OtherCMakePresetsFile.json") +run_cmake_build_presets(OtherCMakePresetsFile "default" "default-from-other-file" "") +set(CMakePresetsBuild_BUILD_ONLY 1) +run_cmake_build_presets(OtherCMakePresetsFileListPresets "" "x" "--list-presets" "") +unset(CMakePresetsBuild_BUILD_ONLY) +unset(CMakePresets_FILE_ARG) + set(CMakePresetsBuild_BUILD_ONLY 1) run_cmake_command(PresetsNoArg-build ${CMAKE_COMMAND} "--build" "--preset") run_cmake_command(PresetsNoArgEq-build ${CMAKE_COMMAND} "--build" "--preset=") +run_cmake_Command(PresetsFileNoArg-build ${CMAKE_COMMAND} "--build" "--presets-file") run_cmake_build_presets(ListPresets "x" "x" "--list-presets" "") run_cmake_build_presets(NoConfigurePreset "x" "noConfigurePreset" "") run_cmake_build_presets(Invalid "x" "hidden;vendorMacro" "") diff --git a/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFile.cmake b/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFile.cmake new file mode 100644 index 0000000000..a9068c7d22 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFile.cmake @@ -0,0 +1,4 @@ +set(CPACK_PACKAGE_NAME OtherCMakePresetsFile) +set(CPACK_GENERATOR "TGZ;TXZ") + +include(CPack) diff --git a/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFile.json.in b/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFile.json.in new file mode 100644 index 0000000000..a015307ea0 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFile.json.in @@ -0,0 +1,22 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "buildPresets": [ + { + "name": "default", + "configurePreset": "default" + } + ], + "packagePresets": [ + { + "name": "default-from-other-file", + "configurePreset": "default" + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFileListPresets-package-x-stdout.txt b/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFileListPresets-package-x-stdout.txt new file mode 100644 index 0000000000..7e03528612 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/OtherCMakePresetsFileListPresets-package-x-stdout.txt @@ -0,0 +1,3 @@ +^Available package presets: + + "default-from-other-file"$ diff --git a/Tests/RunCMake/CMakePresetsPackage/PresetsFileNoArg-package-result.txt b/Tests/RunCMake/CMakePresetsPackage/PresetsFileNoArg-package-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/PresetsFileNoArg-package-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsPackage/PresetsFileNoArg-package-stderr.txt b/Tests/RunCMake/CMakePresetsPackage/PresetsFileNoArg-package-stderr.txt new file mode 100644 index 0000000000..c532031ebd --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/PresetsFileNoArg-package-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No file specified for --presets-file$ diff --git a/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake index 969fda261e..b8c1eb3c13 100644 --- a/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake @@ -33,6 +33,12 @@ function(run_cmake_package_presets name CMakePresetsPackage_CONFIGURE_PRESETS CM configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY) endif() + set(_presets_file) + if(CMakePresets_FILE_ARG) + set(_presets_file "--presets-file=${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}") + configure_file("${RunCMake_SOURCE_DIR}/${CMakePresets_FILE_ARG}.in" "${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}" @ONLY) + endif() + foreach(ASSET ${CMakePresetsPackage_ASSETS}) configure_file("${RunCMake_SOURCE_DIR}/${ASSET}" "${RunCMake_TEST_SOURCE_DIR}" COPYONLY) endforeach() @@ -63,11 +69,11 @@ function(run_cmake_package_presets name CMakePresetsPackage_CONFIGURE_PRESETS CM if(eq) run_cmake_command(${name}-package-${PACKAGE_PRESET} - ${CMAKE_CPACK_COMMAND} "--preset=${PACKAGE_PRESET}" ${ARGN}) + ${CMAKE_CPACK_COMMAND} "--preset=${PACKAGE_PRESET}" ${_presets_file} ${ARGN}) set(eq 0) else() run_cmake_command(${name}-package-${PACKAGE_PRESET} - ${CMAKE_CPACK_COMMAND} "--preset" "${PACKAGE_PRESET}" ${ARGN}) + ${CMAKE_CPACK_COMMAND} "--preset" "${PACKAGE_PRESET}" ${_presets_file} ${ARGN}) set(eq 1) endif() endforeach() @@ -101,5 +107,11 @@ run_cmake_package_presets(UnsupportedVersion "x" "" "") run_cmake_package_presets(Good "default" "build-default-debug" "no-environment;with-environment;generators;configurations;variables;config-file;debug;verbose;package-name;package-version;package-directory;vendor-name") run_cmake_package_presets(ListPresets "default" "" "x" "--list-presets") +set(CMakePresets_FILE_ARG "OtherCMakePresetsFile.json") +run_cmake_package_presets(OtherCMakePresetsFile "default" "default" "default-from-other-file" "") +run_cmake_package_presets(OtherCMakePresetsFileListPresets "" "" "x" "--list-presets") +unset(CMakePresets_FILE_ARG) + run_cmake_command(PresetsNoArg-package ${CMAKE_CPACK_COMMAND} "--preset") run_cmake_command(PresetsNoArgEq-package ${CMAKE_CPACK_COMMAND} "--preset=") +run_cmake_command(PresetsFileNoArg-package ${CMAKE_CPACK_COMMAND} "--presets-file") diff --git a/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFile.cmake b/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFile.cmake new file mode 100644 index 0000000000..3b3b9f9c91 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFile.cmake @@ -0,0 +1,5 @@ +enable_testing() +add_test(testa ${CMAKE_COMMAND} -E echo testa) +add_test(testb ${CMAKE_COMMAND} -E echo testb) +add_test(testc ${CMAKE_COMMAND} -E echo testc) +add_test(testd ${CMAKE_COMMAND} -E echo testd) diff --git a/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFile.json.in b/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFile.json.in new file mode 100644 index 0000000000..7fb2df5e9c --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFile.json.in @@ -0,0 +1,16 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "testPresets": [ + { + "name": "default-from-other-file", + "configurePreset": "default" + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFileListPresets-text-x-stdout.txt b/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFileListPresets-text-x-stdout.txt new file mode 100644 index 0000000000..76234885d4 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/OtherCMakePresetsFileListPresets-text-x-stdout.txt @@ -0,0 +1,3 @@ +^Available test presets: + + "default-from-other-file"$ diff --git a/Tests/RunCMake/CMakePresetsTest/PresetsFileNoArg-test-result.txt b/Tests/RunCMake/CMakePresetsTest/PresetsFileNoArg-test-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/PresetsFileNoArg-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsTest/PresetsFileNoArg-test-stderr.txt b/Tests/RunCMake/CMakePresetsTest/PresetsFileNoArg-test-stderr.txt new file mode 100644 index 0000000000..5235262b13 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/PresetsFileNoArg-test-stderr.txt @@ -0,0 +1 @@ +^CMake Error: '--presets-file' requires an argument$ diff --git a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake index 42dfe182b6..2b320f58bb 100644 --- a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake @@ -37,6 +37,12 @@ function(run_cmake_test_presets name CMakePresetsTest_CONFIGURE_PRESETS CMakePre configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY) endif() + set(_presets_file) + if(CMakePresets_FILE_ARG) + set(_presets_file "--presets-file=${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}") + configure_file("${RunCMake_SOURCE_DIR}/${CMakePresets_FILE_ARG}.in" "${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}" @ONLY) + endif() + foreach(ASSET ${CMakePresetsTest_ASSETS}) configure_file("${RunCMake_SOURCE_DIR}/${ASSET}" "${RunCMake_TEST_SOURCE_DIR}" COPYONLY) endforeach() @@ -65,11 +71,11 @@ function(run_cmake_test_presets name CMakePresetsTest_CONFIGURE_PRESETS CMakePre if(eq) run_cmake_command(${name}-test-${TEST_PRESET} - ${CMAKE_CTEST_COMMAND} "--preset=${TEST_PRESET}" ${ARGN}) + ${CMAKE_CTEST_COMMAND} "--preset=${TEST_PRESET}" ${_presets_file} ${ARGN}) set(eq 0) else() run_cmake_command(${name}-test-${TEST_PRESET} - ${CMAKE_CTEST_COMMAND} "--preset" "${TEST_PRESET}" ${ARGN}) + ${CMAKE_CTEST_COMMAND} "--preset" "${TEST_PRESET}" ${_presets_file} ${ARGN}) set(eq 1) endif() endforeach() @@ -97,6 +103,7 @@ run_cmake_test_presets(ListPresets "" "" "x" "--list-presets") run_cmake_command(PresetsNoArg-test ${CMAKE_CTEST_COMMAND} "--preset") run_cmake_command(PresetsNoArgEq-test ${CMAKE_CTEST_COMMAND} "--preset=") +run_cmake_command(PresetsFileNoArg-test ${CMAKE_CTEST_COMMAND} "--presets-file") set(CMakePresetsTest_FILE "${RunCMake_SOURCE_DIR}/Condition.json.in") run_cmake_test_presets(ConditionListPresets "" "" "x" "--list-presets") @@ -123,6 +130,7 @@ set(CMakePresetsTest_NO_CONFIGURE 0) run_cmake_test_presets(Passthrough "default" "" "basic;inherit;execOnly") run_cmake_test_presets(PassthroughCombined "default" "" "combined" "--" "--cli-arg") -set(CMakePresetsTest_NO_CONFIGURE 1) -set(CMakePresetsTest_NO_BUILD 0) +set(CMakePresets_FILE_ARG OtherCMakePresetsFile.json) +run_cmake_test_presets(OtherCMakePresetsFile "default" "" "default-from-other-file") +run_cmake_test_presets(OtherCMakePresetsFileListPresets "" "" "x" "--list-presets") diff --git a/Tests/RunCMake/CMakePresetsWorkflow/InvalidOption-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/InvalidOption-stderr.txt index 8e23c9b6ed..71a61f579f 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/InvalidOption-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/InvalidOption-stderr.txt @@ -1,6 +1,7 @@ ^Unknown argument -DINVALID_OPTION Usage: cmake --workflow Options: - --preset = Workflow preset to execute\. - --list-presets = List available workflow presets\. - --fresh = Configure a fresh build tree, removing any existing cache file\.$ + --preset = Workflow preset to execute\. + --presets-file = Path to a presets file\. + --list-presets = List available workflow presets\. + --fresh = Configure a fresh build tree, removing any existing cache file\.$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFile.cmake b/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFile.cmake new file mode 100644 index 0000000000..31ce7ffb26 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFile.cmake @@ -0,0 +1,8 @@ +message(STATUS "Testing the configure step at ${CMAKE_BINARY_DIR}") + +add_custom_target(echo_test ALL COMMAND ${CMAKE_COMMAND} -E echo "Testing the build step at ${CMAKE_BINARY_DIR}") + +enable_testing() +add_test(NAME EchoTest COMMAND ${CMAKE_COMMAND} -E echo "Testing the test step at ${CMAKE_BINARY_DIR}") + +include(CPack) diff --git a/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFile.json.in b/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFile.json.in new file mode 100644 index 0000000000..4b3f7c30eb --- /dev/null +++ b/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFile.json.in @@ -0,0 +1,57 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "binaryDir": "${sourceDir}/build", + "generator": "@RunCMake_GENERATOR@" + } + ], + "buildPresets": [ + { + "name": "default", + "configurePreset": "default", + "configuration": "Debug" + } + ], + "testPresets": [ + { + "name": "default", + "configurePreset": "default", + "configuration": "Debug" + } + ], + "packagePresets": [ + { + "name": "default", + "configurePreset": "default", + "generators": [ + "External" + ], + "configurations": ["Debug"] + } + ], + "workflowPresets": [ + { + "name": "OtherCMakePresetsFile", + "steps": [ + { + "type": "configure", + "name": "default" + }, + { + "type": "build", + "name": "default" + }, + { + "type": "test", + "name": "default" + }, + { + "type": "package", + "name": "default" + } + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFileListPresets-stdout.txt b/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFileListPresets-stdout.txt new file mode 100644 index 0000000000..194fbfd6a6 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsWorkflow/OtherCMakePresetsFileListPresets-stdout.txt @@ -0,0 +1,3 @@ +^Available workflow presets: + + "OtherCMakePresetsFile"$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/PresetsFileNoArg-workflow-result.txt b/Tests/RunCMake/CMakePresetsWorkflow/PresetsFileNoArg-workflow-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresetsWorkflow/PresetsFileNoArg-workflow-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsWorkflow/PresetsFileNoArg-workflow-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/PresetsFileNoArg-workflow-stderr.txt new file mode 100644 index 0000000000..50d4e2b6e4 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsWorkflow/PresetsFileNoArg-workflow-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No file specified for --presets-file diff --git a/Tests/RunCMake/CMakePresetsWorkflow/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsWorkflow/RunCMakeTest.cmake index fac8dfc158..e121b1c459 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsWorkflow/RunCMakeTest.cmake @@ -35,6 +35,12 @@ function(run_cmake_workflow_presets name) configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY) endif() + set(_presets_file) + if(CMakePresets_FILE_ARG) + set(_presets_file "--presets-file=${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}") + configure_file("${RunCMake_SOURCE_DIR}/${CMakePresets_FILE_ARG}.in" "${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}" @ONLY) + endif() + foreach(ASSET ${CMakePresets_ASSETS}) configure_file("${RunCMake_SOURCE_DIR}/${ASSET}.in" "${RunCMake_TEST_SOURCE_DIR}/${ASSET}" @ONLY) endforeach() @@ -54,7 +60,7 @@ function(run_cmake_workflow_presets name) set(eq 1 PARENT_SCOPE) set(preset_arg "--preset" "${name}") endif() - run_cmake_command("${name}" "${CMAKE_COMMAND}" "--workflow" ${preset_arg} ${ARGN}) + run_cmake_command("${name}" "${CMAKE_COMMAND}" "--workflow" ${preset_arg} ${_presets_file} ${ARGN}) endfunction() set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) @@ -80,9 +86,15 @@ unset(CMakePresets_FILE) unset(CMakeUserPresets_FILE) unset(CMakePresets_ASSETS) +set(CMakePresets_FILE_ARG "OtherCMakePresetsFile.json") +run_cmake_workflow_presets(OtherCMakePresetsFile) +run_cmake_workflow_presets(OtherCMakePresetsFileListPreset --list-presets) +unset(CMakePresets_FILE_ARG) + run_cmake_workflow_presets(ListPresets --list-presets) run_cmake_command(PresetsNoArg-workflow ${CMAKE_COMMAND} "--workflow" "--preset") run_cmake_command(PresetsNoArgEq-workflow ${CMAKE_COMMAND} "--workflow" "--preset=") +run_cmake_command(PresetsFileNoArg-workflow ${CMAKE_COMMAND} "--workflow" "--presets-file") run_cmake_workflow_presets(InvalidOption -DINVALID_OPTION) set(RunCMake_TEST_NO_CLEAN TRUE) diff --git a/Utilities/Scripts/regenerate-presets.py b/Utilities/Scripts/regenerate-presets.py index 37f801a789..665b712dba 100755 --- a/Utilities/Scripts/regenerate-presets.py +++ b/Utilities/Scripts/regenerate-presets.py @@ -31,11 +31,12 @@ SCHEMA_YAML_FILENAME = 'schema.yaml' SCHEMA_JSON_FILENAME = 'schema.json' WORKSPACE = Path(__file__).parent.parent.parent.absolute() +SCRIPT_REL = Path(__file__).relative_to(WORKSPACE) PRESETS = WORKSPACE / PRESETS_REL DIAGNOSTICS = WORKSPACE / 'Source/cmDiagnostics.h' RST_BANNER = f"""\ -.. This file was generated by {Path(__file__).relative_to(WORKSPACE)} +.. This file was generated by {SCRIPT_REL.as_posix()} from {PRESETS_REL}/{SCHEMA_YAML_FILENAME}. Do not edit. """ diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index ca0b7a1377..39b2d24aac 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -729,11 +729,12 @@ class CMakeDomain(Domain): 'preset': CMakeXRefRole(lowercase=True, warn_dangling=True), # Roles for program-specific command-line options without the program # name (which add the name to form the ref). - 'cmake-option': CMakeOptionXRefRole('cmake'), - 'cmake-build-option': CMakeOptionXRefRole('cmake--build'), - 'cmake-install-option': CMakeOptionXRefRole('cmake--install'), - 'cpack-option': CMakeOptionXRefRole('cpack'), - 'ctest-option': CMakeOptionXRefRole('ctest'), + 'cmake-option': CMakeOptionXRefRole('cmake'), + 'cmake-build-option': CMakeOptionXRefRole('cmake--build'), + 'cmake-install-option': CMakeOptionXRefRole('cmake--install'), + 'cmake-workflow-option': CMakeOptionXRefRole('cmake--workflow'), + 'cpack-option': CMakeOptionXRefRole('cpack'), + 'ctest-option': CMakeOptionXRefRole('ctest'), } initial_data = { 'objects': {}, # fullname -> ObjectEntry