Merge topic 'cmake-diagnostics-doc' 95f7f84609 Help: Fix CMD_INSTALL_ABSOLUTE_DESTINATION documentation a882ec84ec cmDocumentation: Add diagnostics 97d13c3053 Help: Improve diagnostics documentation 3cccce8ca2 Help: Add developer documentation for new diagnostics ffe4c2a8ff Help: Fix developer documentation Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Robert Maynard <robertjmaynard@gmail.com> Merge-request: !11996
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst index ad43cd2..47dfe23 100644 --- a/Help/command/ctest_test.rst +++ b/Help/command/ctest_test.rst
@@ -183,6 +183,13 @@ file is **not** uploaded to CDash because it would be redundant with CTest's ``Test.xml`` file. +``COVERAGE_TOOL <tool>`` + .. versionadded:: 4.4 + + Specify the ``<tool>`` used for collecting coverage during the running + of the tests. See the CTest :ref:`CoverageTool <ctest-CoverageTool>` + setting for details. + ``QUIET`` .. versionadded:: 3.3
diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst index f335e1f..809cf73 100644 --- a/Help/guide/ide-integration/index.rst +++ b/Help/guide/ide-integration/index.rst
@@ -40,7 +40,7 @@ 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 @@ of the platform to be exceeded, the IDE should instead construct a temporary cache script and pass it with the :option:`-C <cmake -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 ec93090..7da09ed 100644 --- a/Help/guide/tutorial/Configuration and Cache Variables.rst +++ b/Help/guide/tutorial/Configuration and Cache Variables.rst
@@ -506,6 +506,12 @@ 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 @@ 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 f11b23d..12d6b84 100644 --- a/Help/guide/user-interaction/index.rst +++ b/Help/guide/user-interaction/index.rst
@@ -425,7 +425,7 @@ 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 4c67213..d5f7c98 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 @@ 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 @@ 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 @@ .. 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 @@ 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 @@ .. 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 @@ ``${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 @@ .. 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 @@ 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 @@ * 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 @@ * 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 @@ * Changes to `Macro Expansion`_ * The `${fileDir} <CMakePresets 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 @@ ====== :download:`This file </manual/presets/schema.json>` 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-variables.7.rst b/Help/manual/cmake-variables.7.rst index a2ddcef..71318dd 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst
@@ -806,6 +806,7 @@ /variable/CTEST_SVN_UPDATE_OPTIONS /variable/CTEST_TEST_LOAD /variable/CTEST_TEST_TIMEOUT + /variable/CTEST_TEST_COVERAGE_TOOL /variable/CTEST_TLS_VERIFY /variable/CTEST_TLS_VERSION /variable/CTEST_UPDATE_COMMAND
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index eef6f6d..7b7680f 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst
@@ -686,12 +686,15 @@ .. option:: --preset <preset>, --preset=<preset> - Reads a :manual:`preset <cmake-presets(7)>` 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 <cmake-presets(7)>` 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 <cmake-gui(1)>` 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 @@ 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 <file>, --presets-file=<file> + + .. versionadded:: 4.4 + + Reads :manual:`presets <cmake-presets(7)>` from the given ``<file>``. 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[=<type>] Lists the available presets of the specified ``<type>``. Valid values for ``<type>`` are ``configure``, ``build``, ``test``, ``package``, or ``all``. - If ``<type>`` 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 ``<type>`` is omitted, ``configure`` is assumed. + + .. versionchanged:: 4.4 + If :cmake-option:`--presets-file` is specified, the presets defined in the + given ``<file>`` 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 @@ .. option:: --preset <preset>, --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 <cmake-presets(7)>` for more details. + Use a build :manual:`preset <cmake-presets(7)>` 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 @@ .. versionchanged:: 4.4 ``cmake --build <dir> --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 <file>, --presets-file=<file> + + .. versionadded:: 4.4 + + Reads :manual:`presets <cmake-presets(7)>` from the given ``<file>``. 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 @@ .. versionchanged:: 4.4 ``cmake --build <dir> --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 ``<file>`` will be listed; otherwise, the presets file(s) are + inferred from the current build directory's ``CMakeCache.txt``. .. option:: -j [<jobs>], --parallel [<jobs>] @@ -1909,10 +1952,8 @@ .. option:: --preset <preset>, --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 <cmake-presets(7)>` for more details. + Use a workflow :manual:`preset <cmake-presets(7)>` 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 @@ $ 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 <file>, --presets-file=<file> + + .. versionadded:: 4.4 + + Reads :manual:`presets <cmake-presets(7)>` from the given ``<file>``. 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 ``<file>`` 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 b6ac331..686d153 100644 --- a/Help/manual/cpack.1.rst +++ b/Help/manual/cpack.1.rst
@@ -120,13 +120,37 @@ Override/define :variable:`CPACK_PACKAGE_VENDOR`. -.. option:: --preset <presetName> +.. option:: --preset <preset>, --preset=<preset> - Use a preset from :manual:`cmake-presets(7)`. + Use a package :manual:`preset <cmake-presets(7)>` 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 <file>, --presets-file=<file> + + .. versionadded:: 4.4 + + Reads :manual:`presets <cmake-presets(7)>` from the given ``<file>``. 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 ``<file>`` 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 dba20c1..4ab9d75 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst
@@ -69,20 +69,41 @@ .. option:: --preset <preset>, --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 <cmake-presets(7)>` for more details. + Use a test :manual:`preset <cmake-presets(7)>` 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 <file>, --presets-file=<file> + + .. versionadded:: 4.4 + + Reads :manual:`presets <cmake-presets(7)>` from the given ``<file>``. 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 ``<file>`` 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 <cfg>, --build-config <cfg> @@ -1362,8 +1383,41 @@ * `CTest Script`_ variable: :variable:`CTEST_TEST_TIMEOUT` * :module:`CTest` module variable: ``DART_TESTING_TIMEOUT`` +.. _`ctest-CoverageTool`: + +``CoverageTool`` + .. versionadded:: 4.4 + + Specify the tool used for collecting coverage during the running + of the tests. The tool may be one of: + + ``LLVM-COV`` + This value indicates the usage of Clang's source-based code coverage + which "operates on AST and preprocessor information directly". + For more information, see the `Clang Source-based Code Coverage`_ + documentation. + + CTest will run each test with the ``LLVM_PROFILE_FILE`` environment + variable set to ``<directory>/<test-name>_<process-id>.profraw``, + where ``<directory>`` is the absolute path to the directory where + the ``CTestTestfile.cmake`` that describes the test is located. + This configures Clang Source-based Code Coverage to uniquely identify + the coverage information gathered by each test without any collisions. + + Any existing ``<directory>/<test-name>_*.profraw`` files for a test + are removed before running the test. Any existing ``LLVM_PROFILE_FILE`` + environment variable is ignored. + + If no value is specified, no work is done and nothing is added to the + environment. + + * `CTest Script`_ variable: :variable:`CTEST_TEST_COVERAGE_TOOL` + * :module:`CTest` module variable: :variable:`CTEST_TEST_COVERAGE_TOOL` + To report extra test values to CDash, see :ref:`Additional Test Measurements`. +.. _`Clang Source-based Code Coverage`: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html + .. _`CTest Coverage Step`: CTest Coverage Step
diff --git a/Help/manual/presets/buildPresets-properties.rst b/Help/manual/presets/buildPresets-properties.rst index 842ee40..1256280 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 ebe80fc..8e3d4a0 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 2c21b53..863500f 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 fe56d73..c66bab0 100644 --- a/Help/manual/presets/schema.yaml +++ b/Help/manual/presets/schema.yaml
@@ -963,9 +963,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. inherits: *preset-inherits condition: *condition vendor: *preset-vendor @@ -1033,7 +1034,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. minimum: 0 targets: anyOf: @@ -1181,9 +1182,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. inherits: *preset-inherits condition: *condition vendor: *preset-vendor @@ -1629,7 +1631,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. minimum: 0 resourceSpecFile: type: string @@ -1819,9 +1821,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. 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 293d88f..6e71ab4 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 20e43c5..ece6941 100644 --- a/Help/release/3.23.rst +++ b/Help/release/3.23.rst
@@ -19,7 +19,7 @@ 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/ctest-llvm-cov.rst b/Help/release/dev/ctest-llvm-cov.rst new file mode 100644 index 0000000..f6ca701 --- /dev/null +++ b/Help/release/dev/ctest-llvm-cov.rst
@@ -0,0 +1,6 @@ +ctest-llvm-cov +-------------- + +* :manual:`ctest(1)` gained a :ref:`CoverageTool <ctest-CoverageTool>` + option in :ref:`Dashboard Client` mode to configure tests for + coverage collection by ``llvm-cov``.
diff --git a/Help/release/dev/presets-file-arg.rst b/Help/release/dev/presets-file-arg.rst new file mode 100644 index 0000000..7cfc969 --- /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 <cmake-presets(7)>` from the specified file instead of + ``CMakePresets.json`` and/or ``CMakeUserPresets.json``. See + :option:`cmake --presets-file`, + :option:`cmake --build --presets-file <cmake--build --presets-file>`, + :option:`cmake --workflow --presets-file <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 45f41d2..6ee8603 100644 --- a/Help/release/dev/presets-fileDir.rst +++ b/Help/release/dev/presets-fileDir.rst
@@ -3,5 +3,5 @@ * :manual:`cmake-presets(7)` files now support schema version 12. The :ref:`${fileDir} <CMakePresets 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/Help/variable/CTEST_TEST_COVERAGE_TOOL.rst b/Help/variable/CTEST_TEST_COVERAGE_TOOL.rst new file mode 100644 index 0000000..bc94825 --- /dev/null +++ b/Help/variable/CTEST_TEST_COVERAGE_TOOL.rst
@@ -0,0 +1,7 @@ +CTEST_TEST_COVERAGE_TOOL +------------------------ + +.. versionadded:: 4.4 + +Specify the CTest :ref:`CoverageTool <ctest-CoverageTool>` setting +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in index 67d9f8f..409a5c6 100644 --- a/Modules/DartConfiguration.tcl.in +++ b/Modules/DartConfiguration.tcl.in
@@ -107,3 +107,6 @@ # specify behavior for retrying the submission CTestSubmitRetryDelay: @CTEST_SUBMIT_RETRY_DELAY@ CTestSubmitRetryCount: @CTEST_SUBMIT_RETRY_COUNT@ + +# Invoke each test with environment variables configuring tool's collection. +CTestTestCoverageTool: @CTEST_TEST_COVERAGE_TOOL@
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake index 901ea22..861540b 100644 --- a/Modules/FindArmadillo.cmake +++ b/Modules/FindArmadillo.cmake
@@ -133,7 +133,7 @@ set(Armadillo_VERSION_NAME "EARLY RELEASE") if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp") - # Read and parse armdillo version header file for version number + # Read and parse Armadillo version header file for version number. file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _ARMA_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ") string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_ARMA_HEADER_CONTENTS}") string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_ARMA_HEADER_CONTENTS}") @@ -176,8 +176,6 @@ ) mark_as_advanced(ARMADILLO_LIBRARY) set(_ARMA_REQUIRED_VARS ARMADILLO_LIBRARY) -else() - set(ARMADILLO_LIBRARY "") endif() # Transitive linking with the wrapper does not work with MSVC,
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 8a6e1fb..73e30d2 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake
@@ -1539,10 +1539,13 @@ _CUDAToolkit_find_and_add_import_lib( sanitizer ONLY_SEARCH_FOR sanitizer-public - LIBRARY_SEARCH_DIRS - "${CUDAToolkit_LIBRARY_ROOT}/compute-sanitizer" - "${CUDAToolkit_LIBRARY_ROOT}/Sanitizer" - "${CUDAToolkit_LIBRARY_ROOT}/extras/Sanitizer" + EXTRA_PATH_SUFFIXES + "../compute-sanitizer" + "../../../compute-sanitizer" + "../Sanitizer" + "../../../Sanitizer" + "../extras/Sanitizer" + "../../../extras/Sanitizer" EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}" ) if(TARGET CUDA::sanitizer)
diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index 260b663..b8fa1fa 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake
@@ -94,12 +94,13 @@ execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE count) + OUTPUT_VARIABLE count + RESULT_VARIABLE _count_ok) #message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'") endif() endif() - if(NOT count) + if(NOT (_count_ok EQUAL 0 AND count GREATER 0)) # Linux (systems with nproc): # Prefer nproc to getconf if available as getconf may return the host CPU count in Linux containers find_program(ProcessorCount_cmd_nproc nproc) @@ -108,12 +109,13 @@ execute_process(COMMAND ${ProcessorCount_cmd_nproc} ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE count) + OUTPUT_VARIABLE count + RESULT_VARIABLE _count_ok) #message("ProcessorCount: trying nproc '${ProcessorCount_cmd_nproc}'") endif() endif() - if(NOT count) + if(NOT (_count_ok EQUAL 0 AND count GREATER 0)) # Linux (systems with getconf): find_program(ProcessorCount_cmd_getconf getconf) mark_as_advanced(ProcessorCount_cmd_getconf) @@ -121,12 +123,13 @@ execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE count) + OUTPUT_VARIABLE count + RESULT_VARIABLE _count_ok) #message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'") endif() endif() - if(NOT count) + if(NOT (_count_ok EQUAL 0 AND count GREATER 0)) # HPUX (systems with machinfo): find_program(ProcessorCount_cmd_machinfo machinfo PATHS /usr/contrib/bin) @@ -150,15 +153,18 @@ execute_process(COMMAND ${ProcessorCount_cmd_mpsched} -s OUTPUT_QUIET ERROR_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE mpsched_output) - string(REGEX MATCHALL "Processor Count *: *([0-9]+)" procs "${mpsched_output}") - set(count "${CMAKE_MATCH_1}") + ERROR_VARIABLE mpsched_output + RESULT_VARIABLE _mpsched_ok) + if(_mpsched_ok EQUAL 0) + string(REGEX MATCHALL "Processor Count *: *([0-9]+)" procs "${mpsched_output}") + set(count "${CMAKE_MATCH_1}") + endif() #message("ProcessorCount: trying mpsched -s '${ProcessorCount_cmd_mpsched}'") endif() endif() endif() - if(NOT count) + if(NOT count GREATER 0) # AIX (systems with lsconf): find_program(ProcessorCount_cmd_lsconf lsconf PATHS /usr/sbin) @@ -167,14 +173,17 @@ execute_process(COMMAND ${ProcessorCount_cmd_lsconf} ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE lsconf_output) - string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}") - set(count "${CMAKE_MATCH_1}") + OUTPUT_VARIABLE lsconf_output + RESULT_VARIABLE _lsconf_ok) + if(_lsconf_ok EQUAL 0) + string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}") + set(count "${CMAKE_MATCH_1}") + endif() #message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'") endif() endif() - if(NOT count) + if(NOT count GREATER 0) # QNX (systems with pidin): find_program(ProcessorCount_cmd_pidin pidin) mark_as_advanced(ProcessorCount_cmd_pidin) @@ -182,14 +191,17 @@ execute_process(COMMAND ${ProcessorCount_cmd_pidin} info ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE pidin_output) - string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}") - list(LENGTH procs count) + OUTPUT_VARIABLE pidin_output + RESULT_VARIABLE _pidin_ok) + if(_pidin_ok EQUAL 0) + string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}") + list(LENGTH procs count) + endif() #message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'") endif() endif() - if(NOT count) + if(NOT count GREATER 0) # Sun (systems where psrinfo tool is available) find_program(ProcessorCount_cmd_psrinfo psrinfo PATHS /usr/sbin /sbin) mark_as_advanced(ProcessorCount_cmd_psrinfo) @@ -197,13 +209,16 @@ execute_process(COMMAND ${ProcessorCount_cmd_psrinfo} -p -v ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE psrinfo_output) - string(REGEX MATCHALL "has [0-9]+ virtual processor" procs "${psrinfo_output}") - set(count "") - foreach(proc ${procs}) - string(REGEX MATCH "has ([0-9]+) virtual" res ${proc}) - math(EXPR count "${count} + ${CMAKE_MATCH_1}") - endforeach() + OUTPUT_VARIABLE psrinfo_output + RESULT_VARIABLE _psrinfo_ok) + if(_psrinfo_ok EQUAL 0) + string(REGEX MATCHALL "has [0-9]+ virtual processor" procs "${psrinfo_output}") + set(count "") + foreach(proc IN LISTS procs) + string(REGEX MATCH "has ([0-9]+) virtual" res ${proc}) + math(EXPR count "${count} + ${CMAKE_MATCH_1}") + endforeach() + endif() #message("ProcessorCount: trying '${ProcessorCount_cmd_psrinfo}' -p -v") else() # Sun (systems where uname -X emits "NumCPU" in its output): @@ -213,9 +228,12 @@ execute_process(COMMAND ${ProcessorCount_cmd_uname} -X ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE uname_X_output) - string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}") - set(count "${CMAKE_MATCH_1}") + OUTPUT_VARIABLE uname_X_output + RESULT_VARIABLE _uname_X_ok) + if(_uname_X_ok EQUAL 0) + string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}") + set(count "${CMAKE_MATCH_1}") + endif() #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'") endif() endif() @@ -224,7 +242,7 @@ # Execute this code when all previously attempted methods return empty # output: # - if(NOT count) + if(NOT count GREATER 0) # Systems with /proc/cpuinfo: set(cpuinfo_file /proc/cpuinfo) if(EXISTS "${cpuinfo_file}") @@ -237,7 +255,7 @@ endif() endif() - if(NOT count) + if(NOT count GREATER 0) # Haiku find_program(ProcessorCount_cmd_sysinfo sysinfo) mark_as_advanced(ProcessorCount_cmd_sysinfo) @@ -245,9 +263,12 @@ execute_process(COMMAND ${ProcessorCount_cmd_sysinfo} ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE sysinfo_X_output) - string(REGEX MATCHALL "\nCPU #[0-9]+:" procs "\n${sysinfo_X_output}") - list(LENGTH procs count) + OUTPUT_VARIABLE sysinfo_X_output + RESULT_VARIABLE _sysinfo_ok) + if(_sysinfo_ok EQUAL 0) + string(REGEX MATCHALL "\nCPU #[0-9]+:" procs "\n${sysinfo_X_output}") + list(LENGTH procs count) + endif() #message("ProcessorCount: trying sysinfo '${ProcessorCount_cmd_sysinfo}'") endif() endif() @@ -255,7 +276,7 @@ # Since cygwin builds of CMake do not define WIN32 anymore, but they still # run on Windows, and will still have this env var defined: # - if(NOT count) + if(NOT count GREATER 0) set(count "$ENV{NUMBER_OF_PROCESSORS}") #message("ProcessorCount: last fallback, trying environment variable") endif()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e7a0aef..a5910ef 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt
@@ -125,6 +125,7 @@ cmCLocaleEnvironmentScope.cxx cmCMakePath.h cmCMakePath.cxx + cmCMakePresetsArgs.h cmCMakePresetsErrors.cxx cmCMakePresetsErrors.h cmCMakePresetsGraph.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index df39ab1..698d700 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 4) set(CMake_VERSION_MINOR 3) -set(CMake_VERSION_PATCH 20260430) +set(CMake_VERSION_PATCH 20260504) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index a7ed74b..c595378 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 cmDocumentationUsage = { {}, " cpack [options]" }; -cmDocumentationEntry const cmDocumentationOptions[14] = { +cmDocumentationEntry const cmDocumentationOptions[] = { { "-G <generators>", "Override/define CPACK_GENERATOR" }, { "-C <Configurations>", "Specify the project configuration(s)" }, { "-D <var>=<value>", "Set a CPack variable." }, @@ -60,6 +61,7 @@ { "-B <packageDirectory>", "Override/define CPACK_PACKAGE_DIRECTORY" }, { "--vendor <vendorName>", "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 @@ std::string cpackProjectVendor; std::string cpackConfigFile; - std::string preset; - bool listPresets = false; + cmCMakePresetsArgs presetsArgs; std::map<std::string, std::string> definitions; @@ -162,6 +163,12 @@ return true; }; + auto const presetFileLambda = [&presetsArgs](std::string const& value, + cmake*, cmMakefile*) -> bool { + presetsArgs.PresetsFile = cmSystemTools::ToNormalizedPathOnDisk(value); + return true; + }; + using CommandArgument = cmCommandLineArgument<bool(std::string const&, cmake*, cmMakefile*)>; @@ -201,9 +208,11 @@ 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 @@ 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 @@ }; 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 @@ 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 7bbf5a3..6546088 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -81,7 +81,7 @@ 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 bede3b1..3e9e1dc 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -64,7 +64,7 @@ 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/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index c5e7ce1..eaf5831 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx
@@ -14,7 +14,10 @@ #include <cm/memory> #include <cm/optional> +#include <cm/string_view> +#include <cmext/string_view> +#include "cmsys/Glob.hxx" #include "cmsys/RegularExpression.hxx" #include "cmCTest.h" @@ -874,6 +877,35 @@ diff.ApplyTo(env); } + // Inject LLVM Profile name : + // https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program + if (this->CTest->GetCTestConfiguration("CTestTestCoverageTool") == + "LLVM-COV"_s || + this->TestHandler->TestOptions.CoverageTool == "LLVM-COV"_s) { + + // Isolate the test from any ambient LLVM_PROFILE_FILE + env.UnPutEnv("LLVM_PROFILE_FILE"); + // Value is <Test Dir>/<testName>_<processID>.profraw + std::string profileEnv = + cmStrCat(this->TestProperties->CTestDirectory, "/", + this->TestProperties->Name, "_%p.profraw"_s); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + this->Index + << ": Using environment variable LLVM_PROFILE_FILE="_s + << profileEnv << " \n", + this->TestHandler->GetQuiet()); + env.PutEnv(cmStrCat("LLVM_PROFILE_FILE="_s, profileEnv)); + // ProcessID -> * to allow for glob to find all + // files generated by the test + cmSystemTools::ReplaceString(profileEnv, "%p", "*"); + + cmsys::Glob glob; + glob.FindFiles(profileEnv); + for (std::string const& file : glob.GetFiles()) { + cmSystemTools::RemoveFile(file); + } + }; + if (this->UseAllocatedResources) { this->SetupResourcesEnvironment(env); } else {
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 2d923a4..1c0d4e7 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -96,6 +96,9 @@ if (!args.ResourceSpecFile.empty()) { handler->TestOptions.ResourceSpecFile = args.ResourceSpecFile; } + if (!args.CoverageTool.empty()) { + handler->TestOptions.CoverageTool = args.CoverageTool; + } if (!args.StopTime.empty()) { this->CTest->SetStopTime(args.StopTime); }
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index 125d5a5..00297f6 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h
@@ -46,6 +46,7 @@ std::string TestLoad; std::string ResourceSpecFile; std::string OutputJUnit; + std::string CoverageTool; bool StopOnFailure = false; }; @@ -74,6 +75,7 @@ .Bind("TEST_LOAD"_s, &TestArguments::TestLoad) .Bind("RESOURCE_SPEC_FILE"_s, &TestArguments::ResourceSpecFile) .Bind("STOP_ON_FAILURE"_s, &TestArguments::StopOnFailure) + .Bind("COVERAGE_TOOL"_s, &TestArguments::CoverageTool) .Bind("OUTPUT_JUNIT"_s, &TestArguments::OutputJUnit); }
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 65957af..9731a17 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -2493,7 +2493,8 @@ cmCTestTestProperties test; test.Name = testname; test.Args = args; - test.Directory = cmSystemTools::GetLogicalWorkingDirectory(); + test.CTestDirectory = cmSystemTools::GetLogicalWorkingDirectory(); + test.Directory = test.CTestDirectory; cmCTestOptionalLog(this->CTest, DEBUG, "Set test directory: " << test.Directory << std::endl, this->Quiet);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index 4d4dbb8..c6238da 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h
@@ -56,6 +56,8 @@ std::string ResourceSpecFile; std::string JUnitXMLFileName; + std::string CoverageTool; + std::vector<std::string> TestPassthroughArguments; }; @@ -131,7 +133,10 @@ void AppendError(cm::string_view err); cm::optional<std::string> Error; std::string Name; + // working directory for test, overridden by WORKING_DIRECTORY property std::string Directory; + // Original directory of test creation + std::string CTestDirectory; std::vector<std::string> Args; std::vector<std::string> RequiredFiles; std::vector<std::string> Depends;
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 9e11197..eb743bc 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx
@@ -541,7 +541,8 @@ 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 32c964c..9be5259 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h
@@ -111,7 +111,7 @@ 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 0000000..7228c9d --- /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 <string> + +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 6b454ac..8f82e66 100644 --- a/Source/cmCMakePresetsErrors.cxx +++ b/Source/cmCMakePresetsErrors.cxx
@@ -197,7 +197,7 @@ 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 7e57854..212a97b 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx
@@ -1142,12 +1142,13 @@ } 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 @@ 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<File*> 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 209fd64..74063e4 100644 --- a/Source/cmCMakePresetsGraph.h +++ b/Source/cmCMakePresetsGraph.h
@@ -453,8 +453,15 @@ 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 @@ private: enum class RootType { + Any, Project, User, }; @@ -482,7 +490,8 @@ 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<File*>& inProgressFiles, File*& file, std::string& errMsg);
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e57bd9d..caf450e 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 @@ 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 @@ 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<cmCMakePresetsGraph::TestPreset>( resolveResult.StatusCode, resolveResult.ErrorPresetName, @@ -1801,8 +1802,7 @@ bool processSteps = false; bool SRArgumentSpecified = false; std::vector<std::pair<std::string, bool>> runScripts; - bool listPresets = false; - std::string presetName; + cmCMakePresetsArgs presetsArgs; // copy the command line cm::append(this->Impl->InitialCommandLineArguments, args); @@ -1990,14 +1990,21 @@ auto const presetArguments = std::vector<CommandArgument>{ 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 @@ } } - 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<int>(!success); } if (!success) { @@ -2607,8 +2614,8 @@ } } - // 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 @@ -3260,6 +3267,7 @@ // CTest Test Step set("CTEST_TEST_TIMEOUT", "TimeOut"); + set("CTEST_TEST_COVERAGE_TOOL", "CTestTestCoverageTool"); // CTest Coverage Step set("CTEST_COVERAGE_COMMAND", "CoverageCommand");
diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 46c88b7..8dce347 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 @@ 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/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 9a5e109..7427422 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -463,7 +463,8 @@ } void cmExtraEclipseCDT4Generator::WriteGroups( - SourceGroupVector const& sourceGroups, std::string& linkName, + SourceGroupVector const& sourceGroups, + cmSourceGroupFiles const& sourceGroupFiles, std::string& linkName, cmXMLWriter& xml) { for (auto const& sg : sourceGroups) { @@ -475,10 +476,11 @@ xml, linkName3, "virtual:/virtual", VirtualFolder); SourceGroupVector const& children = sg->GetGroupChildren(); if (!children.empty()) { - this->WriteGroups(children, linkName, xml); + this->WriteGroups(children, sourceGroupFiles, linkName, xml); } - std::vector<cmSourceFile const*> sFiles = sg->GetSourceFiles(); - for (cmSourceFile const* file : sFiles) { + std::vector<cmSourceFile const*> const& sourceFiles = + sourceGroupFiles.GetSourceFiles(sg.get()); + for (cmSourceFile const* file : sourceFiles) { std::string const& fullPath = file->GetFullPath(); if (!cmSystemTools::FileIsDirectory(fullPath)) { @@ -521,17 +523,18 @@ break; // skip generating the linked resources to the source files } // get the files from the source lists then add them to the groups + cmSourceGroupFiles sourceGroupFiles; std::vector<cmSourceFile*> files; target->GetSourceFiles( files, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); for (cmSourceFile* sf : files) { // Add the file to the list of sources. - std::string const& source = sf->ResolveFullPath(); - cmSourceGroup* sourceGroup = lg->FindSourceGroup(source); - sourceGroup->AssignSource(sf); + sourceGroupFiles.Add(lg->FindSourceGroup(sf->ResolveFullPath()), + sf); } - this->WriteGroups(makefile->GetSourceGroups(), linkName2, xml); + this->WriteGroups(makefile->GetSourceGroups(), sourceGroupFiles, + linkName2, xml); } break; // ignore all others: default:
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index aa7cc25..fa92fb4 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -88,6 +88,7 @@ cmLocalGenerator& lg); void WriteGroups(SourceGroupVector const& sourceGroups, + cmSourceGroupFiles const& sourceGroupFiles, std::string& linkName, cmXMLWriter& xml); void CreateLinksToSubprojects(cmXMLWriter& xml, std::string const& baseDir); void CreateLinksForTargets(cmXMLWriter& xml);
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 3d398b2..8b214b6 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx
@@ -486,7 +486,7 @@ void ProcessLanguages(); void ProcessLanguage(std::string const& lang); - Json::ArrayIndex AddSourceGroup(cmSourceGroup* sg); + Json::ArrayIndex AddSourceGroup(cmSourceGroup const* sg); CompileData BuildCompileData(cmSourceFile* sf); CompileData MergeCompileData(CompileData const& fd); Json::ArrayIndex AddSourceCompileGroup(cmSourceFile* sf, @@ -1469,7 +1469,7 @@ } } -Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg) +Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup const* sg) { auto i = this->SourceGroupsMap.find(sg); if (i == this->SourceGroupsMap.end()) { @@ -1802,7 +1802,8 @@ source["fileSetIndex"] = fsit->second; } - if (cmSourceGroup* sg = this->GT->LocalGenerator->FindSourceGroup(path)) { + if (cmSourceGroup const* sg = + this->GT->LocalGenerator->FindSourceGroup(path)) { Json::ArrayIndex const groupIndex = this->AddSourceGroup(sg); source["sourceGroupIndex"] = groupIndex; this->SourceGroups[groupIndex].SourceIndexes.append(si); @@ -1888,7 +1889,8 @@ source["fileSetIndex"] = fsit->second; } - if (cmSourceGroup* sg = this->GT->LocalGenerator->FindSourceGroup(path)) { + if (cmSourceGroup const* sg = + this->GT->LocalGenerator->FindSourceGroup(path)) { Json::ArrayIndex const groupIndex = this->AddSourceGroup(sg); source["sourceGroupIndex"] = groupIndex; this->SourceGroups[groupIndex].InterfaceSourceIndexes.append(si);
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 9c08298..5c1d1c4 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -545,7 +545,7 @@ std::map<std::string, std::vector<cmSourceFile*>> groupFiles; std::set<std::string> groupNames; for (cmSourceFile* sf : sources) { - cmSourceGroup* sourceGroup = + cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(sf->ResolveFullPath()); std::string gn = sourceGroup->GetFullName(); groupFiles[gn].push_back(sf);
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index c273c87..bfbb24f 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -1063,7 +1063,7 @@ item = cmSystemTools::CollapseFullPath(item, mf->GetCurrentSourceDirectory()); } - cmSourceGroup* sg = + cmSourceGroup const* sg = cmSourceGroup::FindSourceGroup(item, mf->GetSourceGroups()); std::string folderName = sg->GetFullName(); if (folderName.empty()) {
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 1fedd91..1e467e7 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -4563,7 +4563,7 @@ auto addSourceToGroup = [this, >gt, &generator](std::string const& source) { - cmSourceGroup* sourceGroup = generator->FindSourceGroup(source); + cmSourceGroup const* sourceGroup = generator->FindSourceGroup(source); cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt.get(), sourceGroup); std::string key = GetGroupMapKeyFromPath(gtgt.get(), source); @@ -4639,7 +4639,7 @@ } cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( - cmGeneratorTarget* gtgt, cmSourceGroup* sg) + cmGeneratorTarget* gtgt, cmSourceGroup const* sg) { std::string s; std::string target;
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 82bb9d5..114caec 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h
@@ -161,7 +161,7 @@ cm::string_view attributeValue); cmXCodeObject* CreateOrGetPBXGroup(cmGeneratorTarget* gtgt, - cmSourceGroup* sg); + cmSourceGroup const* sg); cmXCodeObject* CreatePBXGroup(cmXCodeObject* parent, std::string const& name); bool CreateGroups(std::vector<cmLocalGenerator*>& generators);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 6de9c50..fa14c0a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1388,6 +1388,8 @@ AllConfigSources sources; sources.Sources = target->GetAllConfigSources(); + cmSourceGroupFiles sourceGroupFiles; + // Add CMakeLists.txt file with rule to re-run CMake for user convenience. if (target->GetType() != cmStateEnums::GLOBAL_TARGET && target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) { @@ -1425,9 +1427,7 @@ } } // Add the file to the list of sources. - std::string const source = sf->GetFullPath(); - cmSourceGroup* sourceGroup = this->FindSourceGroup(source); - sourceGroup->AssignSource(sf); + sourceGroupFiles.Add(this->FindSourceGroup(sf->GetFullPath()), sf); } // open the project @@ -1440,7 +1440,8 @@ // Loop through every source group. SourceGroupVector const& sourceGroups = this->Makefile->GetSourceGroups(); for (auto const& sg : sourceGroups) { - this->WriteGroup(sg.get(), target, fout, libName, configs, sources); + this->WriteGroup(sg.get(), target, fout, libName, configs, sources, + sourceGroupFiles); } fout << "\t</Files>\n"; @@ -1688,11 +1689,12 @@ bool cmLocalVisualStudio7Generator::WriteGroup( cmSourceGroup const* sg, cmGeneratorTarget* target, std::ostream& fout, std::string const& libName, std::vector<std::string> const& configs, - AllConfigSources const& sources) + AllConfigSources const& sources, cmSourceGroupFiles const& sourceGroupFiles) { cmGlobalVisualStudio7Generator* gg = static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator); - std::vector<cmSourceFile const*> const& sourceFiles = sg->GetSourceFiles(); + std::vector<cmSourceFile const*> const& sourceFiles = + sourceGroupFiles.GetSourceFiles(sg); SourceGroupVector const& children = sg->GetGroupChildren(); // Write the children to temporary output. @@ -1700,7 +1702,7 @@ std::ostringstream tmpOut; for (auto const& child : children) { if (this->WriteGroup(child.get(), target, tmpOut, libName, configs, - sources)) { + sources, sourceGroupFiles)) { hasChildrenWithSources = true; } }
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 38df53b..885d8ca 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h
@@ -23,6 +23,7 @@ class cmMakefile; class cmSourceFile; class cmSourceGroup; +class cmSourceGroupFiles; class cmVS7GeneratorOptions : public cmVisualStudioGeneratorOptions { @@ -147,7 +148,8 @@ bool WriteGroup(cmSourceGroup const* sg, cmGeneratorTarget* target, std::ostream& fout, std::string const& libName, std::vector<std::string> const& configs, - AllConfigSources const& sources); + AllConfigSources const& sources, + cmSourceGroupFiles const& sourceGroupFiles); friend class cmLocalVisualStudio7GeneratorFCInfo; friend class cmLocalVisualStudio7GeneratorInternals;
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 7251810..3b5feea 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx
@@ -7,7 +7,6 @@ #include <cm/memory> #include "cmGeneratorExpression.h" -#include "cmSourceFile.h" #include "cmStringAlgorithms.h" class cmSourceGroupInternals @@ -85,21 +84,11 @@ return this->GroupFiles.find(name) != this->GroupFiles.cend(); } -void cmSourceGroup::AssignSource(cmSourceFile const* sf) -{ - this->SourceFiles.push_back(sf); -} - std::set<std::string> const& cmSourceGroup::GetGroupFiles() const { return this->GroupFiles; } -std::vector<cmSourceFile const*> const& cmSourceGroup::GetSourceFiles() const -{ - return this->SourceFiles; -} - void cmSourceGroup::AddChild(std::unique_ptr<cmSourceGroup> child) { this->Internal->GroupChildren.push_back(std::move(child)); @@ -196,3 +185,19 @@ // Shouldn't get here, but just in case, return the default group. return groups.data()->get(); } + +void cmSourceGroupFiles::Add(cmSourceGroup const* sg, cmSourceFile const* sf) +{ + this->SourceFiles[sg].push_back(sf); +} + +std::vector<cmSourceFile const*> const& cmSourceGroupFiles::GetSourceFiles( + cmSourceGroup const* sg) const +{ + auto i = this->SourceFiles.find(sg); + if (i != this->SourceFiles.end()) { + return i->second; + } + static std::vector<cmSourceFile const*> const empty; + return empty; +}
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 4ce79ed..ff7d23f 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h
@@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <map> #include <memory> #include <set> #include <string> @@ -100,22 +101,10 @@ cmSourceGroup* MatchChildrenRegex(std::string const& name) const; /** - * Assign the given source file to this group. Used only by - * generators. - */ - void AssignSource(cmSourceFile const* sf); - - /** * Get the set of file names explicitly added to this source group. */ std::set<std::string> const& GetGroupFiles() const; - /** - * Get the list of the source files that have been assigned to this - * source group. - */ - std::vector<cmSourceFile const*> const& GetSourceFiles() const; - SourceGroupVector const& GetGroupChildren() const; /** @@ -142,11 +131,18 @@ */ std::set<std::string> GroupFiles; - /** - * Vector of all source files that have been assigned to - * this group. - */ - std::vector<cmSourceFile const*> SourceFiles; - std::unique_ptr<cmSourceGroupInternals> Internal; }; + +/** \class cmSourceGroup + * \brief Used by generators to organize a target's sources into groups. + */ +class cmSourceGroupFiles +{ + std::map<cmSourceGroup const*, std::vector<cmSourceFile const*>> SourceFiles; + +public: + void Add(cmSourceGroup const* sg, cmSourceFile const* sf); + std::vector<cmSourceFile const*> const& GetSourceFiles( + cmSourceGroup const* sg) const; +};
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 6622957..71da193 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2007,14 +2007,16 @@ std::set<cmSourceGroup const*> groupsUsed; for (cmGeneratorTarget::AllConfigSource const& si : sources) { std::string const& source = si.Source->GetFullPath(); - cmSourceGroup* sourceGroup = this->LocalGenerator->FindSourceGroup(source); + cmSourceGroup const* sourceGroup = + this->LocalGenerator->FindSourceGroup(source); groupsUsed.insert(sourceGroup); } if (cmSourceFile const* srcCMakeLists = this->LocalGenerator->CreateVCProjBuildRule()) { std::string const& source = srcCMakeLists->GetFullPath(); - cmSourceGroup* sourceGroup = this->LocalGenerator->FindSourceGroup(source); + cmSourceGroup const* sourceGroup = + this->LocalGenerator->FindSourceGroup(source); groupsUsed.insert(sourceGroup); } @@ -2173,7 +2175,8 @@ for (ToolSource const& s : sources) { cmSourceFile const* sf = s.SourceFile; std::string const& source = sf->GetFullPath(); - cmSourceGroup* sourceGroup = this->LocalGenerator->FindSourceGroup(source); + cmSourceGroup const* sourceGroup = + this->LocalGenerator->FindSourceGroup(source); std::string const& filter = sourceGroup->GetFullName(); std::string path = this->ConvertPath(source, s.RelativePath); ConvertToWindowsSlash(path); @@ -6075,7 +6078,7 @@ std::string const& fullFileName = source->GetFullPath(); std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory(); std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory(); - cmSourceGroup* sourceGroup = + cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(fullFileName); if (sourceGroup && !sourceGroup->GetFullName().empty()) { sourceGroupedFile =
diff --git a/Source/cmake.cxx b/Source/cmake.cxx index a51374f..2918cd1 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx
@@ -86,6 +86,7 @@ # include <cm3p/curl/curl.h> # include <cm3p/json/writer.h> +# include "cmCMakePresetsArgs.h" # include "cmConfigureLog.h" # include "cmFileAPI.h" # include "cmGraphVizWriter.h" @@ -1014,9 +1015,9 @@ #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 @@ 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 @@ #ifdef CMAKE_BOOTSTRAP false; #else - !presetName.empty(); + !presetsArgs.PresetName.empty(); #endif if (this->State->GetRole() == cmState::Role::Project && !haveSourceDir && @@ -1593,8 +1601,8 @@ } #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 @@ } #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 @@ 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 @@ } 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<ConfigurePreset>( @@ -3897,13 +3917,14 @@ int cmake::Build(cmBuildArgs buildArgs, std::vector<std::string> targets, std::vector<std::string> nativeOptions, - cmBuildOptions& buildOptions, std::string const& presetName, - bool listPresets, std::vector<std::string> const& args) + cmBuildOptions& buildOptions, + cmCMakePresetsArgs const& presetsArgs, + std::vector<std::string> 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 @@ 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 @@ 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<cmCMakePresetsGraph::BuildPreset>( resolveResult.StatusCode, resolveResult.ErrorPresetName, @@ -4261,8 +4283,7 @@ } #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 @@ 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 @@ 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 @@ 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 @@ if (!configurePreset) { return 1; } - std::vector<std::string> args{ cmSystemTools::GetCMakeCommand(), - "--preset", step.PresetName }; - if (fresh == WorkflowFresh::Yes) { - args.emplace_back("--fresh"); + std::vector<std::string> 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 c2a0f05..900cbb4 100644 --- a/Source/cmake.h +++ b/Source/cmake.h
@@ -48,6 +48,9 @@ #endif class cmExternalMakefileProjectGeneratorFactory; +class cmCMakePresetsArgs; +class cmCMakePresetsConfigureArgs; +class cmCMakePresetsWorkflowArgs; class cmFileAPI; class cmInstrumentation; class cmFileTimeCache; @@ -254,19 +257,8 @@ 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 @@ //! run the --build option int Build(cmBuildArgs buildArgs, std::vector<std::string> targets, std::vector<std::string> nativeOptions, - cmBuildOptions& buildOptions, std::string const& presetName, - bool listPresets, std::vector<std::string> const& args); + cmBuildOptions& buildOptions, + cmCMakePresetsArgs const& presetsArgs, + std::vector<std::string> const& args); enum class DryRun { @@ -640,18 +633,7 @@ 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 7b325ee..d7f0c88 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 cmDocumentationOptions[] = { { "--preset <preset>,--preset=<preset>", "Specify a configure preset." }, + { "--presets-file <file>,--presets-file=<file>", + "Specify the path to a presets file." }, { "--list-presets[=<type>]", "List available presets." }, { "--workflow [<options>]", "Run a workflow preset." }, { "-E", "CMake command mode. Run \"cmake -E\" for a summary of commands." }, @@ -474,8 +477,7 @@ 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 @@ buildArgs.verbose = true; return true; }; + auto presetFileLambda = [&](std::string const& value) -> bool { + presetsArgs.PresetsFile = cmSystemTools::ToNormalizedPathOnDisk(value); + return true; + }; using CommandArgument = cmCommandLineArgument<bool(std::string const& value)>; @@ -523,9 +529,11 @@ std::vector<CommandArgument> 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 @@ } } - if (buildArgs.binaryDir.empty() && presetName.empty() && !listPresets) { + if (buildArgs.binaryDir.empty() && !presetsArgs.HasPresetsArg()) { /* clang-format off */ std::cerr << "Usage: cmake --build <dir> " @@ -633,6 +641,8 @@ " <dir> = Project binary directory to be built.\n" " --preset <preset>, --preset=<preset>\n" " = Specify a build preset.\n" + " --presets-file <file>, --presets-file=<file>\n" + " = Specify the path to a presets file.\n" " --list-presets[=<type>]\n" " = List available build presets.\n" " --parallel [<jobs>], -j [<jobs>]\n" @@ -672,7 +682,7 @@ std::vector<std::string> 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 @@ 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<bool(std::string const& value)>; @@ -992,17 +998,18 @@ std::vector<CommandArgument> 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<std::string> inputArgs; @@ -1029,23 +1036,23 @@ } 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 <options>\n" "Options:\n" - " --preset <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 <preset> = Workflow preset to execute.\n" + " --presets-file <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 @@ cmakemainProgressCallback(msg, prog, &cm); }); - return cm.Workflow(presetName, listPresets, fresh); + return cm.Workflow(presetsArgs); #endif }
diff --git a/Templates/CTestScript.cmake.in b/Templates/CTestScript.cmake.in index 54bfda4..cd79a23 100644 --- a/Templates/CTestScript.cmake.in +++ b/Templates/CTestScript.cmake.in
@@ -48,6 +48,7 @@ set(CTEST_RESOURCE_SPEC_FILE "@CTEST_RESOURCE_SPEC_FILE@") set(CTEST_TEST_LOAD "@CTEST_TEST_LOAD@") set(CTEST_TEST_TIMEOUT "@DART_TESTING_TIMEOUT@") +set(CTEST_TEST_COVERAGE_TOOL "@COVERAGE_TOOL@" # CTest Coverage Step set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in index f92dcc4..a2595c7 100644 --- a/Tests/CMakeTests/ProcessorCountTest.cmake.in +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in
@@ -1,5 +1,8 @@ include(ProcessorCount) +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +# ProcessorCount() must tolerate execute_process() failures + ProcessorCount(processor_count) message("### 1. This line should be the first line of text in the test output.")
diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt index f7e3461..357050f 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 85ddab1..c106f29 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 0000000..d00491f --- /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 0000000..29d37ad --- /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 0000000..d15bd8d --- /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 0000000..af68ee8 --- /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 0000000..4b7648d --- /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 0000000..185f46d --- /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 0000000..7ec3a37 --- /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 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileRelPath.cmake
diff --git a/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileSubdir.cmake b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileSubdir.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OtherCMakePresetsFileSubdir.cmake
diff --git a/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-result.txt b/Tests/RunCMake/CMakePresets/PresetsFileArgNoExist-result.txt new file mode 100644 index 0000000..d00491f --- /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 0000000..668f949 --- /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 c816830..8ca58a2 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -30,6 +30,33 @@ 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 @@ ${_make_program} ${_unused_cli} ${_preset} + ${_presets_file} ${_log_level} ${ARGN} ) @@ -313,6 +341,7 @@ 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(UserDuplicateCross) run_cmake_presets(UserInheritance) +# Test --presets-file=<file> +# <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") +# <file> 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 <file> +run_cmake_presets(OtherCMakePresetsFileList --list-presets=all) +# <file> 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 <file> should have paths evaluated relative to <file> +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 0000000..56db1ad --- /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 0000000..e8a5f7f --- /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 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.cmake
diff --git a/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.json.in b/Tests/RunCMake/CMakePresetsBuild/OtherCMakePresetsFile.json.in new file mode 100644 index 0000000..474c669 --- /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 0000000..ee586df --- /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 0000000..d00491f --- /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 0000000..50d4e2b --- /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 92378d3..50a4e8e 100644 --- a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake
@@ -26,6 +26,12 @@ 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 @@ 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(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 0000000..a9068c7 --- /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 0000000..a015307 --- /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 0000000..7e03528 --- /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 0000000..d00491f --- /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 0000000..c532031 --- /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 969fda2..b8c1eb3 100644 --- a/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake
@@ -33,6 +33,12 @@ 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 @@ 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(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 0000000..3b3b9f9 --- /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 0000000..7fb2df5 --- /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 0000000..7623488 --- /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 0000000..d00491f --- /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 0000000..5235262 --- /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 42dfe18..2b320f5 100644 --- a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
@@ -37,6 +37,12 @@ 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 @@ 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_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 @@ 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 8e23c9b..71a61f5 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> Options: - --preset <preset> = Workflow preset to execute\. - --list-presets = List available workflow presets\. - --fresh = Configure a fresh build tree, removing any existing cache file\.$ + --preset <preset> = Workflow preset to execute\. + --presets-file <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 0000000..31ce7ff --- /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 0000000..4b3f7c3 --- /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 0000000..194fbfd --- /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 0000000..d00491f --- /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 0000000..50d4e2b --- /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 fac8dfc..e121b1c 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsWorkflow/RunCMakeTest.cmake
@@ -35,6 +35,12 @@ 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 @@ 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(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/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake index 730efa8..9f014d0 100644 --- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -260,6 +260,15 @@ endfunction() run_environment() +# Test setting of CTEST_TEST_COVERAGE_TOOL +function(run_CTestTestCoverageTool) + set(CASE_CTEST_TEST_ARGS "COVERAGE_TOOL" "LLVM-COV") + set(CASE_TEST_PREFIX_CODE [[ unset(ENV{LLVM_PROFILE_FILE})]]) + + run_ctest(TestCTestTestCoverageTool -VV) +endfunction() +run_CTestTestCoverageTool() + # test for OUTPUT_JUNIT run_ctest_test(OutputJUnit OUTPUT_JUNIT junit.xml REPEAT UNTIL_FAIL:2)
diff --git a/Tests/RunCMake/ctest_test/TestCTestTestCoverageTool-stdout.txt b/Tests/RunCMake/ctest_test/TestCTestTestCoverageTool-stdout.txt new file mode 100644 index 0000000..768bb03 --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestCTestTestCoverageTool-stdout.txt
@@ -0,0 +1,3 @@ +1: Using environment variable LLVM_PROFILE_FILE=[^ +]*/Tests/RunCMake/ctest_test/[^ +]*_%p.profraw
diff --git a/Utilities/Scripts/regenerate-presets.py b/Utilities/Scripts/regenerate-presets.py index 37f801a..665b712 100755 --- a/Utilities/Scripts/regenerate-presets.py +++ b/Utilities/Scripts/regenerate-presets.py
@@ -31,11 +31,12 @@ 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 9cac302..27049c7 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py
@@ -806,11 +806,12 @@ '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