Merge topic 'linker-depfile-flag'
f4e74af1ea GNU linker: Use single-argument form of --dependency-file flag
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !10049
diff --git a/.clang-tidy b/.clang-tidy
index c85fd67..35503d4 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -8,7 +8,6 @@
-bugprone-implicit-widening-of-multiplication-result,\
-bugprone-inc-dec-in-conditions,\
-bugprone-macro-parentheses,\
--bugprone-misplaced-widening-cast,\
-bugprone-multi-level-implicit-pointer-conversion,\
-bugprone-narrowing-conversions,\
-bugprone-return-const-ref-from-parameter,\
@@ -30,6 +29,7 @@
-misc-use-internal-linkage,\
modernize-*,\
-modernize-avoid-c-arrays,\
+-modernize-concat-nested-namespaces,\
-modernize-macro-to-enum,\
-modernize-return-braced-init-list,\
-modernize-type-traits,\
@@ -45,7 +45,6 @@
-performance-unnecessary-value-param,\
readability-*,\
-readability-avoid-nested-conditional-operator,\
--readability-avoid-return-with-void-value,\
-readability-avoid-unconditional-preprocessor-if,\
-readability-convert-member-functions-to-static,\
-readability-enum-initial-value,\
@@ -59,11 +58,6 @@
-readability-make-member-function-const,\
-readability-math-missing-parentheses,\
-readability-named-parameter,\
--readability-redundant-casting,\
--readability-redundant-declaration,\
--readability-redundant-inline-specifier,\
--readability-redundant-member-init,\
--readability-reference-to-constructed-temporary,\
-readability-simplify-boolean-expr,\
-readability-static-accessed-through-instance,\
-readability-suspicious-call-argument,\
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 222ac91..b4a2425 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -736,6 +736,13 @@
CMAKE_CI_BUILD_NAME: oneapi2024.1.0_makefiles
CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2024.1.0-el8
+t:oneapi2024.2.0-makefiles:
+ extends:
+ - .cmake_test_linux_inteloneapi_makefiles
+ variables:
+ CMAKE_CI_BUILD_NAME: oneapi2024.2.0_makefiles
+ CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2024.2.0-rocky9
+
b:linux-x86_64-package:
extends:
- .linux_package
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 79a562c..ae1359e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
diff --git a/Help/command/LINK_LIBRARIES_LINKER.txt b/Help/command/LINK_LIBRARIES_LINKER.txt
new file mode 100644
index 0000000..7dc6b84
--- /dev/null
+++ b/Help/command/LINK_LIBRARIES_LINKER.txt
@@ -0,0 +1,24 @@
+Handling Compiler Driver Differences
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.32
+
+To pass options to the linker tool, each compiler driver has its own syntax.
+The ``LINKER:`` prefix and ``,`` separator can be used to specify, in a portable
+way, options to pass to the linker tool. ``LINKER:`` is replaced by the
+appropriate driver option and ``,`` by the appropriate driver separator.
+The driver prefix and driver separator are given by the values of the
+:variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG` and
+:variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP` variables.
+
+For example, ``"LINKER:-z,defs"`` becomes ``-Xlinker -z -Xlinker defs`` for
+``Clang`` and ``-Wl,-z,defs`` for ``GNU GCC``.
+
+The ``LINKER:`` prefix supports, as an alternative syntax, specification of
+arguments using the ``SHELL:`` prefix and space as separator. The previous
+example then becomes ``"LINKER:SHELL:-z defs"``.
+
+.. note::
+
+ Specifying the ``SHELL:`` prefix anywhere other than at the beginning of the
+ ``LINKER:`` prefix is not supported.
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index 2a3c759..dbaa4fb 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -16,7 +16,7 @@
CMake only generates tests if the :command:`enable_testing` command has been
invoked. The :module:`CTest` module invokes ``enable_testing`` automatically
-unless ``BUILD_TESTING`` is set to ``OFF``.
+unless :variable:`BUILD_TESTING` is set to ``OFF``.
Tests added with the ``add_test(NAME)`` signature support using
:manual:`generator expressions <cmake-generator-expressions(7)>`
diff --git a/Help/command/ctest_run_script.rst b/Help/command/ctest_run_script.rst
index 145bd90..0d94eb0 100644
--- a/Help/command/ctest_run_script.rst
+++ b/Help/command/ctest_run_script.rst
@@ -9,7 +9,6 @@
script_file_name2 ... [RETURN_VALUE var])
Runs a script or scripts much like if it was run from :option:`ctest -S`.
-If no argument is provided then the current script is run using the current
-settings of the variables. If ``NEW_PROCESS`` is specified then each
-script will be run in a separate process.If ``RETURN_VALUE`` is specified
-the return value of the last script run will be put into ``var``.
+If ``NEW_PROCESS`` is specified then each script will be run in a separate
+process. If ``RETURN_VALUE`` is specified the return value of the last script
+run will be put into ``var``.
diff --git a/Help/command/enable_testing.rst b/Help/command/enable_testing.rst
index 3ac1a19..7bae5c0 100644
--- a/Help/command/enable_testing.rst
+++ b/Help/command/enable_testing.rst
@@ -9,12 +9,12 @@
Enables testing for this directory and below.
-This command should be in the source directory root
-because ctest expects to find a test file in the build
-directory root.
+This command should be in the top-level source directory because
+:manual:`ctest(1)` expects to find a test file in the top-level
+build directory.
This command is automatically invoked when the :module:`CTest`
-module is included, except if the ``BUILD_TESTING`` option is
-turned off.
+module is included, except if the :variable:`BUILD_TESTING`
+option is turned off.
See also the :command:`add_test` command.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index c26076b..3ffabac 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -184,6 +184,11 @@
on components being integers as the single version. By default, both end
points are included. By specifying ``<``, the upper end point will be
excluded. Version ranges are only supported with CMake 3.19 or later.
+ Note that it is not possible to extend the compatibility range specified
+ by the package's version file. For example, if the package version file
+ specifies compatibility within a minor version, it is not possible to
+ extend the compatibility to several minor versions by specifying a
+ version range.
The ``EXACT`` option requests that the version be matched exactly. This option
is incompatible with the specification of a version range.
@@ -507,13 +512,12 @@
configuration file found is used, even if a newer version of the package
resides later in the list of search paths.
-For search paths which contain ``<name>*``, the order among matching paths
-is unspecified unless the :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` variable
-is set. This variable, along with the
-:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable, determines the order
-in which CMake considers paths that match a single search path containing
-``<name>*``. For example, if the file system contains the package
-configuration files
+For search paths which contain glob expressions (``*``), the order in which
+directories matching the glob are searched is unspecified unless the
+:variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` variable is set. This variable,
+along with the :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable,
+determines the order in which CMake considers glob matches. For example, if
+the file system contains the package configuration files
::
@@ -543,6 +547,14 @@
Added the ``CMAKE_FIND_USE_<CATEGORY>`` variables to globally disable
various search locations.
+.. versionchanged:: 3.32
+ The variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
+ :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` now also control the order
+ in which ``find_package`` searches directories matching the glob expression
+ in the search paths ``<prefix>/<name>.framework/Versions/*/Resources/``
+ and ``<prefix>/<name>.framework/Versions/*/Resources/CMake``. In previous
+ versions of CMake, this order was unspecified.
+
.. include:: FIND_XXX_ROOT.txt
.. include:: FIND_XXX_ORDER.txt
diff --git a/Help/command/if.rst b/Help/command/if.rst
index 9eaf6da..f0846f6 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -390,11 +390,13 @@
.. versionadded:: 3.24
- Compares the two paths component-by-component. Only if every component of
- both paths match will the two paths compare equal. Multiple path separators
- are effectively collapsed into a single separator, but note that backslashes
- are not converted to forward slashes. No other
- :ref:`path normalization <Normalization>` is performed.
+ Lexicographically compares two CMake paths component-by-component without
+ accessing the filesystem. Only if every component of both paths match will
+ the two paths compare equal. Multiple path separators are effectively
+ collapsed into a single separator, but note that backslashes are not
+ converted to forward slashes.
+ No other :ref:`path normalization <Normalization>` is performed.
+ Trailing slashes are preserved, thus ``/a/b`` and ``/a/b/`` are not equal.
Component-wise comparison is superior to string-based comparison due to the
handling of multiple path separators. In the following example, the
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index 94a2429..caa6441 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -148,6 +148,8 @@
See the :manual:`cmake-buildsystem(7)` manual for more on defining
buildsystem properties.
+.. include:: ../command/LINK_LIBRARIES_LINKER.txt
+
Libraries for a Target and/or its Dependents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 30ab41a..93713da 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -336,6 +336,10 @@
The current settings of :policy:`CMP0065` and :policy:`CMP0083` are propagated
through to the generated test project.
+.. versionadded:: 3.32
+ The current setting of :policy:`CMP0181` policy is propagated through to the
+ generated test project.
+
Set variable :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` to choose a build
configuration:
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 10b3f7d..8098bb0 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -350,7 +350,7 @@
away from setting policies to OLD.
Update the ``cmake_policy`` version range generated by ``install(EXPORT)``
-in ``cmExportFileGenerator::GeneratePolicyHeaderCode`` and
+in ``cmExportCMakeConfigGenerator::GeneratePolicyHeaderCode`` and
``install_jar_exports`` in ``javaTargets.cmake.in`` to end at the
previous release. We use one release back since we now know all the
policies added for that version. Commit with a message such as::
diff --git a/Help/envvar/CLICOLOR.rst b/Help/envvar/CLICOLOR.rst
new file mode 100644
index 0000000..404e79e
--- /dev/null
+++ b/Help/envvar/CLICOLOR.rst
@@ -0,0 +1,19 @@
+CLICOLOR
+--------
+
+.. versionadded:: 3.21
+
+.. include:: ENV_VAR.txt
+
+Set to ``0`` to tell command-line tools not to print color
+messages even if connected to a terminal.
+This is a `common convention`_ among command-line tools in general.
+
+See also the :envvar:`CLICOLOR_FORCE` environment variable.
+:envvar:`CLICOLOR_FORCE`, if activated, takes precedence over
+:envvar:`!CLICOLOR`.
+
+See the :variable:`CMAKE_COLOR_DIAGNOSTICS` variable to control
+color in a generated build system.
+
+.. _`common convention`: https://web.archive.org/web/20230417221418/https://bixense.com/clicolors/
diff --git a/Help/envvar/CLICOLOR_FORCE.rst b/Help/envvar/CLICOLOR_FORCE.rst
new file mode 100644
index 0000000..639ed85
--- /dev/null
+++ b/Help/envvar/CLICOLOR_FORCE.rst
@@ -0,0 +1,19 @@
+CLICOLOR_FORCE
+--------------
+
+.. versionadded:: 3.5
+
+.. include:: ENV_VAR.txt
+
+Set to a non-empty value, other than ``0``, to tell command-line
+tools to print color messages even if not connected to a terminal.
+This is a `common convention`_ among command-line tools in general.
+
+See also the :envvar:`CLICOLOR` environment variable.
+:envvar:`!CLICOLOR_FORCE`, if activated, takes precedence over
+:envvar:`CLICOLOR`.
+
+See the :variable:`CMAKE_COLOR_DIAGNOSTICS` variable to control
+color in a generated build system.
+
+.. _`common convention`: https://web.archive.org/web/20230417221418/https://bixense.com/clicolors/
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index fc7a27d..dc11956 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -216,7 +216,11 @@
variable for use by client code. This should not be a cache entry.
``Xxx_ROOT_DIR``
- Where to find the base directory of the module.
+ The base directory of the installation of ``Xxx`` that can be optionally set
+ by the find module if ``Xxx`` is found. This is useful for large packages
+ where many files need to be referenced relative to a common base (or root)
+ directory. Not to be confused with the ``Xxx_ROOT`` hint variable set from the
+ outside for the find module to know where to look for the ``Xxx``.
``Xxx_VERSION_VV``
Variables of this form specify whether the ``Xxx`` module being provided
@@ -417,18 +421,18 @@
Now we need to find the libraries and include files; we use the
information from ``pkg-config`` to provide hints to CMake about where to
-look.
+look before checking other default paths.
.. code-block:: cmake
find_path(Foo_INCLUDE_DIR
NAMES foo.h
- PATHS ${PC_Foo_INCLUDE_DIRS}
+ HINTS ${PC_Foo_INCLUDE_DIRS}
PATH_SUFFIXES Foo
)
find_library(Foo_LIBRARY
NAMES foo
- PATHS ${PC_Foo_LIBRARY_DIRS}
+ HINTS ${PC_Foo_LIBRARY_DIRS}
)
Alternatively, if the library is available with multiple configurations, you can
@@ -439,11 +443,11 @@
find_library(Foo_LIBRARY_RELEASE
NAMES foo
- PATHS ${PC_Foo_LIBRARY_DIRS}/Release
+ HINTS ${PC_Foo_LIBRARY_DIRS}/Release
)
find_library(Foo_LIBRARY_DEBUG
NAMES foo
- PATHS ${PC_Foo_LIBRARY_DIRS}/Debug
+ HINTS ${PC_Foo_LIBRARY_DIRS}/Debug
)
include(SelectLibraryConfigurations)
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index fd5935c..fe3e703 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -20,6 +20,8 @@
.. toctree::
:maxdepth: 1
+ /envvar/CLICOLOR
+ /envvar/CLICOLOR_FORCE
/envvar/CMAKE_APPBUNDLE_PATH
/envvar/CMAKE_FRAMEWORK_PATH
/envvar/CMAKE_INCLUDE_PATH
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index c62fb48..216f17a 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,16 @@
to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.32
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0183: add_feature_info() supports full Condition Syntax. </policy/CMP0183>
+ CMP0182: Create shared library archives by default on AIX. </policy/CMP0182>
+ CMP0181: Link command-line fragment variables are parsed and re-quoted. </policy/CMP0181>
+
Policies Introduced by CMake 3.31
=================================
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 10dbe10..4d20d98 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -97,6 +97,7 @@
/prop_dir/VARIABLES
/prop_dir/VS_GLOBAL_SECTION_POST_section
/prop_dir/VS_GLOBAL_SECTION_PRE_section
+ /prop_dir/VS_SOLUTION_ITEMS
/prop_dir/VS_STARTUP_PROJECT
.. _`Target Properties`:
@@ -342,6 +343,7 @@
/prop_tgt/LINK_OPTIONS
/prop_tgt/LINK_SEARCH_END_STATIC
/prop_tgt/LINK_SEARCH_START_STATIC
+ /prop_tgt/LINK_WARNING_AS_ERROR
/prop_tgt/LINK_WHAT_YOU_USE
/prop_tgt/LINKER_LANGUAGE
/prop_tgt/LINKER_TYPE
@@ -415,6 +417,7 @@
/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE
/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
/prop_tgt/UNITY_BUILD_MODE
+ /prop_tgt/UNITY_BUILD_RELOCATABLE
/prop_tgt/UNITY_BUILD_UNIQUE_ID
/prop_tgt/VERIFY_INTERFACE_HEADER_SETS
/prop_tgt/VERSION
@@ -583,6 +586,7 @@
/prop_sf/UNITY_GROUP
/prop_sf/VS_COPY_TO_OUT_DIR
/prop_sf/VS_CSHARP_tagname
+ /prop_sf/VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD
/prop_sf/VS_DEPLOYMENT_CONTENT
/prop_sf/VS_DEPLOYMENT_LOCATION
/prop_sf/VS_INCLUDE_IN_VSIX
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 4c27bd5..24ff9bc 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -175,6 +175,7 @@
:maxdepth: 1
/variable/BUILD_SHARED_LIBS
+ /variable/BUILD_TESTING
/variable/CMAKE_ABSOLUTE_DESTINATION_FILES
/variable/CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
/variable/CMAKE_APPBUNDLE_PATH
@@ -498,6 +499,7 @@
/variable/CMAKE_LINK_LIBRARY_FLAG
/variable/CMAKE_LINK_LIBRARY_USING_FEATURE
/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED
+ /variable/CMAKE_LINK_WARNING_AS_ERROR
/variable/CMAKE_LINK_WHAT_YOU_USE
/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK
/variable/CMAKE_LINKER_TYPE
@@ -611,6 +613,8 @@
/variable/CMAKE_LANG_ARCHIVE_APPEND
/variable/CMAKE_LANG_ARCHIVE_CREATE
/variable/CMAKE_LANG_ARCHIVE_FINISH
+ /variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG
+ /variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG_SEP
/variable/CMAKE_LANG_BYTE_ORDER
/variable/CMAKE_LANG_COMPILE_OBJECT
/variable/CMAKE_LANG_COMPILER
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 4610e11..a39ecc8 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -513,6 +513,14 @@
:variable:`CMAKE_COMPILE_WARNING_AS_ERROR`, preventing warnings from being
treated as errors on compile.
+.. option:: --link-no-warning-as-error
+
+ .. versionadded:: 3.32
+
+ Ignore target property :prop_tgt:`LINK_WARNING_AS_ERROR` and variable
+ :variable:`CMAKE_LINK_WARNING_AS_ERROR`, preventing warnings from being
+ treated as errors on link.
+
.. option:: --profiling-output=<path>
.. versionadded:: 3.18
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 9281339..4d60ca4 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -353,18 +353,32 @@
This allows the user to widen the output to avoid clipping the test
name which can be very annoying.
-.. option:: --interactive-debug-mode [0|1]
+.. option:: --interactive-debug-mode <0|1>
- Set the interactive mode to ``0`` or ``1``.
+ Disable (``0``) or enable (``1``) interactive debug mode.
This option causes CTest to run tests in either an interactive mode
or a non-interactive mode. In dashboard mode (``Experimental``, ``Nightly``,
``Continuous``), the default is non-interactive. In non-interactive mode,
the environment variable :envvar:`DASHBOARD_TEST_FROM_CTEST` is set.
- Prior to CMake 3.11, interactive mode on Windows allowed system debug
- popup windows to appear. Now, due to CTest's use of ``libuv`` to launch
- test processes, all system debug popup windows are always blocked.
+ Interactive Mode allows Windows Error Reporting (WER) to show debug popup
+ windows and to create core dumps. To enable core dumps in tests,
+ use interactive mode, and follow the Windows documentation
+ on `Collecting User-Mode Dumps`_.
+
+ .. versionchanged:: 3.32
+ Windows Error Reporting (WER) is enabled in interactive mode, so
+ test processes may show debug popup windows and create core dumps.
+ This was made possible by updates to ``libuv``.
+
+ .. versionchanged:: 3.11
+ Windows Error Reporting (WER) is disabled in both interactive and
+ non-interactive modes, so test processes do not show popup windows
+ or create core dumps. This is due to launching test processes with
+ ``libuv``.
+
+.. _`Collecting User-Mode Dumps`: https://learn.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps
.. option:: --no-label-summary
@@ -421,11 +435,8 @@
.. option:: --force-new-ctest-process
- Run child CTest instances as new processes.
-
- By default CTest will run child CTest instances within the same
- process. If this behavior is not desired, this argument will
- enforce new processes for child CTest processes.
+ Ignored. This option once disabled a now-removed optimization
+ for tests running ``ctest`` itself.
.. option:: --schedule-random
diff --git a/Help/policy/CMP0000.rst b/Help/policy/CMP0000.rst
index aecfa71..5f146bc 100644
--- a/Help/policy/CMP0000.rst
+++ b/Help/policy/CMP0000.rst
@@ -21,14 +21,12 @@
details.
Note that the command invocation must appear in the ``CMakeLists.txt``
-file itself; a call in an included file is not sufficient. However,
-the :command:`cmake_policy` command may be called to set policy ``CMP0000``
-to ``OLD`` or ``NEW`` behavior explicitly. The ``OLD`` behavior is to
-silently ignore the missing invocation. The ``NEW`` behavior is to issue
-an error instead of a warning. An included file may set ``CMP0000``
-explicitly to affect how this policy is enforced for the main
-``CMakeLists.txt`` file.
+file itself; a call in an included file is not sufficient. The ``OLD``
+behavior was to silently ignore the missing invocation. The ``NEW``
+behavior is to issue an error instead of a warning.
-This policy was introduced in CMake version 2.6.0.
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 2.6.0
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: STANDARD_ADVICE.txt
.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0015.rst b/Help/policy/CMP0015.rst
index cd65c3f..2e18506 100644
--- a/Help/policy/CMP0015.rst
+++ b/Help/policy/CMP0015.rst
@@ -1,7 +1,7 @@
CMP0015
-------
- :command:`link_directories` treats paths relative to the source dir.
+:command:`link_directories` treats paths relative to the source dir.
In CMake 2.8.0 and lower the :command:`link_directories` command passed
relative paths unchanged to the linker. In CMake 2.8.1 and above the
diff --git a/Help/policy/CMP0147.rst b/Help/policy/CMP0147.rst
index fd5dc5f..1790678 100644
--- a/Help/policy/CMP0147.rst
+++ b/Help/policy/CMP0147.rst
@@ -10,7 +10,8 @@
a ``BuildInParallel`` setting to custom commands in ``.vcxproj`` files.
This policy provides compatibility for projects that have not been updated
to expect this, e.g., because their custom commands were accidentally
-relying on serial execution by MSBuild.
+relying on serial execution by MSBuild. To control this behavior in a more
+precise way, refer to :prop_sf:`VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD`.
The ``OLD`` behavior for this policy is to not add ``BuildInParallel``.
The ``NEW`` behavior for this policy is to add ``BuildInParallel`` for
diff --git a/Help/policy/CMP0181.rst b/Help/policy/CMP0181.rst
new file mode 100644
index 0000000..18fb8db
--- /dev/null
+++ b/Help/policy/CMP0181.rst
@@ -0,0 +1,41 @@
+CMP0181
+-------
+
+.. versionadded:: 3.32
+
+The :variable:`CMAKE_EXE_LINKER_FLAGS`,
+:variable:`CMAKE_EXE_LINKER_FLAGS_<CONFIG>`,
+:variable:`CMAKE_SHARED_LINKER_FLAGS`,
+:variable:`CMAKE_SHARED_LINKER_FLAGS_<CONFIG>`,
+:variable:`CMAKE_MODULE_LINKER_FLAGS`,
+and :variable:`CMAKE_MODULE_LINKER_FLAGS_<CONFIG>` variables are parsed and
+re-quoted and support the ``LINKER:`` prefix.
+
+CMake 3.31 and below use the content of these variables as is.
+
+CMake 3.32 and above parse the content of these variables and manage the
+escaping of special characters. Moreover, the ``LINKER:`` prefix is now
+recognized and expanded.
+
+The ``OLD`` behavior of this policy is to consume the content of the
+:variable:`CMAKE_EXE_LINKER_FLAGS`,
+:variable:`CMAKE_EXE_LINKER_FLAGS_<CONFIG>`,
+:variable:`CMAKE_SHARED_LINKER_FLAGS`,
+:variable:`CMAKE_SHARED_LINKER_FLAGS_<CONFIG>`,
+:variable:`CMAKE_MODULE_LINKER_FLAGS`,
+and :variable:`CMAKE_MODULE_LINKER_FLAGS_<CONFIG>` variables as is.
+
+The ``NEW`` behavior of this policy is to parse and re-quote the content of the
+:variable:`CMAKE_EXE_LINKER_FLAGS`,
+:variable:`CMAKE_EXE_LINKER_FLAGS_<CONFIG>`,
+:variable:`CMAKE_SHARED_LINKER_FLAGS`,
+:variable:`CMAKE_SHARED_LINKER_FLAGS_<CONFIG>`,
+:variable:`CMAKE_MODULE_LINKER_FLAGS`,
+and :variable:`CMAKE_MODULE_LINKER_FLAGS_<CONFIG>` variables as well as to
+expand the ``LINKER:`` prefix.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.32
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: STANDARD_ADVICE.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0182.rst b/Help/policy/CMP0182.rst
new file mode 100644
index 0000000..500d841
--- /dev/null
+++ b/Help/policy/CMP0182.rst
@@ -0,0 +1,31 @@
+CMP0182
+-------
+
+.. versionadded:: 3.32
+
+Create shared library archives by default on AIX.
+
+CMake 3.30 and below always represented ``SHARED`` library targets
+as plain shared object ``.so`` files. This is consistent with other
+UNIX platforms, but is not the preferred convention on AIX.
+CMake 3.31 added the :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE` target
+property to create a shared library archive: the shared object ``.so``
+file is placed inside an archive ``.a`` file. However, the behavior
+was disabled by default for compatibility with existing projects that
+do not set :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE`.
+
+CMake 3.32 and above prefer, when :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE`
+is not set, to enable creation of shared library archives by default
+because it is the preferred convention on AIX. This policy provides
+compatibility for projects that have not been updated.
+
+The ``OLD`` behavior for this policy is to disable shared library
+archives when :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE` is not set.
+The ``NEW`` behavior for this policy is to enable shared library
+archives when :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE` is not set.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.32
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: STANDARD_ADVICE.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0183.rst b/Help/policy/CMP0183.rst
new file mode 100644
index 0000000..5c00cc1
--- /dev/null
+++ b/Help/policy/CMP0183.rst
@@ -0,0 +1,33 @@
+CMP0183
+-------
+
+.. versionadded:: 3.32
+
+:command:`add_feature_info` supports full :ref:`Condition Syntax`.
+
+The ``<enabled>`` parameter accepts a :ref:`semicolon-separated list <CMake
+Language Lists>` of conditions. CMake 3.31 and lower evaluate each
+``condition`` as ``if(${condition})``, which does not properly handle
+conditions with nested paren groups. CMake 3.32 and above instead prefer
+to evaluate each ``condition`` as ``if(<condition>)``, where ``<condition>``
+is re-parsed as if literally written in a call to :command:`if`. This
+allows expressions like::
+
+ "A AND (B OR C)"
+
+but requires expressions like::
+
+ "FOO MATCHES (UPPER|lower)"
+
+to be re-written as::
+
+ "FOO MATCHES \"(UPPER|lower)\""
+
+Policy ``CMP0183`` provides compatibility for projects that have not
+been updated to expect the new behavior.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.32
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: STANDARD_ADVICE.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_dir/EXCLUDE_FROM_ALL.rst b/Help/prop_dir/EXCLUDE_FROM_ALL.rst
index 1adb50e..e4563da 100644
--- a/Help/prop_dir/EXCLUDE_FROM_ALL.rst
+++ b/Help/prop_dir/EXCLUDE_FROM_ALL.rst
@@ -3,7 +3,7 @@
Set this directory property to a true value on a subdirectory to exclude
its targets from the "all" target of its ancestors. If excluded, running
-e.g. ``make`` in the parent directory will not build targets the
+e.g. ``make`` in the parent directory will not build targets in the
subdirectory by default. This does not affect the "all" target of the
subdirectory itself. Running e.g. ``make`` inside the subdirectory will
still build its targets.
diff --git a/Help/prop_dir/VS_SOLUTION_ITEMS.rst b/Help/prop_dir/VS_SOLUTION_ITEMS.rst
new file mode 100644
index 0000000..435b9a7
--- /dev/null
+++ b/Help/prop_dir/VS_SOLUTION_ITEMS.rst
@@ -0,0 +1,19 @@
+VS_SOLUTION_ITEMS
+-----------------
+
+.. versionadded:: 3.32
+
+Specify solution level items included in the generated Visual Studio solution.
+
+The :ref:`Visual Studio Generators` create a ``.sln`` file for each directory
+whose ``CMakeLists.txt`` file calls the :command:`project` command. Append paths
+to this property in the same directory as the top-level :command:`project`
+command call (e.g. in the top-level ``CMakeLists.txt`` file) to specify files
+included in the corresponding solution file.
+
+If a file specified in ``VS_SOLUTION_ITEMS`` matches a :command:`source_group`
+command call, the affected solution level items are placed in a hierarchy of
+solution level folders according to the name specified in that command.
+Otherwise the items are placed in a default solution level directory named
+``Solution Items``. This name matches the default directory name used by Visual
+Studio when attempting to add solution level items at the root of the solution.
diff --git a/Help/prop_sf/VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD.rst b/Help/prop_sf/VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD.rst
new file mode 100644
index 0000000..f8bb93d
--- /dev/null
+++ b/Help/prop_sf/VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD.rst
@@ -0,0 +1,9 @@
+VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD
+----------------------------------------
+
+.. versionadded:: 3.32
+
+A boolean property that disables parallel building for the source file in
+Visual Studio if it is built via :command:`add_custom_command` and is the
+``MAIN_DEPENDENCY`` input for the custom command.
+See policy :policy:`CMP0147`.
diff --git a/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst b/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst
index 9e81594..a40caf4 100644
--- a/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst
+++ b/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst
@@ -3,20 +3,32 @@
.. versionadded:: 3.31
-On AIX, enable creation of a shared library archive. This places
-the shared object ``.so`` file inside an archive ``.a`` file.
+On AIX, enable or disable creation of a shared library archive
+for a ``SHARED`` library target:
-By default, CMake creates shared libraries on AIX as plain
-shared object ``.so`` files for consistency with other UNIX platforms.
-Alternatively, set this property to a true value to create a shared
-library archive instead, as is AIX convention.
+* If enabled, the shared object ``.so`` file is placed inside
+ an archive ``.a`` file. This is the preferred convention on AIX.
-The shared object name in the archive encodes version information from
-the :prop_tgt:`SOVERSION` target property, if set, and otherwise from
-the :prop_tgt:`VERSION` target property, if set.
+ The shared object name in the archive encodes version information from
+ the :prop_tgt:`SOVERSION` target property, if set, and otherwise from
+ the :prop_tgt:`VERSION` target property, if set.
+
+* If disabled, a plain shared object ``.so`` file is produced.
+ This is consistent with other UNIX platforms.
This property defaults to :variable:`CMAKE_AIX_SHARED_LIBRARY_ARCHIVE`
if that variable is set when a non-imported ``SHARED`` library target
is created by :command:`add_library`. Imported targets must explicitly
enable :prop_tgt:`!AIX_SHARED_LIBRARY_ARCHIVE` if they import an AIX
shared library archive.
+
+.. versionchanged:: 3.32
+
+ For a non-imported target, if this property is not set, the
+ default is *enabled*. See policy :policy:`CMP0182`.
+
+ In CMake 3.31, policy :policy:`CMP0182` did not exist,
+ so the default was *disabled*.
+
+ In CMake 3.30 and lower, :prop_tgt:`!AIX_SHARED_LIBRARY_ARCHIVE`
+ did not exist, so the default was *disabled*.
diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst
index 53f5838..73d273b 100644
--- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst
@@ -32,6 +32,8 @@
:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` and
:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties.
+.. include:: ../command/LINK_LIBRARIES_LINKER.txt
+
Creating Relocatable Packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
index 785b17c..886adf2 100644
--- a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
@@ -8,3 +8,9 @@
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_OPTIONS``
.. |PROPERTY_LINK| replace:: :prop_tgt:`LINK_OPTIONS`
.. include:: INTERFACE_BUILD_PROPERTY.txt
+
+.. include:: ../command/DEVICE_LINK_OPTIONS.txt
+
+.. include:: ../command/OPTIONS_SHELL.txt
+
+.. include:: ../command/LINK_OPTIONS_LINKER.txt
diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst
index b449aa1..8814980 100644
--- a/Help/prop_tgt/LINK_LIBRARIES.rst
+++ b/Help/prop_tgt/LINK_LIBRARIES.rst
@@ -33,3 +33,5 @@
corresponding :prop_tgt:`LINK_LIBRARIES_STRATEGY` target property
for details on how CMake orders direct link dependencies on linker
command lines.
+
+.. include:: ../command/LINK_LIBRARIES_LINKER.txt
diff --git a/Help/prop_tgt/LINK_WARNING_AS_ERROR.rst b/Help/prop_tgt/LINK_WARNING_AS_ERROR.rst
new file mode 100644
index 0000000..61b7846
--- /dev/null
+++ b/Help/prop_tgt/LINK_WARNING_AS_ERROR.rst
@@ -0,0 +1,27 @@
+LINK_WARNING_AS_ERROR
+---------------------
+
+.. versionadded:: 3.32
+
+Specify whether to treat warnings on link as errors.
+If enabled, adds a flag to treat warnings on link as errors.
+If the :option:`cmake --link-no-warning-as-error` option is given
+on the :manual:`cmake(1)` command line, this property is ignored.
+
+This property is not implemented for all linkers. It is silently ignored
+if there is no implementation for the linker being used. The currently
+implemented :variable:`compiler linker IDs <CMAKE_<LANG>_COMPILER_LINKER_ID>`
+are:
+
+* ``AIX``
+* ``AppleClang``
+* ``GNU``
+* ``GNUgold``
+* ``LLD``
+* ``MOLD``
+* ``MSVC``
+* ``Solaris``
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_LINK_WARNING_AS_ERROR` if it is set when a target is
+created.
diff --git a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
index f5d9437..370c75c 100644
--- a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
+++ b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
@@ -22,3 +22,5 @@
property.
.. include:: ../command/OPTIONS_SHELL.txt
+
+.. include:: ../prop_tgt/STATIC_LIBRARY_OPTIONS_ARCHIVER.txt
diff --git a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS_ARCHIVER.txt b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS_ARCHIVER.txt
new file mode 100644
index 0000000..955cb9c
--- /dev/null
+++ b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS_ARCHIVER.txt
@@ -0,0 +1,23 @@
+Handling Archiver Driver Differences
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.32
+
+To pass options to the archiver tool, each compiler driver has its own syntax.
+The ``ARCHIVER:`` prefix and ``,`` separator can be used to specify, in a portable
+way, options to pass to the archiver tool. ``ARCHIVER:`` is replaced by the
+appropriate driver option and ``,`` by the appropriate driver separator.
+The driver prefix and driver separator are given by the values of the
+:variable:`CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG` and
+:variable:`CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG_SEP` variables.
+
+The ``ARCHIVER:`` prefix can be specified as part of a ``SHELL:`` prefix
+expression.
+
+The ``ARCHIVER:`` prefix supports, as an alternative syntax, specification of
+arguments using the ``SHELL:`` prefix and space as separator.
+
+.. note::
+
+ Specifying the ``SHELL:`` prefix anywhere other than at the beginning of the
+ ``ARCHIVER:`` prefix is not supported.
diff --git a/Help/prop_tgt/UNITY_BUILD_RELOCATABLE.rst b/Help/prop_tgt/UNITY_BUILD_RELOCATABLE.rst
new file mode 100644
index 0000000..daac7fd
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_RELOCATABLE.rst
@@ -0,0 +1,40 @@
+UNITY_BUILD_RELOCATABLE
+-----------------------
+
+.. versionadded:: 3.32
+
+By default, the unity file generated when :prop_tgt:`UNITY_BUILD` is enabled
+uses absolute paths to reference the original source files. This causes the
+unity file to result in a different output depending on the location of the
+source files.
+
+When this property is set to true, the ``#include`` lines inside the generated
+unity source files will attempt to use relative paths to the original source
+files if possible in order to standardize the output of the unity file.
+
+The unity file's path to the original source file will use the following
+priority:
+
+* relative path to the generated unity file if the source file exists
+ directly or in subfolder under the :variable:`CMAKE_BINARY_DIR`
+
+* relative path to :variable:`CMAKE_SOURCE_DIR` if the source file exists
+ directly or in subfolder under the :variable:`CMAKE_SOURCE_DIR`
+
+* absolute path to the source file.
+
+This target property *does not* guarantee a consistent unity file across
+different environments as the final priority is an absolute path.
+
+Example usage:
+
+.. code-block:: cmake
+
+ add_library(example_library
+ source1.cxx
+ source2.cxx
+ source3.cxx)
+
+ set_target_properties(example_library PROPERTIES
+ UNITY_BUILD True
+ UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+ Developers should add similar notes for each topic branch
+ making a noteworthy change. Each document should be named
+ and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/CMAKE_TYPE_LINKER_FLAGS-LINKER-prefix-support.rst b/Help/release/dev/CMAKE_TYPE_LINKER_FLAGS-LINKER-prefix-support.rst
new file mode 100644
index 0000000..3598dc5
--- /dev/null
+++ b/Help/release/dev/CMAKE_TYPE_LINKER_FLAGS-LINKER-prefix-support.rst
@@ -0,0 +1,13 @@
+CMAKE_TYPE_LINKER_FLAGS-LINKER-prefix-support
+---------------------------------------------
+
+* The :variable:`CMAKE_EXE_LINKER_FLAGS`,
+ :variable:`CMAKE_EXE_LINKER_FLAGS_<CONFIG>`,
+ :variable:`CMAKE_SHARED_LINKER_FLAGS`,
+ :variable:`CMAKE_SHARED_LINKER_FLAGS_<CONFIG>`,
+ :variable:`CMAKE_MODULE_LINKER_FLAGS`,
+ and :variable:`CMAKE_MODULE_LINKER_FLAGS_<CONFIG>` variables learned to
+ support the ``LINKER:`` prefix.
+
+ This support implies to parse and re-quote the content of these variables.
+ This parsing is controlled by :policy:`CMP0181` policy.
diff --git a/Help/release/dev/ExternalProject-install-jobserver.rst b/Help/release/dev/ExternalProject-install-jobserver.rst
new file mode 100644
index 0000000..7d8116c
--- /dev/null
+++ b/Help/release/dev/ExternalProject-install-jobserver.rst
@@ -0,0 +1,7 @@
+ExternalProject-install-jobserver
+---------------------------------
+
+* The :module:`ExternalProject` module's :command:`ExternalProject_Add`
+ command gained an ``INSTALL_JOB_SERVER_AWARE`` option to enable
+ integration of the GNU Make job server when using an explicit
+ ``INSTALL_COMMAND`` with :ref:`Makefile Generators`.
diff --git a/Help/release/dev/FindGDAL-deprecate.rst b/Help/release/dev/FindGDAL-deprecate.rst
new file mode 100644
index 0000000..d6151dc
--- /dev/null
+++ b/Help/release/dev/FindGDAL-deprecate.rst
@@ -0,0 +1,8 @@
+FindGDAL-deprecate
+------------------
+
+* The :module:`FindGDAL` module is now deprecated in favor of upstream
+ GDAL's official CMake package configuration file. Port projects to
+ the latter by calling ``find_package(GDAL CONFIG)``. For further
+ details, see `GDAL's documentation on CMake integration
+ <https://gdal.org/en/latest/development/cmake.html>`_.
diff --git a/Help/release/dev/FindProtobuf-protoc-exe-option.rst b/Help/release/dev/FindProtobuf-protoc-exe-option.rst
new file mode 100644
index 0000000..93d60cb
--- /dev/null
+++ b/Help/release/dev/FindProtobuf-protoc-exe-option.rst
@@ -0,0 +1,5 @@
+FindProtobuf-protoc-exe-option
+------------------------------
+
+* The :module:`FindProtobuf` module :command:`protobuf_generate` command
+ gained a ``PROTOC_EXE`` option to specify a custom ``protoc`` executable.
diff --git a/Help/release/dev/STATIC_LIBRARY_OPTIONS-ARCHIVER-prefix.rst b/Help/release/dev/STATIC_LIBRARY_OPTIONS-ARCHIVER-prefix.rst
new file mode 100644
index 0000000..121e688
--- /dev/null
+++ b/Help/release/dev/STATIC_LIBRARY_OPTIONS-ARCHIVER-prefix.rst
@@ -0,0 +1,6 @@
+STATIC_LIBRARY_OPTIONS-ARCHIVER-prefix
+--------------------------------------
+
+* The :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property gains the support of
+ the ``ARCHIVER:`` prefix to pass options to the archiver through the compiler
+ driver in a portable way.
diff --git a/Help/release/dev/add_feature_info.rst b/Help/release/dev/add_feature_info.rst
new file mode 100644
index 0000000..776d804
--- /dev/null
+++ b/Help/release/dev/add_feature_info.rst
@@ -0,0 +1,6 @@
+add_feature_info
+----------------
+
+* The :module:`FeatureSummary` module :command:`add_feature_info`
+ command now supports full :ref:`Condition Syntax`.
+ See policy :policy:`CMP0183`.
diff --git a/Help/release/dev/aix-archive-shared-libraries.rst b/Help/release/dev/aix-archive-shared-libraries.rst
new file mode 100644
index 0000000..1a6cf65
--- /dev/null
+++ b/Help/release/dev/aix-archive-shared-libraries.rst
@@ -0,0 +1,5 @@
+aix-archive-shared-libraries
+----------------------------
+
+* On AIX, ``SHARED`` library targets now produce a shared library archive
+ by default. See policy :policy:`CMP0182`.
diff --git a/Help/release/dev/apple-compiler-selection.rst b/Help/release/dev/apple-compiler-selection.rst
new file mode 100644
index 0000000..79727df
--- /dev/null
+++ b/Help/release/dev/apple-compiler-selection.rst
@@ -0,0 +1,19 @@
+apple-compiler-selection
+------------------------
+
+* Builds targeting macOS no longer choose any SDK or pass an ``-isysroot``
+ flag to the compiler by default. Instead, compilers are expected to
+ choose a default macOS SDK on their own. In order to use a compiler that
+ does not do this, users must now specify ``-DCMAKE_OSX_SYSROOT=macosx``
+ when configuring their build.
+
+* On macOS with :ref:`Ninja Generators` and :ref:`Makefile Generators`, when
+ a compiler is found in ``/usr/bin``, it is now used as-is and is no longer
+ mapped to the corresponding compiler inside Xcode. The mapping was
+ introduced by CMake 3.2 to allow build trees to continue to work with their
+ original compiler even when ``xcode-select`` switches to a different
+ Xcode installation. However, the compilers inside Xcode cannot be used
+ without explicit ``-isysroot`` flags and are therefore not suitable for
+ passing to arbitrary third-party build systems. Furthermore, the mapping
+ behavior can override user-specified compiler paths. Therefore, this
+ behavior has been reverted.
diff --git a/Help/release/dev/ctest-crash-handling.rst b/Help/release/dev/ctest-crash-handling.rst
new file mode 100644
index 0000000..266706f
--- /dev/null
+++ b/Help/release/dev/ctest-crash-handling.rst
@@ -0,0 +1,7 @@
+ctest-crash-handling
+--------------------
+
+* The :option:`ctest --interactive-debug-mode` option on Windows
+ now enables Windows Error Reporting by default in test processes,
+ allowing them to creating debug popup windows and core dumps.
+ This restores behavior previously removed by CMake 3.11.
diff --git a/Help/release/dev/ctest-remove-declarative-script-mode.rst b/Help/release/dev/ctest-remove-declarative-script-mode.rst
new file mode 100644
index 0000000..c346abe
--- /dev/null
+++ b/Help/release/dev/ctest-remove-declarative-script-mode.rst
@@ -0,0 +1,14 @@
+ctest-remove-declarative-script-mode
+------------------------------------
+
+* CTest's declarative scripting mode has been removed. This mode used to be
+ triggered by a :option:`ctest -S` script which did not call any
+ :ref:`CTest Commands` unless :variable:`CTEST_RUN_CURRENT_SCRIPT` was
+ explicitly set to ``OFF``. This feature was undocumented and was not covered
+ by any unit tests.
+
+* The :variable:`CTEST_RUN_CURRENT_SCRIPT` variable no longer has any special
+ meaning.
+
+* The :command:`ctest_run_script` command may no longer be called without any
+ arguments.
diff --git a/Help/release/dev/link-warning-as-error.rst b/Help/release/dev/link-warning-as-error.rst
new file mode 100644
index 0000000..2e90630
--- /dev/null
+++ b/Help/release/dev/link-warning-as-error.rst
@@ -0,0 +1,11 @@
+link-warning-as-error
+---------------------
+
+* The :variable:`CMAKE_LINK_WARNING_AS_ERROR` variable and corresponding
+ :prop_tgt:`LINK_WARNING_AS_ERROR` target property were added to enable
+ link with a linker-specific flag to treat warnings as errors.
+* The :manual:`cmake(1)` command line gained the
+ :option:`--link-no-warning-as-error <cmake --link-no-warning-as-error>`
+ option which causes the effects of the :prop_tgt:`LINK_WARNING_AS_ERROR`
+ target property and :variable:`CMAKE_LINK_WARNING_AS_ERROR` variable to be
+ ignored.
diff --git a/Help/release/dev/target_link_libraries-LINKER-prefix.rst b/Help/release/dev/target_link_libraries-LINKER-prefix.rst
new file mode 100644
index 0000000..08f36af
--- /dev/null
+++ b/Help/release/dev/target_link_libraries-LINKER-prefix.rst
@@ -0,0 +1,5 @@
+target_link_libraries-LINKER-prefix
+-----------------------------------
+
+* The :command:`target_link_libraries` command gains the support of the
+ ``LINKER:`` prefix.
diff --git a/Help/release/dev/vs-custom-command-disable-parallel-build.rst b/Help/release/dev/vs-custom-command-disable-parallel-build.rst
new file mode 100644
index 0000000..1867a4a
--- /dev/null
+++ b/Help/release/dev/vs-custom-command-disable-parallel-build.rst
@@ -0,0 +1,6 @@
+vs-custom-command-disable-parallel-build
+----------------------------------------
+
+* The :prop_sf:`VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD` source file property
+ was added to tell :ref:`Visual Studio Generators` not to run a custom command
+ in parallel.
diff --git a/Help/release/dev/vs-solution-items.rst b/Help/release/dev/vs-solution-items.rst
new file mode 100644
index 0000000..35489bc
--- /dev/null
+++ b/Help/release/dev/vs-solution-items.rst
@@ -0,0 +1,6 @@
+vs-solution-items
+-----------------
+
+* The :prop_dir:`VS_SOLUTION_ITEMS` directory property was added
+ to tell :ref:`Visual Studio Generators` to attach files directly
+ to the Solution (``.sln``).
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 40767b7..101dd68 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Help/variable/BUILD_TESTING.rst b/Help/variable/BUILD_TESTING.rst
new file mode 100644
index 0000000..4d460b2
--- /dev/null
+++ b/Help/variable/BUILD_TESTING.rst
@@ -0,0 +1,27 @@
+BUILD_TESTING
+-------------
+
+Control whether the :module:`CTest` module invokes :command:`enable_testing`.
+
+The :module:`CTest` module, when loaded by ``include(CTest)``,
+runs code of the form:
+
+.. code-block:: cmake
+
+ option(BUILD_TESTING "..." ON)
+ if (BUILD_TESTING)
+ # ...
+ enable_testing()
+ # ...
+ endif()
+
+This creates a ``BUILD_TESTING`` option that controls whether the
+:command:`enable_testing` command is invoked to enable generation
+of tests to run using :manual:`ctest(1)`. See the :command:`add_test`
+command to create tests.
+
+.. note::
+
+ Call ``include(CTest)`` in the top-level source directory since
+ :manual:`ctest(1)` expects to find a test file in the top-level
+ build directory.
diff --git a/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst b/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst
index 2b636c0..88653b3 100644
--- a/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst
+++ b/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst
@@ -3,7 +3,7 @@
.. versionadded:: 3.31
-On AIX, enable creation of shared library archives.
+On AIX, enable or disable creation of shared library archives.
This variable initializes the :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE`
target property on non-imported ``SHARED`` library targets as they are
diff --git a/Help/variable/CMAKE_COLOR_DIAGNOSTICS.rst b/Help/variable/CMAKE_COLOR_DIAGNOSTICS.rst
index a72c9e1..85195cb 100644
--- a/Help/variable/CMAKE_COLOR_DIAGNOSTICS.rst
+++ b/Help/variable/CMAKE_COLOR_DIAGNOSTICS.rst
@@ -3,7 +3,7 @@
.. versionadded:: 3.24
-Enable color diagnostics throughout.
+Enable color diagnostics throughout the generated build system.
This variable uses three states: ``ON``, ``OFF`` and not defined.
@@ -35,3 +35,6 @@
If the :envvar:`CMAKE_COLOR_DIAGNOSTICS` environment variable is set, its
value is used. Otherwise, ``CMAKE_COLOR_DIAGNOSTICS`` is not defined by
default.
+
+See the :envvar:`CLICOLOR` and :envvar:`CLICOLOR_FORCE` environment
+variables to control color output from CMake command-line tools.
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst
index 9e108f8..a978d11 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst
@@ -4,3 +4,5 @@
Linker flags to be used to create executables.
These flags will be used by the linker when creating an executable.
+
+.. include:: ../variable/LINKER_FLAGS.txt
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
index 0cd8113..1d74077 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
@@ -5,3 +5,5 @@
Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating
executables.
+
+.. include:: ../variable/LINKER_FLAGS.txt
diff --git a/Help/variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG.rst b/Help/variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG.rst
new file mode 100644
index 0000000..404b4f1
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG.rst
@@ -0,0 +1,17 @@
+CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG
+----------------------------------
+
+.. versionadded:: 3.32
+
+Defines the syntax of compiler driver option to pass options to the archiver
+tool. It will be used to translate the ``ARCHIVER:`` prefix in the static
+library options (see :prop_tgt:`STATIC_LIBRARY_OPTIONS`).
+
+This variable holds a :ref:`semicolon-separated list <CMake Language Lists>` of
+tokens. If a space (i.e. " ") is specified as last token, flag and
+``ARCHIVER:`` arguments will be specified as separate arguments to the compiler
+driver. The :variable:`CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG_SEP` variable can be
+specified to manage concatenation of arguments.
+
+See :variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG` variable for examples of
+definitions because ``CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG`` use the same syntax.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG_SEP.rst b/Help/variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG_SEP.rst
new file mode 100644
index 0000000..43969f2
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_ARCHIVER_WRAPPER_FLAG_SEP.rst
@@ -0,0 +1,11 @@
+CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG_SEP
+--------------------------------------
+
+.. versionadded:: 3.32
+
+This variable is used with :variable:`CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG`
+variable to format ``ARCHIVER:`` prefix in the static library options
+(see :prop_tgt:`STATIC_LIBRARY_OPTIONS`).
+
+When specified, arguments of the ``ARCHIVER:`` prefix will be concatenated
+using this value as separator.
diff --git a/Help/variable/CMAKE_LINK_WARNING_AS_ERROR.rst b/Help/variable/CMAKE_LINK_WARNING_AS_ERROR.rst
new file mode 100644
index 0000000..7a64657
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_WARNING_AS_ERROR.rst
@@ -0,0 +1,9 @@
+CMAKE_LINK_WARNING_AS_ERROR
+---------------------------
+
+.. versionadded:: 3.32
+
+Specify whether to treat warnings on link as errors.
+
+This variable is used to initialize the
+:prop_tgt:`LINK_WARNING_AS_ERROR` property on all the targets.
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst
index 6372bbd..eed6b65 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst
@@ -4,3 +4,5 @@
Linker flags to be used to create modules.
These flags will be used by the linker when creating a module.
+
+.. include:: ../variable/LINKER_FLAGS.txt
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
index 393263e..fd0769c 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
@@ -4,3 +4,5 @@
Flags to be used when linking a module.
Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating modules.
+
+.. include:: ../variable/LINKER_FLAGS.txt
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst
index fce950c..45748ff 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst
@@ -4,3 +4,5 @@
Linker flags to be used to create shared libraries.
These flags will be used by the linker when creating a shared library.
+
+.. include:: ../variable/LINKER_FLAGS.txt
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
index 4bf87a0..b968820 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
@@ -5,3 +5,5 @@
Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating shared
libraries.
+
+.. include:: ../variable/LINKER_FLAGS.txt
diff --git a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
index 8cb6eaa..616324e 100644
--- a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
+++ b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
@@ -1,7 +1,5 @@
CTEST_RUN_CURRENT_SCRIPT
------------------------
-.. versionadded:: 3.11
-
-Setting this to 0 prevents :manual:`ctest(1)` from being run again when it
-reaches the end of a script run by calling :option:`ctest -S`.
+Removed. This variable once supported an undocumented feature that has since
+been removed.
diff --git a/Help/variable/LINKER_FLAGS.txt b/Help/variable/LINKER_FLAGS.txt
new file mode 100644
index 0000000..7b0630a
--- /dev/null
+++ b/Help/variable/LINKER_FLAGS.txt
@@ -0,0 +1,5 @@
+
+.. include:: ../command/LINK_LIBRARIES_LINKER.txt
+
+This support implies to parse and re-quote the content of the variable. See
+policy :policy:`CMP0181`.
diff --git a/Modules/CMakeBackwardCompatibilityC.cmake b/Modules/CMakeBackwardCompatibilityC.cmake
index 775a513..ef06a2d 100644
--- a/Modules/CMakeBackwardCompatibilityC.cmake
+++ b/Modules/CMakeBackwardCompatibilityC.cmake
@@ -73,4 +73,3 @@
CMAKE_X_CFLAGS
CMAKE_X_LIBS
)
-
diff --git a/Modules/CMakeBackwardCompatibilityCXX.cmake b/Modules/CMakeBackwardCompatibilityCXX.cmake
index 02744a9..815d483 100644
--- a/Modules/CMakeBackwardCompatibilityCXX.cmake
+++ b/Modules/CMakeBackwardCompatibilityCXX.cmake
@@ -46,4 +46,3 @@
include(TestForSSTREAM)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_SAVE}")
endif()
-
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index fc0b714..6036897 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -82,34 +82,6 @@
endif()
unset(_${lang}_COMPILER_HINTS)
unset(_languages)
-
- # Look for a make tool provided by Xcode
- if(CMAKE_HOST_APPLE)
- macro(_query_xcrun compiler_name result_var_keyword result_var)
- if(NOT "x${result_var_keyword}" STREQUAL "xRESULT_VAR")
- message(FATAL_ERROR "Bad arguments to macro")
- endif()
- execute_process(COMMAND xcrun --find ${compiler_name}
- OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _xcrun_err)
- set("${result_var}" "${_xcrun_out}")
- endmacro()
-
- set(xcrun_result)
- if (CMAKE_${lang}_COMPILER MATCHES "^/usr/bin/(.+)$")
- _query_xcrun("${CMAKE_MATCH_1}" RESULT_VAR xcrun_result)
- elseif (CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND")
- foreach(comp IN LISTS CMAKE_${lang}_COMPILER_LIST)
- _query_xcrun("${comp}" RESULT_VAR xcrun_result)
- if(xcrun_result)
- break()
- endif()
- endforeach()
- endif()
- if (xcrun_result)
- set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${xcrun_result}")
- endif()
- endif()
endmacro()
macro(_cmake_find_compiler_path lang)
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 4a75e25..806f0b7 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -52,14 +52,21 @@
__TestCompiler_setTryCompileTargetType()
- # Avoid failing ABI detection on warnings.
+ # Avoid failing ABI detection caused by non-functionally relevant
+ # compiler arguments
if(CMAKE_TRY_COMPILE_CONFIGURATION)
string(TOUPPER "${CMAKE_TRY_COMPILE_CONFIGURATION}" _tc_config)
else()
set(_tc_config "DEBUG")
endif()
foreach(v CMAKE_${lang}_FLAGS CMAKE_${lang}_FLAGS_${_tc_config})
+ # Avoid failing ABI detection on warnings.
string(REGEX REPLACE "(^| )-Werror([= ][^-][^ ]*)?( |$)" " " ${v} "${${v}}")
+ # Avoid passing of "-pipe" when determining the compiler internals. With
+ # "-pipe" GCC will use pipes to pass data between the involved
+ # executables. This may lead to issues when their stderr output (which
+ # contains the relevant compiler internals) becomes interweaved.
+ string(REGEX REPLACE "(^| )-pipe( |$)" " " ${v} "${${v}}")
endforeach()
# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
diff --git a/Modules/CMakeUnixFindMake.cmake b/Modules/CMakeUnixFindMake.cmake
index 1165656..58dedee 100644
--- a/Modules/CMakeUnixFindMake.cmake
+++ b/Modules/CMakeUnixFindMake.cmake
@@ -4,13 +4,3 @@
find_program(CMAKE_MAKE_PROGRAM NAMES gmake make smake)
mark_as_advanced(CMAKE_MAKE_PROGRAM)
-
-# Look for a make tool provided by Xcode
-if(NOT CMAKE_MAKE_PROGRAM AND CMAKE_HOST_APPLE)
- execute_process(COMMAND xcrun --find make
- OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _xcrun_err)
- if(_xcrun_out)
- set_property(CACHE CMAKE_MAKE_PROGRAM PROPERTY VALUE "${_xcrun_out}")
- endif()
-endif()
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 16283d6..6829d66 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -8,15 +8,24 @@
Configure a project for testing with CTest/CDash
Include this module in the top CMakeLists.txt file of a project to
-enable testing with CTest and dashboard submissions to CDash::
+enable testing with CTest and dashboard submissions to CDash:
+
+.. code-block:: cmake
project(MyProject)
...
include(CTest)
-The module automatically creates a ``BUILD_TESTING`` option that selects
-whether to enable testing support (``ON`` by default). After including
-the module, use code like::
+The module automatically creates the following variables:
+
+:variable:`BUILD_TESTING`
+
+ Option selecting whether ``include(CTest)`` calls :command:`enable_testing`.
+ The option is ``ON`` by default when created by the module.
+
+After including the module, use code like:
+
+.. code-block:: cmake
if(BUILD_TESTING)
# ... CMake code to create tests ...
@@ -25,7 +34,9 @@
to creating tests when testing is enabled.
To enable submissions to a CDash server, create a ``CTestConfig.cmake``
-file at the top of the project with content such as::
+file at the top of the project with content such as:
+
+.. code-block:: cmake
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject")
@@ -40,7 +51,9 @@
context from the build log. This generic approach works for all build
tools, but does not give details about the command invocation that
produced a given problem. One may get more detailed reports by setting
-the :variable:`CTEST_USE_LAUNCHERS` variable::
+the :variable:`CTEST_USE_LAUNCHERS` variable:
+
+.. code-block:: cmake
set(CTEST_USE_LAUNCHERS 1)
diff --git a/Modules/CTestScriptMode.cmake b/Modules/CTestScriptMode.cmake
index 7af3577..b4bb535 100644
--- a/Modules/CTestScriptMode.cmake
+++ b/Modules/CTestScriptMode.cmake
@@ -17,4 +17,3 @@
# Also load the system specific file, which sets up e.g. the search paths.
# This makes the FIND_XXX() calls work much better
include(CMakeSystemSpecificInformation)
-
diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake
index 452348b..385bc5a 100644
--- a/Modules/CheckPIESupported.cmake
+++ b/Modules/CheckPIESupported.cmake
@@ -120,6 +120,8 @@
foreach(lang IN LISTS CHECK_PIE_LANGUAGES)
if(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER)
if(NOT DEFINED CMAKE_${lang}_LINK_PIE_SUPPORTED)
+ # ensure PIE compile flags are also used
+ list(JOIN CMAKE_${lang}_COMPILE_OPTIONS_PIE " " CMAKE_REQUIRED_FLAGS)
cmake_check_linker_flag(${lang}
"${CMAKE_${lang}_LINK_OPTIONS_PIE}"
CMAKE_${lang}_LINK_PIE_SUPPORTED
@@ -127,6 +129,7 @@
if (NOT CMAKE_${lang}_LINK_PIE_SUPPORTED)
string (APPEND outputs "PIE (${lang}): ${output}\n")
endif()
+ unset(CMAKE_REQUIRED_FLAGS)
endif()
if(NOT DEFINED CMAKE_${lang}_LINK_NO_PIE_SUPPORTED)
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index ee54d92..c2e131c 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -54,6 +54,7 @@
``LANGUAGE <language>``
Use the ``<language>`` compiler to perform the check.
Acceptable values are ``C`` and ``CXX``.
+ If not specified, it defaults to ``C``.
Despite the name of the macro you may use it to check the size of more
complex expressions, too. To check e.g. for the size of a struct
@@ -83,6 +84,62 @@
``CMAKE_EXTRA_INCLUDE_FILES``
list of extra headers to include.
+
+Examples
+^^^^^^^^
+
+Consider the code:
+
+.. code-block:: cmake
+
+ include(CheckTypeSize)
+
+ # Check for size of long.
+ check_type_size(long SIZEOF_LONG)
+ message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
+ message("SIZEOF_LONG: ${SIZEOF_LONG}")
+ message("SIZEOF_LONG_CODE: ${SIZEOF_LONG_CODE}")
+
+On a 64-bit architecture, the output may look something like this::
+
+ HAVE_SIZEOF_LONG: TRUE
+ SIZEOF_LONG: 8
+ SIZEOF_LONG_CODE: #define SIZEOF_LONG 8
+
+On Apple platforms, when :variable:`CMAKE_OSX_ARCHITECTURES` has multiple
+architectures, types may have architecture-dependent sizes.
+For example, with the code
+
+.. code-block:: cmake
+
+ include(CheckTypeSize)
+
+ check_type_size(long SIZEOF_LONG)
+ message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
+ message("SIZEOF_LONG: ${SIZEOF_LONG}")
+ foreach(key IN LISTS SIZE_OF_LONG_KEYS)
+ message("key: ${key}")
+ message("value: ${SIZE_OF_LONG-${key}}")
+ endforeach()
+ message("SIZEOF_LONG_CODE:
+ ${SIZEOF_LONG_CODE}")
+
+the result may be::
+
+ HAVE_SIZEOF_LONG: TRUE
+ SIZEOF_LONG: 0
+ key: __i386
+ value: 4
+ key: __x86_64
+ value: 8
+ SIZEOF_LONG_CODE:
+ #if defined(__i386)
+ # define SIZE_OF_LONG 4
+ #elif defined(__x86_64)
+ # define SIZE_OF_LONG 8
+ #else
+ # error SIZE_OF_LONG unknown
+ #endif
#]=======================================================================]
include(CheckIncludeFile)
diff --git a/Modules/Compiler/ARMClang.cmake b/Modules/Compiler/ARMClang.cmake
index c839220..87a41b9 100644
--- a/Modules/Compiler/ARMClang.cmake
+++ b/Modules/Compiler/ARMClang.cmake
@@ -135,7 +135,7 @@
else()
set(__CMAKE_ARMClang_USING_armlink_WRAPPER "-Xlinker")
endif()
- set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER} --list=<TARGET_BASE>.map")
+ set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER}")
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "${__CMAKE_ARMClang_USING_armlink_WRAPPER} --via=")
diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake
index 317cfc7..367d26e 100644
--- a/Modules/Compiler/Intel.cmake
+++ b/Modules/Compiler/Intel.cmake
@@ -30,6 +30,9 @@
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g")
+ # Compiler + IPO does not recognize --dependency-file link option
+ set(CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED FALSE)
+
if("${lang}" STREQUAL "CXX")
set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
if(CMAKE_${lang}_COMPILER_ARG1)
diff --git a/Modules/Dart.cmake b/Modules/Dart.cmake
index 3610012..3a6afd5 100644
--- a/Modules/Dart.cmake
+++ b/Modules/Dart.cmake
@@ -141,4 +141,3 @@
#
# End of Dart.cmake
#
-
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 3f43542..7d95bdf 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -749,6 +749,14 @@
install step's own underlying call to :command:`add_custom_command`, which
has additional documentation.
+``INSTALL_JOB_SERVER_AWARE <bool>``
+ .. versionadded:: 3.32
+
+ Specifies that the install step is aware of the GNU Make job server.
+ See the :command:`add_custom_command` documentation of its
+ ``JOB_SERVER_AWARE`` option for details. This option is relevant
+ only when an explicit ``INSTALL_COMMAND`` is specified.
+
.. note::
If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
main project is built, it will only have an effect if the following
@@ -2819,6 +2827,16 @@
PROPERTY _EP_INSTALL_BYPRODUCTS
)
+ get_property(install_job_server_aware
+ TARGET ${name}
+ PROPERTY _EP_INSTALL_JOB_SERVER_AWARE
+ )
+ if(install_job_server_aware)
+ set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
+ else()
+ set(maybe_JOB_SERVER_AWARE "")
+ endif()
+
set(__cmdQuoted)
foreach(__item IN LISTS cmd)
string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -2831,6 +2849,7 @@
WORKING_DIRECTORY \${binary_dir}
DEPENDEES build
ALWAYS \${always}
+ ${maybe_JOB_SERVER_AWARE}
${log}
${uses_terminal}
)"
diff --git a/Modules/ExternalProject/shared_internal_commands.cmake b/Modules/ExternalProject/shared_internal_commands.cmake
index 149a8a7..ac5d2bd 100644
--- a/Modules/ExternalProject/shared_internal_commands.cmake
+++ b/Modules/ExternalProject/shared_internal_commands.cmake
@@ -1934,6 +1934,7 @@
#
INSTALL_COMMAND
INSTALL_BYPRODUCTS
+ INSTALL_JOB_SERVER_AWARE
#
# Test step options
#
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index 009ca38..f728554 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -627,6 +627,10 @@
.. versionchanged:: 3.8
``<enabled>`` can be a list of conditions.
+ .. versionchanged:: 3.32
+ Full :ref:`Condition Syntax` is now supported for ``<enabled>``.
+ See policy :policy:`CMP0183`.
+
Example for setting the info for a feature:
.. code-block:: cmake
@@ -635,15 +639,29 @@
add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
#]=======================================================================]
function(ADD_FEATURE_INFO _name _depends _desc)
+ cmake_policy(GET CMP0183 _CDO_CMP0183
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
set(_enabled 1)
- foreach(_d ${_depends})
- string(REGEX REPLACE " +" ";" _d "${_d}")
- if(${_d})
- else()
- set(_enabled 0)
- break()
- endif()
- endforeach()
+ if("x${_CDO_CMP0183}x" STREQUAL "xNEWx")
+ foreach(_d ${_depends})
+ cmake_language(EVAL CODE "
+ if(${_d})
+ else()
+ set(_enabled 0)
+ endif()"
+ )
+ endforeach()
+ else()
+ foreach(_d ${_depends})
+ string(REGEX REPLACE " +" ";" _d "${_d}")
+ if(${_d})
+ else()
+ set(_enabled 0)
+ break()
+ endif()
+ endforeach()
+ endif()
if (${_enabled})
set_property(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
else ()
@@ -651,6 +669,12 @@
endif ()
set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
+
+ if("x${_CDO_CMP0183}x" STREQUAL "xx" AND "x${_depends}x" MATCHES "[^A-Za-z0-9_.; ]")
+ cmake_policy(GET_WARNING CMP0183 _CDO_CMP0183_WARNING)
+ message(AUTHOR_WARNING "${_CDO_CMP0183_WARNING}")
+ endif()
+ unset(_CDO_CMP0183)
endfunction()
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
index 3515bf0..6d0ace7 100644
--- a/Modules/FindBISON.cmake
+++ b/Modules/FindBISON.cmake
@@ -281,7 +281,8 @@
VERBATIM
DEPENDS ${_BisonInput}
COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
- WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY})
+ WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY}
+ COMMAND_EXPAND_LISTS)
unset(_BISON_WORKING_DIRECTORY)
diff --git a/Modules/FindCUDA/parse_cubin.cmake b/Modules/FindCUDA/parse_cubin.cmake
index 626c8a2..25ceb49 100644
--- a/Modules/FindCUDA/parse_cubin.cmake
+++ b/Modules/FindCUDA/parse_cubin.cmake
@@ -107,5 +107,3 @@
else()
# message("FOUND NO DEPENDS")
endif()
-
-
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index 5ce8a90..f736130 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -239,9 +239,24 @@
IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}")
endif()
- if(CURL_USE_STATIC_LIBS AND MSVC)
- set_target_properties(CURL::libcurl PROPERTIES
- INTERFACE_LINK_LIBRARIES "normaliz.lib;ws2_32.lib;wldap32.lib")
+ if(PC_CURL_FOUND)
+ if(PC_CURL_LINK_LIBRARIES)
+ set_property(TARGET CURL::libcurl PROPERTY
+ INTERFACE_LINK_LIBRARIES "${PC_CURL_LINK_LIBRARIES}")
+ endif()
+ if(PC_CURL_LDFLAGS_OTHER)
+ set_property(TARGET CURL::libcurl PROPERTY
+ INTERFACE_LINK_OPTIONS "${PC_CURL_LDFLAGS_OTHER}")
+ endif()
+ if(PC_CURL_CFLAGS_OTHER)
+ set_property(TARGET CURL::libcurl PROPERTY
+ INTERFACE_COMPILE_OPTIONS "${PC_CURL_CFLAGS_OTHER}")
+ endif()
+ else()
+ if(CURL_USE_STATIC_LIBS AND MSVC)
+ set_target_properties(CURL::libcurl PROPERTIES
+ INTERFACE_LINK_LIBRARIES "normaliz.lib;ws2_32.lib;wldap32.lib")
+ endif()
endif()
endif()
diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake
index a9c5740..b600e58 100644
--- a/Modules/FindGDAL.cmake
+++ b/Modules/FindGDAL.cmake
@@ -7,6 +7,12 @@
Find Geospatial Data Abstraction Library (GDAL).
+.. deprecated:: 3.32
+ GDAL 3.5 and above provide a ``GDALConfig.cmake`` package configuration file.
+ Call ``find_package(GDAL CONFIG)`` to find it directly and avoid using this
+ find module. For further details, see `GDAL's documentation on CMake
+ integration <https://gdal.org/en/latest/development/cmake.html>`_.
+
IMPORTED Targets
^^^^^^^^^^^^^^^^
@@ -184,6 +190,18 @@
set(GDAL_VERSION GDAL_VERSION-NOTFOUND)
endif ()
+if (GDAL_FIND_VERSION VERSION_GREATER_EQUAL 3.5)
+ message(DEPRECATION
+ "The FindGDAL module is deprecated. "
+ "GDAL 3.5 and above provide a CMake package configuration file. "
+ "Since at least version ${GDAL_FIND_VERSION} is requested, this "
+ "project can be ported to find GDAL's CMake package directly:\n"
+ " find_package(GDAL CONFIG)\n"
+ "For further details, see:\n"
+ " https://gdal.org/en/latest/development/cmake.html\n"
+ )
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL
VERSION_VAR GDAL_VERSION
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index c6db433..ffa187b 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -203,10 +203,10 @@
find_package_check_version(1.2.3 result HANDLE_VERSION_RANGE
RESULT_MESSAGE_VARIABLE reason)
- if (result)
- message (STATUS "${reason}")
+ if(result)
+ message(STATUS "${reason}")
else()
- message (FATAL_ERROR "${reason}")
+ message(FATAL_ERROR "${reason}")
endif()
#]=======================================================================]
@@ -215,27 +215,27 @@
cmake_policy(PUSH)
# numbers and boolean constants
-cmake_policy (SET CMP0012 NEW)
+cmake_policy(SET CMP0012 NEW)
# IN_LIST operator
-cmake_policy (SET CMP0057 NEW)
+cmake_policy(SET CMP0057 NEW)
# internal helper macro
macro(_FPHSA_FAILURE_MESSAGE _msg)
- set (__msg "${_msg}")
- if (FPHSA_REASON_FAILURE_MESSAGE)
+ set(__msg "${_msg}")
+ if(FPHSA_REASON_FAILURE_MESSAGE)
string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n")
elseif(NOT DEFINED PROJECT_NAME)
string(APPEND __msg "\n"
"Hint: The project() command has not yet been called. It sets up system-specific search paths.")
endif()
- if (${_NAME}_FIND_REQUIRED)
+ if(${_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "${__msg}")
- else ()
- if (NOT ${_NAME}_FIND_QUIETLY)
+ else()
+ if(NOT ${_NAME}_FIND_QUIETLY)
message(STATUS "${__msg}")
- endif ()
- endif ()
+ endif()
+ endif()
endmacro()
@@ -249,15 +249,11 @@
# List them all in the error message:
if(${_NAME}_CONSIDERED_CONFIGS)
set(configsText "")
- list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
- math(EXPR configsCount "${configsCount} - 1")
- foreach(currentConfigIndex RANGE ${configsCount})
- list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
- list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
+ foreach(filename version IN ZIP_LISTS ${_NAME}_CONSIDERED_CONFIGS ${_NAME}_CONSIDERED_VERSIONS)
string(APPEND configsText "\n ${filename} (version ${version})")
endforeach()
- if (${_NAME}_NOT_FOUND_MESSAGE)
- if (FPHSA_REASON_FAILURE_MESSAGE)
+ if(${_NAME}_NOT_FOUND_MESSAGE)
+ if(FPHSA_REASON_FAILURE_MESSAGE)
string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n ")
else()
set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}")
@@ -276,101 +272,100 @@
function(FIND_PACKAGE_CHECK_VERSION version result)
- cmake_parse_arguments (PARSE_ARGV 2 FPCV "HANDLE_VERSION_RANGE;NO_AUTHOR_WARNING_VERSION_RANGE" "RESULT_MESSAGE_VARIABLE" "")
+ cmake_parse_arguments(PARSE_ARGV 2 FPCV "HANDLE_VERSION_RANGE;NO_AUTHOR_WARNING_VERSION_RANGE" "RESULT_MESSAGE_VARIABLE" "")
- if (FPCV_UNPARSED_ARGUMENTS)
- message (FATAL_ERROR "find_package_check_version(): ${FPCV_UNPARSED_ARGUMENTS}: unexpected arguments")
+ if(FPCV_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "find_package_check_version(): ${FPCV_UNPARSED_ARGUMENTS}: unexpected arguments")
endif()
- if ("RESULT_MESSAGE_VARIABLE" IN_LIST FPCV_KEYWORDS_MISSING_VALUES)
- message (FATAL_ERROR "find_package_check_version(): RESULT_MESSAGE_VARIABLE expects an argument")
+ if("RESULT_MESSAGE_VARIABLE" IN_LIST FPCV_KEYWORDS_MISSING_VALUES)
+ message(FATAL_ERROR "find_package_check_version(): RESULT_MESSAGE_VARIABLE expects an argument")
endif()
- set (${result} FALSE PARENT_SCOPE)
- if (FPCV_RESULT_MESSAGE_VARIABLE)
+ set(${result} FALSE PARENT_SCOPE)
+ if(FPCV_RESULT_MESSAGE_VARIABLE)
unset (${FPCV_RESULT_MESSAGE_VARIABLE} PARENT_SCOPE)
endif()
- if (_CMAKE_FPHSA_PACKAGE_NAME)
- set (package "${_CMAKE_FPHSA_PACKAGE_NAME}")
- elseif (CMAKE_FIND_PACKAGE_NAME)
- set (package "${CMAKE_FIND_PACKAGE_NAME}")
+ if(_CMAKE_FPHSA_PACKAGE_NAME)
+ set(package "${_CMAKE_FPHSA_PACKAGE_NAME}")
+ elseif(CMAKE_FIND_PACKAGE_NAME)
+ set(package "${CMAKE_FIND_PACKAGE_NAME}")
else()
- message (FATAL_ERROR "find_package_check_version(): Cannot be used outside a 'Find Module'")
+ message(FATAL_ERROR "find_package_check_version(): Cannot be used outside a 'Find Module'")
endif()
- if (NOT FPCV_NO_AUTHOR_WARNING_VERSION_RANGE
+ if(NOT FPCV_NO_AUTHOR_WARNING_VERSION_RANGE
AND ${package}_FIND_VERSION_RANGE AND NOT FPCV_HANDLE_VERSION_RANGE)
message(AUTHOR_WARNING
- "`find_package()` specify a version range but the option "
- "HANDLE_VERSION_RANGE` is not passed to `find_package_check_version()`. "
+ "find_package() specify a version range but the option "
+ "HANDLE_VERSION_RANGE` is not passed to find_package_check_version(). "
"Only the lower endpoint of the range will be used.")
endif()
-
- set (version_ok FALSE)
+ set(version_ok FALSE)
unset (version_msg)
- if (FPCV_HANDLE_VERSION_RANGE AND ${package}_FIND_VERSION_RANGE)
- if ((${package}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE"
+ if(FPCV_HANDLE_VERSION_RANGE AND ${package}_FIND_VERSION_RANGE)
+ if((${package}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE"
AND version VERSION_GREATER_EQUAL ${package}_FIND_VERSION_MIN)
AND ((${package}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE"
AND version VERSION_LESS_EQUAL ${package}_FIND_VERSION_MAX)
OR (${package}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE"
AND version VERSION_LESS ${package}_FIND_VERSION_MAX)))
- set (version_ok TRUE)
+ set(version_ok TRUE)
set(version_msg "(found suitable version \"${version}\", required range is \"${${package}_FIND_VERSION_RANGE}\")")
else()
set(version_msg "Found unsuitable version \"${version}\", required range is \"${${package}_FIND_VERSION_RANGE}\"")
endif()
- elseif (DEFINED ${package}_FIND_VERSION)
+ elseif(DEFINED ${package}_FIND_VERSION)
if(${package}_FIND_VERSION_EXACT) # exact version required
# count the dots in the version string
string(REGEX REPLACE "[^.]" "" version_dots "${version}")
# add one dot because there is one dot more than there are components
string(LENGTH "${version_dots}." version_dots)
- if (version_dots GREATER ${package}_FIND_VERSION_COUNT)
+ if(version_dots GREATER ${package}_FIND_VERSION_COUNT)
# Because of the C++ implementation of find_package() ${package}_FIND_VERSION_COUNT
# is at most 4 here. Therefore a simple lookup table is used.
- if (${package}_FIND_VERSION_COUNT EQUAL 1)
+ if(${package}_FIND_VERSION_COUNT EQUAL 1)
set(version_regex "[^.]*")
- elseif (${package}_FIND_VERSION_COUNT EQUAL 2)
+ elseif(${package}_FIND_VERSION_COUNT EQUAL 2)
set(version_regex "[^.]*\\.[^.]*")
- elseif (${package}_FIND_VERSION_COUNT EQUAL 3)
+ elseif(${package}_FIND_VERSION_COUNT EQUAL 3)
set(version_regex "[^.]*\\.[^.]*\\.[^.]*")
else()
set(version_regex "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
endif()
string(REGEX REPLACE "^(${version_regex})\\..*" "\\1" version_head "${version}")
- if (NOT ${package}_FIND_VERSION VERSION_EQUAL version_head)
+ if(NOT ${package}_FIND_VERSION VERSION_EQUAL version_head)
set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"")
- else ()
+ else()
set(version_ok TRUE)
set(version_msg "(found suitable exact version \"${version}\")")
- endif ()
- else ()
- if (NOT ${package}_FIND_VERSION VERSION_EQUAL version)
+ endif()
+ else()
+ if(NOT ${package}_FIND_VERSION VERSION_EQUAL version)
set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"")
- else ()
+ else()
set(version_ok TRUE)
set(version_msg "(found suitable exact version \"${version}\")")
- endif ()
- endif ()
+ endif()
+ endif()
else() # minimum version
- if (${package}_FIND_VERSION VERSION_GREATER version)
+ if(${package}_FIND_VERSION VERSION_GREATER version)
set(version_msg "Found unsuitable version \"${version}\", but required is at least \"${${package}_FIND_VERSION}\"")
else()
set(version_ok TRUE)
set(version_msg "(found suitable version \"${version}\", minimum required is \"${${package}_FIND_VERSION}\")")
endif()
endif()
- else ()
+ else()
set(version_ok TRUE)
set(version_msg "(found version \"${version}\")")
endif()
- set (${result} ${version_ok} PARENT_SCOPE)
- if (FPCV_RESULT_MESSAGE_VARIABLE)
- set (${FPCV_RESULT_MESSAGE_VARIABLE} "${version_msg}" PARENT_SCOPE)
+ set(${result} ${version_ok} PARENT_SCOPE)
+ if(FPCV_RESULT_MESSAGE_VARIABLE)
+ set(${FPCV_RESULT_MESSAGE_VARIABLE} "${version_msg}" PARENT_SCOPE)
endif()
endfunction()
@@ -387,21 +382,21 @@
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
unset(FPHSA_NAME_MISMATCHED_override)
- if (DEFINED FPHSA_NAME_MISMATCHED)
+ if(DEFINED FPHSA_NAME_MISMATCHED)
# If the variable NAME_MISMATCHED variable is set, error if it is passed as
# an argument. The former is for old signatures, the latter is for new
# signatures.
list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx)
- if (NOT name_mismatched_idx EQUAL "-1")
+ if(NOT name_mismatched_idx EQUAL "-1")
message(FATAL_ERROR
- "The `NAME_MISMATCHED` argument may only be specified by the argument or "
+ "The NAME_MISMATCHED argument may only be specified by the argument or "
"the variable, not both.")
- endif ()
+ endif()
# But use the variable if it is not an argument to avoid forcing minimum
# CMake version bumps for calling modules.
set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}")
- endif ()
+ endif()
if(${INDEX} EQUAL -1)
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
@@ -411,7 +406,7 @@
cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
if(FPHSA_UNPARSED_ARGUMENTS)
- message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
+ message(FATAL_ERROR "Unknown keywords given to find_package_handle_standard_args(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
endif()
if(NOT FPHSA_FAIL_MESSAGE)
@@ -427,28 +422,28 @@
endif()
if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS)
- message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
+ message(FATAL_ERROR "No REQUIRED_VARS specified for find_package_handle_standard_args()")
endif()
endif()
- if (DEFINED FPHSA_NAME_MISMATCHED_override)
+ if(DEFINED FPHSA_NAME_MISMATCHED_override)
set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}")
- endif ()
+ endif()
- if (DEFINED CMAKE_FIND_PACKAGE_NAME
+ if(DEFINED CMAKE_FIND_PACKAGE_NAME
AND NOT FPHSA_NAME_MISMATCHED
AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME)
message(AUTHOR_WARNING
- "The package name passed to `find_package_handle_standard_args` "
+ "The package name passed to find_package_handle_standard_args() "
"(${_NAME}) does not match the name of the calling package "
"(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling "
- "code that expects `find_package` result variables (e.g., `_FOUND`) "
+ "code that expects find_package() result variables (e.g., `_FOUND`) "
"to follow a certain pattern.")
- endif ()
+ endif()
- if (${_NAME}_FIND_VERSION_RANGE AND NOT FPHSA_HANDLE_VERSION_RANGE)
+ if(${_NAME}_FIND_VERSION_RANGE AND NOT FPHSA_HANDLE_VERSION_RANGE)
message(AUTHOR_WARNING
- "`find_package()` specify a version range but the module ${_NAME} does "
+ "find_package() specify a version range but the module ${_NAME} does "
"not support this capability. Only the lower endpoint of the range "
"will be used.")
endif()
@@ -462,7 +457,7 @@
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
endif()
- if (FPHSA_REQUIRED_VARS)
+ if(FPHSA_REQUIRED_VARS)
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
endif()
@@ -531,7 +526,7 @@
endif()
endforeach()
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
- string(APPEND DETAILS "[c${COMPONENT_MSG}]")
+ string(APPEND DETAILS "[${COMPONENT_MSG}]")
endif()
# version handling:
@@ -539,17 +534,17 @@
set(VERSION_OK TRUE)
# check that the version variable is not empty to avoid emitting a misleading
- # message (i.e. `Found unsuitable version ""`)
- if (DEFINED ${_NAME}_FIND_VERSION)
+ # message(i.e. `Found unsuitable version ""`)
+ if(DEFINED ${_NAME}_FIND_VERSION)
if(DEFINED ${FPHSA_VERSION_VAR})
if(NOT "${${FPHSA_VERSION_VAR}}" STREQUAL "")
set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
- if (FPHSA_HANDLE_VERSION_RANGE)
- set (FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE)
+ if(FPHSA_HANDLE_VERSION_RANGE)
+ set(FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE)
else()
set(FPCV_HANDLE_VERSION_RANGE NO_AUTHOR_WARNING_VERSION_RANGE)
endif()
- find_package_check_version ("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG
+ find_package_check_version("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG
${FPCV_HANDLE_VERSION_RANGE})
else()
set(VERSION_OK FALSE)
@@ -559,18 +554,18 @@
# if the package was not found, but a version was given, add that to the output:
if(${_NAME}_FIND_VERSION_EXACT)
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
- elseif (FPHSA_HANDLE_VERSION_RANGE AND ${_NAME}_FIND_VERSION_RANGE)
+ elseif(FPHSA_HANDLE_VERSION_RANGE AND ${_NAME}_FIND_VERSION_RANGE)
set(VERSION_MSG "(Required is version range \"${${_NAME}_FIND_VERSION_RANGE}\")")
else()
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
endif()
endif()
- else ()
+ else()
# Check with DEFINED as the found version may be 0.
if(DEFINED ${FPHSA_VERSION_VAR})
set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
endif()
- endif ()
+ endif()
if(VERSION_OK)
string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
@@ -580,23 +575,23 @@
# print the result:
- if (${_NAME}_FOUND)
+ if(${_NAME}_FOUND)
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
- else ()
+ else()
if(FPHSA_CONFIG_MODE)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
else()
if(NOT VERSION_OK)
set(RESULT_MSG)
- if (_FIRST_REQUIRED_VAR)
- string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}")
+ if(_FIRST_REQUIRED_VAR)
+ string(APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}")
endif()
- if (COMPONENT_MSG)
- if (RESULT_MSG)
- string (APPEND RESULT_MSG ", ")
+ if(COMPONENT_MSG)
+ if(RESULT_MSG)
+ string(APPEND RESULT_MSG ", ")
endif()
- string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}")
+ string(APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}")
endif()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})")
else()
@@ -604,7 +599,7 @@
endif()
endif()
- endif ()
+ endif()
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 450acf4..372cab5 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -730,7 +730,7 @@
When the ``QUIET`` argument is given, no status messages will be printed.
- .. versionadded:: 3.1
+ .. versionadded:: 3.3
The :variable:`CMAKE_PREFIX_PATH`,
:variable:`CMAKE_FRAMEWORK_PATH`, and :variable:`CMAKE_APPBUNDLE_PATH` cache
and environment variables will be added to the ``pkg-config`` search path.
@@ -740,14 +740,14 @@
The :variable:`PKG_CONFIG_USE_CMAKE_PREFIX_PATH` variable set to ``FALSE``
disables this behavior globally.
- .. This didn't actually work until 3.3.
+ .. This was actually added in 3.1, but didn't work until 3.3.
- .. versionadded:: 3.6
+ .. versionadded:: 3.7
The ``IMPORTED_TARGET`` argument will create an imported target named
``PkgConfig::<prefix>`` that can be passed directly as an argument to
:command:`target_link_libraries`.
- .. This didn't actually work until 3.7.
+ .. This was actually added in 3.6, but didn't work until 3.7.
.. versionadded:: 3.13
The ``GLOBAL`` argument will make the
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 197e71f..1d69c57 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -108,20 +108,27 @@
Add custom commands to process ``.proto`` files to C++::
- protobuf_generate_cpp (<SRCS> <HDRS>
- [DESCRIPTORS <DESC>] [EXPORT_MACRO <MACRO>] [<ARGN>...])
+ protobuf_generate_cpp (
+ <srcs-var> <hdrs-var>
+ [DESCRIPTORS <var>]
+ [EXPORT_MACRO <macro>]
+ [<proto-file>...])
- ``SRCS``
+ ``<srcs-var>``
Variable to define with autogenerated source files
- ``HDRS``
+
+ ``<hdrs-var>``
Variable to define with autogenerated header files
- ``DESCRIPTORS``
+
+ ``DESCRIPTORS <var>``
.. versionadded:: 3.10
Variable to define with autogenerated descriptor files, if requested.
- ``EXPORT_MACRO``
+
+ ``EXPORT_MACRO <macro>``
is a macro which should expand to ``__declspec(dllexport)`` or
``__declspec(dllimport)`` depending on what is being compiled.
- ``ARGN``
+
+ ``<proto-file>...``
``.proto`` files
.. command:: protobuf_generate_python
@@ -130,11 +137,12 @@
Add custom commands to process ``.proto`` files to Python::
- protobuf_generate_python (<PY> [<ARGN>...])
+ protobuf_generate_python (<py-srcs-var> [<proto-file>...])
- ``PY``
+ ``<py-srcs-var>``
Variable to define with autogenerated Python files
- ``ARGN``
+
+ ``<proto-file>...``
``.proto`` files
.. command:: protobuf_generate
@@ -146,63 +154,82 @@
protobuf_generate (
TARGET <target>
[LANGUAGE <lang>]
- [OUT_VAR <out_var>]
+ [OUT_VAR <var>]
[EXPORT_MACRO <macro>]
[PROTOC_OUT_DIR <dir>]
[PLUGIN <plugin>]
- [PLUGIN_OPTIONS <plugin_options>]
- [DEPENDENCIES <depends]
- [PROTOS <protobuf_files>]
- [IMPORT_DIRS <dirs>]
- [GENERATE_EXTENSIONS <extensions>]
- [PROTOC_OPTIONS <protoc_options>]
+ [PLUGIN_OPTIONS <plugin-options>]
+ [DEPENDENCIES <dependencies>]
+ [PROTOS <proto-file>...]
+ [IMPORT_DIRS <dir>...]
+ [GENERATE_EXTENSIONS <extension>...]
+ [PROTOC_OPTIONS <option>...]
+ [PROTOC_EXE <executable>]
[APPEND_PATH])
``APPEND_PATH``
A flag that causes the base path of all proto schema files to be added to
``IMPORT_DIRS``.
- ``LANGUAGE``
+
+ ``LANGUAGE <lang>``
A single value: cpp or python. Determines what kind of source files are
being generated. Defaults to cpp.
- ``OUT_VAR``
+
+ ``OUT_VAR <var>``
Name of a CMake variable that will be filled with the paths to the generated
source files.
- ``EXPORT_MACRO``
+
+ ``EXPORT_MACRO <macro>``
Name of a macro that is applied to all generated Protobuf message classes
and extern variables. It can, for example, be used to declare DLL exports.
- ``PROTOC_OUT_DIR``
+
+ ``PROTOC_OUT_DIR <dir>``
Output directory of generated source files. Defaults to ``CMAKE_CURRENT_BINARY_DIR``.
- ``PLUGIN``
+
+ ``PLUGIN <plugin>``
.. versionadded:: 3.21
An optional plugin executable. This could, for example, be the path to
``grpc_cpp_plugin``.
- ``PLUGIN_OPTIONS``
+
+ ``PLUGIN_OPTIONS <plugin-options>``
.. versionadded:: 3.28
Additional options provided to the plugin, such as ``generate_mock_code=true``
for the gRPC cpp plugin.
- ``DEPENDENCIES``
+
+ ``DEPENDENCIES <dependencies>``
.. versionadded:: 3.28
Arguments forwarded to the ``DEPENDS`` of the underlying ``add_custom_command``
invocation.
- ``TARGET``
+
+ ``TARGET <target>``
CMake target that will have the generated files added as sources.
- ``PROTOS``
+
+ ``PROTOS <proto-file>...``
List of proto schema files. If omitted, then every source file ending in *proto* of ``TARGET`` will be used.
- ``IMPORT_DIRS``
+
+ ``IMPORT_DIRS <dir>...``
A common parent directory for the schema files. For example, if the schema file is
``proto/helloworld/helloworld.proto`` and the import directory ``proto/`` then the
generated files are ``${PROTOC_OUT_DIR}/helloworld/helloworld.pb.h`` and
``${PROTOC_OUT_DIR}/helloworld/helloworld.pb.cc``.
- ``GENERATE_EXTENSIONS``
+
+ ``GENERATE_EXTENSIONS <extension>...``
If LANGUAGE is omitted then this must be set to the extensions that protoc generates.
- ``PROTOC_OPTIONS``
+
+ ``PROTOC_OPTIONS <option>...``
.. versionadded:: 3.28
Additional arguments that are forwarded to protoc.
+ ``PROTOC_EXE <executable>``
+ .. versionadded:: 3.32
+
+ Command name, path, or CMake executable used to generate protobuf bindings.
+ If omitted, ``protobuf::protoc`` is used.
+
Example::
find_package(gRPC CONFIG REQUIRED)
@@ -223,7 +250,7 @@
function(protobuf_generate)
set(_options APPEND_PATH DESCRIPTORS)
- set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES)
+ set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES PROTOC_EXE)
if(COMMAND target_sources)
list(APPEND _singleargs TARGET)
endif()
@@ -292,10 +319,14 @@
return()
endif()
- if(NOT TARGET protobuf::protoc)
- message(SEND_ERROR "protoc executable not found. "
- "Please define the Protobuf_PROTOC_EXECUTABLE variable or ensure that protoc is in CMake's search path.")
- return()
+ if(NOT protobuf_generate_PROTOC_EXE)
+ if(NOT TARGET protobuf::protoc)
+ message(SEND_ERROR "protoc executable not found. "
+ "Please define the Protobuf_PROTOC_EXECUTABLE variable, or pass PROTOC_EXE to protobuf_generate, or ensure that protoc is in CMake's search path.")
+ return()
+ endif()
+ # Default to using the CMake executable
+ set(protobuf_generate_PROTOC_EXE protobuf::protoc)
endif()
if(protobuf_generate_APPEND_PATH)
@@ -368,7 +399,7 @@
add_custom_command(
OUTPUT ${_generated_srcs}
- COMMAND protobuf::protoc
+ COMMAND ${protobuf_generate_PROTOC_EXE}
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file}
DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_DEPENDENCIES}
COMMENT ${_comment}
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 9174bee..6d764bd 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -1343,4 +1343,3 @@
set( QT_QT_LIBRARY "")
set(QT4_FOUND ${Qt4_FOUND})
set(QT_FOUND ${Qt4_FOUND})
-
diff --git a/Modules/ITKCompatibility.cmake b/Modules/ITKCompatibility.cmake
index 7d211b6..b3d5a6f 100644
--- a/Modules/ITKCompatibility.cmake
+++ b/Modules/ITKCompatibility.cmake
@@ -4,4 +4,3 @@
# work around an old bug in ITK prior to version 3.0
set(TIFF_RIGHT_VERSION 1)
-
diff --git a/Modules/KDE3Macros.cmake b/Modules/KDE3Macros.cmake
index 42f6d2c..787ce0f 100644
--- a/Modules/KDE3Macros.cmake
+++ b/Modules/KDE3Macros.cmake
@@ -399,5 +399,3 @@
# endif ()
endmacro()
-
-
diff --git a/Modules/Linker/AIX.cmake b/Modules/Linker/AIX.cmake
index 6639df3..91a9530 100644
--- a/Modules/Linker/AIX.cmake
+++ b/Modules/Linker/AIX.cmake
@@ -6,4 +6,6 @@
include_guard()
macro(__linker_aix lang)
+ # Linker warning as error
+ set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:-bhalt:0")
endmacro()
diff --git a/Modules/Linker/AppleClang.cmake b/Modules/Linker/AppleClang.cmake
index 4e48998..c31f1f0 100644
--- a/Modules/Linker/AppleClang.cmake
+++ b/Modules/Linker/AppleClang.cmake
@@ -7,4 +7,6 @@
include_guard()
macro(__linker_appleclang lang)
+ # Linker warning as error
+ set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:-fatal_warnings")
endmacro()
diff --git a/Modules/Linker/GNU.cmake b/Modules/Linker/GNU.cmake
index 978ac12..30d6fb0 100644
--- a/Modules/Linker/GNU.cmake
+++ b/Modules/Linker/GNU.cmake
@@ -65,10 +65,14 @@
set(CMAKE_${lang}_LINK_DEPENDS_USE_LINKER FALSE)
endif()
+ # Linker warning as error
+ set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:--fatal-warnings")
+
return(PROPAGATE CMAKE_${lang}_LINKER_DEPFILE_FLAGS
CMAKE_${lang}_LINKER_DEPFILE_FORMAT
CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED
- CMAKE_${lang}_LINK_DEPENDS_USE_LINKER)
+ CMAKE_${lang}_LINK_DEPENDS_USE_LINKER
+ CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR)
endfunction()
endblock()
diff --git a/Modules/Linker/LLD.cmake b/Modules/Linker/LLD.cmake
index 6695f98..1f184d5 100644
--- a/Modules/Linker/LLD.cmake
+++ b/Modules/Linker/LLD.cmake
@@ -3,8 +3,20 @@
include_guard()
-include(Linker/GNU)
+
+block(SCOPE_FOR POLICIES)
+cmake_policy(SET CMP0054 NEW)
macro(__linker_lld lang)
- __linker_gnu(${lang})
+ if(CMAKE_${lang}_COMPILER_LINKER_FRONTEND_VARIANT STREQUAL "MSVC")
+ include(Linker/MSVC)
+
+ __linker_msvc(${lang})
+ else()
+ include(Linker/GNU)
+
+ __linker_gnu(${lang})
+ endif()
endmacro()
+
+endblock()
diff --git a/Modules/Linker/MOLD-ASM.cmake b/Modules/Linker/MOLD-ASM.cmake
index d927106..16179f5 100644
--- a/Modules/Linker/MOLD-ASM.cmake
+++ b/Modules/Linker/MOLD-ASM.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(ASM)
+__linker_mold(ASM)
diff --git a/Modules/Linker/MOLD-C.cmake b/Modules/Linker/MOLD-C.cmake
index 9a19e7d..d26e75f 100644
--- a/Modules/Linker/MOLD-C.cmake
+++ b/Modules/Linker/MOLD-C.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(C)
+__linker_mold(C)
diff --git a/Modules/Linker/MOLD-CUDA.cmake b/Modules/Linker/MOLD-CUDA.cmake
index 82e887f..8267064 100644
--- a/Modules/Linker/MOLD-CUDA.cmake
+++ b/Modules/Linker/MOLD-CUDA.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(CUDA)
+__linker_mold(CUDA)
diff --git a/Modules/Linker/MOLD-CXX.cmake b/Modules/Linker/MOLD-CXX.cmake
index 6b4d719..399d302 100644
--- a/Modules/Linker/MOLD-CXX.cmake
+++ b/Modules/Linker/MOLD-CXX.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(CXX)
+__linker_mold(CXX)
diff --git a/Modules/Linker/MOLD-Fortran.cmake b/Modules/Linker/MOLD-Fortran.cmake
index b4f688a..3aee849 100644
--- a/Modules/Linker/MOLD-Fortran.cmake
+++ b/Modules/Linker/MOLD-Fortran.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(Fortran)
+__linker_mold(Fortran)
diff --git a/Modules/Linker/MOLD-HIP.cmake b/Modules/Linker/MOLD-HIP.cmake
index b2d0b2e..fd42b42 100644
--- a/Modules/Linker/MOLD-HIP.cmake
+++ b/Modules/Linker/MOLD-HIP.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(HIP)
+__linker_mold(HIP)
diff --git a/Modules/Linker/MOLD-OBJC.cmake b/Modules/Linker/MOLD-OBJC.cmake
index a3c668d..915f6c1 100644
--- a/Modules/Linker/MOLD-OBJC.cmake
+++ b/Modules/Linker/MOLD-OBJC.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(OBJC)
+__linker_mold(OBJC)
diff --git a/Modules/Linker/MOLD-OBJCXX.cmake b/Modules/Linker/MOLD-OBJCXX.cmake
index 0b73003..80eafe1 100644
--- a/Modules/Linker/MOLD-OBJCXX.cmake
+++ b/Modules/Linker/MOLD-OBJCXX.cmake
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-include(Linker/GNU)
+include(Linker/MOLD)
-__linker_gnu(OBJCXX)
+__linker_mold(OBJCXX)
diff --git a/Modules/Linker/MOLD.cmake b/Modules/Linker/MOLD.cmake
new file mode 100644
index 0000000..6ad12fd
--- /dev/null
+++ b/Modules/Linker/MOLD.cmake
@@ -0,0 +1,23 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This module is shared by multiple linkers; use include blocker.
+include_guard()
+
+block(SCOPE_FOR POLICIES)
+cmake_policy(SET CMP0054 NEW)
+
+macro(__linker_mold lang)
+ if(CMAKE_EFFECTIVE_SYSTEM_NAME STREQUAL "Apple")
+ include(Linker/AppleClang)
+
+ __linker_appleclang(${lang})
+ else()
+ include(Linker/GNU)
+
+ __linker_gnu(${lang})
+ endif()
+endmacro()
+
+endblock()
diff --git a/Modules/Linker/MSVC-ASM.cmake b/Modules/Linker/MSVC-ASM.cmake
new file mode 100644
index 0000000..e224275
--- /dev/null
+++ b/Modules/Linker/MSVC-ASM.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include(Linker/MSVC)
+
+__linker_msvc(ASM)
diff --git a/Modules/Linker/MSVC-C.cmake b/Modules/Linker/MSVC-C.cmake
new file mode 100644
index 0000000..c1821d1
--- /dev/null
+++ b/Modules/Linker/MSVC-C.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include(Linker/MSVC)
+
+__linker_msvc(C)
diff --git a/Modules/Linker/MSVC-CUDA.cmake b/Modules/Linker/MSVC-CUDA.cmake
new file mode 100644
index 0000000..2ca5eb4
--- /dev/null
+++ b/Modules/Linker/MSVC-CUDA.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include(Linker/MSVC)
+
+__linker_msvc(CUDA)
diff --git a/Modules/Linker/MSVC-CXX.cmake b/Modules/Linker/MSVC-CXX.cmake
new file mode 100644
index 0000000..243af23
--- /dev/null
+++ b/Modules/Linker/MSVC-CXX.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include(Linker/MSVC)
+
+__linker_msvc(CXX)
diff --git a/Modules/Linker/MSVC-Fortran.cmake b/Modules/Linker/MSVC-Fortran.cmake
new file mode 100644
index 0000000..da02a1d
--- /dev/null
+++ b/Modules/Linker/MSVC-Fortran.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include(Linker/MSVC)
+
+__linker_msvc(Fortran)
diff --git a/Modules/Linker/MSVC-HIP.cmake b/Modules/Linker/MSVC-HIP.cmake
new file mode 100644
index 0000000..c770b9e
--- /dev/null
+++ b/Modules/Linker/MSVC-HIP.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include(Linker/MSVC)
+
+__linker_msvc(HIP)
diff --git a/Modules/Linker/MSVC.cmake b/Modules/Linker/MSVC.cmake
new file mode 100644
index 0000000..0899370
--- /dev/null
+++ b/Modules/Linker/MSVC.cmake
@@ -0,0 +1,12 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This module is shared by multiple linkers; use include blocker.
+include_guard()
+
+
+macro(__linker_msvc lang)
+ # Linker warning as error
+ set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:/WX")
+endmacro()
diff --git a/Modules/Linker/Solaris.cmake b/Modules/Linker/Solaris.cmake
index fbd1199..e24365c 100644
--- a/Modules/Linker/Solaris.cmake
+++ b/Modules/Linker/Solaris.cmake
@@ -6,4 +6,6 @@
include_guard()
macro(__linker_solaris lang)
+ # Linker warning as error
+ set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:-z,fatal-warnings")
endmacro()
diff --git a/Modules/Platform/BSDOS.cmake b/Modules/Platform/BSDOS.cmake
index 47852f8..54a156b 100644
--- a/Modules/Platform/BSDOS.cmake
+++ b/Modules/Platform/BSDOS.cmake
@@ -1,2 +1 @@
include(Platform/UnixPaths)
-
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 1b9cece..1a47d9a 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -80,50 +80,8 @@
set(_CMAKE_OSX_SYSROOT_DEFAULT "xros")
elseif(CMAKE_SYSTEM_NAME STREQUAL watchOS)
set(_CMAKE_OSX_SYSROOT_DEFAULT "watchos")
-elseif("${CMAKE_GENERATOR}" MATCHES Xcode
- OR CMAKE_OSX_DEPLOYMENT_TARGET
- OR CMAKE_OSX_ARCHITECTURES MATCHES "[^;]"
- OR NOT EXISTS "/usr/include/sys/types.h")
- # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory.
- set(_CMAKE_OSX_SDKS_DIR "")
- if(OSX_DEVELOPER_ROOT)
- foreach(_d Platforms/MacOSX.platform/Developer/SDKs SDKs)
- file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${_d}/*)
- if(_CMAKE_OSX_SDKS)
- set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${_d})
- break()
- endif()
- endforeach()
- endif()
-
- if(_CMAKE_OSX_SDKS_DIR)
- # Find the latest SDK as recommended by Apple (Technical Q&A QA1806)
- set(_CMAKE_OSX_LATEST_SDK_VERSION "0.0")
- file(GLOB _CMAKE_OSX_SDKS RELATIVE "${_CMAKE_OSX_SDKS_DIR}" "${_CMAKE_OSX_SDKS_DIR}/MacOSX*.sdk")
- foreach(_SDK ${_CMAKE_OSX_SDKS})
- if(IS_DIRECTORY "${_CMAKE_OSX_SDKS_DIR}/${_SDK}"
- AND _SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk"
- AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
- set(_CMAKE_OSX_LATEST_SDK_VERSION "${CMAKE_MATCH_1}")
- endif()
- endforeach()
-
- if(NOT _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0")
- set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_LATEST_SDK_VERSION}.sdk")
- else()
- message(WARNING "Could not find any valid SDKs in ${_CMAKE_OSX_SDKS_DIR}")
- endif()
-
- if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET
- AND (_CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_LATEST_SDK_VERSION
- OR _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0"))
- set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING
- "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE)
- endif()
- else()
- # Assume developer files are in root (such as Xcode 4.5 command-line tools).
- set(_CMAKE_OSX_SYSROOT_DEFAULT "")
- endif()
+else()
+ set(_CMAKE_OSX_SYSROOT_DEFAULT "")
endif()
# Set cache variable - end user may change this during ccmake or cmake-gui configure.
@@ -244,7 +202,7 @@
return() # Only apply to multi-arch
endif()
- if(CMAKE_OSX_SYSROOT STREQUAL "macosx")
+ if(NOT CMAKE_OSX_SYSROOT OR CMAKE_OSX_SYSROOT STREQUAL "macosx")
# macOS doesn't have a simulator sdk / sysroot, so there is no need to handle per-sdk arches.
return()
endif()
@@ -256,7 +214,7 @@
return()
endif()
- string(REPLACE "os" "simulator" _simulator_sdk ${CMAKE_OSX_SYSROOT})
+ string(REPLACE "os" "simulator" _simulator_sdk "${CMAKE_OSX_SYSROOT}")
set(_sdks "${CMAKE_OSX_SYSROOT};${_simulator_sdk}")
foreach(sdk ${_sdks})
_apple_resolve_sdk_path(${sdk} _sdk_path)
@@ -302,25 +260,36 @@
_apple_resolve_multi_arch_sysroots()
-# Transform CMAKE_OSX_SYSROOT to absolute path
-set(_CMAKE_OSX_SYSROOT_PATH "")
-if(CMAKE_OSX_SYSROOT)
- if("x${CMAKE_OSX_SYSROOT}" MATCHES "/")
- # This is a path to the SDK. Make sure it exists.
- if(NOT IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
- message(WARNING "Ignoring CMAKE_OSX_SYSROOT value:\n ${CMAKE_OSX_SYSROOT}\n"
- "because the directory does not exist.")
- set(CMAKE_OSX_SYSROOT "")
- endif()
- set(_CMAKE_OSX_SYSROOT_PATH "${CMAKE_OSX_SYSROOT}")
- else()
- _apple_resolve_sdk_path(${CMAKE_OSX_SYSROOT} _sdk_path)
- if(IS_DIRECTORY "${_sdk_path}")
- set(_CMAKE_OSX_SYSROOT_PATH "${_sdk_path}")
- # For non-Xcode generators use the path.
- if(NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
- set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
- endif()
- endif()
+if(CMAKE_OSX_SYSROOT MATCHES "/")
+ # This is a path to a SDK. Make sure it exists.
+ if(NOT IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
+ message(WARNING "Ignoring CMAKE_OSX_SYSROOT value:\n ${CMAKE_OSX_SYSROOT}\n"
+ "because the directory does not exist.")
+ set(CMAKE_OSX_SYSROOT "")
endif()
+ set(_CMAKE_OSX_SYSROOT_PATH "${CMAKE_OSX_SYSROOT}")
+elseif(CMAKE_OSX_SYSROOT)
+ # This is the name of a SDK. Transform it to a path.
+ _apple_resolve_sdk_path("${CMAKE_OSX_SYSROOT}" _CMAKE_OSX_SYSROOT_PATH)
+ # Use the path for non-Xcode generators.
+ if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_PATH}" AND NOT CMAKE_GENERATOR MATCHES "Xcode")
+ set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
+ endif()
+endif()
+if(NOT CMAKE_OSX_SYSROOT)
+ # Without any explicit SDK we rely on the toolchain default,
+ # which we assume to be what wrappers like /usr/bin/cc use.
+ if(CMAKE_GENERATOR STREQUAL "Xcode")
+ set(_sdk_macosx --sdk macosx)
+ else()
+ set(_sdk_macosx)
+ endif()
+ execute_process(
+ COMMAND xcrun ${_sdk_macosx} --show-sdk-path
+ OUTPUT_VARIABLE _CMAKE_OSX_SYSROOT_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _result
+ )
+ unset(_sdk_macosx)
endif()
diff --git a/Modules/Platform/Generic-ADSP-ASM.cmake b/Modules/Platform/Generic-ADSP-ASM.cmake
index e718bec..ed729f4 100644
--- a/Modules/Platform/Generic-ADSP-ASM.cmake
+++ b/Modules/Platform/Generic-ADSP-ASM.cmake
@@ -4,4 +4,3 @@
set(CMAKE_ASM_OUTPUT_EXTENSION ".doj" )
set(CMAKE_ASM_COMPILE_OBJECT
"<CMAKE_ASM_COMPILER> <INCLUDES> <FLAGS> -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -o <OBJECT> <SOURCE>")
-
diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake
index 425a13f..7aa6aa4 100644
--- a/Modules/Platform/HP-UX.cmake
+++ b/Modules/Platform/HP-UX.cmake
@@ -44,4 +44,3 @@
set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-a,default")
endforeach()
endforeach()
-
diff --git a/Modules/Platform/MP-RAS.cmake b/Modules/Platform/MP-RAS.cmake
index fe8d81a..4cbfd8e 100644
--- a/Modules/Platform/MP-RAS.cmake
+++ b/Modules/Platform/MP-RAS.cmake
@@ -10,5 +10,3 @@
endif()
include(Platform/UnixPaths)
-
-
diff --git a/Modules/Platform/Tru64.cmake b/Modules/Platform/Tru64.cmake
index 47852f8..54a156b 100644
--- a/Modules/Platform/Tru64.cmake
+++ b/Modules/Platform/Tru64.cmake
@@ -1,2 +1 @@
include(Platform/UnixPaths)
-
diff --git a/Modules/Platform/Windows-IntelLLVM.cmake b/Modules/Platform/Windows-IntelLLVM.cmake
index ba2cc9c..2fc909a 100644
--- a/Modules/Platform/Windows-IntelLLVM.cmake
+++ b/Modules/Platform/Windows-IntelLLVM.cmake
@@ -27,6 +27,10 @@
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "${_IntelLLVM_LINKER_WRAPPER_FLAG}")
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP "${_IntelLLVM_LINKER_WRAPPER_FLAG_SEP}")
+ # ARCHIVER: prefix use same values as LINKER: one.
+ set(CMAKE_${lang}_ARCHIVER_WRAPPER_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}")
+ set(CMAKE_${lang}_ARCHIVER_WRAPPER_FLAG_SEP "${CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP}")
+
set(CMAKE_${lang}_CREATE_WIN32_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:windows")
set(CMAKE_${lang}_CREATE_CONSOLE_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:console")
set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/DEF:")
diff --git a/Modules/Platform/Windows.cmake b/Modules/Platform/Windows.cmake
index af7335b..449188e 100644
--- a/Modules/Platform/Windows.cmake
+++ b/Modules/Platform/Windows.cmake
@@ -43,4 +43,3 @@
#set(CMAKE_START_TEMP_FILE "")
#set(CMAKE_END_TEMP_FILE "")
#set(CMAKE_VERBOSE_MAKEFILE 1)
-
diff --git a/Modules/Platform/Xenix.cmake b/Modules/Platform/Xenix.cmake
index 47852f8..54a156b 100644
--- a/Modules/Platform/Xenix.cmake
+++ b/Modules/Platform/Xenix.cmake
@@ -1,2 +1 @@
include(Platform/UnixPaths)
-
diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake
index 25db028..d6407d0 100644
--- a/Modules/Platform/eCos.cmake
+++ b/Modules/Platform/eCos.cmake
@@ -62,4 +62,3 @@
set(CMAKE_CXX_LINK_MODULE_LIBRARY )
set(CMAKE_C_LINK_SHARED_LIBRARY )
set(CMAKE_C_LINK_MODULE_LIBRARY )
-
diff --git a/Modules/Platform/gas.cmake b/Modules/Platform/gas.cmake
index 8484076..12060f7 100644
--- a/Modules/Platform/gas.cmake
+++ b/Modules/Platform/gas.cmake
@@ -16,4 +16,3 @@
# to be done
set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
-
diff --git a/Modules/Platform/iOS-Initialize.cmake b/Modules/Platform/iOS-Initialize.cmake
index 91e3898..2a38bc1 100644
--- a/Modules/Platform/iOS-Initialize.cmake
+++ b/Modules/Platform/iOS-Initialize.cmake
@@ -5,5 +5,3 @@
endif()
set(IOS 1)
-
-set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)
diff --git a/Modules/Platform/tvOS-Initialize.cmake b/Modules/Platform/tvOS-Initialize.cmake
index 6834c80..f265946 100644
--- a/Modules/Platform/tvOS-Initialize.cmake
+++ b/Modules/Platform/tvOS-Initialize.cmake
@@ -3,5 +3,3 @@
if(NOT _CMAKE_OSX_SYSROOT_PATH MATCHES "/AppleTV(OS|Simulator)")
message(FATAL_ERROR "${CMAKE_OSX_SYSROOT} is not an tvOS SDK")
endif()
-
-set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)
diff --git a/Modules/Platform/visionOS-Initialize.cmake b/Modules/Platform/visionOS-Initialize.cmake
index e8431bc..fee7bf3 100644
--- a/Modules/Platform/visionOS-Initialize.cmake
+++ b/Modules/Platform/visionOS-Initialize.cmake
@@ -3,5 +3,3 @@
if(NOT _CMAKE_OSX_SYSROOT_PATH MATCHES "/XR(OS|Simulator)")
message(FATAL_ERROR "${CMAKE_OSX_SYSROOT} is not an visionOS SDK")
endif()
-
-set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)
diff --git a/Modules/Platform/watchOS-Initialize.cmake b/Modules/Platform/watchOS-Initialize.cmake
index 2f396d3..e9705ca 100644
--- a/Modules/Platform/watchOS-Initialize.cmake
+++ b/Modules/Platform/watchOS-Initialize.cmake
@@ -3,5 +3,3 @@
if(NOT _CMAKE_OSX_SYSROOT_PATH MATCHES "/Watch(OS|Simulator)")
message(FATAL_ERROR "${CMAKE_OSX_SYSROOT} is not an watchOS SDK")
endif()
-
-set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)
diff --git a/Modules/Qt4ConfigDependentSettings.cmake b/Modules/Qt4ConfigDependentSettings.cmake
index 4699ecd..5ef0351 100644
--- a/Modules/Qt4ConfigDependentSettings.cmake
+++ b/Modules/Qt4ConfigDependentSettings.cmake
@@ -287,4 +287,3 @@
set(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} "-framework ApplicationServices")
endif()
-
diff --git a/Modules/SystemInformation.cmake b/Modules/SystemInformation.cmake
index 97f3856..0ef4888 100644
--- a/Modules/SystemInformation.cmake
+++ b/Modules/SystemInformation.cmake
@@ -88,4 +88,3 @@
foreach (EXTRA_FILE ${EXTRA_DUMP_FILES})
DUMP_FILE("${EXTRA_FILE}")
endforeach ()
-
diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake
index b1a12cf..d73b1df 100644
--- a/Modules/TestForANSIForScope.cmake
+++ b/Modules/TestForANSIForScope.cmake
@@ -30,8 +30,3 @@
"Does the compiler support ansi for scope.")
endif ()
endif()
-
-
-
-
-
diff --git a/Modules/TestForANSIStreamHeaders.cmake b/Modules/TestForANSIStreamHeaders.cmake
index e532a71..d4cfa2d 100644
--- a/Modules/TestForANSIStreamHeaders.cmake
+++ b/Modules/TestForANSIStreamHeaders.cmake
@@ -29,5 +29,3 @@
mark_as_advanced(CMAKE_NO_ANSI_STREAM_HEADERS)
endif()
-
-
diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake
index e2cc5b0..9780269 100644
--- a/Modules/TestForSSTREAM.cmake
+++ b/Modules/TestForSSTREAM.cmake
@@ -29,7 +29,3 @@
"Does the compiler support sstream")
endif ()
endif()
-
-
-
-
diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake
index 61e922d..31ed993 100644
--- a/Modules/TestForSTDNamespace.cmake
+++ b/Modules/TestForSTDNamespace.cmake
@@ -29,7 +29,3 @@
"Does the compiler support std::.")
endif ()
endif()
-
-
-
-
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
index 5e6f606..f263211 100644
--- a/Modules/UseEcos.cmake
+++ b/Modules/UseEcos.cmake
@@ -243,4 +243,3 @@
COMMAND ${ECOS_ARCH_PREFIX}objdump -S -x -d -C ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.elf >> ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst )
endmacro()
-
diff --git a/Modules/UseJava/javaTargets.cmake.in b/Modules/UseJava/javaTargets.cmake.in
index 6002d4e..11f1f06 100644
--- a/Modules/UseJava/javaTargets.cmake.in
+++ b/Modules/UseJava/javaTargets.cmake.in
@@ -1,5 +1,5 @@
cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.12...3.29)
+cmake_policy(VERSION 2.8.12...3.30)
#----------------------------------------------------------------
# Generated CMake Java target import file.
diff --git a/Modules/VTKCompatibility.cmake b/Modules/VTKCompatibility.cmake
index 4ee7643..c0b8b22 100644
--- a/Modules/VTKCompatibility.cmake
+++ b/Modules/VTKCompatibility.cmake
@@ -43,4 +43,3 @@
macro(SOURCE_FILES)
message (FATAL_ERROR "You are trying to build a very old version of VTK (prior to VTK 4.2). To do this you need to use CMake 2.0 as it was the last version of CMake to support VTK 4.0.")
endmacro()
-
diff --git a/Modules/kde3uic.cmake b/Modules/kde3uic.cmake
index b1f73d5..cf0a57f 100644
--- a/Modules/kde3uic.cmake
+++ b/Modules/kde3uic.cmake
@@ -19,4 +19,3 @@
file(WRITE ${KDE_UIC_CPP_FILE} "#include <kdialog.h>\n#include <klocale.h>\n\n")
file(APPEND ${KDE_UIC_CPP_FILE} "${_uic_CONTENTS}")
-
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c4cd101..cb758bc 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -412,6 +412,8 @@
cmNewLineStyle.cxx
cmOrderDirectories.cxx
cmOrderDirectories.h
+ cmPathResolver.cxx
+ cmPathResolver.h
cmPlistParser.cxx
cmPlistParser.h
cmPolicies.h
@@ -508,8 +510,6 @@
cmake.cxx
cmake.h
- cmCommand.cxx
- cmCommand.h
cmCommands.cxx
cmCommands.h
cmAddCompileDefinitionsCommand.cxx
@@ -1071,9 +1071,10 @@
cmCTest.cxx
CTest/cmProcess.cxx
CTest/cmCTestBinPacker.cxx
- CTest/cmCTestBuildAndTestHandler.cxx
+ CTest/cmCTestBuildAndTest.cxx
CTest/cmCTestBuildCommand.cxx
CTest/cmCTestBuildHandler.cxx
+ CTest/cmCTestCommand.cxx
CTest/cmCTestConfigureCommand.cxx
CTest/cmCTestConfigureHandler.cxx
CTest/cmCTestCoverageCommand.cxx
@@ -1109,10 +1110,9 @@
CTest/cmCTestTestCommand.cxx
CTest/cmCTestTestHandler.cxx
CTest/cmCTestTestMeasurementXMLParser.cxx
+ CTest/cmCTestTypes.cxx
CTest/cmCTestUpdateCommand.cxx
- CTest/cmCTestUpdateHandler.cxx
CTest/cmCTestUploadCommand.cxx
- CTest/cmCTestUploadHandler.cxx
CTest/cmCTestVC.cxx
CTest/cmCTestVC.h
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index dc2427c..f04c69d 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 31)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 20241129)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 0ebe2f4..5d0df06 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -50,14 +50,13 @@
user = user_and_domain;
}
- std::vector<std::string> permissions = cmTokenize(permission_string, ",");
-
this->SourceWriter.BeginElement("Permission");
this->SourceWriter.AddAttribute("User", std::string(user));
if (!domain.empty()) {
this->SourceWriter.AddAttribute("Domain", std::string(domain));
}
- for (std::string const& permission : permissions) {
+ for (auto permission :
+ cmTokenizedView(permission_string, ',', cmTokenizerMode::New)) {
this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
}
this->SourceWriter.EndElement("Permission");
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index c70a2f1..bb1545b 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackArchiveGenerator.h"
-#include <cstring>
#include <map>
#include <ostream>
#include <unordered_map>
@@ -192,15 +191,16 @@
std::string componentUpper(cmSystemTools::UpperCase(component));
std::string packageFileName;
- if (this->IsSet("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME")) {
+ if (cmValue v = this->GetOptionIfSet("CPACK_ARCHIVE_" + componentUpper +
+ "_FILE_NAME")) {
+ packageFileName += *v;
+ } else if ((v = this->GetOptionIfSet("CPACK_ARCHIVE_FILE_NAME"))) {
packageFileName +=
- *this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME");
- } else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
- packageFileName += this->GetComponentPackageFileName(
- *this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName);
+ this->GetComponentPackageFileName(*v, component, isGroupName);
} else {
- packageFileName += this->GetComponentPackageFileName(
- *this->GetOption("CPACK_PACKAGE_FILE_NAME"), component, isGroupName);
+ v = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ packageFileName +=
+ this->GetComponentPackageFileName(*v, component, isGroupName);
}
packageFileName += this->GetOutputExtension();
@@ -238,10 +238,7 @@
// Change to local toplevel
cmWorkingDirectory workdir(localToplevel);
if (workdir.Failed()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Failed to change working directory to "
- << localToplevel << " : "
- << std::strerror(workdir.GetLastResult()) << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_ERROR, workdir.GetError() << std::endl);
return 0;
}
std::string filePrefix;
@@ -398,10 +395,11 @@
this->packageFileNames.emplace_back(this->toplevel);
this->packageFileNames[0] += "/";
- if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
- this->packageFileNames[0] += *this->GetOption("CPACK_ARCHIVE_FILE_NAME");
+ if (cmValue v = this->GetOptionIfSet("CPACK_ARCHIVE_FILE_NAME")) {
+ this->packageFileNames[0] += *v;
} else {
- this->packageFileNames[0] += *this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ v = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ this->packageFileNames[0] += *v;
}
this->packageFileNames[0] += this->GetOutputExtension();
@@ -448,10 +446,7 @@
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
cmWorkingDirectory workdir(this->toplevel);
if (workdir.Failed()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Failed to change working directory to "
- << this->toplevel << " : "
- << std::strerror(workdir.GetLastResult()) << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_ERROR, workdir.GetError() << std::endl);
return 0;
}
for (std::string const& file : this->files) {
@@ -488,10 +483,10 @@
int threads = 1;
// CPACK_ARCHIVE_THREADS overrides CPACK_THREADS
- if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
- threads = std::stoi(*this->GetOption("CPACK_ARCHIVE_THREADS"));
- } else if (this->IsSet("CPACK_THREADS")) {
- threads = std::stoi(*this->GetOption("CPACK_THREADS"));
+ if (cmValue v = this->GetOptionIfSet("CPACK_ARCHIVE_THREADS")) {
+ threads = std::stoi(*v);
+ } else if (cmValue v2 = this->GetOptionIfSet("CPACK_THREADS")) {
+ threads = std::stoi(*v2);
}
return threads;
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 4c518ac..038104e 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -101,13 +101,12 @@
}
this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path);
- if (this->IsSet("CPACK_DMG_SLA_DIR")) {
- slaDirectory = this->GetOption("CPACK_DMG_SLA_DIR");
+ if (cmValue v = this->GetOptionIfSet("CPACK_DMG_SLA_DIR")) {
+ slaDirectory = *v;
if (!slaDirectory.empty() &&
this->IsOn("CPACK_DMG_SLA_USE_RESOURCE_FILE_LICENSE") &&
- this->IsSet("CPACK_RESOURCE_FILE_LICENSE")) {
- std::string license_file =
- this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
+ (v = this->GetOptionIfSet("CPACK_RESOURCE_FILE_LICENSE"))) {
+ std::string license_file = *v;
if (!license_file.empty() &&
(license_file.find("CPack.GenericLicense.txt") ==
std::string::npos)) {
@@ -119,7 +118,8 @@
singleLicense = true;
}
}
- if (!this->IsSet("CPACK_DMG_SLA_LANGUAGES")) {
+ cmValue lang = this->GetOptionIfSet("CPACK_DMG_SLA_LANGUAGES");
+ if (!lang) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_DMG_SLA_DIR set but no languages defined "
"(set CPACK_DMG_SLA_LANGUAGES)"
@@ -132,7 +132,7 @@
return 0;
}
- cmList languages{ this->GetOption("CPACK_DMG_SLA_LANGUAGES") };
+ cmList languages{ *lang };
if (languages.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl);
@@ -742,8 +742,8 @@
std::string componentFileName = cmStrCat(
"CPACK_DMG_", cmSystemTools::UpperCase(componentName), "_FILE_NAME");
- if (this->IsSet(componentFileName)) {
- return this->GetOption(componentFileName);
+ if (cmValue v = this->GetOptionIfSet(componentFileName)) {
+ return *v;
}
return GetComponentPackageFileName(package_file_name, componentName, false);
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 44d0ece..82116b3 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -3,7 +3,6 @@
#include "cmCPackGenerator.h"
#include <algorithm>
-#include <cstring>
#include <memory>
#include <utility>
@@ -52,10 +51,9 @@
}
void cmCPackGenerator::DisplayVerboseOutput(const std::string& msg,
- float progress)
+ float /*unused*/)
{
- (void)progress;
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, msg << std::endl);
}
int cmCPackGenerator::PrepareNames()
@@ -434,10 +432,7 @@
cmWorkingDirectory workdir(goToDir);
if (workdir.Failed()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Failed to change working directory to "
- << goToDir << " : "
- << std::strerror(workdir.GetLastResult())
- << std::endl);
+ workdir.GetError() << std::endl);
return 0;
}
for (auto const& symlinked : symlinkedFiles) {
@@ -1323,6 +1318,15 @@
return this->MakefileMap->IsSet(name);
}
+cmValue cmCPackGenerator::GetOptionIfSet(const std::string& name) const
+{
+ cmValue ret = this->MakefileMap->GetDefinition(name);
+ if (!ret || ret->empty() || cmIsNOTFOUND(*ret)) {
+ return {};
+ }
+ return ret;
+}
+
bool cmCPackGenerator::IsOn(const std::string& name) const
{
return this->GetOption(name).IsOn();
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 980ab8f..30e8451 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -103,6 +103,7 @@
cmValue GetOption(const std::string& op) const;
std::vector<std::string> GetOptions() const;
bool IsSet(const std::string& name) const;
+ cmValue GetOptionIfSet(const std::string& name) const;
bool IsOn(const std::string& name) const;
bool IsSetToOff(const std::string& op) const;
bool IsSetToEmpty(const std::string& op) const;
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.cxx b/Source/CPack/cmCPackInnoSetupGenerator.cxx
index 35d126f..df99e15 100644
--- a/Source/CPack/cmCPackInnoSetupGenerator.cxx
+++ b/Source/CPack/cmCPackInnoSetupGenerator.cxx
@@ -97,9 +97,8 @@
int cmCPackInnoSetupGenerator::PackageFiles()
{
// Includes
- if (IsSet("CPACK_INNOSETUP_EXTRA_SCRIPTS")) {
- const cmList extraScripts(GetOption("CPACK_INNOSETUP_EXTRA_SCRIPTS"));
-
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_EXTRA_SCRIPTS")) {
+ const cmList extraScripts(*v);
for (const std::string& i : extraScripts) {
includeDirectives.emplace_back(cmStrCat(
"#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
@@ -133,9 +132,8 @@
}
// [Code] section
- if (IsSet("CPACK_INNOSETUP_CODE_FILES")) {
- const cmList codeFiles(GetOption("CPACK_INNOSETUP_CODE_FILES"));
-
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_CODE_FILES")) {
+ const cmList codeFiles(*v);
for (const std::string& i : codeFiles) {
codeIncludes.emplace_back(cmStrCat(
"#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
@@ -168,26 +166,26 @@
}
setupDirectives["AppPublisher"] = GetOption("CPACK_PACKAGE_VENDOR");
- if (IsSet("CPACK_PACKAGE_HOMEPAGE_URL")) {
- setupDirectives["AppPublisherURL"] =
- GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
- setupDirectives["AppSupportURL"] = GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
- setupDirectives["AppUpdatesURL"] = GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ if (cmValue v = GetOptionIfSet("CPACK_PACKAGE_HOMEPAGE_URL")) {
+ setupDirectives["AppPublisherURL"] = *v;
+ setupDirectives["AppSupportURL"] = *v;
+ setupDirectives["AppUpdatesURL"] = *v;
}
SetOptionIfNotSet("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE", "OFF");
- if (IsSet("CPACK_RESOURCE_FILE_LICENSE") &&
- !GetOption("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE").IsOn()) {
- setupDirectives["LicenseFile"] = cmSystemTools::ConvertToWindowsOutputPath(
- GetOption("CPACK_RESOURCE_FILE_LICENSE"));
+ if (!GetOption("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE").IsOn()) {
+ if (cmValue v = GetOptionIfSet("CPACK_RESOURCE_FILE_LICENSE")) {
+ setupDirectives["LicenseFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(*v);
+ }
}
SetOptionIfNotSet("CPACK_INNOSETUP_IGNORE_README_PAGE", "ON");
- if (IsSet("CPACK_RESOURCE_FILE_README") &&
- !GetOption("CPACK_INNOSETUP_IGNORE_README_PAGE").IsOn()) {
- setupDirectives["InfoBeforeFile"] =
- cmSystemTools::ConvertToWindowsOutputPath(
- GetOption("CPACK_RESOURCE_FILE_README"));
+ if (!GetOption("CPACK_INNOSETUP_IGNORE_README_PAGE").IsOn()) {
+ if (cmValue v = GetOptionIfSet("CPACK_RESOURCE_FILE_README")) {
+ setupDirectives["InfoBeforeFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(*v);
+ }
}
SetOptionIfNotSet("CPACK_INNOSETUP_USE_MODERN_WIZARD", "OFF");
@@ -201,16 +199,14 @@
setupDirectives["SetupIconFile"] = "compiler:SetupClassicIcon.ico";
}
- if (IsSet("CPACK_INNOSETUP_ICON_FILE")) {
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_ICON_FILE")) {
setupDirectives["SetupIconFile"] =
- cmSystemTools::ConvertToWindowsOutputPath(
- GetOption("CPACK_INNOSETUP_ICON_FILE"));
+ cmSystemTools::ConvertToWindowsOutputPath(*v);
}
- if (IsSet("CPACK_PACKAGE_ICON")) {
+ if (cmValue v = GetOptionIfSet("CPACK_PACKAGE_ICON")) {
setupDirectives["WizardSmallImageFile"] =
- cmSystemTools::ConvertToWindowsOutputPath(
- GetOption("CPACK_PACKAGE_ICON"));
+ cmSystemTools::ConvertToWindowsOutputPath(*v);
}
if (!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) {
@@ -238,8 +234,8 @@
toplevelProgramFolder = false;
}
- if (IsSet("CPACK_INNOSETUP_PASSWORD")) {
- setupDirectives["Password"] = GetOption("CPACK_INNOSETUP_PASSWORD");
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_PASSWORD")) {
+ setupDirectives["Password"] = *v;
setupDirectives["Encryption"] = "yes";
}
@@ -306,9 +302,9 @@
bool cmCPackInnoSetupGenerator::ProcessFiles()
{
std::map<std::string, std::string> customFileInstructions;
- if (IsSet("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS")) {
- const cmList instructions(
- GetOption("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS"));
+ if (cmValue v =
+ GetOptionIfSet("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS")) {
+ const cmList instructions(*v);
if (instructions.size() % 2 != 0) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS should "
@@ -328,8 +324,8 @@
toplevelProgramFolder ? "{autoprograms}\\" : "{group}\\";
std::map<std::string, std::string> icons;
- if (IsSet("CPACK_PACKAGE_EXECUTABLES")) {
- const cmList executables(GetOption("CPACK_PACKAGE_EXECUTABLES"));
+ if (cmValue v = GetOptionIfSet("CPACK_PACKAGE_EXECUTABLES")) {
+ const cmList executables(*v);
if (executables.size() % 2 != 0) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_PACKAGE_EXECUTABLES should should contain pairs of "
@@ -345,13 +341,13 @@
}
std::vector<std::string> desktopIcons;
- if (IsSet("CPACK_CREATE_DESKTOP_LINKS")) {
- cmExpandList(GetOption("CPACK_CREATE_DESKTOP_LINKS"), desktopIcons);
+ if (cmValue v = GetOptionIfSet("CPACK_CREATE_DESKTOP_LINKS")) {
+ cmExpandList(*v, desktopIcons);
}
std::vector<std::string> runExecutables;
- if (IsSet("CPACK_INNOSETUP_RUN_EXECUTABLES")) {
- cmExpandList(GetOption("CPACK_INNOSETUP_RUN_EXECUTABLES"), runExecutables);
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_RUN_EXECUTABLES")) {
+ cmExpandList(*v, runExecutables);
}
for (const std::string& i : files) {
@@ -507,8 +503,8 @@
static cmsys::RegularExpression urlRegex(
"^(mailto:|(ftps?|https?|news)://).*$");
- if (IsSet("CPACK_INNOSETUP_MENU_LINKS")) {
- const cmList menuIcons(GetOption("CPACK_INNOSETUP_MENU_LINKS"));
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_MENU_LINKS")) {
+ const cmList menuIcons(*v);
if (menuIcons.size() % 2 != 0) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_INNOSETUP_MENU_LINKS should "
@@ -784,8 +780,7 @@
const std::string& defaultMessage =
"; CPack didn't find any entries for this section";
- if (IsSet("CPACK_CREATE_DESKTOP_LINKS") &&
- !GetOption("CPACK_CREATE_DESKTOP_LINKS").Get()->empty()) {
+ if (!IsSetToEmpty("CPACK_CREATE_DESKTOP_LINKS")) {
cmCPackInnoSetupKeyValuePairs tasks;
tasks["Name"] = "\"desktopicon\"";
tasks["Description"] = "\"{cm:CreateDesktopIcon}\"";
@@ -858,9 +853,8 @@
}
}
- if (IsSet("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS")) {
- const cmList args(GetOption("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS"));
-
+ if (cmValue v = GetOptionIfSet("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS")) {
+ const cmList args(*v);
isccArgs.insert(isccArgs.end(), args.begin(), args.end());
}
@@ -986,7 +980,7 @@
"Problem running certutil command: " << hashCmd
<< std::endl);
}
- *hash = cmTrimWhitespace(cmTokenize(hashOutput, "\n").at(1));
+ *hash = cmTrimWhitespace(cmTokenizedView(hashOutput, '\n').at(1));
if (hash->length() != 64) {
cmCPackLogger(cmCPackLog::LOG_WARNING,
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 53871ee..8d81183 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -130,23 +130,20 @@
if (this->IsSet("CPACK_NSIS_MUI_ICON") ||
this->IsSet("CPACK_NSIS_MUI_UNIICON")) {
std::string installerIconCode;
- if (this->IsSet("CPACK_NSIS_MUI_ICON")) {
- installerIconCode += cmStrCat(
- "!define MUI_ICON \"", this->GetOption("CPACK_NSIS_MUI_ICON"), "\"\n");
+ if (cmValue icon = this->GetOptionIfSet("CPACK_NSIS_MUI_ICON")) {
+ installerIconCode += cmStrCat("!define MUI_ICON \"", *icon, "\"\n");
}
- if (this->IsSet("CPACK_NSIS_MUI_UNIICON")) {
- installerIconCode +=
- cmStrCat("!define MUI_UNICON \"",
- this->GetOption("CPACK_NSIS_MUI_UNIICON"), "\"\n");
+ if (cmValue icon = this->GetOptionIfSet("CPACK_NSIS_MUI_UNIICON")) {
+ installerIconCode += cmStrCat("!define MUI_UNICON \"", *icon, "\"\n");
}
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE",
installerIconCode.c_str());
}
std::string installerHeaderImage;
- if (this->IsSet("CPACK_NSIS_MUI_HEADERIMAGE")) {
- installerHeaderImage = *this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE");
- } else if (this->IsSet("CPACK_PACKAGE_ICON")) {
- installerHeaderImage = *this->GetOption("CPACK_PACKAGE_ICON");
+ if (cmValue img = this->GetOptionIfSet("CPACK_NSIS_MUI_HEADERIMAGE")) {
+ installerHeaderImage = *img;
+ } else if (cmValue icon = this->GetOptionIfSet("CPACK_PACKAGE_ICON")) {
+ installerHeaderImage = *icon;
}
if (!installerHeaderImage.empty()) {
std::string installerIconCode = cmStrCat(
@@ -155,35 +152,33 @@
installerIconCode);
}
- if (this->IsSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP")) {
- std::string installerBitmapCode = cmStrCat(
- "!define MUI_WELCOMEFINISHPAGE_BITMAP \"",
- this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"), "\"\n");
+ if (cmValue v =
+ this->GetOptionIfSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP")) {
+ std::string installerBitmapCode =
+ cmStrCat("!define MUI_WELCOMEFINISHPAGE_BITMAP \"", *v, "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE",
installerBitmapCode);
}
- if (this->IsSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP")) {
- std::string installerBitmapCode = cmStrCat(
- "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"",
- this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"), "\"\n");
+ if (cmValue v =
+ this->GetOptionIfSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP")) {
+ std::string installerBitmapCode =
+ cmStrCat("!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"", *v, "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE",
installerBitmapCode);
}
- if (this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN")) {
- std::string installerRunCode =
- cmStrCat("!define MUI_FINISHPAGE_RUN \"$INSTDIR\\",
- this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"), '\\',
- this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN"), "\"\n");
+ if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_MUI_FINISHPAGE_RUN")) {
+ std::string installerRunCode = cmStrCat(
+ "!define MUI_FINISHPAGE_RUN \"$INSTDIR\\",
+ this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"), '\\', *v, "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE",
installerRunCode);
}
- if (this->IsSet("CPACK_NSIS_WELCOME_TITLE")) {
+ if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_WELCOME_TITLE")) {
std::string welcomeTitleCode =
- cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"",
- this->GetOption("CPACK_NSIS_WELCOME_TITLE"), "\"");
+ cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"", *v, "\"");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE",
welcomeTitleCode);
}
@@ -193,10 +188,9 @@
"!define MUI_WELCOMEPAGE_TITLE_3LINES");
}
- if (this->IsSet("CPACK_NSIS_FINISH_TITLE")) {
+ if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_FINISH_TITLE")) {
std::string finishTitleCode =
- cmStrCat("!define MUI_FINISHPAGE_TITLE \"",
- this->GetOption("CPACK_NSIS_FINISH_TITLE"), "\"");
+ cmStrCat("!define MUI_FINISHPAGE_TITLE \"", *v, "\"");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE",
finishTitleCode);
}
@@ -211,28 +205,28 @@
"ManifestDPIAware true");
}
- if (this->IsSet("CPACK_NSIS_BRANDING_TEXT")) {
+ if (cmValue brandingText =
+ this->GetOptionIfSet("CPACK_NSIS_BRANDING_TEXT")) {
// Default position to LEFT
std::string brandingTextPosition = "LEFT";
- if (this->IsSet("CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION")) {
- std::string wantedPosition =
- this->GetOption("CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION");
- if (!wantedPosition.empty()) {
+ if (cmValue wantedPosition =
+ this->GetOptionIfSet("CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION")) {
+ if (!wantedPosition->empty()) {
const std::set<std::string> possiblePositions{ "CENTER", "LEFT",
"RIGHT" };
- if (possiblePositions.find(wantedPosition) ==
+ if (possiblePositions.find(*wantedPosition) ==
possiblePositions.end()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Unsupported branding text trim position "
- << wantedPosition << std::endl);
+ << *wantedPosition << std::endl);
return false;
}
- brandingTextPosition = wantedPosition;
+ brandingTextPosition = *wantedPosition;
}
}
std::string brandingTextCode =
cmStrCat("BrandingText /TRIM", brandingTextPosition, " \"",
- this->GetOption("CPACK_NSIS_BRANDING_TEXT"), "\"\n");
+ *brandingText, "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_BRANDING_TEXT_CODE", brandingTextCode);
}
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index ae3c50e..b5b70dc 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.cxx
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -60,10 +60,8 @@
std::string resDir = cmStrCat(packageDirFileName, "/Contents");
- if (this->IsSet("CPACK_PRODUCTBUILD_RESOURCES_DIR")) {
- std::string userResDir =
- this->GetOption("CPACK_PRODUCTBUILD_RESOURCES_DIR");
-
+ if (cmValue v = this->GetOptionIfSet("CPACK_PRODUCTBUILD_RESOURCES_DIR")) {
+ std::string userResDir = *v;
if (!cmSystemTools::CopyADirectory(userResDir, resDir)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem copying the resource files" << std::endl);
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 305ac56..9979dfa 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -113,7 +113,7 @@
log.SetOutputPrefix("CPack: ");
log.SetVerbosePrefix("CPack Verbose: ");
- if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
+ if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Current working directory cannot be established.\n");
return 1;
@@ -208,6 +208,7 @@
CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
CommandArgument::setToTrue(listPresets) },
CommandArgument{ "-D", CommandArgument::Values::One,
+ CommandArgument::RequiresSeparator::No,
[&log, &definitions](const std::string& arg, cmake*,
cmMakefile*) -> bool {
std::string value = arg;
@@ -254,7 +255,7 @@
// Set up presets
if (!preset.empty() || listPresets) {
- const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ const auto workingDirectory = cmSystemTools::GetLogicalWorkingDirectory();
auto const presetGeneratorsPresent =
[&generators](const cmCMakePresetsGraph::PackagePreset& p) {
@@ -349,7 +350,8 @@
return 1;
}
- cmSystemTools::ChangeDirectory(expandedConfigurePreset->BinaryDir);
+ cmSystemTools::SetLogicalWorkingDirectory(
+ expandedConfigurePreset->BinaryDir);
auto presetEnvironment = expandedPreset->Environment;
for (auto const& var : presetEnvironment) {
@@ -405,9 +407,9 @@
bool cpackConfigFileSpecified = true;
if (!cpackConfigFile.empty()) {
- cpackConfigFile = cmSystemTools::CollapseFullPath(cpackConfigFile);
+ cpackConfigFile = cmSystemTools::ToNormalizedPathOnDisk(cpackConfigFile);
} else {
- cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(),
+ cpackConfigFile = cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(),
"/CPackConfig.cmake");
cpackConfigFileSpecified = false;
}
@@ -479,7 +481,7 @@
if (!cpackProjectDirectory.empty()) {
// The value has been set on the command line. Ensure it is absolute.
cpackProjectDirectory =
- cmSystemTools::CollapseFullPath(cpackProjectDirectory);
+ cmSystemTools::ToNormalizedPathOnDisk(cpackProjectDirectory);
} else {
// The value has not been set on the command line. Check config file.
if (cmValue pd = globalMF.GetDefinition("CPACK_PACKAGE_DIRECTORY")) {
@@ -487,7 +489,7 @@
cpackProjectDirectory = cmSystemTools::CollapseFullPath(*pd);
} else {
// Default to the current working directory.
- cpackProjectDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ cpackProjectDirectory = cmSystemTools::GetLogicalWorkingDirectory();
}
}
globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 87081f0..acbc98e 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -16,6 +16,7 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -70,8 +71,8 @@
return 0;
}
-cmCTestBZR::cmCTestBZR(cmCTest* ct, std::ostream& log)
- : cmCTestGlobalVC(ct, log)
+cmCTestBZR::cmCTestBZR(cmCTest* ct, cmMakefile* mf, std::ostream& log)
+ : cmCTestGlobalVC(ct, mf, log)
{
this->PriorRev = this->Unknown;
// Even though it is specified in the documentation, with bzr 1.13
@@ -363,9 +364,9 @@
bool cmCTestBZR::UpdateImpl()
{
// Get user-specified update options.
- std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_UPDATE_OPTIONS");
if (opts.empty()) {
- opts = this->CTest->GetCTestConfiguration("BZRUpdateOptions");
+ opts = this->Makefile->GetSafeDefinition("CTEST_BZR_UPDATE_OPTIONS");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
diff --git a/Source/CTest/cmCTestBZR.h b/Source/CTest/cmCTestBZR.h
index eb0dbbe..96c2038 100644
--- a/Source/CTest/cmCTestBZR.h
+++ b/Source/CTest/cmCTestBZR.h
@@ -10,6 +10,7 @@
#include "cmCTestGlobalVC.h"
class cmCTest;
+class cmMakefile;
/** \class cmCTestBZR
* \brief Interaction with bzr command-line tool
@@ -19,7 +20,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestBZR(cmCTest* ctest, std::ostream& log);
+ cmCTestBZR(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestBZR() override;
diff --git a/Source/CTest/cmCTestBuildAndTest.cxx b/Source/CTest/cmCTestBuildAndTest.cxx
new file mode 100644
index 0000000..a142445
--- /dev/null
+++ b/Source/CTest/cmCTestBuildAndTest.cxx
@@ -0,0 +1,341 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCTestBuildAndTest.h"
+
+#include <chrono>
+#include <cstdint>
+#include <iostream>
+#include <ratio>
+#include <utility>
+
+#include <cm3p/uv.h>
+
+#include "cmBuildOptions.h"
+#include "cmCTest.h"
+#include "cmCTestTestHandler.h"
+#include "cmGlobalGenerator.h"
+#include "cmMakefile.h"
+#include "cmProcessOutput.h"
+#include "cmState.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
+#include "cmWorkingDirectory.h"
+#include "cmake.h"
+
+struct cmMessageMetadata;
+
+cmCTestBuildAndTest::cmCTestBuildAndTest(cmCTest* ctest)
+ : CTest(ctest)
+{
+}
+
+bool cmCTestBuildAndTest::RunCMake(cmake* cm)
+{
+ std::vector<std::string> args;
+ args.push_back(cmSystemTools::GetCMakeCommand());
+ args.push_back(this->SourceDir);
+ if (!this->BuildGenerator.empty()) {
+ args.push_back("-G" + this->BuildGenerator);
+ }
+ if (!this->BuildGeneratorPlatform.empty()) {
+ args.push_back("-A" + this->BuildGeneratorPlatform);
+ }
+ if (!this->BuildGeneratorToolset.empty()) {
+ args.push_back("-T" + this->BuildGeneratorToolset);
+ }
+
+ const char* config = nullptr;
+ if (!this->CTest->GetConfigType().empty()) {
+ config = this->CTest->GetConfigType().c_str();
+ }
+
+ if (config) {
+ args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config));
+ }
+ if (!this->BuildMakeProgram.empty() &&
+ (this->BuildGenerator.find("Make") != std::string::npos ||
+ this->BuildGenerator.find("Ninja") != std::string::npos)) {
+ args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram);
+ }
+
+ for (std::string const& opt : this->BuildOptions) {
+ args.push_back(opt);
+ }
+ std::cout << "======== CMake output ======\n";
+ if (cm->Run(args) != 0) {
+ std::cout << "======== End CMake output ======\n"
+ "Error: cmake execution failed\n";
+ return false;
+ }
+ // do another config?
+ if (this->BuildTwoConfig) {
+ if (cm->Run(args) != 0) {
+ std::cout << "======== End CMake output ======\n"
+ "Error: cmake execution failed\n";
+ return false;
+ }
+ }
+ std::cout << "======== End CMake output ======\n";
+ return true;
+}
+
+bool cmCTestBuildAndTest::RunTest(std::vector<std::string> const& argv,
+ int* retVal, cmDuration timeout)
+{
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(argv).SetMergedBuiltinStreams();
+ auto chain = builder.Start();
+
+ cmProcessOutput processOutput(cmProcessOutput::Auto);
+ cm::uv_pipe_ptr outputStream;
+ outputStream.init(chain.GetLoop(), 0);
+ uv_pipe_open(outputStream, chain.OutputStream());
+ auto outputHandle = cmUVStreamRead(
+ outputStream,
+ [&processOutput](std::vector<char> data) {
+ std::string decoded;
+ processOutput.DecodeText(data.data(), data.size(), decoded);
+ std::cout << decoded << std::flush;
+ },
+ []() {});
+
+ bool complete = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0));
+
+ bool result = false;
+
+ if (complete) {
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ *retVal = static_cast<int>(status.ExitStatus);
+ result = true;
+ break;
+ case cmUVProcessChain::ExceptionCode::Spawn: {
+ std::cout << "\n*** ERROR executing: " << exception.second;
+ } break;
+ default: {
+ *retVal = status.TermSignal;
+ std::cout << "\n*** Exception executing: " << exception.second;
+ } break;
+ }
+ }
+
+ return result;
+}
+
+class cmCTestBuildAndTestCaptureRAII
+{
+ cmake& CM;
+
+public:
+ cmCTestBuildAndTestCaptureRAII(cmake& cm)
+ : CM(cm)
+ {
+ cmSystemTools::SetMessageCallback(
+ [](const std::string& msg, const cmMessageMetadata& /* unused */) {
+ std::cout << msg << std::endl;
+ });
+
+ cmSystemTools::SetStdoutCallback(
+ [](std::string const& m) { std::cout << m << std::flush; });
+ cmSystemTools::SetStderrCallback(
+ [](std::string const& m) { std::cout << m << std::flush; });
+
+ this->CM.SetProgressCallback([](const std::string& msg, float prog) {
+ if (prog < 0) {
+ std::cout << msg << std::endl;
+ }
+ });
+ }
+
+ ~cmCTestBuildAndTestCaptureRAII()
+ {
+ this->CM.SetProgressCallback(nullptr);
+ cmSystemTools::SetStderrCallback(nullptr);
+ cmSystemTools::SetStdoutCallback(nullptr);
+ cmSystemTools::SetMessageCallback(nullptr);
+ }
+
+ cmCTestBuildAndTestCaptureRAII(const cmCTestBuildAndTestCaptureRAII&) =
+ delete;
+ cmCTestBuildAndTestCaptureRAII& operator=(
+ const cmCTestBuildAndTestCaptureRAII&) = delete;
+};
+
+int cmCTestBuildAndTest::Run()
+{
+ // if the generator and make program are not specified then it is an error
+ if (this->BuildGenerator.empty()) {
+ std::cout << "--build-and-test requires that the generator "
+ "be provided using the --build-generator "
+ "command line option.\n";
+ return 1;
+ }
+
+ cmake cm(cmake::RoleProject, cmState::Project);
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cmCTestBuildAndTestCaptureRAII captureRAII(cm);
+ static_cast<void>(captureRAII);
+
+ if (this->CTest->GetConfigType().empty() && !this->ConfigSample.empty()) {
+ // use the config sample to set the ConfigType
+ std::string fullPath;
+ std::string resultingConfig;
+ std::vector<std::string> extraPaths;
+ std::vector<std::string> failed;
+ fullPath = cmCTestTestHandler::FindExecutable(
+ this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed);
+ if (!fullPath.empty() && !resultingConfig.empty()) {
+ this->CTest->SetConfigType(resultingConfig);
+ }
+ std::cout << "Using config sample with results: " << fullPath << " and "
+ << resultingConfig << std::endl;
+ }
+
+ // we need to honor the timeout specified, the timeout include cmake, build
+ // and test time
+ auto clock_start = std::chrono::steady_clock::now();
+
+ // make sure the binary dir is there
+ std::cout << "Internal cmake changing into directory: " << this->BinaryDir
+ << std::endl;
+ if (!cmSystemTools::FileIsDirectory(this->BinaryDir)) {
+ cmSystemTools::MakeDirectory(this->BinaryDir);
+ }
+ cmWorkingDirectory workdir(this->BinaryDir);
+ if (workdir.Failed()) {
+ std::cout << workdir.GetError() << '\n';
+ return 1;
+ }
+
+ if (this->BuildNoCMake) {
+ // Make the generator available for the Build call below.
+ cm.SetGlobalGenerator(cm.CreateGlobalGenerator(this->BuildGenerator));
+ if (!this->BuildGeneratorPlatform.empty()) {
+ cmMakefile mf(cm.GetGlobalGenerator(), cm.GetCurrentSnapshot());
+ if (!cm.GetGlobalGenerator()->SetGeneratorPlatform(
+ this->BuildGeneratorPlatform, &mf)) {
+ return 1;
+ }
+ }
+
+ // Load the cache to make CMAKE_MAKE_PROGRAM available.
+ cm.LoadCache(this->BinaryDir);
+ } else {
+ // do the cmake step, no timeout here since it is not a sub process
+ if (!this->RunCMake(&cm)) {
+ return 1;
+ }
+ }
+
+ // do the build
+ if (this->BuildTargets.empty()) {
+ this->BuildTargets.emplace_back();
+ }
+ for (std::string const& tar : this->BuildTargets) {
+ cmDuration remainingTime = std::chrono::seconds(0);
+ if (this->Timeout > cmDuration::zero()) {
+ remainingTime =
+ this->Timeout - (std::chrono::steady_clock::now() - clock_start);
+ if (remainingTime <= std::chrono::seconds(0)) {
+ std::cout << "--build-and-test timeout exceeded. ";
+ return 1;
+ }
+ }
+ const char* config = nullptr;
+ if (!this->CTest->GetConfigType().empty()) {
+ config = this->CTest->GetConfigType().c_str();
+ }
+ if (!config) {
+ config = "Debug";
+ }
+
+ cmBuildOptions buildOptions(!this->BuildNoClean, false,
+ PackageResolveMode::Disable);
+ int retVal = cm.GetGlobalGenerator()->Build(
+ cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir,
+ this->BuildProject, { tar }, std::cout, this->BuildMakeProgram, config,
+ buildOptions, false, remainingTime, cmSystemTools::OUTPUT_PASSTHROUGH);
+ // if the build failed then return
+ if (retVal) {
+ return 1;
+ }
+ }
+
+ // if no test was specified then we are done
+ if (this->TestCommand.empty()) {
+ return 0;
+ }
+
+ // now run the compiled test if we can find it
+ // store the final location in fullPath
+ std::string fullPath;
+ std::string resultingConfig;
+ std::vector<std::string> extraPaths;
+ // if this->ExecutableDirectory is set try that as well
+ if (!this->ExecutableDirectory.empty()) {
+ std::string tempPath =
+ cmStrCat(this->ExecutableDirectory, '/', this->TestCommand);
+ extraPaths.push_back(tempPath);
+ }
+ std::vector<std::string> failed;
+ fullPath = cmCTestTestHandler::FindExecutable(
+ this->CTest, this->TestCommand, resultingConfig, extraPaths, failed);
+
+ if (!cmSystemTools::FileExists(fullPath)) {
+ std::cout
+ << "Could not find path to executable, perhaps it was not built: "
+ << this->TestCommand << "\n"
+ << "tried to find it in these places:\n"
+ << fullPath << '\n';
+ for (std::string const& fail : failed) {
+ std::cout << fail << '\n';
+ }
+ return 1;
+ }
+
+ std::vector<std::string> testCommand;
+ testCommand.push_back(fullPath);
+ for (std::string const& testCommandArg : this->TestCommandArgs) {
+ testCommand.push_back(testCommandArg);
+ }
+ int retval = 0;
+ // run the test from the this->BuildRunDir if set
+ if (!this->BuildRunDir.empty()) {
+ std::cout << "Run test in directory: " << this->BuildRunDir << '\n';
+ if (!workdir.SetDirectory(this->BuildRunDir)) {
+ std::cout << workdir.GetError() << '\n';
+ return 1;
+ }
+ }
+ std::cout << "Running test command: \"" << fullPath << '"';
+ for (std::string const& testCommandArg : this->TestCommandArgs) {
+ std::cout << " \"" << testCommandArg << '"';
+ }
+ std::cout << '\n';
+
+ // how much time is remaining
+ cmDuration remainingTime = std::chrono::seconds(0);
+ if (this->Timeout > cmDuration::zero()) {
+ remainingTime =
+ this->Timeout - (std::chrono::steady_clock::now() - clock_start);
+ if (remainingTime <= std::chrono::seconds(0)) {
+ std::cout << "--build-and-test timeout exceeded. ";
+ return 1;
+ }
+ }
+
+ bool runTestRes = this->RunTest(testCommand, &retval, remainingTime);
+
+ if (!runTestRes || retval != 0) {
+ std::cout << "\nTest command failed: " << testCommand[0] << '\n';
+ retval = 1;
+ }
+
+ return retval;
+}
diff --git a/Source/CTest/cmCTestBuildAndTest.h b/Source/CTest/cmCTestBuildAndTest.h
new file mode 100644
index 0000000..f680bc2
--- /dev/null
+++ b/Source/CTest/cmCTestBuildAndTest.h
@@ -0,0 +1,56 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+#include "cmDuration.h"
+
+class cmake;
+class cmCTest;
+
+/** \class cmCTestBuildAndTest
+ * \brief A class that handles ctest -S invocations
+ *
+ */
+class cmCTestBuildAndTest
+{
+public:
+ /*
+ * The main entry point for this class
+ */
+ int Run();
+
+ cmCTestBuildAndTest(cmCTest* ctest);
+
+private:
+ cmCTest* CTest;
+
+ bool RunCMake(cmake* cm);
+ bool RunTest(std::vector<std::string> const& args, int* retVal,
+ cmDuration timeout);
+
+ std::string BuildGenerator;
+ std::string BuildGeneratorPlatform;
+ std::string BuildGeneratorToolset;
+ std::vector<std::string> BuildOptions;
+ bool BuildTwoConfig = false;
+ std::string BuildMakeProgram;
+ std::string ConfigSample;
+ std::string SourceDir;
+ std::string BinaryDir;
+ std::string BuildProject;
+ std::string TestCommand;
+ bool BuildNoClean = false;
+ std::string BuildRunDir;
+ std::string ExecutableDirectory;
+ std::vector<std::string> TestCommandArgs;
+ std::vector<std::string> BuildTargets;
+ bool BuildNoCMake = false;
+ cmDuration Timeout = cmDuration::zero();
+
+ friend class cmCTest;
+};
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
deleted file mode 100644
index 9faabf7..0000000
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCTestBuildAndTestHandler.h"
-
-#include <chrono>
-#include <cstdlib>
-#include <cstring>
-#include <ratio>
-
-#include "cmBuildOptions.h"
-#include "cmCTest.h"
-#include "cmCTestTestHandler.h"
-#include "cmGlobalGenerator.h"
-#include "cmMakefile.h"
-#include "cmState.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmWorkingDirectory.h"
-#include "cmake.h"
-
-struct cmMessageMetadata;
-
-cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
-{
- this->BuildTwoConfig = false;
- this->BuildNoClean = false;
- this->BuildNoCMake = false;
- this->Timeout = cmDuration::zero();
-}
-
-void cmCTestBuildAndTestHandler::Initialize()
-{
- this->BuildTargets.clear();
- this->Superclass::Initialize();
-}
-
-const char* cmCTestBuildAndTestHandler::GetOutput()
-{
- return this->Output.c_str();
-}
-int cmCTestBuildAndTestHandler::ProcessHandler()
-{
- this->Output.clear();
- std::string output;
- cmSystemTools::ResetErrorOccurredFlag();
- int retv = this->RunCMakeAndTest(&this->Output);
- cmSystemTools::ResetErrorOccurredFlag();
- return retv;
-}
-
-int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
- std::ostringstream& out,
- std::string& cmakeOutString,
- cmake* cm)
-{
- std::vector<std::string> args;
- args.push_back(cmSystemTools::GetCMakeCommand());
- args.push_back(this->SourceDir);
- if (!this->BuildGenerator.empty()) {
- args.push_back("-G" + this->BuildGenerator);
- }
- if (!this->BuildGeneratorPlatform.empty()) {
- args.push_back("-A" + this->BuildGeneratorPlatform);
- }
- if (!this->BuildGeneratorToolset.empty()) {
- args.push_back("-T" + this->BuildGeneratorToolset);
- }
-
- const char* config = nullptr;
- if (!this->CTest->GetConfigType().empty()) {
- config = this->CTest->GetConfigType().c_str();
- }
-
- if (config) {
- args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config));
- }
- if (!this->BuildMakeProgram.empty() &&
- (this->BuildGenerator.find("Make") != std::string::npos ||
- this->BuildGenerator.find("Ninja") != std::string::npos)) {
- args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram);
- }
-
- for (std::string const& opt : this->BuildOptions) {
- args.push_back(opt);
- }
- if (cm->Run(args) != 0) {
- out << "Error: cmake execution failed\n";
- out << cmakeOutString << "\n";
- if (outstring) {
- *outstring = out.str();
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl);
- }
- return 1;
- }
- // do another config?
- if (this->BuildTwoConfig) {
- if (cm->Run(args) != 0) {
- out << "Error: cmake execution failed\n";
- out << cmakeOutString << "\n";
- if (outstring) {
- *outstring = out.str();
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl);
- }
- return 1;
- }
- }
- out << "======== CMake output ======\n";
- out << cmakeOutString;
- out << "======== End CMake output ======\n";
- return 0;
-}
-
-class cmCTestBuildAndTestCaptureRAII
-{
- cmake& CM;
-
-public:
- cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s)
- : CM(cm)
- {
- cmSystemTools::SetMessageCallback(
- [&s](const std::string& msg, const cmMessageMetadata& /* unused */) {
- s += msg;
- s += "\n";
- });
-
- cmSystemTools::SetStdoutCallback([&s](std::string const& m) { s += m; });
- cmSystemTools::SetStderrCallback([&s](std::string const& m) { s += m; });
-
- this->CM.SetProgressCallback([&s](const std::string& msg, float prog) {
- if (prog < 0) {
- s += msg;
- s += "\n";
- }
- });
- }
-
- ~cmCTestBuildAndTestCaptureRAII()
- {
- this->CM.SetProgressCallback(nullptr);
- cmSystemTools::SetStderrCallback(nullptr);
- cmSystemTools::SetStdoutCallback(nullptr);
- cmSystemTools::SetMessageCallback(nullptr);
- }
-
- cmCTestBuildAndTestCaptureRAII(const cmCTestBuildAndTestCaptureRAII&) =
- delete;
- cmCTestBuildAndTestCaptureRAII& operator=(
- const cmCTestBuildAndTestCaptureRAII&) = delete;
-};
-
-int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
-{
- // if the generator and make program are not specified then it is an error
- if (this->BuildGenerator.empty()) {
- if (outstring) {
- *outstring = "--build-and-test requires that the generator "
- "be provided using the --build-generator "
- "command line option.\n";
- }
- return 1;
- }
-
- cmake cm(cmake::RoleProject, cmState::Project);
- cm.SetHomeDirectory("");
- cm.SetHomeOutputDirectory("");
- std::string cmakeOutString;
- cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString);
- static_cast<void>(captureRAII);
- std::ostringstream out;
-
- if (this->CTest->GetConfigType().empty() && !this->ConfigSample.empty()) {
- // use the config sample to set the ConfigType
- std::string fullPath;
- std::string resultingConfig;
- std::vector<std::string> extraPaths;
- std::vector<std::string> failed;
- fullPath = cmCTestTestHandler::FindExecutable(
- this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed);
- if (!fullPath.empty() && !resultingConfig.empty()) {
- this->CTest->SetConfigType(resultingConfig);
- }
- out << "Using config sample with results: " << fullPath << " and "
- << resultingConfig << std::endl;
- }
-
- // we need to honor the timeout specified, the timeout include cmake, build
- // and test time
- auto clock_start = std::chrono::steady_clock::now();
-
- // make sure the binary dir is there
- out << "Internal cmake changing into directory: " << this->BinaryDir
- << std::endl;
- if (!cmSystemTools::FileIsDirectory(this->BinaryDir)) {
- cmSystemTools::MakeDirectory(this->BinaryDir);
- }
- cmWorkingDirectory workdir(this->BinaryDir);
- if (workdir.Failed()) {
- auto msg = "Failed to change working directory to " + this->BinaryDir +
- " : " + std::strerror(workdir.GetLastResult()) + "\n";
- if (outstring) {
- *outstring = msg;
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE, msg);
- }
- return 1;
- }
-
- if (this->BuildNoCMake) {
- // Make the generator available for the Build call below.
- cm.SetGlobalGenerator(cm.CreateGlobalGenerator(this->BuildGenerator));
- if (!this->BuildGeneratorPlatform.empty()) {
- cmMakefile mf(cm.GetGlobalGenerator(), cm.GetCurrentSnapshot());
- if (!cm.GetGlobalGenerator()->SetGeneratorPlatform(
- this->BuildGeneratorPlatform, &mf)) {
- return 1;
- }
- }
-
- // Load the cache to make CMAKE_MAKE_PROGRAM available.
- cm.LoadCache(this->BinaryDir);
- } else {
- // do the cmake step, no timeout here since it is not a sub process
- if (this->RunCMake(outstring, out, cmakeOutString, &cm)) {
- return 1;
- }
- }
-
- // do the build
- if (this->BuildTargets.empty()) {
- this->BuildTargets.emplace_back();
- }
- for (std::string const& tar : this->BuildTargets) {
- cmDuration remainingTime = std::chrono::seconds(0);
- if (this->Timeout > cmDuration::zero()) {
- remainingTime =
- this->Timeout - (std::chrono::steady_clock::now() - clock_start);
- if (remainingTime <= std::chrono::seconds(0)) {
- if (outstring) {
- *outstring = "--build-and-test timeout exceeded. ";
- }
- return 1;
- }
- }
- const char* config = nullptr;
- if (!this->CTest->GetConfigType().empty()) {
- config = this->CTest->GetConfigType().c_str();
- }
- if (!config) {
- config = "Debug";
- }
-
- cmBuildOptions buildOptions(!this->BuildNoClean, false,
- PackageResolveMode::Disable);
- int retVal = cm.GetGlobalGenerator()->Build(
- cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir,
- this->BuildProject, { tar }, out, this->BuildMakeProgram, config,
- buildOptions, false, remainingTime);
- // if the build failed then return
- if (retVal) {
- if (outstring) {
- *outstring = out.str();
- }
- return 1;
- }
- }
- if (outstring) {
- *outstring = out.str();
- }
-
- // if no test was specified then we are done
- if (this->TestCommand.empty()) {
- return 0;
- }
-
- // now run the compiled test if we can find it
- // store the final location in fullPath
- std::string fullPath;
- std::string resultingConfig;
- std::vector<std::string> extraPaths;
- // if this->ExecutableDirectory is set try that as well
- if (!this->ExecutableDirectory.empty()) {
- std::string tempPath =
- cmStrCat(this->ExecutableDirectory, '/', this->TestCommand);
- extraPaths.push_back(tempPath);
- }
- std::vector<std::string> failed;
- fullPath = cmCTestTestHandler::FindExecutable(
- this->CTest, this->TestCommand, resultingConfig, extraPaths, failed);
-
- if (!cmSystemTools::FileExists(fullPath)) {
- out << "Could not find path to executable, perhaps it was not built: "
- << this->TestCommand << "\n";
- out << "tried to find it in these places:\n";
- out << fullPath << "\n";
- for (std::string const& fail : failed) {
- out << fail << "\n";
- }
- if (outstring) {
- *outstring = out.str();
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
- }
- return 1;
- }
-
- std::vector<std::string> testCommand;
- testCommand.push_back(fullPath);
- for (std::string const& testCommandArg : this->TestCommandArgs) {
- testCommand.push_back(testCommandArg);
- }
- std::string outs;
- int retval = 0;
- // run the test from the this->BuildRunDir if set
- if (!this->BuildRunDir.empty()) {
- out << "Run test in directory: " << this->BuildRunDir << "\n";
- if (!workdir.SetDirectory(this->BuildRunDir)) {
- out << "Failed to change working directory : "
- << std::strerror(workdir.GetLastResult()) << "\n";
- if (outstring) {
- *outstring = out.str();
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
- }
- return 1;
- }
- }
- out << "Running test command: \"" << fullPath << "\"";
- for (std::string const& testCommandArg : this->TestCommandArgs) {
- out << " \"" << testCommandArg << "\"";
- }
- out << "\n";
-
- // how much time is remaining
- cmDuration remainingTime = std::chrono::seconds(0);
- if (this->Timeout > cmDuration::zero()) {
- remainingTime =
- this->Timeout - (std::chrono::steady_clock::now() - clock_start);
- if (remainingTime <= std::chrono::seconds(0)) {
- if (outstring) {
- *outstring = "--build-and-test timeout exceeded. ";
- }
- return 1;
- }
- }
-
- bool runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, nullptr,
- remainingTime, nullptr);
-
- if (!runTestRes || retval != 0) {
- out << "Test command failed: " << testCommand[0] << "\n";
- retval = 1;
- }
-
- out << outs << "\n";
- if (outstring) {
- *outstring = out.str();
- } else {
- cmCTestLog(this->CTest, OUTPUT, out.str() << std::endl);
- }
- return retval;
-}
-
-int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
- const std::string& currentArg, size_t& idx,
- const std::vector<std::string>& allArgs, bool& validArg)
-{
- bool buildAndTestArg = true;
- // --build-and-test options
- if (cmHasLiteralPrefix(currentArg, "--build-and-test") &&
- idx < allArgs.size() - 1) {
- if (idx + 2 < allArgs.size()) {
- idx++;
- this->SourceDir = allArgs[idx];
- idx++;
- this->BinaryDir = allArgs[idx];
- // dir must exist before CollapseFullPath is called
- cmSystemTools::MakeDirectory(this->BinaryDir);
- this->BinaryDir = cmSystemTools::CollapseFullPath(this->BinaryDir);
- this->SourceDir = cmSystemTools::CollapseFullPath(this->SourceDir);
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "--build-and-test must have source and binary dir"
- << std::endl);
- return 0;
- }
- } else if (cmHasLiteralPrefix(currentArg, "--build-target") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->BuildTargets.push_back(allArgs[idx]);
- } else if (cmHasLiteralPrefix(currentArg, "--build-nocmake")) {
- this->BuildNoCMake = true;
- } else if (cmHasLiteralPrefix(currentArg, "--build-run-dir") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->BuildRunDir = allArgs[idx];
- } else if (cmHasLiteralPrefix(currentArg, "--build-two-config")) {
- this->BuildTwoConfig = true;
- } else if (cmHasLiteralPrefix(currentArg, "--build-exe-dir") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->ExecutableDirectory = allArgs[idx];
- } else if (cmHasLiteralPrefix(currentArg, "--test-timeout") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->Timeout = cmDuration(atof(allArgs[idx].c_str()));
- } else if (currentArg == "--build-generator" && idx < allArgs.size() - 1) {
- idx++;
- this->BuildGenerator = allArgs[idx];
- } else if (currentArg == "--build-generator-platform" &&
- idx < allArgs.size() - 1) {
- idx++;
- this->BuildGeneratorPlatform = allArgs[idx];
- } else if (currentArg == "--build-generator-toolset" &&
- idx < allArgs.size() - 1) {
- idx++;
- this->BuildGeneratorToolset = allArgs[idx];
- } else if (cmHasLiteralPrefix(currentArg, "--build-project") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->BuildProject = allArgs[idx];
- } else if (cmHasLiteralPrefix(currentArg, "--build-makeprogram") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->BuildMakeProgram = allArgs[idx];
- } else if (cmHasLiteralPrefix(currentArg, "--build-config-sample") &&
- idx < allArgs.size() - 1) {
- idx++;
- this->ConfigSample = allArgs[idx];
- } else if (cmHasLiteralPrefix(currentArg, "--build-noclean")) {
- this->BuildNoClean = true;
- } else if (cmHasLiteralPrefix(currentArg, "--build-options")) {
- while (idx + 1 < allArgs.size() && allArgs[idx + 1] != "--build-target" &&
- allArgs[idx + 1] != "--test-command") {
- ++idx;
- this->BuildOptions.push_back(allArgs[idx]);
- }
- } else if (cmHasLiteralPrefix(currentArg, "--test-command") &&
- idx < allArgs.size() - 1) {
- ++idx;
- this->TestCommand = allArgs[idx];
- while (idx + 1 < allArgs.size()) {
- ++idx;
- this->TestCommandArgs.push_back(allArgs[idx]);
- }
- } else {
- buildAndTestArg = false;
- }
- validArg = validArg || buildAndTestArg;
- return 1;
-}
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
deleted file mode 100644
index 60b3a11..0000000
--- a/Source/CTest/cmCTestBuildAndTestHandler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <cstddef>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "cmCTestGenericHandler.h"
-#include "cmDuration.h"
-
-class cmake;
-
-/** \class cmCTestBuildAndTestHandler
- * \brief A class that handles ctest -S invocations
- *
- */
-class cmCTestBuildAndTestHandler : public cmCTestGenericHandler
-{
-public:
- using Superclass = cmCTestGenericHandler;
-
- /*
- * The main entry point for this class
- */
- int ProcessHandler() override;
-
- //! Set all the build and test arguments
- int ProcessCommandLineArguments(const std::string& currentArg, size_t& idx,
- const std::vector<std::string>& allArgs,
- bool& validArg) override;
-
- /*
- * Get the output variable
- */
- const char* GetOutput();
-
- cmCTestBuildAndTestHandler();
-
- void Initialize() override;
-
-protected:
- //! Run CMake and build a test and then run it as a single test.
- int RunCMakeAndTest(std::string* output);
- int RunCMake(std::string* outstring, std::ostringstream& out,
- std::string& cmakeOutString, cmake* cm);
-
- std::string Output;
-
- std::string BuildGenerator;
- std::string BuildGeneratorPlatform;
- std::string BuildGeneratorToolset;
- std::vector<std::string> BuildOptions;
- bool BuildTwoConfig;
- std::string BuildMakeProgram;
- std::string ConfigSample;
- std::string SourceDir;
- std::string BinaryDir;
- std::string BuildProject;
- std::string TestCommand;
- bool BuildNoClean;
- std::string BuildRunDir;
- std::string ExecutableDirectory;
- std::vector<std::string> TestCommandArgs;
- std::vector<std::string> BuildTargets;
- bool BuildNoCMake;
- cmDuration Timeout;
-};
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index d8ef195..b57c903 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -5,11 +5,14 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
-#include "cmCommand.h"
+#include "cmCTestGenericHandler.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -18,45 +21,37 @@
#include "cmValue.h"
#include "cmake.h"
-class cmExecutionStatus;
-
-std::unique_ptr<cmCommand> cmCTestBuildCommand::Clone()
+bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
{
- auto ni = cm::make_unique<cmCTestBuildCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
+ static auto const parser =
+ cmArgumentParser<BuildArguments>{ MakeHandlerParser<BuildArguments>() }
+ .Bind("NUMBER_ERRORS"_s, &BuildArguments::NumberErrors)
+ .Bind("NUMBER_WARNINGS"_s, &BuildArguments::NumberWarnings)
+ .Bind("TARGET"_s, &BuildArguments::Target)
+ .Bind("CONFIGURATION"_s, &BuildArguments::Configuration)
+ .Bind("FLAGS"_s, &BuildArguments::Flags)
+ .Bind("PROJECT_NAME"_s, &BuildArguments::ProjectName)
+ .Bind("PARALLEL_LEVEL"_s, &BuildArguments::ParallelLevel);
+
+ return this->Invoke(parser, args, status, [&](BuildArguments& a) {
+ return this->ExecuteHandlerCommand(a, status);
+ });
}
-void cmCTestBuildCommand::BindArguments()
+std::unique_ptr<cmCTestGenericHandler> cmCTestBuildCommand::InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const
{
- this->cmCTestHandlerCommand::BindArguments();
- this->Bind("NUMBER_ERRORS"_s, this->NumberErrors);
- this->Bind("NUMBER_WARNINGS"_s, this->NumberWarnings);
- this->Bind("TARGET"_s, this->Target);
- this->Bind("CONFIGURATION"_s, this->Configuration);
- this->Bind("FLAGS"_s, this->Flags);
- this->Bind("PROJECT_NAME"_s, this->ProjectName);
- this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel);
-}
+ cmMakefile& mf = status.GetMakefile();
+ auto const& args = static_cast<BuildArguments&>(arguments);
+ auto handler = cm::make_unique<cmCTestBuildHandler>(this->CTest);
-cmCTestBuildCommand::~cmCTestBuildCommand() = default;
-
-cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
-{
- cmCTestBuildHandler* handler = this->CTest->GetBuildHandler();
- handler->Initialize();
-
- this->Handler = handler;
-
- cmValue ctestBuildCommand =
- this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
+ cmValue ctestBuildCommand = mf.GetDefinition("CTEST_BUILD_COMMAND");
if (cmNonempty(ctestBuildCommand)) {
this->CTest->SetCTestConfiguration("MakeCommand", *ctestBuildCommand,
- this->Quiet);
+ args.Quiet);
} else {
- cmValue cmakeGeneratorName =
- this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
+ cmValue cmakeGeneratorName = mf.GetDefinition("CTEST_CMAKE_GENERATOR");
// Build configuration is determined by: CONFIGURATION argument,
// or CTEST_BUILD_CONFIGURATION script variable, or
@@ -64,54 +59,46 @@
// line argument... in that order.
//
cmValue ctestBuildConfiguration =
- this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
- std::string cmakeBuildConfiguration = cmNonempty(this->Configuration)
- ? this->Configuration
+ mf.GetDefinition("CTEST_BUILD_CONFIGURATION");
+ std::string cmakeBuildConfiguration = cmNonempty(args.Configuration)
+ ? args.Configuration
: cmNonempty(ctestBuildConfiguration) ? *ctestBuildConfiguration
: this->CTest->GetConfigType();
- const std::string& cmakeBuildAdditionalFlags = cmNonempty(this->Flags)
- ? this->Flags
- : this->Makefile->GetSafeDefinition("CTEST_BUILD_FLAGS");
- const std::string& cmakeBuildTarget = cmNonempty(this->Target)
- ? this->Target
- : this->Makefile->GetSafeDefinition("CTEST_BUILD_TARGET");
+ const std::string& cmakeBuildAdditionalFlags = cmNonempty(args.Flags)
+ ? args.Flags
+ : mf.GetSafeDefinition("CTEST_BUILD_FLAGS");
+ const std::string& cmakeBuildTarget = cmNonempty(args.Target)
+ ? args.Target
+ : mf.GetSafeDefinition("CTEST_BUILD_TARGET");
if (cmNonempty(cmakeGeneratorName)) {
if (cmakeBuildConfiguration.empty()) {
cmakeBuildConfiguration = "Release";
}
- if (this->GlobalGenerator) {
- if (this->GlobalGenerator->GetName() != *cmakeGeneratorName) {
- this->GlobalGenerator.reset();
- }
- }
- if (!this->GlobalGenerator) {
- this->GlobalGenerator =
- this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
- *cmakeGeneratorName);
- if (!this->GlobalGenerator) {
- std::string e = cmStrCat("could not create generator named \"",
- *cmakeGeneratorName, '"');
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
- cmSystemTools::SetFatalErrorOccurred();
- return nullptr;
- }
+
+ auto globalGenerator =
+ mf.GetCMakeInstance()->CreateGlobalGenerator(*cmakeGeneratorName);
+ if (!globalGenerator) {
+ std::string e = cmStrCat("could not create generator named \"",
+ *cmakeGeneratorName, '"');
+ mf.IssueMessage(MessageType::FATAL_ERROR, e);
+ cmSystemTools::SetFatalErrorOccurred();
+ return nullptr;
}
if (cmakeBuildConfiguration.empty()) {
cmakeBuildConfiguration = "Debug";
}
std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory");
- std::string buildCommand =
- this->GlobalGenerator->GenerateCMakeBuildCommand(
- cmakeBuildTarget, cmakeBuildConfiguration, this->ParallelLevel,
- cmakeBuildAdditionalFlags, this->Makefile->IgnoreErrorsCMP0061());
+ std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand(
+ cmakeBuildTarget, cmakeBuildConfiguration, args.ParallelLevel,
+ cmakeBuildAdditionalFlags, mf.IgnoreErrorsCMP0061());
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetMakeCommand:" << buildCommand << "\n",
- this->Quiet);
+ args.Quiet);
this->CTest->SetCTestConfiguration("MakeCommand", buildCommand,
- this->Quiet);
+ args.Quiet);
} else {
std::ostringstream ostr;
/* clang-format off */
@@ -120,38 +107,39 @@
"is set. Otherwise, set CTEST_BUILD_COMMAND to build the project "
"with a custom command line.";
/* clang-format on */
- this->SetError(ostr.str());
+ status.SetError(ostr.str());
return nullptr;
}
}
- if (cmValue useLaunchers =
- this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) {
+ if (cmValue useLaunchers = mf.GetDefinition("CTEST_USE_LAUNCHERS")) {
this->CTest->SetCTestConfiguration("UseLaunchers", *useLaunchers,
- this->Quiet);
+ args.Quiet);
}
if (cmValue labelsForSubprojects =
- this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+ mf.GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
this->CTest->SetCTestConfiguration("LabelsForSubprojects",
- *labelsForSubprojects, this->Quiet);
+ *labelsForSubprojects, args.Quiet);
}
- handler->SetQuiet(this->Quiet);
- return handler;
+ handler->SetQuiet(args.Quiet);
+ return std::unique_ptr<cmCTestGenericHandler>(std::move(handler));
}
-bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+void cmCTestBuildCommand::ProcessAdditionalValues(
+ cmCTestGenericHandler* generic, HandlerArguments const& arguments,
+ cmExecutionStatus& status) const
{
- bool ret = this->cmCTestHandlerCommand::InitialPass(args, status);
- if (!this->NumberErrors.empty()) {
- this->Makefile->AddDefinition(
- this->NumberErrors, std::to_string(this->Handler->GetTotalErrors()));
+ cmMakefile& mf = status.GetMakefile();
+ auto const& args = static_cast<BuildArguments const&>(arguments);
+ auto const* handler = static_cast<cmCTestBuildHandler*>(generic);
+ if (!args.NumberErrors.empty()) {
+ mf.AddDefinition(args.NumberErrors,
+ std::to_string(handler->GetTotalErrors()));
}
- if (!this->NumberWarnings.empty()) {
- this->Makefile->AddDefinition(
- this->NumberWarnings, std::to_string(this->Handler->GetTotalWarnings()));
+ if (!args.NumberWarnings.empty()) {
+ mf.AddDefinition(args.NumberWarnings,
+ std::to_string(handler->GetTotalWarnings()));
}
- return ret;
}
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index 3b7f4f9..a23966d 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -4,54 +4,42 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
-#include <cm/memory>
-
#include "cmCTestHandlerCommand.h"
-class cmCommand;
-class cmCTestBuildHandler;
-class cmCTestGenericHandler;
class cmExecutionStatus;
-class cmGlobalGenerator;
+class cmCTestGenericHandler;
-/** \class cmCTestBuild
- * \brief Run a ctest script
- *
- * cmCTestBuildCommand defineds the command to build the project.
- */
class cmCTestBuildCommand : public cmCTestHandlerCommand
{
public:
- ~cmCTestBuildCommand() override;
-
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override;
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_build"; }
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- cmCTestBuildHandler* Handler;
- void BindArguments() override;
- cmCTestGenericHandler* InitializeHandler() override;
+ struct BuildArguments : HandlerArguments
+ {
+ std::string NumberErrors;
+ std::string NumberWarnings;
+ std::string Target;
+ std::string Configuration;
+ std::string Flags;
+ std::string ProjectName;
+ std::string ParallelLevel;
+ };
- std::string NumberErrors;
- std::string NumberWarnings;
- std::string Target;
- std::string Configuration;
- std::string Flags;
- std::string ProjectName;
- std::string ParallelLevel;
+private:
+ std::string GetName() const override { return "ctest_build"; }
+
+ std::unique_ptr<cmCTestGenericHandler> InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const override;
+
+ void ProcessAdditionalValues(cmCTestGenericHandler* handler,
+ HandlerArguments const& arguments,
+ cmExecutionStatus& status) const override;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index e962cc7..d5d269e 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -176,62 +176,10 @@
{ nullptr, 0, 0 }
};
-cmCTestBuildHandler::cmCTestBuildHandler()
+cmCTestBuildHandler::cmCTestBuildHandler(cmCTest* ctest)
+ : Superclass(ctest)
+ , LastErrorOrWarning(this->ErrorsAndWarnings.end())
{
- this->MaxPreContext = 10;
- this->MaxPostContext = 10;
-
- this->MaxErrors = 50;
- this->MaxWarnings = 50;
-
- this->LastErrorOrWarning = this->ErrorsAndWarnings.end();
-
- this->UseCTestLaunch = false;
-}
-
-void cmCTestBuildHandler::Initialize()
-{
- this->Superclass::Initialize();
- this->StartBuild.clear();
- this->EndBuild.clear();
- this->CustomErrorMatches.clear();
- this->CustomErrorExceptions.clear();
- this->CustomWarningMatches.clear();
- this->CustomWarningExceptions.clear();
- this->ReallyCustomWarningMatches.clear();
- this->ReallyCustomWarningExceptions.clear();
- this->ErrorWarningFileLineRegex.clear();
-
- this->ErrorMatchRegex.clear();
- this->ErrorExceptionRegex.clear();
- this->WarningMatchRegex.clear();
- this->WarningExceptionRegex.clear();
- this->BuildProcessingQueue.clear();
- this->BuildProcessingErrorQueue.clear();
- this->BuildOutputLogSize = 0;
- this->CurrentProcessingLine.clear();
-
- this->SimplifySourceDir.clear();
- this->SimplifyBuildDir.clear();
- this->OutputLineCounter = 0;
- this->ErrorsAndWarnings.clear();
- this->LastErrorOrWarning = this->ErrorsAndWarnings.end();
- this->PostContextCount = 0;
- this->MaxPreContext = 10;
- this->MaxPostContext = 10;
- this->PreContext.clear();
-
- this->TotalErrors = 0;
- this->TotalWarnings = 0;
- this->LastTickChar = 0;
-
- this->ErrorQuotaReached = false;
- this->WarningQuotaReached = false;
-
- this->MaxErrors = 50;
- this->MaxWarnings = 50;
-
- this->UseCTestLaunch = false;
}
void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile* mf)
@@ -502,7 +450,7 @@
void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml)
{
- this->CTest->StartXML(xml, this->AppendXML);
+ this->CTest->StartXML(xml, this->CMake, this->AppendXML);
this->CTest->GenerateSubprojectsOutput(xml);
xml.StartElement("Build");
xml.Element("StartDateTime", this->StartBuild);
@@ -580,9 +528,6 @@
int numErrorsAllowed = this->MaxErrors;
int numWarningsAllowed = this->MaxWarnings;
std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory");
- // make sure the source dir is in the correct case on windows
- // via a call to collapse full path.
- srcdir = cmStrCat(cmSystemTools::CollapseFullPath(srcdir), '/');
for (it = ew.begin();
it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++) {
cmCTestBuildErrorWarning* cm = &(*it);
@@ -613,8 +558,9 @@
}
} else {
// make sure it is a full path with the correct case
- cm->SourceFile = cmSystemTools::CollapseFullPath(cm->SourceFile);
- cmSystemTools::ReplaceString(cm->SourceFile, srcdir.c_str(), "");
+ cm->SourceFile =
+ cmSystemTools::ToNormalizedPathOnDisk(cm->SourceFile);
+ cmSystemTools::ReplaceString(cm->SourceFile, srcdir, "");
}
cm->LineNumber = atoi(re->match(rit.LineIndex).c_str());
break;
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index 90945b1..98fe2da 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -20,6 +20,7 @@
class cmMakefile;
class cmStringReplaceHelper;
class cmXMLWriter;
+class cmCTest;
/** \class cmCTestBuildHandler
* \brief A class that handles ctest -S invocations
@@ -36,17 +37,12 @@
*/
int ProcessHandler() override;
- cmCTestBuildHandler();
+ cmCTestBuildHandler(cmCTest* ctest);
void PopulateCustomVectors(cmMakefile* mf) override;
- /**
- * Initialize handler
- */
- void Initialize() override;
-
- int GetTotalErrors() { return this->TotalErrors; }
- int GetTotalWarnings() { return this->TotalWarnings; }
+ int GetTotalErrors() const { return this->TotalErrors; }
+ int GetTotalWarnings() const { return this->TotalWarnings; }
private:
std::string GetMakeCommand();
@@ -120,34 +116,34 @@
t_BuildProcessingQueueType BuildProcessingQueue;
t_BuildProcessingQueueType BuildProcessingErrorQueue;
- size_t BuildOutputLogSize;
+ size_t BuildOutputLogSize = 0;
std::vector<char> CurrentProcessingLine;
std::string SimplifySourceDir;
std::string SimplifyBuildDir;
- size_t OutputLineCounter;
+ size_t OutputLineCounter = 0;
using t_ErrorsAndWarningsVector = std::vector<cmCTestBuildErrorWarning>;
t_ErrorsAndWarningsVector ErrorsAndWarnings;
t_ErrorsAndWarningsVector::iterator LastErrorOrWarning;
- size_t PostContextCount;
- size_t MaxPreContext;
- size_t MaxPostContext;
+ size_t PostContextCount = 0;
+ size_t MaxPreContext = 10;
+ size_t MaxPostContext = 10;
std::deque<std::string> PreContext;
- int TotalErrors;
- int TotalWarnings;
- char LastTickChar;
+ int TotalErrors = 0;
+ int TotalWarnings = 0;
+ char LastTickChar = '\0';
- bool ErrorQuotaReached;
- bool WarningQuotaReached;
+ bool ErrorQuotaReached = false;
+ bool WarningQuotaReached = false;
- int MaxErrors;
- int MaxWarnings;
+ int MaxErrors = 50;
+ int MaxWarnings = 50;
// Used to remove ANSI color codes before checking for errors and warnings.
cmStringReplaceHelper* ColorRemover;
- bool UseCTestLaunch;
+ bool UseCTestLaunch = false;
std::string CTestLaunchDir;
class LaunchHelper;
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index badd43e..2be96df 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -11,12 +11,13 @@
#include "cmsys/RegularExpression.hxx"
#include "cmCTest.h"
+#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log)
- : cmCTestVC(ct, log)
+cmCTestCVS::cmCTestCVS(cmCTest* ct, cmMakefile* mf, std::ostream& log)
+ : cmCTestVC(ct, mf, log)
{
}
@@ -75,9 +76,9 @@
bool cmCTestCVS::UpdateImpl()
{
// Get user-specified update options.
- std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_UPDATE_OPTIONS");
if (opts.empty()) {
- opts = this->CTest->GetCTestConfiguration("CVSUpdateOptions");
+ opts = this->Makefile->GetSafeDefinition("CTEST_CVS_UPDATE_OPTIONS");
if (opts.empty()) {
opts = "-dP";
}
diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h
index d20239b..1ea4b95 100644
--- a/Source/CTest/cmCTestCVS.h
+++ b/Source/CTest/cmCTestCVS.h
@@ -12,6 +12,7 @@
#include "cmCTestVC.h"
class cmCTest;
+class cmMakefile;
class cmXMLWriter;
/** \class cmCTestCVS
@@ -22,7 +23,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestCVS(cmCTest* ctest, std::ostream& log);
+ cmCTestCVS(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestCVS() override;
diff --git a/Source/CTest/cmCTestCommand.cxx b/Source/CTest/cmCTestCommand.cxx
new file mode 100644
index 0000000..6ecd18b
--- /dev/null
+++ b/Source/CTest/cmCTestCommand.cxx
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCTestCommand.h"
+
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+
+bool cmCTestCommand::operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status) const
+{
+ cmMakefile& mf = status.GetMakefile();
+ std::vector<std::string> expandedArguments;
+ if (!mf.ExpandArguments(args, expandedArguments)) {
+ // There was an error expanding arguments. It was already
+ // reported, so we can skip this command without error.
+ return true;
+ }
+ return this->InitialPass(expandedArguments, status);
+}
diff --git a/Source/CTest/cmCTestCommand.h b/Source/CTest/cmCTestCommand.h
index 007378d..777910a 100644
--- a/Source/CTest/cmCTestCommand.h
+++ b/Source/CTest/cmCTestCommand.h
@@ -2,10 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
-#include "cmCommand.h"
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
class cmCTest;
-class cmCTestScriptHandler;
+class cmExecutionStatus;
+struct cmListFileArgument;
/** \class cmCTestCommand
* \brief A superclass for all commands added to the CTestScriptHandler
@@ -14,15 +18,25 @@
* the ctest script handlers parser.
*
*/
-class cmCTestCommand : public cmCommand
+class cmCTestCommand
{
public:
- cmCTestCommand()
+ cmCTestCommand(cmCTest* ctest)
+ : CTest(ctest)
{
- this->CTest = nullptr;
- this->CTestScriptHandler = nullptr;
}
- cmCTest* CTest;
- cmCTestScriptHandler* CTestScriptHandler;
+ virtual ~cmCTestCommand() = default;
+ cmCTestCommand(cmCTestCommand const&) = default;
+ cmCTestCommand& operator=(cmCTestCommand const&) = default;
+
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status) const;
+
+private:
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus&) const = 0;
+
+protected:
+ cmCTest* CTest = nullptr;
};
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index e0326a9..6255416 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -4,12 +4,17 @@
#include <cstring>
#include <sstream>
+#include <utility>
#include <vector>
+#include <cm/memory>
#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
+#include "cmCTestGenericHandler.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmMakefile.h"
@@ -18,42 +23,38 @@
#include "cmValue.h"
#include "cmake.h"
-void cmCTestConfigureCommand::BindArguments()
+std::unique_ptr<cmCTestGenericHandler>
+cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments,
+ cmExecutionStatus& status) const
{
- this->cmCTestHandlerCommand::BindArguments();
- this->Bind("OPTIONS"_s, this->Options);
-}
-
-cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
-{
+ cmMakefile& mf = status.GetMakefile();
+ auto const& args = static_cast<ConfigureArguments&>(arguments);
cmList options;
- if (!this->Options.empty()) {
- options.assign(this->Options);
+ if (!args.Options.empty()) {
+ options.assign(args.Options);
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) {
- this->SetError(
+ status.SetError(
"Build directory not specified. Either use BUILD "
"argument to CTEST_CONFIGURE command or set CTEST_BINARY_DIRECTORY "
"variable");
return nullptr;
}
- cmValue ctestConfigureCommand =
- this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
+ cmValue ctestConfigureCommand = mf.GetDefinition("CTEST_CONFIGURE_COMMAND");
if (cmNonempty(ctestConfigureCommand)) {
this->CTest->SetCTestConfiguration("ConfigureCommand",
- *ctestConfigureCommand, this->Quiet);
+ *ctestConfigureCommand, args.Quiet);
} else {
- cmValue cmakeGeneratorName =
- this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
+ cmValue cmakeGeneratorName = mf.GetDefinition("CTEST_CMAKE_GENERATOR");
if (cmNonempty(cmakeGeneratorName)) {
const std::string& source_dir =
this->CTest->GetCTestConfiguration("SourceDirectory");
if (source_dir.empty()) {
- this->SetError(
+ status.SetError(
"Source directory not specified. Either use SOURCE "
"argument to CTEST_CONFIGURE command or set CTEST_SOURCE_DIRECTORY "
"variable");
@@ -64,15 +65,15 @@
if (!cmSystemTools::FileExists(cmakelists_file)) {
std::ostringstream e;
e << "CMakeLists.txt file does not exist [" << cmakelists_file << "]";
- this->SetError(e.str());
+ status.SetError(e.str());
return nullptr;
}
bool multiConfig = false;
bool cmakeBuildTypeInOptions = false;
- auto gg = this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
- *cmakeGeneratorName);
+ auto gg =
+ mf.GetCMakeInstance()->CreateGlobalGenerator(*cmakeGeneratorName);
if (gg) {
multiConfig = gg->IsMultiConfig();
gg.reset();
@@ -99,7 +100,7 @@
cmakeConfigureCommand += "\"";
}
- if (this->Makefile->IsOn("CTEST_USE_LAUNCHERS")) {
+ if (mf.IsOn("CTEST_USE_LAUNCHERS")) {
cmakeConfigureCommand += " \"-DCTEST_USE_LAUNCHERS:BOOL=TRUE\"";
}
@@ -108,7 +109,7 @@
cmakeConfigureCommand += "\"";
cmValue cmakeGeneratorPlatform =
- this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
+ mf.GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
if (cmNonempty(cmakeGeneratorPlatform)) {
cmakeConfigureCommand += " \"-A";
cmakeConfigureCommand += *cmakeGeneratorPlatform;
@@ -116,7 +117,7 @@
}
cmValue cmakeGeneratorToolset =
- this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
+ mf.GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
if (cmNonempty(cmakeGeneratorToolset)) {
cmakeConfigureCommand += " \"-T";
cmakeConfigureCommand += *cmakeGeneratorToolset;
@@ -133,9 +134,9 @@
cmakeConfigureCommand += "\"";
this->CTest->SetCTestConfiguration("ConfigureCommand",
- cmakeConfigureCommand, this->Quiet);
+ cmakeConfigureCommand, args.Quiet);
} else {
- this->SetError(
+ status.SetError(
"Configure command is not specified. If this is a "
"\"built with CMake\" project, set CTEST_CMAKE_GENERATOR. If not, "
"set CTEST_CONFIGURE_COMMAND.");
@@ -144,13 +145,25 @@
}
if (cmValue labelsForSubprojects =
- this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+ mf.GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
this->CTest->SetCTestConfiguration("LabelsForSubprojects",
- *labelsForSubprojects, this->Quiet);
+ *labelsForSubprojects, args.Quiet);
}
- cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler();
- handler->Initialize();
- handler->SetQuiet(this->Quiet);
- return handler;
+ auto handler = cm::make_unique<cmCTestConfigureHandler>(this->CTest);
+ handler->SetQuiet(args.Quiet);
+ return std::unique_ptr<cmCTestGenericHandler>(std::move(handler));
+}
+
+bool cmCTestConfigureCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ using Args = ConfigureArguments;
+ static auto const parser =
+ cmArgumentParser<Args>{ MakeHandlerParser<Args>() } //
+ .Bind("OPTIONS"_s, &ConfigureArguments::Options);
+
+ return this->Invoke(parser, args, status, [&](ConfigureArguments& a) {
+ return this->ExecuteHandlerCommand(a, status);
+ });
}
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index f338637..c2c6b3a 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -4,43 +4,32 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
-#include <utility>
-
-#include <cm/memory>
+#include <vector>
#include "cmCTestHandlerCommand.h"
-#include "cmCommand.h"
+class cmExecutionStatus;
class cmCTestGenericHandler;
-/** \class cmCTestConfigure
- * \brief Run a ctest script
- *
- * cmCTestConfigureCommand defineds the command to configures the project.
- */
class cmCTestConfigureCommand : public cmCTestHandlerCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestConfigureCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_configure"; }
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- void BindArguments() override;
- cmCTestGenericHandler* InitializeHandler() override;
+ struct ConfigureArguments : HandlerArguments
+ {
+ std::string Options;
+ };
- std::string Options;
+private:
+ std::string GetName() const override { return "ctest_configure"; }
+
+ std::unique_ptr<cmCTestGenericHandler> InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const override;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index dd8952f..35b6dce 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -11,11 +11,9 @@
#include "cmGeneratedFileStream.h"
#include "cmXMLWriter.h"
-cmCTestConfigureHandler::cmCTestConfigureHandler() = default;
-
-void cmCTestConfigureHandler::Initialize()
+cmCTestConfigureHandler::cmCTestConfigureHandler(cmCTest* ctest)
+ : Superclass(ctest)
{
- this->Superclass::Initialize();
}
// clearly it would be nice if this were broken up into a few smaller
@@ -71,7 +69,7 @@
if (os) {
cmXMLWriter xml(os);
- this->CTest->StartXML(xml, this->AppendXML);
+ this->CTest->StartXML(xml, this->CMake, this->AppendXML);
this->CTest->GenerateSubprojectsOutput(xml);
xml.StartElement("Configure");
xml.Element("StartDateTime", start_time);
diff --git a/Source/CTest/cmCTestConfigureHandler.h b/Source/CTest/cmCTestConfigureHandler.h
index 2aad98c..bcbead7 100644
--- a/Source/CTest/cmCTestConfigureHandler.h
+++ b/Source/CTest/cmCTestConfigureHandler.h
@@ -6,6 +6,8 @@
#include "cmCTestGenericHandler.h"
+class cmCTest;
+
/** \class cmCTestConfigureHandler
* \brief A class that handles ctest -S invocations
*
@@ -20,7 +22,5 @@
*/
int ProcessHandler() override;
- cmCTestConfigureHandler();
-
- void Initialize() override;
+ cmCTestConfigureHandler(cmCTest* ctest);
};
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index 97b0a89..6bed1a3 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -3,36 +3,50 @@
#include "cmCTestCoverageCommand.h"
#include <set>
+#include <utility>
+#include <cm/memory>
#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
+#include "cmCTestGenericHandler.h"
+#include "cmExecutionStatus.h"
-class cmCTestGenericHandler;
+class cmMakefile;
-void cmCTestCoverageCommand::BindArguments()
+std::unique_ptr<cmCTestGenericHandler>
+cmCTestCoverageCommand::InitializeHandler(HandlerArguments& arguments,
+ cmExecutionStatus& status) const
{
- this->cmCTestHandlerCommand::BindArguments();
- this->Bind("LABELS"_s, this->Labels);
-}
-
-cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
-{
+ cmMakefile& mf = status.GetMakefile();
+ auto& args = static_cast<CoverageArguments&>(arguments);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "CoverageCommand", "CTEST_COVERAGE_COMMAND", this->Quiet);
+ &mf, "CoverageCommand", "CTEST_COVERAGE_COMMAND", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS",
- this->Quiet);
- cmCTestCoverageHandler* handler = this->CTest->GetCoverageHandler();
- handler->Initialize();
+ &mf, "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS", args.Quiet);
+ auto handler = cm::make_unique<cmCTestCoverageHandler>(this->CTest);
// If a LABELS option was given, select only files with the labels.
- if (this->Labels) {
+ if (args.Labels) {
handler->SetLabelFilter(
- std::set<std::string>(this->Labels->begin(), this->Labels->end()));
+ std::set<std::string>(args.Labels->begin(), args.Labels->end()));
}
- handler->SetQuiet(this->Quiet);
- return handler;
+ handler->SetQuiet(args.Quiet);
+ return std::unique_ptr<cmCTestGenericHandler>(std::move(handler));
+}
+
+bool cmCTestCoverageCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ using Args = CoverageArguments;
+ static auto const parser =
+ cmArgumentParser<Args>{ MakeHandlerParser<Args>() } //
+ .Bind("LABELS"_s, &CoverageArguments::Labels);
+
+ return this->Invoke(parser, args, status, [&](CoverageArguments& a) {
+ return this->ExecuteHandlerCommand(a, status);
+ });
}
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 55c68b2..dfbb9be 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -4,46 +4,35 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
#include <cm/optional>
#include "cmArgumentParserTypes.h" // IWYU pragma: keep
#include "cmCTestHandlerCommand.h"
-#include "cmCommand.h"
+class cmExecutionStatus;
class cmCTestGenericHandler;
-/** \class cmCTestCoverage
- * \brief Run a ctest script
- *
- * cmCTestCoverageCommand defineds the command to test the project.
- */
class cmCTestCoverageCommand : public cmCTestHandlerCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestCoverageCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_coverage"; }
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- void BindArguments() override;
- cmCTestGenericHandler* InitializeHandler() override;
+ struct CoverageArguments : HandlerArguments
+ {
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Labels;
+ };
- cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Labels;
+private:
+ std::string GetName() const override { return "ctest_coverage"; }
+
+ std::unique_ptr<cmCTestGenericHandler> InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const override;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index cec4a7e..2e63fc8 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -6,7 +6,6 @@
#include <chrono>
#include <cstdio>
#include <cstdlib>
-#include <cstring>
#include <iomanip>
#include <iterator>
#include <memory>
@@ -41,17 +40,9 @@
#define SAFEDIV(x, y) (((y) != 0) ? ((x) / (y)) : (0))
-cmCTestCoverageHandler::cmCTestCoverageHandler() = default;
-
-void cmCTestCoverageHandler::Initialize()
+cmCTestCoverageHandler::cmCTestCoverageHandler(cmCTest* ctest)
+ : Superclass(ctest)
{
- this->Superclass::Initialize();
- this->CustomCoverageExclude.clear();
- this->SourceLabels.clear();
- this->TargetDirs.clear();
- this->LabelIdMap.clear();
- this->Labels.clear();
- this->LabelFilter.clear();
}
void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log)
@@ -100,7 +91,7 @@
void cmCTestCoverageHandler::StartCoverageLogXML(cmXMLWriter& xml)
{
- this->CTest->StartXML(xml, this->AppendXML);
+ this->CTest->StartXML(xml, this->CMake, this->AppendXML);
xml.StartElement("CoverageLog");
xml.Element("StartDateTime", this->CTest->CurrentTime());
xml.Element("StartTime", std::chrono::system_clock::now());
@@ -331,7 +322,7 @@
covSumFile.setf(std::ios::fixed, std::ios::floatfield);
covSumFile.precision(2);
- this->CTest->StartXML(covSumXML, this->AppendXML);
+ this->CTest->StartXML(covSumXML, this->CMake, this->AppendXML);
// Produce output xml files
covSumXML.StartElement("Coverage");
@@ -1325,10 +1316,7 @@
std::string fileDir = cmSystemTools::GetFilenamePath(f);
cmWorkingDirectory workdir(fileDir);
if (workdir.Failed()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Unable to change working directory to "
- << fileDir << " : "
- << std::strerror(workdir.GetLastResult()) << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, workdir.GetError() << std::endl);
cont->Error++;
continue;
}
@@ -1550,9 +1538,7 @@
std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
cmWorkingDirectory workdir(buildDir);
if (workdir.Failed()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Unable to change working directory to " << buildDir
- << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, workdir.GetError() << std::endl);
return false;
}
@@ -1915,7 +1901,7 @@
"Cannot open coverage summary file." << std::endl);
return 0;
}
- this->CTest->StartXML(xml, this->AppendXML);
+ this->CTest->StartXML(xml, this->CMake, this->AppendXML);
auto elapsed_time_start = std::chrono::steady_clock::now();
std::string coverage_start_time = this->CTest->CurrentTime();
xml.StartElement("Coverage");
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 8732723..89969ce 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -17,6 +17,7 @@
class cmGeneratedFileStream;
class cmMakefile;
class cmXMLWriter;
+class cmCTest;
class cmCTestCoverageHandlerContainer
{
@@ -44,9 +45,7 @@
*/
int ProcessHandler() override;
- cmCTestCoverageHandler();
-
- void Initialize() override;
+ cmCTestCoverageHandler(cmCTest* ctest);
/**
* This method is called when reading CTest custom file
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
index 2c92d77..5ae89a1 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
@@ -2,22 +2,98 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestEmptyBinaryDirectoryCommand.h"
-#include "cmCTestScriptHandler.h"
+#include "cmsys/Directory.hxx"
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
-bool cmCTestEmptyBinaryDirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus& status)
+namespace {
+
+// Try to remove the binary directory once
+cmsys::Status TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath)
+{
+ cmsys::Directory directory;
+ directory.Load(directoryPath);
+
+ // Make sure that CMakeCache.txt is deleted last.
+ for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) {
+ std::string path = directory.GetFile(i);
+
+ if (path == "." || path == ".." || path == "CMakeCache.txt") {
+ continue;
+ }
+
+ std::string fullPath = cmStrCat(directoryPath, "/", path);
+
+ bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
+ !cmSystemTools::FileIsSymlink(fullPath);
+
+ cmsys::Status status;
+ if (isDirectory) {
+ status = cmSystemTools::RemoveADirectory(fullPath);
+ } else {
+ status = cmSystemTools::RemoveFile(fullPath);
+ }
+ if (!status) {
+ return status;
+ }
+ }
+
+ return cmSystemTools::RemoveADirectory(directoryPath);
+}
+
+/*
+ * Empty Binary Directory
+ */
+bool EmptyBinaryDirectory(const std::string& sname, std::string& err)
+{
+ // try to avoid deleting root
+ if (sname.size() < 2) {
+ err = "path too short";
+ return false;
+ }
+
+ // consider non existing target directory a success
+ if (!cmSystemTools::FileExists(sname)) {
+ return true;
+ }
+
+ // try to avoid deleting directories that we shouldn't
+ std::string check = cmStrCat(sname, "/CMakeCache.txt");
+
+ if (!cmSystemTools::FileExists(check)) {
+ err = "path does not contain an existing CMakeCache.txt file";
+ return false;
+ }
+
+ cmsys::Status status;
+ for (int i = 0; i < 5; ++i) {
+ status = TryToRemoveBinaryDirectoryOnce(sname);
+ if (status) {
+ return true;
+ }
+ cmSystemTools::Delay(100);
+ }
+
+ err = status.GetString();
+ return false;
+}
+
+} // namespace
+
+bool cmCTestEmptyBinaryDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 1) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string err;
- if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0], err)) {
+ if (!EmptyBinaryDirectory(args[0], err)) {
status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Did not remove the binary directory:\n ", args[0],
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
index ba2b0eb..d19ae98 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -5,42 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
-
-#include "cmCTestCommand.h"
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmCTestEmptyBinaryDirectory
- * \brief Run a ctest script
- *
- * cmLibrarysCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmCTestEmptyBinaryDirectoryCommand : public cmCTestCommand
-{
-public:
- cmCTestEmptyBinaryDirectoryCommand() {}
-
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmCTestEmptyBinaryDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 99c5a2b..1ba8576 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -15,11 +15,11 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmList.h"
+#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
-#include "cmValue.h"
static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
unsigned int minor, unsigned int fix)
@@ -28,8 +28,8 @@
return epic * 10000000 + major * 100000 + minor * 1000 + fix;
}
-cmCTestGIT::cmCTestGIT(cmCTest* ct, std::ostream& log)
- : cmCTestGlobalVC(ct, log)
+cmCTestGIT::cmCTestGIT(cmCTest* ct, cmMakefile* mf, std::ostream& log)
+ : cmCTestGlobalVC(ct, mf, log)
{
this->PriorRev = this->Unknown;
this->CurrentGitVersion = 0;
@@ -146,7 +146,7 @@
!cdup.empty()) {
top_dir += "/";
top_dir += cdup;
- top_dir = cmSystemTools::CollapseFullPath(top_dir);
+ top_dir = cmSystemTools::ToNormalizedPathOnDisk(top_dir);
}
return top_dir;
}
@@ -161,9 +161,9 @@
git_fetch.emplace_back("fetch");
// Add user-specified update options.
- std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_UPDATE_OPTIONS");
if (opts.empty()) {
- opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
+ opts = this->Makefile->GetSafeDefinition("CTEST_GIT_UPDATE_OPTIONS");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
cm::append(git_fetch, args);
@@ -222,7 +222,8 @@
bool cmCTestGIT::UpdateInternal()
{
- std::string custom = this->CTest->GetCTestConfiguration("GITUpdateCustom");
+ std::string custom =
+ this->Makefile->GetSafeDefinition("CTEST_GIT_UPDATE_CUSTOM");
if (!custom.empty()) {
return this->UpdateByCustom(custom);
}
@@ -265,9 +266,7 @@
bool ret;
- std::string init_submodules =
- this->CTest->GetCTestConfiguration("GITInitSubmodules");
- if (cmIsOn(init_submodules)) {
+ if (this->Makefile->IsOn("CTEST_GIT_INIT_SUBMODULES")) {
std::vector<std::string> git_submodule_init = { git, "submodule", "init" };
ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err,
top_dir);
diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h
index a15aef5..c739df8 100644
--- a/Source/CTest/cmCTestGIT.h
+++ b/Source/CTest/cmCTestGIT.h
@@ -10,6 +10,7 @@
#include "cmCTestGlobalVC.h"
class cmCTest;
+class cmMakefile;
/** \class cmCTestGIT
* \brief Interaction with git command-line tool
@@ -19,7 +20,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestGIT(cmCTest* ctest, std::ostream& log);
+ cmCTestGIT(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestGIT() override;
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index dd69968..e4acbef 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -3,113 +3,20 @@
#include "cmCTestGenericHandler.h"
#include <sstream>
-#include <utility>
#include "cmCTest.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-cmCTestGenericHandler::cmCTestGenericHandler()
+cmCTestGenericHandler::cmCTestGenericHandler(cmCTest* ctest)
+ : CTest(ctest)
{
- this->HandlerVerbose = cmSystemTools::OUTPUT_NONE;
- this->CTest = nullptr;
- this->SubmitIndex = 0;
- this->AppendXML = false;
- this->Quiet = false;
- this->TestLoad = 0;
+ this->SetVerbose(ctest->GetExtraVerbose());
+ this->SetSubmitIndex(ctest->GetSubmitIndex());
}
cmCTestGenericHandler::~cmCTestGenericHandler() = default;
-namespace {
-/* Modify the given `map`, setting key `op` to `value` if `value`
- * is non-null, otherwise removing key `op` (if it exists).
- */
-void SetMapValue(cmCTestGenericHandler::t_StringToString& map,
- const std::string& op, const std::string& value)
-{
- map[op] = value;
-}
-void SetMapValue(cmCTestGenericHandler::t_StringToString& map,
- const std::string& op, cmValue value)
-{
- if (!value) {
- map.erase(op);
- return;
- }
-
- map[op] = *value;
-}
-}
-
-void cmCTestGenericHandler::SetOption(const std::string& op,
- const std::string& value)
-{
- SetMapValue(this->Options, op, value);
-}
-void cmCTestGenericHandler::SetOption(const std::string& op, cmValue value)
-{
- SetMapValue(this->Options, op, value);
-}
-
-void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
- const std::string& value)
-{
- this->SetOption(op, value);
- SetMapValue(this->PersistentOptions, op, value);
-}
-void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
- cmValue value)
-{
- this->SetOption(op, value);
- SetMapValue(this->PersistentOptions, op, value);
-}
-
-void cmCTestGenericHandler::AddMultiOption(const std::string& op,
- const std::string& value)
-{
- if (!value.empty()) {
- this->MultiOptions[op].emplace_back(value);
- }
-}
-
-void cmCTestGenericHandler::AddPersistentMultiOption(const std::string& op,
- const std::string& value)
-{
- if (!value.empty()) {
- this->MultiOptions[op].emplace_back(value);
- this->PersistentMultiOptions[op].emplace_back(value);
- }
-}
-
-void cmCTestGenericHandler::Initialize()
-{
- this->AppendXML = false;
- this->TestLoad = 0;
- this->Options = this->PersistentOptions;
- this->MultiOptions = this->PersistentMultiOptions;
-}
-
-cmValue cmCTestGenericHandler::GetOption(const std::string& op)
-{
- auto remit = this->Options.find(op);
- if (remit == this->Options.end()) {
- return nullptr;
- }
- return cmValue(remit->second);
-}
-
-std::vector<std::string> cmCTestGenericHandler::GetMultiOption(
- const std::string& optionName) const
-{
- // Avoid inserting a key, which MultiOptions[op] would do.
- auto remit = this->MultiOptions.find(optionName);
- if (remit == this->MultiOptions.end()) {
- return {};
- }
- return remit->second;
-}
-
bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
const char* name,
cmGeneratedFileStream& xofs)
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
index a189d60..24251c0 100644
--- a/Source/CTest/cmCTestGenericHandler.h
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -4,17 +4,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <map>
#include <string>
-#include <vector>
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmValue.h"
class cmGeneratedFileStream;
class cmMakefile;
+class cmake;
/** \class cmCTestGenericHandler
* \brief A superclass of all CTest Handlers
@@ -44,69 +42,17 @@
virtual int ProcessHandler() = 0;
/**
- * Process command line arguments that are applicable for the handler
+ * Get the CTest instance
*/
- virtual int ProcessCommandLineArguments(
- const std::string& /*currentArg*/, size_t& /*idx*/,
- const std::vector<std::string>& /*allArgs*/, bool& /*valid*/)
- {
- return 1;
- }
-
- /**
- * Initialize handler
- */
- virtual void Initialize();
-
- /**
- * Set the CTest instance
- */
- void SetCTestInstance(cmCTest* ctest) { this->CTest = ctest; }
cmCTest* GetCTestInstance() { return this->CTest; }
/**
* Construct handler
*/
- cmCTestGenericHandler();
+ cmCTestGenericHandler(cmCTest* ctest);
virtual ~cmCTestGenericHandler();
using t_StringToString = std::map<std::string, std::string>;
- using t_StringToMultiString =
- std::map<std::string, std::vector<std::string>>;
-
- /**
- * Options collect a single value from flags; passing the
- * flag multiple times on the command-line *overwrites* values,
- * and only the last one specified counts. Set an option to
- * nullptr to "unset" it.
- *
- * The value is stored as a string. The values set for single
- * and multi-options (see below) live in different spaces,
- * so calling a single-getter for a key that has only been set
- * as a multi-value will return nullptr.
- */
- void SetPersistentOption(const std::string& op, const std::string& value);
- void SetPersistentOption(const std::string& op, cmValue value);
- void SetOption(const std::string& op, const std::string& value);
- void SetOption(const std::string& op, cmValue value);
- cmValue GetOption(const std::string& op);
-
- /**
- * Multi-Options collect one or more values from flags; passing
- * the flag multiple times on the command-line *adds* values,
- * rather than overwriting the previous values.
- *
- * Adding an empty value does nothing.
- *
- * The value is stored as a vector of strings. The values set for single
- * (see above) and multi-options live in different spaces,
- * so calling a multi-getter for a key that has only been set
- * as a single-value will return an empty vector.
- */
- void AddPersistentMultiOption(const std::string& optionName,
- const std::string& value);
- void AddMultiOption(const std::string& optionName, const std::string& value);
- std::vector<std::string> GetMultiOption(const std::string& op) const;
void SetSubmitIndex(int idx) { this->SubmitIndex = idx; }
int GetSubmitIndex() { return this->SubmitIndex; }
@@ -117,21 +63,20 @@
void SetTestLoad(unsigned long load) { this->TestLoad = load; }
unsigned long GetTestLoad() const { return this->TestLoad; }
+ void SetCMakeInstance(cmake* cm) { this->CMake = cm; }
+
protected:
bool StartResultingXML(cmCTest::Part part, const char* name,
cmGeneratedFileStream& xofs);
bool StartLogFile(const char* name, cmGeneratedFileStream& xofs);
- bool AppendXML;
- bool Quiet;
- unsigned long TestLoad;
- cmSystemTools::OutputOption HandlerVerbose;
+ bool AppendXML = false;
+ bool Quiet = false;
+ unsigned long TestLoad = 0;
+ cmSystemTools::OutputOption HandlerVerbose = cmSystemTools::OUTPUT_NONE;
cmCTest* CTest;
- t_StringToString Options;
- t_StringToString PersistentOptions;
- t_StringToMultiString MultiOptions;
- t_StringToMultiString PersistentMultiOptions;
t_StringToString LogFileNames;
+ cmake* CMake = nullptr;
- int SubmitIndex;
+ int SubmitIndex = 0;
};
diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx
index 5f05efb..75c4615 100644
--- a/Source/CTest/cmCTestGlobalVC.cxx
+++ b/Source/CTest/cmCTestGlobalVC.cxx
@@ -9,8 +9,9 @@
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-cmCTestGlobalVC::cmCTestGlobalVC(cmCTest* ct, std::ostream& log)
- : cmCTestVC(ct, log)
+cmCTestGlobalVC::cmCTestGlobalVC(cmCTest* ct, cmMakefile* mf,
+ std::ostream& log)
+ : cmCTestVC(ct, mf, log)
{
this->PriorRev = this->Unknown;
}
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
index 679b0e1..2169ee5 100644
--- a/Source/CTest/cmCTestGlobalVC.h
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -13,6 +13,7 @@
#include "cmCTestVC.h"
class cmCTest;
+class cmMakefile;
class cmXMLWriter;
/** \class cmCTestGlobalVC
@@ -23,7 +24,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestGlobalVC(cmCTest* ctest, std::ostream& log);
+ cmCTestGlobalVC(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestGlobalVC() override;
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 3d56be0..e84e355 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -11,11 +11,12 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-cmCTestHG::cmCTestHG(cmCTest* ct, std::ostream& log)
- : cmCTestGlobalVC(ct, log)
+cmCTestHG::cmCTestHG(cmCTest* ct, cmMakefile* mf, std::ostream& log)
+ : cmCTestGlobalVC(ct, mf, log)
{
this->PriorRev = this->Unknown;
}
@@ -142,9 +143,9 @@
hg_update.emplace_back("-v");
// Add user-specified update options.
- std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_UPDATE_OPTIONS");
if (opts.empty()) {
- opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
+ opts = this->Makefile->GetSafeDefinition("CTEST_HG_UPDATE_OPTIONS");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
cm::append(hg_update, args);
diff --git a/Source/CTest/cmCTestHG.h b/Source/CTest/cmCTestHG.h
index b81f042..47f098c 100644
--- a/Source/CTest/cmCTestHG.h
+++ b/Source/CTest/cmCTestHG.h
@@ -10,6 +10,7 @@
#include "cmCTestGlobalVC.h"
class cmCTest;
+class cmMakefile;
/** \class cmCTestHG
* \brief Interaction with Mercurial command-line tool
@@ -19,7 +20,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestHG(cmCTest* ctest, std::ostream& log);
+ cmCTestHG(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestHG() override;
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index c377d68..6847672 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -4,17 +4,14 @@
#include <algorithm>
#include <cstdlib>
-#include <cstring>
#include <sstream>
#include <cm/string_view>
-#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -72,176 +69,150 @@
};
}
-bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+bool cmCTestHandlerCommand::InvokeImpl(
+ BasicArguments& args, std::vector<std::string> const& unparsed,
+ cmExecutionStatus& status, std::function<bool()> handler) const
{
// save error state and restore it if needed
SaveRestoreErrorState errorState;
- // Allocate space for argument values.
- this->BindArguments();
-
- // Process input arguments.
- std::vector<std::string> unparsedArguments;
- this->Parse(args, &unparsedArguments);
- this->CheckArguments();
-
- std::sort(this->ParsedKeywords.begin(), this->ParsedKeywords.end());
- auto it = std::adjacent_find(this->ParsedKeywords.begin(),
- this->ParsedKeywords.end());
- if (it != this->ParsedKeywords.end()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Called with more than one value for ", *it));
- }
-
- bool const foundBadArgument = !unparsedArguments.empty();
- if (foundBadArgument) {
- this->SetError(cmStrCat("called with unknown argument \"",
- unparsedArguments.front(), "\"."));
- }
- bool const captureCMakeError = !this->CaptureCMakeError.empty();
- // now that arguments are parsed check to see if there is a
- // CAPTURE_CMAKE_ERROR specified let the errorState object know.
- if (captureCMakeError) {
+ if (!args.CaptureCMakeError.empty()) {
errorState.CaptureCMakeError();
}
- // if we found a bad argument then exit before running command
- if (foundBadArgument) {
- // store the cmake error
- if (captureCMakeError) {
- this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
- std::string const err = this->GetName() + " " + status.GetError();
- if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
- }
- // return success because failure is recorded in CAPTURE_CMAKE_ERROR
+
+ bool success = [&]() -> bool {
+ if (args.MaybeReportError(status.GetMakefile())) {
return true;
}
- // return failure because of bad argument
- return false;
+
+ std::sort(args.ParsedKeywords.begin(), args.ParsedKeywords.end());
+ auto const it = std::adjacent_find(args.ParsedKeywords.begin(),
+ args.ParsedKeywords.end());
+ if (it != args.ParsedKeywords.end()) {
+ status.SetError(cmStrCat("called with more than one value for ", *it));
+ return false;
+ }
+
+ if (!unparsed.empty()) {
+ status.SetError(
+ cmStrCat("called with unknown argument \"", unparsed.front(), "\"."));
+ return false;
+ }
+
+ return handler();
+ }();
+
+ if (args.CaptureCMakeError.empty()) {
+ return success;
}
+ if (!success) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ this->GetName() << ' ' << status.GetError() << '\n');
+ }
+
+ cmMakefile& mf = status.GetMakefile();
+ success = success && !cmSystemTools::GetErrorOccurredFlag();
+ mf.AddDefinition(args.CaptureCMakeError, success ? "0" : "-1");
+ return true;
+}
+
+bool cmCTestHandlerCommand::ExecuteHandlerCommand(
+ HandlerArguments& args, cmExecutionStatus& status) const
+{
+ cmMakefile& mf = status.GetMakefile();
+
+ // Process input arguments.
+ this->CheckArguments(args, status);
+
// Set the config type of this ctest to the current value of the
// CTEST_CONFIGURATION_TYPE script variable if it is defined.
// The current script value trumps the -C argument on the command
// line.
- cmValue ctestConfigType =
- this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
+ cmValue ctestConfigType = mf.GetDefinition("CTEST_CONFIGURATION_TYPE");
if (ctestConfigType) {
this->CTest->SetConfigType(*ctestConfigType);
}
- if (!this->Build.empty()) {
+ if (!args.Build.empty()) {
this->CTest->SetCTestConfiguration(
- "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build),
- this->Quiet);
+ "BuildDirectory", cmSystemTools::CollapseFullPath(args.Build),
+ args.Quiet);
} else {
- std::string const& bdir =
- this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
+ std::string const& bdir = mf.GetSafeDefinition("CTEST_BINARY_DIRECTORY");
if (!bdir.empty()) {
this->CTest->SetCTestConfiguration(
- "BuildDirectory", cmSystemTools::CollapseFullPath(bdir), this->Quiet);
+ "BuildDirectory", cmSystemTools::CollapseFullPath(bdir), args.Quiet);
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"CTEST_BINARY_DIRECTORY not set" << std::endl);
}
}
- if (!this->Source.empty()) {
+ if (!args.Source.empty()) {
cmCTestLog(this->CTest, DEBUG,
- "Set source directory to: " << this->Source << std::endl);
+ "Set source directory to: " << args.Source << std::endl);
this->CTest->SetCTestConfiguration(
- "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
- this->Quiet);
+ "SourceDirectory", cmSystemTools::CollapseFullPath(args.Source),
+ args.Quiet);
} else {
this->CTest->SetCTestConfiguration(
"SourceDirectory",
cmSystemTools::CollapseFullPath(
- this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
- this->Quiet);
+ mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
+ args.Quiet);
}
- if (cmValue changeId = this->Makefile->GetDefinition("CTEST_CHANGE_ID")) {
- this->CTest->SetCTestConfiguration("ChangeId", *changeId, this->Quiet);
+ if (cmValue changeId = mf.GetDefinition("CTEST_CHANGE_ID")) {
+ this->CTest->SetCTestConfiguration("ChangeId", *changeId, args.Quiet);
}
cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl);
- cmCTestGenericHandler* handler = this->InitializeHandler();
+ auto handler = this->InitializeHandler(args, status);
if (!handler) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot instantiate test handler " << this->GetName()
<< std::endl);
- if (captureCMakeError) {
- this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
- std::string const& err = status.GetError();
- if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
- }
- return true;
- }
return false;
}
- handler->SetAppendXML(this->Append);
+ handler->SetAppendXML(args.Append);
- handler->PopulateCustomVectors(this->Makefile);
- if (!this->SubmitIndex.empty()) {
- handler->SetSubmitIndex(atoi(this->SubmitIndex.c_str()));
+ handler->PopulateCustomVectors(&mf);
+ if (!args.SubmitIndex.empty()) {
+ handler->SetSubmitIndex(atoi(args.SubmitIndex.c_str()));
}
cmWorkingDirectory workdir(
this->CTest->GetCTestConfiguration("BuildDirectory"));
if (workdir.Failed()) {
- this->SetError("failed to change directory to " +
- this->CTest->GetCTestConfiguration("BuildDirectory") +
- " : " + std::strerror(workdir.GetLastResult()));
- if (captureCMakeError) {
- this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- this->GetName() << " " << status.GetError() << "\n");
- // return success because failure is recorded in CAPTURE_CMAKE_ERROR
- return true;
- }
+ status.SetError(workdir.GetError());
return false;
}
+ // reread time limit, as the variable may have been modified.
+ this->CTest->SetTimeLimit(mf.GetDefinition("CTEST_TIME_LIMIT"));
+ handler->SetCMakeInstance(mf.GetCMakeInstance());
+
int res = handler->ProcessHandler();
- if (!this->ReturnValue.empty()) {
- this->Makefile->AddDefinition(this->ReturnValue, std::to_string(res));
+ if (!args.ReturnValue.empty()) {
+ mf.AddDefinition(args.ReturnValue, std::to_string(res));
}
- this->ProcessAdditionalValues(handler);
- // log the error message if there was an error
- if (captureCMakeError) {
- const char* returnString = "0";
- if (cmSystemTools::GetErrorOccurredFlag()) {
- returnString = "-1";
- std::string const& err = status.GetError();
- // print out the error if it is not "unknown error" which means
- // there was no message
- if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, err);
- }
- }
- // store the captured cmake error state 0 or -1
- this->Makefile->AddDefinition(this->CaptureCMakeError, returnString);
- }
+ this->ProcessAdditionalValues(handler.get(), args, status);
return true;
}
-void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
+void cmCTestHandlerCommand::CheckArguments(HandlerArguments&,
+ cmExecutionStatus&) const
{
}
-void cmCTestHandlerCommand::BindArguments()
+std::unique_ptr<cmCTestGenericHandler>
+cmCTestHandlerCommand::InitializeHandler(HandlerArguments&,
+ cmExecutionStatus&) const
{
- this->BindParsedKeywords(this->ParsedKeywords);
- this->Bind("APPEND"_s, this->Append);
- this->Bind("QUIET"_s, this->Quiet);
- this->Bind("RETURN_VALUE"_s, this->ReturnValue);
- this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
- this->Bind("SOURCE"_s, this->Source);
- this->Bind("BUILD"_s, this->Build);
- this->Bind("SUBMIT_INDEX"_s, this->SubmitIndex);
-}
+ return nullptr;
+};
-void cmCTestHandlerCommand::CheckArguments()
+void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*,
+ HandlerArguments const&,
+ cmExecutionStatus&) const
{
}
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index ed6d9af..c0a2fbc 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -4,59 +4,95 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <functional>
+#include <memory>
#include <string>
+#include <type_traits>
#include <vector>
#include <cm/string_view>
+#include <cmext/string_view>
#include "cmArgumentParser.h"
#include "cmCTestCommand.h"
-class cmCTestGenericHandler;
class cmExecutionStatus;
+class cmCTestGenericHandler;
-/** \class cmCTestHandler
- * \brief Run a ctest script
- *
- * cmCTestHandlerCommand defineds the command to test the project.
- */
-class cmCTestHandlerCommand
- : public cmCTestCommand
- , public cmArgumentParser<void>
+class cmCTestHandlerCommand : public cmCTestCommand
{
public:
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual std::string GetName() const = 0;
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ using cmCTestCommand::cmCTestCommand;
protected:
- virtual cmCTestGenericHandler* InitializeHandler() = 0;
+ struct BasicArguments : ArgumentParser::ParseResult
+ {
+ std::string CaptureCMakeError;
+ std::vector<cm::string_view> ParsedKeywords;
+ };
- virtual void ProcessAdditionalValues(cmCTestGenericHandler* handler);
+ template <typename Args>
+ static auto MakeBasicParser() -> cmArgumentParser<Args>
+ {
+ static_assert(std::is_base_of<BasicArguments, Args>::value, "");
+ return cmArgumentParser<Args>{}
+ .Bind("CAPTURE_CMAKE_ERROR"_s, &BasicArguments::CaptureCMakeError)
+ .BindParsedKeywords(&BasicArguments::ParsedKeywords);
+ }
- // Command argument handling.
- virtual void BindArguments();
- virtual void CheckArguments();
+ struct HandlerArguments : BasicArguments
+ {
+ bool Append = false;
+ bool Quiet = false;
+ std::string ReturnValue;
+ std::string Build;
+ std::string Source;
+ std::string SubmitIndex;
+ };
- std::vector<cm::string_view> ParsedKeywords;
- bool Append = false;
- bool Quiet = false;
- std::string CaptureCMakeError;
- std::string ReturnValue;
- std::string Build;
- std::string Source;
- std::string SubmitIndex;
+ template <typename Args>
+ static auto MakeHandlerParser() -> cmArgumentParser<Args>
+ {
+ static_assert(std::is_base_of<HandlerArguments, Args>::value, "");
+ return cmArgumentParser<Args>{ MakeBasicParser<Args>() }
+ .Bind("APPEND"_s, &HandlerArguments::Append)
+ .Bind("QUIET"_s, &HandlerArguments::Quiet)
+ .Bind("RETURN_VALUE"_s, &HandlerArguments::ReturnValue)
+ .Bind("SOURCE"_s, &HandlerArguments::Source)
+ .Bind("BUILD"_s, &HandlerArguments::Build)
+ .Bind("SUBMIT_INDEX"_s, &HandlerArguments::SubmitIndex);
+ }
+
+protected:
+ template <typename Args, typename Handler>
+ bool Invoke(cmArgumentParser<Args> const& parser,
+ std::vector<std::string> const& arguments,
+ cmExecutionStatus& status, Handler handler) const
+ {
+ std::vector<std::string> unparsed;
+ Args args = parser.Parse(arguments, &unparsed);
+ return this->InvokeImpl(args, unparsed, status,
+ [&]() -> bool { return handler(args); });
+ };
+
+ bool ExecuteHandlerCommand(HandlerArguments& args,
+ cmExecutionStatus& status) const;
+
+private:
+ bool InvokeImpl(BasicArguments& args,
+ std::vector<std::string> const& unparsed,
+ cmExecutionStatus& status,
+ std::function<bool()> handler) const;
+
+ virtual std::string GetName() const = 0;
+
+ virtual void CheckArguments(HandlerArguments& arguments,
+ cmExecutionStatus& status) const;
+
+ virtual std::unique_ptr<cmCTestGenericHandler> InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const;
+
+ virtual void ProcessAdditionalValues(cmCTestGenericHandler*,
+ HandlerArguments const& arguments,
+ cmExecutionStatus& status) const;
};
-
-#define CTEST_COMMAND_APPEND_OPTION_DOCS \
- "The APPEND option marks results for append to those previously " \
- "submitted to a dashboard server since the last ctest_start. " \
- "Append semantics are defined by the dashboard server in use."
diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx
index 4b4e5c5..4156294 100644
--- a/Source/CTest/cmCTestLaunchReporter.cxx
+++ b/Source/CTest/cmCTestLaunchReporter.cxx
@@ -25,7 +25,7 @@
this->Passthru = true;
this->Status.Finished = true;
this->ExitCode = 1;
- this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
+ this->CWD = cmSystemTools::GetLogicalWorkingDirectory();
this->ComputeFileNames();
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 37b3628..28d7158 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,49 +2,65 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
+#include <utility>
+
+#include <cm/memory>
#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
+#include "cmCTestTestHandler.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-void cmCTestMemCheckCommand::BindArguments()
+std::unique_ptr<cmCTestTestHandler>
+cmCTestMemCheckCommand::InitializeActualHandler(
+ HandlerArguments& args, cmExecutionStatus& status) const
{
- this->cmCTestTestCommand::BindArguments();
- this->Bind("DEFECT_COUNT"_s, this->DefectCount);
-}
-
-cmCTestTestHandler* cmCTestMemCheckCommand::InitializeActualHandler()
-{
- cmCTestMemCheckHandler* handler = this->CTest->GetMemCheckHandler();
- handler->Initialize();
+ cmMakefile& mf = status.GetMakefile();
+ auto handler = cm::make_unique<cmCTestMemCheckHandler>(this->CTest);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE", this->Quiet);
+ &mf, "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "MemoryCheckSanitizerOptions",
- "CTEST_MEMORYCHECK_SANITIZER_OPTIONS", this->Quiet);
+ &mf, "MemoryCheckSanitizerOptions", "CTEST_MEMORYCHECK_SANITIZER_OPTIONS",
+ args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND",
- this->Quiet);
+ &mf, "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "MemoryCheckCommandOptions",
- "CTEST_MEMORYCHECK_COMMAND_OPTIONS", this->Quiet);
+ &mf, "MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS",
+ args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "MemoryCheckSuppressionFile",
- "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE", this->Quiet);
+ &mf, "MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE",
+ args.Quiet);
- handler->SetQuiet(this->Quiet);
- return handler;
+ handler->SetQuiet(args.Quiet);
+ return std::unique_ptr<cmCTestTestHandler>(std::move(handler));
}
void cmCTestMemCheckCommand::ProcessAdditionalValues(
- cmCTestGenericHandler* handler)
+ cmCTestGenericHandler* handler, HandlerArguments const& arguments,
+ cmExecutionStatus& status) const
{
- if (!this->DefectCount.empty()) {
- this->Makefile->AddDefinition(
- this->DefectCount,
+ cmMakefile& mf = status.GetMakefile();
+ auto const& args = static_cast<MemCheckArguments const&>(arguments);
+ if (!args.DefectCount.empty()) {
+ mf.AddDefinition(
+ args.DefectCount,
std::to_string(
static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount()));
}
}
+
+bool cmCTestMemCheckCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ static auto const parser =
+ cmArgumentParser<MemCheckArguments>{ MakeTestParser<MemCheckArguments>() }
+ .Bind("DEFECT_COUNT"_s, &MemCheckArguments::DefectCount);
+
+ return this->Invoke(parser, args, status, [&](MemCheckArguments& a) {
+ return this->ExecuteHandlerCommand(a, status);
+ });
+}
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index ee39e49..0f3a7fc 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -4,42 +4,37 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
-#include <utility>
-
-#include <cm/memory>
+#include <vector>
#include "cmCTestTestCommand.h"
-#include "cmCommand.h"
+class cmExecutionStatus;
class cmCTestGenericHandler;
class cmCTestTestHandler;
-/** \class cmCTestMemCheck
- * \brief Run a ctest script
- *
- * cmCTestMemCheckCommand defineds the command to test the project.
- */
class cmCTestMemCheckCommand : public cmCTestTestCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestMemCheckCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
+ using cmCTestTestCommand::cmCTestTestCommand;
protected:
- void BindArguments() override;
+ struct MemCheckArguments : TestArguments
+ {
+ std::string DefectCount;
+ };
- cmCTestTestHandler* InitializeActualHandler() override;
+private:
+ std::string GetName() const override { return "ctest_memcheck"; }
- void ProcessAdditionalValues(cmCTestGenericHandler* handler) override;
+ std::unique_ptr<cmCTestTestHandler> InitializeActualHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const override;
- std::string DefectCount;
+ void ProcessAdditionalValues(cmCTestGenericHandler* handler,
+ HandlerArguments const& arguments,
+ cmExecutionStatus& status) const override;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 8596ffa..e494163 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -118,26 +118,12 @@
#define BOUNDS_CHECKER_MARKER \
"******######*****Begin BOUNDS CHECKER XML******######******"
-cmCTestMemCheckHandler::cmCTestMemCheckHandler()
+cmCTestMemCheckHandler::cmCTestMemCheckHandler(cmCTest* ctest)
+ : Superclass(ctest)
{
this->MemCheck = true;
- this->CustomMaximumPassedTestOutputSize = 0;
- this->CustomMaximumFailedTestOutputSize = 0;
- this->LogWithPID = false;
-}
-
-void cmCTestMemCheckHandler::Initialize()
-{
- this->Superclass::Initialize();
- this->LogWithPID = false;
- this->CustomMaximumPassedTestOutputSize = 0;
- this->CustomMaximumFailedTestOutputSize = 0;
- this->MemoryTester.clear();
- this->MemoryTesterDynamicOptions.clear();
- this->MemoryTesterOptions.clear();
- this->MemoryTesterStyle = UNKNOWN;
- this->MemoryTesterOutputFile.clear();
- this->DefectCount = 0;
+ this->TestOptions.OutputSizePassed = 0;
+ this->TestOptions.OutputSizeFailed = 0;
}
int cmCTestMemCheckHandler::PreProcessHandler()
@@ -311,7 +297,7 @@
if (!this->CTest->GetProduceXML()) {
return;
}
- this->CTest->StartXML(xml, this->AppendXML);
+ this->CTest->StartXML(xml, this->CMake, this->AppendXML);
this->CTest->GenerateSubprojectsOutput(xml);
xml.StartElement("DynamicAnalysis");
switch (this->MemoryTesterStyle) {
@@ -371,9 +357,8 @@
continue;
}
this->CleanTestOutput(
- memcheckstr,
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize),
- this->TestOutputTruncation);
+ memcheckstr, static_cast<size_t>(this->TestOptions.OutputSizeFailed),
+ this->TestOptions.OutputTruncation);
this->WriteTestResultHeader(xml, result);
xml.StartElement("Results");
int memoryErrors = 0;
@@ -929,7 +914,7 @@
cmsys::SystemTools::Split(str, lines);
bool unlimitedOutput = false;
if (str.find("CTEST_FULL_OUTPUT") != std::string::npos ||
- this->CustomMaximumFailedTestOutputSize == 0) {
+ this->TestOptions.OutputSizeFailed == 0) {
unlimitedOutput = true;
}
@@ -1029,7 +1014,7 @@
ostr << lines[i] << std::endl;
if (!unlimitedOutput &&
totalOutputSize >
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) {
+ static_cast<size_t>(this->TestOptions.OutputSizeFailed)) {
ostr << "....\n";
ostr << "Test Output for this test has been truncated see testing"
" machine logs for full output,\n";
@@ -1143,7 +1128,7 @@
cmsys::SystemTools::Split(str, lines);
bool unlimitedOutput = false;
if (str.find("CTEST_FULL_OUTPUT") != std::string::npos ||
- this->CustomMaximumFailedTestOutputSize == 0) {
+ this->TestOptions.OutputSizeFailed == 0) {
unlimitedOutput = true;
}
@@ -1243,7 +1228,7 @@
ostr << lines[i] << std::endl;
if (!unlimitedOutput &&
totalOutputSize >
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) {
+ static_cast<size_t>(this->TestOptions.OutputSizeFailed)) {
ostr << "....\n";
ostr << "Test Output for this test has been truncated see testing"
" machine logs for full output,\n";
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index a63a24d..1971330 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -11,6 +11,7 @@
class cmMakefile;
class cmXMLWriter;
+class cmCTest;
/** \class cmCTestMemCheckHandler
* \brief A class that handles ctest -S invocations
@@ -25,9 +26,7 @@
void PopulateCustomVectors(cmMakefile* mf) override;
- cmCTestMemCheckHandler();
-
- void Initialize() override;
+ cmCTestMemCheckHandler(cmCTest* ctest);
int GetDefectCount() const;
@@ -100,15 +99,15 @@
std::string MemoryTester;
std::vector<std::string> MemoryTesterDynamicOptions;
std::vector<std::string> MemoryTesterOptions;
- int MemoryTesterStyle;
+ int MemoryTesterStyle = UNKNOWN;
std::string MemoryTesterOutputFile;
std::string MemoryTesterEnvironmentVariable;
// these are used to store the types of errors that can show up
std::vector<std::string> ResultStrings;
std::vector<std::string> ResultStringsLong;
std::vector<int> GlobalResults;
- bool LogWithPID; // does log file add pid
- int DefectCount;
+ bool LogWithPID = false; // does log file add pid
+ int DefectCount = 0;
std::vector<int>::size_type FindOrAddWarning(const std::string& warning);
// initialize the ResultStrings and ResultStringsLong for
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 84ea32b..4ef47e7 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -8,7 +8,6 @@
#include <cmath>
#include <cstddef> // IWYU pragma: keep
#include <cstdlib>
-#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
@@ -279,9 +278,7 @@
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
cmCTestRunTest::StartFailure(std::move(testRun), this->Total,
- "Failed to change working directory to " +
- this->Properties[test]->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
+ workdir.GetError(),
"Failed to change working directory");
return;
}
@@ -501,7 +498,7 @@
inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test)
{
- size_t processors = static_cast<int>(this->Properties[test]->Processors);
+ size_t processors = this->Properties[test]->Processors;
size_t const parallelLevel = this->GetParallelLevel();
// If processors setting is set higher than the -j
// setting, we default to using all of the process slots.
@@ -1159,6 +1156,11 @@
properties.append(DumpCTestProperty(
"FIXTURES_SETUP", DumpToJsonArray(testProperties.FixturesSetup)));
}
+ if (!testProperties.GeneratedResourceSpecFile.empty()) {
+ properties.append(
+ DumpCTestProperty("GENERATED_RESOURCE_SPEC_FILE",
+ testProperties.GeneratedResourceSpecFile));
+ }
if (!testProperties.Labels.empty()) {
properties.append(
DumpCTestProperty("LABELS", DumpToJsonArray(testProperties.Labels)));
@@ -1205,6 +1207,15 @@
properties.append(
DumpCTestProperty("TIMEOUT", testProperties.Timeout->count()));
}
+ if (testProperties.TimeoutSignal) {
+ properties.append(DumpCTestProperty("TIMEOUT_SIGNAL_NAME",
+ testProperties.TimeoutSignal->Name));
+ }
+ if (testProperties.TimeoutGracePeriod) {
+ properties.append(
+ DumpCTestProperty("TIMEOUT_SIGNAL_GRACE_PERIOD",
+ testProperties.TimeoutGracePeriod->count()));
+ }
if (!testProperties.TimeoutRegularExpressions.empty()) {
properties.append(DumpCTestProperty(
"TIMEOUT_AFTER_MATCH", DumpTimeoutAfterMatch(testProperties)));
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 20bd0ec..795b747 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -14,11 +14,12 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmList.h"
+#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSystemTools.h"
-cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log)
- : cmCTestGlobalVC(ct, log)
+cmCTestP4::cmCTestP4(cmCTest* ct, cmMakefile* mf, std::ostream& log)
+ : cmCTestGlobalVC(ct, mf, log)
{
this->PriorRev = this->Unknown;
}
@@ -310,7 +311,7 @@
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing
// Perforce commands, if it's different from the default one.
- std::string client = this->CTest->GetCTestConfiguration("P4Client");
+ std::string client = this->Makefile->GetSafeDefinition("CTEST_P4_CLIENT");
if (!client.empty()) {
this->P4Options.emplace_back("-c");
this->P4Options.push_back(client);
@@ -323,7 +324,7 @@
// The CTEST_P4_OPTIONS variable adds additional Perforce command line
// options before the main command
- std::string opts = this->CTest->GetCTestConfiguration("P4Options");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_P4_OPTIONS");
cm::append(this->P4Options, cmSystemTools::ParseArguments(opts));
}
@@ -465,7 +466,8 @@
bool cmCTestP4::UpdateImpl()
{
- std::string custom = this->CTest->GetCTestConfiguration("P4UpdateCustom");
+ std::string custom =
+ this->Makefile->GetSafeDefinition("CTEST_P4_UPDATE_CUSTOM");
if (!custom.empty()) {
return this->UpdateCustom(custom);
}
@@ -483,9 +485,9 @@
p4_sync.emplace_back("sync");
// Get user-specified update options.
- std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_UPDATE_OPTIONS");
if (opts.empty()) {
- opts = this->CTest->GetCTestConfiguration("P4UpdateOptions");
+ opts = this->Makefile->GetSafeDefinition("CTEST_P4_UPDATE_OPTIONS");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
cm::append(p4_sync, args);
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
index 827caa1..61d7fa8 100644
--- a/Source/CTest/cmCTestP4.h
+++ b/Source/CTest/cmCTestP4.h
@@ -12,6 +12,7 @@
#include "cmCTestGlobalVC.h"
class cmCTest;
+class cmMakefile;
/** \class cmCTestP4
* \brief Interaction with the Perforce command-line tool
@@ -21,7 +22,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestP4(cmCTest* ctest, std::ostream& log);
+ cmCTestP4(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestP4() override;
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
index a25cca4..992676f 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.cxx
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -3,19 +3,21 @@
#include "cmCTestReadCustomFilesCommand.h"
#include "cmCTest.h"
+#include "cmExecutionStatus.h"
-class cmExecutionStatus;
+class cmMakefile;
bool cmCTestReadCustomFilesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus& /*unused*/)
+ std::vector<std::string> const& args, cmExecutionStatus& status) const
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& arg : args) {
- this->CTest->ReadCustomConfigurationFileTree(arg, this->Makefile);
+ this->CTest->ReadCustomConfigurationFileTree(arg, &mf);
}
return true;
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index 03714f6..bf12e9e 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -5,13 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
-
#include "cmCTestCommand.h"
-#include "cmCommand.h"
class cmExecutionStatus;
@@ -24,22 +20,12 @@
class cmCTestReadCustomFilesCommand : public cmCTestCommand
{
public:
- cmCTestReadCustomFilesCommand() {}
-
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestReadCustomFilesCommand>();
- ni->CTest = this->CTest;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
+ using cmCTestCommand::cmCTestCommand;
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
index 7661d4d..74620a2 100644
--- a/Source/CTest/cmCTestRunScriptCommand.cxx
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -3,18 +3,19 @@
#include "cmCTestRunScriptCommand.h"
#include "cmCTestScriptHandler.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-
-class cmExecutionStatus;
+#include "cmSystemTools.h"
bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+ cmExecutionStatus& status) const
{
if (args.empty()) {
- this->CTestScriptHandler->RunCurrentScript();
- return true;
+ status.SetError("called with incorrect number of arguments");
+ return false;
}
+ cmMakefile& mf = status.GetMakefile();
bool np = false;
unsigned int i = 0;
if (args[i] == "NEW_PROCESS") {
@@ -37,9 +38,9 @@
++i;
} else {
int ret;
- cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i],
- !np, &ret);
- this->Makefile->AddDefinition(returnVariable, std::to_string(ret));
+ cmCTestScriptHandler::RunScript(
+ this->CTest, &mf, cmSystemTools::CollapseFullPath(args[i]), !np, &ret);
+ mf.AddDefinition(returnVariable, std::to_string(ret));
}
}
return true;
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index 510b748..2ccc0e7 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -5,13 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
-
#include "cmCTestCommand.h"
-#include "cmCommand.h"
class cmExecutionStatus;
@@ -24,23 +20,12 @@
class cmCTestRunScriptCommand : public cmCTestCommand
{
public:
- cmCTestRunScriptCommand() {}
-
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestRunScriptCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
+ using cmCTestCommand::cmCTestCommand;
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 483b3b4..1ca9807 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -7,7 +7,6 @@
#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <cstdio>
-#include <cstring>
#include <iomanip>
#include <ratio>
#include <sstream>
@@ -297,11 +296,11 @@
if (!this->TestHandler->MemCheck && started) {
this->TestHandler->CleanTestOutput(
this->ProcessOutput,
- static_cast<size_t>(
- this->TestResult.Status == cmCTestTestHandler::COMPLETED
- ? this->TestHandler->CustomMaximumPassedTestOutputSize
- : this->TestHandler->CustomMaximumFailedTestOutputSize),
- this->TestHandler->TestOutputTruncation);
+ static_cast<size_t>(this->TestResult.Status ==
+ cmCTestTestHandler::COMPLETED
+ ? this->TestHandler->TestOptions.OutputSizePassed
+ : this->TestHandler->TestOptions.OutputSizeFailed),
+ this->TestHandler->TestOptions.OutputTruncation);
}
this->TestResult.Reason = reason;
if (this->TestHandler->LogFile) {
@@ -398,10 +397,7 @@
// change to tests directory
cmWorkingDirectory workdir(testRun->TestProperties->Directory);
if (workdir.Failed()) {
- testRun->StartFailure(testRun->TotalNumberOfTests,
- "Failed to change working directory to " +
- testRun->TestProperties->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
+ testRun->StartFailure(testRun->TotalNumberOfTests, workdir.GetError(),
"Failed to change working directory");
return true;
}
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index fc7051c..dd29d92 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -13,6 +13,7 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -23,8 +24,8 @@
cmCTestSVN::SVNInfo* SVNInfo;
};
-cmCTestSVN::cmCTestSVN(cmCTest* ct, std::ostream& log)
- : cmCTestGlobalVC(ct, log)
+cmCTestSVN::cmCTestSVN(cmCTest* ct, cmMakefile* mf, std::ostream& log)
+ : cmCTestGlobalVC(ct, mf, log)
{
this->PriorRev = this->Unknown;
}
@@ -240,9 +241,9 @@
bool cmCTestSVN::UpdateImpl()
{
// Get user-specified update options.
- std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ std::string opts = this->Makefile->GetSafeDefinition("CTEST_UPDATE_OPTIONS");
if (opts.empty()) {
- opts = this->CTest->GetCTestConfiguration("SVNUpdateOptions");
+ opts = this->Makefile->GetSafeDefinition("CTEST_SVN_UPDATE_OPTIONS");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
@@ -272,7 +273,8 @@
cm::append(args, parameters);
args.emplace_back("--non-interactive");
- std::string userOptions = this->CTest->GetCTestConfiguration("SVNOptions");
+ std::string userOptions =
+ this->Makefile->GetSafeDefinition("CTEST_SVN_OPTIONS");
std::vector<std::string> parsedUserOptions =
cmSystemTools::ParseArguments(userOptions);
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 1485dc0..a0f1384 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -12,6 +12,7 @@
#include "cmCTestGlobalVC.h"
class cmCTest;
+class cmMakefile;
class cmXMLWriter;
/** \class cmCTestSVN
@@ -22,7 +23,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestSVN(cmCTest* ctest, std::ostream& log);
+ cmCTestSVN(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
~cmCTestSVN() override;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index ed567d4..7d7fa94 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestScriptHandler.h"
-#include <cstdio>
+#include <chrono>
#include <cstdlib>
#include <map>
#include <ratio>
@@ -13,11 +13,8 @@
#include <cm3p/uv.h>
-#include "cmsys/Directory.hxx"
-
#include "cmCTest.h"
#include "cmCTestBuildCommand.h"
-#include "cmCTestCommand.h"
#include "cmCTestConfigureCommand.h"
#include "cmCTestCoverageCommand.h"
#include "cmCTestEmptyBinaryDirectoryCommand.h"
@@ -30,63 +27,20 @@
#include "cmCTestTestCommand.h"
#include "cmCTestUpdateCommand.h"
#include "cmCTestUploadCommand.h"
-#include "cmCommand.h"
#include "cmDuration.h"
-#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
-#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUVHandlePtr.h"
#include "cmUVProcessChain.h"
-#include "cmValue.h"
#include "cmake.h"
-#ifdef _WIN32
-# include <windows.h>
-#else
-# include <unistd.h>
-#endif
-
-cmCTestScriptHandler::cmCTestScriptHandler() = default;
-
-void cmCTestScriptHandler::Initialize()
+cmCTestScriptHandler::cmCTestScriptHandler(cmCTest* ctest)
+ : CTest(ctest)
{
- this->Superclass::Initialize();
- this->Backup = false;
- this->EmptyBinDir = false;
- this->EmptyBinDirOnce = false;
-
- this->SourceDir.clear();
- this->BinaryDir.clear();
- this->BackupSourceDir.clear();
- this->BackupBinaryDir.clear();
- this->CTestRoot.clear();
- this->CVSCheckOut.clear();
- this->CTestCmd.clear();
- this->UpdateCmd.clear();
- this->CTestEnv.clear();
- this->InitialCache.clear();
- this->CMakeCmd.clear();
- this->CMOutFile.clear();
- this->ExtraUpdates.clear();
-
- this->MinimumInterval = 20 * 60;
- this->ContinuousDuration = -1;
-
- // what time in seconds did this script start running
- this->ScriptStartTime = std::chrono::steady_clock::time_point();
-
- this->Makefile.reset();
- this->ParentMakefile = nullptr;
-
- this->GlobalGenerator.reset();
-
- this->CMake.reset();
}
cmCTestScriptHandler::~cmCTestScriptHandler() = default;
@@ -106,9 +60,8 @@
int res = 0;
for (size_t i = 0; i < this->ConfigurationScripts.size(); ++i) {
// for each script run it
- res |= this->RunConfigurationScript(
- cmSystemTools::CollapseFullPath(this->ConfigurationScripts[i]),
- this->ScriptProcessScope[i]);
+ res |= this->RunConfigurationScript(this->ConfigurationScripts[i],
+ this->ScriptProcessScope[i]);
}
if (res) {
return -1;
@@ -120,21 +73,12 @@
{
if (this->Makefile) {
// set the current elapsed time
- auto itime = cmDurationTo<unsigned int>(std::chrono::steady_clock::now() -
- this->ScriptStartTime);
+ auto itime = cmDurationTo<unsigned int>(this->CTest->GetElapsedTime());
auto timeString = std::to_string(itime);
this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString);
}
}
-void cmCTestScriptHandler::AddCTestCommand(
- std::string const& name, std::unique_ptr<cmCTestCommand> command)
-{
- command->CTest = this->CTest;
- command->CTestScriptHandler = this;
- this->CMake->GetState()->AddBuiltinCommand(name, std::move(command));
-}
-
int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
{
// execute the script passing in the arguments to the script as well as the
@@ -235,7 +179,7 @@
cm::make_unique<cmGlobalGenerator>(this->CMake.get());
cmStateSnapshot snapshot = this->CMake->GetCurrentSnapshot();
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
snapshot.GetDirectory().SetCurrentSource(cwd);
snapshot.GetDirectory().SetCurrentBinary(cwd);
this->Makefile =
@@ -252,28 +196,26 @@
}
});
- this->AddCTestCommand("ctest_build", cm::make_unique<cmCTestBuildCommand>());
- this->AddCTestCommand("ctest_configure",
- cm::make_unique<cmCTestConfigureCommand>());
- this->AddCTestCommand("ctest_coverage",
- cm::make_unique<cmCTestCoverageCommand>());
- this->AddCTestCommand("ctest_empty_binary_directory",
- cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>());
- this->AddCTestCommand("ctest_memcheck",
- cm::make_unique<cmCTestMemCheckCommand>());
- this->AddCTestCommand("ctest_read_custom_files",
- cm::make_unique<cmCTestReadCustomFilesCommand>());
- this->AddCTestCommand("ctest_run_script",
- cm::make_unique<cmCTestRunScriptCommand>());
- this->AddCTestCommand("ctest_sleep", cm::make_unique<cmCTestSleepCommand>());
- this->AddCTestCommand("ctest_start", cm::make_unique<cmCTestStartCommand>());
- this->AddCTestCommand("ctest_submit",
- cm::make_unique<cmCTestSubmitCommand>());
- this->AddCTestCommand("ctest_test", cm::make_unique<cmCTestTestCommand>());
- this->AddCTestCommand("ctest_update",
- cm::make_unique<cmCTestUpdateCommand>());
- this->AddCTestCommand("ctest_upload",
- cm::make_unique<cmCTestUploadCommand>());
+ cmState* state = this->CMake->GetState();
+ state->AddBuiltinCommand("ctest_build", cmCTestBuildCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_configure",
+ cmCTestConfigureCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_coverage",
+ cmCTestCoverageCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_empty_binary_directory",
+ cmCTestEmptyBinaryDirectoryCommand);
+ state->AddBuiltinCommand("ctest_memcheck",
+ cmCTestMemCheckCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_read_custom_files",
+ cmCTestReadCustomFilesCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_run_script",
+ cmCTestRunScriptCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_sleep", cmCTestSleepCommand);
+ state->AddBuiltinCommand("ctest_start", cmCTestStartCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_submit", cmCTestSubmitCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_test", cmCTestTestCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_update", cmCTestUpdateCommand(this->CTest));
+ state->AddBuiltinCommand("ctest_upload", cmCTestUploadCommand(this->CTest));
}
// this sets up some variables for the script to use, creates the required
@@ -314,8 +256,6 @@
cmSystemTools::GetCTestCommand());
this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME",
cmSystemTools::GetCMakeCommand());
- this->Makefile->AddDefinitionBool("CTEST_RUN_CURRENT_SCRIPT", true);
- this->SetRunCurrentScript(true);
this->UpdateElapsedTime();
// set the CTEST_CONFIGURATION_TYPE variable to the current value of the
@@ -366,113 +306,6 @@
return 0;
}
-// extract variables from the script to set ivars
-int cmCTestScriptHandler::ExtractVariables()
-{
- // Temporary variables
- cmValue minInterval;
- cmValue contDuration;
-
- this->SourceDir =
- this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
- this->BinaryDir =
- this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
-
- // add in translations for src and bin
- cmSystemTools::AddKeepPath(this->SourceDir);
- cmSystemTools::AddKeepPath(this->BinaryDir);
-
- this->CTestCmd = this->Makefile->GetSafeDefinition("CTEST_COMMAND");
- this->CVSCheckOut = this->Makefile->GetSafeDefinition("CTEST_CVS_CHECKOUT");
- this->CTestRoot = this->Makefile->GetSafeDefinition("CTEST_DASHBOARD_ROOT");
- this->UpdateCmd = this->Makefile->GetSafeDefinition("CTEST_UPDATE_COMMAND");
- if (this->UpdateCmd.empty()) {
- this->UpdateCmd = this->Makefile->GetSafeDefinition("CTEST_CVS_COMMAND");
- }
- this->CTestEnv = this->Makefile->GetSafeDefinition("CTEST_ENVIRONMENT");
- this->InitialCache =
- this->Makefile->GetSafeDefinition("CTEST_INITIAL_CACHE");
- this->CMakeCmd = this->Makefile->GetSafeDefinition("CTEST_CMAKE_COMMAND");
- this->CMOutFile =
- this->Makefile->GetSafeDefinition("CTEST_CMAKE_OUTPUT_FILE_NAME");
-
- this->Backup = this->Makefile->IsOn("CTEST_BACKUP_AND_RESTORE");
- this->EmptyBinDir =
- this->Makefile->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY");
- this->EmptyBinDirOnce =
- this->Makefile->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY_ONCE");
-
- minInterval =
- this->Makefile->GetDefinition("CTEST_CONTINUOUS_MINIMUM_INTERVAL");
- contDuration = this->Makefile->GetDefinition("CTEST_CONTINUOUS_DURATION");
-
- char updateVar[40];
- int i;
- for (i = 1; i < 10; ++i) {
- snprintf(updateVar, sizeof(updateVar), "CTEST_EXTRA_UPDATES_%i", i);
- cmValue updateVal = this->Makefile->GetDefinition(updateVar);
- if (updateVal) {
- if (this->UpdateCmd.empty()) {
- cmSystemTools::Error(
- std::string(updateVar) +
- " specified without specifying CTEST_CVS_COMMAND.");
- return 12;
- }
- this->ExtraUpdates.emplace_back(*updateVal);
- }
- }
-
- // in order to backup and restore we also must have the cvs root
- if (this->Backup && this->CVSCheckOut.empty()) {
- cmSystemTools::Error(
- "Backup was requested without specifying CTEST_CVS_CHECKOUT.");
- return 3;
- }
-
- // make sure the required info is here
- if (this->SourceDir.empty() || this->BinaryDir.empty() ||
- this->CTestCmd.empty()) {
- std::string msg =
- cmStrCat("CTEST_SOURCE_DIRECTORY = ",
- (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)",
- "\nCTEST_BINARY_DIRECTORY = ",
- (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)",
- "\nCTEST_COMMAND = ",
- (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)");
- cmSystemTools::Error(
- "Some required settings in the configuration file were missing:\n" +
- msg);
- return 4;
- }
-
- // if the dashboard root isn't specified then we can compute it from the
- // this->SourceDir
- if (this->CTestRoot.empty()) {
- this->CTestRoot = cmSystemTools::GetFilenamePath(this->SourceDir);
- }
-
- // the script may override the minimum continuous interval
- if (minInterval) {
- this->MinimumInterval = 60 * atof(minInterval->c_str());
- }
- if (contDuration) {
- this->ContinuousDuration = 60.0 * atof(contDuration->c_str());
- }
-
- this->UpdateElapsedTime();
-
- return 0;
-}
-
-void cmCTestScriptHandler::SleepInSeconds(unsigned int secondsToWait)
-{
-#if defined(_WIN32)
- Sleep(1000 * secondsToWait);
-#else
- sleep(secondsToWait);
-#endif
-}
-
// run a specific script
int cmCTestScriptHandler::RunConfigurationScript(
const std::string& total_script_arg, bool pscope)
@@ -483,8 +316,6 @@
int result;
- this->ScriptStartTime = std::chrono::steady_clock::now();
-
// read in the script
if (pscope) {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -495,361 +326,15 @@
"Executing Script: " << total_script_arg << std::endl);
result = this->ExecuteScript(total_script_arg);
}
- if (result) {
- return result;
- }
-
- // only run the current script if we should
- if (this->Makefile && this->Makefile->IsOn("CTEST_RUN_CURRENT_SCRIPT") &&
- this->ShouldRunCurrentScript) {
- return this->RunCurrentScript();
- }
- return result;
-}
-
-int cmCTestScriptHandler::RunCurrentScript()
-{
- int result;
-
- // do not run twice
- this->SetRunCurrentScript(false);
-
- // no popup widows
- cmSystemTools::SetRunCommandHideConsole(true);
-
- // extract the vars from the cache and store in ivars
- result = this->ExtractVariables();
- if (result) {
- return result;
- }
-
- // set any environment variables
- if (!this->CTestEnv.empty()) {
- cmList envArgs{ this->CTestEnv };
- cmSystemTools::AppendEnv(envArgs);
- }
-
- // now that we have done most of the error checking finally run the
- // dashboard, we may be asked to repeatedly run this dashboard, such as
- // for a continuous, do we need to run it more than once?
- if (this->ContinuousDuration >= 0) {
- this->UpdateElapsedTime();
- auto ending_time =
- std::chrono::steady_clock::now() + cmDuration(this->ContinuousDuration);
- if (this->EmptyBinDirOnce) {
- this->EmptyBinDir = true;
- }
- do {
- auto startOfInterval = std::chrono::steady_clock::now();
- result = this->RunConfigurationDashboard();
- auto interval = std::chrono::steady_clock::now() - startOfInterval;
- auto minimumInterval = cmDuration(this->MinimumInterval);
- if (interval < minimumInterval) {
- auto sleepTime =
- cmDurationTo<unsigned int>(minimumInterval - interval);
- this->SleepInSeconds(sleepTime);
- }
- if (this->EmptyBinDirOnce) {
- this->EmptyBinDir = false;
- }
- } while (std::chrono::steady_clock::now() < ending_time);
- }
- // otherwise just run it once
- else {
- result = this->RunConfigurationDashboard();
- }
return result;
}
-int cmCTestScriptHandler::CheckOutSourceDir()
-{
- std::string output;
- int retVal;
-
- if (!cmSystemTools::FileExists(this->SourceDir) &&
- !this->CVSCheckOut.empty()) {
- // we must now checkout the src dir
- output.clear();
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Run cvs: " << this->CVSCheckOut << std::endl);
- bool res = cmSystemTools::RunSingleCommand(
- this->CVSCheckOut, &output, &output, &retVal, this->CTestRoot.c_str(),
- this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/);
- if (!res || retVal != 0) {
- cmSystemTools::Error("Unable to perform cvs checkout:\n" + output);
- return 6;
- }
- }
- return 0;
-}
-
-int cmCTestScriptHandler::BackupDirectories()
-{
- // compute the backup names
- this->BackupSourceDir = cmStrCat(this->SourceDir, "_CMakeBackup");
- this->BackupBinaryDir = cmStrCat(this->BinaryDir, "_CMakeBackup");
-
- // backup the binary and src directories if requested
- if (this->Backup) {
- // if for some reason those directories exist then first delete them
- if (cmSystemTools::FileExists(this->BackupSourceDir)) {
- cmSystemTools::RemoveADirectory(this->BackupSourceDir);
- }
- if (cmSystemTools::FileExists(this->BackupBinaryDir)) {
- cmSystemTools::RemoveADirectory(this->BackupBinaryDir);
- }
-
- // first rename the src and binary directories
- rename(this->SourceDir.c_str(), this->BackupSourceDir.c_str());
- rename(this->BinaryDir.c_str(), this->BackupBinaryDir.c_str());
-
- // we must now checkout the src dir
- int retVal = this->CheckOutSourceDir();
- if (retVal) {
- this->RestoreBackupDirectories();
- return retVal;
- }
- }
-
- return 0;
-}
-
-int cmCTestScriptHandler::PerformExtraUpdates()
-{
- std::string command;
- std::string output;
- int retVal;
- bool res;
-
- // do an initial cvs update as required
- command = this->UpdateCmd;
- for (std::string const& eu : this->ExtraUpdates) {
- cmList cvsArgs{ eu };
- if (cvsArgs.size() == 2) {
- std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]);
- output.clear();
- retVal = 0;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Run Update: " << fullCommand << std::endl);
- res = cmSystemTools::RunSingleCommand(
- fullCommand, &output, &output, &retVal, cvsArgs[0].c_str(),
- this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/);
- if (!res || retVal != 0) {
- cmSystemTools::Error(cmStrCat("Unable to perform extra updates:\n", eu,
- "\nWith output:\n", output));
- return 0;
- }
- }
- }
- return 0;
-}
-
-// run a single dashboard entry
-int cmCTestScriptHandler::RunConfigurationDashboard()
-{
- // local variables
- std::string command;
- std::string output;
- int retVal;
- bool res;
-
- // make sure the src directory is there, if it isn't then we might be able
- // to check it out from cvs
- retVal = this->CheckOutSourceDir();
- if (retVal) {
- return retVal;
- }
-
- // backup the dirs if requested
- retVal = this->BackupDirectories();
- if (retVal) {
- return retVal;
- }
-
- // clear the binary directory?
- if (this->EmptyBinDir) {
- std::string err;
- if (!cmCTestScriptHandler::EmptyBinaryDirectory(this->BinaryDir, err)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Problem removing the binary directory ("
- << err << "): " << this->BinaryDir << std::endl);
- }
- }
-
- // make sure the binary directory exists if it isn't the srcdir
- if (!cmSystemTools::FileExists(this->BinaryDir) &&
- this->SourceDir != this->BinaryDir) {
- if (!cmSystemTools::MakeDirectory(this->BinaryDir)) {
- cmSystemTools::Error("Unable to create the binary directory:\n" +
- this->BinaryDir);
- this->RestoreBackupDirectories();
- return 7;
- }
- }
-
- // if the binary directory and the source directory are the same,
- // and we are starting with an empty binary directory, then that means
- // we must check out the source tree
- if (this->EmptyBinDir && this->SourceDir == this->BinaryDir) {
- // make sure we have the required info
- if (this->CVSCheckOut.empty()) {
- cmSystemTools::Error(
- "You have specified the source and binary "
- "directories to be the same (an in source build). You have also "
- "specified that the binary directory is to be erased. This means "
- "that the source will have to be checked out from CVS. But you have "
- "not specified CTEST_CVS_CHECKOUT");
- return 8;
- }
-
- // we must now checkout the src dir
- retVal = this->CheckOutSourceDir();
- if (retVal) {
- this->RestoreBackupDirectories();
- return retVal;
- }
- }
-
- // backup the dirs if requested
- retVal = this->PerformExtraUpdates();
- if (retVal) {
- return retVal;
- }
-
- // put the initial cache into the bin dir
- if (!this->InitialCache.empty()) {
- if (!cmCTestScriptHandler::WriteInitialCache(this->BinaryDir,
- this->InitialCache)) {
- this->RestoreBackupDirectories();
- return 9;
- }
- }
-
- // do an initial cmake to setup the DartConfig file
- int cmakeFailed = 0;
- std::string cmakeFailedOuput;
- if (!this->CMakeCmd.empty()) {
- command = cmStrCat(this->CMakeCmd, " \"", this->SourceDir);
- output.clear();
- command += "\"";
- retVal = 0;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Run cmake command: " << command << std::endl);
- res = cmSystemTools::RunSingleCommand(
- command, &output, &output, &retVal, this->BinaryDir.c_str(),
- this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/);
-
- if (!this->CMOutFile.empty()) {
- std::string cmakeOutputFile = this->CMOutFile;
- if (!cmSystemTools::FileIsFullPath(cmakeOutputFile)) {
- cmakeOutputFile = this->BinaryDir + "/" + cmakeOutputFile;
- }
-
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Write CMake output to file: " << cmakeOutputFile
- << std::endl);
- cmGeneratedFileStream fout(cmakeOutputFile);
- if (fout) {
- fout << output.c_str();
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Cannot open CMake output file: "
- << cmakeOutputFile << " for writing" << std::endl);
- }
- }
- if (!res || retVal != 0) {
- // even if this fails continue to the next step
- cmakeFailed = 1;
- cmakeFailedOuput = output;
- }
- }
-
- // run ctest, it may be more than one command in here
- cmList ctestCommands{ this->CTestCmd };
- // for each variable/argument do a putenv
- for (std::string const& ctestCommand : ctestCommands) {
- command = ctestCommand;
- output.clear();
- retVal = 0;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Run ctest command: " << command << std::endl);
- res = cmSystemTools::RunSingleCommand(
- command, &output, &output, &retVal, this->BinaryDir.c_str(),
- this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/);
-
- // did something critical fail in ctest
- if (!res || cmakeFailed || retVal & cmCTest::BUILD_ERRORS) {
- this->RestoreBackupDirectories();
- if (cmakeFailed) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Unable to run cmake:" << std::endl
- << cmakeFailedOuput << std::endl);
- return 10;
- }
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Unable to run ctest:" << std::endl
- << "command: " << command << std::endl
- << "output: " << output << std::endl);
- if (!res) {
- return 11;
- }
- return retVal * 100;
- }
- }
-
- // if all was successful, delete the backup dirs to free up disk space
- if (this->Backup) {
- cmSystemTools::RemoveADirectory(this->BackupSourceDir);
- cmSystemTools::RemoveADirectory(this->BackupBinaryDir);
- }
-
- return 0;
-}
-
-bool cmCTestScriptHandler::WriteInitialCache(const std::string& directory,
- const std::string& text)
-{
- std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt");
- cmGeneratedFileStream fout(cacheFile);
- if (!fout) {
- return false;
- }
-
- fout.write(text.data(), text.size());
-
- // Make sure the operating system has finished writing the file
- // before closing it. This will ensure the file is finished before
- // the check below.
- fout.flush();
- fout.close();
- return true;
-}
-
-void cmCTestScriptHandler::RestoreBackupDirectories()
-{
- // if we backed up the dirs and the build failed, then restore
- // the backed up dirs
- if (this->Backup) {
- // if for some reason those directories exist then first delete them
- if (cmSystemTools::FileExists(this->SourceDir)) {
- cmSystemTools::RemoveADirectory(this->SourceDir);
- }
- if (cmSystemTools::FileExists(this->BinaryDir)) {
- cmSystemTools::RemoveADirectory(this->BinaryDir);
- }
- // rename the src and binary directories
- rename(this->BackupSourceDir.c_str(), this->SourceDir.c_str());
- rename(this->BackupBinaryDir.c_str(), this->BinaryDir.c_str());
- }
-}
-
bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
const std::string& sname, bool InProcess,
int* returnValue)
{
- auto sh = cm::make_unique<cmCTestScriptHandler>();
- sh->SetCTestInstance(ctest);
+ auto sh = cm::make_unique<cmCTestScriptHandler>(ctest);
sh->ParentMakefile = mf;
sh->AddConfigurationScript(sname, InProcess);
int res = sh->ProcessHandler();
@@ -858,94 +343,3 @@
}
return true;
}
-
-bool cmCTestScriptHandler::EmptyBinaryDirectory(const std::string& sname,
- std::string& err)
-{
- // try to avoid deleting root
- if (sname.size() < 2) {
- err = "path too short";
- return false;
- }
-
- // consider non existing target directory a success
- if (!cmSystemTools::FileExists(sname)) {
- return true;
- }
-
- // try to avoid deleting directories that we shouldn't
- std::string check = cmStrCat(sname, "/CMakeCache.txt");
-
- if (!cmSystemTools::FileExists(check)) {
- err = "path does not contain an existing CMakeCache.txt file";
- return false;
- }
-
- cmsys::Status status;
- for (int i = 0; i < 5; ++i) {
- status = TryToRemoveBinaryDirectoryOnce(sname);
- if (status) {
- return true;
- }
- cmSystemTools::Delay(100);
- }
-
- err = status.GetString();
- return false;
-}
-
-cmsys::Status cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
- const std::string& directoryPath)
-{
- cmsys::Directory directory;
- directory.Load(directoryPath);
-
- for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) {
- std::string path = directory.GetFile(i);
-
- if (path == "." || path == ".." || path == "CMakeCache.txt") {
- continue;
- }
-
- std::string fullPath = cmStrCat(directoryPath, "/", path);
-
- bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
- !cmSystemTools::FileIsSymlink(fullPath);
-
- cmsys::Status status;
- if (isDirectory) {
- status = cmSystemTools::RemoveADirectory(fullPath);
- } else {
- status = cmSystemTools::RemoveFile(fullPath);
- }
- if (!status) {
- return status;
- }
- }
-
- return cmSystemTools::RemoveADirectory(directoryPath);
-}
-
-cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed()
-{
- if (!this->Makefile) {
- return cmCTest::MaxDuration();
- }
-
- cmValue timelimitS = this->Makefile->GetDefinition("CTEST_TIME_LIMIT");
-
- if (!timelimitS) {
- return cmCTest::MaxDuration();
- }
-
- auto timelimit = cmDuration(atof(timelimitS->c_str()));
-
- auto duration = std::chrono::duration_cast<cmDuration>(
- std::chrono::steady_clock::now() - this->ScriptStartTime);
- return (timelimit - duration);
-}
-
-void cmCTestScriptHandler::SetRunCurrentScript(bool value)
-{
- this->ShouldRunCurrentScript = value;
-}
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index 7747750..bcb3933 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -4,63 +4,21 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <chrono>
#include <memory>
#include <string>
#include <vector>
-#include "cmsys/Status.hxx"
-
-#include "cmCTestGenericHandler.h"
-#include "cmDuration.h"
-
class cmCTest;
-class cmCTestCommand;
class cmGlobalGenerator;
class cmMakefile;
class cmake;
/** \class cmCTestScriptHandler
* \brief A class that handles ctest -S invocations
- *
- * CTest script is controlled using several variables that script has to
- * specify and some optional ones. Required ones are:
- * CTEST_SOURCE_DIRECTORY - Source directory of the project
- * CTEST_BINARY_DIRECTORY - Binary directory of the project
- * CTEST_COMMAND - Testing commands
- *
- * Optional variables are:
- * CTEST_BACKUP_AND_RESTORE
- * CTEST_CMAKE_COMMAND
- * CTEST_CMAKE_OUTPUT_FILE_NAME
- * CTEST_CONTINUOUS_DURATION
- * CTEST_CONTINUOUS_MINIMUM_INTERVAL
- * CTEST_CVS_CHECKOUT
- * CTEST_CVS_COMMAND
- * CTEST_UPDATE_COMMAND
- * CTEST_DASHBOARD_ROOT
- * CTEST_ENVIRONMENT
- * CTEST_INITIAL_CACHE
- * CTEST_START_WITH_EMPTY_BINARY_DIRECTORY
- * CTEST_START_WITH_EMPTY_BINARY_DIRECTORY_ONCE
- *
- * In addition the following variables can be used. The number can be 1-10.
- * CTEST_EXTRA_UPDATES_1
- * CTEST_EXTRA_UPDATES_2
- * ...
- * CTEST_EXTRA_UPDATES_10
- *
- * CTest script can use the following arguments CTest provides:
- * CTEST_SCRIPT_ARG
- * CTEST_SCRIPT_DIRECTORY
- * CTEST_SCRIPT_NAME
- *
*/
-class cmCTestScriptHandler : public cmCTestGenericHandler
+class cmCTestScriptHandler
{
public:
- using Superclass = cmCTestGenericHandler;
-
/**
* Add a script to run, and if is should run in the current process
*/
@@ -69,7 +27,7 @@
/**
* Run a dashboard using a specified configuration script
*/
- int ProcessHandler() override;
+ int ProcessHandler();
/*
* Run a script
@@ -77,104 +35,32 @@
static bool RunScript(cmCTest* ctest, cmMakefile* mf,
const std::string& script, bool InProcess,
int* returnValue);
- int RunCurrentScript();
-
- /*
- * Empty Binary Directory
- */
- static bool EmptyBinaryDirectory(const std::string& dir, std::string& err);
-
- /*
- * Write an initial CMakeCache.txt from the given contents.
- */
- static bool WriteInitialCache(const std::string& directory,
- const std::string& text);
/*
* Some elapsed time handling functions
*/
- static void SleepInSeconds(unsigned int secondsToWait);
void UpdateElapsedTime();
- /**
- * Return the time remaianing that the script is allowed to run in
- * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
- * not been set it returns a very large value.
- */
- cmDuration GetRemainingTimeAllowed();
-
- cmCTestScriptHandler();
+ cmCTestScriptHandler(cmCTest* ctest);
cmCTestScriptHandler(const cmCTestScriptHandler&) = delete;
const cmCTestScriptHandler& operator=(const cmCTestScriptHandler&) = delete;
- ~cmCTestScriptHandler() override;
-
- void Initialize() override;
+ ~cmCTestScriptHandler();
void CreateCMake();
cmake* GetCMake() { return this->CMake.get(); }
-
- void SetRunCurrentScript(bool value);
+ cmMakefile* GetMakefile() { return this->Makefile.get(); }
private:
// reads in a script
int ReadInScript(const std::string& total_script_arg);
int ExecuteScript(const std::string& total_script_arg);
- // extract vars from the script to set ivars
- int ExtractVariables();
-
- // perform a CVS checkout of the source dir
- int CheckOutSourceDir();
-
- // perform any extra cvs updates that were requested
- int PerformExtraUpdates();
-
- // backup and restore dirs
- int BackupDirectories();
- void RestoreBackupDirectories();
-
int RunConfigurationScript(const std::string& script, bool pscope);
- int RunConfigurationDashboard();
- // Add ctest command
- void AddCTestCommand(std::string const& name,
- std::unique_ptr<cmCTestCommand> command);
-
- // Try to remove the binary directory once
- static cmsys::Status TryToRemoveBinaryDirectoryOnce(
- const std::string& directoryPath);
-
+ cmCTest* CTest = nullptr;
std::vector<std::string> ConfigurationScripts;
std::vector<bool> ScriptProcessScope;
- bool ShouldRunCurrentScript;
-
- bool Backup = false;
- bool EmptyBinDir = false;
- bool EmptyBinDirOnce = false;
-
- std::string SourceDir;
- std::string BinaryDir;
- std::string BackupSourceDir;
- std::string BackupBinaryDir;
- std::string CTestRoot;
- std::string CVSCheckOut;
- std::string CTestCmd;
- std::string UpdateCmd;
- std::string CTestEnv;
- std::string InitialCache;
- std::string CMakeCmd;
- std::string CMOutFile;
- std::vector<std::string> ExtraUpdates;
-
- // the *60 is because the settings are in minutes but GetTime is seconds
- double MinimumInterval = 30 * 60;
- double ContinuousDuration = -1;
-
- // what time in seconds did this script start running
- std::chrono::steady_clock::time_point ScriptStartTime =
- std::chrono::steady_clock::time_point();
-
std::unique_ptr<cmMakefile> Makefile;
cmMakefile* ParentMakefile = nullptr;
std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
diff --git a/Source/CTest/cmCTestSleepCommand.cxx b/Source/CTest/cmCTestSleepCommand.cxx
index 623d3b6..f57d856 100644
--- a/Source/CTest/cmCTestSleepCommand.cxx
+++ b/Source/CTest/cmCTestSleepCommand.cxx
@@ -2,42 +2,34 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestSleepCommand.h"
+#include <chrono>
#include <cstdlib>
+#include <thread>
-#include "cmCTestScriptHandler.h"
+#include "cmExecutionStatus.h"
-class cmExecutionStatus;
-
-bool cmCTestSleepCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+bool cmCTestSleepCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
-
// sleep for specified seconds
- unsigned int time1 = atoi(args[0].c_str());
if (args.size() == 1) {
- cmCTestScriptHandler::SleepInSeconds(time1);
- // update the elapsed time since it could have slept for a while
- this->CTestScriptHandler->UpdateElapsedTime();
+ unsigned int duration = atoi(args[0].c_str());
+ std::this_thread::sleep_for(std::chrono::seconds(duration));
return true;
}
// sleep up to a duration
if (args.size() == 3) {
+ unsigned int time1 = atoi(args[0].c_str());
unsigned int duration = atoi(args[1].c_str());
unsigned int time2 = atoi(args[2].c_str());
if (time1 + duration > time2) {
duration = (time1 + duration - time2);
- cmCTestScriptHandler::SleepInSeconds(duration);
- // update the elapsed time since it could have slept for a while
- this->CTestScriptHandler->UpdateElapsedTime();
+ std::this_thread::sleep_for(std::chrono::seconds(duration));
}
return true;
}
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
index 9425576..3d4eb1e 100644
--- a/Source/CTest/cmCTestSleepCommand.h
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -5,42 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
-
-#include "cmCTestCommand.h"
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmCTestSleep
- * \brief Run a ctest script
- *
- * cmLibrarysCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmCTestSleepCommand : public cmCTestCommand
-{
-public:
- cmCTestSleepCommand() {}
-
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestSleepCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmCTestSleepCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index 84d12d7..f6ff24b 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -7,28 +7,24 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
-class cmExecutionStatus;
-
-cmCTestStartCommand::cmCTestStartCommand()
-{
- this->CreateNewTag = true;
- this->Quiet = false;
-}
-
bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+ cmExecutionStatus& status) const
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
size_t cnt = 0;
+ bool append = false;
+ bool quiet = false;
const char* smodel = nullptr;
cmValue src_dir;
cmValue bld_dir;
@@ -40,17 +36,17 @@
args[cnt] == "QUIET") {
std::ostringstream e;
e << args[cnt - 1] << " argument missing group name";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
this->CTest->SetSpecificGroup(args[cnt].c_str());
cnt++;
} else if (args[cnt] == "APPEND") {
cnt++;
- this->CreateNewTag = false;
+ append = true;
} else if (args[cnt] == "QUIET") {
cnt++;
- this->Quiet = true;
+ quiet = true;
} else if (!smodel) {
smodel = args[cnt].c_str();
cnt++;
@@ -61,43 +57,42 @@
bld_dir = cmValue(args[cnt]);
cnt++;
} else {
- this->SetError("Too many arguments");
+ status.SetError("Too many arguments");
return false;
}
}
- if (!src_dir) {
- src_dir = this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY");
- }
- if (!bld_dir) {
- bld_dir = this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY");
- }
- if (!src_dir) {
- this->SetError("source directory not specified. Specify source directory "
- "as an argument or set CTEST_SOURCE_DIRECTORY");
- return false;
- }
- if (!bld_dir) {
- this->SetError("binary directory not specified. Specify binary directory "
- "as an argument or set CTEST_BINARY_DIRECTORY");
- return false;
- }
- if (!smodel && this->CreateNewTag) {
- this->SetError("no test model specified and APPEND not specified. Specify "
- "either a test model or the APPEND argument");
- return false;
- }
+ cmMakefile& mf = status.GetMakefile();
- cmSystemTools::AddKeepPath(*src_dir);
- cmSystemTools::AddKeepPath(*bld_dir);
+ if (!src_dir) {
+ src_dir = mf.GetDefinition("CTEST_SOURCE_DIRECTORY");
+ }
+ if (!bld_dir) {
+ bld_dir = mf.GetDefinition("CTEST_BINARY_DIRECTORY");
+ }
+ if (!src_dir) {
+ status.SetError("source directory not specified. Specify source directory "
+ "as an argument or set CTEST_SOURCE_DIRECTORY");
+ return false;
+ }
+ if (!bld_dir) {
+ status.SetError("binary directory not specified. Specify binary directory "
+ "as an argument or set CTEST_BINARY_DIRECTORY");
+ return false;
+ }
+ if (!smodel && !append) {
+ status.SetError(
+ "no test model specified and APPEND not specified. Specify "
+ "either a test model or the APPEND argument");
+ return false;
+ }
this->CTest->EmptyCTestConfiguration();
std::string sourceDir = cmSystemTools::CollapseFullPath(*src_dir);
std::string binaryDir = cmSystemTools::CollapseFullPath(*bld_dir);
- this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir,
- this->Quiet);
- this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, this->Quiet);
+ this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir, quiet);
+ this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, quiet);
if (smodel) {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
@@ -105,7 +100,7 @@
<< smodel << std::endl
<< " Source directory: " << *src_dir << std::endl
<< " Build directory: " << *bld_dir << std::endl,
- this->Quiet);
+ quiet);
} else {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
"Run dashboard with "
@@ -113,12 +108,12 @@
<< std::endl
<< " Source directory: " << *src_dir << std::endl
<< " Build directory: " << *bld_dir << std::endl,
- this->Quiet);
+ quiet);
}
const char* group = this->CTest->GetSpecificGroup();
if (group) {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Group: " << group << std::endl, this->Quiet);
+ " Group: " << group << std::endl, quiet);
}
// Log startup actions.
@@ -131,7 +126,7 @@
}
// Make sure the source directory exists.
- if (!this->InitialCheckout(ofs, sourceDir)) {
+ if (!this->InitialCheckout(ofs, sourceDir, status)) {
return false;
}
if (!cmSystemTools::FileIsDirectory(sourceDir)) {
@@ -140,11 +135,10 @@
<< " " << sourceDir << "\n"
<< "which is not an existing directory. "
<< "Set CTEST_CHECKOUT_COMMAND to a command line to create it.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- this->CTest->SetRunCurrentScript(false);
this->CTest->SetSuppressUpdatingCTestConfiguration(true);
int model;
if (smodel) {
@@ -155,22 +149,94 @@
this->CTest->SetTestModel(model);
this->CTest->SetProduceXML(true);
- return this->CTest->InitializeFromCommand(this);
+ std::string fname;
+
+ std::string src_dir_fname = cmStrCat(sourceDir, "/CTestConfig.cmake");
+ cmSystemTools::ConvertToUnixSlashes(src_dir_fname);
+
+ std::string bld_dir_fname = cmStrCat(binaryDir, "/CTestConfig.cmake");
+ cmSystemTools::ConvertToUnixSlashes(bld_dir_fname);
+
+ if (cmSystemTools::FileExists(bld_dir_fname)) {
+ fname = bld_dir_fname;
+ } else if (cmSystemTools::FileExists(src_dir_fname)) {
+ fname = src_dir_fname;
+ }
+
+ if (!fname.empty()) {
+ cmCTestOptionalLog(
+ this->CTest, OUTPUT,
+ " Reading ctest configuration file: " << fname << std::endl, quiet);
+ bool readit = mf.ReadDependentFile(fname);
+ if (!readit) {
+ std::string m = cmStrCat("Could not find include file: ", fname);
+ status.SetError(m);
+ return false;
+ }
+ }
+
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ &mf, "NightlyStartTime", "CTEST_NIGHTLY_START_TIME", quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(&mf, "Site",
+ "CTEST_SITE", quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ &mf, "BuildName", "CTEST_BUILD_NAME", quiet);
+
+ this->CTest->Initialize(bld_dir);
+ this->CTest->UpdateCTestConfiguration();
+
+ cmCTestOptionalLog(
+ this->CTest, OUTPUT,
+ " Site: " << this->CTest->GetCTestConfiguration("Site") << std::endl
+ << " Build name: "
+ << cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"))
+ << std::endl,
+ quiet);
+
+ if (this->CTest->GetTestModel() == cmCTest::NIGHTLY &&
+ this->CTest->GetCTestConfiguration("NightlyStartTime").empty()) {
+ cmCTestOptionalLog(
+ this->CTest, WARNING,
+ "WARNING: No nightly start time found please set in CTestConfig.cmake"
+ " or DartConfig.cmake"
+ << std::endl,
+ quiet);
+ return false;
+ }
+
+ this->CTest->ReadCustomConfigurationFileTree(bld_dir, &mf);
+
+ if (append) {
+ if (!this->CTest->ReadExistingTag(quiet)) {
+ return false;
+ }
+ } else {
+ if (!this->CTest->CreateNewTag(quiet)) {
+ return false;
+ }
+ }
+
+ cmCTestOptionalLog(this->CTest, OUTPUT,
+ " Use " << this->CTest->GetTestGroupString() << " tag: "
+ << this->CTest->GetCurrentTag() << std::endl,
+ quiet);
+ return true;
}
bool cmCTestStartCommand::InitialCheckout(std::ostream& ofs,
- std::string const& sourceDir)
+ std::string const& sourceDir,
+ cmExecutionStatus& status) const
{
+ cmMakefile& mf = status.GetMakefile();
// Use the user-provided command to create the source tree.
- cmValue initialCheckoutCommand =
- this->Makefile->GetDefinition("CTEST_CHECKOUT_COMMAND");
+ cmValue initialCheckoutCommand = mf.GetDefinition("CTEST_CHECKOUT_COMMAND");
if (!initialCheckoutCommand) {
- initialCheckoutCommand =
- this->Makefile->GetDefinition("CTEST_CVS_CHECKOUT");
+ initialCheckoutCommand = mf.GetDefinition("CTEST_CVS_CHECKOUT");
}
if (initialCheckoutCommand) {
// Use a generic VC object to run and log the command.
- cmCTestVC vc(this->CTest, ofs);
+ cmCTestVC vc(this->CTest, &mf, ofs);
vc.SetSourceDirectory(sourceDir);
if (!vc.InitialCheckout(*initialCheckoutCommand)) {
return false;
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index b3d06a7..325471a 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -6,13 +6,9 @@
#include <iosfwd>
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
-
#include "cmCTestCommand.h"
-#include "cmCommand.h"
class cmExecutionStatus;
@@ -24,40 +20,16 @@
class cmCTestStartCommand : public cmCTestCommand
{
public:
- cmCTestStartCommand();
-
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestStartCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- ni->CreateNewTag = this->CreateNewTag;
- ni->Quiet = this->Quiet;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
+ using cmCTestCommand::cmCTestCommand;
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /**
- * Will this invocation of ctest_start create a new TAG file?
- */
- bool ShouldCreateNewTag() { return this->CreateNewTag; }
-
- /**
- * Should this invocation of ctest_start output non-error messages?
- */
- bool ShouldBeQuiet() { return this->Quiet; }
+ cmExecutionStatus& status) const override;
private:
- bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir);
- bool CreateNewTag;
- bool Quiet;
+ bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir,
+ cmExecutionStatus& status) const;
};
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 029f81f..8ae0f4c 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -10,9 +10,11 @@
#include <cm/vector>
#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
#include "cmCTestSubmitHandler.h"
-#include "cmCommand.h"
+#include "cmExecutionStatus.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -20,117 +22,101 @@
#include "cmSystemTools.h"
#include "cmValue.h"
-class cmExecutionStatus;
-
-/**
- * This is a virtual constructor for the command.
- */
-std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone()
+std::unique_ptr<cmCTestGenericHandler> cmCTestSubmitCommand::InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const
{
- auto ni = cm::make_unique<cmCTestSubmitCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
-}
-
-cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
-{
- cmValue submitURL = !this->SubmitURL.empty()
- ? cmValue(this->SubmitURL)
- : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
+ cmMakefile& mf = status.GetMakefile();
+ auto const& args = static_cast<SubmitArguments&>(arguments);
+ cmValue submitURL = !args.SubmitURL.empty()
+ ? cmValue(args.SubmitURL)
+ : mf.GetDefinition("CTEST_SUBMIT_URL");
if (submitURL) {
- this->CTest->SetCTestConfiguration("SubmitURL", *submitURL, this->Quiet);
+ this->CTest->SetCTestConfiguration("SubmitURL", *submitURL, args.Quiet);
} else {
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
+ &mf, "DropMethod", "CTEST_DROP_METHOD", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
+ &mf, "DropSiteUser", "CTEST_DROP_SITE_USER", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
- this->Quiet);
+ &mf, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSite", "CTEST_DROP_SITE", this->Quiet);
+ &mf, "DropSite", "CTEST_DROP_SITE", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropLocation", "CTEST_DROP_LOCATION", this->Quiet);
+ &mf, "DropLocation", "CTEST_DROP_LOCATION", args.Quiet);
}
if (!this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "TLSVersion", "CTEST_TLS_VERSION", this->Quiet)) {
- if (cmValue tlsVersionVar =
- this->Makefile->GetDefinition("CMAKE_TLS_VERSION")) {
+ &mf, "TLSVersion", "CTEST_TLS_VERSION", args.Quiet)) {
+ if (cmValue tlsVersionVar = mf.GetDefinition("CMAKE_TLS_VERSION")) {
cmCTestOptionalLog(
this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetCTestConfiguration from CMAKE_TLS_VERSION:TLSVersion:"
<< *tlsVersionVar << std::endl,
- this->Quiet);
+ args.Quiet);
this->CTest->SetCTestConfiguration("TLSVersion", *tlsVersionVar,
- this->Quiet);
+ args.Quiet);
} else if (cm::optional<std::string> tlsVersionEnv =
cmSystemTools::GetEnvVar("CMAKE_TLS_VERSION")) {
cmCTestOptionalLog(
this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetCTestConfiguration from ENV{CMAKE_TLS_VERSION}:TLSVersion:"
<< *tlsVersionEnv << std::endl,
- this->Quiet);
+ args.Quiet);
this->CTest->SetCTestConfiguration("TLSVersion", *tlsVersionEnv,
- this->Quiet);
+ args.Quiet);
}
}
if (!this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "TLSVerify", "CTEST_TLS_VERIFY", this->Quiet)) {
- if (cmValue tlsVerifyVar =
- this->Makefile->GetDefinition("CMAKE_TLS_VERIFY")) {
+ &mf, "TLSVerify", "CTEST_TLS_VERIFY", args.Quiet)) {
+ if (cmValue tlsVerifyVar = mf.GetDefinition("CMAKE_TLS_VERIFY")) {
cmCTestOptionalLog(
this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetCTestConfiguration from CMAKE_TLS_VERIFY:TLSVerify:"
<< *tlsVerifyVar << std::endl,
- this->Quiet);
+ args.Quiet);
this->CTest->SetCTestConfiguration("TLSVerify", *tlsVerifyVar,
- this->Quiet);
+ args.Quiet);
} else if (cm::optional<std::string> tlsVerifyEnv =
cmSystemTools::GetEnvVar("CMAKE_TLS_VERIFY")) {
cmCTestOptionalLog(
this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetCTestConfiguration from ENV{CMAKE_TLS_VERIFY}:TLSVerify:"
<< *tlsVerifyEnv << std::endl,
- this->Quiet);
+ args.Quiet);
this->CTest->SetCTestConfiguration("TLSVerify", *tlsVerifyEnv,
- this->Quiet);
+ args.Quiet);
}
}
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet);
+ &mf, "CurlOptions", "CTEST_CURL_OPTIONS", args.Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "SubmitInactivityTimeout",
- "CTEST_SUBMIT_INACTIVITY_TIMEOUT", this->Quiet);
+ &mf, "SubmitInactivityTimeout", "CTEST_SUBMIT_INACTIVITY_TIMEOUT",
+ args.Quiet);
- cmValue notesFilesVariable =
- this->Makefile->GetDefinition("CTEST_NOTES_FILES");
+ cmValue notesFilesVariable = mf.GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable) {
cmList notesFiles{ *notesFilesVariable };
- this->CTest->GenerateNotesFile(notesFiles);
+ this->CTest->GenerateNotesFile(mf.GetCMakeInstance(), notesFiles);
}
- cmValue extraFilesVariable =
- this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
+ cmValue extraFilesVariable = mf.GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
if (extraFilesVariable) {
cmList extraFiles{ *extraFilesVariable };
if (!this->CTest->SubmitExtraFiles(extraFiles)) {
- this->SetError("problem submitting extra files.");
+ status.SetError("problem submitting extra files.");
return nullptr;
}
}
- cmCTestSubmitHandler* handler = this->CTest->GetSubmitHandler();
- handler->Initialize();
+ auto handler = cm::make_unique<cmCTestSubmitHandler>(this->CTest);
// If no FILES or PARTS given, *all* PARTS are submitted by default.
//
// If FILES are given, but not PARTS, only the FILES are submitted
// and *no* PARTS are submitted.
// (This is why we select the empty "noParts" set in the
- // if(this->Files) block below...)
+ // if(args.Files) block below...)
//
// If PARTS are given, only the selected PARTS are submitted.
//
@@ -139,7 +125,7 @@
// If given explicit FILES to submit, pass them to the handler.
//
- if (this->Files) {
+ if (args.Files) {
// Intentionally select *no* PARTS. (Pass an empty set.) If PARTS
// were also explicitly mentioned, they will be selected below...
// But FILES with no PARTS mentioned should just submit the FILES
@@ -147,99 +133,111 @@
//
handler->SelectParts(std::set<cmCTest::Part>());
handler->SelectFiles(
- std::set<std::string>(this->Files->begin(), this->Files->end()));
+ std::set<std::string>(args.Files->begin(), args.Files->end()));
}
// If a PARTS option was given, select only the named parts for submission.
//
- if (this->Parts) {
+ if (args.Parts) {
auto parts =
- cmMakeRange(*(this->Parts)).transform([this](std::string const& arg) {
+ cmMakeRange(*(args.Parts)).transform([this](std::string const& arg) {
return this->CTest->GetPartFromName(arg);
});
handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
}
// Pass along any HTTPHEADER to the handler if this option was given.
- if (!this->HttpHeaders.empty()) {
- handler->SetHttpHeaders(this->HttpHeaders);
+ if (!args.HttpHeaders.empty()) {
+ handler->SetHttpHeaders(args.HttpHeaders);
}
- handler->SetOption("RetryDelay", this->RetryDelay);
- handler->SetOption("RetryCount", this->RetryCount);
- handler->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF");
+ handler->RetryDelay = args.RetryDelay;
+ handler->RetryCount = args.RetryCount;
+ handler->InternalTest = args.InternalTest;
- handler->SetQuiet(this->Quiet);
+ handler->SetQuiet(args.Quiet);
- if (this->CDashUpload) {
- handler->SetOption("CDashUploadFile", this->CDashUploadFile);
- handler->SetOption("CDashUploadType", this->CDashUploadType);
+ if (args.CDashUpload) {
+ handler->CDashUpload = true;
+ handler->CDashUploadFile = args.CDashUploadFile;
+ handler->CDashUploadType = args.CDashUploadType;
}
- return handler;
+ return std::unique_ptr<cmCTestGenericHandler>(std::move(handler));
}
bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+ cmExecutionStatus& status) const
{
- this->CDashUpload = !args.empty() && args[0] == "CDASH_UPLOAD";
-
- bool ret = this->cmCTestHandlerCommand::InitialPass(args, status);
-
- if (!this->BuildID.empty()) {
- this->Makefile->AddDefinition(this->BuildID, this->CTest->GetBuildID());
- }
-
- return ret;
-}
-
-void cmCTestSubmitCommand::BindArguments()
-{
- if (this->CDashUpload) {
- // Arguments specific to the CDASH_UPLOAD signature.
- this->Bind("CDASH_UPLOAD", this->CDashUploadFile);
- this->Bind("CDASH_UPLOAD_TYPE", this->CDashUploadType);
- } else {
- // Arguments that cannot be used with CDASH_UPLOAD.
- this->Bind("PARTS"_s, this->Parts);
- this->Bind("FILES"_s, this->Files);
- }
// Arguments used by both modes.
- this->Bind("BUILD_ID"_s, this->BuildID);
- this->Bind("HTTPHEADER"_s, this->HttpHeaders);
- this->Bind("RETRY_COUNT"_s, this->RetryCount);
- this->Bind("RETRY_DELAY"_s, this->RetryDelay);
- this->Bind("SUBMIT_URL"_s, this->SubmitURL);
- this->Bind("INTERNAL_TEST_CHECKSUM", this->InternalTest);
+ static auto const parserBase =
+ cmArgumentParser<SubmitArguments>{ MakeHandlerParser<SubmitArguments>() }
+ .Bind("BUILD_ID"_s, &SubmitArguments::BuildID)
+ .Bind("HTTPHEADER"_s, &SubmitArguments::HttpHeaders)
+ .Bind("RETRY_COUNT"_s, &SubmitArguments::RetryCount)
+ .Bind("RETRY_DELAY"_s, &SubmitArguments::RetryDelay)
+ .Bind("SUBMIT_URL"_s, &SubmitArguments::SubmitURL)
+ .Bind("INTERNAL_TEST_CHECKSUM"_s, &SubmitArguments::InternalTest);
- // Look for other arguments.
- this->cmCTestHandlerCommand::BindArguments();
+ // Arguments specific to the CDASH_UPLOAD signature.
+ static auto const uploadParser =
+ cmArgumentParser<SubmitArguments>{ parserBase }
+ .Bind("CDASH_UPLOAD"_s, &SubmitArguments::CDashUploadFile)
+ .Bind("CDASH_UPLOAD_TYPE"_s, &SubmitArguments::CDashUploadType);
+
+ // Arguments that cannot be used with CDASH_UPLOAD.
+ static auto const partsParser =
+ cmArgumentParser<SubmitArguments>{ parserBase }
+ .Bind("PARTS"_s, &SubmitArguments::Parts)
+ .Bind("FILES"_s, &SubmitArguments::Files);
+
+ bool const cdashUpload = !args.empty() && args[0] == "CDASH_UPLOAD";
+ auto const& parser = cdashUpload ? uploadParser : partsParser;
+
+ return this->Invoke(parser, args, status, [&](SubmitArguments& a) -> bool {
+ a.CDashUpload = cdashUpload;
+ return this->ExecuteHandlerCommand(a, status);
+ });
}
-void cmCTestSubmitCommand::CheckArguments()
+void cmCTestSubmitCommand::CheckArguments(HandlerArguments& arguments,
+ cmExecutionStatus& status) const
{
- if (this->Parts) {
- cm::erase_if(*(this->Parts), [this](std::string const& arg) -> bool {
+ cmMakefile& mf = status.GetMakefile();
+ auto& args = static_cast<SubmitArguments&>(arguments);
+ if (args.Parts) {
+ cm::erase_if(*(args.Parts), [this, &mf](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg);
if (p == cmCTest::PartCount) {
std::ostringstream e;
e << "Part name \"" << arg << "\" is invalid.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
return true;
}
return false;
});
}
- if (this->Files) {
- cm::erase_if(*(this->Files), [this](std::string const& arg) -> bool {
+ if (args.Files) {
+ cm::erase_if(*(args.Files), [&mf](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "
<< "a non-existent file.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
return true;
}
return false;
});
}
}
+
+void cmCTestSubmitCommand::ProcessAdditionalValues(
+ cmCTestGenericHandler*, HandlerArguments const& arguments,
+ cmExecutionStatus& status) const
+{
+ cmMakefile& mf = status.GetMakefile();
+ auto const& args = static_cast<SubmitArguments const&>(arguments);
+ if (!args.BuildID.empty()) {
+ mf.AddDefinition(args.BuildID, this->CTest->GetBuildID());
+ }
+}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index b67f182..9c02fc8 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -13,45 +13,45 @@
#include "cmArgumentParserTypes.h"
#include "cmCTestHandlerCommand.h"
-class cmCommand;
-class cmCTestGenericHandler;
class cmExecutionStatus;
+class cmCTestGenericHandler;
-/** \class cmCTestSubmit
- * \brief Run a ctest script
- *
- * cmCTestSubmitCommand defineds the command to submit the test results for
- * the project.
- */
class cmCTestSubmitCommand : public cmCTestHandlerCommand
{
public:
- std::unique_ptr<cmCommand> Clone() override;
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_submit"; }
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- void BindArguments() override;
- void CheckArguments() override;
- cmCTestGenericHandler* InitializeHandler() override;
+ struct SubmitArguments : HandlerArguments
+ {
+ bool CDashUpload = false;
+ bool InternalTest = false;
- bool CDashUpload = false;
- bool InternalTest = false;
+ std::string BuildID;
+ std::string CDashUploadFile;
+ std::string CDashUploadType;
+ std::string RetryCount;
+ std::string RetryDelay;
+ std::string SubmitURL;
- std::string BuildID;
- std::string CDashUploadFile;
- std::string CDashUploadType;
- std::string RetryCount;
- std::string RetryDelay;
- std::string SubmitURL;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Files;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> HttpHeaders;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Parts;
+ };
- cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Files;
- ArgumentParser::MaybeEmpty<std::vector<std::string>> HttpHeaders;
- cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Parts;
+private:
+ std::string GetName() const override { return "ctest_submit"; }
+
+ void CheckArguments(HandlerArguments& arguments,
+ cmExecutionStatus& status) const override;
+
+ std::unique_ptr<cmCTestGenericHandler> InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const override;
+
+ void ProcessAdditionalValues(cmCTestGenericHandler* handler,
+ HandlerArguments const& arguments,
+ cmExecutionStatus& status) const override;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 91dea55..1564c0e 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -19,7 +19,6 @@
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCurl.h"
-#include "cmCTestScriptHandler.h"
#include "cmCryptoHash.h"
#include "cmCurl.h"
#include "cmDuration.h"
@@ -117,40 +116,15 @@
return 0;
}
-cmCTestSubmitHandler::cmCTestSubmitHandler()
-{
- this->Initialize();
-}
-
-void cmCTestSubmitHandler::Initialize()
+cmCTestSubmitHandler::cmCTestSubmitHandler(cmCTest* ctest)
+ : Superclass(ctest)
+ , HttpHeaders(ctest->GetCommandLineHttpHeaders())
{
// We submit all available parts by default.
for (cmCTest::Part p = cmCTest::PartStart; p != cmCTest::PartCount;
p = static_cast<cmCTest::Part>(p + 1)) {
this->SubmitPart[p] = true;
}
- this->HasWarnings = false;
- this->HasErrors = false;
- this->Superclass::Initialize();
- this->HTTPProxy.clear();
- this->HTTPProxyType = 0;
- this->HTTPProxyAuth.clear();
- this->LogFile = nullptr;
- this->Files.clear();
-}
-
-int cmCTestSubmitHandler::ProcessCommandLineArguments(
- const std::string& currentArg, size_t& idx,
- const std::vector<std::string>& allArgs, bool& validArg)
-{
- if (cmHasLiteralPrefix(currentArg, "--http-header") &&
- idx < allArgs.size() - 1) {
- ++idx;
- this->HttpHeaders.push_back(allArgs[idx]);
- this->CommandLineHttpHeaders.push_back(allArgs[idx]);
- validArg = true;
- }
- return 1;
}
bool cmCTestSubmitHandler::SubmitUsingHTTP(
@@ -275,10 +249,8 @@
upload_as += "&stamp=";
upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag());
upload_as += "-";
- upload_as += ctest_curl.Escape(this->CTest->GetTestModelString());
- cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
- cmake* cm = ch->GetCMake();
- if (cm) {
+ upload_as += ctest_curl.Escape(this->CTest->GetTestGroupString());
+ if (cmake* cm = this->CMake) {
cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
upload_as += "&subproject=";
@@ -300,7 +272,7 @@
upload_as += "&MD5=";
- if (this->GetOption("InternalTest").IsOn()) {
+ if (this->InternalTest) {
upload_as += "ffffffffffffffffffffffffffffffff";
} else {
cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
@@ -382,8 +354,8 @@
bool successful_submission = response_code == 200;
if (!successful_submission || this->HasErrors) {
- std::string retryDelay = *this->GetOption("RetryDelay");
- std::string retryCount = *this->GetOption("RetryCount");
+ std::string retryDelay = this->RetryDelay;
+ std::string retryCount = this->RetryCount;
auto delay = cmDuration(
retryDelay.empty()
@@ -512,10 +484,6 @@
int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
std::string const& typeString)
{
- if (file.empty()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Upload file not specified\n");
- return -1;
- }
if (!cmSystemTools::FileExists(file)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Upload file not found: '" << file << "'\n");
@@ -542,11 +510,11 @@
fields = url.substr(pos + 1);
url.erase(pos);
}
- bool internalTest = this->GetOption("InternalTest").IsOn();
+ bool internalTest = this->InternalTest;
// Get RETRY_COUNT and RETRY_DELAY values if they were set.
- std::string retryDelayString = *this->GetOption("RetryDelay");
- std::string retryCountString = *this->GetOption("RetryCount");
+ std::string retryDelayString = this->RetryDelay;
+ std::string retryCountString = this->RetryCount;
auto retryDelay = std::chrono::seconds(0);
if (!retryDelayString.empty()) {
unsigned long retryDelayValue = 0;
@@ -573,9 +541,8 @@
// has already been uploaded
// TODO I added support for subproject. You would need to add
// a "&subproject=subprojectname" to the first POST.
- cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
- cmake* cm = ch->GetCMake();
- cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ cmValue subproject =
+ this->CMake->GetState()->GetGlobalProperty("SubProject");
// TODO: Encode values for a URL instead of trusting caller.
std::ostringstream str;
if (subproject) {
@@ -584,18 +551,18 @@
auto timeNow =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
str << "stamp=" << curl.Escape(this->CTest->GetCurrentTag()) << "-"
- << curl.Escape(this->CTest->GetTestModelString()) << "&"
- << "model=" << curl.Escape(this->CTest->GetTestModelString()) << "&"
+ << curl.Escape(this->CTest->GetTestGroupString()) << "&"
+ << "model=" << curl.Escape(this->CTest->GetTestGroupString()) << "&"
<< "build="
<< curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&"
<< "site=" << curl.Escape(this->CTest->GetCTestConfiguration("Site"))
<< "&"
- << "group=" << curl.Escape(this->CTest->GetTestModelString())
+ << "group=" << curl.Escape(this->CTest->GetTestGroupString())
<< "&"
// For now, we send both "track" and "group" to CDash in case we're
// submitting to an older instance that still expects the prior
// terminology.
- << "track=" << curl.Escape(this->CTest->GetTestModelString()) << "&"
+ << "track=" << curl.Escape(this->CTest->GetTestGroupString()) << "&"
<< "starttime=" << timeNow << "&"
<< "endtime=" << timeNow << "&"
<< "datafilesmd5[0]=" << md5sum << "&"
@@ -735,10 +702,9 @@
int cmCTestSubmitHandler::ProcessHandler()
{
- cmValue cdashUploadFile = this->GetOption("CDashUploadFile");
- cmValue cdashUploadType = this->GetOption("CDashUploadType");
- if (cdashUploadFile && cdashUploadType) {
- return this->HandleCDashUploadFile(*cdashUploadFile, *cdashUploadType);
+ if (this->CDashUpload) {
+ return this->HandleCDashUploadFile(this->CDashUploadFile,
+ this->CDashUploadType);
}
const std::string& buildDirectory =
@@ -906,7 +872,7 @@
cmCTest::SafeBuildIdField(this->CTest->GetCTestConfiguration("BuildName"));
std::string name = this->CTest->GetCTestConfiguration("Site") + "___" +
buildname + "___" + this->CTest->GetCurrentTag() + "-" +
- this->CTest->GetTestModelString() + "___XML___";
+ this->CTest->GetTestGroupString() + "___XML___";
return name;
}
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index d152b71..86067f6 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -4,7 +4,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <iosfwd>
#include <set>
#include <string>
@@ -24,7 +23,7 @@
public:
using Superclass = cmCTestGenericHandler;
- cmCTestSubmitHandler();
+ cmCTestSubmitHandler(cmCTest* ctest);
~cmCTestSubmitHandler() override { this->LogFile = nullptr; }
/*
@@ -32,13 +31,6 @@
*/
int ProcessHandler() override;
- void Initialize() override;
-
- //! Set all the submit arguments
- int ProcessCommandLineArguments(const std::string& currentArg, size_t& idx,
- const std::vector<std::string>& allArgs,
- bool& validArg) override;
-
/** Specify a set of parts (by name) to submit. */
void SelectParts(std::set<cmCTest::Part> const& parts);
@@ -50,12 +42,7 @@
void SetHttpHeaders(std::vector<std::string> const& v)
{
- if (this->CommandLineHttpHeaders.empty()) {
- this->HttpHeaders = v;
- } else {
- this->HttpHeaders = this->CommandLineHttpHeaders;
- this->HttpHeaders.insert(this->HttpHeaders.end(), v.begin(), v.end());
- }
+ this->HttpHeaders.insert(this->HttpHeaders.end(), v.begin(), v.end());
}
private:
@@ -79,13 +66,22 @@
class ResponseParser;
std::string HTTPProxy;
- int HTTPProxyType;
+ int HTTPProxyType = 0;
std::string HTTPProxyAuth;
- std::ostream* LogFile;
+ std::ostream* LogFile = nullptr;
bool SubmitPart[cmCTest::PartCount];
- bool HasWarnings;
- bool HasErrors;
+ bool HasWarnings = false;
+ bool HasErrors = false;
std::set<std::string> Files;
- std::vector<std::string> CommandLineHttpHeaders;
std::vector<std::string> HttpHeaders;
+
+ bool CDashUpload = false;
+ bool InternalTest = false;
+
+ std::string CDashUploadFile;
+ std::string CDashUploadType;
+ std::string RetryCount;
+ std::string RetryDelay;
+
+ friend class cmCTestSubmitCommand;
};
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 98ce862..ef3c80f 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -6,44 +6,26 @@
#include <cstdlib>
#include <ratio>
#include <sstream>
+#include <utility>
+#include <vector>
-#include <cmext/string_view>
+#include <cm/memory>
#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmValue.h"
-void cmCTestTestCommand::BindArguments()
+std::unique_ptr<cmCTestGenericHandler> cmCTestTestCommand::InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const
{
- this->cmCTestHandlerCommand::BindArguments();
- this->Bind("START"_s, this->Start);
- this->Bind("END"_s, this->End);
- this->Bind("STRIDE"_s, this->Stride);
- this->Bind("EXCLUDE"_s, this->Exclude);
- this->Bind("INCLUDE"_s, this->Include);
- this->Bind("EXCLUDE_LABEL"_s, this->ExcludeLabel);
- this->Bind("INCLUDE_LABEL"_s, this->IncludeLabel);
- this->Bind("EXCLUDE_FROM_FILE"_s, this->ExcludeTestsFromFile);
- this->Bind("INCLUDE_FROM_FILE"_s, this->IncludeTestsFromFile);
- this->Bind("EXCLUDE_FIXTURE"_s, this->ExcludeFixture);
- this->Bind("EXCLUDE_FIXTURE_SETUP"_s, this->ExcludeFixtureSetup);
- this->Bind("EXCLUDE_FIXTURE_CLEANUP"_s, this->ExcludeFixtureCleanup);
- this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel);
- this->Bind("REPEAT"_s, this->Repeat);
- this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom);
- this->Bind("STOP_TIME"_s, this->StopTime);
- this->Bind("TEST_LOAD"_s, this->TestLoad);
- this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
- this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure);
- this->Bind("OUTPUT_JUNIT"_s, this->OutputJUnit);
-}
-
-cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
-{
- cmValue ctestTimeout = this->Makefile->GetDefinition("CTEST_TEST_TIMEOUT");
+ cmMakefile& mf = status.GetMakefile();
+ auto& args = static_cast<TestArguments&>(arguments);
+ cmValue ctestTimeout = mf.GetDefinition("CTEST_TEST_TIMEOUT");
cmDuration timeout;
if (ctestTimeout) {
@@ -57,80 +39,77 @@
}
this->CTest->SetTimeOut(timeout);
- cmValue resourceSpecFile =
- this->Makefile->GetDefinition("CTEST_RESOURCE_SPEC_FILE");
- if (this->ResourceSpecFile.empty() && resourceSpecFile) {
- this->ResourceSpecFile = *resourceSpecFile;
+ cmValue resourceSpecFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (args.ResourceSpecFile.empty() && resourceSpecFile) {
+ args.ResourceSpecFile = *resourceSpecFile;
}
- cmCTestTestHandler* handler = this->InitializeActualHandler();
- if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
- handler->SetOption(
- "TestsToRunInformation",
- cmStrCat(this->Start, ',', this->End, ',', this->Stride));
+ auto handler = this->InitializeActualHandler(args, status);
+ if (!args.Start.empty() || !args.End.empty() || !args.Stride.empty()) {
+ handler->TestOptions.TestsToRunInformation =
+ cmStrCat(args.Start, ',', args.End, ',', args.Stride);
}
- if (!this->Exclude.empty()) {
- handler->SetOption("ExcludeRegularExpression", this->Exclude);
+ if (!args.Exclude.empty()) {
+ handler->TestOptions.ExcludeRegularExpression = args.Exclude;
}
- if (!this->Include.empty()) {
- handler->SetOption("IncludeRegularExpression", this->Include);
+ if (!args.Include.empty()) {
+ handler->TestOptions.IncludeRegularExpression = args.Include;
}
- if (!this->ExcludeLabel.empty()) {
- handler->AddMultiOption("ExcludeLabelRegularExpression",
- this->ExcludeLabel);
+ if (!args.ExcludeLabel.empty()) {
+ handler->TestOptions.ExcludeLabelRegularExpression.push_back(
+ args.ExcludeLabel);
}
- if (!this->IncludeLabel.empty()) {
- handler->AddMultiOption("LabelRegularExpression", this->IncludeLabel);
+ if (!args.IncludeLabel.empty()) {
+ handler->TestOptions.LabelRegularExpression.push_back(args.IncludeLabel);
}
- if (!this->ExcludeTestsFromFile.empty()) {
- handler->SetOption("ExcludeTestListFile", this->ExcludeTestsFromFile);
+ if (!args.ExcludeTestsFromFile.empty()) {
+ handler->TestOptions.ExcludeTestListFile = args.ExcludeTestsFromFile;
}
- if (!this->IncludeTestsFromFile.empty()) {
- handler->SetOption("TestListFile", this->IncludeTestsFromFile);
+ if (!args.IncludeTestsFromFile.empty()) {
+ handler->TestOptions.TestListFile = args.IncludeTestsFromFile;
}
- if (!this->ExcludeFixture.empty()) {
- handler->SetOption("ExcludeFixtureRegularExpression",
- this->ExcludeFixture);
+ if (!args.ExcludeFixture.empty()) {
+ handler->TestOptions.ExcludeFixtureRegularExpression = args.ExcludeFixture;
}
- if (!this->ExcludeFixtureSetup.empty()) {
- handler->SetOption("ExcludeFixtureSetupRegularExpression",
- this->ExcludeFixtureSetup);
+ if (!args.ExcludeFixtureSetup.empty()) {
+ handler->TestOptions.ExcludeFixtureSetupRegularExpression =
+ args.ExcludeFixtureSetup;
}
- if (!this->ExcludeFixtureCleanup.empty()) {
- handler->SetOption("ExcludeFixtureCleanupRegularExpression",
- this->ExcludeFixtureCleanup);
+ if (!args.ExcludeFixtureCleanup.empty()) {
+ handler->TestOptions.ExcludeFixtureCleanupRegularExpression =
+ args.ExcludeFixtureCleanup;
}
- if (this->StopOnFailure) {
- handler->SetOption("StopOnFailure", "ON");
+ if (args.StopOnFailure) {
+ handler->TestOptions.StopOnFailure = true;
}
- if (this->ParallelLevel) {
- handler->SetOption("ParallelLevel", *this->ParallelLevel);
+ if (args.ParallelLevel) {
+ handler->ParallelLevel = *args.ParallelLevel;
}
- if (!this->Repeat.empty()) {
- handler->SetOption("Repeat", this->Repeat);
+ if (!args.Repeat.empty()) {
+ handler->Repeat = args.Repeat;
}
- if (!this->ScheduleRandom.empty()) {
- handler->SetOption("ScheduleRandom", this->ScheduleRandom);
+ if (!args.ScheduleRandom.empty()) {
+ handler->TestOptions.ScheduleRandom = cmValue(args.ScheduleRandom).IsOn();
}
- if (!this->ResourceSpecFile.empty()) {
- handler->SetOption("ResourceSpecFile", this->ResourceSpecFile);
+ if (!args.ResourceSpecFile.empty()) {
+ handler->TestOptions.ResourceSpecFile = args.ResourceSpecFile;
}
- if (!this->StopTime.empty()) {
- this->CTest->SetStopTime(this->StopTime);
+ if (!args.StopTime.empty()) {
+ this->CTest->SetStopTime(args.StopTime);
}
// Test load is determined by: TEST_LOAD argument,
// or CTEST_TEST_LOAD script variable, or ctest --test-load
// command line argument... in that order.
unsigned long testLoad;
- cmValue ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
- if (!this->TestLoad.empty()) {
- if (!cmStrToULong(this->TestLoad, &testLoad)) {
+ cmValue ctestTestLoad = mf.GetDefinition("CTEST_TEST_LOAD");
+ if (!args.TestLoad.empty()) {
+ if (!cmStrToULong(args.TestLoad, &testLoad)) {
testLoad = 0;
cmCTestLog(this->CTest, WARNING,
- "Invalid value for 'TEST_LOAD' : " << this->TestLoad
+ "Invalid value for 'TEST_LOAD' : " << args.TestLoad
<< std::endl);
}
} else if (cmNonempty(ctestTestLoad)) {
@@ -146,22 +125,32 @@
handler->SetTestLoad(testLoad);
if (cmValue labelsForSubprojects =
- this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+ mf.GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
this->CTest->SetCTestConfiguration("LabelsForSubprojects",
- *labelsForSubprojects, this->Quiet);
+ *labelsForSubprojects, args.Quiet);
}
- if (!this->OutputJUnit.empty()) {
- handler->SetJUnitXMLFileName(this->OutputJUnit);
+ if (!args.OutputJUnit.empty()) {
+ handler->SetJUnitXMLFileName(args.OutputJUnit);
}
- handler->SetQuiet(this->Quiet);
- return handler;
+ handler->SetQuiet(args.Quiet);
+ return std::unique_ptr<cmCTestGenericHandler>(std::move(handler));
}
-cmCTestTestHandler* cmCTestTestCommand::InitializeActualHandler()
+std::unique_ptr<cmCTestTestHandler>
+cmCTestTestCommand::InitializeActualHandler(HandlerArguments&,
+ cmExecutionStatus&) const
{
- cmCTestTestHandler* handler = this->CTest->GetTestHandler();
- handler->Initialize();
- return handler;
+ return cm::make_unique<cmCTestTestHandler>(this->CTest);
+}
+
+bool cmCTestTestCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ static auto const parser = MakeTestParser<TestArguments>();
+
+ return this->Invoke(parser, args, status, [&](TestArguments& a) {
+ return this->ExecuteHandlerCommand(a, status);
+ });
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 23661c5..038d219 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -4,66 +4,88 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
-#include <utility>
+#include <type_traits>
+#include <vector>
-#include <cm/memory>
#include <cm/optional>
+#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmCTestHandlerCommand.h"
-#include "cmCommand.h"
+class cmExecutionStatus;
class cmCTestGenericHandler;
class cmCTestTestHandler;
-/** \class cmCTestTest
- * \brief Run a ctest script
- *
- * cmCTestTestCommand defineds the command to test the project.
- */
class cmCTestTestCommand : public cmCTestHandlerCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestTestCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_test"; }
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- void BindArguments() override;
- virtual cmCTestTestHandler* InitializeActualHandler();
- cmCTestGenericHandler* InitializeHandler() override;
+ struct TestArguments : HandlerArguments
+ {
+ std::string Start;
+ std::string End;
+ std::string Stride;
+ std::string Exclude;
+ std::string Include;
+ std::string ExcludeLabel;
+ std::string IncludeLabel;
+ std::string IncludeTestsFromFile;
+ std::string ExcludeTestsFromFile;
+ std::string ExcludeFixture;
+ std::string ExcludeFixtureSetup;
+ std::string ExcludeFixtureCleanup;
+ cm::optional<ArgumentParser::Maybe<std::string>> ParallelLevel;
+ std::string Repeat;
+ std::string ScheduleRandom;
+ std::string StopTime;
+ std::string TestLoad;
+ std::string ResourceSpecFile;
+ std::string OutputJUnit;
+ bool StopOnFailure = false;
+ };
- std::string Start;
- std::string End;
- std::string Stride;
- std::string Exclude;
- std::string Include;
- std::string ExcludeLabel;
- std::string IncludeLabel;
- std::string IncludeTestsFromFile;
- std::string ExcludeTestsFromFile;
- std::string ExcludeFixture;
- std::string ExcludeFixtureSetup;
- std::string ExcludeFixtureCleanup;
- cm::optional<ArgumentParser::Maybe<std::string>> ParallelLevel;
- std::string Repeat;
- std::string ScheduleRandom;
- std::string StopTime;
- std::string TestLoad;
- std::string ResourceSpecFile;
- std::string OutputJUnit;
- bool StopOnFailure = false;
+ template <typename Args>
+ static auto MakeTestParser() -> cmArgumentParser<Args>
+ {
+ static_assert(std::is_base_of<TestArguments, Args>::value, "");
+ return cmArgumentParser<Args>{ MakeHandlerParser<Args>() }
+ .Bind("START"_s, &TestArguments::Start)
+ .Bind("END"_s, &TestArguments::End)
+ .Bind("STRIDE"_s, &TestArguments::Stride)
+ .Bind("EXCLUDE"_s, &TestArguments::Exclude)
+ .Bind("INCLUDE"_s, &TestArguments::Include)
+ .Bind("EXCLUDE_LABEL"_s, &TestArguments::ExcludeLabel)
+ .Bind("INCLUDE_LABEL"_s, &TestArguments::IncludeLabel)
+ .Bind("EXCLUDE_FROM_FILE"_s, &TestArguments::ExcludeTestsFromFile)
+ .Bind("INCLUDE_FROM_FILE"_s, &TestArguments::IncludeTestsFromFile)
+ .Bind("EXCLUDE_FIXTURE"_s, &TestArguments::ExcludeFixture)
+ .Bind("EXCLUDE_FIXTURE_SETUP"_s, &TestArguments::ExcludeFixtureSetup)
+ .Bind("EXCLUDE_FIXTURE_CLEANUP"_s, &TestArguments::ExcludeFixtureCleanup)
+ .Bind("PARALLEL_LEVEL"_s, &TestArguments::ParallelLevel)
+ .Bind("REPEAT"_s, &TestArguments::Repeat)
+ .Bind("SCHEDULE_RANDOM"_s, &TestArguments::ScheduleRandom)
+ .Bind("STOP_TIME"_s, &TestArguments::StopTime)
+ .Bind("TEST_LOAD"_s, &TestArguments::TestLoad)
+ .Bind("RESOURCE_SPEC_FILE"_s, &TestArguments::ResourceSpecFile)
+ .Bind("STOP_ON_FAILURE"_s, &TestArguments::StopOnFailure)
+ .Bind("OUTPUT_JUNIT"_s, &TestArguments::OutputJUnit);
+ }
+
+private:
+ std::string GetName() const override { return "ctest_test"; }
+
+ virtual std::unique_ptr<cmCTestTestHandler> InitializeActualHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const;
+
+ std::unique_ptr<cmCTestGenericHandler> InitializeHandler(
+ HandlerArguments& arguments, cmExecutionStatus& status) const override;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index c7875cd..f42d84e 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -8,7 +8,6 @@
#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
-#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
@@ -97,8 +96,7 @@
{
cmWorkingDirectory workdir(fname);
if (workdir.Failed()) {
- status.SetError("Failed to change directory to " + fname + " : " +
- std::strerror(workdir.GetLastResult()));
+ status.SetError(workdir.GetError());
return false;
}
const char* testFilename;
@@ -130,7 +128,7 @@
status.SetError("called with incorrect number of arguments");
return false;
}
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
for (std::string const& arg : args) {
std::string fname;
@@ -156,7 +154,7 @@
}
std::string fname =
- cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), '/', args[0]);
+ cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), '/', args[0]);
return ReadSubdirectory(std::move(fname), status);
}
@@ -276,25 +274,10 @@
} // namespace
-cmCTestTestHandler::cmCTestTestHandler()
+cmCTestTestHandler::cmCTestTestHandler(cmCTest* ctest)
+ : Superclass(ctest)
+ , TestOptions(ctest->GetTestOptions())
{
- this->UseUnion = false;
-
- this->UseIncludeRegExpFlag = false;
- this->UseExcludeRegExpFlag = false;
- this->UseExcludeRegExpFirst = false;
-
- this->CustomMaximumPassedTestOutputSize = 1 * 1024;
- this->CustomMaximumFailedTestOutputSize = 300 * 1024;
- this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
-
- this->MemCheck = false;
-
- this->LogFile = nullptr;
-
- // Support for JUnit XML output.
- this->JUnitXMLFileName = "";
-
// Regular expressions to scan test output for custom measurements.
// Capture the whole section of test output from the first opening
@@ -315,46 +298,6 @@
this->CustomLabelRegex.compile("<CTestLabel>(.*)</CTestLabel>");
}
-void cmCTestTestHandler::Initialize()
-{
- this->Superclass::Initialize();
-
- this->ElapsedTestingTime = cmDuration();
-
- this->TestResults.clear();
-
- this->CustomTestsIgnore.clear();
- this->StartTest.clear();
- this->EndTest.clear();
-
- this->CustomPreTest.clear();
- this->CustomPostTest.clear();
- this->CustomMaximumPassedTestOutputSize = 1 * 1024;
- this->CustomMaximumFailedTestOutputSize = 300 * 1024;
- this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
-
- this->TestsToRun.clear();
-
- this->UseIncludeRegExpFlag = false;
- this->UseExcludeRegExpFlag = false;
- this->UseExcludeRegExpFirst = false;
- this->IncludeLabelRegularExpressions.clear();
- this->ExcludeLabelRegularExpressions.clear();
- this->IncludeRegExp.clear();
- this->ExcludeRegExp.clear();
- this->ExcludeFixtureRegExp.clear();
- this->ExcludeFixtureSetupRegExp.clear();
- this->ExcludeFixtureCleanupRegExp.clear();
- this->TestListFile.clear();
- this->ExcludeTestListFile.clear();
- this->TestsToRunByName.reset();
- this->TestsToExcludeByName.reset();
-
- this->TestsToRunString.clear();
- this->UseUnion = false;
- this->TestList.clear();
-}
-
void cmCTestTestHandler::PopulateCustomVectors(cmMakefile* mf)
{
this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_TEST",
@@ -365,14 +308,14 @@
this->CustomTestsIgnore);
this->CTest->PopulateCustomInteger(
mf, "CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE",
- this->CustomMaximumPassedTestOutputSize);
+ this->TestOptions.OutputSizePassed);
this->CTest->PopulateCustomInteger(
mf, "CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE",
- this->CustomMaximumFailedTestOutputSize);
+ this->TestOptions.OutputSizeFailed);
cmValue dval = mf->GetDefinition("CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION");
if (dval) {
- if (!this->SetTestOutputTruncation(*dval)) {
+ if (!SetTruncationMode(this->TestOptions.OutputTruncation, *dval)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Invalid value for CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION: "
<< *dval << std::endl);
@@ -411,7 +354,7 @@
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
(this->MemCheck ? "Memory check" : "Test")
<< " project "
- << cmSystemTools::GetCurrentWorkingDirectory()
+ << cmSystemTools::GetLogicalWorkingDirectory()
<< std::endl,
this->Quiet);
if (!this->PreProcessHandler()) {
@@ -521,12 +464,11 @@
bool cmCTestTestHandler::ProcessOptions()
{
// Update internal data structure from generic one
- this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
- this->SetUseUnion(this->GetOption("UseUnion").IsOn());
- if (this->GetOption("ScheduleRandom").IsOn()) {
+ this->SetTestsToRunInformation(this->TestOptions.TestsToRunInformation);
+ if (this->TestOptions.ScheduleRandom) {
this->CTest->SetScheduleType("Random");
}
- if (cmValue repeat = this->GetOption("Repeat")) {
+ if (auto repeat = this->Repeat) {
cmsys::RegularExpression repeatRegex(
"^(UNTIL_FAIL|UNTIL_PASS|AFTER_TIMEOUT):([0-9]+)$");
if (repeatRegex.find(*repeat)) {
@@ -550,8 +492,8 @@
return false;
}
}
- if (cmValue parallelLevel = this->GetOption("ParallelLevel")) {
- if (parallelLevel.IsEmpty()) {
+ if (auto parallelLevel = this->ParallelLevel) {
+ if (parallelLevel->empty()) {
// An empty value tells ctest to choose a default.
this->CTest->SetParallelLevel(cm::nullopt);
} else {
@@ -567,50 +509,20 @@
}
}
- if (this->GetOption("StopOnFailure")) {
+ if (this->TestOptions.StopOnFailure) {
this->CTest->SetStopOnFailure(true);
}
- BuildLabelRE(this->GetMultiOption("LabelRegularExpression"),
+ BuildLabelRE(this->TestOptions.LabelRegularExpression,
this->IncludeLabelRegularExpressions);
- BuildLabelRE(this->GetMultiOption("ExcludeLabelRegularExpression"),
+ BuildLabelRE(this->TestOptions.ExcludeLabelRegularExpression,
this->ExcludeLabelRegularExpressions);
- cmValue val = this->GetOption("IncludeRegularExpression");
- if (val) {
+ if (!this->TestOptions.IncludeRegularExpression.empty()) {
this->UseIncludeRegExp();
- this->SetIncludeRegExp(*val);
}
- val = this->GetOption("ExcludeRegularExpression");
- if (val) {
+ if (!this->TestOptions.ExcludeRegularExpression.empty()) {
this->UseExcludeRegExp();
- this->SetExcludeRegExp(*val);
}
- val = this->GetOption("ExcludeFixtureRegularExpression");
- if (val) {
- this->ExcludeFixtureRegExp = *val;
- }
- val = this->GetOption("ExcludeFixtureSetupRegularExpression");
- if (val) {
- this->ExcludeFixtureSetupRegExp = *val;
- }
- val = this->GetOption("ExcludeFixtureCleanupRegularExpression");
- if (val) {
- this->ExcludeFixtureCleanupRegExp = *val;
- }
- val = this->GetOption("ResourceSpecFile");
- if (val) {
- this->ResourceSpecFile = *val;
- }
- val = this->GetOption("TestListFile");
- if (val) {
- this->TestListFile = val;
- }
- val = this->GetOption("ExcludeTestListFile");
- if (val) {
- this->ExcludeTestListFile = val;
- }
- this->SetRerunFailed(this->GetOption("RerunFailed").IsOn());
-
return true;
}
@@ -922,7 +834,7 @@
return false;
}
- if (this->RerunFailed) {
+ if (this->TestOptions.RerunFailed) {
return this->ComputeTestListForRerunFailed();
}
@@ -936,7 +848,7 @@
}
}
// expand the test list based on the union flag
- if (this->UseUnion) {
+ if (this->TestOptions.UseUnion) {
this->ExpandTestsToRunInformation(static_cast<int>(tmsize));
} else {
this->ExpandTestsToRunInformation(inREcnt);
@@ -951,7 +863,7 @@
inREcnt++;
}
- if (this->UseUnion) {
+ if (this->TestOptions.UseUnion) {
// if it is not in the list and not in the regexp then skip
if ((!this->TestsToRun.empty() &&
!cm::contains(this->TestsToRun, cnt)) &&
@@ -1034,22 +946,24 @@
this->Quiet);
// Prepare regular expression evaluators
- std::string setupRegExp(this->ExcludeFixtureRegExp);
- std::string cleanupRegExp(this->ExcludeFixtureRegExp);
- if (!this->ExcludeFixtureSetupRegExp.empty()) {
+ std::string setupRegExp(this->TestOptions.ExcludeFixtureRegularExpression);
+ std::string cleanupRegExp(this->TestOptions.ExcludeFixtureRegularExpression);
+ if (!this->TestOptions.ExcludeFixtureSetupRegularExpression.empty()) {
if (setupRegExp.empty()) {
- setupRegExp = this->ExcludeFixtureSetupRegExp;
+ setupRegExp = this->TestOptions.ExcludeFixtureSetupRegularExpression;
} else {
- setupRegExp.append("(" + setupRegExp + ")|(" +
- this->ExcludeFixtureSetupRegExp + ")");
+ setupRegExp.append(
+ "(" + setupRegExp + ")|(" +
+ this->TestOptions.ExcludeFixtureSetupRegularExpression + ")");
}
}
- if (!this->ExcludeFixtureCleanupRegExp.empty()) {
+ if (!this->TestOptions.ExcludeFixtureCleanupRegularExpression.empty()) {
if (cleanupRegExp.empty()) {
- cleanupRegExp = this->ExcludeFixtureCleanupRegExp;
+ cleanupRegExp = this->TestOptions.ExcludeFixtureCleanupRegularExpression;
} else {
- cleanupRegExp.append("(" + cleanupRegExp + ")|(" +
- this->ExcludeFixtureCleanupRegExp + ")");
+ cleanupRegExp.append(
+ "(" + cleanupRegExp + ")|(" +
+ this->TestOptions.ExcludeFixtureCleanupRegularExpression + ")");
}
}
cmsys::RegularExpression excludeSetupRegex(setupRegExp);
@@ -1431,7 +1345,7 @@
tests[p.Index].Depends = depends;
properties[p.Index] = &p;
}
- parallel->SetResourceSpecFile(this->ResourceSpecFile);
+ parallel->SetResourceSpecFile(this->TestOptions.ResourceSpecFile);
if (!parallel->SetTests(std::move(tests), std::move(properties))) {
return false;
}
@@ -1467,7 +1381,7 @@
return;
}
- this->CTest->StartXML(xml, this->AppendXML);
+ this->CTest->StartXML(xml, this->CMake, this->AppendXML);
this->CTest->GenerateSubprojectsOutput(xml);
xml.StartElement("Testing");
xml.Element("StartDateTime", this->StartTest);
@@ -1761,7 +1675,7 @@
for (unsigned int ai = 0; ai < attempted.size() && fullPath.empty(); ++ai) {
// first check without exe extension
if (cmSystemTools::FileExists(attempted[ai], true)) {
- fullPath = cmSystemTools::CollapseFullPath(attempted[ai]);
+ fullPath = cmSystemTools::ToNormalizedPathOnDisk(attempted[ai]);
resultingConfig = attemptedConfigs[ai];
}
// then try with the exe extension
@@ -1770,7 +1684,7 @@
tempPath =
cmStrCat(attempted[ai], cmSystemTools::GetExecutableExtension());
if (cmSystemTools::FileExists(tempPath, true)) {
- fullPath = cmSystemTools::CollapseFullPath(tempPath);
+ fullPath = cmSystemTools::ToNormalizedPathOnDisk(tempPath);
resultingConfig = attemptedConfigs[ai];
} else {
failed.push_back(tempPath);
@@ -1810,11 +1724,13 @@
bool cmCTestTestHandler::GetListOfTests()
{
- if (!this->IncludeRegExp.empty()) {
- this->IncludeTestsRegularExpression.compile(this->IncludeRegExp);
+ if (!this->TestOptions.IncludeRegularExpression.empty()) {
+ this->IncludeTestsRegularExpression.compile(
+ this->TestOptions.IncludeRegularExpression);
}
- if (!this->ExcludeRegExp.empty()) {
- this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp);
+ if (!this->TestOptions.ExcludeRegularExpression.empty()) {
+ this->ExcludeTestsRegularExpression.compile(
+ this->TestOptions.ExcludeRegularExpression);
}
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Constructing a list of tests" << std::endl, this->Quiet);
@@ -1864,19 +1780,20 @@
return false;
}
cmValue specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE");
- if (this->ResourceSpecFile.empty() && specFile) {
- this->ResourceSpecFile = *specFile;
+ if (this->TestOptions.ResourceSpecFile.empty() && specFile) {
+ this->TestOptions.ResourceSpecFile = *specFile;
}
- if (!this->TestListFile.empty()) {
- this->TestsToRunByName = this->ReadTestListFile(this->TestListFile);
+ if (!this->TestOptions.TestListFile.empty()) {
+ this->TestsToRunByName =
+ this->ReadTestListFile(this->TestOptions.TestListFile);
if (!this->TestsToRunByName) {
return false;
}
}
- if (!this->ExcludeTestListFile.empty()) {
+ if (!this->TestOptions.ExcludeTestListFile.empty()) {
this->TestsToExcludeByName =
- this->ReadTestListFile(this->ExcludeTestListFile);
+ this->ReadTestListFile(this->TestOptions.ExcludeTestListFile);
if (!this->TestsToExcludeByName) {
return false;
}
@@ -2153,41 +2070,14 @@
}
}
-void cmCTestTestHandler::SetIncludeRegExp(const std::string& arg)
+void cmCTestTestHandler::SetTestsToRunInformation(std::string const& in)
{
- this->IncludeRegExp = arg;
-}
-
-void cmCTestTestHandler::SetExcludeRegExp(const std::string& arg)
-{
- this->ExcludeRegExp = arg;
-}
-
-bool cmCTestTestHandler::SetTestOutputTruncation(const std::string& mode)
-{
- if (mode == "tail") {
- this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
- } else if (mode == "middle") {
- this->TestOutputTruncation = cmCTestTypes::TruncationMode::Middle;
- } else if (mode == "head") {
- this->TestOutputTruncation = cmCTestTypes::TruncationMode::Head;
- } else {
- return false;
- }
- return true;
-}
-
-void cmCTestTestHandler::SetTestsToRunInformation(cmValue in)
-{
- if (!in) {
- return;
- }
- this->TestsToRunString = *in;
+ this->TestsToRunString = in;
// if the argument is a file, then read it and use the contents as the
// string
- if (cmSystemTools::FileExists(*in)) {
- cmsys::ifstream fin(in->c_str());
- unsigned long filelen = cmSystemTools::FileLength(*in);
+ if (cmSystemTools::FileExists(in)) {
+ cmsys::ifstream fin(in.c_str());
+ unsigned long filelen = cmSystemTools::FileLength(in);
auto buff = cm::make_unique<char[]>(filelen + 1);
fin.getline(buff.get(), filelen);
buff[fin.gcount()] = 0;
@@ -2495,7 +2385,7 @@
}
std::string const& val = *it;
for (cmCTestTestProperties& rt : this->TestList) {
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
if (cwd == rt.Directory) {
if (key == "LABELS"_s) {
cmList DirectoryLabels{ val };
@@ -2559,7 +2449,7 @@
cmCTestTestProperties test;
test.Name = testname;
test.Args = args;
- test.Directory = cmSystemTools::GetCurrentWorkingDirectory();
+ test.Directory = cmSystemTools::GetLogicalWorkingDirectory();
cmCTestOptionalLog(this->CTest, DEBUG,
"Set test directory: " << test.Directory << std::endl,
this->Quiet);
@@ -2590,22 +2480,22 @@
void cmCTestTestHandler::SetJUnitXMLFileName(const std::string& filename)
{
- this->JUnitXMLFileName = filename;
+ this->TestOptions.JUnitXMLFileName = filename;
}
bool cmCTestTestHandler::WriteJUnitXML()
{
- if (this->JUnitXMLFileName.empty()) {
+ if (this->TestOptions.JUnitXMLFileName.empty()) {
return true;
}
// Open new XML file for writing.
cmGeneratedFileStream xmlfile;
xmlfile.SetTempExt("tmp");
- xmlfile.Open(this->JUnitXMLFileName);
+ xmlfile.Open(this->TestOptions.JUnitXMLFileName);
if (!xmlfile) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Problem opening file: " << this->JUnitXMLFileName
+ "Problem opening file: " << this->TestOptions.JUnitXMLFileName
<< std::endl);
return false;
}
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index c35af3f..a9e2d67 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -24,11 +24,39 @@
#include "cmCTestTypes.h" // IWYU pragma: keep
#include "cmDuration.h"
#include "cmListFileCache.h"
-#include "cmValue.h"
class cmMakefile;
class cmXMLWriter;
+struct cmCTestTestOptions
+{
+ bool RerunFailed = false;
+ bool ScheduleRandom = false;
+ bool StopOnFailure = false;
+ bool UseUnion = false;
+
+ int OutputSizePassed = 1 * 1024;
+ int OutputSizeFailed = 300 * 1024;
+ cmCTestTypes::TruncationMode OutputTruncation =
+ cmCTestTypes::TruncationMode::Tail;
+
+ std::string TestsToRunInformation;
+ std::string IncludeRegularExpression;
+ std::string ExcludeRegularExpression;
+
+ std::vector<std::string> LabelRegularExpression;
+ std::vector<std::string> ExcludeLabelRegularExpression;
+
+ std::string ExcludeFixtureRegularExpression;
+ std::string ExcludeFixtureSetupRegularExpression;
+ std::string ExcludeFixtureCleanupRegularExpression;
+
+ std::string TestListFile;
+ std::string ExcludeTestListFile;
+ std::string ResourceSpecFile;
+ std::string JUnitXMLFileName;
+};
+
/** \class cmCTestTestHandler
* \brief A class that handles ctest -S invocations
*
@@ -48,19 +76,6 @@
int ProcessHandler() override;
/**
- * When both -R and -I are used should the resulting test list be the
- * intersection or the union of the lists. By default it is the
- * intersection.
- */
- void SetUseUnion(bool val) { this->UseUnion = val; }
-
- /**
- * Set whether or not CTest should only execute the tests that failed
- * on the previous run. By default this is false.
- */
- void SetRerunFailed(bool val) { this->RerunFailed = val; }
-
- /**
* This method is called when reading CTest custom file
*/
void PopulateCustomVectors(cmMakefile* mf) override;
@@ -69,28 +84,14 @@
/// them on
void UseIncludeRegExp();
void UseExcludeRegExp();
- void SetIncludeRegExp(const std::string&);
- void SetExcludeRegExp(const std::string&);
void SetMaxIndex(int n) { this->MaxIndex = n; }
int GetMaxIndex() { return this->MaxIndex; }
- void SetTestOutputSizePassed(int n)
- {
- this->CustomMaximumPassedTestOutputSize = n;
- }
- void SetTestOutputSizeFailed(int n)
- {
- this->CustomMaximumFailedTestOutputSize = n;
- }
-
- //! Set test output truncation mode. Return false if unknown mode.
- bool SetTestOutputTruncation(const std::string& mode);
-
//! pass the -I argument down
- void SetTestsToRunInformation(cmValue);
+ void SetTestsToRunInformation(std::string const& in);
- cmCTestTestHandler();
+ cmCTestTestHandler(cmCTest* ctest);
/*
* Add the test to the list of tests to be executed
@@ -107,8 +108,6 @@
*/
bool SetDirectoryProperties(const std::vector<std::string>& args);
- void Initialize() override;
-
struct cmCTestTestResourceRequirement
{
std::string ResourceType;
@@ -260,6 +259,8 @@
void CleanTestOutput(std::string& output, size_t length,
cmCTestTypes::TruncationMode truncate);
+ cmCTestTestOptions TestOptions;
+
cmDuration ElapsedTestingTime;
using TestResultsVector = std::vector<cmCTestTestResult>;
@@ -270,10 +271,7 @@
std::string EndTest;
std::chrono::system_clock::time_point StartTestTime;
std::chrono::system_clock::time_point EndTestTime;
- bool MemCheck;
- int CustomMaximumPassedTestOutputSize;
- int CustomMaximumFailedTestOutputSize;
- cmCTestTypes::TruncationMode TestOutputTruncation;
+ bool MemCheck = false;
int MaxIndex;
public:
@@ -350,24 +348,17 @@
std::vector<int> TestsToRun;
- bool UseIncludeRegExpFlag;
- bool UseExcludeRegExpFlag;
- bool UseExcludeRegExpFirst;
- std::string IncludeRegExp;
- std::string ExcludeRegExp;
- std::string ExcludeFixtureRegExp;
- std::string ExcludeFixtureSetupRegExp;
- std::string ExcludeFixtureCleanupRegExp;
+ bool UseIncludeRegExpFlag = false;
+ bool UseExcludeRegExpFlag = false;
+ bool UseExcludeRegExpFirst = false;
std::vector<cmsys::RegularExpression> IncludeLabelRegularExpressions;
std::vector<cmsys::RegularExpression> ExcludeLabelRegularExpressions;
cmsys::RegularExpression IncludeTestsRegularExpression;
cmsys::RegularExpression ExcludeTestsRegularExpression;
- std::string TestListFile;
- std::string ExcludeTestListFile;
cm::optional<std::set<std::string>> TestsToRunByName;
cm::optional<std::set<std::string>> TestsToExcludeByName;
-
- std::string ResourceSpecFile;
+ cm::optional<std::string> ParallelLevel;
+ cm::optional<std::string> Repeat;
void RecordCustomTestMeasurements(cmXMLWriter& xml, std::string content);
void CheckLabelFilter(cmCTestTestProperties& it);
@@ -375,7 +366,6 @@
void CheckLabelFilterInclude(cmCTestTestProperties& it);
std::string TestsToRunString;
- bool UseUnion;
ListOfTests TestList;
size_t TotalNumberOfTests;
cmsys::RegularExpression AllTestMeasurementsRegex;
@@ -383,11 +373,10 @@
cmsys::RegularExpression CustomCompletionStatusRegex;
cmsys::RegularExpression CustomLabelRegex;
- std::ostream* LogFile;
+ std::ostream* LogFile = nullptr;
cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
int RepeatCount = 1;
- bool RerunFailed;
- std::string JUnitXMLFileName;
+ friend class cmCTestTestCommand;
};
diff --git a/Source/CTest/cmCTestTypes.cxx b/Source/CTest/cmCTestTypes.cxx
new file mode 100644
index 0000000..9a06cd9
--- /dev/null
+++ b/Source/CTest/cmCTestTypes.cxx
@@ -0,0 +1,24 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmCTestTypes.h"
+
+#include <string>
+
+namespace cmCTestTypes {
+
+bool SetTruncationMode(TruncationMode& mode, cm::string_view str)
+{
+ if (str == "tail") {
+ mode = cmCTestTypes::TruncationMode::Tail;
+ } else if (str == "middle") {
+ mode = cmCTestTypes::TruncationMode::Middle;
+ } else if (str == "head") {
+ mode = cmCTestTypes::TruncationMode::Head;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+} // namespace cmCTestTypes
diff --git a/Source/CTest/cmCTestTypes.h b/Source/CTest/cmCTestTypes.h
index 843d27a..0dfc4a5 100644
--- a/Source/CTest/cmCTestTypes.h
+++ b/Source/CTest/cmCTestTypes.h
@@ -5,12 +5,18 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cm/string_view>
+
namespace cmCTestTypes {
+// Test output truncation mode
enum class TruncationMode
-{ // Test output truncation mode
+{
Tail,
Middle,
Head
};
-}
+
+bool SetTruncationMode(TruncationMode& mode, cm::string_view str);
+
+} // namespace cmCTestTypes
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 6655bf7..2e64585 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -2,84 +2,329 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUpdateCommand.h"
+#include <chrono>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cm/memory>
+#include <cmext/string_view>
+
+#include "cmArgumentParser.h"
+#include "cmCLocaleEnvironmentScope.h"
#include "cmCTest.h"
-#include "cmCTestUpdateHandler.h"
+#include "cmCTestBZR.h"
+#include "cmCTestCVS.h"
+#include "cmCTestGIT.h"
+#include "cmCTestHG.h"
+#include "cmCTestP4.h"
+#include "cmCTestSVN.h"
+#include "cmCTestVC.h"
+#include "cmExecutionStatus.h"
+#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmVersion.h"
+#include "cmXMLWriter.h"
-cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
+namespace {
+
+enum
{
- if (!this->Source.empty()) {
- this->CTest->SetCTestConfiguration(
- "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
- this->Quiet);
- } else {
- this->CTest->SetCTestConfiguration(
- "SourceDirectory",
- cmSystemTools::CollapseFullPath(
- this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
- this->Quiet);
+ e_UNKNOWN = 0,
+ e_CVS,
+ e_SVN,
+ e_BZR,
+ e_GIT,
+ e_HG,
+ e_P4,
+ e_LAST
+};
+
+char const* TypeToString(int type)
+{
+ // clang-format off
+ switch (type) {
+ case e_CVS: return "CVS";
+ case e_SVN: return "SVN";
+ case e_BZR: return "BZR";
+ case e_GIT: return "GIT";
+ case e_HG: return "HG";
+ case e_P4: return "P4";
+ default: return "Unknown";
}
- std::string source_dir =
- this->CTest->GetCTestConfiguration("SourceDirectory");
+ // clang-format on
+}
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "UpdateCommand", "CTEST_UPDATE_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "UpdateOptions", "CTEST_UPDATE_OPTIONS", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "CVSCommand", "CTEST_CVS_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "CVSUpdateOptions", "CTEST_CVS_UPDATE_OPTIONS",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "SVNCommand", "CTEST_SVN_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "SVNOptions", "CTEST_SVN_OPTIONS", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "BZRCommand", "CTEST_BZR_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "GITCommand", "CTEST_GIT_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "GITInitSubmodules", "CTEST_GIT_INIT_SUBMODULES",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "UpdateVersionOnly", "CTEST_UPDATE_VERSION_ONLY",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "UpdateVersionOverride", "CTEST_UPDATE_VERSION_OVERRIDE",
- this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "HGCommand", "CTEST_HG_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "P4Command", "CTEST_P4_COMMAND", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "P4UpdateOptions", "CTEST_P4_UPDATE_OPTIONS", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "P4Client", "CTEST_P4_CLIENT", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "P4Options", "CTEST_P4_OPTIONS", this->Quiet);
+char const* TypeToCommandKey(int type)
+{
+ // clang-format off
+ switch (type) {
+ case e_CVS: return "CTEST_CVS_COMMAND";
+ case e_SVN: return "CTEST_SVN_COMMAND";
+ case e_BZR: return "CTEST_BZR_COMMAND";
+ case e_GIT: return "CTEST_GIT_COMMAND";
+ case e_HG: return "CTEST_HG_COMMAND";
+ case e_P4: return "CTEST_P4_COMMAND";
+ default: return nullptr;
+ }
+ // clang-format on
+}
- cmCTestUpdateHandler* handler = this->CTest->GetUpdateHandler();
- handler->Initialize();
+int DetermineType(std::string const& cmd)
+{
+ std::string stype = cmSystemTools::LowerCase(cmd);
+ if (stype.find("cvs") != std::string::npos) {
+ return e_CVS;
+ }
+ if (stype.find("svn") != std::string::npos) {
+ return e_SVN;
+ }
+ if (stype.find("bzr") != std::string::npos) {
+ return e_BZR;
+ }
+ if (stype.find("git") != std::string::npos) {
+ return e_GIT;
+ }
+ if (stype.find("hg") != std::string::npos) {
+ return e_HG;
+ }
+ if (stype.find("p4") != std::string::npos) {
+ return e_P4;
+ }
+ return e_UNKNOWN;
+}
+
+int DetectVCS(std::string const& dir)
+{
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/CVS"))) {
+ return e_CVS;
+ }
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/.svn"))) {
+ return e_SVN;
+ }
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/.bzr"))) {
+ return e_BZR;
+ }
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/.git"))) {
+ return e_GIT;
+ }
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/.hg"))) {
+ return e_HG;
+ }
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/.p4"))) {
+ return e_P4;
+ }
+ if (cmSystemTools::FileExists(cmStrCat(dir, "/.p4config"))) {
+ return e_P4;
+ }
+ return e_UNKNOWN;
+}
+
+std::unique_ptr<cmCTestVC> MakeVC(int type, cmCTest* ctest, cmMakefile* mf,
+ std::ostream& os)
+{
+ // clang-format off
+ switch (type) {
+ case e_CVS: return cm::make_unique<cmCTestCVS>(ctest, mf, os);
+ case e_SVN: return cm::make_unique<cmCTestSVN>(ctest, mf, os);
+ case e_BZR: return cm::make_unique<cmCTestBZR>(ctest, mf, os);
+ case e_GIT: return cm::make_unique<cmCTestGIT>(ctest, mf, os);
+ case e_HG: return cm::make_unique<cmCTestHG> (ctest, mf, os);
+ case e_P4: return cm::make_unique<cmCTestP4> (ctest, mf, os);
+ default: return cm::make_unique<cmCTestVC> (ctest, mf, os);
+ }
+ // clang-format on
+}
+
+} // namespace
+
+bool cmCTestUpdateCommand::ExecuteUpdate(UpdateArguments& args,
+ cmExecutionStatus& status) const
+{
+ cmMakefile& mf = status.GetMakefile();
+
+ std::string const& source_dir = !args.Source.empty()
+ ? args.Source
+ : mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
if (source_dir.empty()) {
- this->SetError("source directory not specified. Please use SOURCE tag");
- return nullptr;
+ status.SetError("called with no source directory specified. "
+ "Use SOURCE argument or set CTEST_SOURCE_DIRECTORY.");
+ return false;
}
- handler->SetOption("SourceDirectory", source_dir);
- handler->SetQuiet(this->Quiet);
- return handler;
+
+ std::string const currentTag = this->CTest->GetCurrentTag();
+ if (currentTag.empty()) {
+ status.SetError("called with no current tag.");
+ return false;
+ }
+
+ // Detect the VCS managing the source tree.
+ int updateType = DetectVCS(source_dir);
+
+ // Get update command
+ std::string updateCommand = mf.GetSafeDefinition("CTEST_UPDATE_COMMAND");
+
+ if (updateType == e_UNKNOWN && !updateCommand.empty()) {
+ updateType = DetermineType(updateCommand);
+ }
+ if (updateType == e_UNKNOWN) {
+ updateType = DetermineType(mf.GetSafeDefinition("CTEST_UPDATE_TYPE"));
+ }
+
+ // If no update command was specified, lookup one for this VCS tool.
+ if (updateCommand.empty()) {
+ const char* key = TypeToCommandKey(updateType);
+ if (key) {
+ updateCommand = mf.GetSafeDefinition(key);
+ }
+
+ if (updateCommand.empty()) {
+ std::ostringstream e;
+ e << "called with no update command specified. "
+ "Please set CTEST_UPDATE_COMMAND";
+ if (key) {
+ e << " or " << key;
+ }
+ e << '.';
+ status.SetError(e.str());
+ return false;
+ }
+ }
+
+ cmGeneratedFileStream ofs;
+ if (!this->CTest->GetShowOnly()) {
+ std::string logFile = cmStrCat("LastUpdate_", currentTag, ".log");
+ if (!this->CTest->OpenOutputFile("Temporary", logFile, ofs)) {
+ status.SetError(cmStrCat("cannot create log file: ", logFile));
+ return false;
+ }
+ }
+
+ cmGeneratedFileStream os;
+ if (!this->CTest->OpenOutputFile(currentTag, "Update.xml", os, true)) {
+ status.SetError("cannot create resulting XML file: Update.xml");
+ return false;
+ }
+
+ this->CTest->AddSubmitFile(cmCTest::PartUpdate, "Update.xml");
+
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Updating " << TypeToString(updateType)
+ << " repository: " << source_dir << '\n',
+ args.Quiet);
+
+ // Make sure VCS tool messages are in English so we can parse them.
+ cmCLocaleEnvironmentScope fixLocale;
+ static_cast<void>(fixLocale);
+
+ // Create an object to interact with the VCS tool.
+ std::unique_ptr<cmCTestVC> vc = MakeVC(updateType, this->CTest, &mf, ofs);
+
+ vc->SetCommandLineTool(updateCommand);
+ vc->SetSourceDirectory(source_dir);
+
+ // Cleanup the working tree.
+ vc->Cleanup();
+
+ std::string start_time = this->CTest->CurrentTime();
+ auto start_time_time = std::chrono::system_clock::now();
+ auto elapsed_time_start = std::chrono::steady_clock::now();
+
+ bool updated = vc->Update();
+ std::string buildname =
+ cmCTest::SafeBuildIdField(mf.GetSafeDefinition("CTEST_BUILD_NAME"));
+
+ cmXMLWriter xml(os);
+ xml.StartDocument();
+ xml.StartElement("Update");
+ xml.Attribute("mode", "Client");
+ xml.Attribute("Generator",
+ std::string("ctest-") + cmVersion::GetCMakeVersion());
+ xml.Element("Site", mf.GetSafeDefinition("CTEST_SITE"));
+ xml.Element("BuildName", buildname);
+ xml.Element("BuildStamp",
+ this->CTest->GetCurrentTag() + "-" +
+ this->CTest->GetTestGroupString());
+ xml.Element("StartDateTime", start_time);
+ xml.Element("StartTime", start_time_time);
+ xml.Element("UpdateCommand", vc->GetUpdateCommandLine());
+ xml.Element("UpdateType", TypeToString(updateType));
+
+ std::string changeId = mf.GetSafeDefinition("CTEST_CHANGE_ID");
+ if (!changeId.empty()) {
+ xml.Element("ChangeId", changeId);
+ }
+
+ bool loadedMods = vc->WriteXML(xml);
+
+ int localModifications = 0;
+ int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
+ if (numUpdated) {
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numUpdated << " updated files\n",
+ args.Quiet);
+ }
+ if (int numModified = vc->GetPathCount(cmCTestVC::PathModified)) {
+ cmCTestOptionalLog(
+ this->CTest, HANDLER_OUTPUT,
+ " Found " << numModified << " locally modified files\n", args.Quiet);
+ localModifications += numModified;
+ }
+ if (int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting)) {
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numConflicting << " conflicting files\n",
+ args.Quiet);
+ localModifications += numConflicting;
+ }
+
+ cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, args.Quiet);
+ std::string end_time = this->CTest->CurrentTime();
+ xml.Element("EndDateTime", end_time);
+ xml.Element("EndTime", std::chrono::system_clock::now());
+ xml.Element("ElapsedMinutes",
+ std::chrono::duration_cast<std::chrono::minutes>(
+ std::chrono::steady_clock::now() - elapsed_time_start)
+ .count());
+
+ xml.StartElement("UpdateReturnStatus");
+ if (localModifications) {
+ xml.Content("Update error: "
+ "There are modified or conflicting files in the repository");
+ cmCTestLog(this->CTest, WARNING,
+ " There are modified or conflicting files in the repository"
+ << std::endl);
+ }
+ if (!updated) {
+ xml.Content("Update command failed:\n");
+ xml.Content(vc->GetUpdateCommandLine());
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Update command failed: " << vc->GetUpdateCommandLine()
+ << "\n");
+ }
+ xml.EndElement(); // UpdateReturnStatus
+ xml.EndElement(); // Update
+ xml.EndDocument();
+
+ if (!args.ReturnValue.empty()) {
+ mf.AddDefinition(args.ReturnValue,
+ std::to_string(updated && loadedMods ? numUpdated : -1));
+ }
+
+ return true;
+}
+
+bool cmCTestUpdateCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ static auto const parser =
+ cmArgumentParser<UpdateArguments>{ MakeBasicParser<UpdateArguments>() }
+ .Bind("SOURCE"_s, &UpdateArguments::Source)
+ .Bind("RETURN_VALUE"_s, &UpdateArguments::ReturnValue)
+ .Bind("QUIET"_s, &UpdateArguments::Quiet);
+
+ return this->Invoke(parser, args, status, [&](UpdateArguments& a) {
+ return this->ExecuteUpdate(a, status);
+ });
}
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index e4c3453..7c58beb 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -5,39 +5,30 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <utility>
-
-#include <cm/memory>
+#include <vector>
#include "cmCTestHandlerCommand.h"
-#include "cmCommand.h"
-class cmCTestGenericHandler;
+class cmExecutionStatus;
-/** \class cmCTestUpdate
- * \brief Run a ctest script
- *
- * cmCTestUpdateCommand defineds the command to updates the repository.
- */
class cmCTestUpdateCommand : public cmCTestHandlerCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestUpdateCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_update"; }
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- cmCTestGenericHandler* InitializeHandler() override;
+ struct UpdateArguments : BasicArguments
+ {
+ std::string Source;
+ std::string ReturnValue;
+ bool Quiet = false;
+ };
+
+private:
+ std::string GetName() const override { return "ctest_update"; }
+
+ bool ExecuteUpdate(UpdateArguments& args, cmExecutionStatus& status) const;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
deleted file mode 100644
index 045eb84..0000000
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ /dev/null
@@ -1,354 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCTestUpdateHandler.h"
-
-#include <chrono>
-#include <sstream>
-
-#include <cm/memory>
-
-#include "cmCLocaleEnvironmentScope.h"
-#include "cmCTest.h"
-#include "cmCTestBZR.h"
-#include "cmCTestCVS.h"
-#include "cmCTestGIT.h"
-#include "cmCTestHG.h"
-#include "cmCTestP4.h"
-#include "cmCTestSVN.h"
-#include "cmCTestVC.h"
-#include "cmGeneratedFileStream.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmValue.h"
-#include "cmVersion.h"
-#include "cmXMLWriter.h"
-
-static const char* cmCTestUpdateHandlerUpdateStrings[] = {
- "Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4"
-};
-
-static const char* cmCTestUpdateHandlerUpdateToString(int type)
-{
- if (type < cmCTestUpdateHandler::e_UNKNOWN ||
- type >= cmCTestUpdateHandler::e_LAST) {
- return cmCTestUpdateHandlerUpdateStrings[cmCTestUpdateHandler::e_UNKNOWN];
- }
- return cmCTestUpdateHandlerUpdateStrings[type];
-}
-
-cmCTestUpdateHandler::cmCTestUpdateHandler() = default;
-
-void cmCTestUpdateHandler::Initialize()
-{
- this->Superclass::Initialize();
- this->UpdateCommand.clear();
- this->UpdateType = e_CVS;
-}
-
-int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
-{
- cmCTestOptionalLog(this->CTest, DEBUG,
- "Determine update type from command: "
- << cmd << " and type: " << type << std::endl,
- this->Quiet);
- if (type && *type) {
- cmCTestOptionalLog(this->CTest, DEBUG,
- "Type specified: " << type << std::endl, this->Quiet);
- std::string stype = cmSystemTools::LowerCase(type);
- if (stype.find("cvs") != std::string::npos) {
- return cmCTestUpdateHandler::e_CVS;
- }
- if (stype.find("svn") != std::string::npos) {
- return cmCTestUpdateHandler::e_SVN;
- }
- if (stype.find("bzr") != std::string::npos) {
- return cmCTestUpdateHandler::e_BZR;
- }
- if (stype.find("git") != std::string::npos) {
- return cmCTestUpdateHandler::e_GIT;
- }
- if (stype.find("hg") != std::string::npos) {
- return cmCTestUpdateHandler::e_HG;
- }
- if (stype.find("p4") != std::string::npos) {
- return cmCTestUpdateHandler::e_P4;
- }
- } else {
- cmCTestOptionalLog(
- this->CTest, DEBUG,
- "Type not specified, check command: " << cmd << std::endl, this->Quiet);
- std::string stype = cmSystemTools::LowerCase(cmd);
- if (stype.find("cvs") != std::string::npos) {
- return cmCTestUpdateHandler::e_CVS;
- }
- if (stype.find("svn") != std::string::npos) {
- return cmCTestUpdateHandler::e_SVN;
- }
- if (stype.find("bzr") != std::string::npos) {
- return cmCTestUpdateHandler::e_BZR;
- }
- if (stype.find("git") != std::string::npos) {
- return cmCTestUpdateHandler::e_GIT;
- }
- if (stype.find("hg") != std::string::npos) {
- return cmCTestUpdateHandler::e_HG;
- }
- if (stype.find("p4") != std::string::npos) {
- return cmCTestUpdateHandler::e_P4;
- }
- }
- return cmCTestUpdateHandler::e_UNKNOWN;
-}
-
-// clearly it would be nice if this were broken up into a few smaller
-// functions and commented...
-int cmCTestUpdateHandler::ProcessHandler()
-{
- // Make sure VCS tool messages are in English so we can parse them.
- cmCLocaleEnvironmentScope fixLocale;
- static_cast<void>(fixLocale);
-
- // Get source dir
- cmValue sourceDirectory = this->GetOption("SourceDirectory");
- if (!sourceDirectory) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Cannot find SourceDirectory key in the DartConfiguration.tcl"
- << std::endl);
- return -1;
- }
-
- cmGeneratedFileStream ofs;
- if (!this->CTest->GetShowOnly()) {
- this->StartLogFile("Update", ofs);
- }
-
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Updating the repository: " << *sourceDirectory
- << std::endl,
- this->Quiet);
-
- if (!this->SelectVCS()) {
- return -1;
- }
-
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Use "
- << cmCTestUpdateHandlerUpdateToString(this->UpdateType)
- << " repository type" << std::endl;
- , this->Quiet);
-
- // Create an object to interact with the VCS tool.
- std::unique_ptr<cmCTestVC> vc;
- switch (this->UpdateType) {
- case e_CVS:
- vc = cm::make_unique<cmCTestCVS>(this->CTest, ofs);
- break;
- case e_SVN:
- vc = cm::make_unique<cmCTestSVN>(this->CTest, ofs);
- break;
- case e_BZR:
- vc = cm::make_unique<cmCTestBZR>(this->CTest, ofs);
- break;
- case e_GIT:
- vc = cm::make_unique<cmCTestGIT>(this->CTest, ofs);
- break;
- case e_HG:
- vc = cm::make_unique<cmCTestHG>(this->CTest, ofs);
- break;
- case e_P4:
- vc = cm::make_unique<cmCTestP4>(this->CTest, ofs);
- break;
- default:
- vc = cm::make_unique<cmCTestVC>(this->CTest, ofs);
- break;
- }
- vc->SetCommandLineTool(this->UpdateCommand);
- vc->SetSourceDirectory(*sourceDirectory);
-
- // Cleanup the working tree.
- vc->Cleanup();
-
- //
- // Now update repository and remember what files were updated
- //
- cmGeneratedFileStream os;
- if (!this->StartResultingXML(cmCTest::PartUpdate, "Update", os)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Cannot open log file" << std::endl);
- return -1;
- }
- std::string start_time = this->CTest->CurrentTime();
- auto start_time_time = std::chrono::system_clock::now();
- auto elapsed_time_start = std::chrono::steady_clock::now();
-
- bool updated = vc->Update();
- std::string buildname =
- cmCTest::SafeBuildIdField(this->CTest->GetCTestConfiguration("BuildName"));
-
- cmXMLWriter xml(os);
- xml.StartDocument();
- xml.StartElement("Update");
- xml.Attribute("mode", "Client");
- xml.Attribute("Generator",
- std::string("ctest-") + cmVersion::GetCMakeVersion());
- xml.Element("Site", this->CTest->GetCTestConfiguration("Site"));
- xml.Element("BuildName", buildname);
- xml.Element("BuildStamp",
- this->CTest->GetCurrentTag() + "-" +
- this->CTest->GetTestModelString());
- xml.Element("StartDateTime", start_time);
- xml.Element("StartTime", start_time_time);
- xml.Element("UpdateCommand", vc->GetUpdateCommandLine());
- xml.Element("UpdateType",
- cmCTestUpdateHandlerUpdateToString(this->UpdateType));
- std::string changeId = this->CTest->GetCTestConfiguration("ChangeId");
- if (!changeId.empty()) {
- xml.Element("ChangeId", changeId);
- }
-
- bool loadedMods = vc->WriteXML(xml);
-
- int localModifications = 0;
- int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
- if (numUpdated) {
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Found " << numUpdated << " updated files\n",
- this->Quiet);
- }
- if (int numModified = vc->GetPathCount(cmCTestVC::PathModified)) {
- cmCTestOptionalLog(
- this->CTest, HANDLER_OUTPUT,
- " Found " << numModified << " locally modified files\n", this->Quiet);
- localModifications += numModified;
- }
- if (int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting)) {
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Found " << numConflicting << " conflicting files\n",
- this->Quiet);
- localModifications += numConflicting;
- }
-
- cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet);
- std::string end_time = this->CTest->CurrentTime();
- xml.Element("EndDateTime", end_time);
- xml.Element("EndTime", std::chrono::system_clock::now());
- xml.Element("ElapsedMinutes",
- std::chrono::duration_cast<std::chrono::minutes>(
- std::chrono::steady_clock::now() - elapsed_time_start)
- .count());
-
- xml.StartElement("UpdateReturnStatus");
- if (localModifications) {
- xml.Content("Update error: "
- "There are modified or conflicting files in the repository");
- cmCTestLog(this->CTest, WARNING,
- " There are modified or conflicting files in the repository"
- << std::endl);
- }
- if (!updated) {
- xml.Content("Update command failed:\n");
- xml.Content(vc->GetUpdateCommandLine());
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Update command failed: " << vc->GetUpdateCommandLine()
- << "\n");
- }
- xml.EndElement(); // UpdateReturnStatus
- xml.EndElement(); // Update
- xml.EndDocument();
- return updated && loadedMods ? numUpdated : -1;
-}
-
-int cmCTestUpdateHandler::DetectVCS(const std::string& dir)
-{
- std::string sourceDirectory = dir;
- cmCTestOptionalLog(this->CTest, DEBUG,
- "Check directory: " << sourceDirectory << std::endl,
- this->Quiet);
- sourceDirectory += "/.svn";
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_SVN;
- }
- sourceDirectory = cmStrCat(dir, "/CVS");
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_CVS;
- }
- sourceDirectory = cmStrCat(dir, "/.bzr");
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_BZR;
- }
- sourceDirectory = cmStrCat(dir, "/.git");
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_GIT;
- }
- sourceDirectory = cmStrCat(dir, "/.hg");
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_HG;
- }
- sourceDirectory = cmStrCat(dir, "/.p4");
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_P4;
- }
- sourceDirectory = cmStrCat(dir, "/.p4config");
- if (cmSystemTools::FileExists(sourceDirectory)) {
- return cmCTestUpdateHandler::e_P4;
- }
- return cmCTestUpdateHandler::e_UNKNOWN;
-}
-
-bool cmCTestUpdateHandler::SelectVCS()
-{
- // Get update command
- this->UpdateCommand = this->CTest->GetCTestConfiguration("UpdateCommand");
-
- // Detect the VCS managing the source tree.
- this->UpdateType = this->DetectVCS(this->GetOption("SourceDirectory"));
- if (this->UpdateType == e_UNKNOWN) {
- // The source tree does not have a recognized VCS. Check the
- // configuration value or command name.
- this->UpdateType = this->DetermineType(
- this->UpdateCommand.c_str(),
- this->CTest->GetCTestConfiguration("UpdateType").c_str());
- }
-
- // If no update command was specified, lookup one for this VCS tool.
- if (this->UpdateCommand.empty()) {
- const char* key = nullptr;
- switch (this->UpdateType) {
- case e_CVS:
- key = "CVSCommand";
- break;
- case e_SVN:
- key = "SVNCommand";
- break;
- case e_BZR:
- key = "BZRCommand";
- break;
- case e_GIT:
- key = "GITCommand";
- break;
- case e_HG:
- key = "HGCommand";
- break;
- case e_P4:
- key = "P4Command";
- break;
- default:
- break;
- }
- if (key) {
- this->UpdateCommand = this->CTest->GetCTestConfiguration(key);
- }
- if (this->UpdateCommand.empty()) {
- std::ostringstream e;
- e << "Cannot find UpdateCommand ";
- if (key) {
- e << "or " << key;
- }
- e << " configuration key.";
- cmCTestLog(this->CTest, ERROR_MESSAGE, e.str() << std::endl);
- return false;
- }
- }
-
- return true;
-}
diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h
deleted file mode 100644
index 70269ea..0000000
--- a/Source/CTest/cmCTestUpdateHandler.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "cmCTestGenericHandler.h"
-
-/** \class cmCTestUpdateHandler
- * \brief A class that handles ctest -S invocations
- *
- */
-class cmCTestUpdateHandler : public cmCTestGenericHandler
-{
-public:
- using Superclass = cmCTestGenericHandler;
-
- /*
- * The main entry point for this class
- */
- int ProcessHandler() override;
-
- cmCTestUpdateHandler();
-
- enum
- {
- e_UNKNOWN = 0,
- e_CVS,
- e_SVN,
- e_BZR,
- e_GIT,
- e_HG,
- e_P4,
- e_LAST
- };
-
- /**
- * Initialize handler
- */
- void Initialize() override;
-
-private:
- // Some structures needed for update
- struct StringPair : public std::pair<std::string, std::string>
- {
- };
- struct UpdateFiles : public std::vector<StringPair>
- {
- };
-
- // Determine the type of version control
- int DetermineType(const char* cmd, const char* type);
-
- // The VCS command to update the working tree.
- std::string UpdateCommand;
- int UpdateType;
-
- int DetectVCS(const std::string& dir);
- bool SelectVCS();
-};
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index 2ed671c..4ec4201 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -2,45 +2,98 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUploadCommand.h"
-#include <set>
+#include <algorithm>
+#include <chrono>
#include <sstream>
+#include <string>
#include <cm/vector>
#include <cmext/string_view>
+#include "cmArgumentParser.h"
#include "cmCTest.h"
-#include "cmCTestUploadHandler.h"
+#include "cmExecutionStatus.h"
+#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
+#include "cmVersion.h"
+#include "cmXMLWriter.h"
-void cmCTestUploadCommand::BindArguments()
+bool cmCTestUploadCommand::ExecuteUpload(UploadArguments& args,
+ cmExecutionStatus& status) const
{
- this->Bind("FILES"_s, this->Files);
- this->Bind("QUIET"_s, this->Quiet);
- this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
-}
+ cmMakefile& mf = status.GetMakefile();
-void cmCTestUploadCommand::CheckArguments()
-{
- cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
+ std::sort(args.Files.begin(), args.Files.end());
+ args.Files.erase(std::unique(args.Files.begin(), args.Files.end()),
+ args.Files.end());
+
+ cm::erase_if(args.Files, [&mf](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "
<< "a non-existent file.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
return true;
}
return false;
});
+
+ cmGeneratedFileStream ofs;
+ if (!this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(), "Upload.xml",
+ ofs)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open Upload.xml file" << std::endl);
+ return false;
+ }
+ std::string buildname =
+ cmCTest::SafeBuildIdField(mf.GetSafeDefinition("CTEST_BUILD_NAME"));
+
+ cmXMLWriter xml(ofs);
+ xml.StartDocument();
+ xml.ProcessingInstruction("xml-stylesheet",
+ "type=\"text/xsl\" "
+ "href=\"Dart/Source/Server/XSL/Build.xsl "
+ "<file:///Dart/Source/Server/XSL/Build.xsl> \"");
+ xml.StartElement("Site");
+ xml.Attribute("BuildName", buildname);
+ xml.Attribute("BuildStamp",
+ this->CTest->GetCurrentTag() + "-" +
+ this->CTest->GetTestGroupString());
+ xml.Attribute("Name", mf.GetSafeDefinition("CTEST_SITE"));
+ xml.Attribute("Generator",
+ std::string("ctest-") + cmVersion::GetCMakeVersion());
+ this->CTest->AddSiteProperties(xml, mf.GetCMakeInstance());
+ xml.StartElement("Upload");
+ xml.Element("Time", std::chrono::system_clock::now());
+
+ for (std::string const& file : args.Files) {
+ cmCTestOptionalLog(this->CTest, OUTPUT,
+ "\tUpload file: " << file << std::endl, args.Quiet);
+ xml.StartElement("File");
+ xml.Attribute("filename", file);
+ xml.StartElement("Content");
+ xml.Attribute("encoding", "base64");
+ xml.Content(this->CTest->Base64EncodeFile(file));
+ xml.EndElement(); // Content
+ xml.EndElement(); // File
+ }
+ xml.EndElement(); // Upload
+ xml.EndElement(); // Site
+ xml.EndDocument();
+ return true;
}
-cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
+bool cmCTestUploadCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
{
- cmCTestUploadHandler* handler = this->CTest->GetUploadHandler();
- handler->Initialize();
- handler->SetFiles(
- std::set<std::string>(this->Files.begin(), this->Files.end()));
- handler->SetQuiet(this->Quiet);
- return handler;
+ static auto const parser =
+ cmArgumentParser<UploadArguments>{ MakeBasicParser<UploadArguments>() }
+ .Bind("FILES"_s, &UploadArguments::Files)
+ .Bind("QUIET"_s, &UploadArguments::Quiet);
+
+ return this->Invoke(parser, args, status, [&](UploadArguments& a) {
+ return this->ExecuteUpload(a, status);
+ });
}
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index a9d1dd2..93fbc35 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -5,46 +5,30 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <utility>
#include <vector>
-#include <cm/memory>
-
#include "cmArgumentParserTypes.h"
#include "cmCTestHandlerCommand.h"
-#include "cmCommand.h"
-class cmCTestGenericHandler;
+class cmExecutionStatus;
-/** \class cmCTestUpload
- * \brief Run a ctest script
- *
- * cmCTestUploadCommand defines the command to upload result files for
- * the project.
- */
class cmCTestUploadCommand : public cmCTestHandlerCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto ni = cm::make_unique<cmCTestUploadCommand>();
- ni->CTest = this->CTest;
- ni->CTestScriptHandler = this->CTestScriptHandler;
- return std::unique_ptr<cmCommand>(std::move(ni));
- }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- std::string GetName() const override { return "ctest_upload"; }
+ using cmCTestHandlerCommand::cmCTestHandlerCommand;
protected:
- void BindArguments() override;
- void CheckArguments() override;
- cmCTestGenericHandler* InitializeHandler() override;
+ struct UploadArguments : BasicArguments
+ {
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Files;
+ bool Quiet = false;
+ };
- ArgumentParser::MaybeEmpty<std::vector<std::string>> Files;
+private:
+ std::string GetName() const override { return "ctest_upload"; }
+
+ bool ExecuteUpload(UploadArguments& args, cmExecutionStatus& status) const;
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) const override;
};
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
deleted file mode 100644
index 59e2b88..0000000
--- a/Source/CTest/cmCTestUploadHandler.cxx
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCTestUploadHandler.h"
-
-#include <chrono>
-#include <ostream>
-#include <string>
-
-#include "cmCTest.h"
-#include "cmGeneratedFileStream.h"
-#include "cmVersion.h"
-#include "cmXMLWriter.h"
-
-cmCTestUploadHandler::cmCTestUploadHandler()
-{
- this->Initialize();
-}
-
-void cmCTestUploadHandler::Initialize()
-{
- this->Superclass::Initialize();
- this->Files.clear();
-}
-
-void cmCTestUploadHandler::SetFiles(std::set<std::string> const& files)
-{
- this->Files = files;
-}
-
-int cmCTestUploadHandler::ProcessHandler()
-{
- cmGeneratedFileStream ofs;
- if (!this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(), "Upload.xml",
- ofs)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Cannot open Upload.xml file" << std::endl);
- return -1;
- }
- std::string buildname =
- cmCTest::SafeBuildIdField(this->CTest->GetCTestConfiguration("BuildName"));
-
- cmXMLWriter xml(ofs);
- xml.StartDocument();
- xml.ProcessingInstruction("xml-stylesheet",
- "type=\"text/xsl\" "
- "href=\"Dart/Source/Server/XSL/Build.xsl "
- "<file:///Dart/Source/Server/XSL/Build.xsl> \"");
- xml.StartElement("Site");
- xml.Attribute("BuildName", buildname);
- xml.Attribute("BuildStamp",
- this->CTest->GetCurrentTag() + "-" +
- this->CTest->GetTestModelString());
- xml.Attribute("Name", this->CTest->GetCTestConfiguration("Site"));
- xml.Attribute("Generator",
- std::string("ctest-") + cmVersion::GetCMakeVersion());
- this->CTest->AddSiteProperties(xml);
- xml.StartElement("Upload");
- xml.Element("Time", std::chrono::system_clock::now());
-
- for (std::string const& file : this->Files) {
- cmCTestOptionalLog(this->CTest, OUTPUT,
- "\tUpload file: " << file << std::endl, this->Quiet);
- xml.StartElement("File");
- xml.Attribute("filename", file);
- xml.StartElement("Content");
- xml.Attribute("encoding", "base64");
- xml.Content(this->CTest->Base64EncodeFile(file));
- xml.EndElement(); // Content
- xml.EndElement(); // File
- }
- xml.EndElement(); // Upload
- xml.EndElement(); // Site
- xml.EndDocument();
- return 0;
-}
diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h
deleted file mode 100644
index 55d21c1..0000000
--- a/Source/CTest/cmCTestUploadHandler.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <set>
-#include <string>
-
-#include "cmCTestGenericHandler.h"
-
-/** \class cmCTestUploadHandler
- * \brief Helper class for CTest
- *
- * Submit arbitrary files
- *
- */
-class cmCTestUploadHandler : public cmCTestGenericHandler
-{
-public:
- using Superclass = cmCTestGenericHandler;
-
- cmCTestUploadHandler();
-
- /*
- * The main entry point for this class
- */
- int ProcessHandler() override;
-
- void Initialize() override;
-
- /** Specify a set of files to submit. */
- void SetFiles(std::set<std::string> const& files);
-
-private:
- std::set<std::string> Files;
-};
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index cbbb5a5..315067e 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -8,13 +8,14 @@
#include <vector>
#include "cmCTest.h"
+#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
-#include "cmValue.h"
#include "cmXMLWriter.h"
-cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log)
+cmCTestVC::cmCTestVC(cmCTest* ct, cmMakefile* mf, std::ostream& log)
: CTest(ct)
+ , Makefile(mf)
, Log(log)
{
this->PathCount[PathUpdated] = 0;
@@ -113,7 +114,7 @@
{
// Get the nightly start time corresponding to the current dau.
struct tm* t = this->CTest->GetNightlyTime(
- this->CTest->GetCTestConfiguration("NightlyStartTime"),
+ this->Makefile->GetSafeDefinition("CTEST_NIGHTLY_START_TIME"),
this->CTest->GetTomorrowTag());
char current_time[1024];
snprintf(current_time, sizeof(current_time), "%04d-%02d-%02d %02d:%02d:%02d",
@@ -140,7 +141,7 @@
// Use the explicitly specified version.
std::string versionOverride =
- this->CTest->GetCTestConfiguration("UpdateVersionOverride");
+ this->Makefile->GetSafeDefinition("CTEST_UPDATE_VERSION_OVERRIDE");
if (!versionOverride.empty()) {
this->SetNewRevision(versionOverride);
return true;
@@ -148,7 +149,7 @@
// if update version only is on then do not actually update,
// just note the current version and finish
- if (!cmIsOn(this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) {
+ if (!this->Makefile->IsOn("CTEST_UPDATE_VERSION_ONLY")) {
result = this->NoteOldRevision() && result;
this->Log << "--- Begin Update ---\n";
result = this->UpdateImpl() && result;
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index dd5456d..03b63de 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -13,6 +13,7 @@
class cmCTest;
class cmXMLWriter;
+class cmMakefile;
/** \class cmCTestVC
* \brief Base class for version control system handlers
@@ -22,7 +23,7 @@
{
public:
/** Construct with a CTest instance and update log stream. */
- cmCTestVC(cmCTest* ctest, std::ostream& log);
+ cmCTestVC(cmCTest* ctest, cmMakefile* mf, std::ostream& log);
virtual ~cmCTestVC();
@@ -128,6 +129,7 @@
// Instance of cmCTest running the script.
cmCTest* CTest;
+ cmMakefile* Makefile;
// A stream to which we write log information.
std::ostream& Log;
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 2c809b6..7a89ffb 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -106,6 +106,11 @@
options.stdio_count = 3; // in, out and err
options.exit_cb = &cmProcess::OnExitCB;
options.stdio = stdio;
+#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
+ if (!this->Runner->GetCTest()->GetInteractiveDebugMode()) {
+ options.flags = UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
+ }
+#endif
#if !defined(CMAKE_USE_SYSTEM_LIBUV)
std::vector<char> cpumask;
if (affinity && !affinity->empty()) {
diff --git a/Source/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt
index bd7c415..1f04bd2 100644
--- a/Source/Checks/Curses/CMakeLists.txt
+++ b/Source/Checks/Curses/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR)
project(CheckCurses C)
set(CURSES_NEED_NCURSES TRUE)
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index bc21cd0..8f7e515 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -101,7 +101,7 @@
}
}
- std::string cacheDir = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cacheDir = cmSystemTools::GetLogicalWorkingDirectory();
for (i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
if (cmHasPrefix(arg, "-B")) {
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 21ed8c8..c3adae1 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -172,8 +172,8 @@
}
}
- sourceDirectory = cmSystemTools::CollapseFullPath(path.toStdString());
- cmSystemTools::ConvertToUnixSlashes(sourceDirectory);
+ sourceDirectory =
+ cmSystemTools::ToNormalizedPathOnDisk(path.toStdString());
} else if (arg.startsWith("-B")) {
QString path = arg.mid(2);
if (path.isEmpty()) {
@@ -189,8 +189,8 @@
}
}
- binaryDirectory = cmSystemTools::CollapseFullPath(path.toStdString());
- cmSystemTools::ConvertToUnixSlashes(binaryDirectory);
+ binaryDirectory =
+ cmSystemTools::ToNormalizedPathOnDisk(path.toStdString());
} else if (arg.startsWith("--preset=")) {
QString preset = arg.mid(cmStrLen("--preset="));
if (preset.isEmpty()) {
@@ -223,7 +223,7 @@
} else {
if (args.count() == 2) {
std::string filePath =
- cmSystemTools::CollapseFullPath(args[1].toStdString());
+ cmSystemTools::ToNormalizedPathOnDisk(args[1].toStdString());
// check if argument is a directory containing CMakeCache.txt
std::string buildFilePath = cmStrCat(filePath, "/CMakeCache.txt");
@@ -243,7 +243,7 @@
} else if (cmSystemTools::FileExists(srcFilePath.c_str())) {
dialog.setSourceDirectory(QString::fromStdString(filePath));
dialog.setBinaryDirectory(
- QString::fromStdString(cmSystemTools::CollapseFullPath(".")));
+ QString::fromStdString(cmSystemTools::GetLogicalWorkingDirectory()));
}
}
}
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 45c4717..7c94ea2 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -258,9 +258,7 @@
#endif
// Apply the same transformations that the command-line invocation does
auto sanitizePath = [](QString const& value) -> std::string {
- std::string path = cmSystemTools::CollapseFullPath(value.toStdString());
- cmSystemTools::ConvertToUnixSlashes(path);
- return path;
+ return cmSystemTools::ToNormalizedPathOnDisk(value.toStdString());
};
this->CMakeInstance->SetHomeDirectory(sanitizePath(this->SourceDirectory));
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index e67e0c2..94dfa3e 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -189,7 +189,7 @@
static uint qHash(const QCMakeProperty& p)
{
- return static_cast<uint>(qHash(p.Key));
+ return qHash(p.Key);
}
void QCMakeCacheModel::setShowNewProperties(bool f)
@@ -242,7 +242,7 @@
bool b = this->blockSignals(true);
this->clear();
- this->NewPropertyCount = static_cast<int>(newProps.size());
+ this->NewPropertyCount = newProps.size();
if (View == FlatView) {
QCMakePropertyList newP = newProps.values();
diff --git a/Source/QtDialog/QCMakePresetItemModel.cxx b/Source/QtDialog/QCMakePresetItemModel.cxx
index 31a6000..cb96b6b 100644
--- a/Source/QtDialog/QCMakePresetItemModel.cxx
+++ b/Source/QtDialog/QCMakePresetItemModel.cxx
@@ -83,7 +83,7 @@
if (this->m_presets.empty()) {
return 1;
}
- return static_cast<int>(this->m_presets.size() + 2);
+ return this->m_presets.size() + 2;
}
int QCMakePresetItemModel::columnCount(const QModelIndex& parent) const
@@ -144,5 +144,5 @@
index++;
}
- return static_cast<int>(this->m_presets.size() + 1);
+ return this->m_presets.size() + 1;
}
diff --git a/Source/QtDialog/QtDialogCPack.cmake.in b/Source/QtDialog/QtDialogCPack.cmake.in
index 7ae8605..a94ebe0 100644
--- a/Source/QtDialog/QtDialogCPack.cmake.in
+++ b/Source/QtDialog/QtDialogCPack.cmake.in
@@ -11,5 +11,3 @@
set(CPACK_SET_DESTDIR TRUE)
endif()
endif()
-
-
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 7311de8..10e7a26 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -611,8 +611,6 @@
case cmPolicies::OLD:
issueMessage = false;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
messageType = MessageType::FATAL_ERROR;
break;
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 9113dfd..e2a52d1 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -242,8 +242,6 @@
type = cmStateEnums::STATIC_LIBRARY;
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
mf.IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx
index 95db689..d9bc926 100644
--- a/Source/cmBreakCommand.cxx
+++ b/Source/cmBreakCommand.cxx
@@ -24,8 +24,6 @@
case cmPolicies::OLD:
issueMessage = false;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
messageType = MessageType::FATAL_ERROR;
break;
@@ -54,8 +52,6 @@
case cmPolicies::OLD:
issueMessage = false;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
messageType = MessageType::FATAL_ERROR;
break;
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index e4160a1..0366030 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -604,14 +604,14 @@
(arguments.ValueNames || arguments.SubKeys)) ||
(arguments.ValueName.empty() && arguments.ValueNames &&
arguments.SubKeys)) {
- status.SetError("given mutually exclusive sub-options \"VALUE\", "
- "\"VALUE_NAMES\" or \"SUBKEYS\".");
+ status.SetError("given mutually exclusive sub-options VALUE, "
+ "VALUE_NAMES or SUBKEYS.");
return false;
}
if (!arguments.View.empty() && !cmWindowsRegistry::ToView(arguments.View)) {
status.SetError(
- cmStrCat("given invalid value for \"VIEW\": ", arguments.View, '.'));
+ cmStrCat("given invalid value for VIEW: ", arguments.View, '.'));
return false;
}
diff --git a/Source/cmCMakePath.h b/Source/cmCMakePath.h
index fd71c1f..52fd6aa 100644
--- a/Source/cmCMakePath.h
+++ b/Source/cmCMakePath.h
@@ -617,19 +617,18 @@
// Non-members
// ===========
- friend inline bool operator==(const cmCMakePath& lhs,
- const cmCMakePath& rhs) noexcept
+ friend bool operator==(const cmCMakePath& lhs,
+ const cmCMakePath& rhs) noexcept
{
return lhs.Compare(rhs) == 0;
}
- friend inline bool operator!=(const cmCMakePath& lhs,
- const cmCMakePath& rhs) noexcept
+ friend bool operator!=(const cmCMakePath& lhs,
+ const cmCMakePath& rhs) noexcept
{
return lhs.Compare(rhs) != 0;
}
- friend inline cmCMakePath operator/(const cmCMakePath& lhs,
- const cmCMakePath& rhs)
+ friend cmCMakePath operator/(const cmCMakePath& lhs, const cmCMakePath& rhs)
{
cmCMakePath result(lhs);
result /= rhs;
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index ebf639b..9035254 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -4,7 +4,6 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -147,19 +146,6 @@
// Report that the policy is set to NEW.
status.GetMakefile().AddDefinition(var, "NEW");
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- // The policy is required to be set before anything needs it.
- {
- status.GetMakefile().IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(
- cmPolicies::GetRequiredPolicyError(pid), "\n",
- "The call to cmake_policy(GET ", id,
- " ...) at which this "
- "error appears requests the policy, and this version of CMake ",
- "requires that the policy be set to NEW before it is checked."));
- }
}
return true;
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 2e6cd40..6f101cb 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -168,7 +168,7 @@
static int CCONV cmCommandExists(void* arg, const char* name)
{
cmMakefile* mf = static_cast<cmMakefile*>(arg);
- return static_cast<int>(mf->GetState()->GetCommand(name) ? 1 : 0);
+ return mf->GetState()->GetCommand(name) ? 1 : 0;
}
static void CCONV cmAddDefineFlag(void* arg, const char* definition)
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 829fbf9..0793a86 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -10,6 +10,7 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
+#include <initializer_list>
#include <iostream>
#include <map>
#include <ratio>
@@ -31,7 +32,6 @@
#include "cmsys/Base64.h"
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/SystemInformation.hxx"
#if defined(_WIN32)
@@ -41,23 +41,18 @@
#endif
#include "cmCMakePresetsGraph.h"
-#include "cmCTestBuildAndTestHandler.h"
-#include "cmCTestBuildHandler.h"
-#include "cmCTestConfigureHandler.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmCTestGenericHandler.h"
-#include "cmCTestMemCheckHandler.h"
+#include "cmCTestBuildAndTest.h"
#include "cmCTestScriptHandler.h"
-#include "cmCTestStartCommand.h"
-#include "cmCTestSubmitHandler.h"
#include "cmCTestTestHandler.h"
-#include "cmCTestUpdateHandler.h"
-#include "cmCTestUploadHandler.h"
+#include "cmCTestTypes.h"
+#include "cmCommandLineArgument.h"
#include "cmDynamicLoader.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
#include "cmList.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmState.h"
@@ -71,6 +66,7 @@
#include "cmValue.h"
#include "cmVersion.h"
#include "cmVersionConfig.h"
+#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -80,6 +76,11 @@
struct cmCTest::Private
{
+ Private(cmCTest* ctest)
+ : BuildAndTest(ctest)
+ {
+ }
+
/** Representation of one part. */
struct PartInfo
{
@@ -114,44 +115,8 @@
bool FlushTestProgressLine = false;
- bool ForceNewCTestProcess = false;
-
- bool RunConfigurationScript = false;
-
// these are helper classes
- cmCTestBuildHandler BuildHandler;
- cmCTestBuildAndTestHandler BuildAndTestHandler;
- cmCTestCoverageHandler CoverageHandler;
- cmCTestScriptHandler ScriptHandler;
- cmCTestTestHandler TestHandler;
- cmCTestUpdateHandler UpdateHandler;
- cmCTestConfigureHandler ConfigureHandler;
- cmCTestMemCheckHandler MemCheckHandler;
- cmCTestSubmitHandler SubmitHandler;
- cmCTestUploadHandler UploadHandler;
-
- std::vector<cmCTestGenericHandler*> GetTestingHandlers()
- {
- return { &this->BuildHandler, &this->BuildAndTestHandler,
- &this->CoverageHandler, &this->ScriptHandler,
- &this->TestHandler, &this->UpdateHandler,
- &this->ConfigureHandler, &this->MemCheckHandler,
- &this->SubmitHandler, &this->UploadHandler };
- }
-
- std::map<std::string, cmCTestGenericHandler*> GetNamedTestingHandlers()
- {
- return { { "build", &this->BuildHandler },
- { "buildtest", &this->BuildAndTestHandler },
- { "coverage", &this->CoverageHandler },
- { "script", &this->ScriptHandler },
- { "test", &this->TestHandler },
- { "update", &this->UpdateHandler },
- { "configure", &this->ConfigureHandler },
- { "memcheck", &this->MemCheckHandler },
- { "submit", &this->SubmitHandler },
- { "upload", &this->UploadHandler } };
- }
+ cmCTestBuildAndTest BuildAndTest;
bool ShowOnly = false;
bool OutputAsJson = false;
@@ -177,6 +142,10 @@
cmDuration GlobalTimeout = cmDuration::zero();
+ std::chrono::steady_clock::time_point StartTime =
+ std::chrono::steady_clock::now();
+ cmDuration TimeLimit = cmCTest::MaxDuration();
+
int MaxTestNameWidth = 30;
cm::optional<size_t> ParallelLevel = 1;
@@ -199,14 +168,9 @@
bool CompressXMLFiles = false;
bool CompressTestOutput = true;
- // By default we write output to the process output streams.
- std::ostream* StreamOut = &std::cout;
- std::ostream* StreamErr = &std::cerr;
-
bool SuppressUpdatingCTestConfiguration = false;
bool Debug = false;
- bool ShowLineNumbers = false;
bool Quiet = false;
std::string BuildID;
@@ -216,7 +180,7 @@
int SubmitIndex = 0;
std::unique_ptr<cmGeneratedFileStream> OutputLogFile;
- int OutputLogFileLastTag = -1;
+ cm::optional<cmCTest::LogType> OutputLogFileLastTag;
bool OutputTestOutputOnTestFailure = false;
bool OutputColorCode = cmCTest::ColoredOutputSupportedByConsole();
@@ -225,6 +189,9 @@
cmCTest::NoTests NoTestsMode = cmCTest::NoTests::Legacy;
bool NoTestsModeSetInCli = false;
+
+ cmCTestTestOptions TestOptions;
+ std::vector<std::string> CommandLineHttpHeaders;
};
struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag)
@@ -340,7 +307,7 @@
}
cmCTest::cmCTest()
- : Impl(new Private)
+ : Impl(cm::make_unique<Private>(this))
{
std::string envValue;
if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) {
@@ -370,10 +337,6 @@
->PartMap[cmSystemTools::LowerCase(this->Impl->Parts[p].GetName())] = p;
}
- for (auto& handler : this->Impl->GetTestingHandlers()) {
- handler->SetCTestInstance(this);
- }
-
// Make sure we can capture the build tool output.
cmSystemTools::EnableVSConsoleOutput();
}
@@ -418,15 +381,13 @@
return PartCount;
}
-int cmCTest::Initialize(const std::string& binary_dir,
- cmCTestStartCommand* command)
+void cmCTest::Initialize(std::string const& binary_dir)
{
- bool quiet = false;
- if (command && command->ShouldBeQuiet()) {
- quiet = true;
+ this->Impl->BuildID = "";
+ for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) {
+ this->Impl->Parts[p].SubmitFiles.clear();
}
- cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
if (!this->Impl->InteractiveDebugMode) {
this->BlockTestErrorDiagnostics();
} else {
@@ -435,269 +396,122 @@
this->Impl->BinaryDir = binary_dir;
cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir);
-
- this->UpdateCTestConfiguration();
-
- cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
- if (this->Impl->ProduceXML) {
- cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
- cmCTestOptionalLog(this, OUTPUT,
- " Site: "
- << this->GetCTestConfiguration("Site") << std::endl
- << " Build name: "
- << cmCTest::SafeBuildIdField(
- this->GetCTestConfiguration("BuildName"))
- << std::endl,
- quiet);
- cmCTestOptionalLog(this, DEBUG, "Produce XML is on" << std::endl, quiet);
- if (this->Impl->TestModel == cmCTest::NIGHTLY &&
- this->GetCTestConfiguration("NightlyStartTime").empty()) {
- cmCTestOptionalLog(
- this, WARNING,
- "WARNING: No nightly start time found please set in CTestConfig.cmake"
- " or DartConfig.cmake"
- << std::endl,
- quiet);
- cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl,
- quiet);
- return 0;
- }
- }
-
- cmake cm(cmake::RoleScript, cmState::CTest);
- cm.SetHomeDirectory("");
- cm.SetHomeOutputDirectory("");
- cm.GetCurrentSnapshot().SetDefaultDefinitions();
- cmGlobalGenerator gg(&cm);
- cmMakefile mf(&gg, cm.GetCurrentSnapshot());
- if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf)) {
- cmCTestOptionalLog(
- this, DEBUG, "Cannot find custom configuration file tree" << std::endl,
- quiet);
- return 0;
- }
-
- if (this->Impl->ProduceXML) {
- // Verify "Testing" directory exists:
- //
- std::string testingDir = this->Impl->BinaryDir + "/Testing";
- if (cmSystemTools::FileExists(testingDir)) {
- if (!cmSystemTools::FileIsDirectory(testingDir)) {
- cmCTestLog(this, ERROR_MESSAGE,
- "File " << testingDir
- << " is in the place of the testing directory"
- << std::endl);
- return 0;
- }
- } else {
- if (!cmSystemTools::MakeDirectory(testingDir)) {
- cmCTestLog(this, ERROR_MESSAGE,
- "Cannot create directory " << testingDir << std::endl);
- return 0;
- }
- }
-
- // Create new "TAG" file or read existing one:
- //
- bool createNewTag = true;
- if (command) {
- createNewTag = command->ShouldCreateNewTag();
- }
-
- std::string tagfile = testingDir + "/TAG";
- cmsys::ifstream tfin(tagfile.c_str());
- std::string tag;
-
- if (createNewTag) {
- time_t tctime = time(nullptr);
- if (this->Impl->TomorrowTag) {
- tctime += (24 * 60 * 60);
- }
- struct tm* lctime = gmtime(&tctime);
- if (tfin && cmSystemTools::GetLineFromStream(tfin, tag)) {
- int year = 0;
- int mon = 0;
- int day = 0;
- int hour = 0;
- int min = 0;
- sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d", &year, &mon, &day, &hour,
- &min);
- if (year != lctime->tm_year + 1900 || mon != lctime->tm_mon + 1 ||
- day != lctime->tm_mday) {
- tag.clear();
- }
- std::string group;
- if (cmSystemTools::GetLineFromStream(tfin, group) &&
- !this->Impl->Parts[PartStart] && !command) {
- this->Impl->SpecificGroup = group;
- }
- std::string model;
- if (cmSystemTools::GetLineFromStream(tfin, model) &&
- !this->Impl->Parts[PartStart] && !command) {
- this->Impl->TestModel = GetTestModelFromString(model);
- }
- tfin.close();
- }
- if (tag.empty() || command || this->Impl->Parts[PartStart]) {
- cmCTestOptionalLog(
- this, DEBUG,
- "TestModel: " << this->GetTestModelString() << std::endl, quiet);
- cmCTestOptionalLog(this, DEBUG,
- "TestModel: " << this->Impl->TestModel << std::endl,
- quiet);
- if (this->Impl->TestModel == cmCTest::NIGHTLY) {
- lctime = this->GetNightlyTime(
- this->GetCTestConfiguration("NightlyStartTime"),
- this->Impl->TomorrowTag);
- }
- char datestring[100];
- snprintf(datestring, sizeof(datestring), "%04d%02d%02d-%02d%02d",
- lctime->tm_year + 1900, lctime->tm_mon + 1, lctime->tm_mday,
- lctime->tm_hour, lctime->tm_min);
- tag = datestring;
- cmsys::ofstream ofs(tagfile.c_str());
- if (ofs) {
- ofs << tag << std::endl;
- ofs << this->GetTestModelString() << std::endl;
- switch (this->Impl->TestModel) {
- case cmCTest::EXPERIMENTAL:
- ofs << "Experimental" << std::endl;
- break;
- case cmCTest::NIGHTLY:
- ofs << "Nightly" << std::endl;
- break;
- case cmCTest::CONTINUOUS:
- ofs << "Continuous" << std::endl;
- break;
- }
- }
- ofs.close();
- if (!command) {
- cmCTestOptionalLog(this, OUTPUT,
- "Create new tag: " << tag << " - "
- << this->GetTestModelString()
- << std::endl,
- quiet);
- }
- }
- } else {
- std::string group;
- std::string modelStr;
- int model = cmCTest::UNKNOWN;
-
- if (tfin) {
- cmSystemTools::GetLineFromStream(tfin, tag);
- cmSystemTools::GetLineFromStream(tfin, group);
- if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
- model = GetTestModelFromString(modelStr);
- }
- tfin.close();
- }
-
- if (tag.empty()) {
- cmCTestLog(this, ERROR_MESSAGE,
- "Cannot read existing TAG file in " << testingDir
- << std::endl);
- return 0;
- }
-
- if (this->Impl->TestModel == cmCTest::UNKNOWN) {
- if (model == cmCTest::UNKNOWN) {
- cmCTestLog(this, ERROR_MESSAGE,
- "TAG file does not contain model and "
- "no model specified in start command"
- << std::endl);
- return 0;
- }
-
- this->SetTestModel(model);
- }
-
- if (model != this->Impl->TestModel && model != cmCTest::UNKNOWN &&
- this->Impl->TestModel != cmCTest::UNKNOWN) {
- cmCTestOptionalLog(this, WARNING,
- "Model given in TAG does not match "
- "model given in ctest_start()"
- << std::endl,
- quiet);
- }
-
- if (!this->Impl->SpecificGroup.empty() &&
- group != this->Impl->SpecificGroup) {
- cmCTestOptionalLog(this, WARNING,
- "Group given in TAG does not match "
- "group given in ctest_start()"
- << std::endl,
- quiet);
- } else {
- this->Impl->SpecificGroup = group;
- }
-
- cmCTestOptionalLog(this, OUTPUT,
- " Use existing tag: " << tag << " - "
- << this->GetTestModelString()
- << std::endl,
- quiet);
- }
-
- this->Impl->CurrentTag = tag;
- }
-
- return 1;
}
-bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
+bool cmCTest::CreateNewTag(bool quiet)
{
- std::string src_dir = this->GetCTestConfiguration("SourceDirectory");
- std::string bld_dir = this->GetCTestConfiguration("BuildDirectory");
- this->Impl->BuildID = "";
- for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) {
- this->Impl->Parts[p].SubmitFiles.clear();
- }
+ std::string const testingDir = this->Impl->BinaryDir + "/Testing";
+ std::string const tagfile = testingDir + "/TAG";
- cmMakefile* mf = command->GetMakefile();
- std::string fname;
-
- std::string src_dir_fname = cmStrCat(src_dir, "/CTestConfig.cmake");
- cmSystemTools::ConvertToUnixSlashes(src_dir_fname);
-
- std::string bld_dir_fname = cmStrCat(bld_dir, "/CTestConfig.cmake");
- cmSystemTools::ConvertToUnixSlashes(bld_dir_fname);
-
- if (cmSystemTools::FileExists(bld_dir_fname)) {
- fname = bld_dir_fname;
- } else if (cmSystemTools::FileExists(src_dir_fname)) {
- fname = src_dir_fname;
- }
-
- if (!fname.empty()) {
- cmCTestOptionalLog(this, OUTPUT,
- " Reading ctest configuration file: " << fname
- << std::endl,
- command->ShouldBeQuiet());
- bool readit = mf->ReadDependentFile(fname);
- if (!readit) {
- std::string m = cmStrCat("Could not find include file: ", fname);
- command->SetError(m);
- return false;
- }
- }
-
- this->SetCTestConfigurationFromCMakeVariable(mf, "NightlyStartTime",
- "CTEST_NIGHTLY_START_TIME",
- command->ShouldBeQuiet());
- this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE",
- command->ShouldBeQuiet());
- this->SetCTestConfigurationFromCMakeVariable(
- mf, "BuildName", "CTEST_BUILD_NAME", command->ShouldBeQuiet());
-
- if (!this->Initialize(bld_dir, command)) {
+ auto const result = cmSystemTools::MakeDirectory(testingDir);
+ if (!result.IsSuccess()) {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Cannot create directory \""
+ << testingDir << "\": " << result.GetString() << std::endl);
return false;
}
+
+ cmCTestOptionalLog(this, DEBUG,
+ "TestModel: " << this->GetTestGroupString() << std::endl,
+ quiet);
+ cmCTestOptionalLog(
+ this, DEBUG, "TestModel: " << this->Impl->TestModel << std::endl, quiet);
+
+ struct tm* lctime = [this]() -> tm* {
+ if (this->Impl->TestModel == cmCTest::NIGHTLY) {
+ return this->GetNightlyTime(
+ this->GetCTestConfiguration("NightlyStartTime"),
+ this->Impl->TomorrowTag);
+ }
+ time_t tctime = time(nullptr);
+ if (this->Impl->TomorrowTag) {
+ tctime += (24 * 60 * 60);
+ }
+ return gmtime(&tctime);
+ }();
+
+ char datestring[100];
+ snprintf(datestring, sizeof(datestring), "%04d%02d%02d-%02d%02d",
+ lctime->tm_year + 1900, lctime->tm_mon + 1, lctime->tm_mday,
+ lctime->tm_hour, lctime->tm_min);
+ this->Impl->CurrentTag = datestring;
+
+ cmsys::ofstream ofs(tagfile.c_str());
+ ofs << this->Impl->CurrentTag << std::endl;
+ ofs << this->GetTestGroupString() << std::endl;
+ ofs << this->GetTestModelString() << std::endl;
+
+ return true;
+}
+
+bool cmCTest::ReadExistingTag(bool quiet)
+{
+ std::string const testingDir = this->Impl->BinaryDir + "/Testing";
+ std::string const tagfile = testingDir + "/TAG";
+
+ std::string tag;
+ std::string group;
+ std::string modelStr;
+ int model = cmCTest::UNKNOWN;
+
+ cmsys::ifstream tfin(tagfile.c_str());
+ if (tfin) {
+ cmSystemTools::GetLineFromStream(tfin, tag);
+ cmSystemTools::GetLineFromStream(tfin, group);
+ if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
+ model = GetTestModelFromString(modelStr);
+ }
+ tfin.close();
+ }
+
+ if (tag.empty()) {
+ if (!quiet) {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Cannot read existing TAG file in " << testingDir
+ << std::endl);
+ }
+ return false;
+ }
+
+ if (this->Impl->TestModel == cmCTest::UNKNOWN) {
+ if (model == cmCTest::UNKNOWN) {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "TAG file does not contain model and "
+ "no model specified in start command"
+ << std::endl);
+ return false;
+ }
+
+ this->SetTestModel(model);
+ }
+
+ if (model != this->Impl->TestModel && model != cmCTest::UNKNOWN &&
+ this->Impl->TestModel != cmCTest::UNKNOWN) {
+ cmCTestOptionalLog(this, WARNING,
+ "Model given in TAG does not match "
+ "model given in ctest_start()"
+ << std::endl,
+ quiet);
+ }
+
+ if (!this->Impl->SpecificGroup.empty() &&
+ group != this->Impl->SpecificGroup) {
+ cmCTestOptionalLog(this, WARNING,
+ "Group given in TAG does not match "
+ "group given in ctest_start()"
+ << std::endl,
+ quiet);
+ } else {
+ this->Impl->SpecificGroup = group;
+ }
+
cmCTestOptionalLog(this, OUTPUT,
- " Use " << this->GetTestModelString() << " tag: "
- << this->GetCurrentTag() << std::endl,
- command->ShouldBeQuiet());
+ " Use existing tag: " << tag << " - "
+ << this->GetTestGroupString()
+ << std::endl,
+ quiet);
+
+ this->Impl->CurrentTag = tag;
return true;
}
@@ -760,7 +574,7 @@
if (!this->GetCTestConfiguration("BuildDirectory").empty()) {
this->Impl->BinaryDir = this->GetCTestConfiguration("BuildDirectory");
if (this->Impl->TestDir.empty()) {
- cmSystemTools::ChangeDirectory(this->Impl->BinaryDir);
+ cmSystemTools::SetLogicalWorkingDirectory(this->Impl->BinaryDir);
}
}
this->Impl->TimeOut =
@@ -825,10 +639,6 @@
return false;
}
-void cmCTest::Finalize()
-{
-}
-
bool cmCTest::OpenOutputFile(const std::string& path, const std::string& name,
cmGeneratedFileStream& stream, bool compress)
{
@@ -889,166 +699,174 @@
return cmSystemTools::FileExists(testingDir);
}
-cmCTestBuildHandler* cmCTest::GetBuildHandler()
-{
- return &this->Impl->BuildHandler;
-}
-
-cmCTestBuildAndTestHandler* cmCTest::GetBuildAndTestHandler()
-{
- return &this->Impl->BuildAndTestHandler;
-}
-
-cmCTestCoverageHandler* cmCTest::GetCoverageHandler()
-{
- return &this->Impl->CoverageHandler;
-}
-
-cmCTestScriptHandler* cmCTest::GetScriptHandler()
-{
- return &this->Impl->ScriptHandler;
-}
-
-cmCTestTestHandler* cmCTest::GetTestHandler()
-{
- return &this->Impl->TestHandler;
-}
-
-cmCTestUpdateHandler* cmCTest::GetUpdateHandler()
-{
- return &this->Impl->UpdateHandler;
-}
-
-cmCTestConfigureHandler* cmCTest::GetConfigureHandler()
-{
- return &this->Impl->ConfigureHandler;
-}
-
-cmCTestMemCheckHandler* cmCTest::GetMemCheckHandler()
-{
- return &this->Impl->MemCheckHandler;
-}
-
-cmCTestSubmitHandler* cmCTest::GetSubmitHandler()
-{
- return &this->Impl->SubmitHandler;
-}
-
-cmCTestUploadHandler* cmCTest::GetUploadHandler()
-{
- return &this->Impl->UploadHandler;
-}
-
int cmCTest::ProcessSteps()
{
- int res = 0;
- bool notest = true;
- int update_count = 0;
+ this->Impl->ExtraVerbose = this->Impl->Verbose;
+ this->Impl->Verbose = true;
+ this->Impl->ProduceXML = true;
- for (Part p = PartStart; notest && p != PartCount;
- p = static_cast<Part>(p + 1)) {
- notest = !this->Impl->Parts[p];
+ const std::string currDir = cmSystemTools::GetLogicalWorkingDirectory();
+ std::string workDir = currDir;
+ if (!this->Impl->TestDir.empty()) {
+ workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir);
}
+
+ cmWorkingDirectory changeDir(workDir);
+ if (changeDir.Failed()) {
+ cmCTestLog(this, ERROR_MESSAGE, changeDir.GetError() << std::endl);
+ return 1;
+ }
+
+ this->Impl->BinaryDir = workDir;
+ cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir);
+ this->UpdateCTestConfiguration();
+ this->BlockTestErrorDiagnostics();
+
+ int res = 0;
+ cmCTestScriptHandler script(this);
+ script.CreateCMake();
+ cmMakefile& mf = *script.GetMakefile();
+ this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf);
+ this->SetTimeLimit(mf.GetDefinition("CTEST_TIME_LIMIT"));
+ this->SetCMakeVariables(mf);
+ std::vector<cmListFileArgument> args{
+ cmListFileArgument("RETURN_VALUE", cmListFileArgument::Unquoted, 0),
+ cmListFileArgument("return_value", cmListFileArgument::Unquoted, 0),
+ };
+
+ if (this->Impl->Parts[PartStart]) {
+ auto const func = cmListFileFunction(
+ "ctest_start", 0, 0,
+ {
+ { this->GetTestModelString(), cmListFileArgument::Unquoted, 0 },
+ { "GROUP", cmListFileArgument::Unquoted, 0 },
+ { this->GetTestGroupString(), cmListFileArgument::Unquoted, 0 },
+ });
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status)) {
+ return 12;
+ }
+ } else if (!this->ReadExistingTag(true) && !this->CreateNewTag(false)) {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Problem initializing the dashboard." << std::endl);
+ return 12;
+ }
+
if (this->Impl->Parts[PartUpdate] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
- cmCTestUpdateHandler* uphandler = this->GetUpdateHandler();
- uphandler->SetPersistentOption(
- "SourceDirectory", this->GetCTestConfiguration("SourceDirectory"));
- update_count = uphandler->ProcessHandler();
- if (update_count < 0) {
+ auto const func = cmListFileFunction("ctest_update", 0, 0, args);
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status)) {
res |= cmCTest::UPDATE_ERRORS;
}
}
- if (this->Impl->TestModel == cmCTest::CONTINUOUS && !update_count) {
+ if (this->Impl->TestModel == cmCTest::CONTINUOUS &&
+ mf.GetDefinition("return_value").IsOff()) {
return 0;
}
if (this->Impl->Parts[PartConfigure] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
- if (this->GetConfigureHandler()->ProcessHandler() < 0) {
+ auto const func = cmListFileFunction("ctest_configure", 0, 0, args);
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status) ||
+ std::stoi(mf.GetDefinition("return_value")) < 0) {
res |= cmCTest::CONFIGURE_ERRORS;
}
}
if (this->Impl->Parts[PartBuild] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetBuildHandler()->ProcessHandler() < 0) {
+ this->SetCMakeVariables(mf);
+ auto const func = cmListFileFunction("ctest_build", 0, 0, args);
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status) ||
+ std::stoi(mf.GetDefinition("return_value")) < 0) {
res |= cmCTest::BUILD_ERRORS;
}
}
- if ((this->Impl->Parts[PartTest] || notest) &&
+ if (this->Impl->Parts[PartTest] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetTestHandler()->ProcessHandler() < 0) {
+ this->SetCMakeVariables(mf);
+ auto const func = cmListFileFunction("ctest_test", 0, 0, args);
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status) ||
+ std::stoi(mf.GetDefinition("return_value")) < 0) {
res |= cmCTest::TEST_ERRORS;
}
}
if (this->Impl->Parts[PartCoverage] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetCoverageHandler()->ProcessHandler() < 0) {
+ this->SetCMakeVariables(mf);
+ auto const func = cmListFileFunction("ctest_coverage", 0, 0, args);
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status) ||
+ std::stoi(mf.GetDefinition("return_value")) < 0) {
res |= cmCTest::COVERAGE_ERRORS;
}
}
if (this->Impl->Parts[PartMemCheck] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetMemCheckHandler()->ProcessHandler() < 0) {
+ this->SetCMakeVariables(mf);
+ auto const func = cmListFileFunction("ctest_memcheck", 0, 0, args);
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status) ||
+ std::stoi(mf.GetDefinition("return_value")) < 0) {
res |= cmCTest::MEMORY_ERRORS;
}
}
- if (!notest) {
- std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes";
- if (cmSystemTools::FileIsDirectory(notes_dir)) {
- cmsys::Directory d;
- d.Load(notes_dir);
- unsigned long kk;
- for (kk = 0; kk < d.GetNumberOfFiles(); kk++) {
- const char* file = d.GetFile(kk);
- std::string fullname = notes_dir + "/" + file;
- if (cmSystemTools::FileExists(fullname, true)) {
- if (!this->Impl->NotesFiles.empty()) {
- this->Impl->NotesFiles += ";";
- }
- this->Impl->NotesFiles += fullname;
- this->Impl->Parts[PartNotes].Enable();
+ std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes";
+ if (cmSystemTools::FileIsDirectory(notes_dir)) {
+ cmsys::Directory d;
+ d.Load(notes_dir);
+ unsigned long kk;
+ for (kk = 0; kk < d.GetNumberOfFiles(); kk++) {
+ const char* file = d.GetFile(kk);
+ std::string fullname = notes_dir + "/" + file;
+ if (cmSystemTools::FileExists(fullname, true)) {
+ if (!this->Impl->NotesFiles.empty()) {
+ this->Impl->NotesFiles += ";";
}
+ this->Impl->NotesFiles += fullname;
+ this->Impl->Parts[PartNotes].Enable();
}
}
}
if (this->Impl->Parts[PartNotes]) {
this->UpdateCTestConfiguration();
if (!this->Impl->NotesFiles.empty()) {
- this->GenerateNotesFile(this->Impl->NotesFiles);
+ this->GenerateNotesFile(script.GetCMake(), this->Impl->NotesFiles);
}
}
if (this->Impl->Parts[PartSubmit]) {
this->UpdateCTestConfiguration();
- if (this->GetSubmitHandler()->ProcessHandler() < 0) {
+ this->SetCMakeVariables(mf);
+
+ std::string count = this->GetCTestConfiguration("CTestSubmitRetryCount");
+ std::string delay = this->GetCTestConfiguration("CTestSubmitRetryDelay");
+ auto const func = cmListFileFunction(
+ "ctest_submit", 0, 0,
+ {
+ cmListFileArgument("RETRY_COUNT", cmListFileArgument::Unquoted, 0),
+ cmListFileArgument(count, cmListFileArgument::Quoted, 0),
+ cmListFileArgument("RETRY_DELAY", cmListFileArgument::Unquoted, 0),
+ cmListFileArgument(delay, cmListFileArgument::Quoted, 0),
+ cmListFileArgument("RETURN_VALUE", cmListFileArgument::Unquoted, 0),
+ cmListFileArgument("return_value", cmListFileArgument::Unquoted, 0),
+ });
+ auto status = cmExecutionStatus(mf);
+ if (!mf.ExecuteCommand(func, status) ||
+ std::stoi(mf.GetDefinition("return_value")) < 0) {
res |= cmCTest::SUBMIT_ERRORS;
}
}
- if (res != 0) {
- cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest" << std::endl);
- if (!this->Impl->OutputTestOutputOnTestFailure) {
- const std::string lastTestLog =
- this->GetBinaryDir() + "/Testing/Temporary/LastTest.log";
- cmCTestLog(this, ERROR_MESSAGE,
- "Output from these tests are in: " << lastTestLog
- << std::endl);
- cmCTestLog(this, ERROR_MESSAGE,
- "Use \"--rerun-failed --output-on-failure\" to re-run the "
- "failed cases verbosely."
- << std::endl);
- }
- }
return res;
}
-std::string cmCTest::GetTestModelString()
+std::string cmCTest::GetTestModelString() const
{
- if (!this->Impl->SpecificGroup.empty()) {
- return this->Impl->SpecificGroup;
- }
switch (this->Impl->TestModel) {
case cmCTest::NIGHTLY:
return "Nightly";
@@ -1058,6 +876,14 @@
return "Experimental";
}
+std::string cmCTest::GetTestGroupString() const
+{
+ if (!this->Impl->SpecificGroup.empty()) {
+ return this->Impl->SpecificGroup;
+ }
+ return this->GetTestModelString();
+}
+
int cmCTest::GetTestModelFromString(const std::string& str)
{
if (str.empty()) {
@@ -1185,177 +1011,6 @@
return true;
}
-bool cmCTest::RunTest(const std::vector<std::string>& argv,
- std::string* output, int* retVal, std::ostream* log,
- cmDuration testTimeOut,
- std::vector<std::string>* environment, Encoding encoding)
-{
- bool modifyEnv = (environment && !environment->empty());
-
- // determine how much time we have
- cmDuration timeout = this->GetRemainingTimeAllowed();
- if (timeout != cmCTest::MaxDuration()) {
- timeout -= std::chrono::minutes(2);
- }
- if (this->Impl->TimeOut > cmDuration::zero() &&
- this->Impl->TimeOut < timeout) {
- timeout = this->Impl->TimeOut;
- }
- if (testTimeOut > cmDuration::zero() &&
- testTimeOut < this->GetRemainingTimeAllowed()) {
- timeout = testTimeOut;
- }
-
- // always have at least 1 second if we got to here
- if (timeout <= cmDuration::zero()) {
- timeout = std::chrono::seconds(1);
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- "Test timeout computed to be: "
- << (timeout == cmCTest::MaxDuration()
- ? std::string("infinite")
- : std::to_string(cmDurationTo<unsigned int>(timeout)))
- << "\n");
- if (cmSystemTools::SameFile(argv[0], cmSystemTools::GetCTestCommand()) &&
- !this->Impl->ForceNewCTestProcess) {
- cmCTest inst;
- inst.Impl->ConfigType = this->Impl->ConfigType;
- inst.Impl->TimeOut = timeout;
-
- // Capture output of the child ctest.
- std::ostringstream oss;
- inst.SetStreams(&oss, &oss);
-
- std::vector<std::string> args;
- for (auto const& i : argv) {
- // make sure we pass the timeout in for any build and test
- // invocations. Since --build-generator is required this is a
- // good place to check for it, and to add the arguments in
- if (i == "--build-generator" && timeout != cmCTest::MaxDuration() &&
- timeout > cmDuration::zero()) {
- args.emplace_back("--test-timeout");
- args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout)));
- }
- args.emplace_back(i);
- }
- if (log) {
- *log << "* Run internal CTest" << std::endl;
- }
-
- std::unique_ptr<cmSystemTools::SaveRestoreEnvironment> saveEnv;
- if (modifyEnv) {
- saveEnv = cm::make_unique<cmSystemTools::SaveRestoreEnvironment>();
- cmSystemTools::AppendEnv(*environment);
- }
-
- *retVal = inst.Run(args, output);
- if (output) {
- *output += oss.str();
- }
- if (log && output) {
- *log << *output;
- }
- if (output) {
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- "Internal cmCTest object used to run test." << std::endl
- << *output
- << std::endl);
- }
-
- return true;
- }
- std::vector<char> tempOutput;
- if (output) {
- output->clear();
- }
-
- std::unique_ptr<cmSystemTools::SaveRestoreEnvironment> saveEnv;
- if (modifyEnv) {
- saveEnv = cm::make_unique<cmSystemTools::SaveRestoreEnvironment>();
- cmSystemTools::AppendEnv(*environment);
- }
-
- cmUVProcessChainBuilder builder;
- builder.AddCommand(argv).SetMergedBuiltinStreams();
- cmCTestLog(this, DEBUG, "Command is: " << argv[0] << std::endl);
- auto chain = builder.Start();
-
- cmProcessOutput processOutput(encoding);
- cm::uv_pipe_ptr outputStream;
- outputStream.init(chain.GetLoop(), 0);
- uv_pipe_open(outputStream, chain.OutputStream());
- auto outputHandle = cmUVStreamRead(
- outputStream,
- [this, &processOutput, &output, &tempOutput,
- &log](std::vector<char> data) {
- std::string strdata;
- processOutput.DecodeText(data.data(), data.size(), strdata);
- if (output) {
- cm::append(tempOutput, data.data(), data.data() + data.size());
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, strdata);
- if (log) {
- log->write(strdata.c_str(), strdata.size());
- }
- },
- [this, &processOutput, &log]() {
- std::string strdata;
- processOutput.DecodeText(std::string(), strdata);
- if (!strdata.empty()) {
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, strdata);
- if (log) {
- log->write(strdata.c_str(), strdata.size());
- }
- }
- });
-
- bool complete = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0));
- processOutput.DecodeText(tempOutput, tempOutput);
- if (output && tempOutput.begin() != tempOutput.end()) {
- output->append(tempOutput.data(), tempOutput.size());
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- "-- Process completed" << std::endl);
-
- bool result = false;
-
- if (complete) {
- auto const& status = chain.GetStatus(0);
- auto exception = status.GetException();
- switch (exception.first) {
- case cmUVProcessChain::ExceptionCode::None:
- *retVal = static_cast<int>(status.ExitStatus);
- if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) {
- this->OutputTestErrors(tempOutput);
- }
- result = true;
- break;
- case cmUVProcessChain::ExceptionCode::Spawn: {
- std::string outerr =
- cmStrCat("\n*** ERROR executing: ", exception.second);
- if (output) {
- *output += outerr;
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
- } break;
- default: {
- if (this->Impl->OutputTestOutputOnTestFailure) {
- this->OutputTestErrors(tempOutput);
- }
- *retVal = status.TermSignal;
- std::string outerr =
- cmStrCat("\n*** Exception executing: ", exception.second);
- if (output) {
- *output += outerr;
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
- } break;
- }
- }
-
- return result;
-}
-
std::string cmCTest::SafeBuildIdField(const std::string& value)
{
std::string safevalue(value);
@@ -1386,7 +1041,7 @@
return safevalue;
}
-void cmCTest::StartXML(cmXMLWriter& xml, bool append)
+void cmCTest::StartXML(cmXMLWriter& xml, cmake* cm, bool append)
{
if (this->Impl->CurrentTag.empty()) {
cmCTestLog(this, ERROR_MESSAGE,
@@ -1405,7 +1060,7 @@
std::string buildname =
cmCTest::SafeBuildIdField(this->GetCTestConfiguration("BuildName"));
std::string stamp = cmCTest::SafeBuildIdField(this->Impl->CurrentTag + "-" +
- this->GetTestModelString());
+ this->GetTestGroupString());
std::string site =
cmCTest::SafeBuildIdField(this->GetCTestConfiguration("Site"));
@@ -1448,25 +1103,17 @@
xml.Attribute("ChangeId", changeId);
}
- this->AddSiteProperties(xml);
+ this->AddSiteProperties(xml, cm);
}
-void cmCTest::AddSiteProperties(cmXMLWriter& xml)
+void cmCTest::AddSiteProperties(cmXMLWriter& xml, cmake* cm)
{
- cmCTestScriptHandler* ch = this->GetScriptHandler();
- cmake* cm = ch->GetCMake();
- // if no CMake then this is the old style script and props like
- // this will not work anyway.
- if (!cm) {
- return;
- }
// This code should go when cdash is changed to use labels only
cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
xml.StartElement("Subproject");
xml.Attribute("name", *subproject);
- cmValue labels =
- ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels");
+ cmValue labels = cm->GetState()->GetGlobalProperty("SubProjectLabels");
if (labels) {
xml.StartElement("Labels");
cmList args{ *labels };
@@ -1518,7 +1165,7 @@
xml.EndDocument();
}
-int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
+int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml, cmake* cm,
std::vector<std::string> const& files)
{
std::string buildname =
@@ -1531,11 +1178,11 @@
xml.StartElement("Site");
xml.Attribute("BuildName", buildname);
xml.Attribute("BuildStamp",
- this->Impl->CurrentTag + "-" + this->GetTestModelString());
+ this->Impl->CurrentTag + "-" + this->GetTestGroupString());
xml.Attribute("Name", this->GetCTestConfiguration("Site"));
xml.Attribute("Generator",
std::string("ctest-") + cmVersion::GetCMakeVersion());
- this->AddSiteProperties(xml);
+ this->AddSiteProperties(xml, cm);
xml.StartElement("Notes");
for (std::string const& file : files) {
@@ -1569,7 +1216,8 @@
return 1;
}
-int cmCTest::GenerateNotesFile(std::vector<std::string> const& files)
+int cmCTest::GenerateNotesFile(cmake* cm,
+ std::vector<std::string> const& files)
{
cmGeneratedFileStream ofs;
if (!this->OpenOutputFile(this->Impl->CurrentTag, "Notes.xml", ofs)) {
@@ -1577,11 +1225,11 @@
return 1;
}
cmXMLWriter xml(ofs);
- this->GenerateCTestNotesOutput(xml, files);
+ this->GenerateCTestNotesOutput(xml, cm, files);
return 0;
}
-int cmCTest::GenerateNotesFile(const std::string& cfiles)
+int cmCTest::GenerateNotesFile(cmake* cm, const std::string& cfiles)
{
if (cfiles.empty()) {
return 1;
@@ -1595,7 +1243,7 @@
return 1;
}
- return this->GenerateNotesFile(files);
+ return this->GenerateNotesFile(cm, files);
}
int cmCTest::GenerateDoneFile()
@@ -1616,31 +1264,14 @@
return 0;
}
-bool cmCTest::TryToChangeDirectory(std::string const& dir)
-{
- cmCTestLog(this, OUTPUT,
- "Internal ctest changing into directory: " << dir << std::endl);
- cmsys::Status status = cmSystemTools::ChangeDirectory(dir);
- if (!status) {
- auto msg = "Failed to change working directory to \"" + dir +
- "\" : " + status.GetString() + "\n";
- cmCTestLog(this, ERROR_MESSAGE, msg);
- return false;
- }
- return true;
-}
-
std::string cmCTest::Base64GzipEncodeFile(std::string const& file)
{
- const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
- std::string parentDir = cmSystemTools::GetParentDirectory(file);
-
// Temporarily change to the file's directory so the tar gets created
// with a flat directory structure.
- if (currDir != parentDir) {
- if (!this->TryToChangeDirectory(parentDir)) {
- return "";
- }
+ cmWorkingDirectory workdir(cmSystemTools::GetParentDirectory(file));
+ if (workdir.Failed()) {
+ cmCTestLog(this, ERROR_MESSAGE, workdir.GetError() << std::endl);
+ return "";
}
std::string tarFile = file + "_temp.tar.gz";
@@ -1657,12 +1288,6 @@
}
std::string base64 = this->Base64EncodeFile(tarFile);
cmSystemTools::RemoveFile(tarFile);
-
- // Change back to the directory we started in.
- if (currDir != parentDir) {
- cmSystemTools::ChangeDirectory(currDir);
- }
-
return base64;
}
@@ -1721,7 +1346,7 @@
// for a -D argument convert the next argument into
// the proper list of dashboard steps via SetTest
-bool cmCTest::AddTestsForDashboardType(std::string& targ)
+bool cmCTest::AddTestsForDashboardType(std::string const& targ)
{
if (targ == "Experimental") {
this->SetTestModel(cmCTest::EXPERIMENTAL);
@@ -1844,7 +1469,7 @@
return true;
}
-void cmCTest::ErrorMessageUnknownDashDValue(std::string& val)
+void cmCTest::ErrorMessageUnknownDashDValue(std::string const& val)
{
cmCTestLog(this, ERROR_MESSAGE,
"CTest -D called with incorrect option: " << val << '\n');
@@ -1869,389 +1494,6 @@
return (arg == varg1) || (varg2 && arg == varg2);
}
-// Processes one command line argument (and its arguments if any)
-// for many simple options and then returns
-bool cmCTest::HandleCommandLineArguments(size_t& i,
- std::vector<std::string>& args,
- std::string& errormsg)
-{
- std::string arg = args[i];
- cm::string_view noTestsPrefix = "--no-tests=";
- if (this->CheckArgument(arg, "-F"_s)) {
- this->Impl->Failover = true;
- } else if (this->CheckArgument(arg, "-j"_s, "--parallel")) {
- cm::optional<size_t> parallelLevel;
- // No value or an empty value tells ctest to choose a default.
- if (i + 1 < args.size() && !cmHasLiteralPrefix(args[i + 1], "-")) {
- ++i;
- if (!args[i].empty()) {
- // A non-empty value must be a non-negative integer.
- unsigned long plevel = 0;
- if (!cmStrToULong(args[i], &plevel)) {
- errormsg =
- cmStrCat("'", arg, "' given invalid value '", args[i], "'");
- return false;
- }
- parallelLevel = plevel;
- }
- }
- this->SetParallelLevel(parallelLevel);
- this->Impl->ParallelLevelSetInCli = true;
- } else if (cmHasPrefix(arg, "-j")) {
- // The value must be a non-negative integer.
- unsigned long plevel = 0;
- if (!cmStrToULong(arg.substr(2), &plevel)) {
- errormsg = cmStrCat("'", arg, "' given invalid value '", args[i], "'");
- return false;
- }
- this->SetParallelLevel(plevel);
- this->Impl->ParallelLevelSetInCli = true;
- }
-
- else if (this->CheckArgument(arg, "--repeat-until-fail"_s)) {
- if (i >= args.size() - 1) {
- errormsg = "'--repeat-until-fail' requires an argument";
- return false;
- }
- if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
- errormsg = "At most one '--repeat' option may be used.";
- return false;
- }
- i++;
- long repeat = 1;
- if (!cmStrToLong(args[i], &repeat)) {
- errormsg = cmStrCat("'--repeat-until-fail' given non-integer value '",
- args[i], "'");
- return false;
- }
- this->Impl->RepeatCount = static_cast<int>(repeat);
- if (repeat > 1) {
- this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
- }
- }
-
- else if (this->CheckArgument(arg, "--repeat"_s)) {
- if (i >= args.size() - 1) {
- errormsg = "'--repeat' requires an argument";
- return false;
- }
- if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
- errormsg = "At most one '--repeat' option may be used.";
- return false;
- }
- i++;
- cmsys::RegularExpression repeatRegex(
- "^(until-fail|until-pass|after-timeout):([0-9]+)$");
- if (repeatRegex.find(args[i])) {
- std::string const& count = repeatRegex.match(2);
- unsigned long n = 1;
- cmStrToULong(count, &n); // regex guarantees success
- this->Impl->RepeatCount = static_cast<int>(n);
- if (this->Impl->RepeatCount > 1) {
- std::string const& mode = repeatRegex.match(1);
- if (mode == "until-fail") {
- this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
- } else if (mode == "until-pass") {
- this->Impl->RepeatMode = cmCTest::Repeat::UntilPass;
- } else if (mode == "after-timeout") {
- this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout;
- }
- }
- } else {
- errormsg = cmStrCat("'--repeat' given invalid value '", args[i], "'");
- return false;
- }
- }
-
- else if (this->CheckArgument(arg, "--test-load"_s) && i < args.size() - 1) {
- i++;
- unsigned long load;
- if (cmStrToULong(args[i], &load)) {
- this->SetTestLoad(load);
- } else {
- cmCTestLog(this, WARNING,
- "Invalid value for 'Test Load' : " << args[i] << '\n');
- }
- }
-
- else if (this->CheckArgument(arg, "--no-compress-output"_s)) {
- this->Impl->CompressTestOutput = false;
- }
-
- else if (this->CheckArgument(arg, "--print-labels"_s)) {
- this->Impl->PrintLabels = true;
- }
-
- else if (this->CheckArgument(arg, "--http1.0"_s)) {
- this->Impl->UseHTTP10 = true;
- }
-
- else if (this->CheckArgument(arg, "--timeout"_s) && i < args.size() - 1) {
- i++;
- auto timeout = cmDuration(atof(args[i].c_str()));
- this->Impl->GlobalTimeout = timeout;
- }
-
- else if (this->CheckArgument(arg, "--stop-time"_s) && i < args.size() - 1) {
- i++;
- this->SetStopTime(args[i]);
- }
-
- else if (this->CheckArgument(arg, "--stop-on-failure"_s)) {
- this->Impl->StopOnFailure = true;
- }
-
- else if (this->CheckArgument(arg, "-C"_s, "--build-config") &&
- i < args.size() - 1) {
- i++;
- this->SetConfigType(args[i]);
- }
-
- else if (this->CheckArgument(arg, "--debug"_s)) {
- this->Impl->Debug = true;
- this->Impl->ShowLineNumbers = true;
- } else if ((this->CheckArgument(arg, "--group"_s) ||
- // This is an undocumented / deprecated option.
- // "Track" has been renamed to "Group".
- this->CheckArgument(arg, "--track"_s)) &&
- i < args.size() - 1) {
- i++;
- this->Impl->SpecificGroup = args[i];
- } else if (this->CheckArgument(arg, "--show-line-numbers"_s)) {
- this->Impl->ShowLineNumbers = true;
- } else if (this->CheckArgument(arg, "--no-label-summary"_s)) {
- this->Impl->LabelSummary = false;
- } else if (this->CheckArgument(arg, "--no-subproject-summary"_s)) {
- this->Impl->SubprojectSummary = false;
- } else if (this->CheckArgument(arg, "-Q"_s, "--quiet")) {
- this->Impl->Quiet = true;
- } else if (this->CheckArgument(arg, "--progress"_s)) {
- this->Impl->TestProgressOutput = true;
- } else if (this->CheckArgument(arg, "-V"_s, "--verbose")) {
- this->Impl->Verbose = true;
- } else if (this->CheckArgument(arg, "-VV"_s, "--extra-verbose")) {
- this->Impl->ExtraVerbose = true;
- this->Impl->Verbose = true;
- } else if (this->CheckArgument(arg, "--output-on-failure"_s)) {
- this->Impl->OutputTestOutputOnTestFailure = true;
- } else if (this->CheckArgument(arg, "--test-output-size-passed"_s) &&
- i < args.size() - 1) {
- i++;
- long outputSize;
- if (cmStrToLong(args[i], &outputSize)) {
- this->Impl->TestHandler.SetTestOutputSizePassed(
- static_cast<int>(outputSize));
- } else {
- cmCTestLog(this, WARNING,
- "Invalid value for '--test-output-size-passed': " << args[i]
- << "\n");
- }
- } else if (this->CheckArgument(arg, "--test-output-size-failed"_s) &&
- i < args.size() - 1) {
- i++;
- long outputSize;
- if (cmStrToLong(args[i], &outputSize)) {
- this->Impl->TestHandler.SetTestOutputSizeFailed(
- static_cast<int>(outputSize));
- } else {
- cmCTestLog(this, WARNING,
- "Invalid value for '--test-output-size-failed': " << args[i]
- << "\n");
- }
- } else if (this->CheckArgument(arg, "--test-output-truncation"_s) &&
- i < args.size() - 1) {
- i++;
- if (!this->Impl->TestHandler.SetTestOutputTruncation(args[i])) {
- errormsg = "Invalid value for '--test-output-truncation': " + args[i];
- return false;
- }
- } else if (this->CheckArgument(arg, "-N"_s, "--show-only")) {
- this->Impl->ShowOnly = true;
- } else if (cmHasLiteralPrefix(arg, "--show-only=")) {
- this->Impl->ShowOnly = true;
-
- // Check if a specific format is requested. Defaults to human readable
- // text.
- std::string argWithFormat = "--show-only=";
- std::string format = arg.substr(argWithFormat.length());
- if (format == "json-v1") {
- // Force quiet mode so the only output is the json object model.
- this->Impl->Quiet = true;
- this->Impl->OutputAsJson = true;
- this->Impl->OutputAsJsonVersion = 1;
- } else if (format != "human") {
- errormsg = "'--show-only=' given unknown value '" + format + "'";
- return false;
- }
- }
-
- else if (this->CheckArgument(arg, "-O"_s, "--output-log") &&
- i < args.size() - 1) {
- i++;
- this->SetOutputLogFileName(args[i]);
- }
-
- else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) {
- this->Impl->TomorrowTag = true;
- } else if (this->CheckArgument(arg, "--force-new-ctest-process"_s)) {
- this->Impl->ForceNewCTestProcess = true;
- } else if (this->CheckArgument(arg, "-W"_s, "--max-width") &&
- i < args.size() - 1) {
- i++;
- this->Impl->MaxTestNameWidth = atoi(args[i].c_str());
- } else if (this->CheckArgument(arg, "--interactive-debug-mode"_s) &&
- i < args.size() - 1) {
- i++;
- this->Impl->InteractiveDebugMode = cmIsOn(args[i]);
- } else if (this->CheckArgument(arg, "--submit-index"_s) &&
- i < args.size() - 1) {
- i++;
- this->Impl->SubmitIndex = atoi(args[i].c_str());
- if (this->Impl->SubmitIndex < 0) {
- this->Impl->SubmitIndex = 0;
- }
- }
-
- else if (this->CheckArgument(arg, "--overwrite"_s) && i < args.size() - 1) {
- i++;
- this->AddCTestConfigurationOverwrite(args[i]);
- } else if (this->CheckArgument(arg, "-A"_s, "--add-notes") &&
- i < args.size() - 1) {
- this->Impl->ProduceXML = true;
- this->SetTest("Notes");
- i++;
- this->SetNotesFiles(args[i]);
- return true;
- } else if (this->CheckArgument(arg, "--test-dir"_s)) {
- if (i >= args.size() - 1) {
- errormsg = "'--test-dir' requires an argument";
- return false;
- }
- i++;
- this->Impl->TestDir = std::string(args[i]);
- } else if (this->CheckArgument(arg, "--output-junit"_s)) {
- if (i >= args.size() - 1) {
- errormsg = "'--output-junit' requires an argument";
- return false;
- }
- i++;
- this->SetOutputJUnitFileName(std::string(args[i]));
- }
-
- else if (cmHasPrefix(arg, noTestsPrefix)) {
- cm::string_view noTestsMode =
- cm::string_view(arg).substr(noTestsPrefix.length());
- if (noTestsMode == "error") {
- this->Impl->NoTestsMode = cmCTest::NoTests::Error;
- } else if (noTestsMode != "ignore") {
- errormsg =
- cmStrCat("'--no-tests=' given unknown value '", noTestsMode, '\'');
- return false;
- } else {
- this->Impl->NoTestsMode = cmCTest::NoTests::Ignore;
- }
- this->Impl->NoTestsModeSetInCli = true;
- }
-
- // options that control what tests are run
- else if (this->CheckArgument(arg, "-I"_s, "--tests-information") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption("TestsToRunInformation",
- args[i]);
- this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation",
- args[i]);
- } else if (this->CheckArgument(arg, "-U"_s, "--union")) {
- this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
- this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
- } else if (this->CheckArgument(arg, "-R"_s, "--tests-regex") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression",
- args[i]);
- this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression",
- args[i]);
- } else if (this->CheckArgument(arg, "-L"_s, "--label-regex") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->AddPersistentMultiOption("LabelRegularExpression",
- args[i]);
- this->GetMemCheckHandler()->AddPersistentMultiOption(
- "LabelRegularExpression", args[i]);
- } else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->AddPersistentMultiOption(
- "ExcludeLabelRegularExpression", args[i]);
- this->GetMemCheckHandler()->AddPersistentMultiOption(
- "ExcludeLabelRegularExpression", args[i]);
- }
-
- else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression",
- args[i]);
- this->GetMemCheckHandler()->SetPersistentOption("ExcludeRegularExpression",
- args[i]);
- }
-
- else if (this->CheckArgument(arg, "-FA"_s, "--fixture-exclude-any") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption(
- "ExcludeFixtureRegularExpression", args[i]);
- this->GetMemCheckHandler()->SetPersistentOption(
- "ExcludeFixtureRegularExpression", args[i]);
- } else if (this->CheckArgument(arg, "-FS"_s, "--fixture-exclude-setup") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption(
- "ExcludeFixtureSetupRegularExpression", args[i]);
- this->GetMemCheckHandler()->SetPersistentOption(
- "ExcludeFixtureSetupRegularExpression", args[i]);
- } else if (this->CheckArgument(arg, "-FC"_s, "--fixture-exclude-cleanup") &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption(
- "ExcludeFixtureCleanupRegularExpression", args[i]);
- this->GetMemCheckHandler()->SetPersistentOption(
- "ExcludeFixtureCleanupRegularExpression", args[i]);
- }
-
- else if (this->CheckArgument(arg, "--resource-spec-file"_s) &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption("ResourceSpecFile", args[i]);
- this->GetMemCheckHandler()->SetPersistentOption("ResourceSpecFile",
- args[i]);
- }
-
- else if (this->CheckArgument(arg, "--tests-from-file"_s) &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption("TestListFile", args[i]);
- this->GetMemCheckHandler()->SetPersistentOption("TestListFile", args[i]);
- }
-
- else if (this->CheckArgument(arg, "--exclude-from-file"_s) &&
- i < args.size() - 1) {
- i++;
- this->GetTestHandler()->SetPersistentOption("ExcludeTestListFile",
- args[i]);
- this->GetMemCheckHandler()->SetPersistentOption("ExcludeTestListFile",
- args[i]);
- }
-
- else if (this->CheckArgument(arg, "--rerun-failed"_s)) {
- this->GetTestHandler()->SetPersistentOption("RerunFailed", "true");
- this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true");
- } else {
- return false;
- }
- return true;
-}
-
#if !defined(_WIN32)
bool cmCTest::ConsoleIsNotDumb()
{
@@ -2296,46 +1538,6 @@
#endif
}
-// handle the -S -SR and -SP arguments
-bool cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
- bool& SRArgumentSpecified)
-{
- std::string arg = args[i];
- if (this->CheckArgument(arg, "-SP"_s, "--script-new-process") &&
- i < args.size() - 1) {
- this->Impl->RunConfigurationScript = true;
- i++;
- cmCTestScriptHandler* ch = this->GetScriptHandler();
- // -SR is an internal argument, -SP should be ignored when it is passed
- if (!SRArgumentSpecified) {
- ch->AddConfigurationScript(args[i], false);
- }
- }
-
- else if (this->CheckArgument(arg, "-SR"_s, "--script-run") &&
- i < args.size() - 1) {
- SRArgumentSpecified = true;
- this->Impl->RunConfigurationScript = true;
- i++;
- cmCTestScriptHandler* ch = this->GetScriptHandler();
- ch->AddConfigurationScript(args[i], true);
- }
-
- else if (this->CheckArgument(arg, "-S"_s, "--script") &&
- i < args.size() - 1) {
- this->Impl->RunConfigurationScript = true;
- i++;
- cmCTestScriptHandler* ch = this->GetScriptHandler();
- // -SR is an internal argument, -S should be ignored when it is passed
- if (!SRArgumentSpecified) {
- ch->AddConfigurationScript(args[i], true);
- }
- } else {
- return false;
- }
- return true;
-}
-
bool cmCTest::AddVariableDefinition(const std::string& arg)
{
std::string name;
@@ -2350,28 +1552,10 @@
return false;
}
-void cmCTest::SetPersistentOptionIfNotEmpty(const std::string& value,
- const std::string& optionName)
-{
- if (!value.empty()) {
- this->GetTestHandler()->SetPersistentOption(optionName, value);
- this->GetMemCheckHandler()->SetPersistentOption(optionName, value);
- }
-}
-
-void cmCTest::AddPersistentMultiOptionIfNotEmpty(const std::string& value,
- const std::string& optionName)
-{
- if (!value.empty()) {
- this->GetTestHandler()->AddPersistentMultiOption(optionName, value);
- this->GetMemCheckHandler()->AddPersistentMultiOption(optionName, value);
- }
-}
-
bool cmCTest::SetArgsFromPreset(const std::string& presetName,
bool listPresets)
{
- const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ const auto workingDirectory = cmSystemTools::GetLogicalWorkingDirectory();
cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(workingDirectory);
@@ -2485,8 +1669,6 @@
}
this->Impl->Debug = expandedPreset->Output->Debug.value_or(false);
- this->Impl->ShowLineNumbers =
- expandedPreset->Output->Debug.value_or(false);
this->Impl->OutputTestOutputOnTestFailure =
expandedPreset->Output->OutputOnFailure.value_or(false);
this->Impl->Quiet = expandedPreset->Output->Quiet.value_or(false);
@@ -2504,17 +1686,17 @@
expandedPreset->Output->SubprojectSummary.value_or(true);
if (expandedPreset->Output->MaxPassedTestOutputSize) {
- this->Impl->TestHandler.SetTestOutputSizePassed(
- *expandedPreset->Output->MaxPassedTestOutputSize);
+ this->Impl->TestOptions.OutputSizePassed =
+ *expandedPreset->Output->MaxPassedTestOutputSize;
}
if (expandedPreset->Output->MaxFailedTestOutputSize) {
- this->Impl->TestHandler.SetTestOutputSizeFailed(
- *expandedPreset->Output->MaxFailedTestOutputSize);
+ this->Impl->TestOptions.OutputSizeFailed =
+ *expandedPreset->Output->MaxFailedTestOutputSize;
}
if (expandedPreset->Output->TestOutputTruncation) {
- this->Impl->TestHandler.TestOutputTruncation =
+ this->Impl->TestOptions.OutputTruncation =
*expandedPreset->Output->TestOutputTruncation;
}
@@ -2525,10 +1707,12 @@
if (expandedPreset->Filter) {
if (expandedPreset->Filter->Include) {
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Filter->Include->Name, "IncludeRegularExpression");
- this->AddPersistentMultiOptionIfNotEmpty(
- expandedPreset->Filter->Include->Label, "LabelRegularExpression");
+ this->Impl->TestOptions.IncludeRegularExpression =
+ expandedPreset->Filter->Include->Name;
+ if (!expandedPreset->Filter->Include->Label.empty()) {
+ this->Impl->TestOptions.LabelRegularExpression.push_back(
+ expandedPreset->Filter->Include->Label);
+ }
if (expandedPreset->Filter->Include->Index) {
if (expandedPreset->Filter->Include->Index->IndexFile.empty()) {
@@ -2542,38 +1726,32 @@
indexOptions +=
cmJoin(expandedPreset->Filter->Include->Index->SpecificTests, ",");
- this->SetPersistentOptionIfNotEmpty(indexOptions,
- "TestsToRunInformation");
+ this->Impl->TestOptions.TestsToRunInformation = indexOptions;
} else {
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Filter->Include->Index->IndexFile,
- "TestsToRunInformation");
+ this->Impl->TestOptions.TestsToRunInformation =
+ expandedPreset->Filter->Include->Index->IndexFile;
}
}
- if (expandedPreset->Filter->Include->UseUnion.value_or(false)) {
- this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
- this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
- }
+ this->Impl->TestOptions.UseUnion =
+ expandedPreset->Filter->Include->UseUnion.value_or(false);
}
if (expandedPreset->Filter->Exclude) {
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Filter->Exclude->Name, "ExcludeRegularExpression");
- this->AddPersistentMultiOptionIfNotEmpty(
- expandedPreset->Filter->Exclude->Label,
- "ExcludeLabelRegularExpression");
+ this->Impl->TestOptions.ExcludeRegularExpression =
+ expandedPreset->Filter->Exclude->Name;
+ if (!expandedPreset->Filter->Exclude->Label.empty()) {
+ this->Impl->TestOptions.ExcludeLabelRegularExpression.push_back(
+ expandedPreset->Filter->Exclude->Label);
+ }
if (expandedPreset->Filter->Exclude->Fixtures) {
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Filter->Exclude->Fixtures->Any,
- "ExcludeFixtureRegularExpression");
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Filter->Exclude->Fixtures->Setup,
- "ExcludeFixtureSetupRegularExpression");
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Filter->Exclude->Fixtures->Cleanup,
- "ExcludeFixtureCleanupRegularExpression");
+ this->Impl->TestOptions.ExcludeFixtureRegularExpression =
+ expandedPreset->Filter->Exclude->Fixtures->Any;
+ this->Impl->TestOptions.ExcludeFixtureSetupRegularExpression =
+ expandedPreset->Filter->Exclude->Fixtures->Setup;
+ this->Impl->TestOptions.ExcludeFixtureCleanupRegularExpression =
+ expandedPreset->Filter->Exclude->Fixtures->Cleanup;
}
}
}
@@ -2590,8 +1768,8 @@
this->Impl->ParallelLevelSetInCli = true;
}
- this->SetPersistentOptionIfNotEmpty(
- expandedPreset->Execution->ResourceSpecFile, "ResourceSpecFile");
+ this->Impl->TestOptions.ResourceSpecFile =
+ expandedPreset->Execution->ResourceSpecFile;
if (expandedPreset->Execution->TestLoad) {
auto testLoad = *expandedPreset->Execution->TestLoad;
@@ -2675,12 +1853,13 @@
}
// the main entry point of ctest, called from main
-int cmCTest::Run(std::vector<std::string>& args, std::string* output)
+int cmCTest::Run(std::vector<std::string> const& args)
{
const char* ctestExec = "ctest";
bool cmakeAndTest = false;
- bool executeTests = true;
+ bool processSteps = false;
bool SRArgumentSpecified = false;
+ std::vector<std::pair<std::string, bool>> runScripts;
// copy the command line
cm::append(this->Impl->InitialCommandLineArguments, args);
@@ -2702,10 +1881,10 @@
success = this->SetArgsFromPreset("", listPresets);
} else {
if (cmHasLiteralPrefix(*it, "--preset=")) {
- auto presetName = it->substr(9);
+ auto const& presetName = it->substr(9);
success = this->SetArgsFromPreset(presetName, listPresets);
} else if (++it != args.end()) {
- auto presetName = *it;
+ auto const& presetName = *it;
success = this->SetArgsFromPreset(presetName, listPresets);
} else {
cmSystemTools::Error("'--preset' requires an argument");
@@ -2722,103 +1901,678 @@
}
}
+ auto const dashD = [this, &processSteps](std::string const& targ) -> bool {
+ // AddTestsForDashboard parses the dashboard type and converts it
+ // into the separate stages
+ if (this->AddTestsForDashboardType(targ)) {
+ processSteps = true;
+ return true;
+ }
+ if (this->AddVariableDefinition(targ)) {
+ return true;
+ }
+ this->ErrorMessageUnknownDashDValue(targ);
+ return false;
+ };
+ auto const dashT = [this, &processSteps,
+ ctestExec](std::string const& action) -> bool {
+ if (!this->SetTest(action, false)) {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "CTest -T called with incorrect option: " << action << '\n');
+ /* clang-format off */
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Available options are:\n"
+ " " << ctestExec << " -T all\n"
+ " " << ctestExec << " -T start\n"
+ " " << ctestExec << " -T update\n"
+ " " << ctestExec << " -T configure\n"
+ " " << ctestExec << " -T build\n"
+ " " << ctestExec << " -T test\n"
+ " " << ctestExec << " -T coverage\n"
+ " " << ctestExec << " -T memcheck\n"
+ " " << ctestExec << " -T notes\n"
+ " " << ctestExec << " -T submit\n");
+ /* clang-format on */
+ return false;
+ }
+ processSteps = true;
+ return true;
+ };
+ auto const dashM = [this, &processSteps,
+ ctestExec](std::string const& model) -> bool {
+ if (cmSystemTools::LowerCase(model) == "nightly"_s) {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ } else if (cmSystemTools::LowerCase(model) == "continuous"_s) {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ } else if (cmSystemTools::LowerCase(model) == "experimental"_s) {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ } else {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "CTest -M called with incorrect option: " << model << '\n');
+ /* clang-format off */
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Available options are:\n"
+ " " << ctestExec << " -M Continuous\n"
+ " " << ctestExec << " -M Experimental\n"
+ " " << ctestExec << " -M Nightly\n");
+ /* clang-format on */
+ return false;
+ }
+ processSteps = true;
+ return true;
+ };
+ auto const dashSP =
+ [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool {
+ // -SR is an internal argument, -SP should be ignored when it is passed
+ if (!SRArgumentSpecified) {
+ runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script),
+ false);
+ }
+ return true;
+ };
+ auto const dashSR =
+ [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool {
+ SRArgumentSpecified = true;
+ runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script),
+ true);
+ return true;
+ };
+ auto const dash_S =
+ [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool {
+ // -SR is an internal argument, -S should be ignored when it is passed
+ if (!SRArgumentSpecified) {
+ runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script),
+ true);
+ }
+ return true;
+ };
+ auto const dashJ = [this](cm::string_view arg,
+ std::string const& j) -> bool {
+ cm::optional<size_t> parallelLevel;
+ // No value or an empty value tells ctest to choose a default.
+ if (!j.empty()) {
+ // A non-empty value must be a non-negative integer.
+ unsigned long plevel = 0;
+ if (!cmStrToULong(j, &plevel)) {
+ cmSystemTools::Error(
+ cmStrCat('\'', arg, "' given invalid value '", j, '\''));
+ return false;
+ }
+ parallelLevel = plevel;
+ }
+ this->SetParallelLevel(parallelLevel);
+ this->Impl->ParallelLevelSetInCli = true;
+ return true;
+ };
+ auto const dashC = [this](std::string const& config) -> bool {
+ this->SetConfigType(config);
+ return true;
+ };
+ auto const dashGroup = [this](std::string const& group) -> bool {
+ this->Impl->SpecificGroup = group;
+ return true;
+ };
+ auto const dashQ = [this](std::string const&) -> bool {
+ this->Impl->Quiet = true;
+ return true;
+ };
+ auto const dashV = [this](std::string const&) -> bool {
+ this->Impl->Verbose = true;
+ return true;
+ };
+ auto const dashVV = [this](std::string const&) -> bool {
+ this->Impl->ExtraVerbose = true;
+ this->Impl->Verbose = true;
+ return true;
+ };
+ auto const dashO = [this](std::string const& log) -> bool {
+ this->SetOutputLogFileName(log);
+ return true;
+ };
+ auto const dashW = [this](std::string const& width) -> bool {
+ this->Impl->MaxTestNameWidth = atoi(width.c_str());
+ return true;
+ };
+ auto const dashA = [this, &processSteps](std::string const& notes) -> bool {
+ processSteps = true;
+ this->SetTest("Notes");
+ this->SetNotesFiles(notes);
+ return true;
+ };
+ auto const dashI = [this](std::string const& tests) -> bool {
+ this->Impl->TestOptions.TestsToRunInformation = tests;
+ return true;
+ };
+ auto const dashU = [this](std::string const&) -> bool {
+ this->Impl->TestOptions.UseUnion = true;
+ return true;
+ };
+ auto const dashR = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.IncludeRegularExpression = expr;
+ return true;
+ };
+ auto const dashE = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.ExcludeRegularExpression = expr;
+ return true;
+ };
+ auto const dashL = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.LabelRegularExpression.push_back(expr);
+ return true;
+ };
+ auto const dashLE = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.ExcludeLabelRegularExpression.push_back(expr);
+ return true;
+ };
+ auto const dashFA = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.ExcludeFixtureRegularExpression = expr;
+ return true;
+ };
+ auto const dashFS = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.ExcludeFixtureSetupRegularExpression = expr;
+ return true;
+ };
+ auto const dashFC = [this](std::string const& expr) -> bool {
+ this->Impl->TestOptions.ExcludeFixtureCleanupRegularExpression = expr;
+ return true;
+ };
+
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+
+ auto const arguments = std::vector<CommandArgument>{
+ CommandArgument{ "--dashboard", CommandArgument::Values::One, dashD },
+ CommandArgument{ "-D",
+ "-D must be followed by dashboard mode or VAR=VALUE.",
+ CommandArgument::Values::One, dashD },
+ CommandArgument{
+ "-D", "-D must be followed by dashboard mode or VAR=VALUE.",
+ CommandArgument::Values::One, CommandArgument::RequiresSeparator::No,
+ [this](std::string const& def) -> bool {
+ // Unsuccessful parsing of VAR=VALUE has historically
+ // been ignored.
+ this->AddVariableDefinition(def);
+ return true;
+ } },
+ CommandArgument{ "-T", CommandArgument::Values::One, dashT },
+ CommandArgument{ "--test-action", CommandArgument::Values::One, dashT },
+ CommandArgument{ "-M", CommandArgument::Values::One, dashM },
+ CommandArgument{ "--test-model", CommandArgument::Values::One, dashM },
+ CommandArgument{ "--extra-submit", CommandArgument::Values::One,
+ [this, &processSteps](std::string const& extra) -> bool {
+ processSteps = true;
+ this->SetTest("Submit");
+ return this->SubmitExtraFiles(extra);
+ } },
+ CommandArgument{
+ "--build-and-test", "--build-and-test must have source and binary dir",
+ CommandArgument::Values::Two,
+ [this, &cmakeAndTest](std::string const& dirs) -> bool {
+ cmakeAndTest = true;
+ cmList dirList{ dirs };
+ if (dirList.size() != 2) {
+ return false;
+ }
+ this->Impl->BuildAndTest.SourceDir =
+ cmSystemTools::ToNormalizedPathOnDisk(dirList[0]);
+ this->Impl->BuildAndTest.BinaryDir =
+ cmSystemTools::ToNormalizedPathOnDisk(dirList[1]);
+ cmSystemTools::MakeDirectory(this->Impl->BuildAndTest.BinaryDir);
+ return true;
+ } },
+ CommandArgument{ "--build-target", CommandArgument::Values::One,
+ [this](std::string const& t) -> bool {
+ this->Impl->BuildAndTest.BuildTargets.emplace_back(t);
+ return true;
+ } },
+ CommandArgument{ "--build-noclean", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->BuildAndTest.BuildNoClean = true;
+ return true;
+ } },
+ CommandArgument{ "--build-nocmake", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->BuildAndTest.BuildNoCMake = true;
+ return true;
+ } },
+ CommandArgument{ "--build-two-config", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->BuildAndTest.BuildTwoConfig = true;
+ return true;
+ } },
+ CommandArgument{ "--build-run-dir", CommandArgument::Values::One,
+ [this](std::string const& dir) -> bool {
+ this->Impl->BuildAndTest.BuildRunDir = dir;
+ return true;
+ } },
+ CommandArgument{ "--build-exe-dir", CommandArgument::Values::One,
+ [this](std::string const& dir) -> bool {
+ this->Impl->BuildAndTest.ExecutableDirectory = dir;
+ return true;
+ } },
+ CommandArgument{ "--test-timeout", CommandArgument::Values::One,
+ [this](std::string const& t) -> bool {
+ this->Impl->BuildAndTest.Timeout =
+ cmDuration(atof(t.c_str()));
+ return true;
+ } },
+ CommandArgument{ "--build-generator", CommandArgument::Values::One,
+ [this](std::string const& g) -> bool {
+ this->Impl->BuildAndTest.BuildGenerator = g;
+ return true;
+ } },
+ CommandArgument{ "--build-generator-platform",
+ CommandArgument::Values::One,
+ [this](std::string const& p) -> bool {
+ this->Impl->BuildAndTest.BuildGeneratorPlatform = p;
+ return true;
+ } },
+ CommandArgument{ "--build-generator-toolset", CommandArgument::Values::One,
+ [this](std::string const& t) -> bool {
+ this->Impl->BuildAndTest.BuildGeneratorToolset = t;
+ return true;
+ } },
+ CommandArgument{ "--build-project", CommandArgument::Values::One,
+ [this](std::string const& p) -> bool {
+ this->Impl->BuildAndTest.BuildProject = p;
+ return true;
+ } },
+ CommandArgument{ "--build-makeprogram", CommandArgument::Values::One,
+ [this](std::string const& p) -> bool {
+ this->Impl->BuildAndTest.BuildMakeProgram = p;
+ return true;
+ } },
+ CommandArgument{ "--build-config-sample", CommandArgument::Values::One,
+ [this](std::string const& s) -> bool {
+ this->Impl->BuildAndTest.ConfigSample = s;
+ return true;
+ } },
+ CommandArgument{ "-SP", CommandArgument::Values::One, dashSP },
+ CommandArgument{ "--script-new-process", CommandArgument::Values::One,
+ dashSP },
+ CommandArgument{ "-SR", CommandArgument::Values::One, dashSR },
+ CommandArgument{ "--script-run", CommandArgument::Values::One, dashSR },
+ CommandArgument{ "-S", CommandArgument::Values::One, dash_S },
+ CommandArgument{ "--script", CommandArgument::Values::One, dash_S },
+ CommandArgument{ "-F", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->Failover = true;
+ return true;
+ } },
+ CommandArgument{
+ "-j", CommandArgument::Values::ZeroOrOne,
+ [&dashJ](std::string const& j) -> bool { return dashJ("-j"_s, j); } },
+ CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne,
+ [&dashJ](std::string const& j) -> bool {
+ return dashJ("--parallel"_s, j);
+ } },
+ CommandArgument{ "-j", CommandArgument::Values::One,
+ CommandArgument::RequiresSeparator::No,
+ [this](std::string const& j) -> bool {
+ // The value must be a non-negative integer.
+ unsigned long plevel = 0;
+ if (!cmStrToULong(j, &plevel)) {
+ cmSystemTools::Error(
+ cmStrCat("'-j' given invalid value '", j, '\''));
+ return false;
+ }
+ this->SetParallelLevel(plevel);
+ this->Impl->ParallelLevelSetInCli = true;
+ return true;
+ } },
+ CommandArgument{
+ "--repeat-until-fail", "'--repeat-until-fail' requires an argument",
+ CommandArgument::Values::One,
+ [this](std::string const& r) -> bool {
+ if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
+ cmSystemTools::Error("At most one '--repeat' option may be used.");
+ return false;
+ }
+ long repeat = 1;
+ if (!cmStrToLong(r, &repeat)) {
+ cmSystemTools::Error(cmStrCat(
+ "'--repeat-until-fail' given non-integer value '", r, '\''));
+ return false;
+ }
+ this->Impl->RepeatCount = static_cast<int>(repeat);
+ if (repeat > 1) {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
+ }
+ return true;
+ } },
+ CommandArgument{
+ "--repeat", CommandArgument::Values::One,
+ [this](std::string const& r) -> bool {
+ if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
+ cmSystemTools::Error("At most one '--repeat' option may be used.");
+ return false;
+ }
+ cmsys::RegularExpression repeatRegex(
+ "^(until-fail|until-pass|after-timeout):([0-9]+)$");
+ if (repeatRegex.find(r)) {
+ std::string const& count = repeatRegex.match(2);
+ unsigned long n = 1;
+ cmStrToULong(count, &n); // regex guarantees success
+ this->Impl->RepeatCount = static_cast<int>(n);
+ if (this->Impl->RepeatCount > 1) {
+ std::string const& mode = repeatRegex.match(1);
+ if (mode == "until-fail") {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
+ } else if (mode == "until-pass") {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilPass;
+ } else if (mode == "after-timeout") {
+ this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout;
+ }
+ }
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("'--repeat' given invalid value '", r, '\''));
+ return false;
+ }
+ return true;
+ } },
+ CommandArgument{ "--test-load", CommandArgument::Values::One,
+ [this](std::string const& l) -> bool {
+ unsigned long load;
+ if (cmStrToULong(l, &load)) {
+ this->SetTestLoad(load);
+ } else {
+ cmCTestLog(
+ this, WARNING,
+ "Invalid value for 'Test Load' : " << l << '\n');
+ }
+ return true;
+ } },
+ CommandArgument{ "--no-compress-output", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->CompressTestOutput = false;
+ return true;
+ } },
+ CommandArgument{ "--print-labels", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->PrintLabels = true;
+ return true;
+ } },
+ CommandArgument{ "--http1.0", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->UseHTTP10 = true;
+ return true;
+ } },
+ CommandArgument{ "--timeout", CommandArgument::Values::One,
+ [this](std::string const& t) -> bool {
+ auto timeout = cmDuration(atof(t.c_str()));
+ this->Impl->GlobalTimeout = timeout;
+ return true;
+ } },
+ CommandArgument{ "--stop-time", CommandArgument::Values::One,
+ [this](std::string const& t) -> bool {
+ this->SetStopTime(t);
+ return true;
+ } },
+ CommandArgument{ "--stop-on-failure", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->StopOnFailure = true;
+ return true;
+ } },
+ CommandArgument{ "-C", CommandArgument::Values::One, dashC },
+ CommandArgument{ "--build-config", CommandArgument::Values::One, dashC },
+ CommandArgument{ "--debug", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->Debug = true;
+ return true;
+ } },
+ CommandArgument{ "--group", CommandArgument::Values::One, dashGroup },
+ // This is an undocumented / deprecated option.
+ // "Track" has been renamed to "Group".
+ CommandArgument{ "--track", CommandArgument::Values::One, dashGroup },
+ CommandArgument{ "--show-line-numbers", CommandArgument::Values::Zero,
+ [](std::string const&) -> bool {
+ // Silently ignore this never-documented and now-removed
+ // option.
+ return true;
+ } },
+ CommandArgument{ "--no-label-summary", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->LabelSummary = false;
+ return true;
+ } },
+ CommandArgument{ "--no-subproject-summary", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->SubprojectSummary = false;
+ return true;
+ } },
+ CommandArgument{ "--progress", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->TestProgressOutput = true;
+ return true;
+ } },
+ CommandArgument{ "-Q", CommandArgument::Values::Zero, dashQ },
+ CommandArgument{ "--quiet", CommandArgument::Values::Zero, dashQ },
+ CommandArgument{ "-V", CommandArgument::Values::Zero, dashV },
+ CommandArgument{ "--verbose", CommandArgument::Values::Zero, dashV },
+ CommandArgument{ "-VV", CommandArgument::Values::Zero, dashVV },
+ CommandArgument{ "--extra-verbose", CommandArgument::Values::Zero,
+ dashVV },
+ CommandArgument{ "--output-on-failure", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->OutputTestOutputOnTestFailure = true;
+ return true;
+ } },
+ CommandArgument{ "--test-output-size-passed", CommandArgument::Values::One,
+ [this](std::string const& sz) -> bool {
+ long outputSize;
+ if (cmStrToLong(sz, &outputSize)) {
+ this->Impl->TestOptions.OutputSizePassed =
+ static_cast<int>(outputSize);
+ } else {
+ cmCTestLog(
+ this, WARNING,
+ "Invalid value for '--test-output-size-passed': "
+ << sz << "\n");
+ }
+ return true;
+ } },
+ CommandArgument{ "--test-output-size-failed", CommandArgument::Values::One,
+ [this](std::string const& sz) -> bool {
+ long outputSize;
+ if (cmStrToLong(sz, &outputSize)) {
+ this->Impl->TestOptions.OutputSizeFailed =
+ static_cast<int>(outputSize);
+ } else {
+ cmCTestLog(
+ this, WARNING,
+ "Invalid value for '--test-output-size-failed': "
+ << sz << "\n");
+ }
+ return true;
+ } },
+ CommandArgument{
+ "--test-output-truncation", CommandArgument::Values::One,
+ [this](std::string const& mode) -> bool {
+ if (!SetTruncationMode(this->Impl->TestOptions.OutputTruncation,
+ mode)) {
+ cmSystemTools::Error(
+ cmStrCat("Invalid value for '--test-output-truncation': ", mode));
+ return false;
+ }
+ return true;
+ } },
+ CommandArgument{ "--show-only", CommandArgument::Values::ZeroOrOne,
+ [this](std::string const& format) -> bool {
+ this->Impl->ShowOnly = true;
+ // Check if a specific format is requested.
+ // Defaults to human readable text.
+ if (format == "json-v1") {
+ // Force quiet mode so the only output
+ // is the json object model.
+ this->Impl->Quiet = true;
+ this->Impl->OutputAsJson = true;
+ this->Impl->OutputAsJsonVersion = 1;
+ } else if (format == "human") {
+ } else if (!format.empty()) {
+ cmSystemTools::Error(
+ cmStrCat("'--show-only=' given unknown value '",
+ format, '\''));
+ return false;
+ }
+ return true;
+ } },
+ CommandArgument{ "-N", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->ShowOnly = true;
+ return true;
+ } },
+ CommandArgument{ "-O", CommandArgument::Values::One, dashO },
+ CommandArgument{ "--output-log", CommandArgument::Values::One, dashO },
+ CommandArgument{ "--tomorrow-tag", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->TomorrowTag = true;
+ return true;
+ } },
+ CommandArgument{ "--force-new-ctest-process",
+ CommandArgument::Values::Zero,
+ [](std::string const&) -> bool {
+ // Silently ignore now-removed option.
+ return true;
+ } },
+ CommandArgument{ "-W", CommandArgument::Values::One, dashW },
+ CommandArgument{ "--max-width", CommandArgument::Values::One, dashW },
+ CommandArgument{ "--interactive-debug-mode", CommandArgument::Values::One,
+ [this](std::string const& idm) -> bool {
+ this->Impl->InteractiveDebugMode = cmIsOn(idm);
+ return true;
+ } },
+ CommandArgument{ "--http-header", CommandArgument::Values::One,
+ [this](std::string const& h) -> bool {
+ this->Impl->CommandLineHttpHeaders.push_back(h);
+ return true;
+ } },
+ CommandArgument{ "--submit-index", CommandArgument::Values::One,
+ [this](std::string const& index) -> bool {
+ this->Impl->SubmitIndex = atoi(index.c_str());
+ if (this->Impl->SubmitIndex < 0) {
+ this->Impl->SubmitIndex = 0;
+ }
+ return true;
+ } },
+ CommandArgument{ "--overwrite", CommandArgument::Values::One,
+ [this](std::string const& opt) -> bool {
+ this->AddCTestConfigurationOverwrite(opt);
+ return true;
+ } },
+ CommandArgument{ "-A", CommandArgument::Values::One, dashA },
+ CommandArgument{ "--add-notes", CommandArgument::Values::One, dashA },
+ CommandArgument{ "--test-dir", "'--test-dir' requires an argument",
+ CommandArgument::Values::One,
+ [this](std::string const& dir) -> bool {
+ this->Impl->TestDir = dir;
+ return true;
+ } },
+ CommandArgument{ "--output-junit", CommandArgument::Values::One,
+ [this](std::string const& file) -> bool {
+ this->SetOutputJUnitFileName(file);
+ return true;
+ } },
+ CommandArgument{ "--no-tests", CommandArgument::Values::One,
+ [this](std::string const& action) -> bool {
+ if (action == "error"_s) {
+ this->Impl->NoTestsMode = cmCTest::NoTests::Error;
+ } else if (action == "ignore"_s) {
+ this->Impl->NoTestsMode = cmCTest::NoTests::Ignore;
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("'--no-tests=' given unknown value '",
+ action, '\''));
+ return false;
+ }
+ this->Impl->NoTestsModeSetInCli = true;
+ return true;
+ } },
+ CommandArgument{ "-I", CommandArgument::Values::One, dashI },
+ CommandArgument{ "--tests-information", CommandArgument::Values::One,
+ dashI },
+ CommandArgument{ "-U", CommandArgument::Values::One, dashU },
+ CommandArgument{ "--union", CommandArgument::Values::One, dashU },
+ CommandArgument{ "-R", CommandArgument::Values::One, dashR },
+ CommandArgument{ "--tests-regex", CommandArgument::Values::One, dashR },
+ CommandArgument{ "-E", CommandArgument::Values::One, dashE },
+ CommandArgument{ "--exclude-regex", CommandArgument::Values::One, dashE },
+ CommandArgument{ "-L", CommandArgument::Values::One, dashL },
+ CommandArgument{ "--label-regex", CommandArgument::Values::One, dashL },
+ CommandArgument{ "-LE", CommandArgument::Values::One, dashLE },
+ CommandArgument{ "--label-exclude", CommandArgument::Values::One, dashLE },
+ CommandArgument{ "-FA", CommandArgument::Values::One, dashFA },
+ CommandArgument{ "--fixture-exclude-any", CommandArgument::Values::One,
+ dashFA },
+ CommandArgument{ "-FS", CommandArgument::Values::One, dashFS },
+ CommandArgument{ "--fixture-exclude-setup", CommandArgument::Values::One,
+ dashFS },
+ CommandArgument{ "-FC", CommandArgument::Values::One, dashFC },
+ CommandArgument{ "--fixture-exclude-cleanup", CommandArgument::Values::One,
+ dashFC },
+ CommandArgument{ "--resource-spec-file", CommandArgument::Values::One,
+ [this](std::string const& file) -> bool {
+ this->Impl->TestOptions.ResourceSpecFile = file;
+ return true;
+ } },
+ CommandArgument{ "--tests-from-file", CommandArgument::Values::One,
+ [this](std::string const& file) -> bool {
+ this->Impl->TestOptions.TestListFile = file;
+ return true;
+ } },
+ CommandArgument{ "--exclude-from-file", CommandArgument::Values::One,
+ [this](std::string const& file) -> bool {
+ this->Impl->TestOptions.ExcludeTestListFile = file;
+ return true;
+ } },
+ CommandArgument{ "--schedule-random", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->TestOptions.ScheduleRandom = true;
+ return true;
+ } },
+ CommandArgument{ "--rerun-failed", CommandArgument::Values::Zero,
+ [this](std::string const&) -> bool {
+ this->Impl->TestOptions.RerunFailed = true;
+ return true;
+ } },
+ };
+
// process the command line arguments
for (size_t i = 1; i < args.size(); ++i) {
- // handle the simple commandline arguments
- std::string errormsg;
- bool validArg = this->HandleCommandLineArguments(i, args, errormsg);
- if (!validArg && !errormsg.empty()) {
- cmSystemTools::Error(errormsg);
- return 1;
- }
- std::string arg = args[i];
-
- // handle the script arguments -S -SR -SP
- validArg =
- validArg || this->HandleScriptArguments(i, args, SRArgumentSpecified);
-
- // --dashboard: handle a request for a dashboard
- if (this->CheckArgument(arg, "-D"_s, "--dashboard") &&
- i < args.size() - 1) {
- this->Impl->ProduceXML = true;
- i++;
- std::string targ = args[i];
- // AddTestsForDashboard parses the dashboard type and converts it
- // into the separate stages
- if (!this->AddTestsForDashboardType(targ)) {
- if (!this->AddVariableDefinition(targ)) {
- this->ErrorMessageUnknownDashDValue(targ);
- executeTests = false;
+ std::string const& arg = args[i];
+ bool matched = false;
+ for (auto const& m : arguments) {
+ if (m.matches(arg)) {
+ matched = true;
+ if (!m.parse(arg, i, args)) {
+ return 1;
}
- }
- validArg = true;
- }
-
- // If it's not exactly -D, but it starts with -D, then try to parse out
- // a variable definition from it, same as CMake does. Unsuccessful
- // attempts are simply ignored since previous ctest versions ignore
- // this too. (As well as many other unknown command line args.)
- //
- if (arg != "-D" && cmHasLiteralPrefix(arg, "-D")) {
- std::string input = arg.substr(2);
- this->AddVariableDefinition(input);
- validArg = true;
- }
-
- // --test-action: calls SetTest(<stage>, /*report=*/ false) to enable
- // the corresponding stage
- if (!this->HandleTestActionArgument(ctestExec, i, args, validArg)) {
- executeTests = false;
- }
-
- // --test-model: what type of test model
- if (!this->HandleTestModelArgument(ctestExec, i, args, validArg)) {
- executeTests = false;
- }
-
- // --extra-submit
- if (this->CheckArgument(arg, "--extra-submit"_s) && i < args.size() - 1) {
- this->Impl->ProduceXML = true;
- this->SetTest("Submit");
- i++;
- if (!this->SubmitExtraFiles(args[i])) {
- return 0;
- }
- validArg = true;
- }
-
- // --build-and-test options
- if (this->CheckArgument(arg, "--build-and-test"_s) &&
- i < args.size() - 1) {
- cmakeAndTest = true;
- validArg = true;
- }
-
- // --schedule-random
- if (this->CheckArgument(arg, "--schedule-random"_s)) {
- this->Impl->ScheduleType = "Random";
- validArg = true;
- }
-
- // pass the argument to all the handlers as well, but it may no longer be
- // set to what it was originally so I'm not sure this is working as
- // intended
- for (auto& handler : this->Impl->GetTestingHandlers()) {
- if (!handler->ProcessCommandLineArguments(arg, i, args, validArg)) {
- cmCTestLog(
- this, ERROR_MESSAGE,
- "Problem parsing command line arguments within a handler\n");
- return 0;
+ break;
}
}
-
- if (!validArg && cmHasLiteralPrefix(arg, "-") &&
+ if (!matched && arg == "--build-options"_s) {
+ matched = true;
+ while (i + 1 < args.size() && args[i + 1] != "--build-target"_s &&
+ args[i + 1] != "--test-command"_s) {
+ ++i;
+ this->Impl->BuildAndTest.BuildOptions.emplace_back(args[i]);
+ }
+ }
+ if (!matched && arg == "--test-command"_s && i + 1 < args.size()) {
+ matched = true;
+ ++i;
+ this->Impl->BuildAndTest.TestCommand = args[i];
+ while (i + 1 < args.size()) {
+ ++i;
+ this->Impl->BuildAndTest.TestCommandArgs.emplace_back(args[i]);
+ }
+ }
+ if (!matched && cmHasLiteralPrefix(arg, "-") &&
!cmHasLiteralPrefix(arg, "--preset")) {
cmSystemTools::Error(cmStrCat("Unknown argument: ", arg));
cmSystemTools::Error("Run 'ctest --help' for all supported options.");
return 1;
}
- } // the close of the for argument loop
+ }
// handle CTEST_PARALLEL_LEVEL environment variable
if (!this->Impl->ParallelLevelSetInCli) {
@@ -2872,157 +2626,111 @@
// now what should cmake do? if --build-and-test was specified then
// we run the build and test handler and return
if (cmakeAndTest) {
- return this->RunCMakeAndTest(output);
+ return this->RunCMakeAndTest();
}
- if (executeTests) {
- return this->ExecuteTests();
+ // -S, -SP, and/or -SP was specified
+ if (!runScripts.empty()) {
+ return this->RunScripts(runScripts);
}
- return 1;
+ // -D, -T, and/or -M was specified
+ if (processSteps) {
+ return this->ProcessSteps();
+ }
+
+ return this->ExecuteTests();
}
-bool cmCTest::HandleTestActionArgument(const char* ctestExec, size_t& i,
- const std::vector<std::string>& args,
- bool& validArg)
+int cmCTest::RunScripts(
+ std::vector<std::pair<std::string, bool>> const& scripts)
{
- bool success = true;
- std::string const& arg = args[i];
- if (this->CheckArgument(arg, "-T"_s, "--test-action") &&
- (i < args.size() - 1)) {
- validArg = true;
- this->Impl->ProduceXML = true;
- i++;
- if (!this->SetTest(args[i], false)) {
- success = false;
- cmCTestLog(this, ERROR_MESSAGE,
- "CTest -T called with incorrect option: " << args[i] << '\n');
- /* clang-format off */
- cmCTestLog(this, ERROR_MESSAGE,
- "Available options are:\n"
- " " << ctestExec << " -T all\n"
- " " << ctestExec << " -T start\n"
- " " << ctestExec << " -T update\n"
- " " << ctestExec << " -T configure\n"
- " " << ctestExec << " -T build\n"
- " " << ctestExec << " -T test\n"
- " " << ctestExec << " -T coverage\n"
- " " << ctestExec << " -T memcheck\n"
- " " << ctestExec << " -T notes\n"
- " " << ctestExec << " -T submit\n");
- /* clang-format on */
- }
+ if (this->Impl->ExtraVerbose) {
+ cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl);
}
- return success;
-}
-bool cmCTest::HandleTestModelArgument(const char* ctestExec, size_t& i,
- const std::vector<std::string>& args,
- bool& validArg)
-{
- bool success = true;
- std::string const& arg = args[i];
- if (this->CheckArgument(arg, "-M"_s, "--test-model") &&
- (i < args.size() - 1)) {
- validArg = true;
- i++;
- std::string const& str = args[i];
- if (cmSystemTools::LowerCase(str) == "nightly"_s) {
- this->SetTestModel(cmCTest::NIGHTLY);
- } else if (cmSystemTools::LowerCase(str) == "continuous"_s) {
- this->SetTestModel(cmCTest::CONTINUOUS);
- } else if (cmSystemTools::LowerCase(str) == "experimental"_s) {
- this->SetTestModel(cmCTest::EXPERIMENTAL);
- } else {
- success = false;
- cmCTestLog(this, ERROR_MESSAGE,
- "CTest -M called with incorrect option: " << str << '\n');
- /* clang-format off */
- cmCTestLog(this, ERROR_MESSAGE,
- "Available options are:\n"
- " " << ctestExec << " -M Continuous\n"
- " " << ctestExec << " -M Experimental\n"
- " " << ctestExec << " -M Nightly\n");
- /* clang-format on */
- }
+ auto ch = cm::make_unique<cmCTestScriptHandler>(this);
+ for (auto const& script : scripts) {
+ ch->AddConfigurationScript(script.first, script.second);
}
- return success;
+
+ int res = ch->ProcessHandler();
+ if (res != 0) {
+ cmCTestLog(this, DEBUG,
+ "running script failing returning: " << res << std::endl);
+ }
+
+ return res;
}
int cmCTest::ExecuteTests()
{
- int res;
- // call process directory
- if (this->Impl->RunConfigurationScript) {
- if (this->Impl->ExtraVerbose) {
- cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl);
- }
- for (auto& handler : this->Impl->GetTestingHandlers()) {
- handler->SetVerbose(this->Impl->ExtraVerbose);
- handler->SetSubmitIndex(this->Impl->SubmitIndex);
- }
- this->GetScriptHandler()->SetVerbose(this->Impl->Verbose);
- res = this->GetScriptHandler()->ProcessHandler();
- if (res != 0) {
- cmCTestLog(this, DEBUG,
- "running script failing returning: " << res << std::endl);
- }
+ this->Impl->ExtraVerbose = this->Impl->Verbose;
+ this->Impl->Verbose = true;
+ const std::string currDir = cmSystemTools::GetLogicalWorkingDirectory();
+ std::string workDir = currDir;
+ if (!this->Impl->TestDir.empty()) {
+ workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir);
+ }
+
+ cmWorkingDirectory changeDir(workDir);
+ if (changeDir.Failed()) {
+ cmCTestLog(this, ERROR_MESSAGE, changeDir.GetError() << std::endl);
+ return 1;
+ }
+
+ cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+ if (!this->Impl->InteractiveDebugMode) {
+ this->BlockTestErrorDiagnostics();
} else {
- // What is this? -V seems to be the same as -VV,
- // and Verbose is always on in this case
- this->Impl->ExtraVerbose = this->Impl->Verbose;
- this->Impl->Verbose = true;
- for (auto& handler : this->Impl->GetTestingHandlers()) {
- handler->SetVerbose(this->Impl->Verbose);
- handler->SetSubmitIndex(this->Impl->SubmitIndex);
- }
+ cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1");
+ }
- const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
- std::string workDir = currDir;
- if (!this->Impl->TestDir.empty()) {
- workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir);
- }
+ this->Impl->BinaryDir = workDir;
+ cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir);
- if (currDir != workDir) {
- if (!this->TryToChangeDirectory(workDir)) {
- return 1;
- }
- }
+ this->UpdateCTestConfiguration();
- if (!this->Initialize(workDir, nullptr)) {
- res = 12;
+ cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+
+ cmCTestTestHandler handler(this);
+
+ {
+ cmake cm(cmake::RoleScript, cmState::CTest);
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator gg(&cm);
+ cmMakefile mf(&gg, cm.GetCurrentSnapshot());
+ this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf);
+ handler.PopulateCustomVectors(&mf);
+ }
+
+ handler.SetVerbose(this->Impl->Verbose);
+ if (handler.ProcessHandler() < 0) {
+ cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest\n");
+ if (!this->Impl->OutputTestOutputOnTestFailure) {
+ const std::string lastTestLog =
+ this->GetBinaryDir() + "/Testing/Temporary/LastTest.log";
cmCTestLog(this, ERROR_MESSAGE,
- "Problem initializing the dashboard." << std::endl);
- } else {
- res = this->ProcessSteps();
+ "Output from these tests are in: " << lastTestLog << '\n');
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Use \"--rerun-failed --output-on-failure\" to re-run the "
+ "failed cases verbosely.\n");
}
- this->Finalize();
+ return cmCTest::TEST_ERRORS;
+ }
- if (currDir != workDir) {
- cmSystemTools::ChangeDirectory(currDir);
- }
- }
- if (res != 0) {
- cmCTestLog(this, DEBUG,
- "Running a test(s) failed returning : " << res << std::endl);
- }
- return res;
+ return 0;
}
-int cmCTest::RunCMakeAndTest(std::string* output)
+int cmCTest::RunCMakeAndTest()
{
- this->Impl->Verbose = true;
- cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler();
- int retv = handler->ProcessHandler();
- *output = handler->GetOutput();
+ int retv = this->Impl->BuildAndTest.Run();
#ifndef CMAKE_BOOTSTRAP
cmDynamicLoader::FlushCache();
#endif
- if (retv != 0) {
- cmCTestLog(this, DEBUG,
- "build and test failing returning: " << retv << std::endl);
- }
return retv;
}
@@ -3094,17 +2802,25 @@
this->Impl->ScheduleType = type;
}
-int cmCTest::ReadCustomConfigurationFileTree(const std::string& dir,
- cmMakefile* mf)
+void cmCTest::ReadCustomConfigurationFileTree(const std::string& dir,
+ cmMakefile* mf)
{
- bool found = false;
cmCTestLog(this, DEBUG,
"* Read custom CTest configuration directory: " << dir
<< std::endl);
- std::string fname = cmStrCat(dir, "/CTestCustom.cmake");
- cmCTestLog(this, DEBUG, "* Check for file: " << fname << std::endl);
- if (cmSystemTools::FileExists(fname)) {
+ auto const fname = [this, &dir]() -> std::string {
+ for (char const* ext : { ".cmake", ".ctest" }) {
+ std::string path = cmStrCat(dir, "/CTestCustom", ext);
+ cmCTestLog(this, DEBUG, "* Check for file: " << path << std::endl);
+ if (cmSystemTools::FileExists(path)) {
+ return path;
+ }
+ }
+ return "";
+ }();
+
+ if (!fname.empty()) {
cmCTestLog(this, DEBUG,
"* Read custom CTest configuration file: " << fname
<< std::endl);
@@ -3116,43 +2832,10 @@
"Problem reading custom configuration: " << fname
<< std::endl);
}
- found = true;
if (erroroc) {
cmSystemTools::SetErrorOccurred();
}
}
-
- std::string rexpr = cmStrCat(dir, "/CTestCustom.ctest");
- cmCTestLog(this, DEBUG, "* Check for file: " << rexpr << std::endl);
- if (!found && cmSystemTools::FileExists(rexpr)) {
- cmsys::Glob gl;
- gl.RecurseOn();
- gl.FindFiles(rexpr);
- std::vector<std::string>& files = gl.GetFiles();
- for (const std::string& file : files) {
- cmCTestLog(this, DEBUG,
- "* Read custom CTest configuration file: " << file
- << std::endl);
- if (!mf->ReadListFile(file) || cmSystemTools::GetErrorOccurredFlag()) {
- cmCTestLog(this, ERROR_MESSAGE,
- "Problem reading custom configuration: " << file
- << std::endl);
- }
- }
- found = true;
- }
-
- if (found) {
- for (auto& handler : this->Impl->GetNamedTestingHandlers()) {
- cmCTestLog(this, DEBUG,
- "* Read custom CTest configuration vectors for handler: "
- << handler.first << " (" << handler.second << ")"
- << std::endl);
- handler.second->PopulateCustomVectors(mf);
- }
- }
-
- return 1;
}
void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def,
@@ -3183,10 +2866,9 @@
std::string cmCTest::GetShortPathToFile(const std::string& cfname)
{
- const std::string& sourceDir = cmSystemTools::CollapseFullPath(
- this->GetCTestConfiguration("SourceDirectory"));
- const std::string& buildDir = cmSystemTools::CollapseFullPath(
- this->GetCTestConfiguration("BuildDirectory"));
+ const std::string& sourceDir =
+ this->GetCTestConfiguration("SourceDirectory");
+ const std::string& buildDir = this->GetCTestConfiguration("BuildDirectory");
std::string fname = cmSystemTools::CollapseFullPath(cfname);
// Find relative paths to both directories
@@ -3409,10 +3091,14 @@
return this->Impl->ExtraVerbose;
}
-void cmCTest::SetStreams(std::ostream* out, std::ostream* err)
+int cmCTest::GetSubmitIndex() const
{
- this->Impl->StreamOut = out;
- this->Impl->StreamErr = err;
+ return this->Impl->SubmitIndex;
+}
+
+bool cmCTest::GetInteractiveDebugMode() const
+{
+ return this->Impl->InteractiveDebugMode;
}
bool cmCTest::GetLabelSummary() const
@@ -3460,6 +3146,16 @@
return this->Impl->BuildID;
}
+cmCTestTestOptions const& cmCTest::GetTestOptions() const
+{
+ return this->Impl->TestOptions;
+}
+
+std::vector<std::string> cmCTest::GetCommandLineHttpHeaders() const
+{
+ return this->Impl->CommandLineHttpHeaders;
+}
+
void cmCTest::AddSubmitFile(Part part, const std::string& name)
{
this->Impl->Parts[part].SubmitFiles.emplace_back(name);
@@ -3520,6 +3216,81 @@
return true;
}
+void cmCTest::SetCMakeVariables(cmMakefile& mf)
+{
+ auto set = [&](char const* cmake_var, char const* ctest_opt) {
+ std::string val = this->GetCTestConfiguration(ctest_opt);
+ if (!val.empty()) {
+ cmCTestOptionalLog(
+ this, HANDLER_VERBOSE_OUTPUT,
+ "SetCMakeVariable:" << cmake_var << ":" << val << std::endl, false);
+ mf.AddDefinition(cmake_var, val);
+ }
+ };
+
+ set("CTEST_SITE", "Site");
+ set("CTEST_BUILD_NAME", "BuildName");
+ set("CTEST_NIGHTLY_START_TIME", "NightlyStartTime");
+ set("CTEST_SOURCE_DIRECTORY", "SourceDirectory");
+ set("CTEST_BINARY_DIRECTORY", "BuildDirectory");
+
+ // CTest Update Step
+ set("CTEST_UPDATE_COMMAND", "UpdateCommand");
+ set("CTEST_UPDATE_OPTIONS", "UpdateOptions");
+ set("CTEST_UPDATE_TYPE", "UpdateType");
+ set("CTEST_CVS_COMMAND", "CVSCommand");
+ set("CTEST_CVS_UPDATE_OPTIONS", "CVSUpdateOptions");
+ set("CTEST_SVN_COMMAND", "SVNCommand");
+ set("CTEST_SVN_UPDATE_OPTIONS", "SVNUpdateOptions");
+ set("CTEST_SVN_OPTIONS", "SVNOptions");
+ set("CTEST_BZR_COMMAND", "BZRCommand");
+ set("CTEST_BZR_UPDATE_OPTIONS", "BZRUpdateOptions");
+ set("CTEST_GIT_COMMAND", "GITCommand");
+ set("CTEST_GIT_UPDATE_OPTIONS", "GITUpdateOptions");
+ set("CTEST_GIT_INIT_SUBMODULES", "GITInitSubmodules");
+ set("CTEST_GIT_UPDATE_CUSTOM", "GITUpdateCustom");
+ set("CTEST_UPDATE_VERSION_ONLY", "UpdateVersionOnly");
+ set("CTEST_UPDATE_VERSION_OVERRIDE", "UpdateVersionOverride");
+ set("CTEST_HG_COMMAND", "HGCommand");
+ set("CTEST_HG_UPDATE_OPTIONS", "HGUpdateOptions");
+ set("CTEST_P4_COMMAND", "P4Command");
+ set("CTEST_P4_UPDATE_CUSTOM", "P4UpdateCustom");
+ set("CTEST_P4_UPDATE_OPTIONS", "P4UpdateOptions");
+ set("CTEST_P4_CLIENT", "P4Client");
+ set("CTEST_P4_OPTIONS", "P4Options");
+
+ // CTest Configure Step
+ set("CTEST_CONFIGURE_COMMAND", "ConfigureCommand");
+ set("CTEST_LABELS_FOR_SUBPROJECTS", "LabelsForSubprojects");
+
+ // CTest Build Step
+ set("CTEST_BUILD_COMMAND", "MakeCommand");
+ set("CTEST_USE_LAUNCHERS", "UseLaunchers");
+
+ // CTest Coverage Step
+ set("CTEST_COVERAGE_COMMAND", "CoverageCommand");
+ set("CTEST_COVERAGE_EXTRA_FLAGS", "CoverageExtraFlags");
+
+ // CTest MemCheck Step
+ set("CTEST_MEMORYCHECK_TYPE", "MemoryCheckType");
+ set("CTEST_MEMORYCHECK_SANITIZER_OPTIONS", "MemoryCheckSanitizerOptions");
+ set("CTEST_MEMORYCHECK_COMMAND", "MemoryCheckCommand");
+ set("CTEST_MEMORYCHECK_COMMAND_OPTIONS", "MemoryCheckCommandOptions");
+ set("CTEST_MEMORYCHECK_SUPPRESSIONS_FILE", "MemoryCheckSuppressionFile");
+
+ // CTest Submit Step
+ set("CTEST_SUBMIT_URL", "SubmitURL");
+ set("CTEST_DROP_METHOD", "DropMethod");
+ set("CTEST_DROP_SITE_USER", "DropSiteUser");
+ set("CTEST_DROP_SITE_PASSWORD", "DropSitePassword");
+ set("CTEST_DROP_SITE", "DropSite");
+ set("CTEST_DROP_LOCATION", "DropLocation");
+ set("CTEST_TLS_VERIFY", "TLSVerify");
+ set("CTEST_TLS_VERSION", "TLSVersion");
+ set("CTEST_CURL_OPTIONS", "CurlOptions");
+ set("CTEST_SUBMIT_INACTIVITY_TIMEOUT", "SubmitInactivityTimeout");
+}
+
bool cmCTest::RunCommand(std::vector<std::string> const& args,
std::string* stdOut, std::string* stdErr, int* retVal,
const char* dir, cmDuration timeout,
@@ -3649,7 +3420,7 @@
void cmCTest::SetOutputJUnitFileName(const std::string& name)
{
- this->Impl->TestHandler.SetJUnitXMLFileName(name);
+ this->Impl->TestOptions.JUnitXMLFileName = name;
// Turn test output compression off.
// This makes it easier to include test output in the resulting
// JUnit XML report.
@@ -3663,20 +3434,11 @@
"HANDLER_TEST_PROGRESS_OUTPUT",
"HANDLER_VERBOSE_OUTPUT",
"WARNING",
- "ERROR_MESSAGE",
- nullptr };
+ "ERROR_MESSAGE" };
-#define cmCTestLogOutputFileLine(stream) \
- do { \
- if (this->Impl->ShowLineNumbers) { \
- (stream) << std::endl << file << ":" << line << " "; \
- } \
- } while (false)
-
-void cmCTest::Log(int logType, const char* file, int line, const char* msg,
- bool suppress)
+void cmCTest::Log(LogType logType, std::string msg, bool suppress)
{
- if (!msg || !*msg) {
+ if (msg.empty()) {
return;
}
if (suppress && logType != cmCTest::ERROR_MESSAGE) {
@@ -3696,49 +3458,38 @@
display = false;
}
if (display) {
- cmCTestLogOutputFileLine(*this->Impl->OutputLogFile);
- if (logType != this->Impl->OutputLogFileLastTag) {
- *this->Impl->OutputLogFile << "[";
- if (logType >= OTHER || logType < 0) {
- *this->Impl->OutputLogFile << "OTHER";
- } else {
- *this->Impl->OutputLogFile << cmCTestStringLogType[logType];
- }
- *this->Impl->OutputLogFile << "] " << std::endl;
+ if (this->Impl->OutputLogFileLastTag &&
+ logType != *this->Impl->OutputLogFileLastTag) {
+ *this->Impl->OutputLogFile << "[" << cmCTestStringLogType[logType]
+ << "] " << std::endl;
}
*this->Impl->OutputLogFile << msg << std::flush;
- if (logType != this->Impl->OutputLogFileLastTag) {
+ if (this->Impl->OutputLogFileLastTag &&
+ logType != *this->Impl->OutputLogFileLastTag) {
*this->Impl->OutputLogFile << std::endl;
this->Impl->OutputLogFileLastTag = logType;
}
}
}
if (!this->Impl->Quiet) {
- std::ostream& out = *this->Impl->StreamOut;
- std::ostream& err = *this->Impl->StreamErr;
-
if (logType == HANDLER_TEST_PROGRESS_OUTPUT) {
if (this->Impl->TestProgressOutput) {
- cmCTestLogOutputFileLine(out);
if (this->Impl->FlushTestProgressLine) {
printf("\r");
this->Impl->FlushTestProgressLine = false;
- out.flush();
+ std::cout.flush();
}
- std::string msg_str{ msg };
- auto const lineBreakIt = msg_str.find('\n');
- if (lineBreakIt != std::string::npos) {
+ if (msg.find('\n') != std::string::npos) {
this->Impl->FlushTestProgressLine = true;
- msg_str.erase(std::remove(msg_str.begin(), msg_str.end(), '\n'),
- msg_str.end());
+ msg.erase(std::remove(msg.begin(), msg.end(), '\n'), msg.end());
}
- out << msg_str;
+ std::cout << msg;
#ifndef _WIN32
printf("\x1B[K"); // move caret to end
#endif
- out.flush();
+ std::cout.flush();
return;
}
logType = HANDLER_OUTPUT;
@@ -3747,41 +3498,29 @@
switch (logType) {
case DEBUG:
if (this->Impl->Debug) {
- cmCTestLogOutputFileLine(out);
- out << msg;
- out.flush();
+ std::cout << msg << std::flush;
}
break;
case OUTPUT:
case HANDLER_OUTPUT:
if (this->Impl->Debug || this->Impl->Verbose) {
- cmCTestLogOutputFileLine(out);
- out << msg;
- out.flush();
+ std::cout << msg << std::flush;
}
break;
case HANDLER_VERBOSE_OUTPUT:
if (this->Impl->Debug || this->Impl->ExtraVerbose) {
- cmCTestLogOutputFileLine(out);
- out << msg;
- out.flush();
+ std::cout << msg << std::flush;
}
break;
case WARNING:
- cmCTestLogOutputFileLine(err);
- err << msg;
- err.flush();
+ std::cerr << msg << std::flush;
break;
case ERROR_MESSAGE:
- cmCTestLogOutputFileLine(err);
- err << msg;
- err.flush();
+ std::cerr << msg << std::flush;
cmSystemTools::SetErrorOccurred();
break;
default:
- cmCTestLogOutputFileLine(out);
- out << msg;
- out.flush();
+ std::cout << msg << std::flush;
}
}
}
@@ -3795,9 +3534,21 @@
return "";
}
-cmDuration cmCTest::GetRemainingTimeAllowed()
+void cmCTest::SetTimeLimit(cmValue val)
{
- return this->GetScriptHandler()->GetRemainingTimeAllowed();
+ this->Impl->TimeLimit =
+ val ? cmDuration(atof(val->c_str())) : cmCTest::MaxDuration();
+}
+
+cmDuration cmCTest::GetElapsedTime() const
+{
+ return std::chrono::duration_cast<cmDuration>(
+ std::chrono::steady_clock::now() - this->Impl->StartTime);
+}
+
+cmDuration cmCTest::GetRemainingTimeAllowed() const
+{
+ return this->Impl->TimeLimit - this->GetElapsedTime();
}
cmDuration cmCTest::MaxDuration()
@@ -3805,20 +3556,6 @@
return cmDuration(1.0e7);
}
-void cmCTest::SetRunCurrentScript(bool value)
-{
- this->GetScriptHandler()->SetRunCurrentScript(value);
-}
-
-void cmCTest::OutputTestErrors(std::vector<char> const& process_output)
-{
- std::string test_outputs("\n*** Test Failed:\n");
- if (!process_output.empty()) {
- test_outputs.append(process_output.data(), process_output.size());
- }
- cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl);
-}
-
bool cmCTest::CompressString(std::string& str)
{
int ret;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 85f75fd..c8dc485 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -10,6 +10,7 @@
#include <memory>
#include <sstream>
#include <string>
+#include <utility>
#include <vector>
#include <cm/optional>
@@ -18,20 +19,12 @@
#include "cmDuration.h"
#include "cmProcessOutput.h"
-class cmCTestBuildHandler;
-class cmCTestBuildAndTestHandler;
-class cmCTestCoverageHandler;
-class cmCTestScriptHandler;
-class cmCTestTestHandler;
-class cmCTestUpdateHandler;
-class cmCTestConfigureHandler;
-class cmCTestMemCheckHandler;
-class cmCTestSubmitHandler;
-class cmCTestUploadHandler;
-class cmCTestStartCommand;
+class cmake;
class cmGeneratedFileStream;
class cmMakefile;
+class cmValue;
class cmXMLWriter;
+struct cmCTestTestOptions;
/** \class cmCTest
* \brief Represents a ctest invocation.
@@ -67,30 +60,16 @@
Part GetPartFromName(const std::string& name);
/** Process Command line arguments */
- int Run(std::vector<std::string>&, std::string* output = nullptr);
+ int Run(std::vector<std::string> const& args);
- /**
- * Initialize and finalize testing
- */
- bool InitializeFromCommand(cmCTestStartCommand* command);
- void Finalize();
+ /** Initialize a dashboard run in the given build tree. */
+ void Initialize(std::string const& binary_dir);
+
+ bool CreateNewTag(bool quiet);
+ bool ReadExistingTag(bool quiet);
/**
* Process the dashboard client steps.
- *
- * Steps are enabled using SetTest()
- *
- * The execution of the steps (or #Part) should look like this:
- *
- * /code
- * ctest foo;
- * foo.Initialize();
- * // Set some things on foo
- * foo.ProcessSteps();
- * foo.Finalize();
- * /endcode
- *
- * \sa Initialize(), Finalize(), Part, PartInfo, SetTest()
*/
int ProcessSteps();
@@ -140,7 +119,8 @@
void SetTestModel(int mode);
int GetTestModel() const;
- std::string GetTestModelString();
+ std::string GetTestModelString() const;
+ std::string GetTestGroupString() const;
static int GetTestModelFromString(const std::string& str);
static std::string CleanString(const std::string& str,
std::string::size_type spos = 0);
@@ -175,12 +155,15 @@
/** base64 encode a file */
std::string Base64EncodeFile(std::string const& file);
+ void SetTimeLimit(cmValue val);
+ cmDuration GetElapsedTime() const;
+
/**
* Return the time remaining that the script is allowed to run in
* seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
* not been set it returns a very large duration.
*/
- cmDuration GetRemainingTimeAllowed();
+ cmDuration GetRemainingTimeAllowed() const;
static cmDuration MaxDuration();
@@ -246,7 +229,7 @@
static std::string SafeBuildIdField(const std::string& value);
/** Start CTest XML output file */
- void StartXML(cmXMLWriter& xml, bool append);
+ void StartXML(cmXMLWriter& xml, cmake* cm, bool append);
/** End CTest XML output file */
void EndXML(cmXMLWriter& xml);
@@ -299,31 +282,6 @@
void SetProduceXML(bool v);
/**
- * Run command specialized for tests. Returns process status and retVal is
- * return value or exception. If environment is non-null, it is used to set
- * environment variables prior to running the test. After running the test,
- * environment variables are restored to their previous values.
- */
- bool RunTest(const std::vector<std::string>& args, std::string* output,
- int* retVal, std::ostream* logfile, cmDuration testTimeOut,
- std::vector<std::string>* environment,
- Encoding encoding = cmProcessOutput::Auto);
-
- /**
- * Get the handler object
- */
- cmCTestBuildHandler* GetBuildHandler();
- cmCTestBuildAndTestHandler* GetBuildAndTestHandler();
- cmCTestCoverageHandler* GetCoverageHandler();
- cmCTestScriptHandler* GetScriptHandler();
- cmCTestTestHandler* GetTestHandler();
- cmCTestUpdateHandler* GetUpdateHandler();
- cmCTestConfigureHandler* GetConfigureHandler();
- cmCTestMemCheckHandler* GetMemCheckHandler();
- cmCTestSubmitHandler* GetSubmitHandler();
- cmCTestUploadHandler* GetUploadHandler();
-
- /**
* Set the CTest variable from CMake variable
*/
bool SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
@@ -331,6 +289,11 @@
const std::string& cmake_var,
bool suppress = false);
+ /**
+ * Set CMake variables from CTest Options
+ */
+ void SetCMakeVariables(cmMakefile& mf);
+
/** Decode a URL to the original string. */
static std::string DecodeURL(const std::string&);
@@ -348,7 +311,7 @@
void AddCTestConfigurationOverwrite(const std::string& encstr);
/** Create XML file that contains all the notes specified */
- int GenerateNotesFile(std::vector<std::string> const& files);
+ int GenerateNotesFile(cmake* cm, std::vector<std::string> const& files);
/** Create XML file to indicate that build is complete */
int GenerateDoneFile();
@@ -367,9 +330,9 @@
void SetConfigType(const std::string& ct);
/** Various log types */
- enum
+ enum LogType
{
- DEBUG = 0,
+ DEBUG,
OUTPUT,
HANDLER_OUTPUT,
HANDLER_PROGRESS_OUTPUT,
@@ -377,12 +340,10 @@
HANDLER_VERBOSE_OUTPUT,
WARNING,
ERROR_MESSAGE,
- OTHER
};
/** Add log to the output */
- void Log(int logType, const char* file, int line, const char* msg,
- bool suppress = false);
+ void Log(LogType logType, std::string msg, bool suppress = false);
/** Color values */
enum class Color
@@ -409,7 +370,7 @@
/**
* Read the custom configuration files and apply them to the current ctest
*/
- int ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf);
+ void ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf);
std::vector<std::string>& GetInitialCommandLineArguments();
@@ -424,11 +385,11 @@
bool GetVerbose() const;
bool GetExtraVerbose() const;
+ int GetSubmitIndex() const;
- /** Direct process output to given streams. */
- void SetStreams(std::ostream* out, std::ostream* err);
+ void AddSiteProperties(cmXMLWriter& xml, cmake* cm);
- void AddSiteProperties(cmXMLWriter& xml);
+ bool GetInteractiveDebugMode() const;
bool GetLabelSummary() const;
bool GetSubprojectSummary() const;
@@ -462,33 +423,22 @@
void GenerateSubprojectsOutput(cmXMLWriter& xml);
std::vector<std::string> GetLabelsForSubprojects();
- void SetRunCurrentScript(bool value);
+ /** Reread the configuration file */
+ bool UpdateCTestConfiguration();
+
+ cmCTestTestOptions const& GetTestOptions() const;
+ std::vector<std::string> GetCommandLineHttpHeaders() const;
private:
- void SetPersistentOptionIfNotEmpty(const std::string& value,
- const std::string& optionName);
- void AddPersistentMultiOptionIfNotEmpty(const std::string& value,
- const std::string& optionName);
-
- int GenerateNotesFile(const std::string& files);
+ int GenerateNotesFile(cmake* cm, const std::string& files);
void BlockTestErrorDiagnostics();
- /**
- * Initialize a dashboard run in the given build tree. The "command"
- * argument is non-NULL when running from a command-driven (ctest_start)
- * dashboard script, and NULL when running from the CTest command
- * line. Note that a declarative dashboard script does not actually
- * call this method because it sets CTEST_COMMAND to drive a build
- * through the ctest command line.
- */
- int Initialize(const std::string& binary_dir, cmCTestStartCommand* command);
-
/** parse the option after -D and convert it into the appropriate steps */
- bool AddTestsForDashboardType(std::string& targ);
+ bool AddTestsForDashboardType(std::string const& targ);
/** read as "emit an error message for an unknown -D value" */
- void ErrorMessageUnknownDashDValue(std::string& val);
+ void ErrorMessageUnknownDashDValue(std::string const& val);
/** add a variable definition from a command line -D value */
bool AddVariableDefinition(const std::string& arg);
@@ -496,10 +446,6 @@
/** set command line arguments read from a test preset */
bool SetArgsFromPreset(const std::string& presetName, bool listPresets);
- /** parse and process most common command line arguments */
- bool HandleCommandLineArguments(size_t& i, std::vector<std::string>& args,
- std::string& errormsg);
-
#if !defined(_WIN32)
/** returns true iff the console supports progress output */
static bool ConsoleIsNotDumb();
@@ -511,40 +457,18 @@
/** returns true iff the console supports colored output */
static bool ColoredOutputSupportedByConsole();
- /** handle the -S -SP and -SR arguments */
- bool HandleScriptArguments(size_t& i, std::vector<std::string>& args,
- bool& SRArgumentSpecified);
-
- /** Reread the configuration file */
- bool UpdateCTestConfiguration();
-
/** Create note from files. */
- int GenerateCTestNotesOutput(cmXMLWriter& xml,
+ int GenerateCTestNotesOutput(cmXMLWriter& xml, cmake* cm,
std::vector<std::string> const& files);
/** Check if the argument is the one specified */
static bool CheckArgument(const std::string& arg, cm::string_view varg1,
const char* varg2 = nullptr);
- /** Output errors from a test */
- void OutputTestErrors(std::vector<char> const& process_output);
-
- /** Handle the --test-action command line argument */
- bool HandleTestActionArgument(const char* ctestExec, size_t& i,
- const std::vector<std::string>& args,
- bool& validArg);
-
- /** Handle the --test-model command line argument */
- bool HandleTestModelArgument(const char* ctestExec, size_t& i,
- const std::vector<std::string>& args,
- bool& validArg);
-
- int RunCMakeAndTest(std::string* output);
+ int RunCMakeAndTest();
+ int RunScripts(std::vector<std::pair<std::string, bool>> const& scripts);
int ExecuteTests();
- /** return true iff change directory was successful */
- bool TryToChangeDirectory(std::string const& dir);
-
struct Private;
std::unique_ptr<Private> Impl;
};
@@ -553,14 +477,12 @@
do { \
std::ostringstream cmCTestLog_msg; \
cmCTestLog_msg << msg; \
- (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__, \
- cmCTestLog_msg.str().c_str()); \
+ (ctSelf)->Log(cmCTest::logType, cmCTestLog_msg.str()); \
} while (false)
#define cmCTestOptionalLog(ctSelf, logType, msg, suppress) \
do { \
std::ostringstream cmCTestLog_msg; \
cmCTestLog_msg << msg; \
- (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__, \
- cmCTestLog_msg.str().c_str(), suppress); \
+ (ctSelf)->Log(cmCTest::logType, cmCTestLog_msg.str(), suppress); \
} while (false)
diff --git a/Source/cmCommand.cxx b/Source/cmCommand.cxx
deleted file mode 100644
index 0c2734e..0000000
--- a/Source/cmCommand.cxx
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCommand.h"
-
-#include <utility>
-
-#include "cmExecutionStatus.h"
-#include "cmMakefile.h"
-
-struct cmListFileArgument;
-
-void cmCommand::SetExecutionStatus(cmExecutionStatus* status)
-{
- this->Status = status;
- this->Makefile = &status->GetMakefile();
-}
-
-bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus& status)
-{
- std::vector<std::string> expandedArguments;
- if (!this->Makefile->ExpandArguments(args, expandedArguments)) {
- // There was an error expanding arguments. It was already
- // reported, so we can skip this command without error.
- return true;
- }
- return this->InitialPass(expandedArguments, status);
-}
-
-void cmCommand::SetError(const std::string& e)
-{
- this->Status->SetError(e);
-}
-
-cmLegacyCommandWrapper::cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd)
- : Command(std::move(cmd))
-{
-}
-
-cmLegacyCommandWrapper::cmLegacyCommandWrapper(
- cmLegacyCommandWrapper const& other)
- : Command(other.Command->Clone())
-{
-}
-
-cmLegacyCommandWrapper& cmLegacyCommandWrapper::operator=(
- cmLegacyCommandWrapper const& other)
-{
- this->Command = other.Command->Clone();
- return *this;
-}
-
-bool cmLegacyCommandWrapper::operator()(
- std::vector<cmListFileArgument> const& args, cmExecutionStatus& status) const
-{
- auto cmd = this->Command->Clone();
- cmd->SetExecutionStatus(&status);
- return cmd->InvokeInitialPass(args, status);
-}
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
deleted file mode 100644
index f5a5190..0000000
--- a/Source/cmCommand.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <memory>
-#include <string>
-#include <vector>
-
-class cmExecutionStatus;
-class cmMakefile;
-struct cmListFileArgument;
-
-/** \class cmCommand
- * \brief Superclass for all commands in CMake.
- *
- * cmCommand is the base class for all commands in CMake. A command
- * manifests as an entry in CMakeLists.txt and produces one or
- * more makefile rules. Commands are associated with a particular
- * makefile. This base class cmCommand defines the API for commands
- * to support such features as enable/disable, inheritance,
- * documentation, and construction.
- */
-class cmCommand
-{
-public:
- /**
- * Construct the command. By default it has no makefile.
- */
- cmCommand() = default;
-
- /**
- * Need virtual destructor to destroy real command type.
- */
- virtual ~cmCommand() = default;
-
- cmCommand(cmCommand const&) = delete;
- cmCommand& operator=(cmCommand const&) = delete;
-
- /**
- * Specify the makefile.
- */
- cmMakefile* GetMakefile() { return this->Makefile; }
-
- void SetExecutionStatus(cmExecutionStatus* s);
- cmExecutionStatus* GetExecutionStatus() { return this->Status; }
-
- /**
- * This is called by the cmMakefile when the command is first
- * encountered in the CMakeLists.txt file. It expands the command's
- * arguments and then invokes the InitialPass.
- */
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus& status);
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- virtual bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&) = 0;
-
- /**
- * This is a virtual constructor for the command.
- */
- virtual std::unique_ptr<cmCommand> Clone() = 0;
-
- /**
- * Set the error message
- */
- void SetError(const std::string& e);
-
-protected:
- cmMakefile* Makefile = nullptr;
-
-private:
- cmExecutionStatus* Status = nullptr;
-};
-
-class cmLegacyCommandWrapper
-{
-public:
- explicit cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd);
-
- cmLegacyCommandWrapper(cmLegacyCommandWrapper const& other);
- cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper const& other);
-
- cmLegacyCommandWrapper(cmLegacyCommandWrapper&&) = default;
- cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper&&) = default;
-
- bool operator()(std::vector<cmListFileArgument> const& args,
- cmExecutionStatus& status) const;
-
-private:
- std::unique_ptr<cmCommand> Command;
-};
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
index 003e972..15a1f70 100644
--- a/Source/cmCommandLineArgument.h
+++ b/Source/cmCommandLineArgument.h
@@ -2,7 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <cctype>
+
#include <cm/optional>
+#include <cm/string_view>
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -126,7 +129,7 @@
if (input.size() == this->Name.size()) {
auto nextValueIndex = index + 1;
if (nextValueIndex >= allArgs.size() ||
- allArgs[nextValueIndex][0] == '-') {
+ IsFlag(allArgs[nextValueIndex])) {
if (this->Type == Values::ZeroOrOne) {
parseState =
this->StoreCall(std::string{}, std::forward<CallState>(state)...)
@@ -153,8 +156,8 @@
}
} else if (this->Type == Values::Two) {
if (input.size() == this->Name.size()) {
- if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' ||
- allArgs[index + 2][0] == '-') {
+ if (index + 2 >= allArgs.size() || IsFlag(allArgs[index + 1]) ||
+ IsFlag(allArgs[index + 2])) {
parseState = ParseMode::ValueError;
} else {
index += 2;
@@ -169,12 +172,12 @@
if (input.size() == this->Name.size()) {
auto nextValueIndex = index + 1;
if (nextValueIndex >= allArgs.size() ||
- allArgs[nextValueIndex][0] == '-') {
+ IsFlag(allArgs[nextValueIndex])) {
parseState = ParseMode::ValueError;
} else {
std::string buffer = allArgs[nextValueIndex++];
while (nextValueIndex < allArgs.size() &&
- allArgs[nextValueIndex][0] != '-') {
+ !IsFlag(allArgs[nextValueIndex])) {
buffer = cmStrCat(buffer, ";", allArgs[nextValueIndex++]);
}
parseState =
@@ -281,4 +284,10 @@
}
return std::string(possible_value);
}
+
+ static bool IsFlag(cm::string_view arg)
+ {
+ return !arg.empty() && arg[0] == '-' &&
+ !(arg.size() >= 2 && std::isdigit(arg[1]));
+ }
};
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index d445128..39bd180 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -257,7 +257,7 @@
if (processingOption.match(1) == "LIBRARY_TYPE") {
featureAttributes.LibraryTypes.clear();
for (auto const& value :
- cmTokenize(processingOption.match(2), ","_s)) {
+ cmTokenize(processingOption.match(2), ',')) {
if (value == "STATIC") {
featureAttributes.LibraryTypes.emplace(
cmStateEnums::STATIC_LIBRARY);
@@ -292,7 +292,8 @@
}
} else if (processingOption.match(1) == "OVERRIDE") {
featureAttributes.Override.clear();
- auto values = cmTokenize(processingOption.match(2), ","_s);
+ std::vector<std::string> values =
+ cmTokenize(processingOption.match(2), ',');
featureAttributes.Override.insert(values.begin(), values.end());
}
} else {
@@ -372,40 +373,19 @@
case cmPolicies::OLD:
// rely on default initialization of the class
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- makefile->GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0156),
- target->GetBacktrace());
- CM_FALLTHROUGH;
case cmPolicies::NEW: {
// Policy 0179 applies only when policy 0156 is new
- switch (target->GetPolicyStatusCMP0179()) {
- case cmPolicies::WARN:
- if (!makefile->GetCMakeInstance()->GetIsInTryCompile() &&
- makefile->PolicyOptionalWarningEnabled(
- "CMAKE_POLICY_WARNING_CMP0179")) {
- makefile->GetCMakeInstance()->IssueMessage(
- MessageType::AUTHOR_WARNING,
- cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0179),
- "\nSince the policy is not set, static libraries "
- "de-duplication will keep the last occurrence of the "
- "static libraries."),
- target->GetBacktrace());
- }
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- makefile->GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0179),
- target->GetBacktrace());
- CM_FALLTHROUGH;
- case cmPolicies::NEW:
- break;
+ if (target->GetPolicyStatusCMP0179() == cmPolicies::WARN &&
+ !makefile->GetCMakeInstance()->GetIsInTryCompile() &&
+ makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0179")) {
+ makefile->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0179),
+ "\nSince the policy is not set, static libraries "
+ "de-duplication will keep the last occurrence of the "
+ "static libraries."),
+ target->GetBacktrace());
}
if (auto libProcessing = makefile->GetDefinition(cmStrCat(
@@ -630,7 +610,7 @@
, DebugMode(this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE") ||
this->Target->GetProperty("LINK_DEPENDS_DEBUG_MODE").IsOn())
, LinkLanguage(linkLanguage)
- , LinkType(CMP0003_ComputeLinkType(
+ , LinkType(ComputeLinkType(
this->Config, this->Makefile->GetCMakeInstance()->GetDebugConfigs()))
, Strategy(strategy)
@@ -677,13 +657,14 @@
*linkLibraryOverride, target->GetLocalGenerator(), config, target, &dag,
target, linkLanguage);
- auto overrideList = cmTokenize(overrideValue, ","_s);
+ std::vector<std::string> overrideList =
+ cmTokenize(overrideValue, ',', cmTokenizerMode::New);
if (overrideList.size() >= 2) {
auto const& feature = overrideList.front();
- for_each(overrideList.cbegin() + 1, overrideList.cend(),
- [this, &feature](std::string const& item) {
- this->LinkLibraryOverride.emplace(item, feature);
- });
+ std::for_each(overrideList.cbegin() + 1, overrideList.cend(),
+ [this, &feature](std::string const& item) {
+ this->LinkLibraryOverride.emplace(item, feature);
+ });
}
}
}
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index c2c210b..e28f491 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1850,8 +1850,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
return false;
}
@@ -1883,6 +1881,7 @@
// foo ==> -lfoo
// libfoo.a ==> -Wl,-Bstatic -lfoo
+ const cm::string_view LINKER{ "LINKER:" };
BT<std::string> const& item = entry.Item;
if (item.Value[0] == '-' || item.Value[0] == '$' || item.Value[0] == '`') {
@@ -1905,6 +1904,13 @@
this->Items.emplace_back(item, ItemIsPath::No);
return;
}
+ if (cmHasPrefix(item.Value, LINKER)) {
+ std::vector<BT<std::string>> linkerFlag{ 1, item };
+ this->Target->ResolveLinkerWrapper(linkerFlag, this->GetLinkLanguage(),
+ true);
+ this->Items.emplace_back(linkerFlag.front(), ItemIsPath::No);
+ return;
+ }
// Parse out the prefix, base, and suffix components of the
// library name. If the name matches that of a shared or static
@@ -2197,18 +2203,6 @@
case cmPolicies::NEW:
// NEW behavior will not get here.
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS: {
- std::ostringstream e;
- /* clang-format off */
- e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0008) << "\n"
- "Target \"" << this->Target->GetName() << "\" links to item\n"
- " " << item << "\n"
- "which is a full-path but not a valid library file name.";
- /* clang-format on */
- this->CMakeInstance->IssueMessage(MessageType::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- } break;
}
}
@@ -2240,15 +2234,6 @@
case cmPolicies::NEW:
// Should never happen due to assignment of OldLinkDirMode
return true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS: {
- std::ostringstream e;
- e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0003) << '\n';
- this->PrintLinkPolicyDiagnosis(e);
- this->CMakeInstance->IssueMessage(MessageType::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- return false;
- }
}
// Add the link directories for full path items.
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index e2faf94..bb5508c 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -364,8 +364,6 @@
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
issueMessage = true;
messageType = MessageType::FATAL_ERROR;
break;
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 5a2b33a..e5b079b 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -453,14 +453,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
return oldResult;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS: {
- errorString = "An argument named \"" + newArg.GetValue() +
- "\" appears in a conditional statement. " +
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0012);
- status = MessageType::FATAL_ERROR;
- break;
- }
case cmPolicies::NEW:
break;
}
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 4d739ff..9674bf2 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -769,12 +769,6 @@
case cmPolicies::OLD:
// OLD behavior is to do nothing.
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0066));
- CM_FALLTHROUGH;
case cmPolicies::NEW: {
// NEW behavior is to pass config-specific compiler flags.
std::string const cfg = !tcConfig.empty()
@@ -810,12 +804,6 @@
case cmPolicies::OLD:
// OLD behavior is to do nothing.
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0056));
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior is to pass linker flags.
{
@@ -910,6 +898,14 @@
? "OLD"
: "NEW");
+ /* Set the appropriate policy information for the LINKER: prefix expansion
+ */
+ fprintf(fout, "cmake_policy(SET CMP0181 %s)\n",
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0181) ==
+ cmPolicies::NEW
+ ? "NEW"
+ : "OLD");
+
// Workaround for -Wl,-headerpad_max_install_names issue until we can avoid
// adding that flag in the platform and compiler language files
fprintf(fout,
@@ -990,12 +986,6 @@
// OLD behavior is to not honor the language standard variables.
honorStandard = false;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0067));
- break;
case cmPolicies::NEW:
// NEW behavior is to honor the language standard variables.
// We already initialized honorStandard to true.
diff --git a/Source/cmDebuggerAdapter.cxx b/Source/cmDebuggerAdapter.cxx
index c2e0d4f..c3587a1 100644
--- a/Source/cmDebuggerAdapter.cxx
+++ b/Source/cmDebuggerAdapter.cxx
@@ -70,7 +70,7 @@
{
}
- inline void Notify()
+ void Notify()
{
std::unique_lock<std::mutex> lock(Mutex);
Count++;
@@ -78,7 +78,7 @@
Cv.notify_one();
}
- inline void Wait()
+ void Wait()
{
std::unique_lock<std::mutex> lock(Mutex);
while (Count == 0) {
@@ -148,6 +148,7 @@
SupportsVariableType = req.supportsVariableType.value(false);
dap::CMakeInitializeResponse response;
response.supportsConfigurationDoneRequest = true;
+ response.supportsValueFormattingOptions = true;
response.cmakeVersion.major = CMake_VERSION_MAJOR;
response.cmakeVersion.minor = CMake_VERSION_MINOR;
response.cmakeVersion.patch = CMake_VERSION_PATCH;
@@ -186,7 +187,7 @@
std::unique_lock<std::mutex> lock(Mutex);
cm::optional<dap::StackTraceResponse> response =
- ThreadManager->GetThreadStackTraceResponse(request.threadId);
+ ThreadManager->GetThreadStackTraceResponse(request);
if (response.has_value()) {
return response.value();
}
diff --git a/Source/cmDebuggerStackFrame.cxx b/Source/cmDebuggerStackFrame.cxx
index 789b0a5..89cdbc6 100644
--- a/Source/cmDebuggerStackFrame.cxx
+++ b/Source/cmDebuggerStackFrame.cxx
@@ -25,4 +25,10 @@
return this->Function.Line();
}
+std::vector<cmListFileArgument> const& cmDebuggerStackFrame::GetArguments()
+ const noexcept
+{
+ return this->Function.Arguments();
+}
+
} // namespace cmDebugger
diff --git a/Source/cmDebuggerStackFrame.h b/Source/cmDebuggerStackFrame.h
index f4e6612..2133bcd 100644
--- a/Source/cmDebuggerStackFrame.h
+++ b/Source/cmDebuggerStackFrame.h
@@ -7,8 +7,10 @@
#include <atomic>
#include <cstdint>
#include <string>
+#include <vector>
class cmListFileFunction;
+struct cmListFileArgument;
class cmMakefile;
namespace cmDebugger {
@@ -32,6 +34,7 @@
{
return this->Function;
}
+ std::vector<cmListFileArgument> const& GetArguments() const noexcept;
};
} // namespace cmDebugger
diff --git a/Source/cmDebuggerThread.cxx b/Source/cmDebuggerThread.cxx
index f7a1778..047dd2d 100644
--- a/Source/cmDebuggerThread.cxx
+++ b/Source/cmDebuggerThread.cxx
@@ -14,6 +14,7 @@
#include "cmDebuggerVariablesHelper.h"
#include "cmDebuggerVariablesManager.h"
#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
namespace cmDebugger {
@@ -117,8 +118,27 @@
}
dap::StackTraceResponse GetStackTraceResponse(
- std::shared_ptr<cmDebuggerThread> const& thread)
+ std::shared_ptr<cmDebuggerThread> const& thread,
+ dap::optional<dap::StackFrameFormat> format)
{
+ dap::boolean showParameters = false;
+ dap::boolean showParameterValues = false;
+ dap::boolean showLine = false;
+ if (format.has_value()) {
+ auto formatValue = format.value();
+ if (formatValue.parameters.has_value()) {
+ showParameters = formatValue.parameters.value();
+ }
+
+ if (formatValue.parameterValues.has_value()) {
+ showParameterValues = formatValue.parameterValues.value();
+ }
+
+ if (formatValue.line.has_value()) {
+ showLine = formatValue.line.value();
+ }
+ }
+
dap::StackTraceResponse response;
std::unique_lock<std::mutex> lock(thread->Mutex);
for (int i = static_cast<int>(thread->Frames.size()) - 1; i >= 0; --i) {
@@ -136,10 +156,29 @@
#endif
stackFrame.line = thread->Frames[i]->GetLine();
stackFrame.column = 1;
- stackFrame.name = thread->Frames[i]->GetFunction().OriginalName();
stackFrame.id = thread->Frames[i]->GetId();
stackFrame.source = source;
+ auto stackName = thread->Frames[i]->GetFunction().OriginalName();
+ if (showParameters) {
+ stackName.push_back('(');
+ if (showParameterValues && !thread->Frames[i]->GetArguments().empty()) {
+ for (auto const& arg : thread->Frames[i]->GetArguments()) {
+ stackName = cmStrCat(stackName, arg.Value, ", ");
+ }
+
+ stackName.erase(stackName.end() - 2, stackName.end());
+ }
+
+ stackName.push_back(')');
+ }
+
+ if (showLine) {
+ stackName =
+ cmStrCat(stackName, " Line: ", static_cast<int64_t>(stackFrame.line));
+ }
+
+ stackFrame.name = stackName;
response.stackFrames.push_back(stackFrame);
}
diff --git a/Source/cmDebuggerThread.h b/Source/cmDebuggerThread.h
index 65ee2cf..81664b5 100644
--- a/Source/cmDebuggerThread.h
+++ b/Source/cmDebuggerThread.h
@@ -23,6 +23,11 @@
class cmDebuggerVariablesManager;
}
+namespace dap {
+template <typename T>
+class optional;
+}
+
namespace cmDebugger {
class cmDebuggerThread
@@ -53,7 +58,8 @@
dap::VariablesResponse GetVariablesResponse(
dap::VariablesRequest const& request);
friend dap::StackTraceResponse GetStackTraceResponse(
- std::shared_ptr<cmDebuggerThread> const& thread);
+ std::shared_ptr<cmDebuggerThread> const& thread,
+ dap::optional<dap::StackFrameFormat> format);
};
} // namespace cmDebugger
diff --git a/Source/cmDebuggerThreadManager.cxx b/Source/cmDebuggerThreadManager.cxx
index 0eb443b..0f15b6b 100644
--- a/Source/cmDebuggerThreadManager.cxx
+++ b/Source/cmDebuggerThreadManager.cxx
@@ -6,6 +6,7 @@
#include <algorithm>
#include <cm3p/cppdap/protocol.h>
+#include <cm3p/cppdap/types.h>
#include "cmDebuggerThread.h"
@@ -30,18 +31,19 @@
}
cm::optional<dap::StackTraceResponse>
-cmDebuggerThreadManager::GetThreadStackTraceResponse(int64_t id)
+cmDebuggerThreadManager::GetThreadStackTraceResponse(
+ const dap::StackTraceRequest& request)
{
auto it = find_if(Threads.begin(), Threads.end(),
[&](const std::shared_ptr<cmDebuggerThread>& t) {
- return t->GetId() == id;
+ return t->GetId() == request.threadId;
});
if (it == Threads.end()) {
return {};
}
- return GetStackTraceResponse(*it);
+ return GetStackTraceResponse(*it, request.format);
}
} // namespace cmDebugger
diff --git a/Source/cmDebuggerThreadManager.h b/Source/cmDebuggerThreadManager.h
index 934cf85..6d27a5c 100644
--- a/Source/cmDebuggerThreadManager.h
+++ b/Source/cmDebuggerThreadManager.h
@@ -17,6 +17,7 @@
}
namespace dap {
+struct StackTraceRequest;
struct StackTraceResponse;
}
@@ -32,7 +33,7 @@
std::shared_ptr<cmDebuggerThread> StartThread(std::string const& name);
void EndThread(std::shared_ptr<cmDebuggerThread> const& thread);
cm::optional<dap::StackTraceResponse> GetThreadStackTraceResponse(
- std::int64_t id);
+ const dap::StackTraceRequest& request);
};
} // namespace cmDebugger
diff --git a/Source/cmDebuggerVariables.h b/Source/cmDebuggerVariables.h
index 753b811..0c4a416 100644
--- a/Source/cmDebuggerVariables.h
+++ b/Source/cmDebuggerVariables.h
@@ -102,22 +102,16 @@
std::shared_ptr<cmDebuggerVariablesManager> variablesManager,
std::string name, bool supportsVariableType,
std::function<std::vector<cmDebuggerVariableEntry>()> getKeyValuesFunc);
- inline int64_t GetId() const noexcept { return this->Id; }
- inline std::string GetName() const noexcept { return this->Name; }
- inline std::string GetValue() const noexcept { return this->Value; }
- inline void SetValue(std::string const& value) noexcept
- {
- this->Value = value;
- }
+ int64_t GetId() const noexcept { return this->Id; }
+ std::string GetName() const noexcept { return this->Name; }
+ std::string GetValue() const noexcept { return this->Value; }
+ void SetValue(std::string const& value) noexcept { this->Value = value; }
void AddSubVariables(std::shared_ptr<cmDebuggerVariables> const& variables);
- inline void SetIgnoreEmptyStringEntries(bool value) noexcept
+ void SetIgnoreEmptyStringEntries(bool value) noexcept
{
this->IgnoreEmptyStringEntries = value;
}
- inline void SetEnableSorting(bool value) noexcept
- {
- this->EnableSorting = value;
- }
+ void SetEnableSorting(bool value) noexcept { this->EnableSorting = value; }
virtual ~cmDebuggerVariables();
};
diff --git a/Source/cmDebuggerVariablesHelper.cxx b/Source/cmDebuggerVariablesHelper.cxx
index 6880eab..deaa3c2 100644
--- a/Source/cmDebuggerVariablesHelper.cxx
+++ b/Source/cmDebuggerVariablesHelper.cxx
@@ -39,8 +39,6 @@
{ cmPolicies::PolicyStatus::OLD, "OLD" },
{ cmPolicies::PolicyStatus::WARN, "WARN" },
{ cmPolicies::PolicyStatus::NEW, "NEW" },
- { cmPolicies::PolicyStatus::REQUIRED_IF_USED, "REQUIRED_IF_USED" },
- { cmPolicies::PolicyStatus::REQUIRED_ALWAYS, "REQUIRED_ALWAYS" }
};
return std::make_shared<cmDebuggerVariables>(
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index 17ec43b..408f19f 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -4,7 +4,6 @@
#include "cmDependsCompiler.h"
#include <algorithm>
-#include <iterator>
#include <map>
#include <string>
#include <unordered_set>
@@ -111,13 +110,9 @@
// copy depends for each target, except first one, which can be
// moved
for (auto index = entry.rules.size() - 1; index > 0; --index) {
- auto& rule_deps = dependencies[entry.rules[index]];
- rule_deps.insert(rule_deps.end(), depends.cbegin(),
- depends.cend());
+ dependencies[entry.rules[index]] = depends;
}
- auto& rule_deps = dependencies[entry.rules.front()];
- std::move(depends.cbegin(), depends.cend(),
- std::back_inserter(rule_deps));
+ dependencies[entry.rules.front()] = std::move(depends);
}
} else {
if (format == "msvc"_s) {
diff --git a/Source/cmDocumentationEntry.h b/Source/cmDocumentationEntry.h
index d971836..2a26ecd 100644
--- a/Source/cmDocumentationEntry.h
+++ b/Source/cmDocumentationEntry.h
@@ -17,7 +17,7 @@
}
#endif
- std::string Name = {};
- std::string Brief = {};
+ std::string Name;
+ std::string Brief;
char CustomNamePrefix = ' ';
};
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index b85b2f5..0c22259 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -5,175 +5,144 @@
#include <algorithm> // IWYU pragma: keep
#include <cassert>
#include <iomanip>
+#include <iterator>
#include <ostream>
#include <string>
#include <vector>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmDocumentationEntry.h"
#include "cmDocumentationSection.h"
+#include "cmStringAlgorithms.h"
namespace {
-const char* skipSpaces(const char* ptr)
-{
- assert(ptr);
- for (; *ptr == ' '; ++ptr) {
- ;
- }
- return ptr;
-}
-const char* skipToSpace(const char* ptr)
-{
- assert(ptr);
- for (; *ptr && (*ptr != '\n') && (*ptr != ' '); ++ptr) {
- ;
- }
- return ptr;
-}
-}
+const auto EOL = "\n"_s;
+const auto SPACE = " "_s;
+const auto TWO_SPACES = " "_s;
+const auto MAX_WIDTH_PADDING =
+ std::string(cmDocumentationFormatter::TEXT_WIDTH, ' ');
-void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
- std::string const& text) const
+void FormatLine(std::back_insert_iterator<std::vector<cm::string_view>> outIt,
+ const cm::string_view text, const cm::string_view padding)
{
- if (text.empty()) {
+ auto tokens = cmTokenizedView(text, ' ', cmTokenizerMode::New);
+ if (tokens.empty()) {
return;
}
- struct Buffer
- {
- // clang-format off
- using PrinterFn = void (cmDocumentationFormatter::*)(
- std::ostream&, std::string const&
- ) const;
- // clang-format on
- std::string collected;
- const PrinterFn printer;
- };
- // const auto NORMAL_IDX = 0u;
- const auto PREFORMATTED_IDX = 1u;
- const auto HANDLERS_SIZE = 2u;
- Buffer buffers[HANDLERS_SIZE] = {
- { {}, &cmDocumentationFormatter::PrintParagraph },
- { {}, &cmDocumentationFormatter::PrintPreformatted }
- };
-
- const auto padding = std::string(this->TextIndent, ' ');
-
- for (std::size_t pos = 0u, eol = 0u; pos < text.size(); pos = eol) {
- const auto current_idx = std::size_t(text[pos] == ' ');
- // size_t(!bool(current_idx))
- const auto other_idx = current_idx ^ 1u;
-
- // Flush the other buffer if anything has been collected
- if (!buffers[other_idx].collected.empty()) {
- // NOTE Whatever the other index is, the current buffered
- // string expected to be empty.
- assert(buffers[current_idx].collected.empty());
-
- (this->*buffers[other_idx].printer)(os, buffers[other_idx].collected);
- buffers[other_idx].collected.clear();
- }
-
- // ATTENTION The previous implementation had called `PrintParagraph()`
- // **for every processed (char by char) input line**.
- // The method unconditionally append the `\n' character after the
- // printed text. To keep the backward-compatible behavior it's needed to
- // add the '\n' character to the previously collected line...
- if (!buffers[current_idx].collected.empty() &&
- current_idx != PREFORMATTED_IDX) {
- buffers[current_idx].collected += '\n';
- }
-
- // Lookup EOL
- eol = text.find('\n', pos);
- if (current_idx == PREFORMATTED_IDX) {
- buffers[current_idx].collected.append(padding);
- }
- buffers[current_idx].collected.append(
- text, pos, eol == std::string::npos ? eol : ++eol - pos);
+ // Push padding in front of a first line
+ if (!padding.empty()) {
+ outIt = padding;
}
- for (auto& buf : buffers) {
- if (!buf.collected.empty()) {
- (this->*buf.printer)(os, buf.collected);
- }
- }
-}
+ auto currentWidth = padding.size();
+ auto newSentence = false;
-void cmDocumentationFormatter::PrintPreformatted(std::ostream& os,
- std::string const& text) const
-{
- os << text << '\n';
-}
-
-void cmDocumentationFormatter::PrintParagraph(std::ostream& os,
- std::string const& text) const
-{
- if (this->TextIndent) {
- os << std::string(this->TextIndent, ' ');
- }
- this->PrintColumn(os, text);
- os << '\n';
-}
-
-void cmDocumentationFormatter::PrintColumn(std::ostream& os,
- std::string const& text) const
-{
- // Print text arranged in an indented column of fixed width.
- bool newSentence = false;
- bool firstLine = true;
-
- assert(this->TextIndent < this->TextWidth);
- const std::ptrdiff_t width = this->TextWidth - this->TextIndent;
- std::ptrdiff_t column = 0;
-
- // Loop until the end of the text.
- for (const char *l = text.c_str(), *r = skipToSpace(text.c_str()); *l;
- l = skipSpaces(r), r = skipToSpace(l)) {
- // Does it fit on this line?
- if (r - l < width - column - std::ptrdiff_t(newSentence)) {
- // Word fits on this line.
- if (r > l) {
- if (column) {
- // Not first word on line. Separate from the previous word
- // by a space, or two if this is a new sentence.
- os << &(" "[std::size_t(!newSentence)]);
- column += 1u + std::ptrdiff_t(newSentence);
- } else if (!firstLine && this->TextIndent) {
- // First word on line. Print indentation unless this is the
- // first line.
- os << std::string(this->TextIndent, ' ');
- }
-
- // Print the word.
- os.write(l, r - l);
- newSentence = (*(r - 1) == '.');
+ for (auto token : tokens) {
+ // It's no need to add a space if this is a very first
+ // word on a line.
+ const auto needSpace = currentWidth > padding.size();
+ // Evaluate the size of a current token + possibly spaces before it.
+ const auto tokenWithSpaceSize = token.size() + std::size_t(needSpace) +
+ std::size_t(needSpace && newSentence);
+ // Check if a current word fits on a line.
+ // Also, take in account:
+ // - extra space if not a first word on a line
+ // - extra space if last token ends w/ a period
+ if (currentWidth + tokenWithSpaceSize <=
+ cmDocumentationFormatter::TEXT_WIDTH) {
+ // If not a first word on a line...
+ if (needSpace) {
+ // ... add a space after the last token +
+ // possibly one more space if the last token
+ // ends with a period (means, end of a sentence).
+ outIt = newSentence ? TWO_SPACES : SPACE;
}
-
- if (*r == '\n') {
- // Text provided a newline. Start a new line.
- os << '\n';
- ++r;
- column = 0;
- firstLine = false;
- } else {
- // No provided newline. Continue this line.
- column += r - l;
- }
+ outIt = token;
+ currentWidth += tokenWithSpaceSize;
} else {
- // Word does not fit on this line. Start a new line.
- os << '\n';
- firstLine = false;
- if (r > l) {
- os << std::string(this->TextIndent, ' ');
- os.write(l, r - l);
- column = r - l;
- newSentence = (*(r - 1) == '.');
- } else {
- column = 0;
+ // Start a new line!
+ outIt = EOL;
+ if (!padding.empty()) {
+ outIt = padding;
}
+ outIt = token;
+ currentWidth = padding.size() + token.size();
}
- // Move to beginning of next word. Skip over whitespace.
+
+ // Start a new sentence if the current word ends with period
+ newSentence = token.back() == '.';
}
+ // Always add EOL at the end of formatted text
+ outIt = EOL;
+}
+} // anonymous namespace
+
+std::string cmDocumentationFormatter::Format(std::string text) const
+{
+ // Exit early on empty text
+ if (text.empty()) {
+ return {};
+ }
+
+ assert(this->TextIndent < this->TEXT_WIDTH);
+
+ const auto padding =
+ cm::string_view(MAX_WIDTH_PADDING.c_str(), this->TextIndent);
+
+ std::vector<cm::string_view> tokens;
+ auto outIt = std::back_inserter(tokens);
+ auto prevWasPreFormatted = false;
+
+ // NOTE Can't use `cmTokenizedView()` cuz every sequential EOL does matter
+ // (and `cmTokenizedView()` will squeeze 'em)
+ for ( // clang-format off
+ std::string::size_type start = 0
+ , end = text.find('\n')
+ ; start < text.size()
+ ; start = end + ((end != std::string::npos) ? 1 : 0)
+ , end = text.find('\n', start)
+ ) // clang-format on
+ {
+ const auto isLastLine = end == std::string::npos;
+ const auto line = isLastLine
+ ? cm::string_view{ text.c_str() + start }
+ : cm::string_view{ text.c_str() + start, end - start };
+
+ if (!line.empty() && line.front() == ' ') {
+ // Preformatted lines go as is w/ a leading padding
+ if (!padding.empty()) {
+ outIt = padding;
+ }
+ outIt = line;
+ prevWasPreFormatted = true;
+ } else {
+ // Separate a normal paragraph from a pre-formatted
+ // w/ an extra EOL
+ if (prevWasPreFormatted) {
+ outIt = EOL;
+ }
+ if (line.empty()) {
+ if (!isLastLine) {
+ outIt = EOL;
+ }
+ } else {
+ FormatLine(outIt, line, padding);
+ }
+ prevWasPreFormatted = false;
+ }
+ if (!isLastLine) {
+ outIt = EOL;
+ }
+ }
+
+ if (prevWasPreFormatted) {
+ outIt = EOL;
+ }
+
+ return cmJoinStrings(tokens, {}, {});
}
void cmDocumentationFormatter::PrintSection(
@@ -202,13 +171,10 @@
if (entry.Name.size() > NAME_SIZE) {
os << '\n' << std::setw(int(this->TextIndent - PREFIX_SIZE)) << ' ';
}
- os << "= ";
- this->PrintColumn(os, entry.Brief);
- os << '\n';
+ os << "= " << this->Format(entry.Brief).substr(this->TextIndent);
} else {
- os << '\n';
this->TextIndent = 0u;
- this->PrintFormatted(os, entry.Brief);
+ os << '\n' << this->Format(entry.Brief);
}
}
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
index 9d35e0a..77606cf 100644
--- a/Source/cmDocumentationFormatter.h
+++ b/Source/cmDocumentationFormatter.h
@@ -14,15 +14,20 @@
class cmDocumentationFormatter
{
public:
- void SetIndent(std::size_t indent) { this->TextIndent = indent; }
- void PrintFormatted(std::ostream& os, std::string const& text) const;
+ std::string Format(std::string text) const;
void PrintSection(std::ostream& os, cmDocumentationSection const& section);
+ void PrintFormatted(std::ostream& os, std::string const& text) const
+ {
+ os << this->Format(text);
+ }
+ void SetIndent(std::size_t indent) { this->TextIndent = indent; }
+
+ static constexpr std::size_t TEXT_WIDTH = 77u;
private:
void PrintPreformatted(std::ostream& os, std::string const&) const;
void PrintParagraph(std::ostream& os, std::string const&) const;
void PrintColumn(std::ostream& os, std::string const&) const;
- std::size_t TextWidth = 77u;
std::size_t TextIndent = 0u;
};
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 003f47b..99d0ba4 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -509,7 +509,7 @@
return 0;
}
ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
- return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j);
+ return sec.sh_offset + sec.sh_entsize * static_cast<unsigned long>(j);
}
template <class Types>
diff --git a/Source/cmExportCMakeConfigGenerator.cxx b/Source/cmExportCMakeConfigGenerator.cxx
index e85d949..2bb0008 100644
--- a/Source/cmExportCMakeConfigGenerator.cxx
+++ b/Source/cmExportCMakeConfigGenerator.cxx
@@ -185,7 +185,7 @@
// Isolate the file policy level.
// Support CMake versions as far back as the
// RequiredCMakeVersion{Major,Minor,Patch}, but also support using NEW
- // policy settings for up to CMake 3.29 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.30 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
@@ -194,7 +194,7 @@
<< "cmake_policy(VERSION "
<< this->RequiredCMakeVersionMajor << '.'
<< this->RequiredCMakeVersionMinor << '.'
- << this->RequiredCMakeVersionPatch << "...3.29)\n";
+ << this->RequiredCMakeVersionPatch << "...3.30)\n";
/* clang-format on */
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 4c6ddfc..7c5b26b 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -405,8 +405,6 @@
return true;
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Default is to not export, but can be enabled.
if (!mf.IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 7b62bb4..5767dc3 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -439,8 +439,6 @@
break;
case cmPolicies::OLD:
continue;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
hadFatalError = true;
break; // Issue fatal message.
@@ -492,8 +490,6 @@
case cmPolicies::OLD:
shouldContinue = true;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
break;
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 92e6b3e..99dc7ef 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -409,8 +409,6 @@
}
have_regex = true;
switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0159)) {
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// store_regex = true
break;
@@ -685,8 +683,6 @@
status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0009);
if (recurse) {
switch (policyStatus) {
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
g.RecurseThroughSymlinksOff();
break;
@@ -839,8 +835,6 @@
}
switch (policyStatus) {
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Correct behavior, yay!
break;
@@ -1110,7 +1104,7 @@
if (!cmSystemTools::ChangeRPath(file, *oldRPath, *newRPath,
removeEnvironmentRPath, &emsg, &changed)) {
status.SetError(cmStrCat("RPATH_CHANGE could not write new RPATH:\n ",
- *newRPath, "\nto the file:\n ", file, "\n",
+ *newRPath, "\nto the file:\n ", file, '\n',
emsg));
success = false;
}
@@ -1165,7 +1159,7 @@
if (!cmSystemTools::SetRPath(file, *newRPath, &emsg, &changed)) {
status.SetError(cmStrCat("RPATH_SET could not write new RPATH:\n ",
- *newRPath, "\nto the file:\n ", file, "\n",
+ *newRPath, "\nto the file:\n ", file, '\n',
emsg));
success = false;
}
@@ -1215,7 +1209,7 @@
if (!cmSystemTools::RemoveRPath(file, &emsg, &removed)) {
status.SetError(
cmStrCat("RPATH_REMOVE could not remove RPATH from file: \n ", file,
- "\n", emsg));
+ '\n', emsg));
success = false;
}
if (success) {
@@ -1389,8 +1383,6 @@
cmPolicies::PolicyStatus policyStatus =
status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0152);
switch (policyStatus) {
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
break;
case cmPolicies::WARN:
@@ -1409,8 +1401,7 @@
auto basePath = cmCMakePath{ *arguments.BaseDirectory };
path = basePath.Append(path);
}
- result = cmSystemTools::GetActualCaseForPath(
- cmSystemTools::GetRealPath(path.String()));
+ result = cmSystemTools::GetRealPath(path.String());
};
std::string realPath;
@@ -1547,7 +1538,7 @@
break;
}
status.SetError(cmStrCat("RENAME failed to rename\n ", oldname, "\nto\n ",
- newname, "\nbecause: ", err, "\n"));
+ newname, "\nbecause: ", err, '\n'));
return false;
}
@@ -1640,7 +1631,7 @@
status.GetMakefile().AddDefinition(arguments.Result, err);
} else {
status.SetError(cmStrCat("COPY_FILE failed to copy\n ", oldname,
- "\nto\n ", newname, "\nbecause: ", err, "\n"));
+ "\nto\n ", newname, "\nbecause: ", err, '\n'));
result = false;
}
}
@@ -1831,7 +1822,7 @@
if (updated) {
status =
- cmStrCat("[", this->Text, " ", this->CurrentPercentage, "% complete]");
+ cmStrCat('[', this->Text, ' ', this->CurrentPercentage, "% complete]");
}
return updated;
@@ -2343,7 +2334,7 @@
"set environment variable CMAKE_TLS_VERIFY=0 to suppress it.");
}
status.GetMakefile().AddDefinition(
- statusVar, cmStrCat(static_cast<int>(res), ";\"", std::move(m), "\""));
+ statusVar, cmStrCat(static_cast<int>(res), ";\"", std::move(m), '"'));
}
::curl_global_cleanup();
@@ -2744,7 +2735,7 @@
"set environment variable CMAKE_TLS_VERIFY=0 to suppress it.");
}
status.GetMakefile().AddDefinition(
- statusVar, cmStrCat(static_cast<int>(res), ";\"", std::move(m), "\""));
+ statusVar, cmStrCat(static_cast<int>(res), ";\"", std::move(m), '"'));
}
::curl_global_cleanup();
@@ -3099,7 +3090,7 @@
if (resultVariable.empty() && !fileLockResult.IsOk()) {
status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("error locking file\n \"", path, "\"\n", result, "."));
+ cmStrCat("error locking file\n \"", path, "\"\n", result, '.'));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -3348,7 +3339,7 @@
platform)) {
status.SetError(
cmStrCat("GET_RUNTIME_DEPENDENCIES is not supported on system \"",
- platform, "\""));
+ platform, '"'));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -3415,7 +3406,7 @@
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
- status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, '"'));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -3547,7 +3538,7 @@
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
status.SetError(
- cmStrCat("CONFIGURE Unrecognized argument: \"", *argIt, "\""));
+ cmStrCat("CONFIGURE Unrecognized argument: \"", *argIt, '"'));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -3681,7 +3672,7 @@
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
- status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, '"'));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -3810,7 +3801,7 @@
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
- status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, '"'));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -3835,7 +3826,7 @@
if (cmSystemTools::FileIsFullPath(parsedArgs.Destination)) {
destDir = parsedArgs.Destination;
} else {
- destDir = cmStrCat(destDir, "/", parsedArgs.Destination);
+ destDir = cmStrCat(destDir, '/', parsedArgs.Destination);
}
if (!cmSystemTools::MakeDirectory(destDir)) {
@@ -3846,14 +3837,13 @@
if (!cmSystemTools::FileIsFullPath(inFile)) {
inFile =
- cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/", inFile);
+ cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), '/', inFile);
}
}
cmWorkingDirectory workdir(destDir);
if (workdir.Failed()) {
- status.SetError(
- cmStrCat("failed to change working directory to: ", destDir));
+ status.SetError(workdir.GetError());
cmSystemTools::SetFatalErrorOccurred();
return false;
}
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 686162b..47d3d51 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -713,7 +713,7 @@
if (!source.empty()) {
dir.Load(source);
}
- unsigned long numFiles = static_cast<unsigned long>(dir.GetNumberOfFiles());
+ unsigned long numFiles = dir.GetNumberOfFiles();
for (unsigned long fileNum = 0; fileNum < numFiles; ++fileNum) {
if (!(strcmp(dir.GetFile(fileNum), ".") == 0 ||
strcmp(dir.GetFile(fileNum), "..") == 0)) {
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
index 548e327..64fbc1f 100644
--- a/Source/cmFileLock.cxx
+++ b/Source/cmFileLock.cxx
@@ -14,6 +14,9 @@
this->File = other.File;
other.File = (decltype(other.File))-1;
this->Filename = std::move(other.Filename);
+#if defined(_WIN32)
+ this->Overlapped = std::move(other.Overlapped);
+#endif
}
cmFileLock::~cmFileLock()
@@ -30,6 +33,9 @@
this->File = other.File;
other.File = (decltype(other.File))-1;
this->Filename = std::move(other.Filename);
+#if defined(_WIN32)
+ this->Overlapped = std::move(other.Overlapped);
+#endif
return *this;
}
diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h
index 0f2e7d9..e17f8bc 100644
--- a/Source/cmFileLock.h
+++ b/Source/cmFileLock.h
@@ -7,6 +7,7 @@
#include <string>
#if defined(_WIN32)
+# include <memory>
using HANDLE = void*;
#endif
@@ -54,6 +55,7 @@
#if defined(_WIN32)
HANDLE File = (HANDLE)-1;
+ std::unique_ptr<struct _OVERLAPPED> Overlapped;
int LockFile(int flags);
#else
int File = -1;
diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx
index 244ade2..8a4dadc 100644
--- a/Source/cmFileLockWin32.cxx
+++ b/Source/cmFileLockWin32.cxx
@@ -1,12 +1,18 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include <windows.h> // CreateFileW
+#include <cm/memory>
+
+#include <windows.h>
#include "cmFileLock.h"
#include "cmSystemTools.h"
+static const unsigned long LOCK_LEN = static_cast<unsigned long>(-1);
+
cmFileLock::cmFileLock()
+ : Overlapped(cm::make_unique<OVERLAPPED>())
{
+ ZeroMemory(this->Overlapped.get(), sizeof(*this->Overlapped));
}
cmFileLockResult cmFileLock::Release()
@@ -14,15 +20,16 @@
if (this->Filename.empty()) {
return cmFileLockResult::MakeOk();
}
- const unsigned long len = static_cast<unsigned long>(-1);
- static OVERLAPPED overlapped;
const DWORD reserved = 0;
+ ZeroMemory(this->Overlapped.get(), sizeof(*this->Overlapped));
+
const BOOL unlockResult =
- UnlockFileEx(File, reserved, len, len, &overlapped);
+ UnlockFileEx(File, reserved, LOCK_LEN, LOCK_LEN, this->Overlapped.get());
this->Filename = "";
CloseHandle(this->File);
+
this->File = INVALID_HANDLE_VALUE;
if (unlockResult) {
@@ -51,37 +58,63 @@
cmFileLockResult cmFileLock::LockWithoutTimeout()
{
+ cmFileLockResult lock_result = cmFileLockResult::MakeOk();
if (!this->LockFile(LOCKFILE_EXCLUSIVE_LOCK)) {
- return cmFileLockResult::MakeSystem();
- } else {
- return cmFileLockResult::MakeOk();
+ lock_result = cmFileLockResult::MakeSystem();
}
+ CloseHandle(this->Overlapped->hEvent);
+ return lock_result;
}
cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
{
+ cmFileLockResult lock_result = cmFileLockResult::MakeOk();
const DWORD flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
- while (true) {
- const BOOL result = this->LockFile(flags);
- if (result) {
- return cmFileLockResult::MakeOk();
+ bool in_time = true;
+ while (in_time && !this->LockFile(flags)) {
+ switch (GetLastError()) {
+ case ERROR_INVALID_HANDLE:
+ lock_result = cmFileLockResult::MakeSystem();
+ break;
+ case ERROR_LOCK_VIOLATION:
+ if (seconds == 0) {
+ in_time = false;
+ lock_result = cmFileLockResult::MakeTimeout();
+ continue;
+ }
+ --seconds;
+ cmSystemTools::Delay(1000);
+ continue;
+ case ERROR_IO_PENDING:
+ switch (
+ WaitForSingleObject(this->Overlapped->hEvent, seconds * 1000)) {
+ case WAIT_OBJECT_0:
+ break;
+ case WAIT_TIMEOUT:
+ lock_result = cmFileLockResult::MakeTimeout();
+ break;
+ default:
+ lock_result = cmFileLockResult::MakeSystem();
+ break;
+ }
+ break;
+ default:
+ lock_result = cmFileLockResult::MakeSystem();
+ break;
}
- const DWORD error = GetLastError();
- if (error != ERROR_LOCK_VIOLATION) {
- return cmFileLockResult::MakeSystem();
- }
- if (seconds == 0) {
- return cmFileLockResult::MakeTimeout();
- }
- --seconds;
- cmSystemTools::Delay(1000);
}
+ CloseHandle(this->Overlapped->hEvent);
+ return lock_result;
}
int cmFileLock::LockFile(int flags)
{
const DWORD reserved = 0;
- const unsigned long len = static_cast<unsigned long>(-1);
- static OVERLAPPED overlapped;
- return LockFileEx(this->File, flags, reserved, len, len, &overlapped);
+
+ this->Overlapped->hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
+ if (this->Overlapped->hEvent == nullptr) {
+ return false;
+ }
+ return LockFileEx(this->File, flags, reserved, LOCK_LEN, LOCK_LEN,
+ this->Overlapped.get());
}
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 81e081c..5189519 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -56,7 +56,9 @@
} else if (argsIn[j] == "ENV") {
if (j + 1 < size) {
j++;
- cmSystemTools::GetPath(args, argsIn[j].c_str());
+ std::vector<std::string> p =
+ cmSystemTools::GetEnvPathNormalized(argsIn[j]);
+ std::move(p.begin(), p.end(), std::back_inserter(args));
}
} else {
args.push_back(argsIn[j]);
@@ -131,7 +133,7 @@
newStyle = true;
} else if (args[j] == "REGISTRY_VIEW") {
if (++j == args.size()) {
- this->SetError("missing required argument for \"REGISTRY_VIEW\"");
+ this->SetError("missing required argument for REGISTRY_VIEW");
return false;
}
auto view = cmWindowsRegistry::ToView(args[j]);
@@ -139,18 +141,18 @@
this->RegistryView = *view;
} else {
this->SetError(
- cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[j]));
+ cmStrCat("given invalid value for REGISTRY_VIEW: ", args[j]));
return false;
}
} else if (args[j] == "VALIDATOR") {
if (++j == args.size()) {
- this->SetError("missing required argument for \"VALIDATOR\"");
+ this->SetError("missing required argument for VALIDATOR");
return false;
}
auto command = this->Makefile->GetState()->GetCommand(args[j]);
if (!command) {
this->SetError(cmStrCat(
- "command specified for \"VALIDATOR\" is undefined: ", args[j], '.'));
+ "command specified for VALIDATOR is undefined: ", args[j], '.'));
return false;
}
// ensure a macro is not specified as validator
@@ -162,7 +164,7 @@
item.c_str()) == 0;
}) != macros.end()) {
this->SetError(cmStrCat(
- "command specified for \"VALIDATOR\" is not a function: ", args[j],
+ "command specified for VALIDATOR is not a function: ", args[j],
'.'));
return false;
}
@@ -338,7 +340,6 @@
struct entry_to_remove
{
entry_to_remove(std::string const& name, cmMakefile* makefile)
- : value()
{
if (cmValue to_skip = makefile->GetDefinition(
cmStrCat("_CMAKE_SYSTEM_PREFIX_PATH_", name, "_PREFIX_COUNT"))) {
@@ -404,9 +405,11 @@
cmList expanded{ *prefix_paths };
install_entry.remove_self(expanded);
staging_entry.remove_self(expanded);
-
- paths.AddPrefixPaths(expanded,
- this->Makefile->GetCurrentSourceDirectory().c_str());
+ for (std::string& p : expanded) {
+ p = cmSystemTools::CollapseFullPath(
+ p, this->Makefile->GetCurrentSourceDirectory());
+ }
+ paths.AddPrefixPaths(expanded);
} else if (add_install_prefix && !install_prefix_in_list) {
paths.AddCMakePrefixPath("CMAKE_INSTALL_PREFIX");
paths.AddCMakePrefixPath("CMAKE_STAGING_PREFIX");
@@ -494,7 +497,6 @@
this->Makefile->GetCMakeInstance()->GetCMakeWorkingDirectory()))
.Normal()
.GenericString();
- // value = cmSystemTools::CollapseFullPath(*existingValue);
if (!cmSystemTools::FileExists(value, false)) {
value = *existingValue;
}
@@ -609,65 +611,62 @@
cmFindBaseDebugState::~cmFindBaseDebugState()
{
- if (this->FindCommand->DebugMode) {
- std::string buffer =
- cmStrCat(this->CommandName, " called with the following settings:\n");
- buffer += cmStrCat(" VAR: ", this->FindCommand->VariableName, "\n");
- buffer += cmStrCat(
- " NAMES: ", cmWrap("\"", this->FindCommand->Names, "\"", "\n "),
- "\n");
- buffer += cmStrCat(
- " Documentation: ", this->FindCommand->VariableDocumentation, "\n");
- buffer += " Framework\n";
- buffer += cmStrCat(" Only Search Frameworks: ",
- this->FindCommand->SearchFrameworkOnly, "\n");
-
- buffer += cmStrCat(" Search Frameworks Last: ",
- this->FindCommand->SearchFrameworkLast, "\n");
- buffer += cmStrCat(" Search Frameworks First: ",
- this->FindCommand->SearchFrameworkFirst, "\n");
- buffer += " AppBundle\n";
- buffer += cmStrCat(" Only Search AppBundle: ",
- this->FindCommand->SearchAppBundleOnly, "\n");
- buffer += cmStrCat(" Search AppBundle Last: ",
- this->FindCommand->SearchAppBundleLast, "\n");
- buffer += cmStrCat(" Search AppBundle First: ",
- this->FindCommand->SearchAppBundleFirst, "\n");
-
- if (this->FindCommand->NoDefaultPath) {
- buffer += " NO_DEFAULT_PATH Enabled\n";
- } else {
- buffer += cmStrCat(
- " CMAKE_FIND_USE_CMAKE_PATH: ", !this->FindCommand->NoCMakePath, "\n",
- " CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: ",
- !this->FindCommand->NoCMakeEnvironmentPath, "\n",
- " CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ",
- !this->FindCommand->NoSystemEnvironmentPath, "\n",
- " CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ",
- !this->FindCommand->NoCMakeSystemPath, "\n",
- " CMAKE_FIND_USE_INSTALL_PREFIX: ",
- !this->FindCommand->NoCMakeInstallPath, "\n");
- }
-
- buffer +=
- cmStrCat(this->CommandName, " considered the following locations:\n");
- for (auto const& state : this->FailedSearchLocations) {
- std::string path = cmStrCat(" ", state.path);
- if (!state.regexName.empty()) {
- path = cmStrCat(path, "/", state.regexName);
- }
- buffer += cmStrCat(path, "\n");
- }
-
- if (!this->FoundSearchLocation.path.empty()) {
- buffer += cmStrCat("The item was found at\n ",
- this->FoundSearchLocation.path, "\n");
- } else {
- buffer += "The item was not found.\n";
- }
-
- this->FindCommand->DebugMessage(buffer);
+ if (!this->FindCommand->DebugMode) {
+ return;
}
+
+ // clang-format off
+ auto buffer =
+ cmStrCat(
+ this->CommandName, " called with the following settings:"
+ "\n VAR: ", this->FindCommand->VariableName,
+ "\n NAMES: ", cmWrap('"', this->FindCommand->Names, '"', "\n "),
+ "\n Documentation: ", this->FindCommand->VariableDocumentation,
+ "\n Framework"
+ "\n Only Search Frameworks: ", this->FindCommand->SearchFrameworkOnly,
+ "\n Search Frameworks Last: ", this->FindCommand->SearchFrameworkLast,
+ "\n Search Frameworks First: ", this->FindCommand->SearchFrameworkFirst,
+ "\n AppBundle"
+ "\n Only Search AppBundle: ", this->FindCommand->SearchAppBundleOnly,
+ "\n Search AppBundle Last: ", this->FindCommand->SearchAppBundleLast,
+ "\n Search AppBundle First: ", this->FindCommand->SearchAppBundleFirst,
+ "\n"
+ );
+ // clang-format on
+
+ if (this->FindCommand->NoDefaultPath) {
+ buffer += " NO_DEFAULT_PATH Enabled\n";
+ } else {
+ // clang-format off
+ buffer += cmStrCat(
+ " CMAKE_FIND_USE_CMAKE_PATH: ", !this->FindCommand->NoCMakePath,
+ "\n CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: ", !this->FindCommand->NoCMakeEnvironmentPath,
+ "\n CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ", !this->FindCommand->NoSystemEnvironmentPath,
+ "\n CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ", !this->FindCommand->NoCMakeSystemPath,
+ "\n CMAKE_FIND_USE_INSTALL_PREFIX: ", !this->FindCommand->NoCMakeInstallPath,
+ "\n"
+ );
+ // clang-format on
+ }
+
+ buffer +=
+ cmStrCat(this->CommandName, " considered the following locations:\n");
+ for (auto const& state : this->FailedSearchLocations) {
+ std::string path = cmStrCat(" ", state.path);
+ if (!state.regexName.empty()) {
+ path = cmStrCat(path, '/', state.regexName);
+ }
+ buffer += cmStrCat(path, '\n');
+ }
+
+ if (!this->FoundSearchLocation.path.empty()) {
+ buffer += cmStrCat("The item was found at\n ",
+ this->FoundSearchLocation.path, '\n');
+ } else {
+ buffer += "The item was not found.\n";
+ }
+
+ this->FindCommand->DebugMessage(buffer);
}
void cmFindBaseDebugState::FoundAt(std::string const& path,
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 31243f6..01c87c2 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -118,20 +118,13 @@
this->PathGroupOrder.push_back(PathGroup::All);
// Create the individual labeled search paths
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::PackageRoot, cmSearchPath(this)));
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::CMake, cmSearchPath(this)));
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::CMakeEnvironment, cmSearchPath(this)));
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::Hints, cmSearchPath(this)));
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::SystemEnvironment, cmSearchPath(this)));
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::CMakeSystem, cmSearchPath(this)));
- this->LabeledPaths.insert(
- std::make_pair(PathLabel::Guess, cmSearchPath(this)));
+ this->LabeledPaths.emplace(PathLabel::PackageRoot, cmSearchPath(this));
+ this->LabeledPaths.emplace(PathLabel::CMake, cmSearchPath(this));
+ this->LabeledPaths.emplace(PathLabel::CMakeEnvironment, cmSearchPath(this));
+ this->LabeledPaths.emplace(PathLabel::Hints, cmSearchPath(this));
+ this->LabeledPaths.emplace(PathLabel::SystemEnvironment, cmSearchPath(this));
+ this->LabeledPaths.emplace(PathLabel::CMakeSystem, cmSearchPath(this));
+ this->LabeledPaths.emplace(PathLabel::Guess, cmSearchPath(this));
}
void cmFindCommon::SelectDefaultRootPathMode()
@@ -215,12 +208,6 @@
void cmFindCommon::RerootPaths(std::vector<std::string>& paths,
std::string* debugBuffer)
{
-#if 0
- for(std::string const& p : paths)
- {
- fprintf(stderr, "[%s]\n", p.c_str());
- }
-#endif
// Short-circuit if there is nothing to do.
if (this->FindRootPathMode == RootPathModeNever) {
return;
@@ -247,13 +234,13 @@
auto debugRoot = [this, debugBuffer](const std::string& name,
cmValue value) {
if (this->DebugMode && debugBuffer) {
- *debugBuffer = cmStrCat(*debugBuffer, name, "\n");
+ *debugBuffer = cmStrCat(*debugBuffer, name, '\n');
cmList roots{ value };
if (roots.empty()) {
*debugBuffer = cmStrCat(*debugBuffer, " none\n");
}
for (auto const& root : roots) {
- *debugBuffer = cmStrCat(*debugBuffer, " ", root, "\n");
+ *debugBuffer = cmStrCat(*debugBuffer, " ", root, '\n');
}
}
};
@@ -325,10 +312,8 @@
void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
{
- static constexpr const char* paths[] = {
- "CMAKE_SYSTEM_IGNORE_PATH",
- "CMAKE_IGNORE_PATH",
- };
+ const std::array<const char*, 2> paths = { { "CMAKE_SYSTEM_IGNORE_PATH",
+ "CMAKE_IGNORE_PATH" } };
// Construct the list of path roots with no trailing slashes.
for (const char* pathName : paths) {
@@ -350,11 +335,9 @@
void cmFindCommon::GetIgnoredPrefixPaths(std::vector<std::string>& ignore)
{
- static constexpr const char* paths[] = {
- "CMAKE_SYSTEM_IGNORE_PREFIX_PATH",
- "CMAKE_IGNORE_PREFIX_PATH",
+ const std::array<const char*, 2> paths = {
+ { "CMAKE_SYSTEM_IGNORE_PREFIX_PATH", "CMAKE_IGNORE_PREFIX_PATH" }
};
-
// Construct the list of path roots with no trailing slashes.
for (const char* pathName : paths) {
// Get the list of paths to ignore from the variable.
@@ -377,31 +360,46 @@
{
if (arg == "NO_DEFAULT_PATH") {
this->NoDefaultPath = true;
- } else if (arg == "NO_PACKAGE_ROOT_PATH") {
- this->NoPackageRootPath = true;
- } else if (arg == "NO_CMAKE_PATH") {
- this->NoCMakePath = true;
- } else if (arg == "NO_CMAKE_ENVIRONMENT_PATH") {
- this->NoCMakeEnvironmentPath = true;
- } else if (arg == "NO_SYSTEM_ENVIRONMENT_PATH") {
- this->NoSystemEnvironmentPath = true;
- } else if (arg == "NO_CMAKE_SYSTEM_PATH") {
- this->NoCMakeSystemPath = true;
- } else if (arg == "NO_CMAKE_INSTALL_PREFIX") {
- this->NoCMakeInstallPath = true;
- } else if (arg == "NO_CMAKE_FIND_ROOT_PATH") {
- this->FindRootPathMode = RootPathModeNever;
- } else if (arg == "ONLY_CMAKE_FIND_ROOT_PATH") {
- this->FindRootPathMode = RootPathModeOnly;
- } else if (arg == "CMAKE_FIND_ROOT_PATH_BOTH") {
- this->FindRootPathMode = RootPathModeBoth;
- } else {
- // The argument is not one of the above.
- return false;
+ return true;
}
-
- // The argument is one of the above.
- return true;
+ if (arg == "NO_PACKAGE_ROOT_PATH") {
+ this->NoPackageRootPath = true;
+ return true;
+ }
+ if (arg == "NO_CMAKE_PATH") {
+ this->NoCMakePath = true;
+ return true;
+ }
+ if (arg == "NO_CMAKE_ENVIRONMENT_PATH") {
+ this->NoCMakeEnvironmentPath = true;
+ return true;
+ }
+ if (arg == "NO_SYSTEM_ENVIRONMENT_PATH") {
+ this->NoSystemEnvironmentPath = true;
+ return true;
+ }
+ if (arg == "NO_CMAKE_SYSTEM_PATH") {
+ this->NoCMakeSystemPath = true;
+ return true;
+ }
+ if (arg == "NO_CMAKE_INSTALL_PREFIX") {
+ this->NoCMakeInstallPath = true;
+ return true;
+ }
+ if (arg == "NO_CMAKE_FIND_ROOT_PATH") {
+ this->FindRootPathMode = RootPathModeNever;
+ return true;
+ }
+ if (arg == "ONLY_CMAKE_FIND_ROOT_PATH") {
+ this->FindRootPathMode = RootPathModeOnly;
+ return true;
+ }
+ if (arg == "CMAKE_FIND_ROOT_PATH_BOTH") {
+ this->FindRootPathMode = RootPathModeBoth;
+ return true;
+ }
+ // The argument is not one of the above.
+ return false;
}
void cmFindCommon::AddPathSuffix(std::string const& arg)
@@ -429,12 +427,6 @@
this->SearchPathSuffixes.push_back(std::move(suffix));
}
-static void AddTrailingSlash(std::string& s)
-{
- if (!s.empty() && s.back() != '/') {
- s += '/';
- }
-}
void cmFindCommon::ComputeFinalPaths(IgnorePaths ignorePaths,
std::string* debugBuffer)
{
@@ -459,5 +451,9 @@
// Add a trailing slash to all paths to aid the search process.
std::for_each(this->SearchPaths.begin(), this->SearchPaths.end(),
- &AddTrailingSlash);
+ [](std::string& s) {
+ if (!s.empty() && s.back() != '/') {
+ s += '/';
+ }
+ });
}
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 9df7665..c5a6038 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -220,9 +220,6 @@
};
std::vector<Name> Names;
- // Current full path under consideration.
- std::string TestPath;
-
void RegexFromLiteral(std::string& out, std::string const& in);
void RegexFromList(std::string& out, cmList const& in);
size_type GetPrefixIndex(std::string const& prefix)
@@ -423,20 +420,17 @@
// one cannot tell just from the library name whether it is a static
// library or an import library).
if (name.TryRaw) {
- this->TestPath = cmStrCat(path, name.Raw);
+ std::string testPath = cmStrCat(path, name.Raw);
- const bool exists = cmSystemTools::FileExists(this->TestPath, true);
- if (!exists) {
- this->DebugLibraryFailed(name.Raw, path);
- } else {
- auto testPath = cmSystemTools::CollapseFullPath(this->TestPath);
+ if (cmSystemTools::FileExists(testPath, true)) {
+ testPath = cmSystemTools::ToNormalizedPathOnDisk(testPath);
if (this->Validate(testPath)) {
this->DebugLibraryFound(name.Raw, path);
this->BestPath = testPath;
return true;
}
- this->DebugLibraryFailed(name.Raw, path);
}
+ this->DebugLibraryFailed(name.Raw, path);
}
// No library file has yet been found.
@@ -446,9 +440,7 @@
unsigned int bestMinor = 0;
// Search for a file matching the library name regex.
- std::string dir = path;
- cmSystemTools::ConvertToUnixSlashes(dir);
- std::set<std::string> const& files = this->GG->GetDirectoryContent(dir);
+ std::set<std::string> const& files = this->GG->GetDirectoryContent(path);
for (std::string const& origName : files) {
#if defined(_WIN32) || defined(__APPLE__)
std::string testName = cmSystemTools::LowerCase(origName);
@@ -456,14 +448,15 @@
std::string const& testName = origName;
#endif
if (name.Regex.find(testName)) {
- this->TestPath = cmStrCat(path, origName);
+ std::string testPath = cmStrCat(path, origName);
// Make sure the path is readable and is not a directory.
- if (cmSystemTools::FileExists(this->TestPath, true)) {
- if (!this->Validate(cmSystemTools::CollapseFullPath(this->TestPath))) {
+ if (cmSystemTools::FileExists(testPath, true)) {
+ testPath = cmSystemTools::ToNormalizedPathOnDisk(testPath);
+ if (!this->Validate(testPath)) {
continue;
}
- this->DebugLibraryFound(name.Raw, dir);
+ this->DebugLibraryFound(name.Raw, path);
// This is a matching file. Check if it is better than the
// best name found so far. Earlier prefixes are preferred,
// followed by earlier suffixes. For OpenBSD, shared library
@@ -480,7 +473,7 @@
(prefix == bestPrefix && suffix == bestSuffix &&
(major > bestMajor ||
(major == bestMajor && minor > bestMinor)))) {
- this->BestPath = this->TestPath;
+ this->BestPath = testPath;
bestPrefix = prefix;
bestSuffix = suffix;
bestMajor = major;
@@ -491,7 +484,7 @@
}
if (this->BestPath.empty()) {
- this->DebugLibraryFailed(name.Raw, dir);
+ this->DebugLibraryFailed(name.Raw, path);
} else {
this->DebugLibraryFound(name.Raw, this->BestPath);
}
@@ -560,7 +553,7 @@
for (std::string const& n : this->Names) {
fwPath = cmStrCat(d, n, ".xcframework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
- auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
if (this->Validate(finalPath)) {
return finalPath;
}
@@ -568,7 +561,7 @@
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
- auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
if (this->Validate(finalPath)) {
return finalPath;
}
@@ -588,7 +581,7 @@
for (std::string const& d : this->SearchPaths) {
fwPath = cmStrCat(d, n, ".xcframework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
- auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
if (this->Validate(finalPath)) {
return finalPath;
}
@@ -596,7 +589,7 @@
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
- auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
if (this->Validate(finalPath)) {
return finalPath;
}
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index cc150fd..12bf160 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -12,11 +12,11 @@
#include <utility>
#include <cm/optional>
+#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
@@ -164,8 +164,7 @@
{
public:
cmCaseInsensitiveDirectoryListGenerator(cm::string_view name)
- : DirectoryLister{}
- , DirName{ name }
+ : DirName{ name }
{
}
@@ -207,11 +206,14 @@
class cmDirectoryListGenerator
{
public:
- cmDirectoryListGenerator(std::vector<std::string> const& names)
+ cmDirectoryListGenerator(std::vector<std::string> const* names,
+ bool exactMatch)
: Names{ names }
- , Matches{}
+ , ExactMatch{ exactMatch }
, Current{ this->Matches.cbegin() }
{
+ assert(names || !exactMatch);
+ assert(!names || !names->empty());
}
virtual ~cmDirectoryListGenerator() = default;
@@ -233,20 +235,28 @@
// `isDirentryToIgnore(i)` condition to check.
for (auto i = 0ul; i < directoryLister.GetNumberOfFiles(); ++i) {
const char* const fname = directoryLister.GetFile(i);
- if (isDirentryToIgnore(fname)) {
+ // Skip entries to ignore or that aren't directories.
+ if (isDirentryToIgnore(fname) || !directoryLister.FileIsDirectory(i)) {
continue;
}
- for (const auto& n : this->Names.get()) {
- // NOTE Customization point for `cmMacProjectDirectoryListGenerator`
- const auto name = this->TransformNameBeforeCmp(n);
- // Skip entries that don't match and non-directories.
- // ATTENTION BTW, original code also didn't check if it's a symlink
- // to a directory!
- const auto equal =
- (cmsysString_strncasecmp(fname, name.c_str(), name.length()) == 0);
- if (equal && directoryLister.FileIsDirectory(i)) {
- this->Matches.emplace_back(fname);
+ if (!this->Names) {
+ this->Matches.emplace_back(fname);
+ } else {
+ for (const auto& n : *this->Names) {
+ // NOTE Customization point for
+ // `cmMacProjectDirectoryListGenerator`
+ const auto name = this->TransformNameBeforeCmp(n);
+ // Skip entries that don't match.
+ const auto equal =
+ ((this->ExactMatch
+ ? cmsysString_strcasecmp(fname, name.c_str())
+ : cmsysString_strncasecmp(fname, name.c_str(),
+ name.length())) == 0);
+ if (equal) {
+ this->Matches.emplace_back(fname);
+ break;
+ }
}
}
}
@@ -274,7 +284,8 @@
virtual void OnMatchesLoaded() {}
virtual std::string TransformNameBeforeCmp(std::string same) { return same; }
- std::reference_wrapper<const std::vector<std::string>> Names;
+ std::vector<std::string> const* Names;
+ bool const ExactMatch;
std::vector<std::string> Matches;
std::vector<std::string>::const_iterator Current;
};
@@ -282,10 +293,11 @@
class cmProjectDirectoryListGenerator : public cmDirectoryListGenerator
{
public:
- cmProjectDirectoryListGenerator(std::vector<std::string> const& names,
+ cmProjectDirectoryListGenerator(std::vector<std::string> const* names,
cmFindPackageCommand::SortOrderType so,
- cmFindPackageCommand::SortDirectionType sd)
- : cmDirectoryListGenerator{ names }
+ cmFindPackageCommand::SortDirectionType sd,
+ bool exactMatch)
+ : cmDirectoryListGenerator{ names, exactMatch }
, SortOrder{ so }
, SortDirection{ sd }
{
@@ -310,9 +322,9 @@
class cmMacProjectDirectoryListGenerator : public cmDirectoryListGenerator
{
public:
- cmMacProjectDirectoryListGenerator(const std::vector<std::string>& names,
+ cmMacProjectDirectoryListGenerator(std::vector<std::string> const* names,
cm::string_view ext)
- : cmDirectoryListGenerator{ names }
+ : cmDirectoryListGenerator{ names, true }
, Extension{ ext }
{
}
@@ -327,49 +339,14 @@
const cm::string_view Extension;
};
-class cmFileListGeneratorGlob
+class cmAnyDirectoryListGenerator : public cmProjectDirectoryListGenerator
{
public:
- cmFileListGeneratorGlob(cm::string_view pattern)
- : Pattern(pattern)
- , Files{}
- , Current{}
+ cmAnyDirectoryListGenerator(cmFindPackageCommand::SortOrderType so,
+ cmFindPackageCommand::SortDirectionType sd)
+ : cmProjectDirectoryListGenerator(nullptr, so, sd, false)
{
}
-
- std::string GetNextCandidate(const std::string& parent)
- {
- if (this->Files.empty()) {
- // Glob the set of matching files.
- std::string expr = cmStrCat(parent, this->Pattern);
- cmsys::Glob g;
- if (!g.FindFiles(expr)) {
- return {};
- }
- this->Files = g.GetFiles();
- this->Current = this->Files.cbegin();
- }
-
- // Skip non-directories
- for (; this->Current != this->Files.cend() &&
- !cmSystemTools::FileIsDirectory(*this->Current);
- ++this->Current) {
- }
-
- return (this->Current != this->Files.cend()) ? *this->Current++
- : std::string{};
- }
-
- void Reset()
- {
- this->Files.clear();
- this->Current = this->Files.cbegin();
- }
-
-private:
- cm::string_view Pattern;
- std::vector<std::string> Files;
- std::vector<std::string>::const_iterator Current;
};
#if defined(__LCC__)
@@ -777,7 +754,7 @@
doing = DoingNone;
} else if (args[i] == "REGISTRY_VIEW") {
if (++i == args.size()) {
- this->SetError("missing required argument for \"REGISTRY_VIEW\"");
+ this->SetError("missing required argument for REGISTRY_VIEW");
return false;
}
auto view = cmWindowsRegistry::ToView(args[i]);
@@ -786,7 +763,7 @@
this->RegistryViewDefined = true;
} else {
this->SetError(
- cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[i]));
+ cmStrCat("given invalid value for REGISTRY_VIEW: ", args[i]));
return false;
}
} else if (this->CheckCommonArgument(args[i])) {
@@ -853,7 +830,7 @@
this->SetError(
cmStrCat("called with components that are both required and "
"optional:\n",
- cmWrap(" ", doubledComponents, "", "\n"), "\n"));
+ cmWrap(" ", doubledComponents, "", "\n"), '\n'));
return false;
}
@@ -1389,7 +1366,7 @@
debugBuffer = cmStrCat(debugBuffer, "The file was not found.\n");
} else {
debugBuffer =
- cmStrCat(debugBuffer, "The file was found at\n ", mfile, "\n");
+ cmStrCat(debugBuffer, "The file was found at\n ", mfile, '\n');
}
this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer);
}
@@ -1404,13 +1381,11 @@
case cmPolicies::WARN: {
this->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
- cmStrCat(cmPolicies::GetPolicyWarning(it->second), "\n"));
+ cmStrCat(cmPolicies::GetPolicyWarning(it->second), '\n'));
CM_FALLTHROUGH;
}
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
return true;
}
@@ -1547,12 +1522,13 @@
std::ostringstream e;
std::ostringstream aw;
if (configFileSetFOUNDFalse) {
- /* clang-format off */
e << "Found package configuration file:\n"
- " " << this->FileFound << "\n"
- "but it set " << foundVar << " to FALSE so package \"" <<
- this->Name << "\" is considered to be NOT FOUND.";
- /* clang-format on */
+ " "
+ << this->FileFound
+ << "\n"
+ "but it set "
+ << foundVar << " to FALSE so package \"" << this->Name
+ << "\" is considered to be NOT FOUND.";
if (!notFoundMessage.empty()) {
e << " Reason given by package: \n" << notFoundMessage << "\n";
}
@@ -1565,7 +1541,7 @@
<< "\" that "
<< (this->VersionExact ? "exactly matches" : "is compatible with")
<< " requested version "
- << (this->VersionRange.empty() ? "" : "range ") << "\""
+ << (this->VersionRange.empty() ? "" : "range ") << '"'
<< this->VersionComplete
<< "\".\n"
"The following configuration files were considered but not "
@@ -1573,7 +1549,7 @@
for (ConfigFileInfo const& info :
cmMakeRange(this->ConsideredConfigs.cbegin(), duplicate_end)) {
- e << " " << info.filename << ", version: " << info.version << "\n";
+ e << " " << info.filename << ", version: " << info.version << '\n';
}
} else {
std::string requestedVersionString;
@@ -1601,15 +1577,12 @@
e << "Could not find a package configuration file provided by \""
<< this->Name << "\"" << requestedVersionString
<< " with any of the following names:\n"
- << cmWrap(" ", this->Configs, "", "\n") << "\n";
+ << cmWrap(" ", this->Configs, "", "\n") << '\n';
}
e << "Add the installation prefix of \"" << this->Name
- << "\" to "
- "CMAKE_PREFIX_PATH or set \""
- << this->Variable
- << "\" to a "
- "directory containing one of the above files. "
+ << "\" to CMAKE_PREFIX_PATH or set \"" << this->Variable
+ << "\" to a directory containing one of the above files. "
"If \""
<< this->Name
<< "\" provides a separate development "
@@ -1735,7 +1708,7 @@
if (this->DebugMode) {
if (found) {
this->DebugBuffer = cmStrCat(
- this->DebugBuffer, "The file was found at\n ", this->FileFound, "\n");
+ this->DebugBuffer, "The file was found at\n ", this->FileFound, '\n');
} else {
this->DebugBuffer =
cmStrCat(this->DebugBuffer, "The file was not found.\n");
@@ -1911,12 +1884,6 @@
case cmPolicies::OLD:
// OLD behavior is to ignore the <PackageName>_ROOT variables.
return;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
- return;
case cmPolicies::NEW: {
// NEW behavior is to honor the <PackageName>_ROOT variables.
} break;
@@ -1947,12 +1914,6 @@
rootDEF = nullptr;
rootENV = cm::nullopt;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0144));
- return;
case cmPolicies::NEW: {
// NEW behavior is to honor the <PACKAGENAME>_ROOT variables.
} break;
@@ -1965,11 +1926,13 @@
cmExpandList(*rootDEF, rootPaths);
}
if (rootEnv) {
- std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
+ std::vector<std::string> p =
+ cmSystemTools::SplitEnvPathNormalized(*rootEnv);
std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
}
if (rootENV) {
- std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootENV);
+ std::vector<std::string> p =
+ cmSystemTools::SplitEnvPathNormalized(*rootENV);
std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
}
}
@@ -2120,9 +2083,9 @@
// Use the system search path to generate prefixes.
// Relative paths are interpreted with respect to the current
// working directory.
- std::vector<std::string> tmp;
- cmSystemTools::GetPath(tmp);
- for (std::string const& i : tmp) {
+ std::vector<std::string> envPATH =
+ cmSystemTools::GetEnvPathNormalized("PATH");
+ for (std::string const& i : envPATH) {
// If the path is a PREFIX/bin case then add its parent instead.
if ((cmHasLiteralSuffix(i, "/bin")) || (cmHasLiteralSuffix(i, "/sbin"))) {
paths.AddPath(cmSystemTools::GetFilenamePath(i));
@@ -2442,8 +2405,12 @@
{
assert(!dir.empty() && dir.back() == '/');
- // Look for the file in this directory.
std::string const d = dir.substr(0, dir.size() - 1);
+ if (cm::contains(this->IgnoredPaths, d)) {
+ return false;
+ }
+
+ // Look for the file in this directory.
if (this->FindConfigFile(d, this->FileFound)) {
// Remove duplicate slashes.
cmSystemTools::ConvertToUnixSlashes(this->FileFound);
@@ -2455,14 +2422,10 @@
bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
std::string& file)
{
- if (this->IgnoredPaths.count(dir)) {
- return false;
- }
-
for (std::string const& c : this->Configs) {
file = cmStrCat(dir, '/', c);
if (this->DebugMode) {
- this->DebugBuffer = cmStrCat(this->DebugBuffer, " ", file, "\n");
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, " ", file, '\n');
}
if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) {
// Allow resolving symlinks when the config file is found through a link
@@ -2667,8 +2630,8 @@
auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
auto firstPkgDirGen =
- cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
- this->SortDirection };
+ cmProjectDirectoryListGenerator{ &this->Names, this->SortOrder,
+ this->SortDirection, false };
// PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
if (TryGeneratedPaths(searchFn, prefix, iCMakeGen)) {
@@ -2686,8 +2649,8 @@
}
auto secondPkgDirGen =
- cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
- this->SortDirection };
+ cmProjectDirectoryListGenerator{ &this->Names, this->SortOrder,
+ this->SortDirection, false };
// PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/(Foo|foo|FOO).*/
if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, iCMakeGen,
@@ -2763,10 +2726,11 @@
auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
auto fwGen =
- cmMacProjectDirectoryListGenerator{ this->Names, ".framework"_s };
+ cmMacProjectDirectoryListGenerator{ &this->Names, ".framework"_s };
auto rGen = cmAppendPathSegmentGenerator{ "Resources"_s };
auto vGen = cmAppendPathSegmentGenerator{ "Versions"_s };
- auto grGen = cmFileListGeneratorGlob{ "/*/Resources"_s };
+ auto anyGen =
+ cmAnyDirectoryListGenerator{ this->SortOrder, this->SortDirection };
// <prefix>/Foo.framework/Resources/
if (TryGeneratedPaths(searchFn, prefix, fwGen, rGen)) {
@@ -2779,12 +2743,13 @@
}
// <prefix>/Foo.framework/Versions/*/Resources/
- if (TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen)) {
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, vGen, anyGen, rGen)) {
return true;
}
// <prefix>/Foo.framework/Versions/*/Resources/CMake/
- return TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen, iCMakeGen);
+ return TryGeneratedPaths(searchFn, prefix, fwGen, vGen, anyGen, rGen,
+ iCMakeGen);
}
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
@@ -2799,7 +2764,7 @@
return this->SearchDirectory(fullPath);
};
- auto appGen = cmMacProjectDirectoryListGenerator{ this->Names, ".app"_s };
+ auto appGen = cmMacProjectDirectoryListGenerator{ &this->Names, ".app"_s };
auto crGen = cmAppendPathSegmentGenerator{ "Contents/Resources"_s };
// <prefix>/Foo.app/Contents/Resources
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 74a69d8..b6a7834 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -106,7 +106,7 @@
globIt.FindFiles(glob);
std::vector<std::string> files = globIt.GetFiles();
if (!files.empty()) {
- std::string fheader = cmSystemTools::CollapseFullPath(files[0]);
+ std::string fheader = cmSystemTools::ToNormalizedPathOnDisk(files[0]);
debug.FoundAt(fheader);
if (this->IncludeFileInPath) {
return fheader;
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index dd22b41..d5603bd 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -48,12 +48,6 @@
// Current names under consideration.
std::vector<std::string> Names;
- // Current name with extension under consideration.
- std::string TestNameExt;
-
- // Current full path under consideration.
- std::string TestPath;
-
// Debug state
cmFindBaseDebugState DebugSearches;
cmMakefile* Makefile;
@@ -81,8 +75,6 @@
{
return std::any_of(this->Names.begin(), this->Names.end(),
[this, &path](std::string const& n) -> bool {
- // Only perform search relative to current directory
- // if the file name contains a directory separator.
return this->CheckDirectoryForName(path, n);
});
}
@@ -93,20 +85,23 @@
if (!ext.empty() && cmHasSuffix(name, ext)) {
return false;
}
- this->TestNameExt = cmStrCat(name, ext);
- this->TestPath = cmSystemTools::CollapseFullPath(
- this->TestNameExt, path);
- bool exists = this->FileIsValid(this->TestPath);
- exists ? this->DebugSearches.FoundAt(this->TestPath)
- : this->DebugSearches.FailedAt(this->TestPath);
- if (exists) {
- this->BestPath = this->TestPath;
- return true;
+ std::string testNameExt = cmStrCat(name, ext);
+ std::string testPath =
+ cmSystemTools::CollapseFullPath(testNameExt, path);
+ if (this->FileIsExecutable(testPath)) {
+ testPath =
+ cmSystemTools::ToNormalizedPathOnDisk(testPath);
+ if (this->FindBase->Validate(testPath)) {
+ this->BestPath = testPath;
+ this->DebugSearches.FoundAt(testPath);
+ return true;
+ }
}
+ this->DebugSearches.FailedAt(testPath);
return false;
});
}
- bool FileIsValid(std::string const& file) const
+ bool FileIsExecutable(std::string const& file) const
{
if (!this->FileIsExecutableCMP0109(file)) {
return false;
@@ -122,7 +117,7 @@
}
}
#endif
- return this->FindBase->Validate(file);
+ return true;
}
bool FileIsExecutableCMP0109(std::string const& file) const
{
@@ -130,8 +125,6 @@
case cmPolicies::OLD:
return cmSystemTools::FileExists(file, true);
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
return cmSystemTools::FileIsExecutable(file);
default:
break;
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 1349308..8d21aa8 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -72,11 +72,11 @@
static std::string StripEmptyListElements(const std::string& input);
- static inline bool StartsWithGeneratorExpression(const std::string& input)
+ static bool StartsWithGeneratorExpression(const std::string& input)
{
return input.length() >= 2 && input[0] == '$' && input[1] == '<';
}
- static inline bool StartsWithGeneratorExpression(const char* input)
+ static bool StartsWithGeneratorExpression(const char* input)
{
return input && input[0] == '$' && input[1] == '<';
}
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 817437e..2e8bb32 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -253,8 +253,6 @@
// which ends up being used relative to the working dir.
resultPath = relativePath;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// NEW behavior is to interpret the relative path with respect
// to the current source or binary directory.
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 80eedf5..3055d61 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -333,8 +333,6 @@
return "0";
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
values.assign(parameters[1], cmList::EmptyElements::Yes);
break;
@@ -1931,8 +1929,6 @@
case cmPolicies::OLD:
return "1";
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
break;
}
}
@@ -3395,7 +3391,7 @@
#undef RETURN_POLICY_ID
assert(false && "Unreachable code. Not a valid policy");
- return cmPolicies::CMP0002;
+ return cmPolicies::CMPCOUNT;
}
static const struct TargetPolicyNode : public cmGeneratorExpressionNode
@@ -3431,8 +3427,6 @@
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(policyForString(policy)));
CM_FALLTHROUGH;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::OLD:
return "0";
case cmPolicies::NEW:
@@ -3527,8 +3521,6 @@
case cmPolicies::OLD:
context->DependTargets.insert(target);
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
break;
}
diff --git a/Source/cmGeneratorOptions.h b/Source/cmGeneratorOptions.h
new file mode 100644
index 0000000..0e17f56
--- /dev/null
+++ b/Source/cmGeneratorOptions.h
@@ -0,0 +1,35 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+/** Flag if byproducts shall also be considered. */
+enum class cmSourceOutputKind
+{
+ OutputOnly,
+ OutputOrByproduct
+};
+
+/** What scanner to use for dependencies lookup. */
+enum class cmDependencyScannerKind
+{
+ CMake,
+ Compiler
+};
+
+/** What to compute language flags for */
+enum class cmBuildStep
+{
+ Compile,
+ Link
+};
+
+/** What compilation mode the swift files are in */
+enum class cmSwiftCompileMode
+{
+ Wholemodule,
+ Incremental,
+ Singlefile,
+ Unknown,
+};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index fb92771..e87cdff 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -30,6 +30,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
+#include "cmGeneratorOptions.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmLocalGenerator.h"
@@ -2473,8 +2474,6 @@
case cmPolicies::OLD:
// The OLD behavior is to not add explicit language flags.
return;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
// The NEW behavior is to add explicit language flags.
break;
@@ -2516,8 +2515,8 @@
return;
}
- return this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "CUDA",
- std::move(arch), flags);
+ this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "CUDA",
+ std::move(arch), flags);
}
void cmGeneratorTarget::AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink,
@@ -2695,8 +2694,9 @@
}
if (this->Makefile->GetSafeDefinition("CMAKE_HIP_PLATFORM") == "nvidia") {
- return this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "HIP",
- std::move(arch), flags);
+ this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "HIP",
+ std::move(arch), flags);
+ return;
}
cmList options(arch);
@@ -4758,15 +4758,6 @@
cm->IssueMessage(MessageType::FATAL_ERROR, e.str(),
this->GetBacktrace());
} break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS: {
- std::ostringstream e;
- e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0004) << "\n"
- << "Target \"" << this->GetName() << "\" links to item \"" << item
- << "\" which has leading or trailing whitespace.";
- cm->IssueMessage(MessageType::FATAL_ERROR, e.str(),
- this->GetBacktrace());
- } break;
}
}
return lib;
@@ -5925,8 +5916,6 @@
// The OLD behavior is to not scan the source.
policyAnswer = CxxModuleSupport::Disabled;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
// The NEW behavior is to scan the source if the compiler supports
// scanning and the generator supports it.
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 8ae98e8..d5a3f98 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -264,9 +264,6 @@
cmLinkInterface const* GetLinkInterface(
const std::string& config, const cmGeneratorTarget* headTarget) const;
- void ComputeLinkInterface(const std::string& config,
- cmOptionalLinkInterface& iface,
- const cmGeneratorTarget* head) const;
enum class UseTo
{
@@ -672,6 +669,10 @@
std::vector<BT<std::string>> GetStaticLibraryLinkOptions(
std::string const& config, std::string const& language) const;
+ std::vector<BT<std::string>>& ResolveArchiverWrapper(
+ std::vector<BT<std::string>>& result, const std::string& language,
+ bool joinItems = false) const;
+
void GetLinkDirectories(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const;
@@ -1357,6 +1358,10 @@
LookupLinkItemScope* scope,
LookupSelf lookupSelf) const;
+ std::vector<BT<std::string>>& ResolvePrefixWrapper(
+ std::vector<BT<std::string>>& result, cm::string_view prefix,
+ const std::string& language, bool joinItems) const;
+
std::vector<BT<std::string>> GetSourceFilePaths(
std::string const& config) const;
std::vector<BT<cmSourceFile*>> GetSourceFilesWithoutObjectLibraries(
diff --git a/Source/cmGeneratorTarget_IncludeDirectories.cxx b/Source/cmGeneratorTarget_IncludeDirectories.cxx
index a05b1a2..fc89331 100644
--- a/Source/cmGeneratorTarget_IncludeDirectories.cxx
+++ b/Source/cmGeneratorTarget_IncludeDirectories.cxx
@@ -164,8 +164,6 @@
case cmPolicies::OLD:
messageType = MessageType::AUTHOR_WARNING;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
break;
}
@@ -204,8 +202,6 @@
case cmPolicies::OLD:
noMessage = true;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
diff --git a/Source/cmGeneratorTarget_Link.cxx b/Source/cmGeneratorTarget_Link.cxx
index 50bcefa..87c41b4 100644
--- a/Source/cmGeneratorTarget_Link.cxx
+++ b/Source/cmGeneratorTarget_Link.cxx
@@ -459,8 +459,6 @@
} break;
case cmPolicies::OLD:
return true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
@@ -687,13 +685,6 @@
void cmGeneratorTarget::ComputeLinkInterface(
const std::string& config, cmOptionalLinkInterface& iface,
- cmGeneratorTarget const* headTarget) const
-{
- this->ComputeLinkInterface(config, iface, headTarget, false);
-}
-
-void cmGeneratorTarget::ComputeLinkInterface(
- const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget, bool secondPass) const
{
if (iface.Explicit) {
@@ -1330,8 +1321,6 @@
case cmPolicies::WARN:
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
dagChecker.SetTransitivePropertiesOnlyCMP0131();
break;
@@ -1390,8 +1379,6 @@
case cmPolicies::OLD:
noMessage = true;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
@@ -1455,8 +1442,7 @@
std::vector<std::string> debugConfigs =
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
- cmTargetLinkLibraryType linkType =
- CMP0003_ComputeLinkType(config, debugConfigs);
+ cmTargetLinkLibraryType linkType = ComputeLinkType(config, debugConfigs);
cmTarget::LinkLibraryVectorType const& oldllibs =
this->Target->GetOriginalLinkLibraries();
diff --git a/Source/cmGeneratorTarget_LinkDirectories.cxx b/Source/cmGeneratorTarget_LinkDirectories.cxx
index bd89497..5882aca 100644
--- a/Source/cmGeneratorTarget_LinkDirectories.cxx
+++ b/Source/cmGeneratorTarget_LinkDirectories.cxx
@@ -60,8 +60,6 @@
case cmPolicies::OLD:
noMessage = true;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
diff --git a/Source/cmGeneratorTarget_Options.cxx b/Source/cmGeneratorTarget_Options.cxx
index d8b3eb3..f1f0703 100644
--- a/Source/cmGeneratorTarget_Options.cxx
+++ b/Source/cmGeneratorTarget_Options.cxx
@@ -95,7 +95,7 @@
enum class NestedLinkerFlags
{
PreserveAsSpelled,
- Normalize,
+ Normalize
};
std::vector<BT<std::string>> wrapOptions(
@@ -363,8 +363,6 @@
this, config, language, &dagChecker, *entry));
} break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
break;
}
}
@@ -527,32 +525,31 @@
return result;
}
-std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
- std::vector<BT<std::string>>& result, const std::string& language,
- bool joinItems) const
+std::vector<BT<std::string>>& cmGeneratorTarget::ResolvePrefixWrapper(
+ std::vector<BT<std::string>>& result, cm::string_view prefix,
+ const std::string& language, bool joinItems) const
{
- // replace "LINKER:" prefixed elements by actual linker wrapper
+ // replace "LINKER:" or "ARCHIVER:" prefixed elements by actual linker or
+ // archiver wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
- "CMAKE_" + language +
- (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
- : "_LINKER_WRAPPER_FLAG")));
+ cmStrCat("CMAKE_", language, (this->IsDeviceLink() ? "_DEVICE_" : "_"),
+ prefix, "_WRAPPER_FLAG")));
cmList wrapperFlag{ wrapper };
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
- "CMAKE_" + language +
- (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG_SEP"
- : "_LINKER_WRAPPER_FLAG_SEP")));
+ cmStrCat("CMAKE_", language, (this->IsDeviceLink() ? "_DEVICE_" : "_"),
+ prefix, "_WRAPPER_FLAG_SEP")));
bool concatFlagAndArgs = true;
if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
concatFlagAndArgs = false;
wrapperFlag.pop_back();
}
- const std::string LINKER{ "LINKER:" };
+ const std::string PREFIX{ cmStrCat(prefix, ':') };
const std::string SHELL{ "SHELL:" };
- const std::string LINKER_SHELL = LINKER + SHELL;
+ const std::string PREFIX_SHELL = cmStrCat(PREFIX, SHELL);
for (auto entry = result.begin(); entry != result.end(); ++entry) {
- if (entry->Value.compare(0, LINKER.length(), LINKER) != 0) {
+ if (entry->Value.compare(0, PREFIX.length(), PREFIX) != 0) {
continue;
}
@@ -560,27 +557,28 @@
cmListFileBacktrace bt = std::move(entry->Backtrace);
entry = result.erase(entry);
- std::vector<std::string> linkerOptions;
- if (value.compare(0, LINKER_SHELL.length(), LINKER_SHELL) == 0) {
+ std::vector<std::string> options;
+ if (value.compare(0, PREFIX_SHELL.length(), PREFIX_SHELL) == 0) {
cmSystemTools::ParseUnixCommandLine(
- value.c_str() + LINKER_SHELL.length(), linkerOptions);
+ value.c_str() + PREFIX_SHELL.length(), options);
} else {
- linkerOptions = cmTokenize(value.substr(LINKER.length()), ",");
+ options =
+ cmTokenize(value.substr(PREFIX.length()), ',', cmTokenizerMode::New);
}
- if (linkerOptions.empty() ||
- (linkerOptions.size() == 1 && linkerOptions.front().empty())) {
+ if (options.empty()) {
continue;
}
// for now, raise an error if prefix SHELL: is part of arguments
- if (std::find_if(linkerOptions.begin(), linkerOptions.end(),
+ if (std::find_if(options.begin(), options.end(),
[&SHELL](const std::string& item) -> bool {
return item.find(SHELL) != std::string::npos;
- }) != linkerOptions.end()) {
+ }) != options.end()) {
this->LocalGenerator->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
- "'SHELL:' prefix is not supported as part of 'LINKER:' arguments.",
+ cmStrCat("'SHELL:' prefix is not supported as part of '", prefix,
+ ":' arguments."),
this->GetBacktrace());
return result;
}
@@ -588,21 +586,30 @@
// Very old versions of the C++ standard library return void for insert, so
// can't use it to get the new iterator
const auto index = entry - result.begin();
- std::vector<BT<std::string>> options =
- wrapOptions(linkerOptions, bt, wrapperFlag, wrapperSep,
- concatFlagAndArgs, NestedLinkerFlags::PreserveAsSpelled);
+ std::vector<BT<std::string>> processedOptions =
+ wrapOptions(options, bt, wrapperFlag, wrapperSep, concatFlagAndArgs,
+ NestedLinkerFlags::PreserveAsSpelled);
if (joinItems) {
result.insert(
- entry, cmJoin(cmMakeRange(options.begin(), options.end()), " "_s));
+ entry,
+ cmJoin(cmMakeRange(processedOptions.begin(), processedOptions.end()),
+ " "_s));
entry = std::next(result.begin(), index);
} else {
- result.insert(entry, options.begin(), options.end());
- entry = std::next(result.begin(), index + options.size() - 1);
+ result.insert(entry, processedOptions.begin(), processedOptions.end());
+ entry = std::next(result.begin(), index + processedOptions.size() - 1);
}
}
return result;
}
+std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
+ std::vector<BT<std::string>>& result, const std::string& language,
+ bool joinItems) const
+{
+ return this->ResolvePrefixWrapper(result, "LINKER"_s, language, joinItems);
+}
+
void cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<std::string>& result, const std::string& config,
const std::string& language) const
@@ -635,9 +642,20 @@
processOptions(this, entries, result, uniqueOptions, false,
"static library link options", OptionsParse::Shell);
+ // Last step: replace "ARCHIVER:" prefixed elements by
+ // actual archiver wrapper
+ this->ResolveArchiverWrapper(result, language);
+
return result;
}
+std::vector<BT<std::string>>& cmGeneratorTarget::ResolveArchiverWrapper(
+ std::vector<BT<std::string>>& result, const std::string& language,
+ bool joinItems) const
+{
+ return this->ResolvePrefixWrapper(result, "ARCHIVER"_s, language, joinItems);
+}
+
void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index d892cfa..d05f1c6 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -90,8 +90,6 @@
status.GetMakefile().GetDefineFlagsCMP0059());
return true;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
break;
}
}
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 1815c4d..febece0 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -107,12 +107,19 @@
}
}
}
- // Collapse the path to its simplest form.
- result = cmSystemTools::CollapseFullPath(filename, baseDir);
- if (args[2] == "REALPATH") {
+ if (args[2] == "ABSOLUTE") {
+ // Collapse the path to its simplest form.
+ result = cmSystemTools::CollapseFullPath(filename, baseDir);
+ } else {
+ // Convert relative paths to absolute paths
+ result = filename;
+ if (!cmSystemTools::FileIsFullPath(result)) {
+ result = cmStrCat(baseDir, '/', result);
+ }
// Resolve symlinks if possible
result = cmSystemTools::GetRealPath(result);
}
+ result = cmSystemTools::GetActualCaseForPath(result);
} else {
std::string err = "unknown component " + args[2];
status.SetError(err);
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 8e21da0..9637349 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -380,8 +380,6 @@
return StoreResult(infoType, status.GetMakefile(), variable,
mf->GetDefineFlagsCMP0059());
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
break;
}
}
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index e1ae9b2..db26860 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -60,8 +60,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
issueMessage = true;
messageType = MessageType::FATAL_ERROR;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index a92faef..888dfd3 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index e3a38b0..1d1d932 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1057,12 +1057,6 @@
// OLD behavior is to convert AppleClang to Clang.
mf->AddDefinition(compilerIdVar, "Clang");
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- mf->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0025));
- break;
case cmPolicies::NEW:
// NEW behavior is to keep AppleClang.
break;
@@ -1093,12 +1087,6 @@
mf->AddDefinition("CMAKE_COMPILER_IS_GNUCXX", "1");
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- mf->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0047));
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior is to keep QCC.
break;
@@ -1124,12 +1112,6 @@
// OLD behavior is to convert XLClang to XL.
mf->AddDefinition(compilerIdVar, "XL");
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- mf->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0089));
- break;
case cmPolicies::NEW:
// NEW behavior is to keep AppleClang.
break;
@@ -1172,12 +1154,6 @@
mf->RemoveDefinition(emulated);
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- mf->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0129));
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior is to keep LCC.
break;
@@ -1503,12 +1479,14 @@
// This generator does not support duplicate custom targets.
std::ostringstream e;
+ // clang-format off
e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
- << "global property. "
- << "The \"" << this->GetName() << "\" generator does not support "
- << "duplicate custom targets. "
- << "Consider using a Makefiles generator or fix the project to not "
- << "use duplicate target names.";
+ "global property. "
+ "The \"" << this->GetName() << "\" generator does not support "
+ "duplicate custom targets. "
+ "Consider using a Makefiles generator or fix the project to not "
+ "use duplicate target names.";
+ // clang-format on
cmSystemTools::Error(e.str());
return false;
}
@@ -1777,11 +1755,12 @@
if (!this->CMP0042WarnTargets.empty()) {
std::ostringstream w;
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0042) << "\n";
- w << "MACOSX_RPATH is not specified for"
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0042)
+ << "\n"
+ "MACOSX_RPATH is not specified for"
" the following targets:\n";
for (std::string const& t : this->CMP0042WarnTargets) {
- w << " " << t << "\n";
+ w << ' ' << t << '\n';
}
this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING,
w.str());
@@ -1798,7 +1777,7 @@
;
/* clang-format on */
for (std::string const& t : this->CMP0068WarnTargets) {
- w << " " << t << "\n";
+ w << ' ' << t << '\n';
}
this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING,
w.str());
@@ -1817,15 +1796,21 @@
void cmGlobalGenerator::WriteInstallJson() const
{
- if (this->GetCMakeInstance()->GetState()->GetGlobalPropertyAsBool(
- "INSTALL_PARALLEL")) {
- Json::Value index(Json::objectValue);
- index["InstallScripts"] = Json::arrayValue;
- for (const auto& file : this->InstallScripts) {
- index["InstallScripts"].append(file);
- }
- this->WriteJsonContent("CMakeFiles/InstallScripts.json", index);
+ Json::Value index(Json::objectValue);
+ index["InstallScripts"] = Json::arrayValue;
+ for (const auto& file : this->InstallScripts) {
+ index["InstallScripts"].append(file);
}
+ index["Parallel"] =
+ this->GetCMakeInstance()->GetState()->GetGlobalPropertyAsBool(
+ "INSTALL_PARALLEL");
+ if (this->SupportsDefaultConfigs()) {
+ index["Configs"] = Json::arrayValue;
+ for (auto const& config : this->GetDefaultConfigs()) {
+ index["Configs"].append(config);
+ }
+ }
+ this->WriteJsonContent("CMakeFiles/InstallScripts.json", index);
}
#endif
@@ -2218,9 +2203,9 @@
cmBuildOptions defaultBuildOptions(false, fast, PackageResolveMode::Disable);
std::stringstream ostr;
- auto ret =
- this->Build(jobs, srcdir, bindir, projectName, newTarget, ostr, "", config,
- defaultBuildOptions, true, this->TryCompileTimeout);
+ auto ret = this->Build(jobs, srcdir, bindir, projectName, newTarget, ostr,
+ "", config, defaultBuildOptions, true,
+ this->TryCompileTimeout, cmSystemTools::OUTPUT_NONE);
output = ostr.str();
return ret;
}
@@ -2249,7 +2234,7 @@
const std::string& projectName, const std::vector<std::string>& targets,
std::ostream& ostr, const std::string& makeCommandCSTR,
const std::string& config, const cmBuildOptions& buildOptions, bool verbose,
- cmDuration timeout, cmSystemTools::OutputOption outputflag,
+ cmDuration timeout, cmSystemTools::OutputOption outputMode,
std::vector<std::string> const& nativeOptions)
{
bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
@@ -2261,8 +2246,7 @@
ostr << "Change Dir: '" << bindir << '\'' << std::endl;
if (workdir.Failed()) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
- std::string err = cmStrCat("Failed to change directory: ",
- std::strerror(workdir.GetLastResult()));
+ std::string const& err = workdir.GetError();
cmSystemTools::Error(err);
ostr << err << std::endl;
return 1;
@@ -2274,17 +2258,18 @@
int retVal = 0;
cmSystemTools::SetRunCommandHideConsole(true);
- std::string outputBuffer;
- std::string* outputPtr = &outputBuffer;
+
+ // Capture build command output when outputMode == OUTPUT_NONE.
+ std::string outputBuf;
std::vector<GeneratedMakeCommand> makeCommand = this->GenerateBuildCommand(
makeCommandCSTR, projectName, bindir, targets, realConfig, jobs, verbose,
buildOptions, nativeOptions);
// Workaround to convince some commands to produce output.
- if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
+ if (outputMode == cmSystemTools::OUTPUT_PASSTHROUGH &&
makeCommand.back().RequiresOutputForward) {
- outputflag = cmSystemTools::OUTPUT_FORWARD;
+ outputMode = cmSystemTools::OUTPUT_FORWARD;
}
// should we do a clean first?
@@ -2303,16 +2288,16 @@
return 1;
}
if (!cmSystemTools::RunSingleCommand(cleanCommand.front().PrimaryCommand,
- outputPtr, outputPtr, &retVal,
- nullptr, outputflag, timeout)) {
+ &outputBuf, &outputBuf, &retVal,
+ nullptr, outputMode, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed.");
- ostr << *outputPtr << "\nGenerator: execution of make clean failed."
+ ostr << outputBuf << "\nGenerator: execution of make clean failed."
<< std::endl;
return 1;
}
- ostr << *outputPtr;
+ ostr << outputBuf;
}
// now build
@@ -2334,22 +2319,22 @@
}
ostr << outputMakeCommandStr << std::endl;
- if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr,
- outputPtr, &retVal, nullptr,
- outputflag, timeout)) {
+ if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, &outputBuf,
+ &outputBuf, &retVal, nullptr,
+ outputMode, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error(
- cmStrCat("Generator: execution of make failed. Make command was: ",
+ cmStrCat("Generator: build tool execution failed, command was: ",
makeCommandStr));
- ostr << *outputPtr
- << "\nGenerator: execution of make failed. Make command was: "
+ ostr << outputBuf
+ << "\nGenerator: build tool execution failed, command was: "
<< outputMakeCommandStr << std::endl;
return 1;
}
- ostr << *outputPtr << std::flush;
+ ostr << outputBuf << std::flush;
if (needBuildOutput) {
- buildOutput += *outputPtr;
+ buildOutput += outputBuf;
}
}
ostr << std::endl;
@@ -2811,21 +2796,19 @@
bool issueMessage = false;
switch (tgt->GetPolicyStatusCMP0037()) {
case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << '\n';
issueMessage = true;
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
issueMessage = true;
messageType = MessageType::FATAL_ERROR;
break;
}
if (issueMessage) {
e << "The target name \"" << targetNameAsWritten << "\" is reserved "
- << reason << ".";
+ << reason << '.';
if (messageType == MessageType::AUTHOR_WARNING) {
e << " It may result in undefined behavior.";
}
@@ -2984,7 +2967,6 @@
}
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
- singleLine.push_back("--force-new-ctest-process");
cmList args(mf->GetDefinition("CMAKE_CTEST_ARGUMENTS"));
for (auto const& arg : args) {
singleLine.push_back(arg);
@@ -3020,14 +3002,12 @@
bool issueMessage = false;
switch (policyStatus) {
case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0171) << "\n";
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0171) << '\n';
issueMessage = true;
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
issueMessage = true;
messageType = MessageType::FATAL_ERROR;
break;
@@ -3064,9 +3044,12 @@
std::string edit_cmd = this->GetEditCacheCommand();
if (!edit_cmd.empty()) {
singleLine.push_back(std::move(edit_cmd));
- if (this->GetCMakeInstance()->GetIgnoreWarningAsError()) {
+ if (this->GetCMakeInstance()->GetIgnoreCompileWarningAsError()) {
singleLine.push_back("--compile-no-warning-as-error");
}
+ if (this->GetCMakeInstance()->GetIgnoreLinkWarningAsError()) {
+ singleLine.push_back("--link-no-warning-as-error");
+ }
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.Message = "Running CMake cache editor...";
@@ -3100,9 +3083,12 @@
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCMakeCommand());
singleLine.push_back("--regenerate-during-build");
- if (this->GetCMakeInstance()->GetIgnoreWarningAsError()) {
+ if (this->GetCMakeInstance()->GetIgnoreCompileWarningAsError()) {
singleLine.push_back("--compile-no-warning-as-error");
}
+ if (this->GetCMakeInstance()->GetIgnoreLinkWarningAsError()) {
+ singleLine.push_back("--link-no-warning-as-error");
+ }
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.CommandLines.push_back(std::move(singleLine));
@@ -3127,8 +3113,8 @@
std::set<std::string>* componentsSet = &this->InstallComponents;
std::ostringstream ostr;
if (!componentsSet->empty()) {
- ostr << "Available install components are: ";
- ostr << cmWrap('"', *componentsSet, '"', " ");
+ ostr << "Available install components are: "
+ << cmWrap('"', *componentsSet, '"', " ");
} else {
ostr << "Only default component available";
}
@@ -3743,7 +3729,7 @@
fout << "# Hashes of file build rules.\n";
for (auto const& rh : this->RuleHashes) {
fout.write(rh.second.Data, 32);
- fout << " " << rh.first << "\n";
+ fout << ' ' << rh.first << '\n';
}
}
}
@@ -3761,7 +3747,7 @@
continue;
}
this->WriteSummary(tgt.get());
- fout << tgt->GetSupportDirectory() << "\n";
+ fout << tgt->GetSupportDirectory() << '\n';
}
}
}
@@ -3799,7 +3785,7 @@
if (!labels.empty()) {
fout << "# Target labels\n";
for (std::string const& l : labels) {
- fout << " " << l << "\n";
+ fout << ' ' << l << '\n';
lj_target_labels.append(l);
}
}
@@ -3822,12 +3808,12 @@
}
for (auto const& li : directoryLabelsList) {
- fout << " " << li << "\n";
+ fout << ' ' << li << '\n';
lj_target_labels.append(li);
}
for (auto const& li : cmakeDirectoryLabelsList) {
- fout << " " << li << "\n";
+ fout << ' ' << li << '\n';
lj_target_labels.append(li);
}
@@ -3844,13 +3830,13 @@
for (cmSourceFile* sf : cmMakeRange(sources.cbegin(), sourcesEnd)) {
Json::Value& lj_source = lj_sources.append(Json::objectValue);
std::string const& sfp = sf->ResolveFullPath();
- fout << sfp << "\n";
+ fout << sfp << '\n';
lj_source["file"] = sfp;
if (cmValue svalue = sf->GetProperty("LABELS")) {
Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
labels.assign(*svalue);
for (auto const& label : labels) {
- fout << " " << label << "\n";
+ fout << ' ' << label << '\n';
lj_source_labels.append(label);
}
}
@@ -4021,3 +4007,16 @@
{
this->InstallScripts.push_back(file);
}
+
+void cmGlobalGenerator::AddTestFile(std::string const& file)
+{
+ this->TestFiles.push_back(file);
+}
+
+void cmGlobalGenerator::AddCMakeFilesToRebuild(
+ std::vector<std::string>& files) const
+{
+ files.insert(files.end(), this->InstallScripts.begin(),
+ this->InstallScripts.end());
+ files.insert(files.end(), this->TestFiles.begin(), this->TestFiles.end());
+}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index a865adb..6b97a50 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -248,15 +248,14 @@
* empty then all is assumed. clean indicates if a "make clean" should be
* done first.
*/
- int Build(
- int jobs, const std::string& srcdir, const std::string& bindir,
- const std::string& projectName,
- std::vector<std::string> const& targetNames, std::ostream& ostr,
- const std::string& makeProgram, const std::string& config,
- const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout,
- cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE,
- std::vector<std::string> const& nativeOptions =
- std::vector<std::string>());
+ int Build(int jobs, const std::string& srcdir, const std::string& bindir,
+ const std::string& projectName,
+ std::vector<std::string> const& targetNames, std::ostream& ostr,
+ const std::string& makeProgram, const std::string& config,
+ const cmBuildOptions& buildOptions, bool verbose,
+ cmDuration timeout, cmSystemTools::OutputOption outputMode,
+ std::vector<std::string> const& nativeOptions =
+ std::vector<std::string>());
/**
* Open a generated IDE project given the following information.
@@ -676,6 +675,14 @@
bool CheckCMP0171() const;
void AddInstallScript(std::string const& file);
+ void AddTestFile(std::string const& file);
+ void AddCMakeFilesToRebuild(std::vector<std::string>& files) const;
+
+ virtual const std::set<std::string>& GetDefaultConfigs() const
+ {
+ static std::set<std::string> configs;
+ return configs;
+ }
protected:
// for a project collect all its targets by following depend
@@ -917,6 +924,7 @@
RuntimeDependencySetsByName;
std::vector<std::string> InstallScripts;
+ std::vector<std::string> TestFiles;
#if !defined(CMAKE_BOOTSTRAP)
// Pool of file locks
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 17e9c44..50cf992 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1956,7 +1956,9 @@
cmNinjaRule rule("RERUN_CMAKE");
rule.Command = cmStrCat(
this->CMakeCmd(), " --regenerate-during-build",
- cm->GetIgnoreWarningAsError() ? " --compile-no-warning-as-error" : "",
+ cm->GetIgnoreCompileWarningAsError() ? " --compile-no-warning-as-error"
+ : "",
+ cm->GetIgnoreLinkWarningAsError() ? " --link-no-warning-as-error" : "",
" -S",
lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL),
@@ -3293,6 +3295,7 @@
if (!this->DefaultFileConfig.empty()) {
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
}
+ this->AddCMakeFilesToRebuild(outputs);
}
void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 69b2361..3af5c1a 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -382,6 +382,7 @@
virtual void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const
{
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
+ this->AddCMakeFilesToRebuild(outputs);
}
int GetRuleCmdLength(const std::string& name)
@@ -465,7 +466,7 @@
std::set<std::string> GetCrossConfigs(const std::string& config) const;
- const std::set<std::string>& GetDefaultConfigs() const
+ const std::set<std::string>& GetDefaultConfigs() const override
{
return this->DefaultConfigs;
}
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index f9abe29..3d911bd 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -339,12 +339,13 @@
bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
- std::vector<std::string> const fields = cmTokenize(ts, ",");
- auto fi = fields.begin();
- if (fi == fields.end()) {
+ std::vector<std::string> const fields =
+ cmTokenize(ts, ',', cmTokenizerMode::New);
+ if (fields.empty()) {
return true;
}
+ auto fi = fields.begin();
// The first field may be the VS platform toolset.
if (fi->find('=') == fi->npos) {
this->GeneratorToolset = *fi;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 35b69af..7fb1ce5 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -541,3 +541,56 @@
// Return an empty string
return std::string();
}
+
+void cmGlobalVisualStudio14Generator::AddSolutionItems(cmLocalGenerator* root)
+{
+ cmValue n = root->GetMakefile()->GetProperty("VS_SOLUTION_ITEMS");
+ if (cmNonempty(n)) {
+ cmMakefile* makefile = root->GetMakefile();
+
+ std::vector<cmSourceGroup> sourceGroups = makefile->GetSourceGroups();
+
+ cmVisualStudioFolder* defaultFolder = nullptr;
+
+ std::vector<std::string> pathComponents = {
+ makefile->GetCurrentSourceDirectory(),
+ "",
+ "",
+ };
+
+ for (const std::string& relativePath : cmList(n)) {
+ pathComponents[2] = relativePath;
+ std::string fullPath = cmSystemTools::JoinPath(pathComponents);
+
+ cmSourceGroup* sg = makefile->FindSourceGroup(fullPath, sourceGroups);
+
+ cmVisualStudioFolder* folder = nullptr;
+ if (!sg->GetFullName().empty()) {
+ std::string folderPath = sg->GetFullName();
+ // Source groups use '\' while solution folders use '/'.
+ cmSystemTools::ReplaceString(folderPath, "\\", "/");
+ folder = this->CreateSolutionFolders(folderPath);
+ } else {
+ // Lazily initialize the default solution items folder.
+ if (defaultFolder == nullptr) {
+ defaultFolder = this->CreateSolutionFolders("Solution Items");
+ }
+ folder = defaultFolder;
+ }
+
+ folder->SolutionItems.insert(fullPath);
+ }
+ }
+}
+
+void cmGlobalVisualStudio14Generator::WriteFolderSolutionItems(
+ std::ostream& fout, const cmVisualStudioFolder& folder)
+{
+ fout << "\tProjectSection(SolutionItems) = preProject\n";
+
+ for (const std::string& item : folder.SolutionItems) {
+ fout << "\t\t" << item << " = " << item << "\n";
+ }
+
+ fout << "\tEndProjectSection\n";
+}
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index e903578..e5b8ff8 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -67,6 +67,11 @@
std::string GetWindows10SDKVersion(cmMakefile* mf);
+ void AddSolutionItems(cmLocalGenerator* root) override;
+
+ void WriteFolderSolutionItems(std::ostream& fout,
+ const cmVisualStudioFolder& folder) override;
+
private:
class Factory;
friend class Factory;
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 8375b72..b59c6c6 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -48,9 +48,10 @@
std::ostringstream targetsSlnString;
this->WriteTargetsToSolution(targetsSlnString, root, orderedProjectTargets);
+ this->AddSolutionItems(root);
+
// Generate folder specification.
- bool useFolderProperty = this->UseFolderProperty();
- if (useFolderProperty) {
+ if (!this->VisualStudioFolders.empty()) {
this->WriteFolders(fout);
}
@@ -67,7 +68,7 @@
this->WriteTargetConfigurations(fout, configs, orderedProjectTargets);
fout << "\tEndGlobalSection\n";
- if (useFolderProperty) {
+ if (!this->VisualStudioFolders.empty()) {
// Write out project folders
fout << "\tGlobalSection(NestedProjects) = preSolution\n";
this->WriteFoldersContent(fout);
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 8c644ab..5541617 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -375,6 +375,40 @@
}
}
+cmVisualStudioFolder* cmGlobalVisualStudio7Generator::CreateSolutionFolders(
+ const std::string& path)
+{
+ if (path.empty()) {
+ return nullptr;
+ }
+
+ std::vector<std::string> tokens =
+ cmSystemTools::SplitString(path, '/', false);
+
+ std::string cumulativePath;
+
+ for (std::string const& iter : tokens) {
+ if (iter.empty()) {
+ continue;
+ }
+
+ if (cumulativePath.empty()) {
+ cumulativePath = cmStrCat("CMAKE_FOLDER_GUID_", iter);
+ } else {
+ this->VisualStudioFolders[cumulativePath].Projects.insert(
+ cmStrCat(cumulativePath, '/', iter));
+
+ cumulativePath = cmStrCat(cumulativePath, '/', iter);
+ }
+ }
+
+ if (cumulativePath.empty()) {
+ return nullptr;
+ }
+
+ return &this->VisualStudioFolders[cumulativePath];
+}
+
void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
std::ostream& fout, cmLocalGenerator* root,
OrderedTargetDependSet const& projectTargets)
@@ -421,31 +455,11 @@
// Create "solution folder" information from FOLDER target property
//
if (written && this->UseFolderProperty()) {
- const std::string targetFolder = target->GetEffectiveFolderName();
- if (!targetFolder.empty()) {
- std::vector<std::string> tokens =
- cmSystemTools::SplitString(targetFolder, '/', false);
+ cmVisualStudioFolder* folder =
+ this->CreateSolutionFolders(target->GetEffectiveFolderName());
- std::string cumulativePath;
-
- for (std::string const& iter : tokens) {
- if (iter.empty()) {
- continue;
- }
-
- if (cumulativePath.empty()) {
- cumulativePath = cmStrCat("CMAKE_FOLDER_GUID_", iter);
- } else {
- VisualStudioFolders[cumulativePath].insert(
- cmStrCat(cumulativePath, '/', iter));
-
- cumulativePath = cmStrCat(cumulativePath, '/', iter);
- }
- }
-
- if (!cumulativePath.empty()) {
- VisualStudioFolders[cumulativePath].insert(target->GetName());
- }
+ if (folder != nullptr) {
+ folder->Projects.insert(target->GetName());
}
}
}
@@ -467,7 +481,13 @@
std::string nameOnly = cmSystemTools::GetFilenameName(fullName);
fout << "Project(\"{" << guidProjectTypeFolder << "}\") = \"" << nameOnly
- << "\", \"" << fullName << "\", \"{" << guid << "}\"\nEndProject\n";
+ << "\", \"" << fullName << "\", \"{" << guid << "}\"\n";
+
+ if (!iter.second.SolutionItems.empty()) {
+ this->WriteFolderSolutionItems(fout, iter.second);
+ }
+
+ fout << "EndProject\n";
}
}
@@ -477,7 +497,7 @@
std::string key(iter.first);
std::string guidParent(this->GetGUID(key));
- for (std::string const& it : iter.second) {
+ for (std::string const& it : iter.second.Projects) {
std::string const& value(it);
std::string guid(this->GetGUID(value));
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 2056b2f..d7d7aec 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -25,6 +25,12 @@
template <typename T>
class BT;
+struct cmVisualStudioFolder
+{
+ std::set<std::string> Projects;
+ std::set<std::string> SolutionItems;
+};
+
/** \class cmGlobalVisualStudio7Generator
* \brief Write a Unix makefiles.
*
@@ -154,6 +160,8 @@
virtual void WriteSLNFooter(std::ostream& fout);
std::string WriteUtilityDepend(const cmGeneratorTarget* target) override;
+ cmVisualStudioFolder* CreateSolutionFolders(const std::string& path);
+
virtual void WriteTargetsToSolution(
std::ostream& fout, cmLocalGenerator* root,
OrderedTargetDependSet const& projectTargets);
@@ -178,7 +186,12 @@
virtual void WriteFolders(std::ostream& fout);
virtual void WriteFoldersContent(std::ostream& fout);
- std::map<std::string, std::set<std::string>> VisualStudioFolders;
+
+ virtual void AddSolutionItems(cmLocalGenerator* root) = 0;
+ virtual void WriteFolderSolutionItems(
+ std::ostream& fout, const cmVisualStudioFolder& folder) = 0;
+
+ std::map<std::string, cmVisualStudioFolder> VisualStudioFolders;
// Set during OutputSLNFile with the name of the current project.
// There is one SLN file per project.
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index b1fba8f..08d0d1b 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -128,12 +128,13 @@
{
this->GeneratorPlatform.clear();
- std::vector<std::string> const fields = cmTokenize(p, ",");
- auto fi = fields.begin();
- if (fi == fields.end()) {
+ std::vector<std::string> const fields =
+ cmTokenize(p, ',', cmTokenizerMode::New);
+ if (fields.empty()) {
return true;
}
+ auto fi = fields.begin();
// The first field may be the VS platform.
if (fi->find('=') == fi->npos) {
this->GeneratorPlatform = *fi;
@@ -324,9 +325,12 @@
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list",
stampList, "--vs-solution-file", sln });
- if (cm->GetIgnoreWarningAsError()) {
+ if (cm->GetIgnoreCompileWarningAsError()) {
commandLines[0].emplace_back("--compile-no-warning-as-error");
}
+ if (cm->GetIgnoreLinkWarningAsError()) {
+ commandLines[0].emplace_back("--link-no-warning-as-error");
+ }
// Add the rule. Note that we cannot use the CMakeLists.txt
// file as the main dependency because it would get
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 14460fd..ba51e36 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -584,12 +584,13 @@
this->GeneratorInstance.clear();
this->GeneratorInstanceVersion.clear();
- std::vector<std::string> const fields = cmTokenize(is, ",");
- auto fi = fields.begin();
- if (fi == fields.end()) {
+ std::vector<std::string> const fields =
+ cmTokenize(is, ',', cmTokenizerMode::New);
+ if (fields.empty()) {
return true;
}
+ auto fi = fields.begin();
// The first field may be the VS instance.
if (fi->find('=') == fi->npos) {
this->GeneratorInstance = *fi;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7fa21d0..bb3f33a 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -27,6 +27,7 @@
#include "cmCustomCommandTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmLinkItem.h"
@@ -354,12 +355,13 @@
bool cmGlobalXCodeGenerator::ParseGeneratorToolset(std::string const& ts,
cmMakefile* mf)
{
- std::vector<std::string> const fields = cmTokenize(ts, ",");
- auto fi = fields.cbegin();
- if (fi == fields.cend()) {
+ std::vector<std::string> const fields =
+ cmTokenize(ts, ',', cmTokenizerMode::New);
+ if (fields.empty()) {
return true;
}
+ auto fi = fields.cbegin();
// The first field may be the Xcode GCC_VERSION.
if (fi->find('=') == fi->npos) {
this->GeneratorToolset = *fi;
@@ -775,14 +777,14 @@
}
makefileStream << ConvertToMakefilePath(checkCache) << ": $(TARGETS)\n";
- makefileStream << '\t'
- << ConvertToMakefilePath(cmSystemTools::GetCMakeCommand())
- << " -S" << ConvertToMakefilePath(root->GetSourceDirectory())
- << " -B" << ConvertToMakefilePath(root->GetBinaryDirectory())
- << (cm->GetIgnoreWarningAsError()
- ? " --compile-no-warning-as-error"
- : "")
- << '\n';
+ makefileStream
+ << '\t' << ConvertToMakefilePath(cmSystemTools::GetCMakeCommand()) << " -S"
+ << ConvertToMakefilePath(root->GetSourceDirectory()) << " -B"
+ << ConvertToMakefilePath(root->GetBinaryDirectory())
+ << (cm->GetIgnoreCompileWarningAsError() ? " --compile-no-warning-as-error"
+ : "")
+ << (cm->GetIgnoreLinkWarningAsError() ? " --link-no-warning-as-error" : "")
+ << '\n';
}
static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l,
@@ -1362,12 +1364,20 @@
{
std::string const& a = l->GetTarget()->GetName();
std::string const& b = r->GetTarget()->GetName();
+ if (a == b) {
+ return false;
+ }
if (a == "ALL_BUILD"_s) {
return true;
}
if (b == "ALL_BUILD"_s) {
return false;
}
+ std::string a_low = cmSystemTools::LowerCase(l->GetTarget()->GetName());
+ std::string b_low = cmSystemTools::LowerCase(r->GetTarget()->GetName());
+ if (a_low != b_low) {
+ return a_low < b_low;
+ }
return a < b;
}
};
@@ -2530,7 +2540,8 @@
}
if (!extraLinkOptionsVar.empty()) {
this->CurrentLocalGenerator->AddConfigVariableFlags(
- extraLinkOptions, extraLinkOptionsVar, configName);
+ extraLinkOptions, extraLinkOptionsVar, gtgt, cmBuildStep::Link, llang,
+ configName);
}
if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
@@ -2540,6 +2551,8 @@
} else {
this->CurrentLocalGenerator->AppendLinkerTypeFlags(extraLinkOptions, gtgt,
configName, llang);
+ this->CurrentLocalGenerator->AppendWarningAsErrorLinkerFlags(
+ extraLinkOptions, gtgt, llang);
cmValue targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
@@ -2685,7 +2698,7 @@
// in many ways as an application bundle, as far as
// link flags go
std::string createFlags = this->LookupFlags(
- "CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", "-bundle");
+ "CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", gtgt, "-bundle");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -2711,7 +2724,7 @@
this->CreateString("NO"));
// Add the flags to create an executable.
std::string createFlags =
- this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
+ this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", gtgt, "");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -2740,8 +2753,9 @@
this->CreateString(plist));
} else {
// Add the flags to create a shared library.
- std::string createFlags = this->LookupFlags(
- "CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS", "-dynamiclib");
+ std::string createFlags =
+ this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS",
+ gtgt, "-dynamiclib");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -2761,7 +2775,7 @@
case cmStateEnums::EXECUTABLE: {
// Add the flags to create an executable.
std::string createFlags =
- this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
+ this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", gtgt, "");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -4446,7 +4460,7 @@
if (it != this->TargetGroup.end()) {
tgroup = it->second;
} else {
- std::vector<std::string> tgt_folders = cmTokenize(target, "/");
+ std::vector<std::string> const tgt_folders = cmTokenize(target, '/');
std::string curr_tgt_folder;
for (std::vector<std::string>::size_type i = 0; i < tgt_folders.size();
i++) {
@@ -4479,7 +4493,7 @@
// It's a recursive folder structure, let's find the real parent group
if (sg->GetFullName() != sg->GetName()) {
std::string curr_folder = cmStrCat(target, '/');
- for (auto const& folder : cmTokenize(sg->GetFullName(), "\\")) {
+ for (auto const& folder : cmTokenize(sg->GetFullName(), '\\')) {
curr_folder += folder;
auto const i_folder = this->GroupNameMap.find(curr_folder);
// Create new folder
@@ -5199,13 +5213,17 @@
std::string cmGlobalXCodeGenerator::LookupFlags(
const std::string& varNamePrefix, const std::string& varNameLang,
- const std::string& varNameSuffix, const std::string& default_flags)
+ const std::string& varNameSuffix, cmGeneratorTarget const* gt,
+ const std::string& default_flags)
{
if (!varNameLang.empty()) {
std::string varName = cmStrCat(varNamePrefix, varNameLang, varNameSuffix);
if (cmValue varValue = this->CurrentMakefile->GetDefinition(varName)) {
if (!varValue->empty()) {
- return *varValue;
+ std::string flags;
+ this->CurrentLocalGenerator->AppendFlags(
+ flags, *varValue, varName, gt, cmBuildStep::Link, varNameLang);
+ return flags;
}
}
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 14e9308..22743e5 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -304,6 +304,7 @@
std::string LookupFlags(const std::string& varNamePrefix,
const std::string& varNameLang,
const std::string& varNameSuffix,
+ cmGeneratorTarget const* gt,
const std::string& default_flags);
class Factory;
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 5ac2bd3..23ca4ce 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -100,8 +100,6 @@
}
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
mfile = "";
break;
@@ -130,8 +128,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
modal = "may";
messageType = MessageType::FATAL_ERROR;
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 9a797a7..7f5a22b 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -105,7 +105,7 @@
bool MakeFilesFullPath(const char* modeName, const std::string& basePath,
const std::vector<std::string>& relFiles,
std::vector<std::string>& absFiles);
- bool CheckCMP0006(bool& failure) const;
+ bool CheckCMP0006() const;
std::string GetDestination(const cmInstallCommandArguments* args,
const std::string& varName,
@@ -1018,14 +1018,11 @@
bundleGenerator = CreateInstallTargetGenerator(
target, bundleArgs, false, helper.Makefile->GetBacktrace());
} else if (!runtimeArgs.GetDestination().empty()) {
- bool failure = false;
- if (helper.CheckCMP0006(failure)) {
+ if (helper.CheckCMP0006()) {
// For CMake 2.4 compatibility fallback to the RUNTIME
// properties.
bundleGenerator = CreateInstallTargetGenerator(
target, runtimeArgs, false, helper.Makefile->GetBacktrace());
- } else if (failure) {
- return false;
}
}
if (!bundleGenerator) {
@@ -1625,8 +1622,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
modal = "may";
messageType = MessageType::FATAL_ERROR;
@@ -1880,13 +1875,6 @@
case cmPolicies::OLD:
destination = args[i];
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- // We should never get here, only OLD, WARN, and NEW are used
- status.GetMakefile().IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0177));
- return false;
}
doing = DoingNone;
} else if (doing == DoingType) {
@@ -2494,7 +2482,7 @@
return true;
}
-bool Helper::CheckCMP0006(bool& failure) const
+bool Helper::CheckCMP0006() const
{
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0006)) {
case cmPolicies::WARN:
@@ -2508,13 +2496,6 @@
case cmPolicies::NEW:
// NEW behavior is to disallow compatibility
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- failure = true;
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0006));
- break;
}
return false;
}
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index f371cff..075ff36 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -66,12 +66,6 @@
return ArgumentParser::Continue::Yes;
};
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- // We should never get here, only OLD, WARN, and NEW are used
- makefile.IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0177));
}
this->Bind("DESTINATION"_s, normalizeDest);
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index af531f2..8a4d724 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -43,8 +43,6 @@
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
this->AllowGenex = true;
break;
}
diff --git a/Source/cmInstallScriptHandler.cxx b/Source/cmInstallScriptHandler.cxx
index 9a4e70f..e4620d1 100644
--- a/Source/cmInstallScriptHandler.cxx
+++ b/Source/cmInstallScriptHandler.cxx
@@ -33,41 +33,76 @@
cmInstallScriptHandler::cmInstallScriptHandler(std::string _binaryDir,
std::string _component,
+ std::string _config,
std::vector<std::string>& args)
: binaryDir(std::move(_binaryDir))
, component(std::move(_component))
{
const std::string& file =
cmStrCat(this->binaryDir, "/CMakeFiles/InstallScripts.json");
+ this->parallel = false;
+
+ auto addScript = [this, &args](std::string script,
+ std::string config) -> void {
+ this->commands.push_back(args);
+ if (!config.empty()) {
+ this->commands.back().insert(
+ this->commands.back().end() - 1,
+ cmStrCat("-DCMAKE_INSTALL_CONFIG_NAME=", config));
+ }
+ this->commands.back().emplace_back(script);
+ this->directories.push_back(cmSystemTools::GetFilenamePath(script));
+ };
+
+ int compare = 1;
if (cmSystemTools::FileExists(file)) {
- int compare;
cmSystemTools::FileTimeCompare(
cmStrCat(this->binaryDir, "/CMakeFiles/cmake.check_cache"), file,
&compare);
- if (compare < 1) {
+ }
+ if (compare < 1) {
+ Json::CharReaderBuilder rbuilder;
+ auto JsonReader =
+ std::unique_ptr<Json::CharReader>(rbuilder.newCharReader());
+ std::vector<char> content;
+ Json::Value value;
+ cmJSONState state(file, &value);
+ this->parallel = value["Parallel"].asBool();
+ if (this->parallel) {
args.insert(args.end() - 1, "-DCMAKE_INSTALL_LOCAL_ONLY=1");
- Json::CharReaderBuilder rbuilder;
- auto JsonReader =
- std::unique_ptr<Json::CharReader>(rbuilder.newCharReader());
- std::vector<char> content;
- Json::Value value;
- cmJSONState state(file, &value);
- for (auto const& script : value["InstallScripts"]) {
- this->commands.push_back(args);
- this->commands.back().emplace_back(script.asCString());
- this->directories.push_back(
- cmSystemTools::GetFilenamePath(script.asCString()));
+ }
+ if (_config.empty() && value.isMember("Configs")) {
+ for (auto const& config : value["Configs"]) {
+ this->configs.push_back(config.asCString());
+ }
+ } else {
+ this->configs.push_back(_config);
+ }
+ for (auto const& script : value["InstallScripts"]) {
+ for (auto const& config : configs) {
+ addScript(script.asCString(), config);
+ }
+ if (!this->parallel) {
+ break;
}
}
+ } else {
+ addScript(cmStrCat(this->binaryDir, "/cmake_install.cmake"), _config);
}
}
-bool cmInstallScriptHandler::isParallel()
+bool cmInstallScriptHandler::IsParallel()
{
- return !this->commands.empty();
+ return this->parallel;
}
-int cmInstallScriptHandler::install(unsigned int j)
+std::vector<std::vector<std::string>> cmInstallScriptHandler::GetCommands()
+ const
+{
+ return this->commands;
+}
+
+int cmInstallScriptHandler::Install(unsigned int j)
{
cm::uv_loop_ptr loop;
loop.init();
@@ -133,7 +168,7 @@
InstallScript::InstallScript(const std::vector<std::string>& cmd)
{
this->name = cmSystemTools::RelativePath(
- cmSystemTools::GetCurrentWorkingDirectory(), cmd.back());
+ cmSystemTools::GetLogicalWorkingDirectory(), cmd.back());
this->command = cmd;
}
diff --git a/Source/cmInstallScriptHandler.h b/Source/cmInstallScriptHandler.h
index 4143044..a904dc9 100644
--- a/Source/cmInstallScriptHandler.h
+++ b/Source/cmInstallScriptHandler.h
@@ -16,9 +16,11 @@
{
public:
cmInstallScriptHandler() = default;
- cmInstallScriptHandler(std::string, std::string, std::vector<std::string>&);
- bool isParallel();
- int install(unsigned int j);
+ cmInstallScriptHandler(std::string, std::string, std::string,
+ std::vector<std::string>&);
+ bool IsParallel();
+ int Install(unsigned int j);
+ std::vector<std::vector<std::string>> GetCommands() const;
class InstallScript
{
public:
@@ -38,6 +40,8 @@
private:
std::vector<std::vector<std::string>> commands;
std::vector<std::string> directories;
+ std::vector<std::string> configs;
std::string binaryDir;
std::string component;
+ bool parallel;
};
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index dd71332..89771aa 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -63,9 +63,7 @@
// OLD behavior is handled in cmLocalGenerator::GenerateInstallRules()
break;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS: {
+ case cmPolicies::NEW: {
Indent indent;
std::string odir = this->BinaryDirectory;
cmSystemTools::ConvertToUnixSlashes(odir);
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index 6775a60..395f7ce 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -67,11 +67,6 @@
case cmPolicies::OLD:
// OLD behavior does not convert
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0015);
- mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior converts
convertToAbsolute = true;
diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx
index 3654176..6744bbb 100644
--- a/Source/cmLinkItem.cxx
+++ b/Source/cmLinkItem.cxx
@@ -13,8 +13,6 @@
const std::string cmLinkItem::DEFAULT = "DEFAULT";
-cmLinkItem::cmLinkItem() = default;
-
cmLinkItem::cmLinkItem(std::string n, bool c, cmListFileBacktrace bt,
std::string feature)
: String(std::move(n))
@@ -73,11 +71,6 @@
return os << item.AsStr();
}
-cmLinkImplItem::cmLinkImplItem()
- : cmLinkItem()
-{
-}
-
cmLinkImplItem::cmLinkImplItem(cmLinkItem item, bool checkCMP0027)
: cmLinkItem(std::move(item))
, CheckCMP0027(checkCMP0027)
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 4e356b7..4ef0566 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -29,7 +29,7 @@
// default feature: link library without decoration
static const std::string DEFAULT;
- cmLinkItem();
+ cmLinkItem() = default;
cmLinkItem(std::string s, bool c, cmListFileBacktrace bt,
std::string feature = DEFAULT);
cmLinkItem(cmGeneratorTarget const* t, bool c, cmListFileBacktrace bt,
@@ -50,7 +50,7 @@
class cmLinkImplItem : public cmLinkItem
{
public:
- cmLinkImplItem();
+ cmLinkImplItem() = default;
cmLinkImplItem(cmLinkItem item, bool checkCMP0027);
bool CheckCMP0027 = false;
};
@@ -153,7 +153,7 @@
};
/** Compute the link type to use for the given configuration. */
-inline cmTargetLinkLibraryType CMP0003_ComputeLinkType(
+inline cmTargetLinkLibraryType ComputeLinkType(
const std::string& config, std::vector<std::string> const& debugConfigs)
{
// No configuration is always optimized.
diff --git a/Source/cmList.h b/Source/cmList.h
index e107096..7771a0e 100644
--- a/Source/cmList.h
+++ b/Source/cmList.h
@@ -1135,11 +1135,11 @@
// Non-members
// ===========
- friend inline bool operator==(const cmList& lhs, const cmList& rhs) noexcept
+ friend bool operator==(const cmList& lhs, const cmList& rhs) noexcept
{
return lhs.Values == rhs.Values;
}
- friend inline bool operator!=(const cmList& lhs, const cmList& rhs) noexcept
+ friend bool operator!=(const cmList& lhs, const cmList& rhs) noexcept
{
return lhs.Values != rhs.Values;
}
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index ebf5841..67c6032 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -48,13 +48,6 @@
break;
case cmPolicies::NEW:
return false;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- std::string msg =
- cmStrCat(cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0121),
- " Invalid list index \"", arg, "\".");
- mf.IssueMessage(MessageType::FATAL_ERROR, msg);
- break;
}
}
@@ -118,12 +111,6 @@
return list;
case cmPolicies::NEW:
return list;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- makefile.IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0007));
- return {};
}
return list;
}
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 81edea5..66ea52d 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -18,12 +18,10 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
-#include <utility>
#include <cm/memory>
#include "cmCPluginAPI.h"
-#include "cmCommand.h"
#include "cmDynamicLoader.h"
#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
@@ -40,6 +38,12 @@
# include <malloc.h> /* for malloc/free on QNX */
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wcast-function-type-strict")
+# pragma clang diagnostic ignored "-Wcast-function-type-strict"
+# endif
+#endif
+
namespace {
const char* LastName = nullptr;
@@ -124,40 +128,32 @@
};
// a class for loadabple commands
-class cmLoadedCommand : public cmCommand
+class cmLoadedCommand
{
public:
- cmLoadedCommand() = default;
explicit cmLoadedCommand(CM_INIT_FUNCTION init)
: Impl(std::make_shared<LoadedCommandImpl>(init))
{
}
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto newC = cm::make_unique<cmLoadedCommand>();
- // we must copy when we clone
- newC->Impl = this->Impl;
- return std::unique_ptr<cmCommand>(std::move(newC));
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&) override;
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status) const;
private:
std::shared_ptr<LoadedCommandImpl> Impl;
};
-bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmLoadedCommand::operator()(
+ std::vector<cmListFileArgument> const& arguments,
+ cmExecutionStatus& status) const
{
+ cmMakefile& mf = status.GetMakefile();
+
+ std::vector<std::string> args;
+ if (!mf.ExpandArguments(arguments, args)) {
+ return true;
+ }
+
if (!this->Impl->InitialPass) {
return true;
}
@@ -177,13 +173,13 @@
for (i = 0; i < argc; ++i) {
argv[i] = strdup(args[i].c_str());
}
- int result = this->Impl->DoInitialPass(this->Makefile, argc, argv);
+ int result = this->Impl->DoInitialPass(&mf, argc, argv);
cmFreeArguments(argc, argv);
if (result) {
if (this->Impl->FinalPass) {
auto impl = this->Impl;
- this->Makefile->AddGeneratorAction(
+ mf.AddGeneratorAction(
[impl](cmLocalGenerator& lg, const cmListFileBacktrace&) {
impl->DoFinalPass(lg.GetMakefile());
});
@@ -193,7 +189,7 @@
/* Initial Pass must have failed so set the error string */
if (this->Impl->Error) {
- this->SetError(this->Impl->Error);
+ status.SetError(this->Impl->Error);
}
return false;
}
@@ -270,9 +266,8 @@
if (initFunction) {
return status.GetMakefile().GetState()->AddScriptedCommand(
args[0],
- BT<cmState::Command>(
- cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)),
- status.GetMakefile().GetBacktrace()),
+ BT<cmState::Command>(cmLoadedCommand(initFunction),
+ status.GetMakefile().GetBacktrace()),
status.GetMakefile());
}
status.SetError("Attempt to load command failed. "
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 42b517e..5c9baf9 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -208,12 +208,62 @@
}
std::unique_ptr<cmRulePlaceholderExpander>
-cmLocalGenerator::CreateRulePlaceholderExpander() const
+cmLocalGenerator::CreateRulePlaceholderExpander(cmBuildStep buildStep) const
{
return cm::make_unique<cmRulePlaceholderExpander>(
- this->Compilers, this->VariableMappings, this->CompilerSysroot,
+ buildStep, this->Compilers, this->VariableMappings, this->CompilerSysroot,
this->LinkerSysroot);
}
+std::unique_ptr<cmRulePlaceholderExpander>
+cmLocalGenerator::CreateRulePlaceholderExpander(
+ cmBuildStep buildStep, cmGeneratorTarget const* target,
+ std::string const& language)
+{
+ auto targetType = target->GetType();
+ if (buildStep == cmBuildStep::Link &&
+ (targetType == cmStateEnums::EXECUTABLE ||
+ targetType == cmStateEnums::SHARED_LIBRARY ||
+ targetType == cmStateEnums::MODULE_LIBRARY)) {
+ auto mappings = this->VariableMappings;
+ auto updateMapping = [buildStep, target, &language, &mappings,
+ this](std::string const& variable) {
+ auto search = this->VariableMappings.find(variable);
+ if (search != this->VariableMappings.end()) {
+ std::string finalFlags;
+ this->AppendFlags(finalFlags, search->second, variable, target,
+ buildStep, language);
+ mappings[variable] = std::move(finalFlags);
+ }
+ };
+
+ switch (targetType) {
+ // FALLTHROUGH is used because, depending of the compiler and/or
+ // platform, the wrong variable is used. For example
+ // CMAKE_SHARED_LIBRARY_CREATE_<LANG>_FLAGS is used to generate a module,
+ // and the variable CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS is ignored.
+ case cmStateEnums::MODULE_LIBRARY:
+ updateMapping(
+ cmStrCat("CMAKE_SHARED_MODULE_CREATE_", language, "_FLAGS"));
+ CM_FALLTHROUGH;
+ case cmStateEnums::SHARED_LIBRARY:
+ updateMapping(
+ cmStrCat("CMAKE_SHARED_LIBRARY_CREATE_", language, "_FLAGS"));
+ CM_FALLTHROUGH;
+ case cmStateEnums::EXECUTABLE:
+ updateMapping(cmStrCat("CMAKE_", language, "_LINK_FLAGS"));
+ break;
+ default:
+ // no action needed
+ ;
+ }
+
+ return cm::make_unique<cmRulePlaceholderExpander>(
+ buildStep, this->Compilers, std::move(mappings), this->CompilerSysroot,
+ this->LinkerSysroot);
+ }
+
+ return this->CreateRulePlaceholderExpander(buildStep);
+}
cmLocalGenerator::~cmLocalGenerator() = default;
@@ -241,14 +291,14 @@
std::ostringstream w;
w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax
<< ", which is less than the minimum of 128. "
- << "The value will be ignored.";
+ "The value will be ignored.";
this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
} else {
std::ostringstream w;
w << "CMAKE_OBJECT_PATH_MAX is set to \"" << *plen
<< "\", which fails to parse as a positive integer. "
- << "The value will be ignored.";
+ "The value will be ignored.";
this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
}
@@ -316,9 +366,9 @@
std::string file =
cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentBinary(),
"/CTestTestfile.cmake");
+ this->GlobalGenerator->AddTestFile(file);
cmGeneratedFileStream fout(file);
- fout.SetCopyIfDifferent(true);
fout << "# CMake generated Testfile for \n"
"# Source directory: "
@@ -502,7 +552,6 @@
file += "/cmake_install.cmake";
this->GetGlobalGenerator()->AddInstallScript(file);
cmGeneratedFileStream fout(file);
- fout.SetCopyIfDifferent(true);
// Write the header.
/* clang-format off */
@@ -705,8 +754,6 @@
}
} break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// NEW behavior is handled in
// cmInstallSubdirectoryGenerator::GenerateScript()
@@ -1051,7 +1098,7 @@
}
// Add Warning as errors flags
- if (!this->GetCMakeInstance()->GetIgnoreWarningAsError()) {
+ if (!this->GetCMakeInstance()->GetIgnoreCompileWarningAsError()) {
const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR");
const cmValue wErrorOpts = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_WARNING_AS_ERROR"));
@@ -1495,17 +1542,16 @@
libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
CM_FALLTHROUGH;
case cmStateEnums::SHARED_LIBRARY: {
- std::string sharedLibFlags;
if (this->IsSplitSwiftBuild() || linkLanguage != "Swift") {
- sharedLibFlags = cmStrCat(
- this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
- if (!configUpper.empty()) {
- std::string build = cmStrCat(libraryLinkVariable, '_', configUpper);
- sharedLibFlags += this->Makefile->GetSafeDefinition(build);
- sharedLibFlags += " ";
+ std::string libFlags;
+ this->AddConfigVariableFlags(libFlags, libraryLinkVariable, target,
+ cmBuildStep::Link, linkLanguage, config);
+ if (!libFlags.empty()) {
+ linkFlags.emplace_back(std::move(libFlags));
}
}
+ std::string sharedLibFlags;
cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
sharedLibFlags += *targetLinkFlags;
@@ -1538,7 +1584,6 @@
}
} break;
case cmStateEnums::EXECUTABLE: {
- std::string exeFlags;
if (linkLanguage.empty()) {
cmSystemTools::Error(
"CMake can not determine linker language for target: " +
@@ -1547,25 +1592,28 @@
}
if (linkLanguage != "Swift") {
- exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
- exeFlags += " ";
- if (!configUpper.empty()) {
- exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
- exeFlags += " ";
+ std::string exeFlags;
+ this->AddConfigVariableFlags(exeFlags, "CMAKE_EXE_LINKER_FLAGS",
+ target, cmBuildStep::Link, linkLanguage,
+ config);
+ if (!exeFlags.empty()) {
+ linkFlags.emplace_back(std::move(exeFlags));
}
}
- if (target->IsWin32Executable(config)) {
- exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE"));
- exeFlags += " ";
- } else {
- exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE"));
- exeFlags += " ";
+ {
+ auto exeType = cmStrCat(
+ "CMAKE_", linkLanguage, "_CREATE_",
+ (target->IsWin32Executable(config) ? "WIN32" : "CONSOLE"), "_EXE");
+ std::string exeFlags;
+ this->AppendFlags(exeFlags, this->Makefile->GetDefinition(exeType),
+ exeType, target, cmBuildStep::Link, linkLanguage);
+ if (!exeFlags.empty()) {
+ linkFlags.emplace_back(std::move(exeFlags));
+ }
}
+ std::string exeFlags;
if (target->IsExecutableWithExports()) {
exeFlags += this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
@@ -1625,6 +1673,7 @@
this->AppendLinkerTypeFlags(extraLinkFlags, target, config, linkLanguage);
this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
+ this->AppendWarningAsErrorLinkerFlags(extraLinkFlags, target, linkLanguage);
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
this->AppendDependencyInfoLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
@@ -1946,12 +1995,6 @@
add_shlib_flags =
!(tgt.IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"));
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065));
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior is to only add the flags if ENABLE_EXPORTS is on,
// except on AIX where we compute symbol exports.
@@ -2380,7 +2423,7 @@
dep = cmStrCat(this->GetCurrentBinaryDirectory(), '/', inName);
}
- dep = cmSystemTools::CollapseFullPath(dep, this->GetBinaryDirectory());
+ dep = cmSystemTools::CollapseFullPath(dep);
return true;
}
@@ -2554,8 +2597,6 @@
}
case cmPolicies::OLD:
return true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
return false;
}
@@ -2621,6 +2662,19 @@
this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar));
}
}
+void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
+ const std::string& var,
+ cmGeneratorTarget const* target,
+ cmBuildStep compileOrLink,
+ const std::string& lang,
+ const std::string& config)
+{
+ std::string newFlags;
+ this->AddConfigVariableFlags(newFlags, var, config);
+ if (!newFlags.empty()) {
+ this->AppendFlags(flags, newFlags, var, target, compileOrLink, lang);
+ }
+}
void cmLocalGenerator::AppendFlags(std::string& flags,
const std::string& newFlags) const
@@ -2651,6 +2705,52 @@
this->EscapeForShell(rawFlag, false, false, false, this->IsNinjaMulti()));
}
+void cmLocalGenerator::AppendFlags(std::string& flags,
+ std::string const& newFlags,
+ const std::string& name,
+ const cmGeneratorTarget* target,
+ cmBuildStep compileOrLink,
+ const std::string& language)
+{
+ switch (target->GetPolicyStatusCMP0181()) {
+ case cmPolicies::WARN:
+ if (!this->Makefile->GetCMakeInstance()->GetIsInTryCompile() &&
+ this->Makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0181")) {
+ this->Makefile->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0181),
+ "\nSince the policy is not set, the contents of variable '",
+ name,
+ "' will "
+ "be used as is."),
+ target->GetBacktrace());
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ this->AppendFlags(flags, newFlags);
+ break;
+ case cmPolicies::NEW:
+ if (compileOrLink == cmBuildStep::Link) {
+ std::vector<std::string> options;
+ cmSystemTools::ParseUnixCommandLine(newFlags.c_str(), options);
+ this->SetLinkScriptShell(this->GlobalGenerator->GetUseLinkScript());
+ std::vector<BT<std::string>> optionsWithBT{ options.size() };
+ std::transform(options.cbegin(), options.cend(), optionsWithBT.begin(),
+ [](const std::string& item) -> BT<std::string> {
+ return BT<std::string>{ item };
+ });
+ target->ResolveLinkerWrapper(optionsWithBT, language);
+ for (const auto& item : optionsWithBT) {
+ this->AppendFlagEscape(flags, item.Value);
+ }
+ this->SetLinkScriptShell(false);
+ } else {
+ this->AppendFlags(flags, newFlags);
+ }
+ }
+}
+
void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target)
{
std::vector<std::string> enabledLanguages =
@@ -3087,7 +3187,8 @@
cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource(
cmGeneratorTarget* target, std::vector<std::string> const& configs,
cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
- cmValue beforeInclude, cmValue afterInclude, std::string filename) const
+ cmValue beforeInclude, cmValue afterInclude, std::string filename,
+ std::string const& unityFileDirectory, UnityPathMode pathMode) const
{
cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID");
cmGeneratedFileStream file(
@@ -3110,7 +3211,8 @@
}
RegisterUnitySources(target, ubs.Source, filename);
WriteUnitySourceInclude(file, cond, ubs.Source->ResolveFullPath(),
- beforeInclude, afterInclude, uniqueIdName);
+ beforeInclude, afterInclude, uniqueIdName,
+ pathMode, unityFileDirectory);
}
return UnitySource(std::move(filename), perConfig);
@@ -3119,28 +3221,35 @@
void cmLocalGenerator::WriteUnitySourceInclude(
std::ostream& unity_file, cm::optional<std::string> const& cond,
std::string const& sf_full_path, cmValue beforeInclude, cmValue afterInclude,
- cmValue uniqueIdName) const
+ cmValue uniqueIdName, UnityPathMode pathMode,
+ std::string const& unityFileDirectory) const
{
if (cond) {
unity_file << "#if " << *cond << "\n";
}
+ std::string pathToHash;
+ std::string relocatableIncludePath;
+ auto PathEqOrSubDir = [](std::string const& a, std::string const& b) {
+ return (cmSystemTools::ComparePath(a, b) ||
+ cmSystemTools::IsSubDirectory(a, b));
+ };
+ const auto path = cmSystemTools::GetFilenamePath(sf_full_path);
+ if (PathEqOrSubDir(path, this->GetBinaryDirectory())) {
+ relocatableIncludePath =
+ cmSystemTools::RelativePath(unityFileDirectory, sf_full_path);
+ pathToHash = "BLD_" +
+ cmSystemTools::RelativePath(this->GetBinaryDirectory(), sf_full_path);
+ } else if (PathEqOrSubDir(path, this->GetSourceDirectory())) {
+ relocatableIncludePath =
+ cmSystemTools::RelativePath(this->GetSourceDirectory(), sf_full_path);
+ pathToHash = "SRC_" + relocatableIncludePath;
+ } else {
+ relocatableIncludePath = sf_full_path;
+ pathToHash = "ABS_" + sf_full_path;
+ }
+
if (cmNonempty(uniqueIdName)) {
- std::string pathToHash;
- auto PathEqOrSubDir = [](std::string const& a, std::string const& b) {
- return (cmSystemTools::ComparePath(a, b) ||
- cmSystemTools::IsSubDirectory(a, b));
- };
- const auto path = cmSystemTools::GetFilenamePath(sf_full_path);
- if (PathEqOrSubDir(path, this->GetBinaryDirectory())) {
- pathToHash = "BLD_" +
- cmSystemTools::RelativePath(this->GetBinaryDirectory(), sf_full_path);
- } else if (PathEqOrSubDir(path, this->GetSourceDirectory())) {
- pathToHash = "SRC_" +
- cmSystemTools::RelativePath(this->GetSourceDirectory(), sf_full_path);
- } else {
- pathToHash = "ABS_" + sf_full_path;
- }
cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
unity_file << "/* " << pathToHash << " */\n"
<< "#undef " << *uniqueIdName << "\n"
@@ -3156,7 +3265,11 @@
unity_file
<< "/* NOLINTNEXTLINE(bugprone-suspicious-include,misc-include-cleaner) "
"*/\n";
- unity_file << "#include \"" << sf_full_path << "\"\n";
+ if (pathMode == UnityPathMode::Relative) {
+ unity_file << "#include \"" << relocatableIncludePath << "\"\n";
+ } else {
+ unity_file << "#include \"" << sf_full_path << "\"\n";
+ }
if (afterInclude) {
unity_file << *afterInclude << "\n";
@@ -3192,7 +3305,7 @@
std::vector<std::string> const& configs,
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
- std::string const& filename_base, size_t batchSize)
+ std::string const& filename_base, UnityPathMode pathMode, size_t batchSize)
{
if (batchSize == 0) {
batchSize = filtered_sources.size();
@@ -3210,7 +3323,7 @@
auto const end = begin + chunk;
unity_files.emplace_back(this->WriteUnitySource(
target, configs, cmMakeRange(begin, end), beforeInclude, afterInclude,
- std::move(filename)));
+ std::move(filename), filename_base, pathMode));
}
return unity_files;
}
@@ -3221,7 +3334,7 @@
std::vector<std::string> const& configs,
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
- std::string const& filename_base)
+ std::string const& filename_base, UnityPathMode pathMode)
{
std::vector<UnitySource> unity_files;
@@ -3247,7 +3360,7 @@
cmStrCat(filename_base, "unity_", name, unity_file_extension(lang));
unity_files.emplace_back(this->WriteUnitySource(
target, configs, cmMakeRange(item.second), beforeInclude, afterInclude,
- std::move(filename)));
+ std::move(filename), filename_base, pathMode));
}
return unity_files;
@@ -3305,6 +3418,9 @@
target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
cmValue afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
cmValue unityMode = target->GetProperty("UNITY_BUILD_MODE");
+ UnityPathMode pathMode = target->GetPropertyAsBool("UNITY_BUILD_RELOCATABLE")
+ ? UnityPathMode::Relative
+ : UnityPathMode::Absolute;
for (std::string lang : { "C", "CXX", "OBJC", "OBJCXX", "CUDA" }) {
std::vector<UnityBatchedSource> filtered_sources;
@@ -3325,11 +3441,11 @@
if (!unityMode || *unityMode == "BATCH") {
unity_files = AddUnityFilesModeAuto(
target, lang, configs, filtered_sources, beforeInclude, afterInclude,
- filename_base, unityBatchSize);
+ filename_base, pathMode, unityBatchSize);
} else if (unityMode && *unityMode == "GROUP") {
- unity_files =
- AddUnityFilesModeGroup(target, lang, configs, filtered_sources,
- beforeInclude, afterInclude, filename_base);
+ unity_files = AddUnityFilesModeGroup(
+ target, lang, configs, filtered_sources, beforeInclude, afterInclude,
+ filename_base, pathMode);
} else {
// unity mode is set to an unsupported value
std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode +
@@ -3348,6 +3464,11 @@
unity->SetProperty("COMPILE_DEFINITIONS",
"CMAKE_UNITY_CONFIG_$<UPPER_CASE:$<CONFIG>>");
}
+
+ if (pathMode == UnityPathMode::Relative) {
+ unity->AppendProperty("INCLUDE_DIRECTORIES",
+ this->GetSourceDirectory(), false);
+ }
}
}
}
@@ -3472,6 +3593,34 @@
}
}
+void cmLocalGenerator::AppendWarningAsErrorLinkerFlags(
+ std::string& flags, cmGeneratorTarget* target, const std::string& lang)
+{
+ if (this->GetCMakeInstance()->GetIgnoreLinkWarningAsError()) {
+ return;
+ }
+
+ switch (target->GetType()) {
+ case cmStateEnums::EXECUTABLE:
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ break;
+ default:
+ return;
+ }
+
+ const auto wError = target->GetProperty("LINK_WARNING_AS_ERROR");
+ const auto wErrorOpts = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_LINK_OPTIONS_WARNING_AS_ERROR"));
+ if (wError.IsOn() && wErrorOpts.IsSet()) {
+ auto items = cmExpandListWithBacktrace(wErrorOpts, target->GetBacktrace());
+ target->ResolveLinkerWrapper(items, lang);
+ for (const auto& item : items) {
+ this->AppendFlagEscape(flags, item.Value);
+ }
+ }
+}
+
void cmLocalGenerator::AppendDependencyInfoLinkerFlags(
std::string& flags, cmGeneratorTarget* target, const std::string& config,
const std::string& linkLanguage)
@@ -4256,12 +4405,6 @@
break;
case cmPolicies::NEW:
// New behavior is to ignore the variable.
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- // This will never be the case because the only way to require
- // the setting is to require the user to specify version policy
- // 2.6 or higher. Once we add that requirement then this whole
- // method can be removed anyway.
return false;
}
@@ -4286,10 +4429,10 @@
std::ostringstream e;
/* clang-format off */
e << "WARNING: Function-style preprocessor definitions may not be "
- << "passed on the compiler command line because many compilers "
- << "do not support it.\n"
- << "CMake is dropping a preprocessor definition: " << define << "\n"
- << "Consider defining the macro in a (configured) header file.\n";
+ "passed on the compiler command line because many compilers "
+ "do not support it.\n"
+ "CMake is dropping a preprocessor definition: " << define << "\n"
+ "Consider defining the macro in a (configured) header file.\n";
/* clang-format on */
cmSystemTools::Message(e.str());
return false;
@@ -4301,10 +4444,10 @@
std::ostringstream e;
/* clang-format off */
e << "WARNING: Preprocessor definitions containing '#' may not be "
- << "passed on the compiler command line because many compilers "
- << "do not support it.\n"
- << "CMake is dropping a preprocessor definition: " << define << "\n"
- << "Consider defining the macro in a (configured) header file.\n";
+ "passed on the compiler command line because many compilers "
+ "do not support it.\n"
+ "CMake is dropping a preprocessor definition: " << define << "\n"
+ "Consider defining the macro in a (configured) header file.\n";
/* clang-format on */
cmSystemTools::Message(e.str());
return false;
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 3ec349b..ec4240f 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -19,6 +19,7 @@
#include <cm3p/kwiml/int.h>
#include "cmCustomCommandTypes.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmListFileCache.h"
#include "cmMessageType.h" // IWYU pragma: keep
@@ -46,36 +47,6 @@
template <typename Iter>
class cmRange;
-/** Flag if byproducts shall also be considered. */
-enum class cmSourceOutputKind
-{
- OutputOnly,
- OutputOrByproduct
-};
-
-/** What scanner to use for dependencies lookup. */
-enum class cmDependencyScannerKind
-{
- CMake,
- Compiler
-};
-
-/** What to compute language flags for */
-enum class cmBuildStep
-{
- Compile,
- Link
-};
-
-/** What compilation mode the swift files are in */
-enum class cmSwiftCompileMode
-{
- Wholemodule,
- Incremental,
- Singlefile,
- Unknown,
-};
-
/** Target and source file which have a specific output. */
struct cmSourcesWithOutput
{
@@ -147,7 +118,12 @@
}
virtual std::unique_ptr<cmRulePlaceholderExpander>
- CreateRulePlaceholderExpander() const;
+ CreateRulePlaceholderExpander(
+ cmBuildStep buildStep = cmBuildStep::Compile) const;
+ virtual std::unique_ptr<cmRulePlaceholderExpander>
+ CreateRulePlaceholderExpander(cmBuildStep buildStep,
+ cmGeneratorTarget const* target,
+ std::string const& language);
std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
cmGeneratorTarget& tgt) const;
@@ -174,6 +150,12 @@
const std::string& lang);
void AddConfigVariableFlags(std::string& flags, const std::string& var,
const std::string& config);
+ // Handle prefixes processing (like LINKER:)
+ void AddConfigVariableFlags(std::string& flags, const std::string& var,
+ cmGeneratorTarget const* target,
+ cmBuildStep compileOrLink,
+ const std::string& lang,
+ const std::string& config);
void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang);
//! Append flags to a string.
virtual void AppendFlags(std::string& flags,
@@ -182,6 +164,13 @@
const std::vector<BT<std::string>>& newFlags) const;
virtual void AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const;
+ /**
+ * Append flags after parsing, prefixes processing (like LINKER:) and
+ * escaping
+ */
+ void AppendFlags(std::string& flags, std::string const& newFlags,
+ const std::string& name, const cmGeneratorTarget* target,
+ cmBuildStep compileOrLink, const std::string& lang);
void AddISPCDependencies(cmGeneratorTarget* target);
void AddPchDependencies(cmGeneratorTarget* target);
void AddUnityBuild(cmGeneratorTarget* target);
@@ -196,6 +185,9 @@
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ void AppendWarningAsErrorLinkerFlags(std::string& flags,
+ cmGeneratorTarget* target,
+ const std::string& lang);
void AppendDependencyInfoLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& config,
@@ -699,28 +691,37 @@
{
}
};
+ /** Whether to insert relative or absolute paths into unity files */
+ enum class UnityPathMode
+ {
+ Absolute,
+ Relative
+ };
UnitySource WriteUnitySource(
cmGeneratorTarget* target, std::vector<std::string> const& configs,
cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
- cmValue beforeInclude, cmValue afterInclude, std::string filename) const;
+ cmValue beforeInclude, cmValue afterInclude, std::string filename,
+ std::string const& unityFileDirectory, UnityPathMode pathMode) const;
void WriteUnitySourceInclude(std::ostream& unity_file,
cm::optional<std::string> const& cond,
std::string const& sf_full_path,
cmValue beforeInclude, cmValue afterInclude,
- cmValue uniqueIdName) const;
+ cmValue uniqueIdName, UnityPathMode pathMode,
+ std::string const& unityFileDirectory) const;
std::vector<UnitySource> AddUnityFilesModeAuto(
cmGeneratorTarget* target, std::string const& lang,
std::vector<std::string> const& configs,
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
- std::string const& filename_base, size_t batchSize);
+ std::string const& filename_base, UnityPathMode pathMode,
+ size_t batchSize);
std::vector<UnitySource> AddUnityFilesModeGroup(
cmGeneratorTarget* target, std::string const& lang,
std::vector<std::string> const& configs,
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
- std::string const& filename_base);
+ std::string const& filename_base, UnityPathMode pathMode);
};
namespace detail {
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 46a95af..02a458b 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -50,9 +50,20 @@
// Virtual public methods.
std::unique_ptr<cmRulePlaceholderExpander>
-cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const
+cmLocalNinjaGenerator::CreateRulePlaceholderExpander(
+ cmBuildStep buildStep) const
{
- auto ret = this->cmLocalGenerator::CreateRulePlaceholderExpander();
+ auto ret = this->cmLocalGenerator::CreateRulePlaceholderExpander(buildStep);
+ ret->SetTargetImpLib("$TARGET_IMPLIB");
+ return std::unique_ptr<cmRulePlaceholderExpander>(std::move(ret));
+}
+std::unique_ptr<cmRulePlaceholderExpander>
+cmLocalNinjaGenerator::CreateRulePlaceholderExpander(
+ cmBuildStep buildStep, cmGeneratorTarget const* target,
+ std::string const& language)
+{
+ auto ret = this->cmLocalGenerator::CreateRulePlaceholderExpander(
+ buildStep, target, language);
ret->SetTargetImpLib("$TARGET_IMPLIB");
return std::unique_ptr<cmRulePlaceholderExpander>(std::move(ret));
}
@@ -719,8 +730,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
depfile = ccg.GetInternalDepfile();
break;
@@ -822,8 +831,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
transformDepfile = true;
break;
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 74b8b3b..1abc410 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -11,6 +11,7 @@
#include <string>
#include <vector>
+#include "cmGeneratorOptions.h"
#include "cmLocalCommonGenerator.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
@@ -42,8 +43,11 @@
void Generate() override;
- std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander()
- const override;
+ std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander(
+ cmBuildStep buildStep = cmBuildStep::Compile) const override;
+ std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander(
+ cmBuildStep buildStep, cmGeneratorTarget const* target,
+ std::string const& language) override;
std::string GetTargetDirectory(
cmGeneratorTarget const* target) const override;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 4a776b4..83ecef0 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -829,7 +829,9 @@
std::string cmakefileName = "CMakeFiles/Makefile.cmake";
std::string runRule = cmStrCat(
"$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) ",
- cm->GetIgnoreWarningAsError() ? "--compile-no-warning-as-error " : "",
+ cm->GetIgnoreCompileWarningAsError() ? "--compile-no-warning-as-error "
+ : "",
+ cm->GetIgnoreLinkWarningAsError() ? "--link-no-warning-as-error " : "",
"--check-build-system ",
this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
" 0");
@@ -1831,7 +1833,9 @@
{
std::string runRule = cmStrCat(
"$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) ",
- cm->GetIgnoreWarningAsError() ? "--compile-no-warning-as-error " : "",
+ cm->GetIgnoreCompileWarningAsError() ? "--compile-no-warning-as-error "
+ : "",
+ cm->GetIgnoreLinkWarningAsError() ? "--link-no-warning-as-error " : "",
"--check-build-system ",
this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
" 1");
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 7d5a922..6db410b 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -12,8 +12,8 @@
#include <vector>
#include "cmDepends.h"
+#include "cmGeneratorOptions.h"
#include "cmLocalCommonGenerator.h"
-#include "cmLocalGenerator.h"
class cmCustomCommand;
class cmCustomCommandGenerator;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 8be21c2..2f6421e 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -25,6 +25,7 @@
#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio7Generator.h"
@@ -258,9 +259,12 @@
cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB,
"--check-stamp-file", stampName });
- if (cm->GetIgnoreWarningAsError()) {
+ if (cm->GetIgnoreCompileWarningAsError()) {
commandLines[0].emplace_back("--compile-no-warning-as-error");
}
+ if (cm->GetIgnoreLinkWarningAsError()) {
+ commandLines[0].emplace_back("--link-no-warning-as-error");
+ }
std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
auto cc = cm::make_unique<cmCustomCommand>();
cc->SetOutputs(stampName);
@@ -664,16 +668,16 @@
}
std::string flags;
std::string langForClCompile;
+ const std::string& linkLanguage =
+ (this->FortranProject ? std::string("Fortran")
+ : target->GetLinkerLanguage(configName));
+ if (linkLanguage.empty()) {
+ cmSystemTools::Error(
+ cmStrCat("CMake can not determine linker language for target: ",
+ target->GetName()));
+ return;
+ }
if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
- const std::string& linkLanguage =
- (this->FortranProject ? std::string("Fortran")
- : target->GetLinkerLanguage(configName));
- if (linkLanguage.empty()) {
- cmSystemTools::Error(
- cmStrCat("CMake can not determine linker language for target: ",
- target->GetName()));
- return;
- }
langForClCompile = linkLanguage;
if (langForClCompile == "C" || langForClCompile == "CXX" ||
langForClCompile == "Fortran") {
@@ -957,26 +961,14 @@
}
this->OutputTargetRules(fout, configName, target, libName);
- this->OutputBuildTool(fout, configName, target, targetOptions);
+ this->OutputBuildTool(fout, linkLanguage, configName, target, targetOptions);
this->OutputDeploymentDebuggerTool(fout, configName, target);
fout << "\t\t</Configuration>\n";
}
-std::string cmLocalVisualStudio7Generator::GetBuildTypeLinkerFlags(
- std::string const& rootLinkerFlags, const std::string& configName)
-{
- std::string configTypeUpper = cmSystemTools::UpperCase(configName);
- std::string extraLinkOptionsBuildTypeDef =
- cmStrCat(rootLinkerFlags, '_', configTypeUpper);
-
- const std::string& extraLinkOptionsBuildType =
- this->Makefile->GetRequiredDefinition(extraLinkOptionsBuildTypeDef);
-
- return extraLinkOptionsBuildType;
-}
-
void cmLocalVisualStudio7Generator::OutputBuildTool(
- std::ostream& fout, const std::string& configName, cmGeneratorTarget* target,
+ std::ostream& fout, const std::string& linkLanguage,
+ const std::string& configName, cmGeneratorTarget* target,
const Options& targetOptions)
{
cmGlobalVisualStudio7Generator* gg =
@@ -984,19 +976,19 @@
std::string temp;
std::string extraLinkOptions;
if (target->GetType() == cmStateEnums::EXECUTABLE) {
- extraLinkOptions = cmStrCat(
- this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS"), ' ',
- GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName));
+ this->AddConfigVariableFlags(extraLinkOptions, "CMAKE_EXE_LINKER_FLAGS",
+ target, cmBuildStep::Link, linkLanguage,
+ configName);
}
if (target->GetType() == cmStateEnums::SHARED_LIBRARY) {
- extraLinkOptions = cmStrCat(
- this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS"), ' ',
- GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName));
+ this->AddConfigVariableFlags(extraLinkOptions, "CMAKE_SHARED_LINKER_FLAGS",
+ target, cmBuildStep::Link, linkLanguage,
+ configName);
}
if (target->GetType() == cmStateEnums::MODULE_LIBRARY) {
- extraLinkOptions = cmStrCat(
- this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS"), ' ',
- GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName));
+ this->AddConfigVariableFlags(extraLinkOptions, "CMAKE_MODULE_LINKER_FLAGS",
+ target, cmBuildStep::Link, linkLanguage,
+ configName);
}
cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS");
@@ -1018,6 +1010,9 @@
// LINK_OPTIONS are escaped.
this->AppendCompileOptions(extraLinkOptions, opts);
+ this->AppendWarningAsErrorLinkerFlags(extraLinkOptions, target,
+ linkLanguage);
+
Options linkOptions(this, Options::Linker);
if (this->FortranProject) {
linkOptions.AddTable(cmLocalVisualStudio7GeneratorFortranLinkFlagTable);
@@ -1089,7 +1084,6 @@
return;
}
cmComputeLinkInformation& cli = *pcli;
- std::string linkLanguage = cli.GetLinkLanguage();
if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
// Visual Studio 10 or upper is required for this feature
@@ -1173,7 +1167,6 @@
return;
}
cmComputeLinkInformation& cli = *pcli;
- std::string linkLanguage = cli.GetLinkLanguage();
if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
// Visual Studio 10 or upper is required for this feature
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 7c395d6..baf85fb 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -99,8 +99,6 @@
private:
using Options = cmVS7GeneratorOptions;
using FCInfo = cmLocalVisualStudio7GeneratorFCInfo;
- std::string GetBuildTypeLinkerFlags(std::string const& rootLinkerFlags,
- const std::string& configName);
void FixGlobalTargets();
void WriteVCProjHeader(std::ostream& fout, const std::string& libName,
cmGeneratorTarget* tgt,
@@ -119,8 +117,9 @@
void OutputTargetRules(std::ostream& fout, const std::string& configName,
cmGeneratorTarget* target,
const std::string& libName);
- void OutputBuildTool(std::ostream& fout, const std::string& configName,
- cmGeneratorTarget* t, const Options& targetOptions);
+ void OutputBuildTool(std::ostream& fout, const std::string& linkLanguage,
+ const std::string& configName, cmGeneratorTarget* t,
+ const Options& targetOptions);
void OutputDeploymentDebuggerTool(std::ostream& fout,
std::string const& config,
cmGeneratorTarget* target);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 98da10d..d49fefb 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -211,8 +211,6 @@
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
issueMessage = true;
messageType = MessageType::FATAL_ERROR;
break;
@@ -486,10 +484,6 @@
return result;
}
- if (this->ExecuteCommandCallback) {
- this->ExecuteCommandCallback();
- }
-
// Place this call on the call stack.
cmMakefileCall stack_manager(this, lff, std::move(deferId), status);
static_cast<void>(stack_manager);
@@ -545,6 +539,10 @@
}
}
+ if (this->ExecuteCommandCallback) {
+ this->ExecuteCommandCallback();
+ }
+
return result;
}
@@ -601,12 +599,6 @@
// OLD behavior is to not push a scope at all.
this->NoPolicyScope = true;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- // We should never make this policy required, but we handle it
- // here just in case.
- this->CheckCMP0011 = true;
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior is to push a (strong) scope.
this->Makefile->PushPolicy();
@@ -664,17 +656,6 @@
this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e);
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS: {
- auto e = cmStrCat(
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011),
- "\n"
- "The included script\n ",
- this->Makefile->GetBacktrace().Top().FilePath,
- "\n"
- "affects policy settings, so it requires this policy to be set.");
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
- } break;
case cmPolicies::OLD:
case cmPolicies::NEW:
// The script set this policy. We assume the purpose of the
@@ -980,8 +961,6 @@
// OLD behavior is to use policy version 2.4 set in
// cmListFileCache.
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// NEW behavior is to issue an error.
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
@@ -1183,8 +1162,6 @@
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
issueMessage = true;
messageType = MessageType::FATAL_ERROR;
break;
@@ -1539,12 +1516,6 @@
// OLD behavior is to not escape the value. We should not
// convert the definition to use the property.
return false;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0005));
- return false;
case cmPolicies::NEW:
// NEW behavior is to escape the value. Proceed to convert it
// to an entry in the property.
@@ -1923,11 +1894,6 @@
case cmPolicies::OLD:
// OLD behavior does not warn.
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- e += cmStrCat('\n',
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0014));
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior prints the error.
this->IssueMessage(MessageType::FATAL_ERROR, e);
@@ -2088,7 +2054,7 @@
cmList files(value);
for (auto& file : files) {
if (!cmIsOff(file)) {
- file = cmSystemTools::CollapseFullPath(file);
+ file = cmSystemTools::ToNormalizedPathOnDisk(file);
}
}
nvalue = files.to_string();
@@ -2116,8 +2082,6 @@
this->StateSnapshot.RemoveDefinition(name);
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
break;
}
}
@@ -2387,13 +2351,9 @@
cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name)
{
- std::string delimiters;
- if (cmValue p = this->GetDefinition("SOURCE_GROUP_DELIMITER")) {
- delimiters = *p;
- } else {
- delimiters = "/\\";
- }
- return this->GetOrCreateSourceGroup(cmTokenize(name, delimiters));
+ auto p = this->GetDefinition("SOURCE_GROUP_DELIMITER");
+ return this->GetOrCreateSourceGroup(
+ cmTokenize(name, p ? cm::string_view(*p) : R"(\/)"_s));
}
/**
@@ -2794,8 +2754,6 @@
noEscapes, atOnly, filename,
line, removeEmpty, true);
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
// Messaging here would be *very* verbose.
case cmPolicies::NEW:
mtype = this->ExpandVariablesInStringNew(errorstr, source, escapeQuotes,
@@ -2941,11 +2899,6 @@
// OLD behavior is to just warn and continue.
mtype = MessageType::AUTHOR_WARNING;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- error += cmStrCat(
- '\n', cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0010));
- break;
case cmPolicies::NEW:
// NEW behavior is to report the error.
break;
@@ -3722,10 +3675,7 @@
// use the cmake object instead of calling cmake
cmWorkingDirectory workdir(bindir);
if (workdir.Failed()) {
- this->IssueMessage(MessageType::FATAL_ERROR,
- cmStrCat("Failed to set working directory to ", bindir,
- " : ",
- std::strerror(workdir.GetLastResult())));
+ this->IssueMessage(MessageType::FATAL_ERROR, workdir.GetError());
cmSystemTools::SetFatalErrorOccurred();
this->IsSourceFileTryCompile = false;
return 1;
@@ -3969,8 +3919,6 @@
system = false;
result = moduleInCMakeModulePath;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
system = true;
result = moduleInCMakeRoot;
@@ -4435,12 +4383,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
return true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0002));
- return true;
case cmPolicies::NEW:
break;
}
@@ -4525,11 +4467,6 @@
case cmPolicies::OLD:
// OLD behavior does not warn.
return true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- e = cmStrCat(cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0013),
- '\n');
- CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior prints the error.
e += cmStrCat("The binary directory\n"
@@ -4636,23 +4573,22 @@
bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
cmPolicies::PolicyStatus status)
{
- // A REQUIRED_ALWAYS policy may be set only to NEW.
- if (status != cmPolicies::NEW &&
- cmPolicies::GetPolicyStatus(id) == cmPolicies::REQUIRED_ALWAYS) {
- std::string msg = cmPolicies::GetRequiredAlwaysPolicyError(id);
+ // A removed policy may be set only to NEW.
+ if (cmPolicies::IsRemoved(id) && status != cmPolicies::NEW) {
+ std::string msg = cmPolicies::GetRemovedPolicyError(id);
this->IssueMessage(MessageType::FATAL_ERROR, msg);
return false;
}
// Deprecate old policies.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0129 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0139 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 ||
id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104 ||
id == cmPolicies::CMP0123 || id == cmPolicies::CMP0126 ||
- id == cmPolicies::CMP0128)) &&
+ id == cmPolicies::CMP0128 || id == cmPolicies::CMP0136)) &&
(!this->IsSet("CMAKE_WARN_DEPRECATED") ||
this->IsOn("CMAKE_WARN_DEPRECATED"))) {
this->IssueMessage(MessageType::DEPRECATION_WARNING,
@@ -4750,8 +4686,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
ignoreErrors = false;
break;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 96a0d5c..e24f2b7 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -12,6 +12,7 @@
#include <cmext/algorithm>
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
@@ -233,7 +234,8 @@
}
auto rulePlaceholderExpander =
- this->LocalGenerator->CreateRulePlaceholderExpander();
+ this->LocalGenerator->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
@@ -370,19 +372,20 @@
// Add flags to create an executable.
this->LocalGenerator->AddConfigVariableFlags(
- linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GetConfigName());
+ linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GeneratorTarget,
+ cmBuildStep::Link, linkLanguage, this->GetConfigName());
- if (this->GeneratorTarget->IsWin32Executable(
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"))) {
+ {
+ auto exeType =
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_",
+ (this->GeneratorTarget->IsWin32Executable(
+ this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
+ ? "WIN32"
+ : "CONSOLE"),
+ "_EXE");
this->LocalGenerator->AppendFlags(
- linkFlags,
- this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE")));
- } else {
- this->LocalGenerator->AppendFlags(
- linkFlags,
- this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE")));
+ linkFlags, this->Makefile->GetDefinition(exeType), exeType,
+ this->GeneratorTarget, cmBuildStep::Link, linkLanguage);
}
// Add symbol export flags if necessary.
@@ -602,7 +605,8 @@
}
auto rulePlaceholderExpander =
- this->LocalGenerator->CreateRulePlaceholderExpander();
+ this->LocalGenerator->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 225e63b..746ee50 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -12,6 +12,7 @@
#include <cmext/algorithm>
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
@@ -177,7 +178,8 @@
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GetConfigName());
+ extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GeneratorTarget,
+ cmBuildStep::Link, linkLanguage, this->GetConfigName());
std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
@@ -212,7 +214,8 @@
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GetConfigName());
+ extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GeneratorTarget,
+ cmBuildStep::Link, linkLanguage, this->GetConfigName());
std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
@@ -239,7 +242,8 @@
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GetConfigName());
+ extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GeneratorTarget,
+ cmBuildStep::Link, linkLanguage, this->GetConfigName());
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -382,7 +386,8 @@
}
auto rulePlaceholderExpander =
- this->LocalGenerator->CreateRulePlaceholderExpander();
+ this->LocalGenerator->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
// Construct the main link rule and expand placeholders.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
@@ -707,7 +712,8 @@
// Expand the rule variables.
auto rulePlaceholderExpander =
- this->LocalGenerator->CreateRulePlaceholderExpander();
+ this->LocalGenerator->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
bool useWatcomQuote =
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
cmList real_link_commands;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 9d0d466..aec690e 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -25,6 +25,7 @@
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
@@ -74,8 +75,6 @@
this->CMP0113New = false;
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
this->CMP0113New = true;
break;
}
@@ -157,6 +156,8 @@
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
+ this->LocalGenerator->AppendWarningAsErrorLinkerFlags(
+ flags, this->GeneratorTarget, linkLanguage);
this->LocalGenerator->AppendDependencyInfoLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
@@ -683,9 +684,7 @@
// The object file should be checked for dependency integrity.
std::string objFullPath =
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', obj);
- objFullPath = cmSystemTools::CollapseFullPath(objFullPath);
- std::string const srcFullPath =
- cmSystemTools::CollapseFullPath(source.GetFullPath());
+ std::string const srcFullPath = source.GetFullPath();
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
objFullPath, srcFullPath, scanner);
@@ -1560,8 +1559,7 @@
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(this->InfoFileNameFull),
- cmOutputConverter::SHELL);
+ this->InfoFileNameFull, cmOutputConverter::SHELL);
if (this->LocalGenerator->GetColorMakefile()) {
depCmd << " \"--color=$(COLOR)\"";
}
@@ -1710,7 +1708,8 @@
vars.Flags = flags.c_str();
std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE");
- auto rulePlaceholderExpander = localGen->CreateRulePlaceholderExpander();
+ auto rulePlaceholderExpander = localGen->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GetGeneratorTarget(), "CUDA");
rulePlaceholderExpander->ExpandRuleVariables(localGen, compileCmd, vars);
commands.emplace_back(compileCmd);
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index 87421f5..8edbb6a 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -54,8 +54,6 @@
oldBehavior = true;
break;
case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
if (!state->GetCacheEntryValue(variable)) {
ignoreVariable = true;
}
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index a4b2538..3a40069 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -26,14 +26,6 @@
namespace {
-enum class CheckingType
-{
- UNDEFINED,
- CHECK_START,
- CHECK_PASS,
- CHECK_FAIL
-};
-
std::string IndentText(std::string text, cmMakefile& mf)
{
auto indent =
@@ -106,7 +98,7 @@
auto type = MessageType::MESSAGE;
auto fatal = false;
auto level = Message::LogLevel::LOG_UNDEFINED;
- auto checkingType = CheckingType::UNDEFINED;
+ auto checkingType = Message::CheckType::UNDEFINED;
if (*i == "SEND_ERROR") {
type = MessageType::FATAL_ERROR;
level = Message::LogLevel::LOG_ERROR;
@@ -135,15 +127,15 @@
++i;
} else if (*i == "CHECK_START") {
level = Message::LogLevel::LOG_STATUS;
- checkingType = CheckingType::CHECK_START;
+ checkingType = Message::CheckType::CHECK_START;
++i;
} else if (*i == "CHECK_PASS") {
level = Message::LogLevel::LOG_STATUS;
- checkingType = CheckingType::CHECK_PASS;
+ checkingType = Message::CheckType::CHECK_PASS;
++i;
} else if (*i == "CHECK_FAIL") {
level = Message::LogLevel::LOG_STATUS;
- checkingType = CheckingType::CHECK_FAIL;
+ checkingType = Message::CheckType::CHECK_FAIL;
++i;
} else if (*i == "CONFIGURE_LOG") {
#ifndef CMAKE_BOOTSTRAP
@@ -217,16 +209,16 @@
case Message::LogLevel::LOG_STATUS:
switch (checkingType) {
- case CheckingType::CHECK_START:
+ case Message::CheckType::CHECK_START:
mf.DisplayStatus(IndentText(message, mf), -1);
mf.GetCMakeInstance()->PushCheckInProgressMessage(message);
break;
- case CheckingType::CHECK_PASS:
+ case Message::CheckType::CHECK_PASS:
ReportCheckResult("CHECK_PASS"_s, message, mf);
break;
- case CheckingType::CHECK_FAIL:
+ case Message::CheckType::CHECK_FAIL:
ReportCheckResult("CHECK_FAIL"_s, message, mf);
break;
diff --git a/Source/cmMessageType.h b/Source/cmMessageType.h
index decb4b3..a877592 100644
--- a/Source/cmMessageType.h
+++ b/Source/cmMessageType.h
@@ -6,6 +6,7 @@
enum class MessageType
{
+ UNDEFINED,
AUTHOR_WARNING,
AUTHOR_ERROR,
FATAL_ERROR,
@@ -31,4 +32,13 @@
LOG_DEBUG,
LOG_TRACE
};
+
+enum class CheckType
+{
+ UNDEFINED,
+ CHECK_START,
+ CHECK_PASS,
+ CHECK_FAIL
+};
+
}
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index 01ff7f0..1583353 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -102,11 +102,10 @@
t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) {
cmSystemTools::SetErrorOccurred();
md.title = "Error";
- cmSystemTools::Message(msg.str(), md);
} else {
md.title = "Warning";
- cmSystemTools::Message(msg.str(), md);
}
+ cmSystemTools::Message(msg.str(), md);
}
void PrintCallStack(std::ostream& out, cmListFileBacktrace bt,
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 891187a..ff514ff 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmLinkLineComputer.h"
@@ -350,7 +351,9 @@
}
auto rulePlaceholderExpander =
- this->GetLocalGenerator()->CreateRulePlaceholderExpander();
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GetGeneratorTarget(),
+ this->TargetLinkLanguage(config));
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd();
@@ -413,7 +416,9 @@
std::string compileCmd = this->GetMakefile()->GetRequiredDefinition(
"CMAKE_CUDA_DEVICE_LINK_COMPILE");
auto rulePlaceholderExpander =
- this->GetLocalGenerator()->CreateRulePlaceholderExpander();
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GetGeneratorTarget(),
+ this->TargetLinkLanguage(config));
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
compileCmd, vars);
@@ -566,7 +571,9 @@
}
auto rulePlaceholderExpander =
- this->GetLocalGenerator()->CreateRulePlaceholderExpander();
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander(
+ cmBuildStep::Link, this->GetGeneratorTarget(),
+ this->TargetLinkLanguage(config));
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 720020d..9beeaa6 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -29,6 +29,7 @@
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalNinjaGenerator.h"
@@ -1059,8 +1060,6 @@
case cmPolicies::WARN:
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
usePrivateGeneratedSources = true;
break;
@@ -1289,11 +1288,9 @@
if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
return *name;
}
- return this->GetLocalGenerator()->ConvertToOutputFormat(
- this->ConvertToNinjaPath(cmStrCat(target->GetSupportDirectory(), '/',
- config, '/', target->GetName(),
- ".swiftdeps")),
- cmOutputConverter::SHELL);
+ return this->ConvertToNinjaPath(cmStrCat(target->GetSupportDirectory(),
+ '/', config, '/',
+ target->GetName(), ".swiftdeps"));
}();
std::string mapFilePath =
@@ -1311,7 +1308,7 @@
// Add flag
this->LocalGenerator->AppendFlags(flags, "-output-file-map");
- this->LocalGenerator->AppendFlagEscape(
+ this->LocalGenerator->AppendFlags(
flags,
this->GetLocalGenerator()->ConvertToOutputFormat(
ConvertToNinjaPath(mapFilePath), cmOutputConverter::SHELL));
@@ -2014,7 +2011,10 @@
std::string const emitModuleFlag = "-emit-module";
std::string const modulePathFlag = "-emit-module-path";
this->LocalGenerator->AppendFlags(
- vars["FLAGS"], { emitModuleFlag, modulePathFlag, moduleFilepath });
+ vars["FLAGS"],
+ { emitModuleFlag, modulePathFlag,
+ this->LocalGenerator->ConvertToOutputFormat(
+ moduleFilepath, cmOutputConverter::SHELL) });
objBuild.Outputs.push_back(moduleFilepath);
}
this->LocalGenerator->AppendFlags(vars["FLAGS"],
@@ -2273,7 +2273,10 @@
}
compileObjectVars.Source = escapedSourceFileName.c_str();
- compileObjectVars.Object = objectFileName.c_str();
+ std::string escapedObjectFileName =
+ this->LocalGenerator->ConvertToOutputFormat(objectFileName,
+ cmOutputConverter::SHELL);
+ compileObjectVars.Object = escapedObjectFileName.c_str();
compileObjectVars.ObjectDir = objectDir.c_str();
compileObjectVars.ObjectFileDir = objectFileDir.c_str();
compileObjectVars.Flags = fullFlags.c_str();
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index d589f0e..2960cf7 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -38,8 +38,6 @@
case cmPolicies::OLD:
// OLD behavior does not warn.
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW: {
// See if a local variable with this name already exists.
// If so we ignore the option command.
diff --git a/Source/cmPathResolver.cxx b/Source/cmPathResolver.cxx
new file mode 100644
index 0000000..93457a5
--- /dev/null
+++ b/Source/cmPathResolver.cxx
@@ -0,0 +1,541 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmPathResolver.h"
+
+#include <algorithm>
+#include <cerrno>
+#include <cstddef>
+#include <string>
+#include <utility>
+
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#ifdef _WIN32
+# include <cctype>
+
+# include <windows.h>
+#endif
+
+#define MAX_SYMBOLIC_LINKS 32
+
+namespace cm {
+namespace PathResolver {
+
+namespace {
+
+namespace Options {
+
+enum class ActualCase
+{
+ No,
+ Yes,
+};
+
+enum class Symlinks
+{
+ None,
+ Lazy,
+ Eager,
+};
+
+enum class Existence
+{
+ Agnostic,
+ Required,
+};
+}
+
+enum class Root
+{
+ None,
+ POSIX,
+#ifdef _WIN32
+ Drive,
+ Network,
+#endif
+};
+
+struct Control
+{
+ enum class Tag
+ {
+ Continue,
+ Restart,
+ Error,
+ };
+ Tag tag;
+ union
+ {
+ std::string::size_type slash; // data for Continue
+ cmsys::Status error; // data for Error
+ };
+ static Control Continue(std::string::size_type s)
+ {
+ Control c{ Tag::Continue };
+ c.slash = s;
+ return c;
+ }
+ static Control Restart() { return Control{ Tag::Restart }; }
+ static Control Error(cmsys::Status e)
+ {
+ Control c{ Tag::Error };
+ c.error = e;
+ return c;
+ }
+
+private:
+ Control(Tag t)
+ : tag(t)
+ {
+ }
+};
+
+Root ClassifyRoot(cm::string_view p)
+{
+#ifdef _WIN32
+ if (p.size() >= 2 && std::isalpha(p[0]) && p[1] == ':') {
+ return Root::Drive;
+ }
+ if (p.size() >= 3 && p[0] == '/' && p[1] == '/' && p[2] != '/') {
+ return Root::Network;
+ }
+#endif
+ if (!p.empty() && p[0] == '/') {
+ return Root::POSIX;
+ }
+ return Root::None;
+}
+
+class ImplBase
+{
+protected:
+ ImplBase(System& os)
+ : OS(os)
+ {
+ }
+
+ System& OS;
+ std::string P;
+ std::size_t SymlinkDepth = 0;
+
+#ifdef _WIN32
+ std::string GetWorkingDirectoryOnDrive(char letter);
+ Control ResolveRootRelative();
+#endif
+ cm::optional<std::string> ReadSymlink(std::string const& path,
+ cmsys::Status& status);
+ Control ResolveSymlink(Root root, std::string::size_type slash,
+ std::string::size_type next_slash,
+ std::string symlink_target);
+};
+
+template <class Policy>
+class Impl : public ImplBase
+{
+ Control ResolveRelativePath();
+ Control ResolveRoot(Root root);
+ Control ResolveComponent(Root root, std::string::size_type root_slash,
+ std::string::size_type slash);
+ Control ResolvePath();
+
+public:
+ Impl(System& os)
+ : ImplBase(os)
+ {
+ }
+ cmsys::Status Resolve(std::string in, std::string& out);
+};
+
+template <class Policy>
+Control Impl<Policy>::ResolveRelativePath()
+{
+ // This is a relative path. Convert it to absolute and restart.
+ std::string p = this->OS.GetWorkingDirectory();
+ std::replace(p.begin(), p.end(), '\\', '/');
+ if (ClassifyRoot(p) == Root::None) {
+ p.insert(0, 1, '/');
+ }
+ if (p.back() != '/') {
+ p.push_back('/');
+ }
+ P.insert(0, p);
+ return Control::Restart();
+}
+
+#ifdef _WIN32
+std::string ImplBase::GetWorkingDirectoryOnDrive(char letter)
+{
+ // Use the drive's working directory, if any.
+ std::string d = this->OS.GetWorkingDirectoryOnDrive(letter);
+ std::replace(d.begin(), d.end(), '\\', '/');
+ if (d.size() >= 3 && std::toupper(d[0]) == std::toupper(letter) &&
+ d[1] == ':' && d[2] == '/') {
+ d[0] = letter;
+ d.push_back('/');
+ return d;
+ }
+
+ // Use the current working directory if the drive matches.
+ d = this->OS.GetWorkingDirectory();
+ if (d.size() >= 3 && std::toupper(d[0]) == std::toupper(letter) &&
+ d[1] == ':' && d[2] == '/') {
+ d[0] = letter;
+ d.push_back('/');
+ return d;
+ }
+
+ // Fall back to the root directory on the drive.
+ d = "_:/";
+ d[0] = letter;
+ return d;
+}
+
+Control ImplBase::ResolveRootRelative()
+{
+ // This is a root-relative path. Resolve the root drive and restart.
+ P.replace(0, 2, this->GetWorkingDirectoryOnDrive(P[0]));
+ return Control::Restart();
+}
+#endif
+
+cm::optional<std::string> ImplBase::ReadSymlink(std::string const& path,
+ cmsys::Status& status)
+{
+ cm::optional<std::string> result;
+ std::string target;
+ status = this->OS.ReadSymlink(path, target);
+ if (status && ++this->SymlinkDepth >= MAX_SYMBOLIC_LINKS) {
+ status = cmsys::Status::POSIX(ELOOP);
+ }
+ if (status) {
+ if (!target.empty()) {
+ result = std::move(target);
+ }
+ } else if (status.GetPOSIX() == EINVAL
+#ifdef _WIN32
+ || status.GetWindows() == ERROR_NOT_A_REPARSE_POINT
+#endif
+ ) {
+ // The path was not a symlink.
+ status = cmsys::Status::Success();
+ }
+ return result;
+}
+
+Control ImplBase::ResolveSymlink(Root root, std::string::size_type slash,
+ std::string::size_type next_slash,
+ std::string symlink_target)
+{
+ std::replace(symlink_target.begin(), symlink_target.end(), '\\', '/');
+ Root const symlink_target_root = ClassifyRoot(symlink_target);
+ if (symlink_target_root == Root::None) {
+ // This is a symlink to a relative path.
+ // Resolve the symlink, while preserving the leading and
+ // trailing (if any) slash:
+ // "*/link/" => "*/dest/"
+ // ^slash ^slash
+ P.replace(slash + 1, next_slash - slash - 1, symlink_target);
+ return Control::Continue(slash);
+ }
+
+#ifdef _WIN32
+ if (root == Root::Drive && symlink_target_root == Root::POSIX) {
+ // This is a symlink to a POSIX absolute path,
+ // but the current path is on a drive letter. Resolve the
+ // symlink while preserving the drive letter, and start over:
+ // "C:/*/link/" => "C:/dest/"
+ // ^slash (restart)
+ P.replace(2, next_slash - 2, symlink_target);
+ return Control::Restart();
+ }
+#else
+ static_cast<void>(root);
+#endif
+
+ // This is a symlink to an absolute path.
+ // Resolve it and start over:
+ // "*/link/" => "/dest/"
+ // ^slash (restart)
+ P.replace(0, next_slash, symlink_target);
+ return Control::Restart();
+}
+
+template <class Policy>
+Control Impl<Policy>::ResolveRoot(Root root)
+{
+ if (root == Root::None) {
+ return this->ResolveRelativePath();
+ }
+
+ // POSIX absolute paths always start with a '/'.
+ std::string::size_type root_slash = 0;
+
+#ifdef _WIN32
+ if (root == Root::Drive) {
+ if (P.size() == 2 || P[2] != '/') {
+ return this->ResolveRootRelative();
+ }
+
+ if (Policy::ActualCase == Options::ActualCase::Yes) {
+ // Normalize the drive letter to upper-case.
+ P[0] = static_cast<char>(std::toupper(P[0]));
+ }
+
+ // The root is a drive letter. The root '/' immediately follows.
+ root_slash = 2;
+ } else if (root == Root::Network) {
+ // The root is a network name. Find the root '/' after it.
+ root_slash = P.find('/', 2);
+ if (root_slash == std::string::npos) {
+ root_slash = P.size();
+ P.push_back('/');
+ }
+ }
+#endif
+
+ if (Policy::Existence == Options::Existence::Required
+#ifdef _WIN32
+ && root != Root::Network
+#endif
+ ) {
+ std::string path = P.substr(0, root_slash + 1);
+ if (!this->OS.PathExists(path)) {
+ P = std::move(path);
+ return Control::Error(cmsys::Status::POSIX(ENOENT));
+ }
+ }
+
+ return Control::Continue(root_slash);
+}
+
+template <class Policy>
+Control Impl<Policy>::ResolveComponent(Root root,
+ std::string::size_type root_slash,
+ std::string::size_type slash)
+{
+ // Look for the '/' or end-of-input that ends this component.
+ // The sample paths in comments below show the trailing slash
+ // even if it is actually beyond the end of the path.
+ std::string::size_type next_slash = P.find('/', slash + 1);
+ if (next_slash == std::string::npos) {
+ next_slash = P.size();
+ }
+ cm::string_view c =
+ cm::string_view(P).substr(slash + 1, next_slash - (slash + 1));
+
+ if (slash == root_slash) {
+ if (c.empty() || c == "."_s || c == ".."_s) {
+ // This is an empty, '.', or '..' component at the root.
+ // Drop the component and its trailing slash, if any,
+ // while preserving the root slash:
+ // "//" => "/"
+ // "/./" => "/"
+ // "/../" => "/"
+ // ^slash ^slash
+ P.erase(slash + 1, next_slash - slash);
+ return Control::Continue(slash);
+ }
+ } else {
+ if (c.empty() || c == "."_s) {
+ // This is an empty or '.' component not at the root.
+ // Drop the component and its leading slash:
+ // "*//" => "*/"
+ // "*/./" => "*/"
+ // ^slash ^slash
+ P.erase(slash, next_slash - slash);
+ return Control::Continue(slash);
+ }
+
+ if (c == ".."_s) {
+ // This is a '..' component not at the root.
+ // Rewind to the previous component:
+ // "*/prev/../" => "*/prev/../"
+ // ^slash ^slash
+ next_slash = slash;
+ slash = P.rfind('/', slash - 1);
+
+ if (Policy::Symlinks == Options::Symlinks::Lazy) {
+ cmsys::Status status;
+ std::string path = P.substr(0, next_slash);
+ if (cm::optional<std::string> maybe_symlink_target =
+ this->ReadSymlink(path, status)) {
+ return this->ResolveSymlink(root, slash, next_slash,
+ std::move(*maybe_symlink_target));
+ }
+ if (!status && Policy::Existence == Options::Existence::Required) {
+ P = std::move(path);
+ return Control::Error(status);
+ }
+ }
+
+ // This is not a symlink.
+ // Drop the component, the following '..', and its trailing slash,
+ // if any, while preserving the (possibly root) leading slash:
+ // "*/dir/../" => "*/"
+ // ^slash ^slash
+ P.erase(slash + 1, next_slash + 3 - slash);
+ return Control::Continue(slash);
+ }
+ }
+
+ // This is a named component.
+
+ if (Policy::Symlinks == Options::Symlinks::Eager) {
+ cmsys::Status status;
+ std::string path = P.substr(0, next_slash);
+ if (cm::optional<std::string> maybe_symlink_target =
+ this->ReadSymlink(path, status)) {
+ return this->ResolveSymlink(root, slash, next_slash,
+ std::move(*maybe_symlink_target));
+ }
+ if (!status && Policy::Existence == Options::Existence::Required) {
+ P = std::move(path);
+ return Control::Error(status);
+ }
+ }
+
+#ifdef _WIN32
+ bool exists = false;
+ if (Policy::ActualCase == Options::ActualCase::Yes) {
+ std::string name;
+ std::string path = P.substr(0, next_slash);
+ if (cmsys::Status status = this->OS.ReadName(path, name)) {
+ exists = true;
+ if (!name.empty()) {
+ // Rename this component:
+ // "*/name/" => "*/Name/"
+ // ^slash ^slash
+ P.replace(slash + 1, next_slash - slash - 1, name);
+ next_slash = slash + 1 + name.length();
+ }
+ } else if (Policy::Existence == Options::Existence::Required) {
+ P = std::move(path);
+ return Control::Error(status);
+ }
+ }
+#endif
+
+ if (Policy::Existence == Options::Existence::Required
+#ifdef _WIN32
+ && !exists
+#endif
+ ) {
+ std::string path = P.substr(0, next_slash);
+ if (!this->OS.PathExists(path)) {
+ P = std::move(path);
+ return Control::Error(cmsys::Status::POSIX(ENOENT));
+ }
+ }
+
+ // Keep this component:
+ // "*/name/" => "*/name/"
+ // ^slash ^slash
+ return Control::Continue(next_slash);
+}
+
+template <class Policy>
+Control Impl<Policy>::ResolvePath()
+{
+ Root const root = ClassifyRoot(P);
+
+ // Resolve the root component. It always ends in a slash.
+ Control control = this->ResolveRoot(root);
+ if (control.tag != Control::Tag::Continue) {
+ return control;
+ }
+ std::string::size_type const root_slash = control.slash;
+
+ // Resolve later components. Every iteration that finishes
+ // the loop body makes progress either by removing a component
+ // or advancing the slash past it.
+ for (std::string::size_type slash = root_slash;
+ P.size() > root_slash + 1 && slash < P.size();) {
+ control = this->ResolveComponent(root, root_slash, slash);
+ if (control.tag != Control::Tag::Continue) {
+ return control;
+ }
+ slash = control.slash;
+ }
+ return Control::Continue(P.size());
+}
+
+template <class Policy>
+cmsys::Status Impl<Policy>::Resolve(std::string in, std::string& out)
+{
+ P = std::move(in);
+ std::replace(P.begin(), P.end(), '\\', '/');
+ for (;;) {
+ Control control = this->ResolvePath();
+ switch (control.tag) {
+ case Control::Tag::Continue:
+ out = std::move(P);
+ return cmsys::Status::Success();
+ case Control::Tag::Restart:
+ continue;
+ case Control::Tag::Error:
+ out = std::move(P);
+ return control.error;
+ };
+ }
+}
+
+}
+
+namespace Policies {
+struct NaivePath
+{
+#ifdef _WIN32
+ static constexpr Options::ActualCase ActualCase = Options::ActualCase::No;
+#endif
+ static constexpr Options::Symlinks Symlinks = Options::Symlinks::None;
+ static constexpr Options::Existence Existence = Options::Existence::Agnostic;
+};
+struct RealPath
+{
+#ifdef _WIN32
+ static constexpr Options::ActualCase ActualCase = Options::ActualCase::Yes;
+#endif
+ static constexpr Options::Symlinks Symlinks = Options::Symlinks::Eager;
+ static constexpr Options::Existence Existence = Options::Existence::Required;
+};
+struct LogicalPath
+{
+#ifdef _WIN32
+ static constexpr Options::ActualCase ActualCase = Options::ActualCase::Yes;
+#endif
+ static constexpr Options::Symlinks Symlinks = Options::Symlinks::Lazy;
+ static constexpr Options::Existence Existence = Options::Existence::Agnostic;
+};
+
+#if defined(__SUNPRO_CC)
+constexpr Options::Symlinks NaivePath::Symlinks;
+constexpr Options::Existence NaivePath::Existence;
+constexpr Options::Symlinks RealPath::Symlinks;
+constexpr Options::Existence RealPath::Existence;
+constexpr Options::Symlinks LogicalPath::Symlinks;
+constexpr Options::Existence LogicalPath::Existence;
+#endif
+}
+
+template <class Policy>
+Resolver<Policy>::Resolver(System& os)
+ : OS(os)
+{
+}
+template <class Policy>
+cmsys::Status Resolver<Policy>::Resolve(std::string in, std::string& out) const
+{
+ return Impl<Policy>(OS).Resolve(std::move(in), out);
+}
+
+System::System() = default;
+System::~System() = default;
+
+template class Resolver<Policies::LogicalPath>;
+template class Resolver<Policies::RealPath>;
+template class Resolver<Policies::NaivePath>;
+
+}
+}
diff --git a/Source/cmPathResolver.h b/Source/cmPathResolver.h
new file mode 100644
index 0000000..0f8baf8
--- /dev/null
+++ b/Source/cmPathResolver.h
@@ -0,0 +1,98 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+#include "cmsys/Status.hxx"
+
+namespace cm {
+namespace PathResolver {
+
+class System;
+
+/** Normalize filesystem paths according to a Policy.
+ *
+ * Resolved paths are always absolute, have no '..', '.', or empty
+ * components, and have a trailing '/' if and only if the entire
+ * path is a root component.
+ *
+ * The Policy determines behavior w.r.t. symbolic links, existence,
+ * and matching the on-disk case (upper/lower) of existing paths.
+ */
+template <class Policy>
+class Resolver
+{
+ System& OS;
+
+public:
+ /** Construct with a concrete filesystem access implementation. */
+ Resolver(System& os);
+
+ /** Resolve the input path according to the Policy, if possible.
+ On success, the resolved path is stored in 'out'.
+ On failure, the non-existent path is stored in 'out'. */
+ cmsys::Status Resolve(std::string in, std::string& out) const;
+};
+
+/** Access the filesystem via runtime dispatch.
+ This allows unit tests to work without accessing a real filesystem,
+ which is particularly important on Windows where symbolic links
+ may not be something we can create without administrator privileges.
+ */
+class System
+{
+public:
+ System();
+ virtual ~System() = 0;
+
+ /** If the given path is a symbolic link, read its target.
+ If the path exists but is not a symbolic link, fail
+ with EINVAL or ERROR_NOT_A_REPARSE_POINT. */
+ virtual cmsys::Status ReadSymlink(std::string const& path,
+ std::string& symlink_target) = 0;
+
+ /** Return whether the given path exists on disk. */
+ virtual bool PathExists(std::string const& path) = 0;
+
+ /** Get the process's working directory. */
+ virtual std::string GetWorkingDirectory() = 0;
+
+#ifdef _WIN32
+ /** Get the process's working directory on a Windows drive letter.
+ This is a legacy DOS concept supported by 'cmd' shells. */
+ virtual std::string GetWorkingDirectoryOnDrive(char drive_letter) = 0;
+
+ /** Read the on-disk spelling of the last component of a file path. */
+ virtual cmsys::Status ReadName(std::string const& path,
+ std::string& name) = 0;
+#endif
+};
+
+namespace Policies {
+// IWYU pragma: begin_exports
+
+/** Normalizes paths while resolving symlinks only when followed
+ by '..' components. Does not require paths to exist, but
+ reads on-disk case of paths that do exist (on Windows). */
+struct LogicalPath;
+
+/** Normalizes paths while resolving all symlinks.
+ Requires paths to exist, and reads their on-disk case (on Windows). */
+struct RealPath;
+
+/** Normalizes paths in memory without disk access.
+ Assumes components followed by '..' components are not symlinks. */
+struct NaivePath;
+
+// IWYU pragma: end_exports
+}
+
+extern template class Resolver<Policies::LogicalPath>;
+extern template class Resolver<Policies::RealPath>;
+extern template class Resolver<Policies::NaivePath>;
+
+}
+}
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index d3b2769..fa64029 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -1,3 +1,5 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPolicies.h"
#include <cassert>
@@ -55,6 +57,10 @@
#define CM_FOR_EACH_POLICY_ID_DOC(POLICY) \
CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID_DOC)
+#define CM_SELECT_ID_STATUS(F, A1, A2, A3, A4, A5, A6) F(A1, A6)
+#define CM_FOR_EACH_POLICY_ID_STATUS(POLICY) \
+ CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID_STATUS)
+
static const char* idToString(cmPolicies::PolicyID id)
{
switch (id) {
@@ -117,6 +123,23 @@
return nullptr;
}
+namespace {
+cmPolicies::PolicyStatus idToStatus(cmPolicies::PolicyID id)
+{
+ switch (id) {
+#define POLICY_CASE(ID, STATUS) \
+ case cmPolicies::ID: \
+ return cmPolicies::STATUS;
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ CM_FOR_EACH_POLICY_ID_STATUS(POLICY_CASE)
+#undef POLICY_CASE
+ case cmPolicies::CMPCOUNT:
+ break;
+ }
+ return cmPolicies::WARN;
+}
+}
+
static void DiagnoseAncientPolicies(
std::vector<cmPolicies::PolicyID> const& ancient, unsigned int majorVer,
unsigned int minorVer, unsigned int patchVer, cmMakefile* mf)
@@ -254,6 +277,21 @@
warnCompat);
}
+namespace {
+bool IsFromLegacyInstallEXPORT(cmMakefile* mf, unsigned int majorVer,
+ unsigned int minorVer, unsigned int patchVer)
+{
+ return majorVer == 2 && minorVer == 6 && patchVer == 0 &&
+ mf->GetStateSnapshot().CanPopPolicyScope() &&
+ cmSystemTools::Strucmp(mf->GetBacktrace().Top().Name.c_str(),
+ "cmake_policy") == 0;
+}
+#define ADVICE_UPDATE_VERSION_ARGUMENT \
+ "Update the VERSION argument <min> value. Or, use the <min>...<max> " \
+ "syntax to tell CMake that the project requires at least <min> but has " \
+ "been updated to work with policies introduced by <max> or earlier."
+}
+
bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
unsigned int minorVer,
unsigned int patchVer,
@@ -262,19 +300,13 @@
// Warn about policy versions for which support will be removed.
if (warnCompat == WarnCompat::On &&
(majorVer < 3 || (majorVer == 3 && minorVer < 10)) &&
- // Avoid warning on calls generated by install(EXPORT)
+ // Silently tolerate cmake_policy calls generated by install(EXPORT)
// in CMake versions prior to 3.18.
- !(majorVer == 2 && minorVer == 6 && patchVer == 0 &&
- mf->GetStateSnapshot().CanPopPolicyScope() &&
- cmSystemTools::Strucmp(mf->GetBacktrace().Top().Name.c_str(),
- "cmake_policy") == 0)) {
+ !IsFromLegacyInstallEXPORT(mf, majorVer, minorVer, patchVer)) {
mf->IssueMessage(
MessageType::DEPRECATION_WARNING,
"Compatibility with CMake < 3.10 will be removed from "
- "a future version of CMake.\n"
- "Update the VERSION argument <min> value. Or, use the <min>...<max> "
- "syntax to tell CMake that the project requires at least <min> but has "
- "been updated to work with policies introduced by <max> or earlier.");
+ "a future version of CMake.\n" ADVICE_UPDATE_VERSION_ARGUMENT);
}
// now loop over all the policies and set them as appropriate
@@ -282,7 +314,7 @@
for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
pid = static_cast<PolicyID>(pid + 1)) {
if (isPolicyNewerThan(pid, majorVer, minorVer, patchVer)) {
- if (cmPolicies::GetPolicyStatus(pid) == cmPolicies::REQUIRED_ALWAYS) {
+ if (cmPolicies::IsRemoved(pid)) {
ancientPolicies.push_back(pid);
} else {
cmPolicies::PolicyStatus status = cmPolicies::WARN;
@@ -353,36 +385,12 @@
"to the NEW behavior and not rely on setting a policy to OLD.");
}
-//! return an error string for when a required policy is unspecified
-std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id)
+bool cmPolicies::IsRemoved(cmPolicies::PolicyID id)
{
- return cmStrCat(
- "Policy ", idToString(id),
- " is not set to NEW: ", idToShortDescription(id),
- " "
- "Run \"cmake --help-policy ",
- idToString(id),
- "\" for policy details. "
- "CMake now requires this policy to be set to NEW by the project. "
- "The policy may be set explicitly using the code\n"
- " cmake_policy(SET ",
- idToString(id),
- " NEW)\n"
- "or by upgrading all policies with the code\n"
- " cmake_policy(VERSION ",
- idToVersion(id),
- ") # or later\n"
- "Run \"cmake --help-command cmake_policy\" for more information.");
+ return idToStatus(id) == cmPolicies::NEW;
}
-//! Get the default status for a policy
-cmPolicies::PolicyStatus cmPolicies::GetPolicyStatus(
- cmPolicies::PolicyID /*unused*/)
-{
- return cmPolicies::WARN;
-}
-
-std::string cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
+std::string cmPolicies::GetRemovedPolicyError(cmPolicies::PolicyID id)
{
std::string pid = idToString(id);
return cmStrCat(
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index dbd6ce8..e70e159 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -9,550 +9,551 @@
class cmMakefile;
+// Each policy has a short description, the version of CMake in which
+// it was introduced, and its default status. The status is WARN for
+// existing policies and NEW for removed policies.
+
#define CM_FOR_EACH_POLICY_TABLE(POLICY, SELECT) \
SELECT(POLICY, CMP0000, \
"A minimum required CMake version must be specified.", 2, 6, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0001, \
"CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.", 2, 6, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0002, "Logical target names must be globally unique.", 2, \
- 6, 0, cmPolicies::WARN) \
+ 6, 0, WARN) \
SELECT( \
POLICY, CMP0003, \
"Libraries linked via full path no longer produce linker search paths.", \
- 2, 6, 0, cmPolicies::WARN) \
+ 2, 6, 0, WARN) \
SELECT(POLICY, CMP0004, \
"Libraries linked may not have leading or trailing whitespace.", 2, \
- 6, 0, cmPolicies::WARN) \
+ 6, 0, WARN) \
SELECT(POLICY, CMP0005, \
"Preprocessor definition values are now escaped automatically.", 2, \
- 6, 0, cmPolicies::WARN) \
+ 6, 0, WARN) \
SELECT(POLICY, CMP0006, \
"Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.", \
- 2, 6, 0, cmPolicies::WARN) \
+ 2, 6, 0, WARN) \
SELECT(POLICY, CMP0007, "list command no longer ignores empty elements.", \
- 2, 6, 0, cmPolicies::WARN) \
+ 2, 6, 0, WARN) \
SELECT( \
POLICY, CMP0008, \
"Libraries linked by full-path must have a valid library file name.", 2, \
- 6, 1, cmPolicies::WARN) \
+ 6, 1, WARN) \
SELECT(POLICY, CMP0009, \
"FILE GLOB_RECURSE calls should not follow symlinks by default.", 2, \
- 6, 2, cmPolicies::WARN) \
+ 6, 2, WARN) \
SELECT(POLICY, CMP0010, "Bad variable reference syntax is an error.", 2, 6, \
- 3, cmPolicies::WARN) \
+ 3, WARN) \
SELECT(POLICY, CMP0011, \
"Included scripts do automatic cmake_policy PUSH and POP.", 2, 6, 3, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0012, "if() recognizes numbers and boolean constants.", \
- 2, 8, 0, cmPolicies::WARN) \
+ 2, 8, 0, WARN) \
SELECT(POLICY, CMP0013, "Duplicate binary directories are not allowed.", 2, \
- 8, 0, cmPolicies::WARN) \
+ 8, 0, WARN) \
SELECT(POLICY, CMP0014, "Input directories must have CMakeLists.txt.", 2, \
- 8, 0, cmPolicies::WARN) \
+ 8, 0, WARN) \
SELECT(POLICY, CMP0015, \
"link_directories() treats paths relative to the source dir.", 2, 8, \
- 1, cmPolicies::WARN) \
+ 1, WARN) \
SELECT(POLICY, CMP0016, \
"target_link_libraries() reports error if its only argument " \
"is not a target.", \
- 2, 8, 3, cmPolicies::WARN) \
+ 2, 8, 3, WARN) \
SELECT(POLICY, CMP0017, \
"Prefer files from the CMake module directory when including from " \
"there.", \
- 2, 8, 4, cmPolicies::WARN) \
+ 2, 8, 4, WARN) \
SELECT(POLICY, CMP0018, \
- "Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.", 2, 8, 9, \
- cmPolicies::WARN) \
+ "Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.", 2, 8, 9, WARN) \
SELECT(POLICY, CMP0019, \
"Do not re-expand variables in include and link information.", 2, 8, \
- 11, cmPolicies::WARN) \
+ 11, WARN) \
SELECT(POLICY, CMP0020, \
"Automatically link Qt executables to qtmain target on Windows.", 2, \
- 8, 11, cmPolicies::WARN) \
+ 8, 11, WARN) \
SELECT( \
POLICY, CMP0021, \
"Fatal error on relative paths in INCLUDE_DIRECTORIES target property.", \
- 2, 8, 12, cmPolicies::WARN) \
+ 2, 8, 12, WARN) \
SELECT(POLICY, CMP0022, \
"INTERFACE_LINK_LIBRARIES defines the link interface.", 2, 8, 12, \
- cmPolicies::WARN) \
+ WARN) \
SELECT( \
POLICY, CMP0023, \
"Plain and keyword target_link_libraries signatures cannot be mixed.", 2, \
- 8, 12, cmPolicies::WARN) \
- SELECT(POLICY, CMP0024, "Disallow include export result.", 3, 0, 0, \
- cmPolicies::WARN) \
+ 8, 12, WARN) \
+ SELECT(POLICY, CMP0024, "Disallow include export result.", 3, 0, 0, WARN) \
SELECT(POLICY, CMP0025, "Compiler id for Apple Clang is now AppleClang.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0026, "Disallow use of the LOCATION target property.", 3, \
- 0, 0, cmPolicies::WARN) \
+ 0, 0, WARN) \
SELECT(POLICY, CMP0027, \
"Conditionally linked imported targets with missing include " \
"directories.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0028, \
"Double colon in target name means ALIAS or IMPORTED target.", 3, 0, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0029, "The subdir_depends command should not be called.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0030, \
- "The use_mangled_mesa command should not be called.", 3, 0, 0, \
- cmPolicies::WARN) \
+ "The use_mangled_mesa command should not be called.", 3, 0, 0, WARN) \
SELECT(POLICY, CMP0031, "The load_command command should not be called.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0032, \
"The output_required_files command should not be called.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0033, \
"The export_library_dependencies command should not be called.", 3, \
- 0, 0, cmPolicies::WARN) \
+ 0, 0, WARN) \
SELECT(POLICY, CMP0034, "The utility_source command should not be called.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0035, \
"The variable_requires command should not be called.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0036, "The build_name command should not be called.", 3, \
- 0, 0, cmPolicies::WARN) \
+ 0, 0, WARN) \
SELECT(POLICY, CMP0037, \
"Target names should not be reserved and should match a validity " \
"pattern.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0038, "Targets may not link directly to themselves.", 3, \
- 0, 0, cmPolicies::WARN) \
+ 0, 0, WARN) \
SELECT(POLICY, CMP0039, "Utility targets may not have link dependencies.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0040, \
"The target in the TARGET signature of add_custom_command() must " \
"exist and must be defined in the current directory.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0041, \
"Error on relative include with generator expression.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0042, "MACOSX_RPATH is enabled by default.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0043, "Ignore COMPILE_DEFINITIONS_<Config> properties.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0044, \
"Case sensitive <LANG>_COMPILER_ID generator expressions.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0045, \
"Error on non-existent target in get_target_property.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0046, \
"Error on non-existent dependency in add_dependencies.", 3, 0, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0047, "Use QCC compiler id for the qcc drivers on QNX.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0048, "project() command manages VERSION variables.", 3, \
- 0, 0, cmPolicies::WARN) \
+ 0, 0, WARN) \
SELECT(POLICY, CMP0049, \
- "Do not expand variables in target source entries.", 3, 0, 0, \
- cmPolicies::WARN) \
+ "Do not expand variables in target source entries.", 3, 0, 0, WARN) \
SELECT(POLICY, CMP0050, "Disallow add_custom_command SOURCE signatures.", \
- 3, 0, 0, cmPolicies::WARN) \
+ 3, 0, 0, WARN) \
SELECT(POLICY, CMP0051, "List TARGET_OBJECTS in SOURCES target property.", \
- 3, 1, 0, cmPolicies::WARN) \
+ 3, 1, 0, WARN) \
SELECT(POLICY, CMP0052, \
"Reject source and build dirs in installed " \
"INTERFACE_INCLUDE_DIRECTORIES.", \
- 3, 1, 0, cmPolicies::WARN) \
+ 3, 1, 0, WARN) \
SELECT(POLICY, CMP0053, \
"Simplify variable reference and escape sequence evaluation.", 3, 1, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT( \
POLICY, CMP0054, \
"Only interpret if() arguments as variables or keywords when unquoted.", \
- 3, 1, 0, cmPolicies::WARN) \
+ 3, 1, 0, WARN) \
SELECT(POLICY, CMP0055, "Strict checking for break() command.", 3, 2, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0056, \
"Honor link flags in try_compile() source-file signature.", 3, 2, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0057, "Support new IN_LIST if() operator.", 3, 3, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0058, \
"Ninja requires custom command byproducts to be explicit.", 3, 3, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0059, \
"Do not treat DEFINITIONS as a built-in directory property.", 3, 3, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0060, \
"Link libraries by full path even in implicit directories.", 3, 3, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0061, \
"CTest does not by default tell make to ignore errors (-i).", 3, 3, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0062, "Disallow install() of export() result.", 3, 3, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0063, \
- "Honor visibility properties for all target types.", 3, 3, 0, \
- cmPolicies::WARN) \
- SELECT(POLICY, CMP0064, "Support new TEST if() operator.", 3, 4, 0, \
- cmPolicies::WARN) \
+ "Honor visibility properties for all target types.", 3, 3, 0, WARN) \
+ SELECT(POLICY, CMP0064, "Support new TEST if() operator.", 3, 4, 0, WARN) \
SELECT(POLICY, CMP0065, \
"Do not add flags to export symbols from executables without " \
"the ENABLE_EXPORTS target property.", \
- 3, 4, 0, cmPolicies::WARN) \
+ 3, 4, 0, WARN) \
SELECT(POLICY, CMP0066, \
"Honor per-config flags in try_compile() source-file signature.", 3, \
- 7, 0, cmPolicies::WARN) \
+ 7, 0, WARN) \
SELECT(POLICY, CMP0067, \
"Honor language standard in try_compile() source-file signature.", \
- 3, 8, 0, cmPolicies::WARN) \
+ 3, 8, 0, WARN) \
SELECT(POLICY, CMP0068, \
"RPATH settings on macOS do not affect install_name.", 3, 9, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0069, \
"INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.", 3, 9, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0070, \
"Define file(GENERATE) behavior for relative paths.", 3, 10, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0071, "Let AUTOMOC and AUTOUIC process GENERATED files.", \
- 3, 10, 0, cmPolicies::WARN) \
+ 3, 10, 0, WARN) \
SELECT(POLICY, CMP0072, \
"FindOpenGL prefers GLVND by default when available.", 3, 11, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0073, \
- "Do not produce legacy _LIB_DEPENDS cache entries.", 3, 12, 0, \
- cmPolicies::WARN) \
+ "Do not produce legacy _LIB_DEPENDS cache entries.", 3, 12, 0, WARN) \
SELECT(POLICY, CMP0074, "find_package uses <PackageName>_ROOT variables.", \
- 3, 12, 0, cmPolicies::WARN) \
+ 3, 12, 0, WARN) \
SELECT(POLICY, CMP0075, \
"Include file check macros honor CMAKE_REQUIRED_LIBRARIES.", 3, 12, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0076, \
"target_sources() command converts relative paths to absolute.", 3, \
- 13, 0, cmPolicies::WARN) \
+ 13, 0, WARN) \
SELECT(POLICY, CMP0077, "option() honors normal variables.", 3, 13, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0078, "UseSWIG generates standard target names.", 3, 13, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT( \
POLICY, CMP0079, \
"target_link_libraries allows use with targets in other directories.", 3, \
- 13, 0, cmPolicies::WARN) \
+ 13, 0, WARN) \
SELECT(POLICY, CMP0080, \
"BundleUtilities cannot be included at configure time.", 3, 13, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0081, \
"Relative paths not allowed in LINK_DIRECTORIES target property.", \
- 3, 13, 0, cmPolicies::WARN) \
+ 3, 13, 0, WARN) \
SELECT(POLICY, CMP0082, \
"Install rules from add_subdirectory() are interleaved with those " \
"in caller.", \
- 3, 14, 0, cmPolicies::WARN) \
+ 3, 14, 0, WARN) \
SELECT(POLICY, CMP0083, "Add PIE options when linking executable.", 3, 14, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0084, \
"The FindQt module does not exist for find_package().", 3, 14, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0085, "$<IN_LIST:...> handles empty list items.", 3, 14, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0086, \
- "UseSWIG honors SWIG_MODULE_NAME via -module flag.", 3, 14, 0, \
- cmPolicies::WARN) \
+ "UseSWIG honors SWIG_MODULE_NAME via -module flag.", 3, 14, 0, WARN) \
SELECT(POLICY, CMP0087, \
"Install CODE|SCRIPT allow the use of generator " \
"expressions.", \
- 3, 14, 0, cmPolicies::WARN) \
+ 3, 14, 0, WARN) \
SELECT(POLICY, CMP0088, \
"FindBISON runs bison in CMAKE_CURRENT_BINARY_DIR when executing.", \
- 3, 14, 0, cmPolicies::WARN) \
+ 3, 14, 0, WARN) \
SELECT(POLICY, CMP0089, \
"Compiler id for IBM Clang-based XL compilers is now XLClang.", 3, \
- 15, 0, cmPolicies::WARN) \
+ 15, 0, WARN) \
SELECT(POLICY, CMP0090, \
"export(PACKAGE) does not populate package registry by default.", 3, \
- 15, 0, cmPolicies::WARN) \
+ 15, 0, WARN) \
SELECT(POLICY, CMP0091, \
"MSVC runtime library flags are selected by an abstraction.", 3, 15, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0092, \
"MSVC warning flags are not in CMAKE_<LANG>_FLAGS by default.", 3, \
- 15, 0, cmPolicies::WARN) \
+ 15, 0, WARN) \
SELECT(POLICY, CMP0093, "FindBoost reports Boost_VERSION in x.y.z format.", \
- 3, 15, 0, cmPolicies::WARN) \
+ 3, 15, 0, WARN) \
SELECT(POLICY, CMP0094, \
"FindPython3, FindPython2 and FindPyton use " \
"LOCATION for lookup strategy.", \
- 3, 15, 0, cmPolicies::WARN) \
+ 3, 15, 0, WARN) \
SELECT(POLICY, CMP0095, \
"RPATH entries are properly escaped in the intermediary CMake " \
"install script.", \
- 3, 16, 0, cmPolicies::WARN) \
+ 3, 16, 0, WARN) \
SELECT(POLICY, CMP0096, \
"project() preserves leading zeros in version components.", 3, 16, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0097, \
"ExternalProject_Add with GIT_SUBMODULES \"\" initializes no " \
"submodules.", \
- 3, 16, 0, cmPolicies::WARN) \
+ 3, 16, 0, WARN) \
SELECT(POLICY, CMP0098, \
"FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing.", 3, \
- 17, 0, cmPolicies::WARN) \
+ 17, 0, WARN) \
SELECT(POLICY, CMP0099, \
"Link properties are transitive over private dependencies of " \
"static libraries.", \
- 3, 17, 0, cmPolicies::WARN) \
+ 3, 17, 0, WARN) \
SELECT(POLICY, CMP0100, "Let AUTOMOC and AUTOUIC process .hh files.", 3, \
- 17, 0, cmPolicies::WARN) \
+ 17, 0, WARN) \
SELECT(POLICY, CMP0101, \
"target_compile_options honors BEFORE keyword in all scopes.", 3, \
- 17, 0, cmPolicies::WARN) \
+ 17, 0, WARN) \
SELECT(POLICY, CMP0102, \
"mark_as_advanced() does nothing if a cache entry does not exist.", \
- 3, 17, 0, cmPolicies::WARN) \
+ 3, 17, 0, WARN) \
SELECT(POLICY, CMP0103, \
"Multiple export() with same FILE without APPEND is not allowed.", \
- 3, 18, 0, cmPolicies::WARN) \
+ 3, 18, 0, WARN) \
SELECT(POLICY, CMP0104, \
"CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty " \
"CUDA_ARCHITECTURES not allowed.", \
- 3, 18, 0, cmPolicies::WARN) \
+ 3, 18, 0, WARN) \
SELECT(POLICY, CMP0105, "Device link step uses the link options.", 3, 18, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0106, "The Documentation module is removed.", 3, 18, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
- 3, 18, 0, cmPolicies::WARN) \
+ 3, 18, 0, WARN) \
SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
- 3, 18, 0, cmPolicies::WARN) \
+ 3, 18, 0, WARN) \
SELECT(POLICY, CMP0109, \
"find_program() requires permission to execute but not to read.", 3, \
- 19, 0, cmPolicies::WARN) \
+ 19, 0, WARN) \
SELECT(POLICY, CMP0110, \
"add_test() supports arbitrary characters in test names.", 3, 19, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0111, \
"An imported target missing its location property fails during " \
"generation.", \
- 3, 19, 0, cmPolicies::WARN) \
+ 3, 19, 0, WARN) \
SELECT(POLICY, CMP0112, \
"Target file component generator expressions do not add target " \
"dependencies.", \
- 3, 19, 0, cmPolicies::WARN) \
+ 3, 19, 0, WARN) \
SELECT(POLICY, CMP0113, \
"Makefile generators do not repeat custom commands from target " \
"dependencies.", \
- 3, 19, 0, cmPolicies::WARN) \
+ 3, 19, 0, WARN) \
SELECT(POLICY, CMP0114, \
"ExternalProject step targets fully adopt their steps.", 3, 19, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0115, "Source file extensions must be explicit.", 3, 20, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0116, \
"Ninja generators transform DEPFILEs from add_custom_command().", 3, \
- 20, 0, cmPolicies::WARN) \
+ 20, 0, WARN) \
SELECT(POLICY, CMP0117, \
"MSVC RTTI flag /GR is not added to CMAKE_CXX_FLAGS by default.", 3, \
- 20, 0, cmPolicies::WARN) \
+ 20, 0, WARN) \
SELECT(POLICY, CMP0118, \
"GENERATED sources may be used across directories without manual " \
"marking.", \
- 3, 20, 0, cmPolicies::WARN) \
+ 3, 20, 0, WARN) \
SELECT(POLICY, CMP0119, \
"LANGUAGE source file property explicitly compiles as specified " \
"language.", \
- 3, 20, 0, cmPolicies::WARN) \
+ 3, 20, 0, WARN) \
SELECT(POLICY, CMP0120, \
"The WriteCompilerDetectionHeader module is removed.", 3, 20, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0121, \
"The list() command now validates parsing of index arguments.", 3, \
- 21, 0, cmPolicies::WARN) \
+ 21, 0, WARN) \
SELECT( \
POLICY, CMP0122, \
"UseSWIG use standard library name conventions for csharp language.", 3, \
- 21, 0, cmPolicies::WARN) \
+ 21, 0, WARN) \
SELECT(POLICY, CMP0123, \
"ARMClang cpu/arch compile and link flags must be set explicitly.", \
- 3, 21, 0, cmPolicies::WARN) \
+ 3, 21, 0, WARN) \
SELECT(POLICY, CMP0124, \
"foreach() loop variables are only available in the loop scope.", 3, \
- 21, 0, cmPolicies::WARN) \
+ 21, 0, WARN) \
SELECT(POLICY, CMP0125, \
"find_(path|file|library|program) have consistent behavior for " \
"cache variables.", \
- 3, 21, 0, cmPolicies::WARN) \
+ 3, 21, 0, WARN) \
SELECT(POLICY, CMP0126, \
"set(CACHE) does not remove a normal variable of the same name.", 3, \
- 21, 0, cmPolicies::WARN) \
+ 21, 0, WARN) \
SELECT(POLICY, CMP0127, \
"cmake_dependent_option() supports full Condition Syntax.", 3, 22, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0128, \
"Selection of language standard and extension flags improved.", 3, \
- 22, 0, cmPolicies::WARN) \
+ 22, 0, WARN) \
SELECT(POLICY, CMP0129, \
"Compiler id for MCST LCC compilers is now LCC, not GNU.", 3, 23, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0130, "while() diagnoses condition evaluation errors.", \
- 3, 24, 0, cmPolicies::WARN) \
+ 3, 24, 0, WARN) \
SELECT(POLICY, CMP0131, \
"LINK_LIBRARIES supports the LINK_ONLY generator expression.", 3, \
- 24, 0, cmPolicies::WARN) \
+ 24, 0, WARN) \
SELECT(POLICY, CMP0132, \
"Do not set compiler environment variables on first run", 3, 24, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0133, \
"The CPack module disables SLA by default in the CPack DragNDrop " \
"Generator.", \
- 3, 24, 0, cmPolicies::WARN) \
+ 3, 24, 0, WARN) \
SELECT(POLICY, CMP0134, \
"Fallback to \"HOST\" Windows registry view when \"TARGET\" view " \
"is not usable.", \
- 3, 24, 0, cmPolicies::WARN) \
+ 3, 24, 0, WARN) \
SELECT(POLICY, CMP0135, \
"ExternalProject and FetchContent ignore timestamps in archives by " \
"default for the URL download method", \
- 3, 24, 0, cmPolicies::WARN) \
+ 3, 24, 0, WARN) \
SELECT(POLICY, CMP0136, \
"Watcom runtime library flags are selected by an abstraction.", 3, \
- 24, 0, cmPolicies::WARN) \
+ 24, 0, WARN) \
SELECT(POLICY, CMP0137, \
"try_compile() passes platform variables in project mode", 3, 24, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0138, \
"CheckIPOSupported uses flags from calling project.", 3, 24, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT( \
POLICY, CMP0139, \
"The if() command supports path comparisons using PATH_EQUAL operator.", \
- 3, 24, 0, cmPolicies::WARN) \
+ 3, 24, 0, WARN) \
SELECT(POLICY, CMP0140, "The return() command checks its arguments.", 3, \
- 25, 0, cmPolicies::WARN) \
+ 25, 0, WARN) \
SELECT( \
POLICY, CMP0141, \
"MSVC debug information format flags are selected by an abstraction.", 3, \
- 25, 0, cmPolicies::WARN) \
+ 25, 0, WARN) \
SELECT(POLICY, CMP0142, \
"The Xcode generator does not append per-config suffixes to " \
"library search paths.", \
- 3, 25, 0, cmPolicies::WARN) \
+ 3, 25, 0, WARN) \
SELECT(POLICY, CMP0143, \
"Global property USE_FOLDERS treated as ON by default", 3, 26, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0144, \
"find_package uses upper-case <PACKAGENAME>_ROOT variables.", 3, 27, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0145, "The Dart and FindDart modules are removed.", 3, \
- 27, 0, cmPolicies::WARN) \
- SELECT(POLICY, CMP0146, "The FindCUDA module is removed.", 3, 27, 0, \
- cmPolicies::WARN) \
+ 27, 0, WARN) \
+ SELECT(POLICY, CMP0146, "The FindCUDA module is removed.", 3, 27, 0, WARN) \
SELECT(POLICY, CMP0147, \
"Visual Studio generators build custom commands in parallel.", 3, \
- 27, 0, cmPolicies::WARN) \
+ 27, 0, WARN) \
SELECT(POLICY, CMP0148, \
"The FindPythonInterp and FindPythonLibs modules are removed.", 3, \
- 27, 0, cmPolicies::WARN) \
+ 27, 0, WARN) \
SELECT(POLICY, CMP0149, \
"Visual Studio generators select latest Windows SDK by default.", 3, \
- 27, 0, cmPolicies::WARN) \
+ 27, 0, WARN) \
SELECT(POLICY, CMP0150, \
"ExternalProject_Add and FetchContent_Declare commands " \
"treat relative GIT_REPOSITORY paths as being relative " \
"to the parent project's remote.", \
- 3, 27, 0, cmPolicies::WARN) \
+ 3, 27, 0, WARN) \
SELECT(POLICY, CMP0151, \
"AUTOMOC include directory is a system include directory by " \
"default.", \
- 3, 27, 0, cmPolicies::WARN) \
+ 3, 27, 0, WARN) \
SELECT( \
POLICY, CMP0152, \
"file(REAL_PATH) resolves symlinks before collapsing ../ components.", 3, \
- 28, 0, cmPolicies::WARN) \
+ 28, 0, WARN) \
SELECT(POLICY, CMP0153, "The exec_program command should not be called.", \
- 3, 28, 0, cmPolicies::WARN) \
+ 3, 28, 0, WARN) \
SELECT( \
POLICY, CMP0154, \
"Generated files are private by default in targets using file sets.", 3, \
- 28, 0, cmPolicies::WARN) \
+ 28, 0, WARN) \
SELECT(POLICY, CMP0155, \
"C++ sources in targets with at least C++20 are scanned for " \
"imports when supported.", \
- 3, 28, 0, cmPolicies::WARN) \
+ 3, 28, 0, WARN) \
SELECT( \
POLICY, CMP0156, \
"De-duplicate libraries on link lines based on linker capabilities.", 3, \
- 29, 0, cmPolicies::WARN) \
+ 29, 0, WARN) \
SELECT(POLICY, CMP0157, \
"Swift compilation mode selected by an abstraction.", 3, 29, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0158, \
"add_test() honors CMAKE_CROSSCOMPILING_EMULATOR only when " \
"cross-compiling.", \
- 3, 29, 0, cmPolicies::WARN) \
+ 3, 29, 0, WARN) \
SELECT(POLICY, CMP0159, \
- "file(STRINGS) with REGEX updates CMAKE_MATCH_<n>.", 3, 29, 0, \
- cmPolicies::WARN) \
+ "file(STRINGS) with REGEX updates CMAKE_MATCH_<n>.", 3, 29, 0, WARN) \
SELECT( \
POLICY, CMP0160, \
"More read-only target properties now error when trying to set them.", 3, \
- 29, 0, cmPolicies::WARN) \
+ 29, 0, WARN) \
SELECT(POLICY, CMP0161, "CPACK_PRODUCTBUILD_DOMAINS defaults to true.", 3, \
- 29, 0, cmPolicies::WARN) \
+ 29, 0, WARN) \
SELECT( \
POLICY, CMP0162, \
"Visual Studio generators add UseDebugLibraries indicators by default.", \
- 3, 30, 0, cmPolicies::WARN) \
+ 3, 30, 0, WARN) \
SELECT( \
POLICY, CMP0163, \
"The GENERATED source file property is now visible in all directories.", \
- 3, 30, 0, cmPolicies::WARN) \
+ 3, 30, 0, WARN) \
SELECT(POLICY, CMP0164, \
"add_library() rejects SHARED libraries when not supported by the " \
"platform.", \
- 3, 30, 0, cmPolicies::WARN) \
+ 3, 30, 0, WARN) \
SELECT(POLICY, CMP0165, \
"enable_language() must not be called before project().", 3, 30, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0166, \
"TARGET_PROPERTY evaluates link properties transitively over " \
"private dependencies of static libraries.", \
- 3, 30, 0, cmPolicies::WARN) \
- SELECT(POLICY, CMP0167, "The FindBoost module is removed.", 3, 30, 0, \
- cmPolicies::WARN) \
+ 3, 30, 0, WARN) \
+ SELECT(POLICY, CMP0167, "The FindBoost module is removed.", 3, 30, 0, WARN) \
SELECT(POLICY, CMP0168, \
"FetchContent implements steps directly instead of through a " \
"sub-build.", \
- 3, 30, 0, cmPolicies::WARN) \
+ 3, 30, 0, WARN) \
SELECT(POLICY, CMP0169, \
"FetchContent_Populate(depName) single-argument signature is " \
"deprecated.", \
- 3, 30, 0, cmPolicies::WARN) \
+ 3, 30, 0, WARN) \
SELECT(POLICY, CMP0170, \
"FETCHCONTENT_FULLY_DISCONNECTED requirements are enforced.", 3, 30, \
- 0, cmPolicies::WARN) \
+ 0, WARN) \
SELECT(POLICY, CMP0171, "'codegen' is a reserved target name.", 3, 31, 0, \
- cmPolicies::WARN) \
+ WARN) \
SELECT(POLICY, CMP0172, \
"The CPack module enables per-machine installation by default in " \
"the CPack WIX Generator.", \
- 3, 31, 0, cmPolicies::WARN) \
+ 3, 31, 0, WARN) \
SELECT(POLICY, CMP0173, "The CMakeFindFrameworks module is removed.", 3, \
- 31, 0, cmPolicies::WARN) \
+ 31, 0, WARN) \
SELECT(POLICY, CMP0174, \
"cmake_parse_arguments(PARSE_ARGV) defines a variable for an empty " \
"string after a single-value keyword.", \
- 3, 31, 0, cmPolicies::WARN) \
+ 3, 31, 0, WARN) \
SELECT(POLICY, CMP0175, "add_custom_command() rejects invalid arguments.", \
- 3, 31, 0, cmPolicies::WARN) \
+ 3, 31, 0, WARN) \
SELECT(POLICY, CMP0176, "execute_process() ENCODING is UTF-8 by default.", \
- 3, 31, 0, cmPolicies::WARN) \
+ 3, 31, 0, WARN) \
SELECT(POLICY, CMP0177, "install() DESTINATION paths are normalized.", 3, \
- 31, 0, cmPolicies::WARN) \
+ 31, 0, WARN) \
SELECT(POLICY, CMP0178, "Test command lines preserve empty arguments.", 3, \
- 31, 0, cmPolicies::WARN) \
+ 31, 0, WARN) \
SELECT(POLICY, CMP0179, \
"De-duplication of static libraries on link lines keeps first " \
"occurrence.", \
- 3, 31, 0, cmPolicies::WARN) \
+ 3, 31, 0, WARN) \
SELECT(POLICY, CMP0180, \
"project() always sets <PROJECT-NAME>_* as normal variables.", 3, \
- 31, 0, cmPolicies::WARN)
+ 31, 0, WARN) \
+ SELECT(POLICY, CMP0181, \
+ "Link command-line fragment variables are parsed and re-quoted.", 3, \
+ 32, 0, WARN) \
+ SELECT(POLICY, CMP0182, \
+ "Create shared library archives by default on AIX.", 3, 32, 0, WARN) \
+ SELECT(POLICY, CMP0183, \
+ "add_feature_info() supports full Condition Syntax.", 3, 32, 0, \
+ WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -597,7 +598,9 @@
F(CMP0157) \
F(CMP0160) \
F(CMP0162) \
- F(CMP0179)
+ F(CMP0179) \
+ F(CMP0181) \
+ F(CMP0182)
#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
F(CMP0116) \
@@ -617,10 +620,6 @@
OLD, ///< Use old behavior
WARN, ///< Use old behavior but issue a warning
NEW, ///< Use new behavior
- /// Issue an error if user doesn't set policy status to NEW and hits the
- /// check
- REQUIRED_IF_USED,
- REQUIRED_ALWAYS ///< Issue an error unless user sets policy status to NEW.
};
/// Policy identifiers
@@ -641,8 +640,8 @@
//! convert a string policy ID into a number
static bool GetPolicyID(const char* id, /* out */ cmPolicies::PolicyID& pid);
- //! Get the default status for a policy
- static cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
+ //! Return whether a policy has been removed.
+ static bool IsRemoved(cmPolicies::PolicyID id);
enum class WarnCompat
{
@@ -664,10 +663,7 @@
static std::string GetPolicyDeprecatedWarning(cmPolicies::PolicyID id);
//! return an error string for when a required policy is unspecified
- static std::string GetRequiredPolicyError(cmPolicies::PolicyID id);
-
- //! return an error string for when a required policy is unspecified
- static std::string GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id);
+ static std::string GetRemovedPolicyError(cmPolicies::PolicyID id);
/** Represent a set of policy values. */
struct PolicyMap
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 1fd406c..d04f72b 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -360,11 +360,11 @@
if (genVars.ExecutableTarget) {
dependencies.push_back(genVars.ExecutableTarget->Target->GetName());
} else if (this->MultiConfig && this->UseBetterGraph) {
- cm::string_view const& configGenexWithCommandConfig =
+ cm::string_view const configGenexWithCommandConfig =
"$<COMMAND_CONFIG:$<$<CONFIG:";
- cm::string_view const& configGenex = "$<$<CONFIG:";
- cm::string_view const& configGenexEnd = ">";
- cm::string_view const& configGenexEndWithCommandConfig = ">>";
+ cm::string_view const configGenex = "$<$<CONFIG:";
+ cm::string_view const configGenexEnd = ">";
+ cm::string_view const configGenexEndWithCommandConfig = ">>";
auto genexBegin =
this->CrossConfig ? configGenexWithCommandConfig : configGenex;
auto genexEnd =
@@ -433,8 +433,6 @@
case cmPolicies::OLD:
// Ignore GENERATED files
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Process GENERATED files
this->CMP0071Accept = true;
@@ -450,8 +448,6 @@
case cmPolicies::OLD:
// Ignore .hh files
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Process .hh file
this->CMP0100Accept = true;
@@ -669,8 +665,6 @@
case cmPolicies::OLD:
addBefore = true;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
this->GenTarget->AddSystemIncludeDirectory(this->Dir.IncludeGenExp,
"CXX");
@@ -1340,12 +1334,25 @@
}
if (this->Uic.Enabled) {
- // Make all ui_*.h files byproducts of the ${target}_autogen/timestamp
- // custom command if the generation of depfile is enabled.
- auto& byProducts = useDepfile ? timestampByproducts : autogenByproducts;
- for (auto const& file : this->Uic.UiHeaders) {
- this->AddGeneratedSource(file.first, this->Uic);
- byProducts.push_back(file.second);
+ auto const useAdvancedUicGraph = [this]() -> bool {
+ if (this->MultiConfig && this->GlobalGen->IsNinja()) {
+ return this->UseBetterGraph;
+ }
+ return true;
+ }();
+ if (useAdvancedUicGraph) {
+ // Make all ui_*.h files byproducts of the ${target}_autogen/timestamp
+ // custom command if the generation of depfile is enabled.
+ auto& byProducts = useDepfile ? timestampByproducts : autogenByproducts;
+ for (auto const& file : this->Uic.UiHeaders) {
+ this->AddGeneratedSource(file.first, this->Uic);
+ byProducts.push_back(file.second);
+ }
+ } else {
+ for (auto const& file : this->Uic.UiHeaders) {
+ this->AddGeneratedSource(file.first, this->Uic);
+ autogenByproducts.push_back(file.second);
+ }
}
}
@@ -1483,16 +1490,6 @@
}
}
- // For the Ninja, Makefile and Qt >= 5.15, add custom commands that create
- // XXX_autogen/timestamp files. Those custom commands have a depfile
- // assigned that is generated from the depfiles that were created by moc.
- //
- // The XXX_autogen targets merely wrap the XXX_autogen/timestamp custom
- // commands.
- // The dependency tree would then look like
- // the original dependencies of '_autogen' target <-'/timestamp' file
- // <- '_autogen' target
-
cmTarget* timestampTarget = nullptr;
std::vector<std::string> dependencies(
this->AutogenTarget.DependFiles.begin(),
@@ -1500,6 +1497,40 @@
if (useDepfile) {
// Create a custom command that generates a timestamp file and
// has a depfile assigned. The depfile is created by JobDepFilesMergeT.
+ //
+ // Also create an additional '_autogen_timestamp_deps' that the custom
+ // command will depend on. It will have no sources or commands to
+ // execute, but it will have dependencies that would originally be
+ // assigned to the pre-Qt 5.15 'autogen' target. These dependencies will
+ // serve as a list of order-only dependencies for the custom command,
+ // without forcing the custom command to re-execute.
+ //
+ // The dependency tree would then look like
+ // '_autogen_timestamp_deps (order-only)' <- '/timestamp' file <-
+ // '_autogen' target.
+ const auto timestampTargetName =
+ cmStrCat(this->GenTarget->GetName(), "_autogen_timestamp_deps");
+
+ auto cc = cm::make_unique<cmCustomCommand>();
+ cc->SetWorkingDirectory(this->Dir.Work.c_str());
+ cc->SetDepends(dependencies);
+ cc->SetEscapeOldStyle(false);
+ timestampTarget = this->LocalGen->AddUtilityCommand(timestampTargetName,
+ true, std::move(cc));
+
+ this->LocalGen->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(timestampTarget, this->LocalGen));
+
+ // Set FOLDER property on the timestamp target, so it appears in the
+ // appropriate folder in an IDE or in the file api.
+ if (!this->TargetsFolder.empty()) {
+ timestampTarget->SetProperty("FOLDER", this->TargetsFolder);
+ }
+
+ // Make '/timestamp' file depend on '_autogen_timestamp_deps' and on the
+ // moc and uic executables (whichever are enabled).
+ dependencies.clear();
+ dependencies.push_back(timestampTargetName);
AddAutogenExecutableToDependencies(this->Moc, dependencies);
AddAutogenExecutableToDependencies(this->Uic, dependencies);
@@ -1544,7 +1575,7 @@
{ cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
this->AddGeneratedSource(outputFile, this->Moc);
}
- auto cc = cm::make_unique<cmCustomCommand>();
+ cc = cm::make_unique<cmCustomCommand>();
cc->SetOutputs(outputFile);
cc->SetByproducts(timestampByproducts);
cc->SetDepends(dependencies);
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 376ac2a..cbd5949 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -439,7 +439,6 @@
// Info file
this->InfoFile_ = std::string(infoFile);
- cmSystemTools::CollapseFullPath(this->InfoFile_);
this->InfoDir_ = cmSystemTools::GetFilenamePath(this->InfoFile_);
// Load info file time
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 251ef3a..8bedc11 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -7,7 +7,6 @@
#include <cstddef>
#include <limits>
#include <map>
-#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
@@ -561,7 +560,6 @@
std::string AbsoluteIncludePath(cm::string_view relativePath) const;
template <class JOBTYPE>
void CreateParseJobs(SourceFileMapT const& sourceMap);
- std::string CollapseFullPathTS(std::string const& path) const;
private:
// -- Abstract processing interface
@@ -595,8 +593,6 @@
// -- Worker thread pool
std::atomic<bool> JobError_{ false };
cmWorkerPool WorkerPool_;
- // -- Concurrent processing
- mutable std::mutex CMakeLibMutex_;
};
cmQtAutoMocUicT::IncludeKeyT::IncludeKeyT(std::string const& key,
@@ -1494,8 +1490,9 @@
&headerHandle](std::string const& basePath) -> bool {
bool found = false;
for (std::string const& ext : this->BaseConst().HeaderExtensions) {
- std::string const testPath =
- this->Gen()->CollapseFullPathTS(cmStrCat(basePath, '.', ext));
+ std::string const testPath = cmSystemTools::CollapseFullPath(
+ cmStrCat(basePath, '.', ext),
+ this->Gen()->ProjectDirs().CurrentSource);
cmFileTime fileTime;
if (!fileTime.Load(testPath)) {
// File not found
@@ -1682,7 +1679,8 @@
this->SearchLocations.clear();
auto findUi = [this](std::string const& testPath) -> bool {
- std::string const fullPath = this->Gen()->CollapseFullPathTS(testPath);
+ std::string const fullPath = cmSystemTools::CollapseFullPath(
+ testPath, this->Gen()->ProjectDirs().CurrentSource);
cmFileTime fileTime;
if (!fileTime.Load(fullPath)) {
this->SearchLocations.emplace_back(cmQtAutoGen::ParentDir(fullPath));
@@ -2885,17 +2883,6 @@
}
}
-/** Concurrently callable implementation of cmSystemTools::CollapseFullPath */
-std::string cmQtAutoMocUicT::CollapseFullPathTS(std::string const& path) const
-{
- std::lock_guard<std::mutex> guard(this->CMakeLibMutex_);
-#if defined(__NVCOMPILER) || defined(__LCC__)
- static_cast<void>(guard); // convince compiler var is used
-#endif
- return cmSystemTools::CollapseFullPath(path,
- this->ProjectDirs().CurrentSource);
-}
-
void cmQtAutoMocUicT::InitJobs()
{
// Add moc_predefs.h job
@@ -3130,10 +3117,6 @@
std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
const char* filePath)
{
- std::lock_guard<std::mutex> guard(this->CMakeLibMutex_);
-#if defined(__NVCOMPILER) || defined(__LCC__)
- static_cast<void>(guard); // convince compiler var is used
-#endif
auto const content = cmReadGccDepfile(filePath);
if (!content || content->empty()) {
return {};
diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx
index 765b772..79caf8c 100644
--- a/Source/cmReturnCommand.cxx
+++ b/Source/cmReturnCommand.cxx
@@ -29,13 +29,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
return true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- status.GetMakefile().IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat('\n', cmPolicies::GetPolicyWarning(cmPolicies::CMP0140)));
- cmSystemTools::SetFatalErrorOccurred();
- return false;
default:
break;
}
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index a8c81d0..a2435a3 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -9,10 +9,11 @@
#include "cmSystemTools.h"
cmRulePlaceholderExpander::cmRulePlaceholderExpander(
- std::map<std::string, std::string> compilers,
+ cmBuildStep buildStep, std::map<std::string, std::string> compilers,
std::map<std::string, std::string> variableMappings,
std::string compilerSysroot, std::string linkerSysroot)
- : Compilers(std::move(compilers))
+ : BuildStep(buildStep)
+ , Compilers(std::move(compilers))
, VariableMappings(std::move(variableMappings))
, CompilerSysroot(std::move(compilerSysroot))
, LinkerSysroot(std::move(linkerSysroot))
@@ -320,9 +321,8 @@
}
std::string sysroot;
// Some platforms may use separate sysroots for compiling and linking.
- // If we detect link flags, then we pass the link sysroot instead.
- // FIXME: Use a more robust way to detect link line expansion.
- if (this->ReplaceValues->LinkFlags) {
+ // When the build step is link, pass the link sysroot instead.
+ if (this->BuildStep == cmBuildStep::Link) {
sysroot = this->LinkerSysroot;
} else {
sysroot = this->CompilerSysroot;
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 225abd4..4858b08 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -8,6 +8,7 @@
#include <map>
#include <string>
+#include "cmGeneratorOptions.h"
#include "cmPlaceholderExpander.h"
class cmOutputConverter;
@@ -16,7 +17,7 @@
{
public:
cmRulePlaceholderExpander(
- std::map<std::string, std::string> compilers,
+ cmBuildStep buildStep, std::map<std::string, std::string> compilers,
std::map<std::string, std::string> variableMappings,
std::string compilerSysroot, std::string linkerSysroot);
@@ -84,6 +85,7 @@
std::string TargetImpLib;
+ cmBuildStep BuildStep = cmBuildStep::Compile;
std::map<std::string, std::string> Compilers;
std::map<std::string, std::string> VariableMappings;
std::string CompilerSysroot;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index ec70c05..6784ef2 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -25,15 +25,11 @@
void cmSearchPath::ExtractWithout(const std::set<std::string>& ignorePaths,
const std::set<std::string>& ignorePrefixes,
- std::vector<std::string>& outPaths,
- bool clear) const
+ std::vector<std::string>& outPaths) const
{
- if (clear) {
- outPaths.clear();
- }
for (auto const& path : this->Paths) {
- if (ignorePaths.count(path.Path) == 0 &&
- ignorePrefixes.count(path.Prefix) == 0) {
+ if (ignorePaths.find(path.Path) == ignorePaths.end() &&
+ ignorePrefixes.find(path.Prefix) == ignorePrefixes.end()) {
outPaths.push_back(path.Path);
}
}
@@ -62,7 +58,9 @@
// Process them all from the current directory
for (std::string const& p : outPaths) {
this->AddPathInternal(
- p, "", this->FC->Makefile->GetCurrentSourceDirectory().c_str());
+ cmSystemTools::CollapseFullPath(
+ p, this->FC->Makefile->GetCurrentSourceDirectory()),
+ "");
}
}
@@ -76,15 +74,17 @@
for (std::string const& p : expanded) {
this->AddPathInternal(
- p, "", this->FC->Makefile->GetCurrentSourceDirectory().c_str());
+ cmSystemTools::CollapseFullPath(
+ p, this->FC->Makefile->GetCurrentSourceDirectory()),
+ "");
}
}
}
void cmSearchPath::AddEnvPath(const std::string& variable)
{
- std::vector<std::string> expanded;
- cmSystemTools::GetPath(expanded, variable.c_str());
+ std::vector<std::string> expanded =
+ cmSystemTools::GetEnvPathNormalized(variable);
for (std::string const& p : expanded) {
this->AddPathInternal(p, "");
}
@@ -97,9 +97,11 @@
// Get a path from a CMake variable.
if (cmValue value = this->FC->Makefile->GetDefinition(variable)) {
cmList expanded{ *value };
-
- this->AddPrefixPaths(
- expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str());
+ for (std::string& p : expanded) {
+ p = cmSystemTools::CollapseFullPath(
+ p, this->FC->Makefile->GetCurrentSourceDirectory());
+ }
+ this->AddPrefixPaths(expanded);
}
}
@@ -114,8 +116,8 @@
void cmSearchPath::AddEnvPrefixPath(const std::string& variable, bool stripBin)
{
- std::vector<std::string> expanded;
- cmSystemTools::GetPath(expanded, variable.c_str());
+ std::vector<std::string> expanded =
+ cmSystemTools::GetEnvPathNormalized(variable);
if (stripBin) {
std::transform(expanded.begin(), expanded.end(), expanded.begin(),
cmSearchPathStripBin);
@@ -138,21 +140,20 @@
// path on windows and cause huge delays.
std::string p = inPath.Path;
if (!p.empty() && p.back() != '/') {
- p += "/";
+ p += '/';
}
// Combine with all the suffixes
for (std::string const& suffix : suffixes) {
- this->Paths.push_back(PathWithPrefix{ p + suffix, inPath.Prefix });
+ this->Paths.emplace_back(PathWithPrefix{ p + suffix, inPath.Prefix });
}
// And now the original w/o any suffix
- this->Paths.push_back(std::move(inPath));
+ this->Paths.emplace_back(std::move(inPath));
}
}
-void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
- const char* base)
+void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths)
{
assert(this->FC);
@@ -192,52 +193,43 @@
"CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
if (foundUnknown) {
this->AddPathInternal(cmStrCat('/', archNoUnknown, dir, subdir),
- cmStrCat('/', archNoUnknown, prefix), base);
+ cmStrCat('/', archNoUnknown, prefix));
}
this->AddPathInternal(cmStrCat('/', *arch, dir, subdir),
- cmStrCat('/', *arch, prefix), base);
+ cmStrCat('/', *arch, prefix));
} else {
if (foundUnknown) {
this->AddPathInternal(cmStrCat(dir, subdir, '/', archNoUnknown),
- prefix, base);
+ prefix);
}
- this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix,
- base);
+ this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix);
}
}
}
std::string add = dir + subdir;
if (add != "/") {
- this->AddPathInternal(add, prefix, base);
+ this->AddPathInternal(add, prefix);
}
if (subdir == "bin") {
- this->AddPathInternal(dir + "sbin", prefix, base);
+ this->AddPathInternal(dir + "sbin", prefix);
}
if (!subdir.empty() && path != "/") {
- this->AddPathInternal(path, prefix, base);
+ this->AddPathInternal(path, prefix);
}
}
}
void cmSearchPath::AddPathInternal(const std::string& path,
- const std::string& prefix, const char* base)
+ const std::string& prefix)
{
assert(this->FC);
- std::string collapsedPath = cmSystemTools::CollapseFullPath(path, base);
-
- if (collapsedPath.empty()) {
+ if (path.empty()) {
return;
}
- std::string collapsedPrefix;
- if (!prefix.empty()) {
- collapsedPrefix = cmSystemTools::CollapseFullPath(prefix, base);
- }
-
// Insert the path if has not already been emitted.
- PathWithPrefix pathWithPrefix{ std::move(collapsedPath),
- std::move(collapsedPrefix) };
+ PathWithPrefix pathWithPrefix{ path, prefix };
if (this->FC->SearchPathsEmitted.insert(pathWithPrefix).second) {
this->Paths.emplace_back(std::move(pathWithPrefix));
}
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
index 4c0cabb..16d11c4 100644
--- a/Source/cmSearchPath.h
+++ b/Source/cmSearchPath.h
@@ -45,8 +45,7 @@
void ExtractWithout(const std::set<std::string>& ignorePaths,
const std::set<std::string>& ignorePrefixes,
- std::vector<std::string>& outPaths,
- bool clear = false) const;
+ std::vector<std::string>& outPaths) const;
void AddPath(const std::string& path);
void AddUserPath(const std::string& path);
@@ -55,12 +54,10 @@
void AddCMakePrefixPath(const std::string& variable);
void AddEnvPrefixPath(const std::string& variable, bool stripBin = false);
void AddSuffixes(const std::vector<std::string>& suffixes);
- void AddPrefixPaths(const std::vector<std::string>& paths,
- const char* base = nullptr);
+ void AddPrefixPaths(const std::vector<std::string>& paths);
protected:
- void AddPathInternal(const std::string& path, const std::string& prefix,
- const char* base = nullptr);
+ void AddPathInternal(const std::string& path, const std::string& prefix);
cmFindCommon* FC;
std::vector<PathWithPrefix> Paths;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 5443c47..a4c381c 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -226,8 +226,6 @@
err = cmStrCat(err, " .", ext);
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
break;
}
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index bb92856..31f541e 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -29,11 +29,6 @@
const std::string kRegexOptionName = "REGULAR_EXPRESSION";
const std::string kSourceGroupOptionName = "<sg_name>";
-std::vector<std::string> tokenizePath(const std::string& path)
-{
- return cmTokenize(path, "\\/");
-}
-
std::set<std::string> getSourceGroupFilesPaths(
const std::string& root, const std::vector<std::string>& files)
{
@@ -95,31 +90,28 @@
cmSourceGroup* sg;
for (std::string const& sgFilesPath : sgFilesPaths) {
+ std::vector<std::string> tokenizedPath = cmTokenize(
+ prefix.empty() ? sgFilesPath : cmStrCat(prefix, '/', sgFilesPath),
+ R"(\/)", cmTokenizerMode::New);
- std::vector<std::string> tokenizedPath;
- if (!prefix.empty()) {
- tokenizedPath = tokenizePath(cmStrCat(prefix, '/', sgFilesPath));
- } else {
- tokenizedPath = tokenizePath(sgFilesPath);
+ if (tokenizedPath.empty()) {
+ continue;
+ }
+ tokenizedPath.pop_back();
+
+ if (tokenizedPath.empty()) {
+ tokenizedPath.emplace_back();
}
- if (!tokenizedPath.empty()) {
- tokenizedPath.pop_back();
+ sg = makefile.GetOrCreateSourceGroup(tokenizedPath);
- if (tokenizedPath.empty()) {
- tokenizedPath.emplace_back();
- }
-
- sg = makefile.GetOrCreateSourceGroup(tokenizedPath);
-
- if (!sg) {
- errorMsg = "Could not create source group for file: " + sgFilesPath;
- return false;
- }
- const std::string fullPath =
- cmSystemTools::CollapseFullPath(sgFilesPath, root);
- sg->AddGroupFile(fullPath);
+ if (!sg) {
+ errorMsg = "Could not create source group for file: " + sgFilesPath;
+ return false;
}
+ const std::string fullPath =
+ cmSystemTools::CollapseFullPath(sgFilesPath, root);
+ sg->AddGroupFile(fullPath);
}
return true;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index b716dc7..31dba0e 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -13,7 +13,6 @@
#include "cmsys/RegularExpression.hxx"
#include "cmCacheManager.h"
-#include "cmCommand.h"
#include "cmDefinitions.h"
#include "cmExecutionStatus.h"
#include "cmGlobCacheEntry.h"
@@ -397,12 +396,6 @@
this->IsGeneratorMultiConfig = b;
}
-void cmState::AddBuiltinCommand(std::string const& name,
- std::unique_ptr<cmCommand> command)
-{
- this->AddBuiltinCommand(name, cmLegacyCommandWrapper(std::move(command)));
-}
-
void cmState::AddBuiltinCommand(std::string const& name, Command command)
{
assert(name == cmSystemTools::LowerCase(name));
@@ -471,8 +464,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
mf.IssueMessage(MessageType::FATAL_ERROR, message);
return true;
diff --git a/Source/cmState.h b/Source/cmState.h
index 4dc982f..6239511 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -27,7 +27,6 @@
#include "cmValue.h"
class cmCacheManager;
-class cmCommand;
class cmGlobVerificationManager;
class cmMakefile;
class cmStateSnapshot;
@@ -177,8 +176,6 @@
// Returns a command from its name, or nullptr
Command GetCommandByExactName(std::string const& name) const;
- void AddBuiltinCommand(std::string const& name,
- std::unique_ptr<cmCommand> command);
void AddBuiltinCommand(std::string const& name, Command command);
void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
void AddFlowControlCommand(std::string const& name, Command command);
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 343bee5..104e707 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -21,7 +21,6 @@
#include "cmState.h"
#include "cmStatePrivate.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
#include "cmValue.h"
static std::string const kBINARY_DIR = "BINARY_DIR";
@@ -36,11 +35,9 @@
void cmStateDirectory::SetCurrentSource(std::string const& dir)
{
- std::string& loc = this->DirectoryState->Location;
- loc = dir;
- cmSystemTools::ConvertToUnixSlashes(loc);
- loc = cmSystemTools::CollapseFullPath(loc);
- this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
+ this->DirectoryState->Location = dir;
+ this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR",
+ this->DirectoryState->Location);
}
std::string const& cmStateDirectory::GetCurrentBinary() const
@@ -50,11 +47,9 @@
void cmStateDirectory::SetCurrentBinary(std::string const& dir)
{
- std::string& loc = this->DirectoryState->OutputLocation;
- loc = dir;
- cmSystemTools::ConvertToUnixSlashes(loc);
- loc = cmSystemTools::CollapseFullPath(loc);
- this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
+ this->DirectoryState->OutputLocation = dir;
+ this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR",
+ this->DirectoryState->OutputLocation);
}
cmStateDirectory::cmStateDirectory(
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 6ee0225..1485992 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -165,13 +165,12 @@
cmPolicies::PolicyStatus cmStateSnapshot::GetPolicy(cmPolicies::PolicyID id,
bool parent_scope) const
{
- cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
-
- if (status == cmPolicies::REQUIRED_ALWAYS ||
- status == cmPolicies::REQUIRED_IF_USED) {
- return status;
+ if (cmPolicies::IsRemoved(id)) {
+ return cmPolicies::NEW;
}
+ cmPolicies::PolicyStatus status = cmPolicies::WARN;
+
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator dir =
this->Position->BuildSystemDirectory;
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index 332bd8d..724ca75 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -55,30 +55,6 @@
return result;
}
-std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
-{
- std::vector<std::string> tokens;
- cm::string_view::size_type tokend = 0;
-
- do {
- cm::string_view::size_type tokstart = str.find_first_not_of(sep, tokend);
- if (tokstart == cm::string_view::npos) {
- break; // no more tokens
- }
- tokend = str.find_first_of(sep, tokstart);
- if (tokend == cm::string_view::npos) {
- tokens.emplace_back(str.substr(tokstart));
- } else {
- tokens.emplace_back(str.substr(tokstart, tokend - tokstart));
- }
- } while (tokend != cm::string_view::npos);
-
- if (tokens.empty()) {
- tokens.emplace_back();
- }
- return tokens;
-}
-
namespace {
template <std::size_t N, typename T>
inline void MakeDigits(cm::string_view& view, char (&digits)[N],
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 2bd615a..72557d5 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -24,7 +24,7 @@
/** Returns length of a literal string. */
template <size_t N>
-constexpr size_t cmStrLen(const char (&/*str*/)[N])
+constexpr size_t cmStrLen(const char (&)[N])
{
return N - 1;
}
@@ -91,12 +91,12 @@
}
std::string result;
- result.reserve(
- std::accumulate(std::begin(rng), std::end(rng),
- initial.size() + (rng.size() - 1) * separator.size(),
- [](std::size_t sum, const std::string& item) {
- return sum + item.size();
- }));
+ result.reserve(std::accumulate(
+ std::begin(rng), std::end(rng),
+ initial.size() + (rng.size() - 1) * separator.size(),
+ [](std::size_t sum, typename Range::value_type const& item) {
+ return sum + item.size();
+ }));
result.append(std::begin(initial), std::end(initial));
auto begin = std::begin(rng);
@@ -122,8 +122,81 @@
std::string cmJoin(cmStringRange const& rng, cm::string_view separator,
cm::string_view initial = {});
-/** Extract tokens that are separated by any of the characters in @a sep. */
-std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
+enum class cmTokenizerMode
+{
+ /// A backward-compatible behavior when in the case of no
+ /// tokens have found in an input text it'll return one empty
+ /// token in the result container (vector).
+ Legacy,
+ /// The new behavior is to return an empty vector.
+ New
+};
+
+/**
+ * \brief A generic version of a tokenizer.
+ *
+ * Extract tokens from the input string separated by any
+ * of the characters in `sep` and assign them to the
+ * given output iterator.
+ *
+ * The `mode` parameter defines the behavior in the case when
+ * no tokens have found in the input text.
+ *
+ */
+template <typename StringT, typename OutIt, typename Sep = char>
+void cmTokenize(OutIt outIt, cm::string_view str, Sep sep,
+ cmTokenizerMode mode)
+{
+ auto hasTokens = false;
+ // clang-format off
+ for (auto start = str.find_first_not_of(sep)
+ , end = str.find_first_of(sep, start)
+ ; start != cm::string_view::npos
+ ; start = str.find_first_not_of(sep, end)
+ , end = str.find_first_of(sep, start)
+ , hasTokens = true
+ ) {
+ *outIt++ = StringT{ str.substr(start, end - start) };
+ }
+ // clang-format on
+ if (!hasTokens && mode == cmTokenizerMode::Legacy) {
+ *outIt = {};
+ }
+}
+
+/**
+ * \brief Extract tokens that are separated by any of the
+ * characters in `sep`.
+ *
+ * Backward compatible signature.
+ *
+ * \return A vector of strings.
+ */
+template <typename Sep = char>
+std::vector<std::string> cmTokenize(
+ cm::string_view str, Sep sep, cmTokenizerMode mode = cmTokenizerMode::Legacy)
+{
+ using StringType = std::string;
+ std::vector<StringType> tokens;
+ cmTokenize<StringType>(std::back_inserter(tokens), str, sep, mode);
+ return tokens;
+}
+
+/**
+ * \brief Extract tokens that are separated by any of the
+ * characters in `sep`.
+ *
+ * \return A vector of string views.
+ */
+template <typename Sep = char>
+std::vector<cm::string_view> cmTokenizedView(
+ cm::string_view str, Sep sep, cmTokenizerMode mode = cmTokenizerMode::Legacy)
+{
+ using StringType = cm::string_view;
+ std::vector<StringType> tokens;
+ cmTokenize<StringType>(std::back_inserter(tokens), str, sep, mode);
+ return tokens;
+}
/** Concatenate string pieces into a single string. */
std::string cmCatViews(
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 5ad0439..cdb661c 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -20,6 +20,12 @@
#include "cmSystemTools.h"
+#include <iterator>
+
+#ifdef _WIN32
+# include <unordered_map>
+#endif
+
#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -29,6 +35,7 @@
#include "cmDuration.h"
#include "cmELF.h"
#include "cmMessageMetadata.h"
+#include "cmPathResolver.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -126,6 +133,116 @@
cmSystemTools::OutputCallback s_StderrCallback;
cmSystemTools::OutputCallback s_StdoutCallback;
+#ifdef _WIN32
+std::string GetDosDriveWorkingDirectory(char letter)
+{
+ // The Windows command processor tracks a per-drive working
+ // directory for compatibility with MS-DOS by using special
+ // environment variables named "=C:".
+ // https://web.archive.org/web/20100522040616/
+ // https://blogs.msdn.com/oldnewthing/archive/2010/05/06/10008132.aspx
+ return cmSystemTools::GetEnvVar(cmStrCat('=', letter, ':'))
+ .value_or(std::string());
+}
+
+cmsys::Status ReadNameOnDisk(std::string const& path, std::string& name)
+{
+ std::wstring wp = cmsys::Encoding::ToWide(path);
+ HANDLE h = CreateFileW(
+ wp.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
+ if (h == INVALID_HANDLE_VALUE) {
+ return cmsys::Status::Windows_GetLastError();
+ }
+
+ WCHAR local_fni[((sizeof(FILE_NAME_INFO) - 1) / sizeof(WCHAR)) + 1024];
+ size_t fni_size = sizeof(local_fni);
+ auto* fni = reinterpret_cast<FILE_NAME_INFO*>(local_fni);
+ if (!GetFileInformationByHandleEx(h, FileNameInfo, fni, fni_size)) {
+ DWORD e = GetLastError();
+ if (e != ERROR_MORE_DATA) {
+ CloseHandle(h);
+ return cmsys::Status::Windows(e);
+ }
+ fni_size = fni->FileNameLength;
+ fni = static_cast<FILE_NAME_INFO*>(malloc(fni_size));
+ if (!fni) {
+ e = ERROR_NOT_ENOUGH_MEMORY;
+ CloseHandle(h);
+ return cmsys::Status::Windows(e);
+ }
+ if (!GetFileInformationByHandleEx(h, FileNameInfo, fni, fni_size)) {
+ e = GetLastError();
+ free(fni);
+ CloseHandle(h);
+ return cmsys::Status::Windows(e);
+ }
+ }
+
+ std::wstring wn{ fni->FileName, fni->FileNameLength / sizeof(WCHAR) };
+ std::string nn = cmsys::Encoding::ToNarrow(wn);
+ std::string::size_type last_slash = nn.find_last_of("/\\");
+ if (last_slash != std::string::npos) {
+ name = nn.substr(last_slash + 1);
+ }
+ if (fni != reinterpret_cast<FILE_NAME_INFO*>(local_fni)) {
+ free(fni);
+ }
+ CloseHandle(h);
+ return cmsys::Status::Success();
+}
+#endif
+
+class RealSystem : public cm::PathResolver::System
+{
+public:
+ ~RealSystem() override = default;
+ cmsys::Status ReadSymlink(std::string const& path,
+ std::string& link) override
+ {
+ return cmSystemTools::ReadSymlink(path, link);
+ }
+ bool PathExists(std::string const& path) override
+ {
+ return cmSystemTools::PathExists(path);
+ }
+ std::string GetWorkingDirectory() override
+ {
+ return cmSystemTools::GetLogicalWorkingDirectory();
+ }
+#ifdef _WIN32
+ std::string GetWorkingDirectoryOnDrive(char letter) override
+ {
+ return GetDosDriveWorkingDirectory(letter);
+ }
+
+ struct NameOnDisk
+ {
+ cmsys::Status Status;
+ std::string Name;
+ };
+ using NameOnDiskMap = std::unordered_map<std::string, NameOnDisk>;
+ NameOnDiskMap CachedNameOnDisk;
+
+ cmsys::Status ReadName(std::string const& path, std::string& name) override
+ {
+ // Cache results to avoid repeated filesystem access.
+ // We assume any files created by our own process keep their case.
+ // Index the cache by lower-case paths to make it case-insensitive.
+ std::string path_lower = cmSystemTools::LowerCase(path);
+ auto i = this->CachedNameOnDisk.find(path_lower);
+ if (i == this->CachedNameOnDisk.end()) {
+ i = this->CachedNameOnDisk.emplace(path_lower, NameOnDisk()).first;
+ i->second.Status = ReadNameOnDisk(path, i->second.Name);
+ }
+ name = i->second.Name;
+ return i->second.Status;
+ }
+#endif
+};
+
+RealSystem RealOS;
+
} // namespace
#if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
@@ -133,7 +250,7 @@
# if defined(_WIN32)
extern __declspec(dllimport) char** environ;
# else
-extern char** environ;
+extern char** environ; // NOLINT(readability-redundant-declaration)
# endif
#endif
@@ -984,36 +1101,22 @@
#endif
-std::string cmSystemTools::GetRealPathResolvingWindowsSubst(
- const std::string& path, std::string* errorMessage)
+std::string cmSystemTools::GetRealPath(const std::string& path,
+ std::string* errorMessage)
{
#ifdef _WIN32
- // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found
std::string resolved_path;
- uv_fs_t req;
- int err = uv_fs_realpath(nullptr, &req, path.c_str(), nullptr);
- if (!err) {
- resolved_path = std::string((char*)req.ptr);
- cmSystemTools::ConvertToUnixSlashes(resolved_path);
- // Normalize to upper-case drive letter as GetActualCaseForPath does.
- if (resolved_path.size() > 1 && resolved_path[1] == ':') {
- resolved_path[0] = toupper(resolved_path[0]);
+ using namespace cm::PathResolver;
+ // IWYU pragma: no_forward_declare cm::PathResolver::Policies::RealPath
+ static const Resolver<Policies::RealPath> resolver(RealOS);
+ cmsys::Status status = resolver.Resolve(path, resolved_path);
+ if (!status) {
+ if (errorMessage) {
+ *errorMessage = status.GetString();
+ resolved_path.clear();
+ } else {
+ resolved_path = path;
}
- } else if (err == UV_ENOSYS) {
- resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage);
- } else if (errorMessage) {
- LPSTR message = nullptr;
- DWORD size = FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message,
- 0, nullptr);
- *errorMessage = std::string(message, size);
- LocalFree(message);
-
- resolved_path = "";
- } else {
- resolved_path = path;
}
return resolved_path;
#else
@@ -1614,20 +1717,59 @@
return result;
}
-std::vector<std::string> cmSystemTools::SplitEnvPath(std::string const& value)
+std::vector<std::string> cmSystemTools::GetEnvPathNormalized(
+ std::string const& var)
+{
+ std::vector<std::string> result;
+ if (cm::optional<std::string> env = cmSystemTools::GetEnvVar(var)) {
+ std::vector<std::string> p = cmSystemTools::SplitEnvPathNormalized(*env);
+ std::move(p.begin(), p.end(), std::back_inserter(result));
+ }
+ return result;
+}
+
+std::vector<std::string> cmSystemTools::SplitEnvPath(cm::string_view in)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
static cm::string_view sep = ";"_s;
#else
static cm::string_view sep = ":"_s;
#endif
- std::vector<std::string> paths = cmTokenize(value, sep);
- for (std::string& p : paths) {
- SystemTools::ConvertToUnixSlashes(p);
+ std::vector<std::string> paths;
+ cm::string_view::size_type e = 0;
+ for (;;) {
+ cm::string_view::size_type b = in.find_first_not_of(sep, e);
+ if (b == cm::string_view::npos) {
+ break;
+ }
+ e = in.find_first_of(sep, b);
+ if (e == cm::string_view::npos) {
+ paths.emplace_back(in.substr(b));
+ break;
+ }
+ paths.emplace_back(in.substr(b, e - b));
}
return paths;
}
+std::vector<std::string> cmSystemTools::SplitEnvPathNormalized(
+ cm::string_view in)
+{
+ std::vector<std::string> paths = cmSystemTools::SplitEnvPath(in);
+ std::transform(paths.begin(), paths.end(), paths.begin(),
+ cmSystemTools::ToNormalizedPathOnDisk);
+ return paths;
+}
+
+std::string cmSystemTools::ToNormalizedPathOnDisk(std::string p)
+{
+ using namespace cm::PathResolver;
+ // IWYU pragma: no_forward_declare cm::PathResolver::Policies::LogicalPath
+ static const Resolver<Policies::LogicalPath> resolver(RealOS);
+ resolver.Resolve(std::move(p), p);
+ return p;
+}
+
#ifndef CMAKE_BOOTSTRAP
bool cmSystemTools::UnsetEnv(const char* value)
{
@@ -1874,12 +2016,12 @@
std::string const& format, int compressionLevel)
{
#if !defined(CMAKE_BOOTSTRAP)
- cmWorkingDirectory workdir(cmSystemTools::GetCurrentWorkingDirectory());
+ cmWorkingDirectory workdir(cmSystemTools::GetLogicalWorkingDirectory());
if (!workingDirectory.empty()) {
workdir.SetDirectory(workingDirectory);
}
- const std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ const std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary);
if (!fout) {
std::string e = cmStrCat("Cannot open output file \"", outFileName,
@@ -2513,30 +2655,48 @@
#endif
}
-static std::string cmSystemToolsCMakeCommand;
-static std::string cmSystemToolsCTestCommand;
-static std::string cmSystemToolsCPackCommand;
-static std::string cmSystemToolsCMakeCursesCommand;
-static std::string cmSystemToolsCMakeGUICommand;
-static std::string cmSystemToolsCMClDepsCommand;
-static std::string cmSystemToolsCMakeRoot;
-static std::string cmSystemToolsHTMLDoc;
-void cmSystemTools::FindCMakeResources(const char* argv0)
+namespace {
+std::string InitLogicalWorkingDirectory()
{
- std::string exe_dir;
+ std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
+ std::string pwd;
+ if (cmSystemTools::GetEnv("PWD", pwd)) {
+ std::string const pwd_real = cmSystemTools::GetRealPath(pwd);
+ if (pwd_real == cwd) {
+ cwd = std::move(pwd);
+ }
+ }
+ return cwd;
+}
+
+std::string cmSystemToolsLogicalWorkingDirectory =
+ InitLogicalWorkingDirectory();
+
+std::string cmSystemToolsCMakeCommand;
+std::string cmSystemToolsCTestCommand;
+std::string cmSystemToolsCPackCommand;
+std::string cmSystemToolsCMakeCursesCommand;
+std::string cmSystemToolsCMakeGUICommand;
+std::string cmSystemToolsCMClDepsCommand;
+std::string cmSystemToolsCMakeRoot;
+std::string cmSystemToolsHTMLDoc;
+
+#if defined(__APPLE__)
+bool IsCMakeAppBundleExe(std::string const& exe)
+{
+ return cmHasLiteralSuffix(cmSystemTools::LowerCase(exe), "/macos/cmake");
+}
+#endif
+
+std::string FindOwnExecutable(const char* argv0)
+{
#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)argv0; // ignore this on windows
+ static_cast<void>(argv0);
wchar_t modulepath[_MAX_PATH];
::GetModuleFileNameW(nullptr, modulepath, sizeof(modulepath));
- std::string path = cmsys::Encoding::ToNarrow(modulepath);
- std::string realPath =
- cmSystemTools::GetRealPathResolvingWindowsSubst(path, nullptr);
- if (realPath.empty()) {
- realPath = path;
- }
- exe_dir = cmSystemTools::GetFilenamePath(realPath);
+ std::string exe = cmsys::Encoding::ToNarrow(modulepath);
#elif defined(__APPLE__)
- (void)argv0; // ignore this on OS X
+ static_cast<void>(argv0);
# define CM_EXE_PATH_LOCAL_SIZE 16384
char exe_path_local[CM_EXE_PATH_LOCAL_SIZE];
# if defined(MAC_OS_X_VERSION_10_3) && !defined(MAC_OS_X_VERSION_10_4)
@@ -2550,41 +2710,133 @@
exe_path = static_cast<char*>(malloc(exe_path_size));
_NSGetExecutablePath(exe_path, &exe_path_size);
}
- exe_dir =
- cmSystemTools::GetFilenamePath(cmSystemTools::GetRealPath(exe_path));
+ std::string exe = exe_path;
if (exe_path != exe_path_local) {
free(exe_path);
}
- if (cmSystemTools::GetFilenameName(exe_dir) == "MacOS") {
+ if (IsCMakeAppBundleExe(exe)) {
// The executable is inside an application bundle.
- // Look for ..<CMAKE_BIN_DIR> (install tree) and then fall back to
- // ../../../bin (build tree).
- exe_dir = cmSystemTools::GetFilenamePath(exe_dir);
- if (cmSystemTools::FileExists(exe_dir + CMAKE_BIN_DIR "/cmake")) {
- exe_dir += CMAKE_BIN_DIR;
- } else {
- exe_dir = cmSystemTools::GetFilenamePath(exe_dir);
- exe_dir = cmSystemTools::GetFilenamePath(exe_dir);
+ // The install tree has "..<CMAKE_BIN_DIR>/cmake-gui".
+ // The build tree has '../../../cmake-gui".
+ std::string dir = cmSystemTools::GetFilenamePath(exe);
+ dir = cmSystemTools::GetFilenamePath(dir);
+ exe = cmStrCat(dir, CMAKE_BIN_DIR "/cmake-gui");
+ if (!cmSystemTools::PathExists(exe)) {
+ dir = cmSystemTools::GetFilenamePath(dir);
+ dir = cmSystemTools::GetFilenamePath(dir);
+ exe = cmStrCat(dir, "/cmake-gui");
}
}
#else
std::string errorMsg;
std::string exe;
- if (cmSystemTools::FindProgramPath(argv0, exe, errorMsg)) {
- // remove symlinks
- exe = cmSystemTools::GetRealPath(exe);
- exe_dir = cmSystemTools::GetFilenamePath(exe);
- } else {
+ if (!cmSystemTools::FindProgramPath(argv0, exe, errorMsg)) {
// ???
}
#endif
- exe_dir = cmSystemTools::GetActualCaseForPath(exe_dir);
- cmSystemToolsCMakeCommand =
- cmStrCat(exe_dir, "/cmake", cmSystemTools::GetExecutableExtension());
+ exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
+ return exe;
+}
+
+#ifndef CMAKE_BOOTSTRAP
+bool ResolveSymlinkToOwnExecutable(std::string& exe, std::string& exe_dir)
+{
+ std::string linked_exe;
+ if (!cmSystemTools::ReadSymlink(exe, linked_exe)) {
+ return false;
+ }
+# if defined(__APPLE__)
+ // Ignore "cmake-gui -> ../MacOS/CMake".
+ if (IsCMakeAppBundleExe(linked_exe)) {
+ return false;
+ }
+# endif
+ if (cmSystemTools::FileIsFullPath(linked_exe)) {
+ exe = std::move(linked_exe);
+ } else {
+ exe = cmStrCat(exe_dir, '/', std::move(linked_exe));
+ }
+ exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
+ exe_dir = cmSystemTools::GetFilenamePath(exe);
+ return true;
+}
+
+bool FindCMakeResourcesInInstallTree(std::string const& exe_dir)
+{
+ // Install tree has
+ // - "<prefix><CMAKE_BIN_DIR>/cmake"
+ // - "<prefix><CMAKE_DATA_DIR>"
+ // - "<prefix><CMAKE_DOC_DIR>"
+ if (cmHasLiteralSuffix(exe_dir, CMAKE_BIN_DIR)) {
+ std::string const prefix =
+ exe_dir.substr(0, exe_dir.size() - cmStrLen(CMAKE_BIN_DIR));
+ // Set cmSystemToolsCMakeRoot set to the location expected in an
+ // install tree, even if it does not exist, so that
+ // cmake::AddCMakePaths can print the location in its error message.
+ cmSystemToolsCMakeRoot = cmStrCat(prefix, CMAKE_DATA_DIR);
+ if (cmSystemTools::FileExists(
+ cmStrCat(cmSystemToolsCMakeRoot, "/Modules/CMake.cmake"))) {
+ if (cmSystemTools::FileExists(
+ cmStrCat(prefix, CMAKE_DOC_DIR "/html/index.html"))) {
+ cmSystemToolsHTMLDoc = cmStrCat(prefix, CMAKE_DOC_DIR "/html");
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+void FindCMakeResourcesInBuildTree(std::string const& exe_dir)
+{
+ // Build tree has "<build>/bin[/<config>]/cmake" and
+ // "<build>/CMakeFiles/CMakeSourceDir.txt".
+ std::string dir = cmSystemTools::GetFilenamePath(exe_dir);
+ std::string src_dir_txt = cmStrCat(dir, "/CMakeFiles/CMakeSourceDir.txt");
+ cmsys::ifstream fin(src_dir_txt.c_str());
+ std::string src_dir;
+ if (fin && cmSystemTools::GetLineFromStream(fin, src_dir) &&
+ cmSystemTools::FileIsDirectory(src_dir)) {
+ cmSystemToolsCMakeRoot = src_dir;
+ } else {
+ dir = cmSystemTools::GetFilenamePath(dir);
+ src_dir_txt = cmStrCat(dir, "/CMakeFiles/CMakeSourceDir.txt");
+ cmsys::ifstream fin2(src_dir_txt.c_str());
+ if (fin2 && cmSystemTools::GetLineFromStream(fin2, src_dir) &&
+ cmSystemTools::FileIsDirectory(src_dir)) {
+ cmSystemToolsCMakeRoot = src_dir;
+ }
+ }
+ if (!cmSystemToolsCMakeRoot.empty() && cmSystemToolsHTMLDoc.empty() &&
+ cmSystemTools::FileExists(
+ cmStrCat(dir, "/Utilities/Sphinx/html/index.html"))) {
+ cmSystemToolsHTMLDoc = cmStrCat(dir, "/Utilities/Sphinx/html");
+ }
+}
+#endif
+}
+
+void cmSystemTools::FindCMakeResources(const char* argv0)
+{
+ std::string exe = FindOwnExecutable(argv0);
#ifdef CMAKE_BOOTSTRAP
+ // The bootstrap cmake knows its resource locations.
+ cmSystemToolsCMakeRoot = CMAKE_BOOTSTRAP_SOURCE_DIR;
+ cmSystemToolsCMakeCommand = exe;
// The bootstrap cmake does not provide the other tools,
// so use the directory where they are about to be built.
- exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
+ std::string exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
+#else
+ // Find resources relative to our own executable.
+ std::string exe_dir = cmSystemTools::GetFilenamePath(exe);
+ bool found = false;
+ do {
+ found = FindCMakeResourcesInInstallTree(exe_dir);
+ } while (!found && ResolveSymlinkToOwnExecutable(exe, exe_dir));
+ if (!found) {
+ FindCMakeResourcesInBuildTree(exe_dir);
+ }
+ cmSystemToolsCMakeCommand =
+ cmStrCat(exe_dir, "/cmake", cmSystemTools::GetExecutableExtension());
#endif
cmSystemToolsCTestCommand =
cmStrCat(exe_dir, "/ctest", cmSystemTools::GetExecutableExtension());
@@ -2605,52 +2857,6 @@
if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand)) {
cmSystemToolsCMClDepsCommand.clear();
}
-
-#ifndef CMAKE_BOOTSTRAP
- // Install tree has
- // - "<prefix><CMAKE_BIN_DIR>/cmake"
- // - "<prefix><CMAKE_DATA_DIR>"
- // - "<prefix><CMAKE_DOC_DIR>"
- if (cmHasLiteralSuffix(exe_dir, CMAKE_BIN_DIR)) {
- std::string const prefix =
- exe_dir.substr(0, exe_dir.size() - cmStrLen(CMAKE_BIN_DIR));
- cmSystemToolsCMakeRoot = cmStrCat(prefix, CMAKE_DATA_DIR);
- if (cmSystemTools::FileExists(
- cmStrCat(prefix, CMAKE_DOC_DIR "/html/index.html"))) {
- cmSystemToolsHTMLDoc = cmStrCat(prefix, CMAKE_DOC_DIR "/html");
- }
- }
- if (cmSystemToolsCMakeRoot.empty() ||
- !cmSystemTools::FileExists(
- cmStrCat(cmSystemToolsCMakeRoot, "/Modules/CMake.cmake"))) {
- // Build tree has "<build>/bin[/<config>]/cmake" and
- // "<build>/CMakeFiles/CMakeSourceDir.txt".
- std::string dir = cmSystemTools::GetFilenamePath(exe_dir);
- std::string src_dir_txt = cmStrCat(dir, "/CMakeFiles/CMakeSourceDir.txt");
- cmsys::ifstream fin(src_dir_txt.c_str());
- std::string src_dir;
- if (fin && cmSystemTools::GetLineFromStream(fin, src_dir) &&
- cmSystemTools::FileIsDirectory(src_dir)) {
- cmSystemToolsCMakeRoot = src_dir;
- } else {
- dir = cmSystemTools::GetFilenamePath(dir);
- src_dir_txt = cmStrCat(dir, "/CMakeFiles/CMakeSourceDir.txt");
- cmsys::ifstream fin2(src_dir_txt.c_str());
- if (fin2 && cmSystemTools::GetLineFromStream(fin2, src_dir) &&
- cmSystemTools::FileIsDirectory(src_dir)) {
- cmSystemToolsCMakeRoot = src_dir;
- }
- }
- if (!cmSystemToolsCMakeRoot.empty() && cmSystemToolsHTMLDoc.empty() &&
- cmSystemTools::FileExists(
- cmStrCat(dir, "/Utilities/Sphinx/html/index.html"))) {
- cmSystemToolsHTMLDoc = cmStrCat(dir, "/Utilities/Sphinx/html");
- }
- }
-#else
- // Bootstrap build knows its source.
- cmSystemToolsCMakeRoot = CMAKE_BOOTSTRAP_SOURCE_DIR;
-#endif
}
std::string const& cmSystemTools::GetCMakeCommand()
@@ -2737,10 +2943,18 @@
return config;
}
-std::string cmSystemTools::GetCurrentWorkingDirectory()
+std::string const& cmSystemTools::GetLogicalWorkingDirectory()
{
- return cmSystemTools::CollapseFullPath(
- cmsys::SystemTools::GetCurrentWorkingDirectory());
+ return cmSystemToolsLogicalWorkingDirectory;
+}
+
+cmsys::Status cmSystemTools::SetLogicalWorkingDirectory(std::string const& lwd)
+{
+ cmsys::Status status = cmSystemTools::ChangeDirectory(lwd);
+ if (status) {
+ cmSystemToolsLogicalWorkingDirectory = lwd;
+ }
+ return status;
}
void cmSystemTools::MakefileColorEcho(int color, const char* message,
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 0531f63..4f62aee 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -399,7 +399,18 @@
std::string const& in);
static cm::optional<std::string> GetEnvVar(std::string const& var);
- static std::vector<std::string> SplitEnvPath(std::string const& value);
+ static std::vector<std::string> GetEnvPathNormalized(std::string const& var);
+
+ static std::vector<std::string> SplitEnvPath(cm::string_view in);
+ static std::vector<std::string> SplitEnvPathNormalized(cm::string_view in);
+
+ /** Convert an input path to an absolute path with no '/..' components.
+ Backslashes in the input path are converted to forward slashes.
+ Relative paths are interpreted w.r.t. GetLogicalWorkingDirectory.
+ On Windows, the on-disk capitalization is loaded for existing paths.
+ This is similar to 'realpath', but preserves symlinks that are
+ not erased by '../' components. */
+ static std::string ToNormalizedPathOnDisk(std::string p);
#ifndef CMAKE_BOOTSTRAP
/** Remove an environment variable */
@@ -529,8 +540,11 @@
static cm::optional<std::string> GetSystemConfigDirectory();
static cm::optional<std::string> GetCMakeConfigDirectory();
- /** Get the CWD mapped through the KWSys translation map. */
- static std::string GetCurrentWorkingDirectory();
+ static std::string const& GetLogicalWorkingDirectory();
+
+ /** The logical working directory may contain symlinks but must not
+ contain any '../' path components. */
+ static cmsys::Status SetLogicalWorkingDirectory(std::string const& lwd);
/** Echo a message in color using KWSys's Terminal cprintf. */
static void MakefileColorEcho(int color, const char* message, bool newLine,
@@ -591,11 +605,9 @@
static std::string GetComspec();
#endif
- /** Get the real path for a given path, removing all symlinks.
- This variant of GetRealPath also works on Windows but will
- resolve subst drives too. */
- static std::string GetRealPathResolvingWindowsSubst(
- const std::string& path, std::string* errorMessage = nullptr);
+ /** Get the real path for a given path, removing all symlinks. */
+ static std::string GetRealPath(const std::string& path,
+ std::string* errorMessage = nullptr);
/** Perform one-time initialization of libuv. */
static void InitializeLibUV();
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f1dcc76..30eef70 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -120,8 +120,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
addContent = true;
break;
@@ -250,7 +248,7 @@
void CopyFromEntries(cmBTStringRange entries)
{
- return cm::append(this->Entries, entries);
+ cm::append(this->Entries, entries);
}
enum class Action
@@ -354,6 +352,8 @@
}
cm::static_string_view const Name;
+ // Explicit initialization is needed for AppleClang in Xcode 8 and below
+ // NOLINTNEXTLINE(readability-redundant-member-init)
cm::optional<cm::static_string_view> const Default = {};
InitCondition const InitConditional = InitCondition::Always;
Repetition const Repeat = Repetition::Once;
@@ -464,6 +464,7 @@
// Linking properties
{ "LINKER_TYPE"_s, IC::CanCompileSources },
+ { "LINK_WARNING_AS_ERROR"_s, IC::CanCompileSources },
{ "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
{ "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
{ "LINK_LIBRARIES_STRATEGY"_s, IC::NormalNonImportedTarget },
@@ -551,6 +552,7 @@
{ "UNITY_BUILD_UNIQUE_ID"_s, IC::CanCompileSources },
{ "UNITY_BUILD_BATCH_SIZE"_s, "8"_s, IC::CanCompileSources },
{ "UNITY_BUILD_MODE"_s, "BATCH"_s, IC::CanCompileSources },
+ { "UNITY_BUILD_RELOCATABLE"_s, IC::CanCompileSources },
{ "OPTIMIZE_DEPENDENCIES"_s, IC::CanCompileSources },
{ "VERIFY_INTERFACE_HEADER_SETS"_s },
// -- Android
@@ -1305,8 +1307,25 @@
bool cmTarget::IsArchivedAIXSharedLibrary() const
{
- return (this->GetType() == cmStateEnums::SHARED_LIBRARY && this->IsAIX() &&
- this->GetPropertyAsBool("AIX_SHARED_LIBRARY_ARCHIVE"));
+ if (this->GetType() == cmStateEnums::SHARED_LIBRARY && this->IsAIX()) {
+ cmValue value = this->GetProperty("AIX_SHARED_LIBRARY_ARCHIVE");
+ if (!value.IsEmpty()) {
+ return value.IsOn();
+ }
+ if (this->IsImported()) {
+ return false;
+ }
+ switch (this->GetPolicyStatusCMP0182()) {
+ case cmPolicies::WARN:
+ case cmPolicies::OLD:
+ // The OLD behavior's default is to disable shared library archives.
+ break;
+ case cmPolicies::NEW:
+ // The NEW behavior's default is to enable shared library archives.
+ return true;
+ }
+ }
+ return false;
}
bool cmTarget::IsAppBundleOnApple() const
@@ -1417,8 +1436,6 @@
case cmPolicies::OLD:
noMessage = true;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
messageType = MessageType::FATAL_ERROR;
}
@@ -2052,10 +2069,13 @@
{
ReadOnlyProperty(ReadOnlyCondition cond)
: Condition{ cond }
- , Policy{} {};
+ {
+ }
ReadOnlyProperty(ReadOnlyCondition cond, cmPolicies::PolicyID id)
: Condition{ cond }
- , Policy{ id } {};
+ , Policy{ id }
+ {
+ }
ReadOnlyCondition Condition;
cm::optional<cmPolicies::PolicyID> Policy;
@@ -2104,8 +2124,6 @@
case cmPolicies::OLD:
readOnly = false;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
context->IssueMessage(MessageType::FATAL_ERROR,
this->message(prop, target));
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 51dce76..b5d8ebc 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -97,8 +97,8 @@
if (!target) {
MessageType t = MessageType::FATAL_ERROR; // fail by default
std::ostringstream e;
- e << "Cannot specify link libraries for target \"" << args[0] << "\" "
- << "which is not built by this project.";
+ e << "Cannot specify link libraries for target \"" << args[0]
+ << "\" which is not built by this project.";
// The bad target is the only argument. Check how policy CMP0016 is set,
// and accept, warn or fail respectively:
if (args.size() < 2) {
@@ -107,18 +107,14 @@
t = MessageType::AUTHOR_WARNING;
// Print the warning.
e << "\n"
- << "CMake does not support this but it used to work accidentally "
- << "and is being allowed for compatibility."
- << "\n"
+ "CMake does not support this but it used to work accidentally "
+ "and is being allowed for compatibility."
+ "\n"
<< cmPolicies::GetPolicyWarning(cmPolicies::CMP0016);
break;
case cmPolicies::OLD: // OLD behavior does not warn.
t = MessageType::MESSAGE;
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- e << "\n" << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0016);
- break;
case cmPolicies::NEW: // NEW behavior prints the error.
break;
}
@@ -145,13 +141,11 @@
MessageType messageType = MessageType::AUTHOR_WARNING;
switch (mf.GetPolicyStatus(cmPolicies::CMP0039)) {
case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n";
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << '\n';
modal = "should";
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
modal = "must";
messageType = MessageType::FATAL_ERROR;
@@ -408,8 +402,6 @@
case cmPolicies::OLD:
this->RejectRemoteLinking = true;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
this->EncodeRemoteReference = true;
break;
@@ -456,13 +448,11 @@
MessageType messageType = MessageType::AUTHOR_WARNING;
switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0023)) {
case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n";
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << '\n';
modal = "should";
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
modal = "must";
messageType = MessageType::FATAL_ERROR;
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index 134b4b6..bf9dddd 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -22,8 +22,6 @@
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
modal = "may";
messageType = MessageType::FATAL_ERROR;
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index babbaa5..8ce5751 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -165,12 +165,6 @@
case cmPolicies::OLD:
issueMessage = false;
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0076));
- break;
case cmPolicies::NEW: {
issueMessage = false;
useAbsoluteContent = true;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index ffb5e21..0fcd3bd 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -49,8 +49,6 @@
case cmPolicies::OLD:
// OLD behavior is to not quote the test's name.
return false;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
default:
// NEW behavior is to quote the test's name.
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 4d8bc02..cb6eb6f 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -62,8 +62,7 @@
const std::string& formatString,
bool utcFlag) const
{
- std::string real_path =
- cmSystemTools::GetRealPathResolvingWindowsSubst(path);
+ std::string real_path = cmSystemTools::GetRealPath(path);
if (!cmsys::SystemTools::FileExists(real_path)) {
return std::string();
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index b8b3491..ef88ef1 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -158,10 +158,10 @@
};
template <typename T>
-inline uv_handle_ptr_base_<T>::uv_handle_ptr_base_(
+uv_handle_ptr_base_<T>::uv_handle_ptr_base_(
uv_handle_ptr_base_<T>&&) noexcept = default;
template <typename T>
-inline uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=(
+uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=(
uv_handle_ptr_base_<T>&&) noexcept = default;
/**
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index b787f19..4060a3d 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -342,6 +342,9 @@
!defined(CMAKE_USE_SYSTEM_LIBUV)
options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME;
#endif
+#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
+ options.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
+#endif
if (!this->Builder->WorkingDirectory.empty()) {
options.cwd = this->Builder->WorkingDirectory.c_str();
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 694976e..0c4992b 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -30,6 +30,7 @@
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio10Generator.h"
@@ -1870,7 +1871,9 @@
BuildInParallel buildInParallel = BuildInParallel::No;
if (command.GetCMP0147Status() == cmPolicies::NEW &&
!command.GetUsesTerminal() &&
- !(command.HasMainDependency() && source->GetIsGenerated())) {
+ !(command.HasMainDependency() && source->GetIsGenerated()) &&
+ !source->GetPropertyAsBool(
+ "VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD")) {
buildInParallel = BuildInParallel::Yes;
}
this->WriteCustomRuleCpp(*spe2, c, script, additional_inputs.str(),
@@ -4426,12 +4429,9 @@
linkType = "EXE";
}
std::string flags;
- std::string linkFlagVarBase = cmStrCat("CMAKE_", linkType, "_LINKER_FLAGS");
- flags += ' ';
- flags += this->Makefile->GetRequiredDefinition(linkFlagVarBase);
- std::string linkFlagVar = cmStrCat(linkFlagVarBase, '_', CONFIG);
- flags += ' ';
- flags += this->Makefile->GetRequiredDefinition(linkFlagVar);
+ this->LocalGenerator->AddConfigVariableFlags(
+ flags, cmStrCat("CMAKE_", linkType, "_LINKER_FLAGS"),
+ this->GeneratorTarget, cmBuildStep::Link, linkLanguage, config);
cmValue targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
flags += ' ';
@@ -4448,6 +4448,9 @@
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(flags, opts);
+ this->LocalGenerator->AppendWarningAsErrorLinkerFlags(
+ flags, this->GeneratorTarget, linkLanguage);
+
cmComputeLinkInformation* pcli =
this->GeneratorTarget->GetLinkInformation(config);
if (!pcli) {
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 6b454d7..f10146c 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -126,8 +126,6 @@
case cmPolicies::OLD:
// OLD behavior is to silently ignore the error.
break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
// NEW behavior is to enforce the error.
enforceError = true;
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index 2fbf657..69ebdab 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -250,6 +250,9 @@
this->UVOptions_.args = const_cast<char**>(this->CommandPtr_.data());
this->UVOptions_.cwd = this->Setup_.WorkingDirectory.c_str();
this->UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE;
+#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
+ this->UVOptions_.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
+#endif
this->UVOptions_.stdio_count =
static_cast<int>(this->UVOptionsStdIO_.size());
this->UVOptions_.stdio = this->UVOptionsStdIO_.data();
diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx
index 12fae12..ec10fb1 100644
--- a/Source/cmWorkingDirectory.cxx
+++ b/Source/cmWorkingDirectory.cxx
@@ -2,13 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWorkingDirectory.h"
-#include <cerrno>
-
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir)
{
- this->OldDir = cmSystemTools::GetCurrentWorkingDirectory();
+ this->OldDir = cmSystemTools::GetLogicalWorkingDirectory();
this->SetDirectory(newdir);
}
@@ -19,11 +18,13 @@
bool cmWorkingDirectory::SetDirectory(std::string const& newdir)
{
- if (cmSystemTools::ChangeDirectory(newdir)) {
- this->ResultCode = 0;
+ cmsys::Status status = cmSystemTools::SetLogicalWorkingDirectory(newdir);
+ if (status) {
+ this->Error.clear();
return true;
}
- this->ResultCode = errno;
+ this->Error = cmStrCat("Failed to change working directory to \"", newdir,
+ "\": ", status.GetString());
return false;
}
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
index e593621..82f79bc 100644
--- a/Source/cmWorkingDirectory.h
+++ b/Source/cmWorkingDirectory.h
@@ -26,19 +26,11 @@
bool SetDirectory(std::string const& newdir);
void Pop();
- bool Failed() const { return this->ResultCode != 0; }
-
- /** \return 0 if the last attempt to set the working directory was
- * successful. If it failed, the value returned will be the
- * \c errno value associated with the failure. A description
- * of the error code can be obtained by passing the result
- * to \c std::strerror().
- */
- int GetLastResult() const { return this->ResultCode; }
-
+ bool Failed() const { return !this->Error.empty(); }
+ std::string const& GetError() const { return this->Error; }
std::string const& GetOldDirectory() const { return this->OldDir; }
private:
std::string OldDir;
- int ResultCode;
+ std::string Error;
};
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index fcee5e5..7289740 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -7,7 +7,6 @@
#include <chrono>
#include <cstdio>
#include <cstdlib>
-#include <cstring>
#include <initializer_list>
#include <iomanip>
#include <iostream>
@@ -287,7 +286,7 @@
};
cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
- : CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory())
+ : CMakeWorkingDirectory(cmSystemTools::GetLogicalWorkingDirectory())
, FileTimeCache(cm::make_unique<cmFileTimeCache>())
#ifndef CMAKE_BOOTSTRAP
, VariableWatch(cm::make_unique<cmVariableWatch>())
@@ -638,8 +637,8 @@
// Documented behavior of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
// set to $PWD for -P mode.
state->SetWorkingMode(SCRIPT_MODE);
- state->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- state->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ state->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+ state->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
state->ReadListFile(args, path);
return true;
};
@@ -690,7 +689,7 @@
cmSystemTools::Stdout("loading initial cache file " + value + "\n");
// Resolve script path specified on command line
// relative to $PWD.
- auto path = cmSystemTools::CollapseFullPath(value);
+ auto path = cmSystemTools::ToNormalizedPathOnDisk(value);
state->ReadListFile(args, path);
return true;
} },
@@ -779,10 +778,7 @@
snapshot.SetDefaultDefinitions();
cmMakefile mf(gg, snapshot);
if (this->GetWorkingMode() != NORMAL_MODE) {
- std::string file(cmSystemTools::CollapseFullPath(path));
- cmSystemTools::ConvertToUnixSlashes(file);
- mf.SetScriptModeFile(file);
-
+ mf.SetScriptModeFile(cmSystemTools::ToNormalizedPathOnDisk(path));
mf.SetArgcArgv(args);
}
if (!cmSystemTools::FileExists(path, true)) {
@@ -796,16 +792,16 @@
bool cmake::FindPackage(const std::vector<std::string>& args)
{
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+ this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
this->SetGlobalGenerator(cm::make_unique<cmGlobalGenerator>(this));
cmStateSnapshot snapshot = this->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(
- cmSystemTools::GetCurrentWorkingDirectory());
+ cmSystemTools::GetLogicalWorkingDirectory());
snapshot.GetDirectory().SetCurrentSource(
- cmSystemTools::GetCurrentWorkingDirectory());
+ cmSystemTools::GetLogicalWorkingDirectory());
// read in the list file to fill the cache
snapshot.SetDefaultDefinitions();
auto mfu = cm::make_unique<cmMakefile>(this->GetGlobalGenerator(), snapshot);
@@ -956,10 +952,8 @@
cmSystemTools::Error("No source directory specified for -S");
return false;
}
- std::string path = cmSystemTools::CollapseFullPath(value);
- cmSystemTools::ConvertToUnixSlashes(path);
-
- state->SetHomeDirectoryViaCommandLine(path);
+ state->SetHomeDirectoryViaCommandLine(
+ cmSystemTools::ToNormalizedPathOnDisk(value));
return true;
};
@@ -968,9 +962,8 @@
cmSystemTools::Error("No build directory specified for -B");
return false;
}
- std::string path = cmSystemTools::CollapseFullPath(value);
- cmSystemTools::ConvertToUnixSlashes(path);
- state->SetHomeOutputDirectory(path);
+ state->SetHomeOutputDirectory(
+ cmSystemTools::ToNormalizedPathOnDisk(value));
haveBArg = true;
return true;
};
@@ -1074,7 +1067,8 @@
CommandArgument{ "--graphviz", "No file specified for --graphviz",
CommandArgument::Values::One,
[](std::string const& value, cmake* state) -> bool {
- state->SetGraphVizFile(value);
+ state->SetGraphVizFile(
+ cmSystemTools::ToNormalizedPathOnDisk(value));
return true;
} },
@@ -1137,7 +1131,7 @@
"--debug-find-pkg", "Provide a package argument for --debug-find-pkg",
CommandArgument::Values::One, CommandArgument::RequiresSeparator::Yes,
[](std::string const& value, cmake* state) -> bool {
- std::vector<std::string> find_pkgs(cmTokenize(value, ","));
+ std::vector<std::string> find_pkgs(cmTokenize(value, ','));
std::cout << "Running with debug output on for the 'find' commands "
"for package(s)";
for (auto const& v : find_pkgs) {
@@ -1151,7 +1145,7 @@
"--debug-find-var", CommandArgument::Values::One,
CommandArgument::RequiresSeparator::Yes,
[](std::string const& value, cmake* state) -> bool {
- std::vector<std::string> find_vars(cmTokenize(value, ","));
+ std::vector<std::string> find_vars(cmTokenize(value, ','));
std::cout << "Running with debug output on for the variable(s)";
for (auto const& v : find_vars) {
std::cout << ' ' << v;
@@ -1247,7 +1241,15 @@
[](std::string const&, cmake* state) -> bool {
std::cout << "Ignoring COMPILE_WARNING_AS_ERROR target property and "
"CMAKE_COMPILE_WARNING_AS_ERROR variable.\n";
- state->SetIgnoreWarningAsError(true);
+ state->SetIgnoreCompileWarningAsError(true);
+ return true;
+ } },
+ CommandArgument{
+ "--link-no-warning-as-error", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "Ignoring LINK_WARNING_AS_ERROR target property and "
+ "CMAKE_LINK_WARNING_AS_ERROR variable.\n";
+ state->SetIgnoreLinkWarningAsError(true);
return true;
} },
CommandArgument{ "--debugger", CommandArgument::Values::Zero,
@@ -1278,23 +1280,22 @@
return false;
#endif
} },
- CommandArgument{
- "--debugger-dap-log", "No file specified for --debugger-dap-log",
- CommandArgument::Values::One,
- [](std::string const& value, cmake* state) -> bool {
+ CommandArgument{ "--debugger-dap-log",
+ "No file specified for --debugger-dap-log",
+ CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
#ifdef CMake_ENABLE_DEBUGGER
- std::string path = cmSystemTools::CollapseFullPath(value);
- cmSystemTools::ConvertToUnixSlashes(path);
- state->DebuggerDapLogFile = path;
- return true;
+ state->DebuggerDapLogFile =
+ cmSystemTools::ToNormalizedPathOnDisk(value);
+ return true;
#else
- static_cast<void>(value);
- static_cast<void>(state);
- cmSystemTools::Error(
- "CMake was not built with support for --debugger-dap-log");
- return false;
+ static_cast<void>(value);
+ static_cast<void>(state);
+ cmSystemTools::Error("CMake was not built with support "
+ "for --debugger-dap-log");
+ return false;
#endif
- } },
+ } },
};
#if defined(CMAKE_HAVE_VS_GENERATORS)
@@ -1316,9 +1317,8 @@
arguments.emplace_back(
"--profiling-output", "No path specified for --profiling-output",
CommandArgument::Values::One,
- [&](std::string const& value, cmake*) -> bool {
- profilingOutput = cmSystemTools::CollapseFullPath(value);
- cmSystemTools::ConvertToUnixSlashes(profilingOutput);
+ [&profilingOutput](std::string const& value, cmake*) -> bool {
+ profilingOutput = cmSystemTools::ToNormalizedPathOnDisk(value);
return true;
});
arguments.emplace_back("--preset", "No preset specified for --preset",
@@ -1479,10 +1479,10 @@
}
if (!haveSourceDir) {
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
}
if (!haveBinaryDir) {
- this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
}
#if !defined(CMAKE_BOOTSTRAP)
@@ -1588,7 +1588,8 @@
if (!expandedPreset->GraphVizFile.empty()) {
if (this->GraphVizFile.empty()) {
- this->SetGraphVizFile(expandedPreset->GraphVizFile);
+ this->SetGraphVizFile(
+ cmSystemTools::CollapseFullPath(expandedPreset->GraphVizFile));
}
}
@@ -1779,8 +1780,7 @@
bool is_source_dir = false;
bool is_empty_directory = false;
if (cmSystemTools::FileIsDirectory(arg)) {
- std::string path = cmSystemTools::CollapseFullPath(arg);
- cmSystemTools::ConvertToUnixSlashes(path);
+ std::string path = cmSystemTools::ToNormalizedPathOnDisk(arg);
std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
std::string listFile = cmStrCat(path, "/CMakeLists.txt");
@@ -1795,7 +1795,7 @@
is_source_dir = true;
}
} else if (cmSystemTools::FileExists(arg)) {
- std::string fullPath = cmSystemTools::CollapseFullPath(arg);
+ std::string fullPath = cmSystemTools::ToNormalizedPathOnDisk(arg);
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
if (name == "cmakecache.txt"_s) {
@@ -1846,14 +1846,13 @@
if (is_source_dir) {
this->SetHomeDirectoryViaCommandLine(listPath);
if (no_build_tree) {
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->SetHomeOutputDirectory(cwd);
+ this->SetHomeOutputDirectory(
+ cmSystemTools::GetLogicalWorkingDirectory());
}
} else if (no_source_tree && no_build_tree) {
this->SetHomeDirectory(listPath);
-
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->SetHomeOutputDirectory(cwd);
+ this->SetHomeOutputDirectory(
+ cmSystemTools::GetLogicalWorkingDirectory());
} else if (no_build_tree) {
this->SetHomeOutputDirectory(listPath);
}
@@ -1861,18 +1860,16 @@
if (no_source_tree) {
// We didn't find a CMakeLists.txt and it wasn't specified
// with -S. Assume it is the path to the source tree
- std::string full = cmSystemTools::CollapseFullPath(arg);
- this->SetHomeDirectory(full);
+ this->SetHomeDirectory(cmSystemTools::ToNormalizedPathOnDisk(arg));
}
if (no_build_tree && !no_source_tree && is_empty_directory) {
// passed `-S <path> <build_dir> when build_dir is an empty directory
- std::string full = cmSystemTools::CollapseFullPath(arg);
- this->SetHomeOutputDirectory(full);
+ this->SetHomeOutputDirectory(cmSystemTools::ToNormalizedPathOnDisk(arg));
} else if (no_build_tree) {
// We didn't find a CMakeCache.txt and it wasn't specified
// with -B. Assume the current working directory as the build tree.
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->SetHomeOutputDirectory(cwd);
+ this->SetHomeOutputDirectory(
+ cmSystemTools::GetLogicalWorkingDirectory());
used_provided_path = false;
}
}
@@ -2373,7 +2370,6 @@
int cmake::ActualConfigure()
{
// Construct right now our path conversion table before it's too late:
- this->UpdateConversionPathTable();
this->CleanupCommandsAndMacros();
cmSystemTools::RemoveADirectory(this->GetHomeOutputDirectory() +
@@ -2937,7 +2933,7 @@
this->SaveCache(this->GetHomeOutputDirectory());
#if !defined(CMAKE_BOOTSTRAP)
- this->GetGlobalGenerator()->WriteInstallJson();
+ this->GlobalGenerator->WriteInstallJson();
this->FileAPI->WriteReplies();
#endif
@@ -3214,31 +3210,6 @@
#endif
}
-void cmake::UpdateConversionPathTable()
-{
- // Update the path conversion table with any specified file:
- cmValue tablepath =
- this->State->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE");
-
- if (tablepath) {
- cmsys::ifstream table(tablepath->c_str());
- if (!table) {
- cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to " + *tablepath +
- ". CMake can not open file.");
- cmSystemTools::ReportLastSystemError("CMake can not open file.");
- } else {
- std::string a;
- std::string b;
- while (!table.eof()) {
- // two entries per line
- table >> a;
- table >> b;
- cmSystemTools::AddTranslationPath(a, b);
- }
- }
- }
-}
-
int cmake::CheckBuildSystem()
{
// We do not need to rerun CMake. Check dependency integrity.
@@ -3479,7 +3450,7 @@
{
// so create the directory
std::string resultFile;
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
std::string destPath = cwd + "/__cmake_systeminformation";
cmSystemTools::RemoveADirectory(destPath);
if (!cmSystemTools::MakeDirectory(destPath)) {
@@ -3548,8 +3519,7 @@
// file to it, so we wouldn't expect to get here unless the default
// permissions are questionable or some other process has deleted the
// directory
- std::cerr << "Failed to change to directory " << destPath << " : "
- << std::strerror(workdir.GetLastResult()) << '\n';
+ std::cerr << workdir.GetError() << '\n';
return 1;
}
std::vector<std::string> args2;
@@ -3618,8 +3588,8 @@
#if !defined(CMAKE_BOOTSTRAP)
if (!presetName.empty() || listPresets) {
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+ this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
@@ -3964,8 +3934,8 @@
WorkflowListPresets listPresets, WorkflowFresh fresh)
{
#ifndef CMAKE_BOOTSTRAP
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+ this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
diff --git a/Source/cmake.h b/Source/cmake.h
index cfe4edd..271b914 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -26,7 +26,6 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
#include "cmValue.h"
#if !defined(CMAKE_BOOTSTRAP)
@@ -300,12 +299,7 @@
}
//! Set the name of the graphviz file.
- void SetGraphVizFile(std::string const& ts)
- {
- std::string path = cmSystemTools::CollapseFullPath(ts);
- cmSystemTools::ConvertToUnixSlashes(path);
- this->GraphVizFile = path;
- }
+ void SetGraphVizFile(std::string const& ts) { this->GraphVizFile = ts; }
bool IsAKnownSourceExtension(cm::string_view ext) const
{
@@ -548,8 +542,22 @@
void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
bool GetCheckSystemVars() const { return this->CheckSystemVars; }
void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
- bool GetIgnoreWarningAsError() const { return this->IgnoreWarningAsError; }
- void SetIgnoreWarningAsError(bool b) { this->IgnoreWarningAsError = b; }
+ bool GetIgnoreCompileWarningAsError() const
+ {
+ return this->IgnoreCompileWarningAsError;
+ }
+ void SetIgnoreCompileWarningAsError(bool b)
+ {
+ this->IgnoreCompileWarningAsError = b;
+ }
+ bool GetIgnoreLinkWarningAsError() const
+ {
+ return this->IgnoreLinkWarningAsError;
+ }
+ void SetIgnoreLinkWarningAsError(bool b)
+ {
+ this->IgnoreLinkWarningAsError = b;
+ }
void MarkCliAsUsed(const std::string& variable);
@@ -759,7 +767,8 @@
bool WarnUninitialized = false;
bool WarnUnusedCli = true;
bool CheckSystemVars = false;
- bool IgnoreWarningAsError = false;
+ bool IgnoreCompileWarningAsError = false;
+ bool IgnoreLinkWarningAsError = false;
std::map<std::string, bool> UsedCliVariables;
std::string CMakeEditCommand;
std::string CXXEnvironment;
@@ -811,8 +820,6 @@
std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
- void UpdateConversionPathTable();
-
//! Print a list of valid generators to stderr.
void PrintGeneratorList();
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index b57cdb3..d807237 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -71,7 +71,7 @@
"Run 'cmake --help' for more information."
};
-const cmDocumentationEntry cmDocumentationOptions[34] = {
+const cmDocumentationEntry cmDocumentationOptions[35] = {
{ "--preset <preset>,--preset=<preset>", "Specify a configure preset." },
{ "--list-presets[=<type>]", "List available presets." },
{ "--workflow [<options>]", "Run a workflow preset." },
@@ -123,6 +123,9 @@
{ "--compile-no-warning-as-error",
"Ignore COMPILE_WARNING_AS_ERROR property and "
"CMAKE_COMPILE_WARNING_AS_ERROR variable." },
+ { "--link-no-warning-as-error",
+ "Ignore LINK_WARNING_AS_ERROR property and "
+ "CMAKE_LINK_WARNING_AS_ERROR variable." },
{ "--profiling-format=<fmt>",
"Output data for profiling CMake scripts. Supported formats: "
"google-trace" },
@@ -219,7 +222,7 @@
int do_cmake(int ac, char const* const* av)
{
- if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
+ if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
std::cerr << "Current working directory cannot be established."
<< std::endl;
return 1;
@@ -601,7 +604,7 @@
}
}
if (!matched && i == 0) {
- dir = cmSystemTools::CollapseFullPath(arg);
+ dir = cmSystemTools::ToNormalizedPathOnDisk(arg);
matched = true;
parsed = true;
}
@@ -873,7 +876,7 @@
};
if (ac >= 3) {
- dir = cmSystemTools::CollapseFullPath(av[2]);
+ dir = cmSystemTools::ToNormalizedPathOnDisk(av[2]);
std::vector<std::string> inputArgs;
inputArgs.reserve(ac - 3);
@@ -921,20 +924,6 @@
return 1;
}
- cmake cm(cmake::RoleScript, cmState::Script);
-
- cmSystemTools::SetMessageCallback(
- [&cm](const std::string& msg, const cmMessageMetadata& md) {
- cmakemainMessageCallback(msg, md, &cm);
- });
- cm.SetProgressCallback([&cm](const std::string& msg, float prog) {
- cmakemainProgressCallback(msg, prog, &cm);
- });
- cm.SetHomeDirectory("");
- cm.SetHomeOutputDirectory("");
- cm.SetDebugOutputOn(verbose);
- cm.SetWorkingMode(cmake::SCRIPT_MODE);
-
std::vector<std::string> args{ av[0] };
if (!prefix.empty()) {
@@ -949,10 +938,6 @@
args.emplace_back("-DCMAKE_INSTALL_DO_STRIP=1");
}
- if (!config.empty()) {
- args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config);
- }
-
if (!defaultDirectoryPermissions.empty()) {
std::string parsedPermissionsVar;
if (!parse_default_directory_permissions(defaultDirectoryPermissions,
@@ -967,25 +952,38 @@
args.emplace_back("-P");
- auto handler = cmInstallScriptHandler(dir, component, args);
+ auto handler = cmInstallScriptHandler(dir, component, config, args);
int ret = 0;
- if (!handler.isParallel()) {
- args.emplace_back(cmStrCat(dir, "/cmake_install.cmake"));
- ret = int(bool(cm.Run(args)));
- } else {
- if (!jobs) {
- jobs = 1;
- auto envvar = cmSystemTools::GetEnvVar("CMAKE_INSTALL_PARALLEL_LEVEL");
- if (envvar.has_value()) {
- jobs = extract_job_number("", envvar.value());
- if (jobs < 1) {
- std::cerr << "Value of CMAKE_INSTALL_PARALLEL_LEVEL environment"
- " variable must be a positive integer.\n";
- return 1;
- }
+ if (!jobs && handler.IsParallel()) {
+ jobs = 1;
+ auto envvar = cmSystemTools::GetEnvVar("CMAKE_INSTALL_PARALLEL_LEVEL");
+ if (envvar.has_value()) {
+ jobs = extract_job_number("", envvar.value());
+ if (jobs < 1) {
+ std::cerr << "Value of CMAKE_INSTALL_PARALLEL_LEVEL environment"
+ " variable must be a positive integer.\n";
+ return 1;
}
}
- ret = handler.install(jobs);
+ }
+ if (handler.IsParallel()) {
+ ret = handler.Install(jobs);
+ } else {
+ for (auto const& cmd : handler.GetCommands()) {
+ cmake cm(cmake::RoleScript, cmState::Script);
+ cmSystemTools::SetMessageCallback(
+ [&cm](const std::string& msg, const cmMessageMetadata& md) {
+ cmakemainMessageCallback(msg, md, &cm);
+ });
+ cm.SetProgressCallback([&cm](const std::string& msg, float prog) {
+ cmakemainProgressCallback(msg, prog, &cm);
+ });
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.SetDebugOutputOn(verbose);
+ cm.SetWorkingMode(cmake::SCRIPT_MODE);
+ ret = int(bool(cm.Run(cmd)));
+ }
}
return int(ret > 0);
@@ -1098,7 +1096,7 @@
for (int i = 2; i < ac; ++i) {
switch (doing) {
case DoingDir:
- dir = cmSystemTools::CollapseFullPath(av[i]);
+ dir = cmSystemTools::ToNormalizedPathOnDisk(av[i]);
doing = DoingNone;
break;
default:
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 5310166..aa4fd76 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -24,6 +24,7 @@
#include <windows.h>
#include "cmsys/Encoding.hxx"
+#include "cmsys/SystemTools.hxx"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -151,7 +152,7 @@
// FIXME should this be fatal or not? delete obj? delete d?
if (!out)
return;
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
replaceAll(cwd, "/", "\\");
cwd += "\\";
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index c82cb32..997c1a6 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1347,10 +1347,10 @@
// Create a local generator configured for the directory in
// which dependencies will be scanned.
- homeDir = cmSystemTools::CollapseFullPath(homeDir);
- startDir = cmSystemTools::CollapseFullPath(startDir);
- homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir);
- startOutDir = cmSystemTools::CollapseFullPath(startOutDir);
+ homeDir = cmSystemTools::ToNormalizedPathOnDisk(homeDir);
+ startDir = cmSystemTools::ToNormalizedPathOnDisk(startDir);
+ homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(homeOutDir);
+ startOutDir = cmSystemTools::ToNormalizedPathOnDisk(startOutDir);
cm.SetHomeDirectory(homeDir);
cm.SetHomeOutputDirectory(homeOutDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
@@ -1643,10 +1643,10 @@
std::string startDir;
std::string homeOutDir;
std::string startOutDir;
- homeDir = cmSystemTools::CollapseFullPath(args[4]);
- startDir = cmSystemTools::CollapseFullPath(args[5]);
- homeOutDir = cmSystemTools::CollapseFullPath(args[6]);
- startOutDir = cmSystemTools::CollapseFullPath(args[7]);
+ homeDir = cmSystemTools::ToNormalizedPathOnDisk(args[4]);
+ startDir = cmSystemTools::ToNormalizedPathOnDisk(args[5]);
+ homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[6]);
+ startOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[7]);
cm.SetHomeDirectory(homeDir);
cm.SetHomeOutputDirectory(homeOutDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
@@ -2413,7 +2413,7 @@
// Create a resource file referencing the manifest.
std::string absManifestFile =
- cmSystemTools::CollapseFullPath(this->ManifestFile);
+ cmSystemTools::ToNormalizedPathOnDisk(this->ManifestFile);
if (this->Verbose) {
std::cout << "Create " << this->ManifestFileRC << '\n';
}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 68c36df..388e96b 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -15,7 +15,6 @@
#include "cmSystemTools.h"
#include "CTest/cmCTestLaunch.h"
-#include "CTest/cmCTestScriptHandler.h"
namespace {
const cmDocumentationEntry cmDocumentationName = {
@@ -147,8 +146,6 @@
{ "--overwrite", "Overwrite CTest configuration option." },
{ "--extra-submit <file>[;<file>]", "Submit extra files to the dashboard." },
{ "--http-header <header>", "Append HTTP header when submitting" },
- { "--force-new-ctest-process",
- "Run child CTest instances as new processes" },
{ "--schedule-random", "Use a random order for scheduling tests" },
{ "--submit-index",
"Submit individual dashboard tests with specific index" },
@@ -185,11 +182,8 @@
return cmCTestLaunch::Main(argc, argv);
}
- cmCTest inst;
-
- if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
- cmCTestLog(&inst, ERROR_MESSAGE,
- "Current working directory cannot be established.\n");
+ if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
+ std::cerr << "Current working directory cannot be established.\n";
return 1;
}
@@ -200,18 +194,13 @@
!(cmSystemTools::FileExists("CTestTestfile.cmake") ||
cmSystemTools::FileExists("DartTestfile.txt"))) {
if (argc == 1) {
- cmCTestLog(&inst, ERROR_MESSAGE,
- "*********************************\n"
- "No test configuration file found!\n"
- "*********************************\n");
+ std::cerr << "*********************************\n"
+ "No test configuration file found!\n"
+ "*********************************\n";
}
cmDocumentation doc;
doc.addCTestStandardDocSections();
if (doc.CheckOptions(argc, argv)) {
- // Construct and print requested documentation.
- cmCTestScriptHandler* ch = inst.GetScriptHandler();
- ch->CreateCMake();
-
doc.SetShowGenerators(false);
doc.SetName("ctest");
doc.SetSection("Name", cmDocumentationName);
@@ -222,15 +211,8 @@
}
// copy the args to a vector
- std::vector<std::string> args;
- args.reserve(argc);
- for (int i = 0; i < argc; ++i) {
- args.emplace_back(argv[i]);
- }
- // run ctest
- std::string output;
- int res = inst.Run(args, &output);
- cmCTestLog(&inst, OUTPUT, output);
+ auto args = std::vector<std::string>(argv, argv + argc);
- return res;
+ // run ctest
+ return cmCTest{}.Run(args);
}
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 562d5e6..be510b1 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -410,14 +410,6 @@
endif()
if(KWSYS_USE_SystemTools)
- if (NOT DEFINED KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP)
- set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1)
- endif ()
- if (KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP)
- set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1)
- else ()
- set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 0)
- endif ()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_SETENV
"Checking whether CXX compiler has setenv" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UNSETENV
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
index 8d47340..b4b0efa 100644
--- a/Source/kwsys/Configure.hxx.in
+++ b/Source/kwsys/Configure.hxx.in
@@ -11,9 +11,6 @@
/* Whether <ext/stdio_filebuf.h> is available. */
#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@
-/* Whether the translation map is available or not. */
-#define @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP \
- @KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP@
#if defined(__SUNPRO_CC) && __SUNPRO_CC > 0x5130 && defined(__has_attribute)
# define @KWSYS_NAMESPACE@_has_cpp_attribute(x) __has_attribute(x)
@@ -58,8 +55,6 @@
# define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
# define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH
-# define KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP \
- @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP
#endif
#endif
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 0b43b4a..c1a566f 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -666,14 +666,14 @@
if (dir && dir[0]) {
wchar_t* wdir = kwsysEncoding_DupToWide(dir);
/* We must convert the working directory to a full path. */
- DWORD length = GetFullPathNameW(wdir, 0, 0, 0);
+ DWORD length = GetFullPathNameW(wdir, 0, NULL, NULL);
if (length > 0) {
wchar_t* work_dir = malloc(length * sizeof(wchar_t));
if (!work_dir) {
free(wdir);
return 0;
}
- if (!GetFullPathNameW(wdir, length, work_dir, 0)) {
+ if (!GetFullPathNameW(wdir, length, work_dir, NULL)) {
free(work_dir);
free(wdir);
return 0;
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 933d649..7b0d271 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -4759,7 +4759,7 @@
std::string SystemInformationImplementation::RunProcess(
std::vector<const char*> args)
{
- std::string buffer;
+ std::string out;
// Run the application
kwsysProcess* gp = kwsysProcess_New();
@@ -4778,7 +4778,10 @@
(pipe == kwsysProcess_Pipe_STDOUT ||
pipe == kwsysProcess_Pipe_STDERR))) // wait for 1s
{
- buffer.append(data, length);
+ // Keep stdout, ignore stderr.
+ if (pipe == kwsysProcess_Pipe_STDOUT) {
+ out.append(data, length);
+ }
}
kwsysProcess_WaitForExit(gp, nullptr);
@@ -4808,7 +4811,7 @@
if (result) {
std::cerr << "Error " << args[0] << " returned :" << result << "\n";
}
- return buffer;
+ return out;
}
std::string SystemInformationImplementation::ParseValueFromKStat(
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 6cc103d..5b57900 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -59,9 +59,6 @@
#include <cctype>
#include <cerrno>
-#ifdef __QNX__
-# include <malloc.h> /* for malloc/free on QNX */
-#endif
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -338,10 +335,9 @@
std::string* errorMessage = nullptr)
{
std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
- wchar_t* ptemp;
wchar_t fullpath[MAX_PATH];
DWORD bufferLen = GetFullPathNameW(
- tmp.c_str(), sizeof(fullpath) / sizeof(fullpath[0]), fullpath, &ptemp);
+ tmp.c_str(), sizeof(fullpath) / sizeof(fullpath[0]), fullpath, nullptr);
if (bufferLen < sizeof(fullpath) / sizeof(fullpath[0])) {
resolved_path = KWSYS_NAMESPACE::Encoding::ToNarrow(fullpath);
KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path);
@@ -494,75 +490,17 @@
}
};
-#ifdef _WIN32
-# if defined(_WIN64)
-static constexpr size_t FNV_OFFSET_BASIS = 14695981039346656037ULL;
-static constexpr size_t FNV_PRIME = 1099511628211ULL;
-# else
-static constexpr size_t FNV_OFFSET_BASIS = 2166136261U;
-static constexpr size_t FNV_PRIME = 16777619U;
-# endif
-
-// Case insensitive Fnv1a hash
-struct SystemToolsPathCaseHash
-{
- size_t operator()(std::string const& path) const
- {
- size_t hash = FNV_OFFSET_BASIS;
- for (auto c : path) {
- hash ^= static_cast<size_t>(std::tolower(c));
- hash *= FNV_PRIME;
- }
-
- return hash;
- }
-};
-
-struct SystemToolsPathCaseEqual
-{
- bool operator()(std::string const& l, std::string const& r) const
- {
-# ifdef _MSC_VER
- return _stricmp(l.c_str(), r.c_str()) == 0;
-# elif defined(__GNUC__)
- return strcasecmp(l.c_str(), r.c_str()) == 0;
-# else
- return SystemTools::Strucmp(l.c_str(), r.c_str()) == 0;
-# endif
- }
-};
-#endif
-
/**
* SystemTools static variables singleton class.
*/
class SystemToolsStatic
{
public:
- using StringMap = std::map<std::string, std::string>;
-#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
- /**
- * Path translation table from dir to refdir
- * Each time 'dir' will be found it will be replace by 'refdir'
- */
- StringMap TranslationMap;
-#endif
#ifdef _WIN32
- static std::string GetCasePathName(std::string const& pathIn,
- bool const cache);
- static std::string GetActualCaseForPathCached(std::string const& path);
+ static std::string GetCasePathName(std::string const& pathIn);
static const char* GetEnvBuffered(const char* key);
- std::unordered_map<std::string, std::string, SystemToolsPathCaseHash,
- SystemToolsPathCaseEqual>
- FindFileMap;
- std::unordered_map<std::string, std::string, SystemToolsPathCaseHash,
- SystemToolsPathCaseEqual>
- PathCaseMap;
std::map<std::string, std::string> EnvMap;
#endif
-#ifdef __CYGWIN__
- StringMap Cyg2Win32Map;
-#endif
/**
* Actual implementation of ReplaceString.
@@ -589,8 +527,7 @@
static SystemToolsStatic* SystemToolsStatics;
#ifdef _WIN32
-std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn,
- bool const cache)
+std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
{
std::string casePath;
@@ -643,30 +580,15 @@
std::string test_str = casePath;
test_str += path_components[idx];
- bool found_in_cache = false;
- if (cache) {
- auto const it = SystemToolsStatics->FindFileMap.find(test_str);
- if (it != SystemToolsStatics->FindFileMap.end()) {
- path_components[idx] = it->second;
- found_in_cache = true;
- }
- }
-
- if (!found_in_cache) {
- WIN32_FIND_DATAW findData;
- HANDLE hFind =
- ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData);
- if (INVALID_HANDLE_VALUE != hFind) {
- auto case_file_name = Encoding::ToNarrow(findData.cFileName);
- if (cache) {
- SystemToolsStatics->FindFileMap.emplace(test_str,
- case_file_name);
- }
- path_components[idx] = std::move(case_file_name);
- ::FindClose(hFind);
- } else {
- converting = false;
- }
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind =
+ ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData);
+ if (INVALID_HANDLE_VALUE != hFind) {
+ auto case_file_name = Encoding::ToNarrow(findData.cFileName);
+ path_components[idx] = std::move(case_file_name);
+ ::FindClose(hFind);
+ } else {
+ converting = false;
}
}
}
@@ -675,21 +597,6 @@
}
return casePath;
}
-
-std::string SystemToolsStatic::GetActualCaseForPathCached(std::string const& p)
-{
- std::string casePath;
-
- auto it = SystemToolsStatics->PathCaseMap.find(p);
- if (it != SystemToolsStatics->PathCaseMap.end()) {
- casePath = it->second;
- } else {
- casePath = SystemToolsStatic::GetCasePathName(p, true);
- SystemToolsStatics->PathCaseMap.emplace(p, casePath);
- }
-
- return casePath;
-}
#endif
// adds the elements of the env variable path to the arg passed in
@@ -824,25 +731,14 @@
#elif defined(__CYGWIN__) || defined(__GLIBC__)
/* putenv("A") removes A from the environment. It must not put the
memory in the environment because it does not have any "=" syntax. */
+
static int kwsysUnPutEnv(const std::string& env)
{
int err = 0;
- size_t pos = env.find('=');
- size_t const len = pos == std::string::npos ? env.size() : pos;
- size_t const sz = len + 1;
- char local_buf[256];
- char* buf = sz > sizeof(local_buf) ? (char*)malloc(sz) : local_buf;
- if (!buf) {
- return -1;
- }
- strncpy(buf, env.c_str(), len);
- buf[len] = 0;
- if (putenv(buf) < 0 && errno != EINVAL) {
+ std::string buf = env.substr(0, env.find('='));
+ if (putenv(&buf[0]) < 0 && errno != EINVAL) {
err = errno;
}
- if (buf != local_buf) {
- free(buf);
- }
if (err) {
errno = err;
return -1;
@@ -3407,6 +3303,14 @@
}
std::wstring substituteName(substituteNameData, substituteNameLength);
origName = Encoding::ToNarrow(substituteName);
+ // Symbolic links to absolute paths may use a NT Object Path prefix.
+ // If the path begins with "\??\UNC\", replace it with "\\".
+ // Otherwise, if the path begins with "\??\", remove the prefix.
+ if (origName.compare(0, 8, "\\??\\UNC\\") == 0) {
+ origName.erase(1, 6);
+ } else if (origName.compare(0, 4, "\\??\\") == 0) {
+ origName.erase(0, 4);
+ }
#else
char buf[KWSYS_SYSTEMTOOLS_MAXPATH + 1];
int count = static_cast<int>(
@@ -3501,72 +3405,6 @@
return true;
}
-#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
-void SystemTools::AddTranslationPath(const std::string& a,
- const std::string& b)
-{
- std::string path_a = a;
- std::string path_b = b;
- SystemTools::ConvertToUnixSlashes(path_a);
- SystemTools::ConvertToUnixSlashes(path_b);
- // First check this is a directory path, since we don't want the table to
- // grow too fat
- if (SystemTools::FileIsDirectory(path_a)) {
- // Make sure the path is a full path and does not contain no '..'
- // Ken--the following code is incorrect. .. can be in a valid path
- // for example /home/martink/MyHubba...Hubba/Src
- if (SystemTools::FileIsFullPath(path_b) &&
- path_b.find("..") == std::string::npos) {
- // Before inserting make sure path ends with '/'
- if (!path_a.empty() && path_a.back() != '/') {
- path_a += '/';
- }
- if (!path_b.empty() && path_b.back() != '/') {
- path_b += '/';
- }
- if (!(path_a == path_b)) {
- SystemToolsStatics->TranslationMap.insert(
- SystemToolsStatic::StringMap::value_type(std::move(path_a),
- std::move(path_b)));
- }
- }
- }
-}
-
-void SystemTools::AddKeepPath(const std::string& dir)
-{
- std::string cdir;
- Realpath(SystemTools::CollapseFullPath(dir), cdir);
- SystemTools::AddTranslationPath(cdir, dir);
-}
-
-void SystemTools::CheckTranslationPath(std::string& path)
-{
- // Do not translate paths that are too short to have meaningful
- // translations.
- if (path.size() < 2) {
- return;
- }
-
- // Always add a trailing slash before translation. It does not
- // matter if this adds an extra slash, but we do not want to
- // translate part of a directory (like the foo part of foo-dir).
- path += '/';
-
- // In case a file was specified we still have to go through this:
- // Now convert any path found in the table back to the one desired:
- for (auto const& pair : SystemToolsStatics->TranslationMap) {
- // We need to check of the path is a substring of the other path
- if (path.compare(0, pair.first.size(), pair.first) == 0) {
- path = path.replace(0, pair.first.size(), pair.second);
- }
- }
-
- // Remove the trailing slash we added before.
- path.pop_back();
-}
-#endif
-
static void SystemToolsAppendComponents(
std::vector<std::string>& out_components,
std::vector<std::string>::iterator first,
@@ -3629,25 +3467,7 @@
// Transform the path back to a string.
std::string newPath = SystemTools::JoinPath(out_components);
-#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
- // Update the translation table with this potentially new path. I am not
- // sure why this line is here, it seems really questionable, but yet I
- // would put good money that if I remove it something will break, basically
- // from what I can see it created a mapping from the collapsed path, to be
- // replaced by the input path, which almost completely does the opposite of
- // this function, the only thing preventing this from happening a lot is
- // that if the in_path has a .. in it, then it is not added to the
- // translation table. So for most calls this either does nothing due to the
- // .. or it adds a translation between identical paths as nothing was
- // collapsed, so I am going to try to comment it out, and see what hits the
- // fan, hopefully quickly.
- // Commented out line below:
- // SystemTools::AddTranslationPath(newPath, in_path);
-
- SystemTools::CheckTranslationPath(newPath);
-#endif
#ifdef _WIN32
- newPath = SystemToolsStatics->GetActualCaseForPathCached(newPath);
SystemTools::ConvertToUnixSlashes(newPath);
#endif
// Return the reconstructed path.
@@ -3756,7 +3576,7 @@
std::string SystemTools::GetActualCaseForPath(const std::string& p)
{
#ifdef _WIN32
- return SystemToolsStatic::GetCasePathName(p, false);
+ return SystemToolsStatic::GetCasePathName(p);
#else
return p;
#endif
@@ -4968,51 +4788,6 @@
// Create statics singleton instance
SystemToolsStatics = new SystemToolsStatic;
-
-#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
-// Add some special translation paths for unix. These are not added
-// for windows because drive letters need to be maintained. Also,
-// there are not sym-links and mount points on windows anyway.
-# if !defined(_WIN32) || defined(__CYGWIN__)
- // The tmp path is frequently a logical path so always keep it:
- SystemTools::AddKeepPath("/tmp/");
-
- // If the current working directory is a logical path then keep the
- // logical name.
- std::string pwd_str;
- if (SystemTools::GetEnv("PWD", pwd_str)) {
- char buf[2048];
- if (const char* cwd = Getcwd(buf, 2048)) {
- // The current working directory may be a logical path. Find
- // the shortest logical path that still produces the correct
- // physical path.
- std::string cwd_changed;
- std::string pwd_changed;
-
- // Test progressively shorter logical-to-physical mappings.
- std::string cwd_str = cwd;
- std::string pwd_path;
- Realpath(pwd_str, pwd_path);
- while (cwd_str == pwd_path && cwd_str != pwd_str) {
- // The current pair of paths is a working logical mapping.
- cwd_changed = cwd_str;
- pwd_changed = pwd_str;
-
- // Strip off one directory level and see if the logical
- // mapping still works.
- pwd_str = SystemTools::GetFilenamePath(pwd_str);
- cwd_str = SystemTools::GetFilenamePath(cwd_str);
- Realpath(pwd_str, pwd_path);
- }
-
- // Add the translation to keep the logical path name.
- if (!cwd_changed.empty() && !pwd_changed.empty()) {
- SystemTools::AddTranslationPath(cwd_changed, pwd_changed);
- }
- }
- }
-# endif
-#endif
}
void SystemTools::ClassFinalize()
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 294ffca..03fa3bc 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -984,25 +984,6 @@
*/
static int GetTerminalWidth();
-#if @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP
- /**
- * Add an entry in the path translation table.
- */
- static void AddTranslationPath(const std::string& dir,
- const std::string& refdir);
-
- /**
- * If dir is different after CollapseFullPath is called,
- * Then insert it into the path translation table
- */
- static void AddKeepPath(const std::string& dir);
-
- /**
- * Update path by going through the Path Translation table;
- */
- static void CheckTranslationPath(std::string& path);
-#endif
-
/**
* Delay the execution for a specified amount of time specified
* in milliseconds
@@ -1052,14 +1033,7 @@
static std::string DecodeURL(const std::string& url);
private:
- /**
- * Allocate the stl map that serve as the Path Translation table.
- */
static void ClassInitialize();
-
- /**
- * Deallocate the stl map that serve as the Path Translation table.
- */
static void ClassFinalize();
/**
diff --git a/Templates/CPack.GenericDescription.txt b/Templates/CPack.GenericDescription.txt
index 712ee14..43c83e5 100644
--- a/Templates/CPack.GenericDescription.txt
+++ b/Templates/CPack.GenericDescription.txt
@@ -2,4 +2,3 @@
===========
This is an installer created using CPack (https://cmake.org). No additional installation instructions provided.
-
diff --git a/Templates/CPack.GenericLicense.txt b/Templates/CPack.GenericLicense.txt
index 09c6218..50861ea 100644
--- a/Templates/CPack.GenericLicense.txt
+++ b/Templates/CPack.GenericLicense.txt
@@ -2,4 +2,3 @@
=======
This is an installer created using CPack (https://cmake.org). No license provided.
-
diff --git a/Tests/BundleGeneratorTest/StartupCommand b/Tests/BundleGeneratorTest/StartupCommand
index 5bc5ad2..9776772 100755
--- a/Tests/BundleGeneratorTest/StartupCommand
+++ b/Tests/BundleGeneratorTest/StartupCommand
@@ -9,4 +9,3 @@
export DYLD_LIBRARY_PATH=$RESOURCES/lib
exec "$RESOURCES/bin/Executable"
-
diff --git a/Tests/BundleTest/randomResourceFile.plist.in b/Tests/BundleTest/randomResourceFile.plist.in
index cfe3222..10e02d2 100644
--- a/Tests/BundleTest/randomResourceFile.plist.in
+++ b/Tests/BundleTest/randomResourceFile.plist.in
@@ -6,4 +6,3 @@
<string>CMake</string>
</dict>
</plist>
-
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 9eeb532..341b135 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -1,7 +1,7 @@
# Using 2.8 will trigger a deprecation warning. In this case it's explicitly
# intentional since the tests checks various policy implementations prior to
# 3.10
-cmake_minimum_required(VERSION 2.8.10) # old enough to not set CMP0022
+cmake_minimum_required(VERSION 2.8.11) # old enough to not set CMP0022
if(POLICY CMP0129)
cmake_policy(SET CMP0129 NEW)
@@ -151,7 +151,7 @@
target_link_libraries(SubDirB TopDirImported)
add_subdirectory(SubDirC)
target_link_libraries(SubDirC PRIVATE SubDirC2)
-target_link_libraries(TopDir SubDirC)
+target_link_libraries(TopDir PRIVATE SubDirC)
add_library(TopDirImported IMPORTED INTERFACE)
target_compile_definitions(TopDirImported INTERFACE DEF_TopDirImported)
cmake_policy(POP)
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 5b189e7..de08d56 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -16,12 +16,14 @@
testCTestResourceSpec.cxx
testCTestResourceGroups.cxx
testDebug.cxx
+ testDocumentationFormatter.cxx
testGccDepfileReader.cxx
testGeneratedFileStream.cxx
testJSONHelpers.cxx
testRST.cxx
testRange.cxx
testOptional.cxx
+ testPathResolver.cxx
testString.cxx
testStringAlgorithms.cxx
testSystemTools.cxx
diff --git a/Tests/CMakeLib/testCommon.h b/Tests/CMakeLib/testCommon.h
index de4a689..56e5ef4 100644
--- a/Tests/CMakeLib/testCommon.h
+++ b/Tests/CMakeLib/testCommon.h
@@ -40,10 +40,9 @@
break;
}
}
- std::cout << '.';
}
- if (!result) {
- std::cout << " Passed\n";
+ if (result == 0) {
+ std::cout << "Passed\n";
}
return result;
}
diff --git a/Tests/CMakeLib/testDebuggerAdapter.cxx b/Tests/CMakeLib/testDebuggerAdapter.cxx
index a055cb7..b2c9458 100644
--- a/Tests/CMakeLib/testDebuggerAdapter.cxx
+++ b/Tests/CMakeLib/testDebuggerAdapter.cxx
@@ -132,6 +132,7 @@
ASSERT_TRUE(initializeResponse.response.supportsExceptionInfoRequest);
ASSERT_TRUE(
initializeResponse.response.exceptionBreakpointFilters.has_value());
+ ASSERT_TRUE(initializeResponse.response.supportsValueFormattingOptions);
dap::LaunchRequest launchRequest;
auto launchResponse = client->send(launchRequest).get();
diff --git a/Tests/CMakeLib/testDebuggerAdapterPipe.cxx b/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
index 3647088..312b0e2 100644
--- a/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
+++ b/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
@@ -20,9 +20,10 @@
#include "cmVersionConfig.h"
#ifdef _WIN32
+# include "cmsys/SystemTools.hxx"
+
# include "cmCryptoHash.h"
# include "cmDebuggerWindowsPipeConnection.h"
-# include "cmSystemTools.h"
#else
# include "cmDebuggerPosixPipeConnection.h"
#endif
@@ -69,7 +70,7 @@
#ifdef _WIN32
std::string namedPipe = R"(\\.\pipe\LOCAL\CMakeDebuggerPipe2_)" +
cmCryptoHash(cmCryptoHash::AlgoSHA256)
- .HashString(cmSystemTools::GetCurrentWorkingDirectory());
+ .HashString(cmsys::SystemTools::GetCurrentWorkingDirectory());
#else
std::string namedPipe = "CMakeDebuggerPipe2";
#endif
diff --git a/Tests/CMakeLib/testDebuggerThread.cxx b/Tests/CMakeLib/testDebuggerThread.cxx
index 3b7fe6e..4eed247 100644
--- a/Tests/CMakeLib/testDebuggerThread.cxx
+++ b/Tests/CMakeLib/testDebuggerThread.cxx
@@ -2,6 +2,7 @@
#include <string>
#include <vector>
+#include <cm3p/cppdap/optional.h>
#include <cm3p/cppdap/protocol.h>
#include <cm3p/cppdap/types.h>
@@ -10,21 +11,52 @@
#include "testCommon.h"
-static bool testStackFrameFunctionName()
+static bool testStackFrameFunctionName(
+ dap::optional<dap::StackFrameFormat> format, const char* expectedName)
{
auto thread = std::make_shared<cmDebugger::cmDebuggerThread>(0, "name");
const auto* functionName = "function_name";
- auto arguments = std::vector<cmListFileArgument>{};
+ auto arguments = std::vector<cmListFileArgument>{ cmListFileArgument(
+ "arg", cmListFileArgument::Delimiter::Unquoted, 0) };
cmListFileFunction func(functionName, 10, 20, arguments);
thread->PushStackFrame(nullptr, "CMakeLists.txt", func);
- auto stackTrace = GetStackTraceResponse(thread);
+ auto stackTrace = GetStackTraceResponse(thread, format);
- ASSERT_TRUE(stackTrace.stackFrames[0].name == functionName);
+ ASSERT_TRUE(stackTrace.stackFrames[0].name == expectedName);
return true;
}
+bool testStackFrameNoFormatting()
+{
+ return testStackFrameFunctionName({}, "function_name");
+}
+
+bool testStackFrameFormatParameters()
+{
+ dap::StackFrameFormat format;
+ format.parameters = true;
+ return testStackFrameFunctionName(format, "function_name()");
+}
+
+bool testStackFrameFormatParameterValues()
+{
+ dap::StackFrameFormat format;
+ format.parameters = true;
+ format.parameterValues = true;
+ return testStackFrameFunctionName(format, "function_name(arg)");
+}
+
+bool testStackFrameFormatLine()
+{
+ dap::StackFrameFormat format;
+ format.line = true;
+ return testStackFrameFunctionName(format, "function_name Line: 10");
+}
+
int testDebuggerThread(int, char*[])
{
- return runTests({ testStackFrameFunctionName });
+ return runTests({ testStackFrameNoFormatting, testStackFrameFormatParameters,
+ testStackFrameFormatParameterValues,
+ testStackFrameFormatLine });
}
diff --git a/Tests/CMakeLib/testDebuggerVariablesHelper.cxx b/Tests/CMakeLib/testDebuggerVariablesHelper.cxx
index 5fe1c63..e3dbbce 100644
--- a/Tests/CMakeLib/testDebuggerVariablesHelper.cxx
+++ b/Tests/CMakeLib/testDebuggerVariablesHelper.cxx
@@ -74,9 +74,9 @@
std::make_shared<cmDebugger::cmDebuggerVariablesManager>();
cmPolicies::PolicyMap policyMap;
- policyMap.Set(cmPolicies::CMP0000, cmPolicies::NEW);
- policyMap.Set(cmPolicies::CMP0003, cmPolicies::WARN);
- policyMap.Set(cmPolicies::CMP0005, cmPolicies::OLD);
+ policyMap.Set(cmPolicies::CMP0178, cmPolicies::NEW);
+ policyMap.Set(cmPolicies::CMP0179, cmPolicies::WARN);
+ policyMap.Set(cmPolicies::CMP0180, cmPolicies::OLD);
auto vars = cmDebugger::cmDebuggerVariablesHelper::Create(
variablesManager, "Locals", true, policyMap);
@@ -84,9 +84,9 @@
variablesManager->HandleVariablesRequest(
CreateVariablesRequest(vars->GetId()));
ASSERT_TRUE(variables.size() == 3);
- ASSERT_VARIABLE(variables[0], "CMP0000", "NEW", "string");
- ASSERT_VARIABLE(variables[1], "CMP0003", "WARN", "string");
- ASSERT_VARIABLE(variables[2], "CMP0005", "OLD", "string");
+ ASSERT_VARIABLE(variables[0], "CMP0178", "NEW", "string");
+ ASSERT_VARIABLE(variables[1], "CMP0179", "WARN", "string");
+ ASSERT_VARIABLE(variables[2], "CMP0180", "OLD", "string");
return true;
}
diff --git a/Tests/CMakeLib/testDocumentationFormatter.cxx b/Tests/CMakeLib/testDocumentationFormatter.cxx
new file mode 100644
index 0000000..e332535
--- /dev/null
+++ b/Tests/CMakeLib/testDocumentationFormatter.cxx
@@ -0,0 +1,184 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include <cmDocumentationFormatter.h>
+
+#include "testCommon.h"
+
+namespace {
+using TestCases = std::initializer_list<std::pair<std::string, std::string>>;
+
+bool testPrintFormattedNoIndent()
+{
+ const TestCases testCases = {
+ { "", "" },
+ { "\n\n", "\n\n\n\n" },
+ { "\n \n\n", "\n\n \n\n\n\n" },
+ { "One line no EOL text", "One line no EOL text\n" },
+ { "One line with trailing spaces and no EOL ",
+ "One line with trailing spaces and no EOL\n" },
+ { "Short text. Two sentences.", "Short text. Two sentences.\n" },
+ { "Short text\non\nmultiple\nlines\n",
+ "Short text\n\non\n\nmultiple\n\nlines\n\n" },
+ { "Just one a very long word: "
+ "01234567890123456789012345678901234567890123456789012345"
+ "678901234567890123456789",
+ "Just one a very long "
+ "word:\n01234567890123456789012345678901234567890123456789012345"
+ "678901234567890123456789\n" },
+ { " Pre-formatted paragraph with the very long word stays the same: "
+ "0123456789012345678901234567890123456789012345678901234567890123456789",
+ " Pre-formatted paragraph with the very long word stays the same: "
+ "0123456789012345678901234567890123456789012345678901234567890123456789"
+ "\n" },
+ { " Two pre-formatted\n paragraphs w/o EOL",
+ " Two pre-formatted\n paragraphs w/o EOL\n" },
+ { " Two pre-formatted\n paragraphs w/ EOL\n",
+ " Two pre-formatted\n paragraphs w/ EOL\n\n" },
+ { "Extra spaces are removed. However, \n not in a "
+ "pre-formatted\n "
+ "paragraph",
+ "Extra spaces are removed. However,\n\n not in a pre-formatted\n "
+ "paragraph\n" },
+ { "This is the text paragraph longer than a pre-defined wrapping position "
+ "of the `cmDocumentationFormatter` class. And it's gonna be wrapped "
+ "over multiple lines!",
+ "This is the text paragraph longer than a pre-defined wrapping position "
+ "of the\n`cmDocumentationFormatter` class. And it's gonna be wrapped "
+ "over multiple\nlines!\n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces ",
+ "A normal paragraph, followed by ...\n\n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \nAnd another paragraph w/o EOL",
+ "A normal paragraph, followed by ...\n\n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \n\nAnd another paragraph w/o EOL\n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \nAnd another paragraph w/ EOL\n",
+ "A normal paragraph, followed by ...\n\n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \n\nAnd another paragraph w/ EOL\n\n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \nAnd another two\nparagraphs w/ EOL\n",
+ "A normal paragraph, followed by ...\n\n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \n\nAnd another two\n\nparagraphs w/ "
+ "EOL\n\n" }
+ };
+
+ cmDocumentationFormatter formatter;
+
+ for (auto& test : testCases) {
+ std::ostringstream out;
+ formatter.PrintFormatted(out, test.first);
+ auto actual = out.str();
+ ASSERT_EQUAL(actual, test.second);
+ }
+
+ return true;
+}
+
+bool testPrintFormattedIndent2()
+{
+ const TestCases testCases = {
+ { "", "" },
+ // BEGIN NOTE Empty lines are not indented.
+ { "\n\n", "\n\n\n\n" },
+ { "\n \n\n", "\n\n \n\n\n\n" },
+ // END NOTE
+ { "One line no EOL text", " One line no EOL text\n" },
+ { "Short text. Two sentences.", " Short text. Two sentences.\n" },
+ { "Short text\non\nmultiple\nlines\n",
+ " Short text\n\n on\n\n multiple\n\n lines\n\n" },
+ { "Just one a very long word: "
+ "01234567890123456789012345678901234567890123456789012345"
+ "678901234567890123456789",
+ " Just one a very long "
+ "word:\n 01234567890123456789012345678901234567890123456789012345"
+ "678901234567890123456789\n" },
+ { " Pre-formatted paragraph with the very long word stays the same: "
+ "0123456789012345678901234567890123456789012345678901234567890123456789",
+ " Pre-formatted paragraph with the very long word stays the same: "
+ "0123456789012345678901234567890123456789012345678901234567890123456789"
+ "\n" },
+ { "Extra spaces are removed. However, \n not in a "
+ "pre-formatted\n "
+ "paragraph",
+ " Extra spaces are removed. However,\n\n not in a "
+ "pre-formatted\n "
+ "paragraph\n" },
+ { "This is the text paragraph longer than a pre-defined wrapping position "
+ "of the `cmDocumentationFormatter` class. And it's gonna be wrapped "
+ "over multiple lines!",
+ " This is the text paragraph longer than a pre-defined wrapping "
+ "position of\n"
+ " the `cmDocumentationFormatter` class. And it's gonna be wrapped "
+ "over\n multiple lines!\n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces ",
+ " A normal paragraph, followed by ...\n\n Pre-formatted\n "
+ "paragraphs "
+ "with trailing whitespaces \n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \nAnd another paragraph w/o EOL",
+ " A normal paragraph, followed by ...\n\n Pre-formatted\n "
+ "paragraphs with trailing whitespaces \n\n And another paragraph "
+ "w/o EOL\n" },
+ { "A normal paragraph, followed by ... \n Pre-formatted\n paragraphs "
+ "with trailing whitespaces \nAnd another paragraph w/ EOL\n",
+ " A normal paragraph, followed by ...\n\n Pre-formatted\n "
+ "paragraphs with trailing whitespaces \n\n And another paragraph "
+ "w/ EOL\n\n" }
+ };
+
+ cmDocumentationFormatter formatter;
+ formatter.SetIndent(2);
+
+ for (auto& test : testCases) {
+ std::ostringstream out;
+ formatter.PrintFormatted(out, test.first);
+ auto actual = out.str();
+ ASSERT_EQUAL(actual, test.second);
+ }
+
+ return true;
+}
+
+bool testPrintFormattedIndent10()
+{
+ const TestCases testCases = {
+ { "", "" },
+ { "One line no EOL text", " One line no EOL text\n" },
+ { "This is the text paragraph longer than a pre-defined wrapping position "
+ "of the `cmDocumentationFormatter` class. And it's gonna be wrapped "
+ "over multiple lines!",
+ " This is the text paragraph longer than a pre-defined "
+ "wrapping\n"
+ " position of the `cmDocumentationFormatter` class. "
+ "And it's gonna\n"
+ " be wrapped over multiple lines!\n" }
+ };
+
+ cmDocumentationFormatter formatter;
+ formatter.SetIndent(10);
+
+ for (auto& test : testCases) {
+ std::ostringstream out;
+ formatter.PrintFormatted(out, test.first);
+ auto actual = out.str();
+ ASSERT_EQUAL(actual, test.second);
+ }
+
+ return true;
+}
+}
+
+int testDocumentationFormatter(int /*unused*/, char* /*unused*/[])
+{
+ return runTests({ testPrintFormattedNoIndent, testPrintFormattedIndent2,
+ testPrintFormattedIndent10 },
+ false);
+}
diff --git a/Tests/CMakeLib/testPathResolver.cxx b/Tests/CMakeLib/testPathResolver.cxx
new file mode 100644
index 0000000..4c4ff87
--- /dev/null
+++ b/Tests/CMakeLib/testPathResolver.cxx
@@ -0,0 +1,476 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include <cerrno>
+#include <map>
+#include <string>
+#include <utility>
+
+#include <cmsys/Status.hxx>
+
+#include "cmPathResolver.h"
+
+#ifdef _WIN32
+# include <cctype>
+
+# include "cmSystemTools.h"
+#endif
+
+#include "testCommon.h"
+
+// IWYU pragma: no_forward_declare cm::PathResolver::Policies::LogicalPath
+// IWYU pragma: no_forward_declare cm::PathResolver::Policies::NaivePath
+// IWYU pragma: no_forward_declare cm::PathResolver::Policies::RealPath
+
+namespace {
+
+class MockSystem : public cm::PathResolver::System
+{
+public:
+ ~MockSystem() override = default;
+
+ struct Path
+ {
+ std::string Name;
+ std::string Link;
+ };
+
+ std::map<std::string, Path> Paths;
+
+ void SetPaths(std::map<std::string, Path> paths)
+ {
+ this->Paths = std::move(paths);
+ }
+
+ static std::string AdjustCase(std::string const& path)
+ {
+#ifdef _WIN32
+ return cmSystemTools::LowerCase(path);
+#else
+ return path;
+#endif
+ }
+
+ cmsys::Status ReadSymlink(std::string const& path,
+ std::string& link) override
+ {
+ auto i = this->Paths.find(AdjustCase(path));
+ if (i == this->Paths.end()) {
+ return cmsys::Status::POSIX(ENOENT);
+ }
+ if (i->second.Link.empty()) {
+ return cmsys::Status::POSIX(EINVAL);
+ }
+ link = i->second.Link;
+ return cmsys::Status::Success();
+ }
+
+ bool PathExists(std::string const& path) override
+ {
+ return this->Paths.find(AdjustCase(path)) != this->Paths.end();
+ }
+
+ std::string WorkDir;
+
+ void SetWorkDir(std::string wd) { this->WorkDir = std::move(wd); }
+
+ std::string GetWorkingDirectory() override { return this->WorkDir; }
+
+#ifdef _WIN32
+ std::map<char, std::string> WorkDirOnDrive;
+
+ void SetWorkDirOnDrive(std::map<char, std::string> wd)
+ {
+ this->WorkDirOnDrive = std::move(wd);
+ }
+
+ std::string GetWorkingDirectoryOnDrive(char letter) override
+ {
+ std::string result;
+ auto i = this->WorkDirOnDrive.find(std::tolower(letter));
+ if (i != this->WorkDirOnDrive.end()) {
+ result = i->second;
+ }
+ return result;
+ }
+
+ cmsys::Status ReadName(std::string const& path, std::string& name) override
+ {
+ auto i = this->Paths.find(AdjustCase(path));
+ if (i == this->Paths.end()) {
+ return cmsys::Status::POSIX(ENOENT);
+ }
+ name = i->second.Name;
+ return cmsys::Status::Success();
+ }
+#endif
+};
+
+#define EXPECT_RESOLVE(_in, _expect) \
+ do { \
+ std::string out; \
+ ASSERT_TRUE(r.Resolve(_in, out)); \
+ ASSERT_EQUAL(out, _expect); \
+ } while (false)
+
+#define EXPECT_ENOENT(_in, _expect) \
+ do { \
+ std::string out; \
+ ASSERT_EQUAL(r.Resolve(_in, out).GetPOSIX(), ENOENT); \
+ ASSERT_EQUAL(out, _expect); \
+ } while (false)
+
+using namespace cm::PathResolver;
+
+bool posixRoot()
+{
+ std::cout << "posixRoot()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "/", { {}, {} } },
+ });
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("/", "/");
+ EXPECT_RESOLVE("//", "/");
+ EXPECT_RESOLVE("/.", "/");
+ EXPECT_RESOLVE("/./", "/");
+ EXPECT_RESOLVE("/..", "/");
+ EXPECT_RESOLVE("/../", "/");
+ return true;
+}
+
+bool posixAbsolutePath()
+{
+ std::cout << "posixAbsolutePath()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "/", { {}, {} } },
+ { "/a", { {}, {} } },
+ });
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("/a", "/a");
+ EXPECT_RESOLVE("/a/", "/a");
+ EXPECT_RESOLVE("/a//", "/a");
+ EXPECT_RESOLVE("/a/.", "/a");
+ EXPECT_RESOLVE("/a/./", "/a");
+ EXPECT_RESOLVE("/a/..", "/");
+ EXPECT_RESOLVE("/a/../", "/");
+ EXPECT_RESOLVE("/a/../..", "/");
+#ifndef _WIN32
+ EXPECT_RESOLVE("//a", "/a");
+#endif
+ return true;
+}
+
+bool posixWorkingDirectory()
+{
+ std::cout << "posixWorkingDirectory()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "/", { {}, {} } },
+ { "/a", { {}, {} } },
+ { "/cwd", { {}, {} } },
+ { "/cwd/a", { {}, {} } },
+ });
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("", "/");
+ EXPECT_RESOLVE(".", "/");
+ EXPECT_RESOLVE("..", "/");
+ EXPECT_RESOLVE("a", "/a");
+ os.SetWorkDir("/cwd");
+ EXPECT_RESOLVE("", "/cwd");
+ EXPECT_RESOLVE(".", "/cwd");
+ EXPECT_RESOLVE("..", "/");
+ EXPECT_RESOLVE("a", "/cwd/a");
+ return true;
+}
+
+bool posixSymlink()
+{
+ std::cout << "posixSymlink()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "/", { {}, {} } },
+ { "/link-a", { {}, "a" } },
+ { "/link-a-excess", { {}, "a//." } },
+ { "/link-broken", { {}, "link-broken-dest" } },
+ { "/a", { {}, {} } },
+ { "/a/b", { {}, {} } },
+ { "/a/link-b", { {}, "b" } },
+ { "/a/b/link-c", { {}, "c" } },
+ { "/a/b/c", { {}, {} } },
+ { "/a/b/c/link-..|..", { {}, "../.." } },
+ { "/a/link-|1|2", { {}, "/1/2" } },
+ { "/1", { {}, {} } },
+ { "/1/2", { {}, {} } },
+ { "/1/2/3", { {}, {} } },
+ });
+
+ {
+ Resolver<Policies::LogicalPath> const r(os);
+ EXPECT_RESOLVE("/link-a", "/link-a");
+ EXPECT_RESOLVE("/link-a-excess", "/link-a-excess");
+ EXPECT_RESOLVE("/link-a-excess/b", "/link-a-excess/b");
+ EXPECT_RESOLVE("/link-broken", "/link-broken");
+ EXPECT_RESOLVE("/link-a/../missing", "/missing");
+ EXPECT_RESOLVE("/a/b/link-c", "/a/b/link-c");
+ EXPECT_RESOLVE("/a/link-b/c", "/a/link-b/c");
+ EXPECT_RESOLVE("/a/link-b/link-c/..", "/a/link-b");
+ EXPECT_RESOLVE("/a/b/c/link-..|..", "/a/b/c/link-..|..");
+ EXPECT_RESOLVE("/a/b/c/link-..|../link-b", "/a/b/c/link-..|../link-b");
+ EXPECT_RESOLVE("/a/link-|1|2/3", "/a/link-|1|2/3");
+ EXPECT_RESOLVE("/a/link-|1|2/../2/3", "/1/2/3");
+ }
+
+ {
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("/link-a", "/a");
+ EXPECT_RESOLVE("/link-a-excess", "/a");
+ EXPECT_RESOLVE("/link-a-excess/b", "/a/b");
+ EXPECT_ENOENT("/link-broken", "/link-broken-dest");
+ EXPECT_ENOENT("/link-a/../missing", "/missing");
+ EXPECT_RESOLVE("/a/b/link-c", "/a/b/c");
+ EXPECT_RESOLVE("/a/link-b/c", "/a/b/c");
+ EXPECT_RESOLVE("/a/link-b/link-c/..", "/a/b");
+ EXPECT_RESOLVE("/a/b/c/link-..|..", "/a");
+ EXPECT_RESOLVE("/a/b/c/link-..|../link-b", "/a/b");
+ EXPECT_RESOLVE("/a/link-|1|2/3", "/1/2/3");
+ }
+
+ return true;
+}
+
+#ifdef _WIN32
+bool windowsRoot()
+{
+ std::cout << "windowsRoot()\n";
+ MockSystem os;
+ {
+ Resolver<Policies::NaivePath> const r(os);
+ EXPECT_RESOLVE("c:/", "c:/");
+ EXPECT_RESOLVE("C:/", "C:/");
+ EXPECT_RESOLVE("c://", "c:/");
+ EXPECT_RESOLVE("C:/.", "C:/");
+ EXPECT_RESOLVE("c:/./", "c:/");
+ EXPECT_RESOLVE("C:/..", "C:/");
+ EXPECT_RESOLVE("c:/../", "c:/");
+ }
+ os.SetPaths({
+ { "c:/", { {}, {} } },
+ { "//host/", { {}, {} } },
+ });
+ {
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("c:/", "C:/");
+ EXPECT_RESOLVE("C:/", "C:/");
+ EXPECT_RESOLVE("c://", "C:/");
+ EXPECT_RESOLVE("C:/.", "C:/");
+ EXPECT_RESOLVE("c:/./", "C:/");
+ EXPECT_RESOLVE("C:/..", "C:/");
+ EXPECT_RESOLVE("c:/../", "C:/");
+ EXPECT_RESOLVE("//host", "//host/");
+ EXPECT_RESOLVE("//host/.", "//host/");
+ EXPECT_RESOLVE("//host/./", "//host/");
+ EXPECT_RESOLVE("//host/..", "//host/");
+ EXPECT_RESOLVE("//host/../", "//host/");
+ }
+ return true;
+}
+
+bool windowsAbsolutePath()
+{
+ std::cout << "windowsAbsolutePath()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "c:/", { {}, {} } },
+ { "c:/a", { {}, {} } },
+ });
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("c:/a", "C:/a");
+ EXPECT_RESOLVE("c:/a/", "C:/a");
+ EXPECT_RESOLVE("c:/a//", "C:/a");
+ EXPECT_RESOLVE("c:/a/.", "C:/a");
+ EXPECT_RESOLVE("c:/a/./", "C:/a");
+ EXPECT_RESOLVE("c:/a/..", "C:/");
+ EXPECT_RESOLVE("c:/a/../", "C:/");
+ EXPECT_RESOLVE("c:/a/../..", "C:/");
+ return true;
+}
+
+bool windowsActualCase()
+{
+ std::cout << "windowsActualCase()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "c:/", { {}, {} } },
+ { "c:/mixed", { "MiXeD", {} } },
+ { "c:/mixed/link-mixed", { "LiNk-MiXeD", "mixed" } },
+ { "c:/mixed/mixed", { "MiXeD", {} } },
+ { "c:/mixed/link-c-mixed", { "LiNk-C-MiXeD", "C:/mIxEd" } },
+ { "c:/upper", { "UPPER", {} } },
+ { "c:/upper/link-upper", { "LINK-UPPER", "upper" } },
+ { "c:/upper/upper", { "UPPER", {} } },
+ { "c:/upper/link-c-upper", { "LINK-C-UPPER", "c:/upper" } },
+ });
+
+ {
+ Resolver<Policies::LogicalPath> const r(os);
+ EXPECT_RESOLVE("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG");
+ EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/LiNk-MiXeD");
+ EXPECT_RESOLVE("c:/mIxEd/link-c-MiXeD", "C:/MiXeD/LiNk-C-MiXeD");
+ EXPECT_RESOLVE("c:/upper/mIsSiNg", "C:/UPPER/mIsSiNg");
+ EXPECT_RESOLVE("c:/upper/link-upper", "C:/UPPER/LINK-UPPER");
+ EXPECT_RESOLVE("c:/upper/link-c-upper", "C:/UPPER/LINK-C-UPPER");
+ }
+
+ {
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_ENOENT("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG");
+ EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/MiXeD");
+ EXPECT_RESOLVE("c:/mIxEd/link-c-MiXeD", "C:/MiXeD");
+ EXPECT_ENOENT("c:/upper/mIsSiNg", "C:/UPPER/mIsSiNg");
+ EXPECT_RESOLVE("c:/upper/link-upper", "C:/UPPER/UPPER");
+ EXPECT_RESOLVE("c:/upper/link-c-upper", "C:/UPPER");
+ }
+
+ return true;
+}
+
+bool windowsWorkingDirectory()
+{
+ std::cout << "windowsWorkingDirectory()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "c:/", { {}, {} } },
+ { "c:/a", { {}, {} } },
+ { "c:/cwd", { {}, {} } },
+ { "c:/cwd/a", { {}, {} } },
+ });
+ {
+ Resolver<Policies::LogicalPath> const r(os);
+ EXPECT_RESOLVE("", "/");
+ EXPECT_RESOLVE(".", "/");
+ EXPECT_RESOLVE("..", "/");
+ EXPECT_RESOLVE("a", "/a");
+ }
+ {
+ Resolver<Policies::RealPath> const r(os);
+ os.SetWorkDir("c:/cwd");
+ EXPECT_RESOLVE("", "C:/cwd");
+ EXPECT_RESOLVE(".", "C:/cwd");
+ EXPECT_RESOLVE("..", "C:/");
+ EXPECT_RESOLVE("a", "C:/cwd/a");
+ EXPECT_ENOENT("missing", "C:/cwd/missing");
+ }
+ return true;
+}
+
+bool windowsWorkingDirectoryOnDrive()
+{
+ std::cout << "windowsWorkingDirectoryOnDrive()\n";
+ MockSystem os;
+ os.SetWorkDir("c:/cwd");
+ os.SetWorkDirOnDrive({
+ { 'd', "d:/cwd-d" },
+ });
+ {
+ Resolver<Policies::NaivePath> const r(os);
+ EXPECT_RESOLVE("c:", "c:/cwd");
+ EXPECT_RESOLVE("c:.", "c:/cwd");
+ EXPECT_RESOLVE("c:..", "c:/");
+ EXPECT_RESOLVE("C:", "C:/cwd");
+ EXPECT_RESOLVE("C:.", "C:/cwd");
+ EXPECT_RESOLVE("C:..", "C:/");
+ EXPECT_RESOLVE("d:", "d:/cwd-d");
+ EXPECT_RESOLVE("d:.", "d:/cwd-d");
+ EXPECT_RESOLVE("d:..", "d:/");
+ EXPECT_RESOLVE("D:", "D:/cwd-d");
+ EXPECT_RESOLVE("D:.", "D:/cwd-d");
+ EXPECT_RESOLVE("D:..", "D:/");
+ EXPECT_RESOLVE("e:", "e:/");
+ EXPECT_RESOLVE("e:.", "e:/");
+ EXPECT_RESOLVE("e:..", "e:/");
+ EXPECT_RESOLVE("E:", "E:/");
+ EXPECT_RESOLVE("E:.", "E:/");
+ EXPECT_RESOLVE("E:..", "E:/");
+ }
+ os.SetPaths({
+ { "c:/", { {}, {} } },
+ { "c:/cwd", { {}, {} } },
+ { "c:/cwd/existing", { {}, {} } },
+ { "d:/", { {}, {} } },
+ { "d:/cwd-d", { {}, {} } },
+ { "d:/cwd-d/existing", { {}, {} } },
+ { "e:/", { {}, {} } },
+ });
+ {
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("c:existing", "C:/cwd/existing");
+ EXPECT_ENOENT("c:missing", "C:/cwd/missing");
+ EXPECT_RESOLVE("C:existing", "C:/cwd/existing");
+ EXPECT_ENOENT("C:missing", "C:/cwd/missing");
+ EXPECT_RESOLVE("d:existing", "D:/cwd-d/existing");
+ EXPECT_ENOENT("d:missing", "D:/cwd-d/missing");
+ EXPECT_ENOENT("e:missing", "E:/missing");
+ EXPECT_ENOENT("f:", "F:/");
+ }
+ return true;
+}
+
+bool windowsNetworkShare()
+{
+ std::cout << "windowsNetworkShare()\n";
+ MockSystem os;
+ os.SetPaths({
+ { "c:/", { {}, {} } },
+ { "c:/cwd", { {}, {} } },
+ { "c:/cwd/link-to-host-share", { {}, "//host/share" } },
+ { "//host/", { {}, {} } },
+ { "//host/share", { {}, {} } },
+ });
+ os.SetWorkDir("c:/cwd");
+ {
+ Resolver<Policies::RealPath> const r(os);
+ EXPECT_RESOLVE("//host/share", "//host/share");
+ EXPECT_RESOLVE("//host/share/", "//host/share");
+ EXPECT_RESOLVE("//host/share/.", "//host/share");
+ EXPECT_RESOLVE("//host/share/./", "//host/share");
+ EXPECT_RESOLVE("//host/share/..", "//host/");
+ EXPECT_RESOLVE("//host/share/../", "//host/");
+ EXPECT_RESOLVE("//host/share/../..", "//host/");
+ EXPECT_RESOLVE("link-to-host-share", "//host/share");
+ EXPECT_RESOLVE("link-to-host-share/..", "//host/");
+ EXPECT_ENOENT("link-to-host-share/../missing", "//host/missing");
+ }
+
+ {
+ Resolver<Policies::LogicalPath> const r(os);
+ EXPECT_RESOLVE("link-to-host-share", "C:/cwd/link-to-host-share");
+ EXPECT_RESOLVE("link-to-host-share/..", "//host/");
+ EXPECT_RESOLVE("link-to-host-share/../missing", "//host/missing");
+ }
+ return true;
+}
+#endif
+
+}
+
+int testPathResolver(int /*unused*/, char* /*unused*/[])
+{
+ return runTests({
+ posixRoot,
+ posixAbsolutePath,
+ posixWorkingDirectory,
+ posixSymlink,
+#ifdef _WIN32
+ windowsRoot,
+ windowsAbsolutePath,
+ windowsActualCase,
+ windowsWorkingDirectory,
+ windowsWorkingDirectoryOnDrive,
+ windowsNetworkShare,
+#endif
+ });
+}
diff --git a/Tests/CMakeLib/testStringAlgorithms.cxx b/Tests/CMakeLib/testStringAlgorithms.cxx
index 78442ba..4d418b4 100644
--- a/Tests/CMakeLib/testStringAlgorithms.cxx
+++ b/Tests/CMakeLib/testStringAlgorithms.cxx
@@ -10,6 +10,7 @@
#include <vector>
#include <cm/string_view>
+#include <cmext/string_view>
#include "cmStringAlgorithms.h"
@@ -103,7 +104,9 @@
{
typedef std::vector<std::string> VT;
assert_ok(cmTokenize("", ";") == VT{ "" }, "cmTokenize empty");
- assert_ok(cmTokenize(";", ";") == VT{ "" }, "cmTokenize sep");
+ assert_ok(cmTokenize(";", ";") == VT{ "" }, "cmTokenize sep (char*)");
+ assert_ok(cmTokenize(";", ";"_s) == VT{ "" },
+ "cmTokenize sep (string_view)");
assert_ok(cmTokenize("abc", ";") == VT{ "abc" }, "cmTokenize item");
assert_ok(cmTokenize("abc;", ";") == VT{ "abc" }, "cmTokenize item sep");
assert_ok(cmTokenize(";abc", ";") == VT{ "abc" }, "cmTokenize sep item");
@@ -112,6 +115,22 @@
assert_ok(cmTokenize("a1;a2;a3;a4", ";") == VT{ "a1", "a2", "a3", "a4" },
"cmTokenize multiple items");
}
+ {
+ typedef std::vector<cm::string_view> VT;
+ assert_ok(cmTokenizedView("", ';') == VT{ "" }, "cmTokenizedView empty");
+ assert_ok(cmTokenizedView(";", ';') == VT{ "" }, "cmTokenizedView sep");
+ assert_ok(cmTokenizedView("abc", ';') == VT{ "abc" },
+ "cmTokenizedView item");
+ assert_ok(cmTokenizedView("abc;", ';') == VT{ "abc" },
+ "cmTokenizedView item sep");
+ assert_ok(cmTokenizedView(";abc", ';') == VT{ "abc" },
+ "cmTokenizedView sep item");
+ assert_ok(cmTokenizedView("abc;;efg", ';') == VT{ "abc", "efg" },
+ "cmTokenizedView item sep sep item");
+ assert_ok(cmTokenizedView("a1;a2;a3;a4", ';') ==
+ VT{ "a1", "a2", "a3", "a4" },
+ "cmTokenizedView multiple items");
+ }
// ----------------------------------------------------------------------
// Test cmStrCat
diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx
index 1b4adb7..29ee765 100644
--- a/Tests/CMakeLib/testUVProcessChainHelper.cxx
+++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx
@@ -7,7 +7,7 @@
#include <string>
#include <thread>
-#include "cmSystemTools.h"
+#include "cmsys/SystemTools.hxx"
#ifdef _WIN32
# include <windows.h>
@@ -73,7 +73,7 @@
#endif
}
if (command == "pwd") {
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
std::cout << cwd << std::flush;
return 0;
}
diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx
index af06a8e..1f42727 100644
--- a/Tests/CMakeLib/testUVStreambuf.cxx
+++ b/Tests/CMakeLib/testUVStreambuf.cxx
@@ -106,6 +106,9 @@
options.file = cmakeCommand;
options.args = const_cast<char**>(processArgs.data());
options.flags = UV_PROCESS_WINDOWS_HIDE;
+#if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV)
+ options.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE;
+#endif
options.stdio = stdio.data();
options.stdio_count = static_cast<int>(stdio.size());
options.exit_cb = [](uv_process_t* handle, int64_t exitStatus,
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 428ec8b..f102bb4 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -351,7 +351,7 @@
# add a bunch of standard build-and-test style tests
ADD_TEST_MACRO(CommandLineTest CommandLineTest)
- ADD_TEST_MACRO(FindPackageTest FindPackageTest)
+ ADD_TEST_MACRO(FindPackageCMakeTest FindPackageCMakeTest)
ADD_TEST_MACRO(StringFileTest StringFileTest)
ADD_TEST_MACRO(TryCompile TryCompile)
ADD_TEST_MACRO(SystemInformation SystemInformation)
@@ -663,7 +663,6 @@
${build_generator_args}
--build-project ExternalDataTest
--build-noclean
- --force-new-ctest-process
--build-options
-DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
--test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
@@ -1383,7 +1382,6 @@
${build_generator_args}
--build-project EnvironmentProj
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Environment"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment")
@@ -1422,7 +1420,6 @@
${build_generator_args}
--build-project Qt4Targets
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Targets"
- --force-new-ctest-process
--build-options
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
--test-command ${CMAKE_CTEST_COMMAND} -V
@@ -1437,7 +1434,6 @@
${build_generator_args}
--build-project Qt4And5Automoc
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocForward"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocForward")
@@ -1448,7 +1444,6 @@
${build_generator_args}
--build-project Qt4And5Automoc
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse"
- --force-new-ctest-process
--build-options -DQT_REVERSE_FIND_ORDER=1
--test-command ${CMAKE_CTEST_COMMAND} -V
)
@@ -1645,7 +1640,6 @@
${build_generator_args}
--build-project ExternalProjectTest
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProject"
- --force-new-ctest-process
--build-options ${ExternalProject_BUILD_OPTIONS}
--test-command ${CMAKE_CTEST_COMMAND} -V
)
@@ -1662,7 +1656,6 @@
"${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir"
${build_generator_args}
--build-project ExternalProjectSubdir
- --force-new-ctest-process
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir")
@@ -1673,7 +1666,6 @@
"${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdir"
${build_generator_args}
--build-project ExternalProjectSourceSubdir
- --force-new-ctest-process
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdir")
@@ -1684,7 +1676,6 @@
"${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake"
${build_generator_args}
--build-project ExternalProjectSourceSubdirNotCMake
- --force-new-ctest-process
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake")
@@ -1695,7 +1686,6 @@
${build_generator_args}
--build-project ExternalProjectLocalTest
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal")
@@ -1710,7 +1700,6 @@
${build_generator_args}
--build-project ExternalProjectUpdateTest
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate")
@@ -1766,7 +1755,6 @@
${build_generator_args}
--build-project superpro
--build-exe-dir "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}"
- --force-new-ctest-process
--build-options
${_maybe_BUILD_OPTIONS}
"-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}/install"
@@ -2363,7 +2351,6 @@
--build-generator "Green Hills MULTI"
--build-project test
--build-config $<CONFIGURATION>
- --force-new-ctest-process
--build-options ${ghs_target_arch} ${ghs_toolset_name} ${ghs_toolset_root} ${ghs_target_platform}
${ghs_os_root} ${ghs_os_dir} ${ghs_bsp_name} ${_ghs_build_opts} ${_ghs_toolset_extra}
${_ghs_test_command}
@@ -2577,7 +2564,6 @@
${build_generator_args}
--build-project TestsWorkingDirectoryProj
--build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory")
@@ -2589,9 +2575,9 @@
# A simple test for ctest in script mode
configure_file("${CMake_SOURCE_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake" @ONLY)
-# add_test(CTest.ScriptMode ${CMAKE_CTEST_COMMAND}
-# -S "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake"
-# )
+ add_test(CTest.ScriptMode ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake"
+ )
# Test CTest Update with Subversion
if(NOT DEFINED CMake_TEST_CTestUpdate_SVN OR CMake_TEST_CTestUpdate_SVN)
@@ -3032,7 +3018,6 @@
)
if(NOT BORLAND)
- set(CTestLimitDashJ_CTEST_OPTIONS --force-new-ctest-process)
add_test_macro(CTestLimitDashJ ${CMAKE_CTEST_COMMAND} -j 4
--output-on-failure -C "\${CTestTest_CONFIG}")
endif()
diff --git a/Tests/CPackComponentsForAll/CMakeLists.txt b/Tests/CPackComponentsForAll/CMakeLists.txt
index a1a9709..253a035 100644
--- a/Tests/CPackComponentsForAll/CMakeLists.txt
+++ b/Tests/CPackComponentsForAll/CMakeLists.txt
@@ -7,7 +7,7 @@
# Depending on the CPack generator and on some CPACK_xxx var values
# the generator may produce a single (NSIS, productbuild)
# or several package files (Archive Generators, RPM, DEB)
-cmake_minimum_required(VERSION 2.8.3.20101130 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(CPackComponentsForAll)
# Use GNUInstallDirs in order to enforce lib64 if needed
diff --git a/Tests/CTestConfig/ScriptWithArgs.cmake b/Tests/CTestConfig/ScriptWithArgs.cmake
index 79896a7..4d63e22 100644
--- a/Tests/CTestConfig/ScriptWithArgs.cmake
+++ b/Tests/CTestConfig/ScriptWithArgs.cmake
@@ -1,5 +1,3 @@
-set(CTEST_RUN_CURRENT_SCRIPT 0)
-
macro(check_arg name expected_value)
message("${name}='${${name}}'")
if(NOT "${${name}}" STREQUAL "${expected_value}")
diff --git a/Tests/CTestLimitDashJ/CreateSleepDelete.cmake b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake
index b09307f..f16deaa 100644
--- a/Tests/CTestLimitDashJ/CreateSleepDelete.cmake
+++ b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake
@@ -1,5 +1,3 @@
-set(CTEST_RUN_CURRENT_SCRIPT 0)
-
if(NOT DEFINED basefilename)
message(FATAL_ERROR "pass -Dbasefilename=f1")
endif()
diff --git a/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in b/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in
index 45f0e37..5ff1bf2 100644
--- a/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in
+++ b/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in
@@ -6,9 +6,3 @@
if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_CMAKE_SYSTEM_NAME}")
message(FATAL_ERROR "Error: CMAKE_SYSTEM_NAME is \"${CMAKE_SYSTEM_NAME}\", but should be \"@CMAKE_SYSTEM_NAME@\"")
endif()
-
-# this seems to be necessary, otherwise ctest complains that these
-# variables are not set:
-set(CTEST_COMMAND "\"@CMAKE_CTEST_COMMAND@\"")
-set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestScriptMode/")
-set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestScriptMode/")
diff --git a/Tests/CTestTest/test.cmake.in b/Tests/CTestTest/test.cmake.in
index 23166a7..61d30a6 100644
--- a/Tests/CTestTest/test.cmake.in
+++ b/Tests/CTestTest/test.cmake.in
@@ -43,12 +43,6 @@
CMAKE_GENERATOR:INTERNAL=@CMAKE_GENERATOR@
CMAKE_GENERATOR_PLATFORM:INTERNAL=@CMAKE_GENERATOR_PLATFORM@
CMAKE_GENERATOR_TOOLSET:INTERNAL=@CMAKE_GENERATOR_TOOLSET@
-CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
-CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
-CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@
-CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@
-CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@
-CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
DART_ROOT:PATH=
MEMORYCHECK_COMMAND:STRING=@MEMORYCHECK_COMMAND@
MEMORYCHECK_SUPPRESSIONS_FILE:FILEPATH=@MEMORYCHECK_SUPPRESSIONS_FILE@
diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in
index 6d833fe..48fd82a 100644
--- a/Tests/CTestTest2/test.cmake.in
+++ b/Tests/CTestTest2/test.cmake.in
@@ -28,12 +28,6 @@
#CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
-CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
-CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
-CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@
-CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@
-CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@
-CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
KWSYS_ENCODING_DEFAULT_CODEPAGE:STRING=CP_UTF8
# This one is needed for testing advanced ctest features
diff --git a/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in b/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in
index 3f8437c..e71d514 100644
--- a/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in
+++ b/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in
@@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.10)
-set(CTEST_RUN_CURRENT_SCRIPT 0)
-
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestEmptyBinaryDirectory")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestEmptyBinaryDirectory")
diff --git a/Tests/CTestTestLaunchers/test.cmake.in b/Tests/CTestTestLaunchers/test.cmake.in
index 21a3ed4..3c99857 100644
--- a/Tests/CTestTestLaunchers/test.cmake.in
+++ b/Tests/CTestTestLaunchers/test.cmake.in
@@ -22,15 +22,6 @@
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
- file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
- CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
- CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
- CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@
- CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@
- CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@
- CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
- ")
-
ctest_start(Experimental)
ctest_configure(OPTIONS "-DCTEST_USE_LAUNCHERS=1")
ctest_build(NUMBER_ERRORS error_count)
diff --git a/Tests/CTestTestRunScript/hello.cmake.in b/Tests/CTestTestRunScript/hello.cmake.in
index 37905e3..4fa6446 100644
--- a/Tests/CTestTestRunScript/hello.cmake.in
+++ b/Tests/CTestTestRunScript/hello.cmake.in
@@ -1,2 +1 @@
-set(CTEST_RUN_CURRENT_SCRIPT 0)
message("hello world")
diff --git a/Tests/CTestTestRunScript/test.cmake.in b/Tests/CTestTestRunScript/test.cmake.in
index 3074a51..9e50f7f 100644
--- a/Tests/CTestTestRunScript/test.cmake.in
+++ b/Tests/CTestTestRunScript/test.cmake.in
@@ -1,2 +1 @@
-set(CTEST_RUN_CURRENT_SCRIPT 0)
CTEST_RUN_SCRIPT("CTestTestRunScript/hello.cmake" RETURN_VALUE res RETURN_VALUE)
diff --git a/Tests/CTestTestSerialInDepends/test.ctest b/Tests/CTestTestSerialInDepends/test.ctest
index cf0d314..71c6da2 100644
--- a/Tests/CTestTestSerialInDepends/test.ctest
+++ b/Tests/CTestTestSerialInDepends/test.ctest
@@ -1,5 +1,3 @@
-set(CTEST_RUN_CURRENT_SCRIPT 0)
-
set(LOCK_FILE "${TEST_NAME}.lock")
# Delete the old lock file in case it's lingering from a previous failed test run
diff --git a/Tests/CTestTestUpload/sleep.c b/Tests/CTestTestUpload/sleep.c
index b9b6e89..2d69f7f 100644
--- a/Tests/CTestTestUpload/sleep.c
+++ b/Tests/CTestTestUpload/sleep.c
@@ -1,3 +1,5 @@
+#include <stdlib.h>
+
#if defined(_WIN32)
# include <windows.h>
#else
diff --git a/Tests/Complex/Executable/Included.cmake b/Tests/Complex/Executable/Included.cmake
index 520a68b..3c7ec8b 100644
--- a/Tests/Complex/Executable/Included.cmake
+++ b/Tests/Complex/Executable/Included.cmake
@@ -1,2 +1 @@
get_directory_property(LF_VALUE LISTFILE_STACK)
-
diff --git a/Tests/Complex/cmTestConfigure.h.in b/Tests/Complex/cmTestConfigure.h.in
index 72317bc..96045d1 100644
--- a/Tests/Complex/cmTestConfigure.h.in
+++ b/Tests/Complex/cmTestConfigure.h.in
@@ -77,4 +77,3 @@
// test parenthesis in conditionals
#cmakedefine CONDITIONAL_PARENTHESES
-
diff --git a/Tests/ComplexOneConfig/Executable/Included.cmake b/Tests/ComplexOneConfig/Executable/Included.cmake
index 520a68b..3c7ec8b 100644
--- a/Tests/ComplexOneConfig/Executable/Included.cmake
+++ b/Tests/ComplexOneConfig/Executable/Included.cmake
@@ -1,2 +1 @@
get_directory_property(LF_VALUE LISTFILE_STACK)
-
diff --git a/Tests/ComplexOneConfig/cmTestConfigure.h.in b/Tests/ComplexOneConfig/cmTestConfigure.h.in
index 72317bc..96045d1 100644
--- a/Tests/ComplexOneConfig/cmTestConfigure.h.in
+++ b/Tests/ComplexOneConfig/cmTestConfigure.h.in
@@ -77,4 +77,3 @@
// test parenthesis in conditionals
#cmakedefine CONDITIONAL_PARENTHESES
-
diff --git a/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt b/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt
index f7308e8..d1c6046 100644
--- a/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt
+++ b/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt
@@ -10,4 +10,3 @@
)
add_library(GeneratedHeader main.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
-
diff --git a/Tests/CustomCommand/foo.in b/Tests/CustomCommand/foo.in
index 15d2d2c..69bb6cb 100644
--- a/Tests/CustomCommand/foo.in
+++ b/Tests/CustomCommand/foo.in
@@ -29,4 +29,3 @@
return -1;
}
-
diff --git a/Tests/CustomCommandWorkingDirectory/working.c.in b/Tests/CustomCommandWorkingDirectory/working.c.in
index cf75bd1..e026ff1 100644
--- a/Tests/CustomCommandWorkingDirectory/working.c.in
+++ b/Tests/CustomCommandWorkingDirectory/working.c.in
@@ -4,4 +4,3 @@
{
return customTarget();
}
-
diff --git a/Tests/Dependency/Case1/CMakeLists.txt b/Tests/Dependency/Case1/CMakeLists.txt
index 4c5fc20..da9f54c 100644
--- a/Tests/Dependency/Case1/CMakeLists.txt
+++ b/Tests/Dependency/Case1/CMakeLists.txt
@@ -16,4 +16,3 @@
add_executable(hello main.c)
target_link_libraries(hello case1c case1b case1d case1c)
-
diff --git a/Tests/Dependency/Eight/CMakeLists.txt b/Tests/Dependency/Eight/CMakeLists.txt
index db5e2df..6e761d6 100644
--- a/Tests/Dependency/Eight/CMakeLists.txt
+++ b/Tests/Dependency/Eight/CMakeLists.txt
@@ -1,3 +1,2 @@
add_library( Eight EightSrc.c )
target_link_libraries( Eight Seven )
-
diff --git a/Tests/Dependency/Exec/CMakeLists.txt b/Tests/Dependency/Exec/CMakeLists.txt
index a920685..417477a 100644
--- a/Tests/Dependency/Exec/CMakeLists.txt
+++ b/Tests/Dependency/Exec/CMakeLists.txt
@@ -4,4 +4,3 @@
link_libraries( NoDepB NoDepC NoDepA SixB SixA )
add_executable( exec ExecMain.c )
-
diff --git a/Tests/Dependency/Exec2/CMakeLists.txt b/Tests/Dependency/Exec2/CMakeLists.txt
index 04d6fe8..ae439c5 100644
--- a/Tests/Dependency/Exec2/CMakeLists.txt
+++ b/Tests/Dependency/Exec2/CMakeLists.txt
@@ -9,4 +9,3 @@
link_libraries( Eight Five )
add_executable( exec2 ExecMain.c )
-
diff --git a/Tests/Dependency/Exec3/CMakeLists.txt b/Tests/Dependency/Exec3/CMakeLists.txt
index 605fbc9..7f981d6 100644
--- a/Tests/Dependency/Exec3/CMakeLists.txt
+++ b/Tests/Dependency/Exec3/CMakeLists.txt
@@ -3,4 +3,3 @@
link_libraries( Five Two Eight Five )
add_executable( exec3 ExecMain.c )
-
diff --git a/Tests/Dependency/Exec4/CMakeLists.txt b/Tests/Dependency/Exec4/CMakeLists.txt
index 94c6bf5..036d5e8 100644
--- a/Tests/Dependency/Exec4/CMakeLists.txt
+++ b/Tests/Dependency/Exec4/CMakeLists.txt
@@ -3,4 +3,3 @@
link_libraries( Five Two Five )
add_executable( exec4 ExecMain.c )
-
diff --git a/Tests/Dependency/Five/CMakeLists.txt b/Tests/Dependency/Five/CMakeLists.txt
index 19c1c77..03b3d01 100644
--- a/Tests/Dependency/Five/CMakeLists.txt
+++ b/Tests/Dependency/Five/CMakeLists.txt
@@ -1,3 +1,2 @@
add_library( Five FiveSrc.c )
target_link_libraries( Five Two )
-
diff --git a/Tests/Dependency/Seven/CMakeLists.txt b/Tests/Dependency/Seven/CMakeLists.txt
index 7fba55c..c5c585b 100644
--- a/Tests/Dependency/Seven/CMakeLists.txt
+++ b/Tests/Dependency/Seven/CMakeLists.txt
@@ -1,3 +1,2 @@
add_library( Seven SevenSrc.c )
target_link_libraries( Seven Two )
-
diff --git a/Tests/Dependency/Six/CMakeLists.txt b/Tests/Dependency/Six/CMakeLists.txt
index db12051..05eecdb 100644
--- a/Tests/Dependency/Six/CMakeLists.txt
+++ b/Tests/Dependency/Six/CMakeLists.txt
@@ -9,4 +9,3 @@
add_library( SixB SixBSrc.c )
target_link_libraries( SixB Four )
-
diff --git a/Tests/Dependency/Three/CMakeLists.txt b/Tests/Dependency/Three/CMakeLists.txt
index 3897f0c..4880243 100644
--- a/Tests/Dependency/Three/CMakeLists.txt
+++ b/Tests/Dependency/Three/CMakeLists.txt
@@ -1,3 +1,2 @@
add_library( Three ThreeSrc.c )
target_link_libraries( Three One Four )
-
diff --git a/Tests/EmptyProperty/CMakeLists.txt b/Tests/EmptyProperty/CMakeLists.txt
index 39e75f3..b6f393c 100644
--- a/Tests/EmptyProperty/CMakeLists.txt
+++ b/Tests/EmptyProperty/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
project (EmptyProperty)
set_property(DIRECTORY APPEND
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index 3d00673..1208152 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -168,7 +168,7 @@
ExternalProject_Add(${proj}
SOURCE_DIR ${local_cvs_repo}
URL ${CMAKE_CURRENT_SOURCE_DIR}/cvsrepo.tgz
- URL_MD5 55fc85825ffdd9ed2597123c68b79f7e
+ URL_MD5 287399370738adfe932e036cbe38d5b0
BUILD_COMMAND ""
CONFIGURE_COMMAND "${CVS_EXECUTABLE}" --version
INSTALL_COMMAND ""
@@ -190,11 +190,11 @@
# CVS by date stamp:
#
- set(proj TutorialStep1-CVS-20090626)
+ set(proj TutorialStep1-CVS-20241115)
ExternalProject_Add(${proj}
CVS_REPOSITORY ":local:${local_cvs_repo}"
CVS_MODULE "TutorialStep1"
- CVS_TAG "-D2009-06-26 16:50:00 UTC"
+ CVS_TAG "-D2024-11-15 23:11:00 UTC"
UPDATE_COMMAND ""
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
@@ -229,7 +229,7 @@
INSTALL_COMMAND ""
DEPENDS "SetupLocalCVSRepository"
DEPENDS "EmptyNoOpProject"
- DEPENDS "TutorialStep1-CVS-20090626"
+ DEPENDS "TutorialStep1-CVS-20241115"
DEPENDS "TutorialStep1-CVS-testtag1"
)
set_property(TARGET ${proj} PROPERTY FOLDER "CVS")
@@ -248,7 +248,7 @@
ExternalProject_Add(${proj}
SOURCE_DIR ${local_svn_repo}
URL ${CMAKE_CURRENT_SOURCE_DIR}/svnrepo.tgz
- URL_MD5 2f468be4ed1fa96377fca0cc830819c4
+ URL_MD5 0d75c80611c998e36c36f4a9e1e739d0
BUILD_COMMAND ""
CONFIGURE_COMMAND "${Subversion_SVN_EXECUTABLE}" --version
INSTALL_COMMAND ""
@@ -258,10 +258,10 @@
# SVN by date stamp:
#
- set(proj TutorialStep1-SVN-20090626)
+ set(proj TutorialStep1-SVN-20241115)
ExternalProject_Add(${proj}
SVN_REPOSITORY "${local_svn_repo_url}"
- SVN_REVISION "-r{2009-06-26 16:50:00 +0000}"
+ SVN_REVISION "-r{2024-11-15 23:23:00 +0000}"
UPDATE_COMMAND ""
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
@@ -272,10 +272,10 @@
# SVN by revision number:
#
- set(proj TutorialStep1-SVN-r2)
+ set(proj TutorialStep1-SVN-r3)
ExternalProject_Add(${proj}
SVN_REPOSITORY "${local_svn_repo_url}"
- SVN_REVISION "-r2"
+ SVN_REVISION "-r3"
UPDATE_COMMAND ""
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
@@ -320,7 +320,7 @@
set(proj TutorialStep1-GIT-byhash)
ExternalProject_Add(${proj}
GIT_REPOSITORY "${local_git_repo}"
- GIT_TAG 57418671a0a0e371e7bac532337152595fbe0df5 # generated by gitrepo.bash
+ GIT_TAG 4ed00009457732fc8b6d75f6159bbc384119c3d1 # generated by gitrepo.bash
UPDATE_COMMAND ""
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
@@ -568,7 +568,7 @@
set(proj TutorialStep1-HG-byhash)
ExternalProject_Add(${proj}
HG_REPOSITORY "${local_hg_repo}"
- HG_TAG dd2ce38a6b8a
+ HG_TAG fc5a0c915390
UPDATE_COMMAND ""
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
@@ -621,8 +621,8 @@
# BuildTree tests:
#
if(EP_TEST_CVS)
- add_test(TutorialStep1-CVS-20090626-BuildTreeTest
- "${binary_base}/TutorialStep1-CVS-20090626/Tutorial" 4)
+ add_test(TutorialStep1-CVS-20241115-BuildTreeTest
+ "${binary_base}/TutorialStep1-CVS-20241115/Tutorial" 4)
add_test(TutorialStep1-CVS-testtag1-BuildTreeTest
"${binary_base}/TutorialStep1-CVS-testtag1/Tutorial" 64)
@@ -632,11 +632,11 @@
endif()
if(EP_TEST_SVN)
- add_test(TutorialStep1-SVN-20090626-BuildTreeTest
- "${binary_base}/TutorialStep1-SVN-20090626/Tutorial" 100)
+ add_test(TutorialStep1-SVN-20241115-BuildTreeTest
+ "${binary_base}/TutorialStep1-SVN-20241115/Tutorial" 100)
- add_test(TutorialStep1-SVN-r2-BuildTreeTest
- "${binary_base}/TutorialStep1-SVN-r2/Tutorial" 99)
+ add_test(TutorialStep1-SVN-r3-BuildTreeTest
+ "${binary_base}/TutorialStep1-SVN-r3/Tutorial" 99)
add_test(TutorialStep1-SVN-trunk-BuildTreeTest
"${binary_base}/TutorialStep1-SVN-trunk/Tutorial" 98)
diff --git a/Tests/ExternalProject/cvsrepo.tgz b/Tests/ExternalProject/cvsrepo.tgz
index baba6d3..25bb7c3 100644
--- a/Tests/ExternalProject/cvsrepo.tgz
+++ b/Tests/ExternalProject/cvsrepo.tgz
Binary files differ
diff --git a/Tests/ExternalProject/gitrepo-sub-rec.tgz b/Tests/ExternalProject/gitrepo-sub-rec.tgz
index 0e63651..838d212 100644
--- a/Tests/ExternalProject/gitrepo-sub-rec.tgz
+++ b/Tests/ExternalProject/gitrepo-sub-rec.tgz
Binary files differ
diff --git a/Tests/ExternalProject/gitrepo-sub.tgz b/Tests/ExternalProject/gitrepo-sub.tgz
index ab34fff..20ec5b8 100644
--- a/Tests/ExternalProject/gitrepo-sub.tgz
+++ b/Tests/ExternalProject/gitrepo-sub.tgz
Binary files differ
diff --git a/Tests/ExternalProject/gitrepo.bash b/Tests/ExternalProject/gitrepo.bash
index c341f28..fd03c81 100755
--- a/Tests/ExternalProject/gitrepo.bash
+++ b/Tests/ExternalProject/gitrepo.bash
@@ -13,6 +13,9 @@
export GIT_AUTHOR_EMAIL='testauthor@cmake.org'
export GIT_COMMITTER_NAME='testauthor'
export GIT_COMMITTER_EMAIL='testauthor@cmake.org'
+export GIT_CONFIG_NOSYSTEM=1
+export GIT_CONFIG_GLOBAL="$tmpdir/.gitconfig"
+git config --global protocol.file.allow always
(
cd "$tmpdir"
@@ -23,7 +26,7 @@
mkdir gitrepo
cd gitrepo
git init -b "$defaultBranch"
-echo 'cmake_minimum_required(VERSION 3.19)
+echo 'cmake_minimum_required(VERSION 3.31)
project(Example NONE)
add_custom_target(example ALL
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/example.cmake.in example.cmake
@@ -43,7 +46,7 @@
mkdir gitrepo-sub
cd gitrepo-sub
git init -b "$defaultBranch"
-echo 'cmake_minimum_required(VERSION 3.19)
+echo 'cmake_minimum_required(VERSION 3.31)
project(ExampleWithSub NONE)
file(STRINGS "${CMAKE_SOURCE_DIR}/.git/config" git_config_strings
REGEX "^\\[submodule")
diff --git a/Tests/ExternalProject/gitrepo.tgz b/Tests/ExternalProject/gitrepo.tgz
index 8d2d144..63a6ddc 100644
--- a/Tests/ExternalProject/gitrepo.tgz
+++ b/Tests/ExternalProject/gitrepo.tgz
Binary files differ
diff --git a/Tests/ExternalProject/hgrepo.tgz b/Tests/ExternalProject/hgrepo.tgz
index 0d75ce2..aebbcc0 100644
--- a/Tests/ExternalProject/hgrepo.tgz
+++ b/Tests/ExternalProject/hgrepo.tgz
Binary files differ
diff --git a/Tests/ExternalProject/svnrepo.tgz b/Tests/ExternalProject/svnrepo.tgz
index b848416..da5350f 100644
--- a/Tests/ExternalProject/svnrepo.tgz
+++ b/Tests/ExternalProject/svnrepo.tgz
Binary files differ
diff --git a/Tests/ExternalProjectLocal/CMakeLists.txt b/Tests/ExternalProjectLocal/CMakeLists.txt
index f9abe11..7caefae 100644
--- a/Tests/ExternalProjectLocal/CMakeLists.txt
+++ b/Tests/ExternalProjectLocal/CMakeLists.txt
@@ -79,7 +79,7 @@
set(proj TutorialStep1-LocalTAR)
ExternalProject_Add(${proj}
URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tar"
- URL_MD5 a87c5b47c0201c09ddfe1d5738fdb1e3
+ URL_MD5 e3774630066d0df5b9074cb777d72802
LIST_SEPARATOR ::
PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/Step1Patch.cmake
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
@@ -94,7 +94,7 @@
set(proj TutorialStep1-LocalNoDirTAR)
ExternalProject_Add(${proj}
URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tar"
- URL_MD5 d09e3d370c5c908fa035c30939ee438e
+ URL_MD5 a7357d2e8a52cc807957634ea135eb31
LIST_SEPARATOR @@
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
-DTEST_LIST:STRING=1@@2@@3
@@ -115,7 +115,7 @@
set(proj TutorialStep1-LocalTGZ)
ExternalProject_Add(${proj}
URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tgz"
- URL_MD5 38c648e817339c356f6be00eeed79bd0
+ URL_MD5 c04edffa0520d5468d51ecd13a971828
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
INSTALL_COMMAND ""
LOG_BUILD 1
@@ -126,7 +126,7 @@
set(proj TutorialStep1-LocalNoDirTGZ)
ExternalProject_Add(${proj}
URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tgz"
- URL_HASH SHA256=496229e2a5ed620a37c385ad9406004a18026beab8b55dd2c4565d4b7f1d5383
+ URL_HASH SHA256=b9aff8a865842b21cb3bc2ec8bed426b46ef560518962a81242c7f2e089c00de
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
INSTALL_COMMAND ""
diff --git a/Tests/ExternalProjectLocal/Step1.tar b/Tests/ExternalProjectLocal/Step1.tar
index 3711f07..e99effb 100644
--- a/Tests/ExternalProjectLocal/Step1.tar
+++ b/Tests/ExternalProjectLocal/Step1.tar
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1.tar.bz2 b/Tests/ExternalProjectLocal/Step1.tar.bz2
index 49b5f23..3aa9e2a 100644
--- a/Tests/ExternalProjectLocal/Step1.tar.bz2
+++ b/Tests/ExternalProjectLocal/Step1.tar.bz2
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1.tgz b/Tests/ExternalProjectLocal/Step1.tgz
index d9b4cd2..c1f36a3 100644
--- a/Tests/ExternalProjectLocal/Step1.tgz
+++ b/Tests/ExternalProjectLocal/Step1.tgz
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1.zip b/Tests/ExternalProjectLocal/Step1.zip
index 49dac24..c1fe9ed 100644
--- a/Tests/ExternalProjectLocal/Step1.zip
+++ b/Tests/ExternalProjectLocal/Step1.zip
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1NoDir.tar b/Tests/ExternalProjectLocal/Step1NoDir.tar
index 03664b8..c60961c 100644
--- a/Tests/ExternalProjectLocal/Step1NoDir.tar
+++ b/Tests/ExternalProjectLocal/Step1NoDir.tar
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1NoDir.tar.bz2 b/Tests/ExternalProjectLocal/Step1NoDir.tar.bz2
index 92eb480..f4edfa8 100644
--- a/Tests/ExternalProjectLocal/Step1NoDir.tar.bz2
+++ b/Tests/ExternalProjectLocal/Step1NoDir.tar.bz2
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1NoDir.tgz b/Tests/ExternalProjectLocal/Step1NoDir.tgz
index 71a2d81..66facf6 100644
--- a/Tests/ExternalProjectLocal/Step1NoDir.tgz
+++ b/Tests/ExternalProjectLocal/Step1NoDir.tgz
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step1NoDir.zip b/Tests/ExternalProjectLocal/Step1NoDir.zip
index b42d318..6717202 100644
--- a/Tests/ExternalProjectLocal/Step1NoDir.zip
+++ b/Tests/ExternalProjectLocal/Step1NoDir.zip
Binary files differ
diff --git a/Tests/ExternalProjectLocal/Step5/CMakeLists.txt b/Tests/ExternalProjectLocal/Step5/CMakeLists.txt
index bde2641..94845fe 100644
--- a/Tests/ExternalProjectLocal/Step5/CMakeLists.txt
+++ b/Tests/ExternalProjectLocal/Step5/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.31)
project (Tutorial)
# The version number.
diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
index 08e533b..96dca38 100644
--- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
+++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
@@ -189,16 +189,16 @@
file(REMOVE_RECURSE ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals)
if(do_git_tests)
- check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 1 REBASE)
- check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 1 0 REBASE)
+ check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
+ check_a_tag(tag1 4209914b424925d6f1b558d79454d60967d4b0f3 1 0 REBASE)
# With the Git UPDATE_COMMAND performance patch, this will not require a
# 'git fetch'
- check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 0 0 REBASE)
- check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 0 REBASE)
- check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 0 0 REBASE)
- check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 1 REBASE)
+ check_a_tag(tag1 4209914b424925d6f1b558d79454d60967d4b0f3 0 0 REBASE)
+ check_a_tag(tag2 ae72641040f1c9512f152d08afb6909f0498f958 1 0 REBASE)
+ check_a_tag(4209914b42 4209914b424925d6f1b558d79454d60967d4b0f3 0 0 REBASE)
+ check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
# This is a remote symbolic ref, so it will always trigger a 'git fetch'
- check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 1 REBASE)
+ check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
foreach(strategy IN ITEMS CHECKOUT REBASE_CHECKOUT)
# Move local master back, then apply a change that will cause a conflict
@@ -232,7 +232,7 @@
message(FATAL_ERROR "Could not commit conflicting change.")
endif()
# This should discard our commit but leave behind an annotated tag
- check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 1 ${strategy})
+ check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 ${strategy})
endforeach()
# This file matches a .gitignore rule that the last commit defines. We can't
@@ -242,7 +242,7 @@
# doesn't choke on it.
set(ignoredFile ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/ignored_item)
file(TOUCH ${ignoredFile})
- check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 1 REBASE)
+ check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
if(NOT EXISTS ${ignoredFile})
message(FATAL_ERROR "Ignored file is missing")
endif()
diff --git a/Tests/ExternalProjectUpdate/gitrepo.tgz b/Tests/ExternalProjectUpdate/gitrepo.tgz
index 4dab56b..be00071 100644
--- a/Tests/ExternalProjectUpdate/gitrepo.tgz
+++ b/Tests/ExternalProjectUpdate/gitrepo.tgz
Binary files differ
diff --git a/Tests/FindGTK2/CMakeLists.txt b/Tests/FindGTK2/CMakeLists.txt
index 0105fae..15a7c29 100644
--- a/Tests/FindGTK2/CMakeLists.txt
+++ b/Tests/FindGTK2/CMakeLists.txt
@@ -11,7 +11,6 @@
--build-target gtk-all-libs
--build-project gtk
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtk"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -25,7 +24,6 @@
--build-target gtkmm-all-libs
--build-project gtkmm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtkmm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -40,7 +38,6 @@
${build_generator_args}
--build-project glib
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glib"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -53,7 +50,6 @@
${build_generator_args}
--build-project gobject
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gobject"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -66,7 +62,6 @@
${build_generator_args}
--build-project gio
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gio"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -79,7 +74,6 @@
${build_generator_args}
--build-project gmodule
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gmodule"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -92,7 +86,6 @@
${build_generator_args}
--build-project gthread
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gthread"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -105,7 +98,6 @@
${build_generator_args}
--build-project atk
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atk"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -118,7 +110,6 @@
${build_generator_args}
--build-project gdk_pixbuf
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk_pixbuf"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -131,7 +122,6 @@
${build_generator_args}
--build-project cairo
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairo"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -144,7 +134,6 @@
${build_generator_args}
--build-project pango
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pango"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -157,7 +146,6 @@
${build_generator_args}
--build-project pangocairo
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangocairo"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -170,7 +158,6 @@
${build_generator_args}
--build-project pangoxft
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoxft"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -183,7 +170,6 @@
${build_generator_args}
--build-project pangoft2
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoft2"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -196,7 +182,6 @@
${build_generator_args}
--build-project gdk
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -209,7 +194,6 @@
${build_generator_args}
--build-project gtk
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtk"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -222,7 +206,6 @@
${build_generator_args}
--build-project sigc++
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/sigc++"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -235,7 +218,6 @@
${build_generator_args}
--build-project glibmm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glibmm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -248,7 +230,6 @@
${build_generator_args}
--build-project giomm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/giomm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -261,7 +242,6 @@
${build_generator_args}
--build-project atkmm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atkmm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -274,7 +254,6 @@
${build_generator_args}
--build-project cairomm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairomm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -287,7 +266,6 @@
${build_generator_args}
--build-project pangomm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangomm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -300,7 +278,6 @@
${build_generator_args}
--build-project gdkmm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/GTK2Targets/gdkmm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
@@ -314,7 +291,6 @@
--build-target gtkmm-target
--build-project gtkmm
--build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtkmm"
- --force-new-ctest-process
--test-command ${CMAKE_CTEST_COMMAND} -V
)
endif()
diff --git a/Tests/FindPackageTest/.gitignore b/Tests/FindPackageCMakeTest/.gitignore
similarity index 100%
rename from Tests/FindPackageTest/.gitignore
rename to Tests/FindPackageCMakeTest/.gitignore
diff --git a/Tests/FindPackageTest/A/wibble-config.cmake b/Tests/FindPackageCMakeTest/A/wibble-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/A/wibble-config.cmake
rename to Tests/FindPackageCMakeTest/A/wibble-config.cmake
diff --git a/Tests/FindPackageTest/B/wibble-config.cmake b/Tests/FindPackageCMakeTest/B/wibble-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/B/wibble-config.cmake
rename to Tests/FindPackageCMakeTest/B/wibble-config.cmake
diff --git a/Tests/FindPackageTest/Baz 1.1/BazConfig.cmake b/Tests/FindPackageCMakeTest/Baz 1.1/BazConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 1.1/BazConfig.cmake
rename to Tests/FindPackageCMakeTest/Baz 1.1/BazConfig.cmake
diff --git a/Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake b/Tests/FindPackageCMakeTest/Baz 1.1/BazConfigVersion.cmake
similarity index 99%
rename from Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/Baz 1.1/BazConfigVersion.cmake
index 979bbdf..5b0261a 100644
--- a/Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake
+++ b/Tests/FindPackageCMakeTest/Baz 1.1/BazConfigVersion.cmake
@@ -5,4 +5,3 @@
set(PACKAGE_VERSION_EXACT 1)
endif()
endif()
-
diff --git a/Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake b/Tests/FindPackageCMakeTest/Baz 1.2/CMake/BazConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake
rename to Tests/FindPackageCMakeTest/Baz 1.2/CMake/BazConfig.cmake
diff --git a/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake b/Tests/FindPackageCMakeTest/Baz 1.2/CMake/BazConfigVersion.cmake
similarity index 100%
copy from Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake
copy to Tests/FindPackageCMakeTest/Baz 1.2/CMake/BazConfigVersion.cmake
diff --git a/Tests/FindPackageTest/Baz 1.3/lib/cmake/Baz/BazConfig.cmake b/Tests/FindPackageCMakeTest/Baz 1.3/lib/cmake/Baz/BazConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 1.3/lib/cmake/Baz/BazConfig.cmake
rename to Tests/FindPackageCMakeTest/Baz 1.3/lib/cmake/Baz/BazConfig.cmake
diff --git a/Tests/FindPackageTest/Baz 1.3/lib/cmake/Baz/BazConfigVersion.cmake b/Tests/FindPackageCMakeTest/Baz 1.3/lib/cmake/Baz/BazConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 1.3/lib/cmake/Baz/BazConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/Baz 1.3/lib/cmake/Baz/BazConfigVersion.cmake
diff --git a/Tests/FindPackageTest/Baz 2.0/share/Baz 2/BazConfig.cmake b/Tests/FindPackageCMakeTest/Baz 2.0/share/Baz 2/BazConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 2.0/share/Baz 2/BazConfig.cmake
rename to Tests/FindPackageCMakeTest/Baz 2.0/share/Baz 2/BazConfig.cmake
diff --git a/Tests/FindPackageTest/Baz 2.0/share/Baz 2/BazConfigVersion.cmake b/Tests/FindPackageCMakeTest/Baz 2.0/share/Baz 2/BazConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 2.0/share/Baz 2/BazConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/Baz 2.0/share/Baz 2/BazConfigVersion.cmake
diff --git a/Tests/FindPackageTest/Baz 2.1/lib/Baz 2/cmake/BazConfig.cmake b/Tests/FindPackageCMakeTest/Baz 2.1/lib/Baz 2/cmake/BazConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 2.1/lib/Baz 2/cmake/BazConfig.cmake
rename to Tests/FindPackageCMakeTest/Baz 2.1/lib/Baz 2/cmake/BazConfig.cmake
diff --git a/Tests/FindPackageTest/Baz 2.1/lib/Baz 2/cmake/BazConfigVersion.cmake b/Tests/FindPackageCMakeTest/Baz 2.1/lib/Baz 2/cmake/BazConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/Baz 2.1/lib/Baz 2/cmake/BazConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/Baz 2.1/lib/Baz 2/cmake/BazConfigVersion.cmake
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageCMakeTest/CMakeLists.txt
similarity index 90%
rename from Tests/FindPackageTest/CMakeLists.txt
rename to Tests/FindPackageCMakeTest/CMakeLists.txt
index 73d3fb4..772be08 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageCMakeTest/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10)
-project(FindPackageTest)
+project(FindPackageCMakeTest)
# Protect tests from running inside the default install prefix.
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
@@ -22,7 +22,7 @@
# Look for a package that has an advanced find module.
find_package(Boost QUIET)
-add_executable(FindPackageTest FindPackageTest.cxx)
+add_executable(FindPackageCMakeTest FindPackageTest.cxx)
# test behavior of cmFindBase wrt. the CMAKE_PREFIX_PATH variable
# foo.h should be found in ${CMAKE_CURRENT_SOURCE_DIR}/include:
@@ -67,9 +67,9 @@
set(CMakeTestSystemPackage "")
if(WIN32 AND NOT CYGWIN)
# Try writing a value to the system package registry.
- set(_data "${FindPackageTest_SOURCE_DIR}/SystemPackage")
+ set(_data "${FindPackageCMakeTest_SOURCE_DIR}/SystemPackage")
set(_key "HKLM\\Software\\Kitware\\CMake\\Packages\\CMakeTestSystemPackage")
- set(_file "${FindPackageTest_BINARY_DIR}/CMakeTestSystemPackage.data")
+ set(_file "${FindPackageCMakeTest_BINARY_DIR}/CMakeTestSystemPackage.data")
file(WRITE ${_file} "${_data}\n")
execute_process(
COMMAND ${CMAKE_COMMAND} -E md5sum ${_file}
@@ -204,7 +204,7 @@
# The result must preserve the /symlink/ path.
set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/symlink/cmake")
if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}")
- message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")")
+ message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to\n \"${SetFoundResolved_DIR}\"\nnot the expected\n \"${SetFoundResolved_EXPECTED}\"")
endif()
# This part of the test only works if there are no symlinks in our path.
@@ -217,7 +217,7 @@
# ./symlink points back here so it should be gone when resolved.
set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}")
- message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")")
+ message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to\n \"${SetFoundResolved_DIR}\"\nnot the expected\n \"${SetFoundResolved_EXPECTED}\"")
endif()
endif()
@@ -383,8 +383,8 @@
message(STATUS "Preparing export(PACKAGE) test project")
try_compile(EXPORTER_COMPILED
- ${FindPackageTest_BINARY_DIR}/Exporter-build
- ${FindPackageTest_SOURCE_DIR}/Exporter
+ ${FindPackageCMakeTest_BINARY_DIR}/Exporter-build
+ ${FindPackageCMakeTest_SOURCE_DIR}/Exporter
CMakeTestExportPackage dummy
CMAKE_FLAGS "-UCMAKE_EXPORT_NO_PACKAGE_REGISTRY"
"-DCMAKE_POLICY_DEFAULT_CMP0090:STRING=OLD"
@@ -434,15 +434,15 @@
unset(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY)
message(STATUS "Remove export(PACKAGE) test project")
-file(REMOVE_RECURSE ${FindPackageTest_BINARY_DIR}/Exporter-build)
+file(REMOVE_RECURSE ${FindPackageCMakeTest_BINARY_DIR}/Exporter-build)
set(CMakeTestExportPackage_DIR "" CACHE FILEPATH
"Wipe out find results for testing." FORCE)
find_package(CMakeTestExportPackage QUIET) # Should clean the user package cache
#
message(STATUS "Preparing export(PACKAGE) test project with CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE")
try_compile(EXPORTER_COMPILED
- ${FindPackageTest_BINARY_DIR}/Exporter-build
- ${FindPackageTest_SOURCE_DIR}/Exporter
+ ${FindPackageCMakeTest_BINARY_DIR}/Exporter-build
+ ${FindPackageCMakeTest_SOURCE_DIR}/Exporter
CMakeTestExportPackage dummy
CMAKE_FLAGS "-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY:BOOL=TRUE"
-Dversion=${version}
@@ -454,12 +454,12 @@
endif()
message(STATUS "Remove export(PACKAGE) test project")
-file(REMOVE_RECURSE ${FindPackageTest_BINARY_DIR}/Exporter-build)
+file(REMOVE_RECURSE ${FindPackageCMakeTest_BINARY_DIR}/Exporter-build)
message(STATUS "Preparing export(PACKAGE) test project with POLICY CMP0090=NEW")
try_compile(EXPORTER_COMPILED
- ${FindPackageTest_BINARY_DIR}/Exporter-build
- ${FindPackageTest_SOURCE_DIR}/Exporter
+ ${FindPackageCMakeTest_BINARY_DIR}/Exporter-build
+ ${FindPackageCMakeTest_SOURCE_DIR}/Exporter
CMakeTestExportPackage dummy
CMAKE_FLAGS
"-DCMAKE_POLICY_DEFAULT_CMP0090:STRING=NEW"
@@ -492,15 +492,15 @@
include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
- message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")")
+ message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to\n \"${RELOC_INCLUDE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/include\"")
endif()
if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/")
- message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")")
+ message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to\n \"${RELOC_SHARE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/share/\"")
endif()
if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
- message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
+ message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to\n \"${RELOC_BUILD_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}\"")
endif()
if(NOT DEFINED Relocatable_FOUND)
@@ -527,15 +527,15 @@
include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
- message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")")
+ message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to\n \"${RELOC_INCLUDE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/include\"")
endif()
if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/")
- message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")")
+ message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to\n \"${RELOC_SHARE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/share/\"")
endif()
if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
- message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
+ message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to\n \"${RELOC_BUILD_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}\"")
endif()
if(NOT DEFINED Relocatable_FOUND)
@@ -550,10 +550,10 @@
############################################################################
##Test FIND_PACKAGE using sorting
set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
-SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
-SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
FIND_PACKAGE(SortLib CONFIG)
IF (NOT "${SortLib_VERSION}" STREQUAL "3.1.1")
message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Name Asc! ${SortLib_VERSION}")
@@ -579,6 +579,28 @@
endif()
unset(SortLib_VERSION)
+
+set(SortFramework_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
+FIND_PACKAGE(SortFramework CONFIG)
+IF (NOT "${SortFramework_VERSION}" STREQUAL "3.1.1")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Framework Name Asc! ${SortFramework_VERSION}")
+endif()
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+unset(SortFramework_VERSION)
+
+
+set(SortFramework_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+FIND_PACKAGE(SortFramework CONFIG)
+IF (NOT "${SortFramework_VERSION}" STREQUAL "3.10.1")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Framework Natural! Dec ${SortFramework_VERSION}")
+endif()
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+unset(SortFramework_VERSION)
+
unset(CMAKE_FIND_PACKAGE_SORT_ORDER)
unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION)
set(CMAKE_PREFIX_PATH )
diff --git a/Tests/FindPackageTest/Exporter/CMakeLists.txt b/Tests/FindPackageCMakeTest/Exporter/CMakeLists.txt
similarity index 100%
rename from Tests/FindPackageTest/Exporter/CMakeLists.txt
rename to Tests/FindPackageCMakeTest/Exporter/CMakeLists.txt
diff --git a/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfig.cmake.in b/Tests/FindPackageCMakeTest/Exporter/CMakeTestExportPackageConfig.cmake.in
similarity index 100%
rename from Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfig.cmake.in
rename to Tests/FindPackageCMakeTest/Exporter/CMakeTestExportPackageConfig.cmake.in
diff --git a/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in b/Tests/FindPackageCMakeTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
similarity index 100%
rename from Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
rename to Tests/FindPackageCMakeTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
diff --git a/Tests/FindPackageTest/Exporter/dummy.c b/Tests/FindPackageCMakeTest/Exporter/dummy.c
similarity index 100%
rename from Tests/FindPackageTest/Exporter/dummy.c
rename to Tests/FindPackageCMakeTest/Exporter/dummy.c
diff --git a/Tests/FindPackageTest/FindLotsOfComponents.cmake b/Tests/FindPackageCMakeTest/FindLotsOfComponents.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindLotsOfComponents.cmake
rename to Tests/FindPackageCMakeTest/FindLotsOfComponents.cmake
diff --git a/Tests/FindPackageTest/FindPackageHandleStandardArgs.cmake b/Tests/FindPackageCMakeTest/FindPackageHandleStandardArgs.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindPackageHandleStandardArgs.cmake
rename to Tests/FindPackageCMakeTest/FindPackageHandleStandardArgs.cmake
diff --git a/Tests/FindPackageTest/FindPackageTest.cxx b/Tests/FindPackageCMakeTest/FindPackageTest.cxx
similarity index 100%
rename from Tests/FindPackageTest/FindPackageTest.cxx
rename to Tests/FindPackageCMakeTest/FindPackageTest.cxx
diff --git a/Tests/FindPackageTest/FindRecursiveA.cmake b/Tests/FindPackageCMakeTest/FindRecursiveA.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindRecursiveA.cmake
rename to Tests/FindPackageCMakeTest/FindRecursiveA.cmake
diff --git a/Tests/FindPackageTest/FindRecursiveB.cmake b/Tests/FindPackageCMakeTest/FindRecursiveB.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindRecursiveB.cmake
rename to Tests/FindPackageCMakeTest/FindRecursiveB.cmake
diff --git a/Tests/FindPackageTest/FindRecursiveC.cmake b/Tests/FindPackageCMakeTest/FindRecursiveC.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindRecursiveC.cmake
rename to Tests/FindPackageCMakeTest/FindRecursiveC.cmake
diff --git a/Tests/FindPackageTest/FindSomePackage.cmake b/Tests/FindPackageCMakeTest/FindSomePackage.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindSomePackage.cmake
rename to Tests/FindPackageCMakeTest/FindSomePackage.cmake
diff --git a/Tests/FindPackageTest/FindUpperCasePackage.cmake b/Tests/FindPackageCMakeTest/FindUpperCasePackage.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindUpperCasePackage.cmake
rename to Tests/FindPackageCMakeTest/FindUpperCasePackage.cmake
diff --git a/Tests/FindPackageTest/FindVersionTestA.cmake b/Tests/FindPackageCMakeTest/FindVersionTestA.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindVersionTestA.cmake
rename to Tests/FindPackageCMakeTest/FindVersionTestA.cmake
diff --git a/Tests/FindPackageTest/FindVersionTestB.cmake b/Tests/FindPackageCMakeTest/FindVersionTestB.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindVersionTestB.cmake
rename to Tests/FindPackageCMakeTest/FindVersionTestB.cmake
diff --git a/Tests/FindPackageTest/FindVersionTestC.cmake b/Tests/FindPackageCMakeTest/FindVersionTestC.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindVersionTestC.cmake
rename to Tests/FindPackageCMakeTest/FindVersionTestC.cmake
diff --git a/Tests/FindPackageTest/FindVersionTestD.cmake b/Tests/FindPackageCMakeTest/FindVersionTestD.cmake
similarity index 100%
rename from Tests/FindPackageTest/FindVersionTestD.cmake
rename to Tests/FindPackageCMakeTest/FindVersionTestD.cmake
diff --git a/Tests/FindPackageTest/PreferConfig/ABCConfig.cmake b/Tests/FindPackageCMakeTest/PreferConfig/ABCConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/PreferConfig/ABCConfig.cmake
rename to Tests/FindPackageCMakeTest/PreferConfig/ABCConfig.cmake
diff --git a/Tests/FindPackageTest/PreferConfig/FindABC.cmake b/Tests/FindPackageCMakeTest/PreferConfig/FindABC.cmake
similarity index 100%
rename from Tests/FindPackageTest/PreferConfig/FindABC.cmake
rename to Tests/FindPackageCMakeTest/PreferConfig/FindABC.cmake
diff --git a/Tests/FindPackageTest/PreferConfigOnlyModule/FindACME.cmake b/Tests/FindPackageCMakeTest/PreferConfigOnlyModule/FindACME.cmake
similarity index 100%
rename from Tests/FindPackageTest/PreferConfigOnlyModule/FindACME.cmake
rename to Tests/FindPackageCMakeTest/PreferConfigOnlyModule/FindACME.cmake
diff --git a/Tests/FindPackageTest/PreferConfigRecurse/ACMEConfig.cmake b/Tests/FindPackageCMakeTest/PreferConfigRecurse/ACMEConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/PreferConfigRecurse/ACMEConfig.cmake
rename to Tests/FindPackageCMakeTest/PreferConfigRecurse/ACMEConfig.cmake
diff --git a/Tests/FindPackageTest/PreferConfigRecurse/FindACME.cmake b/Tests/FindPackageCMakeTest/PreferConfigRecurse/FindACME.cmake
similarity index 100%
rename from Tests/FindPackageTest/PreferConfigRecurse/FindACME.cmake
rename to Tests/FindPackageCMakeTest/PreferConfigRecurse/FindACME.cmake
diff --git a/Tests/FindPackageTest/RelocatableConfig.cmake.in b/Tests/FindPackageCMakeTest/RelocatableConfig.cmake.in
similarity index 100%
rename from Tests/FindPackageTest/RelocatableConfig.cmake.in
rename to Tests/FindPackageCMakeTest/RelocatableConfig.cmake.in
diff --git a/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.1.1/Resources/CMake/SortFrameworkConfig.cmake b/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.1.1/Resources/CMake/SortFrameworkConfig.cmake
new file mode 100644
index 0000000..f51edb2
--- /dev/null
+++ b/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.1.1/Resources/CMake/SortFrameworkConfig.cmake
@@ -0,0 +1,2 @@
+set(SORT_FRAMEWORK_VERSION 3.1.1)
+message("SortFramework 3.1.1 config reached")
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake b/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.1.1/Resources/CMake/SortFrameworkConfigVersion.cmake
similarity index 100%
copy from Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake
copy to Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.1.1/Resources/CMake/SortFrameworkConfigVersion.cmake
diff --git a/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.10.1/Resources/CMake/SortFrameworkConfig.cmake b/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.10.1/Resources/CMake/SortFrameworkConfig.cmake
new file mode 100644
index 0000000..f7f05ef
--- /dev/null
+++ b/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.10.1/Resources/CMake/SortFrameworkConfig.cmake
@@ -0,0 +1,2 @@
+set(SORT_FRAMEWORK_VERSION 3.10.1)
+message("SortFramework 3.10.1 config reached")
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake b/Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.10.1/Resources/CMake/SortFrameworkConfigVersion.cmake
similarity index 100%
copy from Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake
copy to Tests/FindPackageCMakeTest/SortFramework.framework/Versions/3.10.1/Resources/CMake/SortFrameworkConfigVersion.cmake
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake b/Tests/FindPackageCMakeTest/SortLib-3.1.1/SortLibConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake
rename to Tests/FindPackageCMakeTest/SortLib-3.1.1/SortLibConfig.cmake
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake b/Tests/FindPackageCMakeTest/SortLib-3.1.1/SortLibConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/SortLib-3.1.1/SortLibConfigVersion.cmake
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake b/Tests/FindPackageCMakeTest/SortLib-3.10.1/SortLibConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake
rename to Tests/FindPackageCMakeTest/SortLib-3.10.1/SortLibConfig.cmake
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake b/Tests/FindPackageCMakeTest/SortLib-3.10.1/SortLibConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/SortLib-3.10.1/SortLibConfigVersion.cmake
diff --git a/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake b/Tests/FindPackageCMakeTest/SystemPackage/CMakeTestSystemPackageConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake
rename to Tests/FindPackageCMakeTest/SystemPackage/CMakeTestSystemPackageConfig.cmake
diff --git a/Tests/FindPackageTest/TApp.app/Contents/Resources/TAppConfig.cmake b/Tests/FindPackageCMakeTest/TApp.app/Contents/Resources/TAppConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/TApp.app/Contents/Resources/TAppConfig.cmake
rename to Tests/FindPackageCMakeTest/TApp.app/Contents/Resources/TAppConfig.cmake
diff --git a/Tests/FindPackageTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake b/Tests/FindPackageCMakeTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake
rename to Tests/FindPackageCMakeTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake
diff --git a/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake b/Tests/FindPackageCMakeTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake
rename to Tests/FindPackageCMakeTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake
diff --git a/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake b/Tests/FindPackageCMakeTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake
rename to Tests/FindPackageCMakeTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake
diff --git a/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake b/Tests/FindPackageCMakeTest/cmake/SetFoundFALSEConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake
rename to Tests/FindPackageCMakeTest/cmake/SetFoundFALSEConfig.cmake
diff --git a/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake b/Tests/FindPackageCMakeTest/cmake/SetFoundResolvedConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake
rename to Tests/FindPackageCMakeTest/cmake/SetFoundResolvedConfig.cmake
diff --git a/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake b/Tests/FindPackageCMakeTest/cmake/SetFoundTRUEConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake
rename to Tests/FindPackageCMakeTest/cmake/SetFoundTRUEConfig.cmake
diff --git a/Tests/FindPackageTest/include/foo.h b/Tests/FindPackageCMakeTest/include/foo.h
similarity index 100%
rename from Tests/FindPackageTest/include/foo.h
rename to Tests/FindPackageCMakeTest/include/foo.h
diff --git a/Tests/FindPackageTest/lib/Bar/BarConfig.cmake b/Tests/FindPackageCMakeTest/lib/Bar/BarConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/Bar/BarConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/Bar/BarConfig.cmake
diff --git a/Tests/FindPackageTest/lib/Bar/cmake/bar-config.cmake b/Tests/FindPackageCMakeTest/lib/Bar/cmake/bar-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/Bar/cmake/bar-config.cmake
rename to Tests/FindPackageCMakeTest/lib/Bar/cmake/bar-config.cmake
diff --git a/Tests/FindPackageTest/lib/Blub/BlubConfig.cmake b/Tests/FindPackageCMakeTest/lib/Blub/BlubConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/Blub/BlubConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/Blub/BlubConfig.cmake
diff --git a/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake b/Tests/FindPackageCMakeTest/lib/RecursiveA/recursivea-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake
rename to Tests/FindPackageCMakeTest/lib/RecursiveA/recursivea-config.cmake
diff --git a/Tests/FindPackageTest/lib/SortLib-4.0.0/SortLibConfig.cmake b/Tests/FindPackageCMakeTest/lib/SortLib-4.0.0/SortLibConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/SortLib-4.0.0/SortLibConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/SortLib-4.0.0/SortLibConfig.cmake
diff --git a/Tests/FindPackageTest/lib/SortLib-4.0.0/SortLibConfigVersion.cmake b/Tests/FindPackageCMakeTest/lib/SortLib-4.0.0/SortLibConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/SortLib-4.0.0/SortLibConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/lib/SortLib-4.0.0/SortLibConfigVersion.cmake
diff --git a/Tests/FindPackageTest/lib/TApp/TAppConfig.cmake b/Tests/FindPackageCMakeTest/lib/TApp/TAppConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/TApp/TAppConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/TApp/TAppConfig.cmake
diff --git a/Tests/FindPackageTest/lib/arch/Bar/BarConfig.cmake b/Tests/FindPackageCMakeTest/lib/arch/Bar/BarConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/arch/Bar/BarConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/arch/Bar/BarConfig.cmake
diff --git a/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake
rename to Tests/FindPackageCMakeTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake
diff --git a/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/arch/cmake/zot-4.0/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/arch/cmake/zot-4.0/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/arch/foo-1.2/CMake/FooConfig.cmake b/Tests/FindPackageCMakeTest/lib/arch/foo-1.2/CMake/FooConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/arch/foo-1.2/CMake/FooConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/arch/foo-1.2/CMake/FooConfig.cmake
diff --git a/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/arch/zot-3.1/zot-config-version.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake
rename to Tests/FindPackageCMakeTest/lib/arch/zot-3.1/zot-config-version.cmake
diff --git a/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/arch/zot-3.1/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/arch/zot-3.1/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/arch/zot-3.1/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/cmake/zot-3.1/zot-config-version.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config-version.cmake
rename to Tests/FindPackageCMakeTest/lib/cmake/zot-3.1/zot-config-version.cmake
diff --git a/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/cmake/zot-3.1/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/cmake/zot-3.1/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/cmake/zot-4.0/zot-config-version.cmake
similarity index 100%
copy from Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake
copy to Tests/FindPackageCMakeTest/lib/cmake/zot-4.0/zot-config-version.cmake
diff --git a/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/cmake/zot-4.0/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/cmake/zot-4.0/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/foo-1.2/CMake/FooConfig.cmake b/Tests/FindPackageCMakeTest/lib/foo-1.2/CMake/FooConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/foo-1.2/CMake/FooConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/foo-1.2/CMake/FooConfig.cmake
diff --git a/Tests/FindPackageTest/lib/foo-1.2/foo-config.cmake b/Tests/FindPackageCMakeTest/lib/foo-1.2/foo-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/foo-1.2/foo-config.cmake
rename to Tests/FindPackageCMakeTest/lib/foo-1.2/foo-config.cmake
diff --git a/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfig.cmake b/Tests/FindPackageCMakeTest/lib/suffix/test/SuffixTestConfig.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/suffix/test/SuffixTestConfig.cmake
rename to Tests/FindPackageCMakeTest/lib/suffix/test/SuffixTestConfig.cmake
diff --git a/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake b/Tests/FindPackageCMakeTest/lib/suffix/test/SuffixTestConfigVersion.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake
rename to Tests/FindPackageCMakeTest/lib/suffix/test/SuffixTestConfigVersion.cmake
diff --git a/Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/zot-1.0/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/zot-1.0/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/zot-2.0/zot-config-version.cmake
similarity index 98%
rename from Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake
rename to Tests/FindPackageCMakeTest/lib/zot-2.0/zot-config-version.cmake
index db3a8a4..3b14664 100644
--- a/Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake
+++ b/Tests/FindPackageCMakeTest/lib/zot-2.0/zot-config-version.cmake
@@ -2,4 +2,3 @@
if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 2)
set(PACKAGE_VERSION_COMPATIBLE 1)
endif()
-
diff --git a/Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/zot-2.0/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/zot-2.0/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/zot-3.0/zot-config-version.cmake
similarity index 98%
rename from Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake
rename to Tests/FindPackageCMakeTest/lib/zot-3.0/zot-config-version.cmake
index dd9c939..a4d45a4 100644
--- a/Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake
+++ b/Tests/FindPackageCMakeTest/lib/zot-3.0/zot-config-version.cmake
@@ -2,4 +2,3 @@
if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
set(PACKAGE_VERSION_COMPATIBLE 1)
endif()
-
diff --git a/Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/zot-3.0/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/zot-3.0/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/zot-3.1/zot-config-version.cmake
similarity index 100%
copy from Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake
copy to Tests/FindPackageCMakeTest/lib/zot-3.1/zot-config-version.cmake
diff --git a/Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/zot-3.1/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/zot-3.1/zot-config.cmake
diff --git a/Tests/FindPackageTest/lib/zot/zot-config-version.cmake b/Tests/FindPackageCMakeTest/lib/zot/zot-config-version.cmake
similarity index 99%
rename from Tests/FindPackageTest/lib/zot/zot-config-version.cmake
rename to Tests/FindPackageCMakeTest/lib/zot/zot-config-version.cmake
index 430f009..093776f 100644
--- a/Tests/FindPackageTest/lib/zot/zot-config-version.cmake
+++ b/Tests/FindPackageCMakeTest/lib/zot/zot-config-version.cmake
@@ -7,4 +7,3 @@
set(PACKAGE_VERSION_EXACT 1)
endif()
endif()
-
diff --git a/Tests/FindPackageTest/lib/zot/zot-config.cmake b/Tests/FindPackageCMakeTest/lib/zot/zot-config.cmake
similarity index 100%
rename from Tests/FindPackageTest/lib/zot/zot-config.cmake
rename to Tests/FindPackageCMakeTest/lib/zot/zot-config.cmake
diff --git a/Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake b/Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake
deleted file mode 100644
index 17caaa7..0000000
--- a/Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-set(PACKAGE_VERSION 1.2)
-if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
- set(PACKAGE_VERSION_COMPATIBLE 1)
- if("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 2)
- set(PACKAGE_VERSION_EXACT 1)
- endif()
-endif()
-
diff --git a/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake b/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake
deleted file mode 100644
index bcefcd7..0000000
--- a/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-set(PACKAGE_VERSION 4.0)
-if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 4)
- set(PACKAGE_VERSION_COMPATIBLE 1)
- if("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 0)
- set(PACKAGE_VERSION_EXACT 1)
- endif()
-endif()
-
diff --git a/Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake b/Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake
deleted file mode 100644
index 8fa767e..0000000
--- a/Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-set(PACKAGE_VERSION 3.1)
-if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
- set(PACKAGE_VERSION_COMPATIBLE 1)
- if("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
- set(PACKAGE_VERSION_EXACT 1)
- endif()
-endif()
-
diff --git a/Tests/FindProtobuf/CMakeLists.txt b/Tests/FindProtobuf/CMakeLists.txt
index b4ca29b..8e46ff8 100644
--- a/Tests/FindProtobuf/CMakeLists.txt
+++ b/Tests/FindProtobuf/CMakeLists.txt
@@ -9,3 +9,4 @@
"-DCMake_TEST_FindProtobuf_gRPC=${CMake_TEST_FindProtobuf_gRPC}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+set_property(TEST FindProtobuf.Test PROPERTY FAIL_REGULAR_EXPRESSION PROTOC_EXE)
diff --git a/Tests/FindProtobuf/Test/CMakeLists.txt b/Tests/FindProtobuf/Test/CMakeLists.txt
index 2859c48..1409bd9 100644
--- a/Tests/FindProtobuf/Test/CMakeLists.txt
+++ b/Tests/FindProtobuf/Test/CMakeLists.txt
@@ -70,7 +70,7 @@
# NOTE: with IMPORT_DIRS msgs/, generated files will be placed under ${CMAKE_CURRENT_BINARY_DIR}/grpc/
target_include_directories(msgs_grpc_IMPORT_DIRS PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/grpc/)
target_link_libraries(msgs_grpc_IMPORT_DIRS PUBLIC ${Protobuf_LIBRARIES})
- protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE cpp IMPORT_DIRS msgs/)
+ protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE cpp IMPORT_DIRS msgs/ PROTOC_EXE ${Protobuf_PROTOC_EXECUTABLE})
protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE grpc IMPORT_DIRS msgs/ GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${gRPC_CPP_PLUGIN}")
add_executable(test_generate_grpc_IMPORT_DIRS main-generate-grpc.cxx)
target_link_libraries(test_generate_grpc_IMPORT_DIRS PRIVATE msgs_grpc_IMPORT_DIRS)
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index 636a7b0..7a3b7f7 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -342,16 +342,18 @@
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.Python3Embedded COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/Python3Embedded"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python3Embedded"
- ${build_generator_args}
- --build-project TestPython3Embedded
- --build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
+ if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "4.8")
+ add_test(NAME FindPython.Python3Embedded COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python3Embedded"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3Embedded"
+ ${build_generator_args}
+ --build-project TestPython3Embedded
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ endif()
add_test(NAME FindPython.RequiredArtifacts COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
@@ -430,10 +432,13 @@
FindPython.Python.V3.ExactVersion.LOCATION FindPython.Python.V3.ExactVersion.VERSION
FindPython.Python3.VersionRange.LOCATION FindPython.Python3.VersionRange.VERSION
FindPython.Python.V3.VersionRange.LOCATION FindPython.Python.V3.VersionRange.VERSION
- FindPython.VirtualEnv FindPython.Python3Embedded FindPython.RequiredArtifacts
+ FindPython.VirtualEnv FindPython.RequiredArtifacts
FindPython.ArtifactsInteractive.ON FindPython.ArtifactsInteractive.OFF
FindPython.CustomFailureMessage FindPython.DifferentComponents
APPEND PROPERTY LABELS Python3)
+ if(TEST FindPython.Python3Embedded)
+ set_property(TEST FindPython.Python3Embedded APPEND PROPERTY LABELS Python3)
+ endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_test(NAME FindPython.UnversionedNames COMMAND
diff --git a/Tests/FindPython/display_time.c b/Tests/FindPython/display_time.c
index 568d510..7b95f1f 100644
--- a/Tests/FindPython/display_time.c
+++ b/Tests/FindPython/display_time.c
@@ -9,27 +9,32 @@
void display_time(void)
{
#if defined(PYTHON3)
- wchar_t* program = Py_DecodeLocale("display_time", NULL);
- if (program == NULL) {
- fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
- exit(1);
+ PyConfig config;
+ PyStatus status;
+
+ PyConfig_InitPythonConfig(&config);
+ status =
+ PyConfig_SetBytesString(&config, &config.program_name, "display_time");
+ if (PyStatus_Exception(status)) {
+ Py_ExitStatusException(status);
}
+
char* cmd = "from time import time,ctime\n"
"print('Today is', ctime(time()))\n";
#else
char* program = "display_time";
char* cmd = "from time import time,ctime\n"
"print 'Today is', ctime(time())\n";
-#endif
Py_SetProgramName(program); /* optional but recommended */
+#endif
Py_Initialize();
PyRun_SimpleString(cmd);
#if defined(PYTHON3)
if (Py_FinalizeEx() < 0) {
exit(120);
}
- PyMem_RawFree(program);
+ PyConfig_Clear(&config);
#else
Py_Finalize();
#endif
diff --git a/Tests/FindPython/spam.c b/Tests/FindPython/spam.c
index 1c65d54..6dad10a 100644
--- a/Tests/FindPython/spam.c
+++ b/Tests/FindPython/spam.c
@@ -1,4 +1,4 @@
-
+#define Py_LIMITED_API 3
#include <Python.h>
static PyObject* spam_system(PyObject* self, PyObject* args)
diff --git a/Tests/Fortran/hello.f b/Tests/Fortran/hello.f
index aa0de77..63e6408 100644
--- a/Tests/Fortran/hello.f
+++ b/Tests/Fortran/hello.f
@@ -3,4 +3,3 @@
PRINT *, 'Hello'
END
-
diff --git a/Tests/Fortran/testf.f b/Tests/Fortran/testf.f
index abf6c6d..4909181 100644
--- a/Tests/Fortran/testf.f
+++ b/Tests/Fortran/testf.f
@@ -4,4 +4,3 @@
CALL WORLD()
END
-
diff --git a/Tests/Fortran/world.f b/Tests/Fortran/world.f
index 0487dff..deae3fa 100644
--- a/Tests/Fortran/world.f
+++ b/Tests/Fortran/world.f
@@ -3,4 +3,3 @@
PRINT *, 'World!'
END
-
diff --git a/Tests/FortranC/Flags.cmake.in b/Tests/FortranC/Flags.cmake.in
index cf361a5..83ceef0 100644
--- a/Tests/FortranC/Flags.cmake.in
+++ b/Tests/FortranC/Flags.cmake.in
@@ -5,6 +5,9 @@
# flags, remove them, and invoke the real compiler.
set(ID "CC")
set(COMMAND "@CMAKE_C_COMPILER@")
+if("x${COMMAND}" MATCHES "xctoolchain(/usr/bin/cc)$")
+ set(COMMAND "${CMAKE_MATCH_1}")
+endif()
configure_file("${src}/test_opt.sh.in" "${bld}/cc.sh" @ONLY)
set(ID "FC")
set(COMMAND "@CMAKE_Fortran_COMPILER@")
diff --git a/Tests/Java/HelloWorld.java b/Tests/Java/HelloWorld.java
index 995ee48..8d00940 100644
--- a/Tests/Java/HelloWorld.java
+++ b/Tests/Java/HelloWorld.java
@@ -8,4 +8,3 @@
System.out.println("Hello World!");
}
}
-
diff --git a/Tests/LibName/CMakeLists.txt b/Tests/LibName/CMakeLists.txt
index b8f0890..3624f96 100644
--- a/Tests/LibName/CMakeLists.txt
+++ b/Tests/LibName/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
project(LibName)
# this is a test to make sure that relative path
# LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH work
diff --git a/Tests/LinkLine/CMakeLists.txt b/Tests/LinkLine/CMakeLists.txt
index 6154dd4..0e7ff47 100644
--- a/Tests/LinkLine/CMakeLists.txt
+++ b/Tests/LinkLine/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
project( LinkLine )
# Makes sure that the library order as specified by the user are
diff --git a/Tests/LinkLineOrder/CMakeLists.txt b/Tests/LinkLineOrder/CMakeLists.txt
index 78455e9..b4c8876 100644
--- a/Tests/LinkLineOrder/CMakeLists.txt
+++ b/Tests/LinkLineOrder/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
project( LinkLineOrder )
# This tests ensures that the order of libraries are preserved when
diff --git a/Tests/LoadCommand/CMakeLists.txt b/Tests/LoadCommand/CMakeLists.txt
index d892703..891b534 100644
--- a/Tests/LoadCommand/CMakeLists.txt
+++ b/Tests/LoadCommand/CMakeLists.txt
@@ -50,4 +50,3 @@
if (TEST_DEF AND SOME_CACHE_VARIABLE AND TEST_EXEC)
add_definitions(-DCMAKE_IS_FUN)
endif ()
-
diff --git a/Tests/LoadCommandOneConfig/CMakeLists.txt b/Tests/LoadCommandOneConfig/CMakeLists.txt
index ac304e3..ff68ae6 100644
--- a/Tests/LoadCommandOneConfig/CMakeLists.txt
+++ b/Tests/LoadCommandOneConfig/CMakeLists.txt
@@ -56,4 +56,3 @@
if (TEST_DEF AND SOME_CACHE_VARIABLE AND TEST_EXEC)
add_definitions(-DCMAKE_IS_FUN)
endif ()
-
diff --git a/Tests/MathTest/CMakeLists.txt b/Tests/MathTest/CMakeLists.txt
index 6cafcc0..dad3970 100644
--- a/Tests/MathTest/CMakeLists.txt
+++ b/Tests/MathTest/CMakeLists.txt
@@ -52,4 +52,3 @@
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
add_executable(MathTest MathTestExec.cxx)
-
diff --git a/Tests/MumpsCoverage/ZZCOVTST.mcov b/Tests/MumpsCoverage/ZZCOVTST.mcov
index e1fa18c..f3bd40b 100644
--- a/Tests/MumpsCoverage/ZZCOVTST.mcov
+++ b/Tests/MumpsCoverage/ZZCOVTST.mcov
@@ -37,5 +37,3 @@
^ZZCOVERAGE("ZZCOVTST","T6",4)="1:0:0:0:41"
^ZZCOVERAGE("ZZCOVTST","T6",5)="1:0:0:0:34"
^ZZCOVERAGE("ZZCOVTST","T6",6)="1:0:0:0:38"
-
-
diff --git a/Tests/NewlineArgs/libcxx2.h.in b/Tests/NewlineArgs/libcxx2.h.in
index bdf9cfa..0ece510 100644
--- a/Tests/NewlineArgs/libcxx2.h.in
+++ b/Tests/NewlineArgs/libcxx2.h.in
@@ -3,4 +3,3 @@
#define TEST_FLAG_3
#endif
#endif
-
diff --git a/Tests/PerConfig/CMakeLists.txt b/Tests/PerConfig/CMakeLists.txt
index 7f461b0..d6d63d1 100644
--- a/Tests/PerConfig/CMakeLists.txt
+++ b/Tests/PerConfig/CMakeLists.txt
@@ -1,5 +1,7 @@
project(PerConfig C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
# Targets with per-configuration names.
add_library(pcStatic STATIC pcStatic.c)
set_property(TARGET pcStatic PROPERTY RELEASE_POSTFIX -opt)
diff --git a/Tests/PolicyScope/Bar.cmake b/Tests/PolicyScope/Bar.cmake
index 5202cb5..f15124f 100644
--- a/Tests/PolicyScope/Bar.cmake
+++ b/Tests/PolicyScope/Bar.cmake
@@ -1,8 +1,8 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.31)
# Make sure a policy set differently by our includer is now correct.
-cmake_policy(GET CMP0003 cmp)
-check(CMP0003 "NEW" "${cmp}")
+cmake_policy(GET CMP0180 cmp)
+check(CMP0180 "NEW" "${cmp}")
# Test allowing the top-level file to not have cmake_minimum_required.
cmake_policy(SET CMP0000 OLD)
diff --git a/Tests/PolicyScope/CMakeLists.txt b/Tests/PolicyScope/CMakeLists.txt
index 353842b..36ba01a 100644
--- a/Tests/PolicyScope/CMakeLists.txt
+++ b/Tests/PolicyScope/CMakeLists.txt
@@ -12,9 +12,7 @@
#-----------------------------------------------------------------------------
# Test using a development framework that sets policies for us.
-# Policy CMP0011 should not be set at this point.
-cmake_policy(GET CMP0011 cmp)
-check(CMP0011 "" "${cmp}")
+cmake_policy(SET CMP0011 OLD)
# Put the test modules in the search path.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
@@ -23,22 +21,22 @@
find_package(Foo)
# Check policies set by the package.
-cmake_policy(GET CMP0003 cmp)
-check(CMP0003 "OLD" "${cmp}")
-cmake_policy(GET CMP0002 cmp)
-check(CMP0002 "NEW" "${cmp}")
+cmake_policy(GET CMP0180 cmp)
+check(CMP0180 "OLD" "${cmp}")
+cmake_policy(GET CMP0179 cmp)
+check(CMP0179 "NEW" "${cmp}")
cmake_policy(GET CMP0011 cmp)
check(CMP0011 "NEW" "${cmp}")
# Make sure an included file cannot change policies.
include(Bar)
-cmake_policy(GET CMP0003 cmp)
-check(CMP0003 "OLD" "${cmp}")
+cmake_policy(GET CMP0180 cmp)
+check(CMP0180 "OLD" "${cmp}")
# Allow the included file to change policies.
include(Bar NO_POLICY_SCOPE)
-cmake_policy(GET CMP0003 cmp)
-check(CMP0003 "NEW" "${cmp}")
+cmake_policy(GET CMP0180 cmp)
+check(CMP0180 "NEW" "${cmp}")
#-----------------------------------------------------------------------------
# Test function and macro policy recording.
@@ -46,65 +44,65 @@
# Create the functions in an isolated scope in which we change policies.
cmake_policy(PUSH)
if(1)
- # Change CMP0002
- cmake_policy(SET CMP0002 OLD)
+ # Change CMP0179
+ cmake_policy(SET CMP0179 OLD)
function(func1)
- # CMP0002 should be changed when this function is invoked
- cmake_policy(GET CMP0002 cmp)
- check(CMP0002 "OLD" "${cmp}")
+ # CMP0179 should be changed when this function is invoked
+ cmake_policy(GET CMP0179 cmp)
+ check(CMP0179 "OLD" "${cmp}")
# The undocumented PARENT_SCOPE option sees the caller's setting.
- cmake_policy(GET CMP0002 cmp PARENT_SCOPE)
- check(CMP0002 "NEW" "${cmp}")
+ cmake_policy(GET CMP0179 cmp PARENT_SCOPE)
+ check(CMP0179 "NEW" "${cmp}")
endfunction()
- # Unset CMP0002
- cmake_policy(VERSION 2.4)
+ # Unset CMP0179
+ cmake_policy(VERSION 3.30)
macro(macro1)
- # CMP0002 should be unset when this macro is invoked
- cmake_policy(GET CMP0002 cmp)
- check(CMP0002 "" "${cmp}")
+ # CMP0179 should be unset when this macro is invoked
+ cmake_policy(GET CMP0179 cmp)
+ check(CMP0179 "" "${cmp}")
# The undocumented PARENT_SCOPE option sees the caller's setting.
- cmake_policy(GET CMP0002 cmp PARENT_SCOPE)
- check(CMP0002 "NEW" "${cmp}")
+ cmake_policy(GET CMP0179 cmp PARENT_SCOPE)
+ check(CMP0179 "NEW" "${cmp}")
# Setting the policy should work here and also in the caller.
- cmake_policy(SET CMP0002 OLD)
- cmake_policy(GET CMP0002 cmp)
- check(CMP0002 "OLD" "${cmp}")
+ cmake_policy(SET CMP0179 OLD)
+ cmake_policy(GET CMP0179 cmp)
+ check(CMP0179 "OLD" "${cmp}")
endmacro()
endif()
cmake_policy(POP)
-# CMP0002 should still be NEW in this context.
-cmake_policy(GET CMP0002 cmp)
-check(CMP0002 "NEW" "${cmp}")
+# CMP0179 should still be NEW in this context.
+cmake_policy(GET CMP0179 cmp)
+check(CMP0179 "NEW" "${cmp}")
# Check the recorded policies
func1()
macro1()
-# The macro should have changed CMP0002.
-cmake_policy(GET CMP0002 cmp)
-check(CMP0002 "OLD" "${cmp}")
+# The macro should have changed CMP0179.
+cmake_policy(GET CMP0179 cmp)
+check(CMP0179 "OLD" "${cmp}")
#-----------------------------------------------------------------------------
# Test CMAKE_POLICY_DEFAULT_CMP<NNNN> variable.
cmake_policy(PUSH)
- set(CMAKE_POLICY_DEFAULT_CMP0010 OLD) # ignored
- set(CMAKE_POLICY_DEFAULT_CMP0012 OLD) # honored
- set(CMAKE_POLICY_DEFAULT_CMP0013 NEW) # honored
- set(CMAKE_POLICY_DEFAULT_CMP0014 "") # noop
- cmake_policy(VERSION 2.6.3)
- cmake_policy(GET CMP0010 cmp)
- check(CMP0010 "NEW" "${cmp}")
- cmake_policy(GET CMP0012 cmp)
- check(CMP0012 "OLD" "${cmp}")
- cmake_policy(GET CMP0013 cmp)
- check(CMP0013 "NEW" "${cmp}")
- cmake_policy(GET CMP0014 cmp)
- check(CMP0014 "" "${cmp}")
+ set(CMAKE_POLICY_DEFAULT_CMP0170 OLD) # ignored
+ set(CMAKE_POLICY_DEFAULT_CMP0171 OLD) # honored
+ set(CMAKE_POLICY_DEFAULT_CMP0172 NEW) # honored
+ set(CMAKE_POLICY_DEFAULT_CMP0173 "") # noop
+ cmake_policy(VERSION 3.30)
+ cmake_policy(GET CMP0170 cmp)
+ check(CMP0170 "NEW" "${cmp}")
+ cmake_policy(GET CMP0171 cmp)
+ check(CMP0171 "OLD" "${cmp}")
+ cmake_policy(GET CMP0172 cmp)
+ check(CMP0172 "NEW" "${cmp}")
+ cmake_policy(GET CMP0173 cmp)
+ check(CMP0173 "" "${cmp}")
cmake_policy(POP)
#-----------------------------------------------------------------------------
diff --git a/Tests/PolicyScope/FindFoo.cmake b/Tests/PolicyScope/FindFoo.cmake
index e364b6d..843c650 100644
--- a/Tests/PolicyScope/FindFoo.cmake
+++ b/Tests/PolicyScope/FindFoo.cmake
@@ -1,2 +1,2 @@
-cmake_minimum_required(VERSION 3.10)
-cmake_policy(SET CMP0003 OLD)
+cmake_minimum_required(VERSION 3.31)
+cmake_policy(SET CMP0180 OLD)
diff --git a/Tests/PreOrder/CMakeLists.txt b/Tests/PreOrder/CMakeLists.txt
index 8b4c439..1fcdf66 100644
--- a/Tests/PreOrder/CMakeLists.txt
+++ b/Tests/PreOrder/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
# a simple test case
project (PreOrder)
set(CMAKE_IGNORE_DEPENDENCIES_ORDERING 1)
diff --git a/Tests/PreOrder/Library/CMakeLists.txt b/Tests/PreOrder/Library/CMakeLists.txt
index 018ffa5..effad96 100644
--- a/Tests/PreOrder/Library/CMakeLists.txt
+++ b/Tests/PreOrder/Library/CMakeLists.txt
@@ -1,2 +1 @@
add_library(simpleLib simpleLib.cxx )
-
diff --git a/Tests/QtAutogen/TestMacros.cmake b/Tests/QtAutogen/TestMacros.cmake
index 529592e..a2e0fca 100644
--- a/Tests/QtAutogen/TestMacros.cmake
+++ b/Tests/QtAutogen/TestMacros.cmake
@@ -48,7 +48,6 @@
--build-project ${NAME}
${Autogen_CTEST_OPTIONS}
--build-exe-dir "${_BuildDir}"
- --force-new-ctest-process
--build-options ${build_options} ${Autogen_BUILD_OPTIONS}
${_TestCommand}
)
diff --git a/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER-check.cmake b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER-check.cmake
new file mode 100644
index 0000000..d485f2b
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "ARCHIVER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/ARCHIVER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_NESTED-check.cmake b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_NESTED-check.cmake
new file mode 100644
index 0000000..35c0baa
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_NESTED-check.cmake
@@ -0,0 +1,4 @@
+
+set(reference_file "ARCHIVER_NESTED.txt")
+set(archiver_prefix_expected YES)
+include ("${CMAKE_CURRENT_LIST_DIR}/ARCHIVER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_NESTED_SHELL-check.cmake b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_NESTED_SHELL-check.cmake
new file mode 100644
index 0000000..d0321f2
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_NESTED_SHELL-check.cmake
@@ -0,0 +1,4 @@
+
+set(reference_file "ARCHIVER_NESTED_SHELL.txt")
+set(archiver_prefix_expected YES)
+include ("${CMAKE_CURRENT_LIST_DIR}/ARCHIVER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_SHELL-check.cmake b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_SHELL-check.cmake
new file mode 100644
index 0000000..d485f2b
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-ARCHIVER_SHELL-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "ARCHIVER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/ARCHIVER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-validation.cmake b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-validation.cmake
new file mode 100644
index 0000000..8bb0753
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion-validation.cmake
@@ -0,0 +1,15 @@
+
+if (actual_stdout MATCHES "ARCHIVER:" AND NOT archiver_prefix_expected)
+ set (RunCMake_TEST_FAILED "ARCHIVER: prefix was not expanded.")
+ return()
+endif()
+
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${reference_file}")
+ set (RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/${reference_file}: Reference file not found.")
+ return()
+endif()
+file(READ "${RunCMake_TEST_BINARY_DIR}/${reference_file}" archiver_flag)
+
+if (NOT actual_stdout MATCHES "${archiver_flag}")
+ set (RunCMake_TEST_FAILED "ARCHIVER: was not expanded correctly.")
+endif()
diff --git a/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion.cmake b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion.cmake
new file mode 100644
index 0000000..fa3fc9e
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/ARCHIVER_expansion.cmake
@@ -0,0 +1,66 @@
+
+enable_language(C)
+
+set(cfg_dir)
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+ set(cfg_dir /Debug)
+endif()
+
+set(DUMP_EXE "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/dump${CMAKE_EXECUTABLE_SUFFIX}")
+
+add_executable(dump dump.c)
+
+# Overwrite archive rule to enable command line dump
+set(CMAKE_C_CREATE_STATIC_LIBRARY "\"${DUMP_EXE}\" create_archive <LINK_FLAGS>")
+
+function(add_test_library target_name options)
+ add_library(${target_name} STATIC lib.c)
+ set_property(TARGET ${target_name} PROPERTY STATIC_LIBRARY_OPTIONS "${options}")
+
+ add_dependencies(${target_name} dump)
+endfunction()
+
+# Use ARCHIVER alone
+add_test_library(archiver "ARCHIVER:-foo,bar")
+
+# Use ARCHIVER with SHELL
+add_test_library(archiver_shell "ARCHIVER:SHELL:-foo bar")
+
+# Nested ARCHIVER: prefixes should be preserved as written, only the outermost ARCHIVER: prefix removed
+add_test_library(archiver_nested "ARCHIVER:ARCHIVER:-foo,bar")
+
+# Same with ARCHIVER:SHELL:
+add_test_library(archiver_nested_shell "ARCHIVER:SHELL:ARCHIVER:-foo bar")
+
+# generate reference for ARCHIVER flag
+if (CMAKE_C_ARCHIVER_WRAPPER_FLAG)
+ set(archiver_flag ${CMAKE_C_ARCHIVER_WRAPPER_FLAG})
+ list(GET archiver_flag -1 archiver_space)
+ if (archiver_space STREQUAL " ")
+ list(REMOVE_AT archiver_flag -1)
+ else()
+ set(archiver_space)
+ endif()
+ list (JOIN archiver_flag " " archiver_flag)
+ if (CMAKE_C_ARCHIVER_WRAPPER_FLAG_SEP)
+ set(archiver_sep "${CMAKE_C_ARCHIVER_WRAPPER_FLAG_SEP}")
+
+ set(archiver_flag_nested "${archiver_flag}${archiver_space}ARCHIVER:-foo${archiver_sep}bar")
+ set(archiver_flag_nested_shell "${archiver_flag}${archiver_space}ARCHIVER:-foo${archiver_sep}bar")
+ string (APPEND archiver_flag "${archiver_space}" "-foo${archiver_sep}bar")
+ else()
+ set(archiver_prefix "${archiver_flag}${archiver_space}")
+
+ set(archiver_flag_nested "${archiver_prefix}ARCHIVER:-foo ${archiver_prefix}bar")
+ set(archiver_flag_nested_shell "${archiver_prefix}ARCHIVER:-foo ${archiver_prefix}bar")
+ set (archiver_flag "${archiver_prefix}-foo ${archiver_prefix}bar")
+ endif()
+else()
+ set(archiver_flag_nested "ARCHIVER:-foo bar")
+ set(archiver_flag_nested_shell "ARCHIVER:-foo bar")
+ set(archiver_flag "-foo bar")
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ARCHIVER.txt" "${archiver_flag}")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ARCHIVER_NESTED.txt" "${archiver_flag_nested}")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ARCHIVER_NESTED_SHELL.txt" "${archiver_flag_nested_shell}")
diff --git a/Tests/RunCMake/ARCHIVER-prefix/CMakeLists.txt b/Tests/RunCMake/ARCHIVER-prefix/CMakeLists.txt
new file mode 100644
index 0000000..9051bd3
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.31...3.32)
+
+project(${RunCMake_TEST} LANGUAGES NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ARCHIVER-prefix/RunCMakeTest.cmake b/Tests/RunCMake/ARCHIVER-prefix/RunCMakeTest.cmake
new file mode 100644
index 0000000..4f15e1e
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/RunCMakeTest.cmake
@@ -0,0 +1,30 @@
+
+include(RunCMake)
+
+macro(run_cmake_target test subtest target)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${VERBOSE})
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endmacro()
+
+run_cmake(bad_SHELL_usage)
+
+if(RunCMake_GENERATOR MATCHES "Ninja|Makefile|Xcode|Visual Studio")
+ # Some environments are excluded because they are not able to honor verbose mode
+ if (RunCMake_GENERATOR MATCHES "Xcode|Visual Studio"
+ AND NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+ set(RunCMake_TEST_EXPECT_RESULT ".*")
+ set(VERBOSE "--verbose")
+ endif()
+
+ run_cmake(ARCHIVER_expansion)
+
+ run_cmake_target(ARCHIVER_expansion ARCHIVER archiver)
+ run_cmake_target(ARCHIVER_expansion ARCHIVER_SHELL archiver_shell)
+ run_cmake_target(ARCHIVER_expansion ARCHIVER_NESTED archiver_nested)
+ run_cmake_target(ARCHIVER_expansion ARCHIVER_NESTED_SHELL archiver_nested_shell)
+endif()
diff --git a/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage-result.txt b/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage-stderr.txt b/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage-stderr.txt
new file mode 100644
index 0000000..f72e3bf
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at bad_SHELL_usage.cmake:4 \(add_library\):
+ 'SHELL:' prefix is not supported as part of 'ARCHIVER:' arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:5 \(include\)
diff --git a/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage.cmake b/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage.cmake
new file mode 100644
index 0000000..4ef634e
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/bad_SHELL_usage.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(example STATIC lib.c)
+set_property(TARGET example PROPERTY STATIC_LIBRARY_OPTIONS "ARCHIVER:-foo,SHELL:-bar")
diff --git a/Tests/RunCMake/ARCHIVER-prefix/dump.c b/Tests/RunCMake/ARCHIVER-prefix/dump.c
new file mode 100644
index 0000000..8baa313
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/dump.c
@@ -0,0 +1,13 @@
+
+#include "stdio.h"
+
+int main(int argc, char* argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ printf("%s ", argv[i]);
+ printf("\n");
+
+ return 0;
+}
diff --git a/Tests/RunCMake/ARCHIVER-prefix/lib.c b/Tests/RunCMake/ARCHIVER-prefix/lib.c
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/ARCHIVER-prefix/lib.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Autogen_6/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_6/RunCMakeTest.cmake
index b629a5c..66514f9 100644
--- a/Tests/RunCMake/Autogen_6/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Autogen_6/RunCMakeTest.cmake
@@ -6,6 +6,7 @@
-Dwith_qt_version=${with_qt_version}
"-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
"-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+ "-DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON"
)
if (QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
macro(set_test_variables_for_unwanted_builds)
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
index c3725a4..331d21d 100644
--- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
@@ -77,5 +77,14 @@
\"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:subexe>\"
\"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:sublib>\"
)
+
+ if (RunCMake_GENERATOR MATCHES \"Make\")
+ file(STRINGS \"${CMAKE_BINARY_DIR}/CMakeFiles/topcc.dir/compiler_depend.internal\" deps REGEX \"^.*topccdep\\\\.txt$\")
+ list(LENGTH deps count)
+ if (NOT count EQUAL 1)
+ string(APPEND RunCMake_TEST_FAILED \"dependencies are duplicated\\n\")
+ set(RunCMake_TEST_FAILED \"\${RunCMake_TEST_FAILED}\" PARENT_SCOPE)
+ endif()
+ endif()
endif()
")
diff --git a/Tests/RunCMake/CMP0019/CMakeLists.txt b/Tests/RunCMake/CMP0019/CMakeLists.txt
index 8f85fbf..129b75c 100644
--- a/Tests/RunCMake/CMP0019/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0019/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.10)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake
index 3fee15d..308980c 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-NOWARN-static-NEW)
+enable_language(CXX)
cmake_policy(SET CMP0022 NEW)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake
index 3e4144f..17f71b0 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-NOWARN-static)
+enable_language(CXX)
add_library(foo STATIC empty_vs6_1.cpp)
add_library(bar STATIC empty_vs6_2.cpp)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old.cmake
index c5d3c29..7356e29 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-WARN-empty-old)
+enable_language(CXX)
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake
index b3cb131..0ea4fe5 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-WARN)
+enable_language(CXX)
add_library(foo STATIC empty_vs6_1.cpp)
add_library(bar STATIC empty_vs6_2.cpp)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake
index 03223e8..ba207db 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-WARN-tll)
+enable_language(CXX)
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
index e3552b2..38adcca 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-WARN)
+enable_language(CXX)
cmake_policy(SET CMP0042 NEW)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export.cmake b/Tests/RunCMake/CMP0022/CMP0022-export.cmake
index 06147f3..e121b53 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-export.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-export.cmake
@@ -1,5 +1,5 @@
-project(cmp0022NEW)
+enable_language(CXX)
cmake_policy(SET CMP0022 NEW)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake b/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake
index 171febe..532e204 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake
@@ -1,5 +1,5 @@
-project(cmp0022NEW)
+enable_language(CXX)
cmake_policy(SET CMP0022 NEW)
diff --git a/Tests/RunCMake/CMP0132/CMP0132-OLD-stderr.txt b/Tests/RunCMake/CMP0132/CMP0132-OLD-stderr.txt
new file mode 100644
index 0000000..025665d
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0132-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0132 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0135/CMP0135-OLD-stderr.txt b/Tests/RunCMake/CMP0135/CMP0135-OLD-stderr.txt
new file mode 100644
index 0000000..59a7a58
--- /dev/null
+++ b/Tests/RunCMake/CMP0135/CMP0135-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0135-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0135 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt b/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt
index 1cfb319..b04cd1a 100644
--- a/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt
@@ -1,3 +1,14 @@
+^CMake Deprecation Warning at CMP0139-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0139 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
CMake Error at CMP0139-OLD.cmake:[0-9]+ \(if\):
if given arguments:
@@ -5,4 +16,4 @@
Unknown arguments specified
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 0a96aef..092b147 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -240,6 +240,7 @@
set_property(TEST RunCMake.Ninja APPEND PROPERTY LABELS "Fortran")
set(NinjaMultiConfig_ARGS
-DCYGWIN=${CYGWIN} -DMSYS=${MSYS}
+ -DCMAKE_EXECUTABLE_SUFFIX=${CMAKE_EXECUTABLE_SUFFIX}
)
if(ninja_test_with_qt_version)
list(APPEND NinjaMultiConfig_ARGS
@@ -473,6 +474,7 @@
add_RunCMake_test(LinkItemValidation)
add_RunCMake_test(LinkStatic)
+add_RunCMake_test(ARCHIVER-prefix -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|Fujitsu|FujitsuClang)$")
add_RunCMake_test(MetaCompileFeatures)
endif()
@@ -506,6 +508,12 @@
add_RunCMake_test(find_dependency)
add_RunCMake_test(CompileDefinitions)
add_RunCMake_test(CompileWarningAsError -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
+if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|MSVC"
+ OR (CMAKE_SYSTEM_NAME MATCHES "Linux|Windows" AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
+ OR (CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_C_COMPILER_ID STREQUAL "SunPro")
+ OR (CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_C_COMPILER_ID STREQUAL "XL"))
+ add_RunCMake_test(LinkWarningAsError)
+endif()
set_property(TEST RunCMake.CompileWarningAsError APPEND PROPERTY LABELS "CUDA")
add_RunCMake_test(CompileFeatures -DCMake_NO_C_STANDARD=${CMake_NO_C_STANDARD} -DCMake_NO_CXX_STANDARD=${CMake_NO_CXX_STANDARD})
add_RunCMake_test(Policy)
@@ -875,6 +883,9 @@
-DCMAKE_IMPORT_LIBRARY_PREFIX=${CMAKE_IMPORT_LIBRARY_PREFIX}
-DCMAKE_IMPORT_LIBRARY_SUFFIX=${CMAKE_IMPORT_LIBRARY_SUFFIX}
-DCMAKE_LINK_LIBRARY_FLAG=${CMAKE_LINK_LIBRARY_FLAG})
+add_RunCMake_test(target_link_libraries-LINKER-prefix -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
+ -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+ -DCMAKE_C_COMPILER_FRONTEND_VARIANT=${CMAKE_C_COMPILER_FRONTEND_VARIANT})
add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
-DCMake_TEST_CUDA=${CMake_TEST_CUDA})
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
index a92a4c4..b0833d3 100644
--- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -76,11 +76,16 @@
set(_preset)
endif()
+ set(_make_program)
+ if(RunCMake_MAKE_PROGRAM)
+ set(_make_program -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM})
+ endif()
+
set(RunCMake_TEST_COMMAND ${CMAKE_COMMAND}
${_source_args}
-DRunCMake_TEST=${name}
-DRunCMake_GENERATOR=${RunCMake_GENERATOR}
- -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}
+ ${_make_program}
${_unused_cli}
${_preset}
${ARGN}
diff --git a/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in b/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in
index 4e2c085..d8f2e7b 100644
--- a/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in
+++ b/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in
@@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 3.12)
-set(CTEST_RUN_CURRENT_SCRIPT 0)
get_property(role GLOBAL PROPERTY CMAKE_ROLE)
if(NOT role STREQUAL "CTEST")
diff --git a/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-result.txt b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-result.txt
new file mode 100644
index 0000000..f5c8955
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-result.txt
@@ -0,0 +1 @@
+32
diff --git a/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt
index e6f9325..f6d28a1 100644
--- a/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt
+++ b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt
@@ -1,3 +1,3 @@
Cannot find file: [^
]*/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-build/DartConfiguration.tcl
-Binary directory is not set. No coverage checking will be performed.$
+CTEST_BINARY_DIRECTORY not set
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index b2374ca..0786499 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -355,6 +355,9 @@
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/DartConfiguration.tcl" "
+BuildDirectory: ${RunCMake_TEST_BINARY_DIR}
+")
file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
add_test(PassingTest \"${CMAKE_COMMAND}\" -E echo PassingTestOutput)
add_test(FailingTest \"${CMAKE_COMMAND}\" -E no_such_command)
@@ -375,6 +378,9 @@
set(TRUNCATED_OUTPUT ${expected}) # used in TestOutputTruncation-check.cmake
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/DartConfiguration.tcl" "
+BuildDirectory: ${RunCMake_TEST_BINARY_DIR}
+")
file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
add_test(Truncation_${mode} \"${CMAKE_COMMAND}\" -E echo 123456789)
")
@@ -463,10 +469,14 @@
file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
add_test(ShowOnly \"${CMAKE_COMMAND}\" -E echo)
set_tests_properties(ShowOnly PROPERTIES
- WILL_FAIL true
+ GENERATED_RESOURCE_SPEC_FILE \"/Path/Does/Not/Exist\"
RESOURCE_GROUPS \"2,threads:2,gpus:4;gpus:2,threads:4\"
REQUIRED_FILES RequiredFileDoesNotExist
_BACKTRACE_TRIPLES \"file1;1;add_test;file0;;\"
+ TIMEOUT 1234.5
+ TIMEOUT_SIGNAL_NAME SIGINT
+ TIMEOUT_SIGNAL_GRACE_PERIOD 2.1
+ WILL_FAIL true
USER_DEFINED_A \"User defined property A value\"
USER_DEFINED_B \"User defined property B value\"
)
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt
deleted file mode 100644
index 19310b8..0000000
--- a/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputSize/DartConfiguration.tcl
-Errors while running CTest
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_head-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_head-stderr.txt
deleted file mode 100644
index 30b46ce..0000000
--- a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_head-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputTruncation.*/DartConfiguration.tcl
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_middle-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_middle-stderr.txt
deleted file mode 100644
index 30b46ce..0000000
--- a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_middle-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputTruncation.*/DartConfiguration.tcl
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_tail-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_tail-stderr.txt
deleted file mode 100644
index 30b46ce..0000000
--- a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_tail-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputTruncation.*/DartConfiguration.tcl
diff --git a/Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py b/Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py
index f9667ae..504bd3f 100644
--- a/Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py
+++ b/Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py
@@ -1,3 +1,5 @@
+import sys
+
from show_only_json_check import *
def check_kind(k):
@@ -57,12 +59,20 @@
assert is_list(c)
assert len(c) == 3
assert is_string(c[0])
- check_re(c[0], "/cmake(\.exe)?$")
+ check_re(c[0], r"/cmake(\.exe)?$")
assert is_string(c[1])
assert c[1] == "-E"
assert is_string(c[2])
assert c[2] == "echo"
+def check_generated_resource_spec_file_property(p):
+ assert is_dict(p)
+ assert sorted(p.keys()) == ["name", "value"]
+ assert is_string(p["name"])
+ assert is_string(p["value"])
+ assert p["name"] == "GENERATED_RESOURCE_SPEC_FILE"
+ assert p["value"] == "/Path/Does/Not/Exist"
+
def check_reqfiles_property(p):
assert is_dict(p)
assert sorted(p.keys()) == ["name", "value"]
@@ -72,6 +82,30 @@
assert len(p["value"]) == 1
assert p["value"][0] == "RequiredFileDoesNotExist"
+def check_timeout_property(p):
+ assert is_dict(p)
+ assert sorted(p.keys()) == ["name", "value"]
+ assert is_string(p["name"])
+ assert is_float(p["value"])
+ assert p["name"] == "TIMEOUT"
+ assert p["value"] == 1234.5
+
+def check_timeout_signal_name_property(p):
+ assert is_dict(p)
+ assert sorted(p.keys()) == ["name", "value"]
+ assert is_string(p["name"])
+ assert is_string(p["value"])
+ assert p["name"] == "TIMEOUT_SIGNAL_NAME"
+ assert p["value"] == "SIGINT"
+
+def check_timeout_signal_grace_property(p):
+ assert is_dict(p)
+ assert sorted(p.keys()) == ["name", "value"]
+ assert is_string(p["name"])
+ assert is_float(p["value"])
+ assert p["name"] == "TIMEOUT_SIGNAL_GRACE_PERIOD"
+ assert p["value"] == 2.1
+
def check_willfail_property(p):
assert is_dict(p)
assert sorted(p.keys()) == ["name", "value"]
@@ -155,12 +189,26 @@
def check_properties(p):
assert is_list(p)
- assert len(p) == 6
- check_resource_groups_property(p[0])
- check_reqfiles_property(p[1])
- check_willfail_property(p[2])
- check_workingdir_property(p[3])
- check_defined_properties(p[4:5])
+ if sys.platform in ("win32"):
+ assert len(p) == 8
+ check_generated_resource_spec_file_property(p[0])
+ check_resource_groups_property(p[1])
+ check_reqfiles_property(p[2])
+ check_timeout_property(p[3])
+ check_willfail_property(p[4])
+ check_workingdir_property(p[5])
+ check_defined_properties(p[6:7])
+ else:
+ assert len(p) == 10
+ check_generated_resource_spec_file_property(p[0])
+ check_resource_groups_property(p[1])
+ check_reqfiles_property(p[2])
+ check_timeout_property(p[3])
+ check_timeout_signal_name_property(p[4])
+ check_timeout_signal_grace_property(p[5])
+ check_willfail_property(p[6])
+ check_workingdir_property(p[7])
+ check_defined_properties(p[8:9])
def check_tests(t):
assert is_list(t)
diff --git a/Tests/RunCMake/CTestCommandLine/show_only_json_check.py b/Tests/RunCMake/CTestCommandLine/show_only_json_check.py
index 493c9e5..3310db7 100644
--- a/Tests/RunCMake/CTestCommandLine/show_only_json_check.py
+++ b/Tests/RunCMake/CTestCommandLine/show_only_json_check.py
@@ -14,6 +14,9 @@
def is_int(x):
return isinstance(x, int) or isinstance(x, long)
+def is_float(x):
+ return isinstance(x, float)
+
def is_string(x):
return isinstance(x, str) or isinstance(x, unicode)
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt
index 017ccb0..6b16868 100644
--- a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt
+++ b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt
@@ -1 +1 @@
-Failed to change working directory to ".*/non-existing-dir" : No such file or directory
+Failed to change working directory to ".*/non-existing-dir": No such file or directory
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt
deleted file mode 100644
index ddcd238..0000000
--- a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Internal ctest changing into directory: .*/non-existing-dir
diff --git a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
index 319ebf1..3237ef0 100644
--- a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
+++ b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
@@ -31,10 +31,18 @@
list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/resspec.json")
endif()
+set(test_args)
+if(DEFINED CTEST_PARALLEL)
+ list(APPEND test_args PARALLEL_LEVEL ${CTEST_PARALLEL})
+endif()
+if(DEFINED CTEST_RANDOM)
+ list(APPEND test_args SCHEDULE_RANDOM ${CTEST_RANDOM})
+endif()
+
ctest_start(Experimental QUIET)
ctest_configure(OPTIONS "${config_options}")
ctest_build()
-ctest_test(${resspec} RETURN_VALUE retval PARALLEL_LEVEL ${CTEST_PARALLEL} SCHEDULE_RANDOM ${CTEST_RANDOM})
+ctest_test(${resspec} RETURN_VALUE retval ${test_args})
if(retval)
message(FATAL_ERROR "Tests did not pass")
endif()
diff --git a/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake b/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake
index 470bbd8..6b4b96a 100644
--- a/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake
@@ -34,7 +34,7 @@
target_compile_definitions(TestTimeout PRIVATE SIGNAL)
set_tests_properties(TestTimeout PROPERTIES
TIMEOUT_SIGNAL_NAME SIGUSR1
- TIMEOUT_SIGNAL_GRACE_PERIOD 1.2
+ TIMEOUT_SIGNAL_GRACE_PERIOD 32.1
)
]])
run_ctest_timeout(Signal)
@@ -91,7 +91,7 @@
block()
set(TIMEOUT 4)
set(CASE_TEST_PREFIX_CODE "set(CTEST_TEST_TIMEOUT 2)")
- set(CASE_CMAKELISTS_SUFFIX_CODE "set_property(TEST TestTimeout PROPERTY TIMEOUT 10)\n")
+ set(CASE_CMAKELISTS_SUFFIX_CODE "set_property(TEST TestTimeout PROPERTY TIMEOUT 60)\n")
run_ctest_timeout(PropertyOverridesVar)
endblock()
diff --git a/Tests/RunCMake/CXXModules/check-json.cmake b/Tests/RunCMake/CXXModules/check-json.cmake
index 8d95973..ec15f14 100644
--- a/Tests/RunCMake/CXXModules/check-json.cmake
+++ b/Tests/RunCMake/CXXModules/check-json.cmake
@@ -50,8 +50,8 @@
function (check_json_value path actual_type expect_type actual_value expect_value)
if (NOT actual_type STREQUAL expect_type)
- list(APPEND RunCMake_TEST_FAILED
- "Type mismatch at ${path}: ${actual_type} vs. ${expect_type}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Type mismatch at:\n ${path}\nexpected:\n ${expect_type}\nactual:\n ${actual_type}\n")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
return ()
endif ()
@@ -60,13 +60,13 @@
# Nothing to check
elseif (actual_type STREQUAL BOOLEAN)
if (NOT actual_value STREQUAL expect_value)
- list(APPEND RunCMake_TEST_FAILED
- "Boolean mismatch at ${path}: ${actual_value} vs. ${expect_value}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Boolean mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n")
endif ()
elseif (actual_type STREQUAL NUMBER)
if (NOT actual_value EQUAL expect_value)
- list(APPEND RunCMake_TEST_FAILED
- "Number mismatch at ${path}: ${actual_value} vs. ${expect_value}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Number mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n")
endif ()
elseif (actual_type STREQUAL STRING)
# Allow some values to be ignored.
@@ -79,24 +79,24 @@
string(REPLACE "\\" "/" actual_value_check "${actual_value}")
string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}")
if (NOT actual_value_check MATCHES "^${expect_value_expanded}$")
- list(APPEND RunCMake_TEST_FAILED
- "String mismatch (path regex) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$")
+ string(APPEND RunCMake_TEST_FAILED
+ "String mismatch (path regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n")
endif ()
elseif (expect_value MATCHES "^REGEX:")
if (NOT actual_value MATCHES "^${expect_value_expanded}$")
- list(APPEND RunCMake_TEST_FAILED
- "String mismatch (regex) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$")
+ string(APPEND RunCMake_TEST_FAILED
+ "String mismatch (regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n")
endif ()
elseif (expect_value MATCHES "^PATH:")
string(REPLACE "\\" "/" actual_value_check "${actual_value}")
string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}")
if (NOT actual_value_check STREQUAL "${expect_value_expanded}")
- list(APPEND RunCMake_TEST_FAILED
- "String mismatch (path) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$")
+ string(APPEND RunCMake_TEST_FAILED
+ "String mismatch (path) at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n")
endif ()
elseif (NOT actual_value STREQUAL expect_value_expanded)
- list(APPEND RunCMake_TEST_FAILED
- "String mismatch at ${path}: ${actual_value} vs. ${expect_value_expanded}")
+ string(APPEND RunCMake_TEST_FAILED
+ "String mismatch at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n")
endif ()
elseif (actual_type STREQUAL ARRAY)
check_json_array("${path}" "${actual_value}" "${expect_value}")
@@ -130,11 +130,11 @@
set(iter_len "${actual_len}")
if (actual_len LESS expect_len)
- list(APPEND RunCMake_TEST_FAILED
- "Missing array items at ${path}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Missing array items at:\n ${path}\n")
elseif (expect_len LESS actual_len)
- list(APPEND RunCMake_TEST_FAILED
- "Extra array items at ${path}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Extra array items at:\n ${path}\n")
set(iter_len "${expect_len}")
endif ()
@@ -200,13 +200,13 @@
if (actual_keys_missed)
string(REPLACE ";" ", " actual_keys_missed_text "${actual_keys_missed}")
- list(APPEND RunCMake_TEST_FAILED
- "Extra unexpected members at ${path}: ${actual_keys_missed_text}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Extra unexpected members at:\n ${path}\nactual:\n ${actual_keys_missed_text}\n")
endif ()
if (expect_keys_missed)
string(REPLACE ";" ", " expect_keys_missed_text "${expect_keys_missed}")
- list(APPEND RunCMake_TEST_FAILED
- "Missing expected members at ${path}: ${expect_keys_missed_text}")
+ string(APPEND RunCMake_TEST_FAILED
+ "Missing expected members at\n ${path}\nactual:\n ${expect_keys_missed_text}\n")
endif ()
foreach (key IN LISTS common_keys)
diff --git a/Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stderr.txt b/Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stderr.txt
new file mode 100644
index 0000000..375ab1d
--- /dev/null
+++ b/Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0138-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0138 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CommandLine/C_basic-stdout.txt b/Tests/RunCMake/CommandLine/C_basic-stdout.txt
index 74a938e..1cb0322 100644
--- a/Tests/RunCMake/CommandLine/C_basic-stdout.txt
+++ b/Tests/RunCMake/CommandLine/C_basic-stdout.txt
@@ -1 +1 @@
-loading initial cache file ../C_basic_initial-cache.txt
+loading initial cache file \.\./C_basic_initial-cache.txt
diff --git a/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt b/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt
index 32724f5..700e449 100644
--- a/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt
+++ b/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt
@@ -1 +1,2 @@
-loading initial cache file .*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt
+loading initial cache file [^
+]*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt
diff --git a/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt b/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt
index 862cfeb..c73adbd 100644
--- a/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt
+++ b/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt
@@ -1,2 +1,2 @@
-loading initial cache file .*initial-cache.txt
-.*
+loading initial cache file [^
+]*initial-cache.txt
diff --git a/Tests/RunCMake/Configure/RerunCMake-build5-check.cmake b/Tests/RunCMake/Configure/RerunCMake-build5-check.cmake
new file mode 100644
index 0000000..d740671
--- /dev/null
+++ b/Tests/RunCMake/Configure/RerunCMake-build5-check.cmake
@@ -0,0 +1,4 @@
+file(READ ${stamp} content)
+if(NOT content STREQUAL 5)
+ set(RunCMake_TEST_FAILED "Expected stamp '5' but got: '${content}'")
+endif()
diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake
index 00d3272..9b686e4 100644
--- a/Tests/RunCMake/Configure/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake
@@ -37,6 +37,15 @@
set(RunCMake_TEST_OUTPUT_MERGE 0)
run_cmake_command(RerunCMake-build4 ${CMAKE_COMMAND} --build .)
endif()
+ if(RunCMake_GENERATOR MATCHES "^Ninja")
+ file(REMOVE "${error}")
+ run_cmake(RerunCMake)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
+ # remove cmake_install.cmake to trigger rerun
+ file(REMOVE "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake")
+ file(WRITE "${input}" "5")
+ run_cmake_command(RerunCMake-build5 ${CMAKE_COMMAND} --build .)
+ endif()
endblock()
block()
diff --git a/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake
index 55a9f0d..f1d621b 100644
--- a/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake
+++ b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake
@@ -12,5 +12,6 @@
endfunction()
check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? --build "?.*"?]])
+check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? --install "?.*"?]])
check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? -E touch "?.*"?]])
check("/CMakeFiles/Foo.dir/build.make" [[\+"?.*"? -E true]])
diff --git a/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake
index 3f688ca..077b929 100644
--- a/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake
+++ b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake
@@ -1,9 +1,11 @@
include(ExternalProject)
ExternalProject_Add(Foo
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Foo
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR>
BUILD_JOB_SERVER_AWARE 1
- INSTALL_COMMAND ""
+ INSTALL_COMMAND ${CMAKE_COMMAND} --install <BINARY_DIR>
+ INSTALL_JOB_SERVER_AWARE 1
)
# Add a second step to test JOB_SERVER_AWARE
diff --git a/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
index 8ee6ec1..cab8134 100644
--- a/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
+++ b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
@@ -1,8 +1,8 @@
CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
- The package name passed to `find_package_handle_standard_args`
+ The package name passed to find_package_handle_standard_args\(\)
\(NAMEMISMATCH\) does not match the name of the calling package
\(NameMismatch\). This can lead to problems in calling code that expects
- `find_package` result variables \(e.g., `_FOUND`\) to follow a certain
+ find_package\(\) result variables \(e.g., `_FOUND`\) to follow a certain
pattern.
Call Stack \(most recent call first\):
FindNameMismatch.cmake:[0-9]+ \(find_package_handle_standard_args\)
@@ -11,10 +11,10 @@
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
- The package name passed to `find_package_handle_standard_args`
+ The package name passed to find_package_handle_standard_args\(\)
\(NAMEMISMATCH\) does not match the name of the calling package
\(NameMismatchOld\). This can lead to problems in calling code that expects
- `find_package` result variables \(e.g., `_FOUND`\) to follow a certain
+ find_package\(\) result variables \(e.g., `_FOUND`\) to follow a certain
pattern.
Call Stack \(most recent call first\):
FindNameMismatchOld.cmake:[0-9]+ \(find_package_handle_standard_args\)
diff --git a/Tests/RunCMake/FPHSA/range_ignored-stderr.txt b/Tests/RunCMake/FPHSA/range_ignored-stderr.txt
index 43f2336..24a7dff 100644
--- a/Tests/RunCMake/FPHSA/range_ignored-stderr.txt
+++ b/Tests/RunCMake/FPHSA/range_ignored-stderr.txt
@@ -1,4 +1,4 @@
CMake Warning \(dev\) at .+FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
- `find_package\(\)` specify a version range but the module Pseudo does not
+ find_package\(\) specify a version range but the module Pseudo does not
support this capability. Only the lower endpoint of the range will be
used.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-NEW-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-NEW-stdout.txt
new file mode 100644
index 0000000..a18e8f7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-NEW-stdout.txt
@@ -0,0 +1,3 @@
+-- The following features have been enabled:
+
+ \* Foo, Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-NEW.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-NEW.cmake
new file mode 100644
index 0000000..154d2c0
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-NEW.cmake
@@ -0,0 +1,11 @@
+include(FeatureSummary)
+
+cmake_policy(SET CMP0183 NEW)
+
+set(WITH_FOO 1)
+set(WITH_BAR 1)
+set(WITH_BAZ 0)
+
+add_feature_info(Foo "WITH_FOO AND (WITH_BAR OR WITH_BAZ)" "Foo.")
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN-stderr.txt
new file mode 100644
index 0000000..efd7a4e
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Warning \(dev\) at [^
+]*/Modules/FeatureSummary\.cmake:[0-9]+ \(message\):
+ Policy CMP0183 is not set: add_feature_info\(\) supports full Condition
+ Syntax\. Run "cmake --help-policy CMP0183" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning\.
+Call Stack \(most recent call first\):
+ FeatureSummaryParentheses-CMP0183-WARN\.cmake:[0-9]+ \(add_feature_info\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN-stdout.txt
new file mode 100644
index 0000000..2b4a5ed
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN-stdout.txt
@@ -0,0 +1,7 @@
+-- The following features have been enabled:
+
+ \* Bar, Bar\.
+
+-- The following features have been disabled:
+
+ \* Foo, Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN.cmake
new file mode 100644
index 0000000..3fbd7d3
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryParentheses-CMP0183-WARN.cmake
@@ -0,0 +1,10 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 1)
+set(WITH_BAZ 0)
+
+add_feature_info(Foo "WITH_FOO AND (WITH_BAR OR WITH_BAZ)" "Foo.")
+add_feature_info(Bar "WITH_FOO;WITH_BAR" "Bar.")
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-NEW-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-NEW-stdout.txt
new file mode 100644
index 0000000..a18e8f7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-NEW-stdout.txt
@@ -0,0 +1,3 @@
+-- The following features have been enabled:
+
+ \* Foo, Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-NEW.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-NEW.cmake
new file mode 100644
index 0000000..f60103a
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-NEW.cmake
@@ -0,0 +1,8 @@
+include(FeatureSummary)
+
+cmake_policy(SET CMP0183 NEW)
+
+set(FOO "lower")
+add_feature_info(Foo "FOO MATCHES \"(UPPER|lower)\"" "Foo.")
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-OLD-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-OLD-stdout.txt
new file mode 100644
index 0000000..a18e8f7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-OLD-stdout.txt
@@ -0,0 +1,3 @@
+-- The following features have been enabled:
+
+ \* Foo, Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-OLD.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-OLD.cmake
new file mode 100644
index 0000000..590d202
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryRegex-CMP0183-OLD.cmake
@@ -0,0 +1,8 @@
+include(FeatureSummary)
+
+cmake_policy(SET CMP0183 OLD)
+
+set(FOO "lower")
+add_feature_info(Foo "FOO MATCHES (UPPER|lower)" "Foo.")
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
index c672c16..0a8d344 100644
--- a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
@@ -21,3 +21,7 @@
run_cmake(FeatureSummaryCustomRequiredListA)
run_cmake(FeatureSummaryCustomRequiredListB)
run_cmake(FeatureSummaryCustomDescription)
+run_cmake(FeatureSummaryParentheses-CMP0183-NEW)
+run_cmake(FeatureSummaryParentheses-CMP0183-WARN)
+run_cmake(FeatureSummaryRegex-CMP0183-NEW)
+run_cmake(FeatureSummaryRegex-CMP0183-OLD)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
index b57ab45..27a1c45 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
@@ -51,7 +51,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 43,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -96,7 +96,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -144,7 +144,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -189,7 +189,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -233,7 +233,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -277,7 +277,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 51,
+ "line": 53,
"command": "install",
"hasParent": true
},
@@ -324,7 +324,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 53,
+ "line": 55,
"command": "install",
"hasParent": true
},
@@ -369,7 +369,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 54,
+ "line": 56,
"command": "install",
"hasParent": true
},
@@ -418,7 +418,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 55,
+ "line": 57,
"command": "install",
"hasParent": true
},
@@ -470,7 +470,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 56,
+ "line": 58,
"command": "install",
"hasParent": true
},
@@ -519,7 +519,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 57,
+ "line": 59,
"command": "install",
"hasParent": true
},
@@ -561,7 +561,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 58,
+ "line": 60,
"command": "install",
"hasParent": true
},
@@ -603,7 +603,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 59,
+ "line": 61,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/apple_exe_framework.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/apple_exe_framework.json
index a4c13a8..dd49b39 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/apple_exe_framework.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/apple_exe_framework.json
@@ -26,7 +26,7 @@
"backtrace": null
}
],
- "compileCommandFragments": []
+ "compileCommandFragments": null
}
],
"link": {
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
index c6ff37a..a9c313b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
@@ -16,7 +16,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 6,
+ "line": 8,
"command": "add_executable",
"hasParent": true
},
@@ -64,7 +64,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 6,
+ "line": 8,
"command": "add_executable",
"hasParent": true
},
@@ -114,7 +114,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 7,
+ "line": 9,
"command": "target_link_libraries",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
index 5b58dd1..4a0a43d 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
@@ -16,7 +16,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 5,
+ "line": 7,
"command": "add_library",
"hasParent": true
},
@@ -64,7 +64,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 5,
+ "line": 7,
"command": "add_library",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
index 5e92840..09cbf2d 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
@@ -16,7 +16,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 10,
+ "line": 12,
"command": "add_executable",
"hasParent": true
},
@@ -64,7 +64,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 10,
+ "line": 12,
"command": "add_executable",
"hasParent": true
},
@@ -114,7 +114,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 11,
+ "line": 13,
"command": "target_link_libraries",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
index 8d5faf8..11738b8 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
@@ -16,7 +16,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 9,
+ "line": 11,
"command": "add_library",
"hasParent": true
},
@@ -69,7 +69,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 9,
+ "line": 11,
"command": "add_library",
"hasParent": true
},
@@ -118,7 +118,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -148,7 +148,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -178,7 +178,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 51,
+ "line": 53,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
index df43319..6f636df 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
@@ -16,7 +16,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 14,
+ "line": 16,
"command": "add_executable",
"hasParent": true
},
@@ -64,7 +64,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 14,
+ "line": 16,
"command": "add_executable",
"hasParent": true
},
@@ -114,7 +114,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 15,
+ "line": 17,
"command": "target_link_libraries",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
index 2220581..05312ca 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
@@ -16,7 +16,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 13,
+ "line": 15,
"command": "add_library",
"hasParent": true
},
@@ -64,7 +64,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 13,
+ "line": 15,
"command": "add_library",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
index a5bebcd..2ab99c2 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
@@ -89,7 +89,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 17,
+ "line": 19,
"command": "add_library",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
index 73f9346..16a86c7 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -139,7 +139,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 43,
+ "line": 45,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json
index bbd973b..a1b15ca 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json
@@ -87,13 +87,7 @@
"link": {
"language": "CXX",
"lto": null,
- "commandFragments": [
- {
- "fragment" : ".*",
- "role" : "flags",
- "backtrace": null
- }
- ]
+ "commandFragments": null
},
"archive": null,
"dependencies": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator_args.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator_args.json
index c1a8b0c..24a7550 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator_args.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator_args.json
@@ -91,13 +91,7 @@
"link": {
"language": "CXX",
"lto": null,
- "commandFragments": [
- {
- "fragment" : ".*",
- "role" : "flags",
- "backtrace": null
- }
- ]
+ "commandFragments": null
},
"archive": null,
"dependencies": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json
index 9002368..f5e365c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json
@@ -87,13 +87,7 @@
"link": {
"language": "CXX",
"lto": null,
- "commandFragments": [
- {
- "fragment" : ".*",
- "role" : "flags",
- "backtrace": null
- }
- ]
+ "commandFragments": null
},
"archive": null,
"dependencies": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json
index 06e7a7b..8facf86 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json
@@ -91,13 +91,7 @@
"link": {
"language": "CXX",
"lto": null,
- "commandFragments": [
- {
- "fragment" : ".*",
- "role" : "flags",
- "backtrace": null
- }
- ]
+ "commandFragments": null
},
"archive": null,
"dependencies": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
index 2274e45..f3624d4 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
@@ -94,7 +94,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -124,7 +124,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 46,
+ "line": 48,
"command": "install",
"hasParent": true
},
@@ -154,7 +154,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 51,
+ "line": 53,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
index 5b47814..e737de5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
@@ -28,7 +28,7 @@
},
{
"file": "^codemodel-v2\\.cmake$",
- "line": 3,
+ "line": 5,
"command": "include",
"hasParent": true
},
@@ -91,7 +91,7 @@
},
{
"file": "^codemodel-v2\\.cmake$",
- "line": 3,
+ "line": 5,
"command": "include",
"hasParent": true
},
@@ -134,7 +134,7 @@
},
{
"file": "^codemodel-v2\\.cmake$",
- "line": 3,
+ "line": 5,
"command": "include",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index 5f4019d..c493ce1 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
include("${CMAKE_CURRENT_LIST_DIR}/include_test.cmake")
add_library(c_lib empty.c)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake
index ddf3887..6aa01f4 100644
--- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake
@@ -1,5 +1,7 @@
enable_language (C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
set (win_platforms Windows CYGWIN MSYS)
set (GENERATE_CONTENT [[
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake
index 9c5d932..4f38076 100644
--- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake
@@ -1,5 +1,7 @@
enable_language (C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
set (win_platforms Windows CYGWIN MSYS)
set (GENERATE_CONTENT [[
diff --git a/Tests/RunCMake/GenEx-TARGET_IMPORT_FILE/TARGET_SONAME_IMPORT_FILE.cmake b/Tests/RunCMake/GenEx-TARGET_IMPORT_FILE/TARGET_SONAME_IMPORT_FILE.cmake
index 02ba513..38dae3c 100644
--- a/Tests/RunCMake/GenEx-TARGET_IMPORT_FILE/TARGET_SONAME_IMPORT_FILE.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_IMPORT_FILE/TARGET_SONAME_IMPORT_FILE.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
set (GENERATE_CONTENT [[
macro (CHECK_VALUE test_msg value expected)
if (NOT "${value}" STREQUAL "${expected}")
diff --git a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
index bd7fdd1..e828028 100644
--- a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)
if(RunCMake_TEST STREQUAL "CMP0044-WARN")
- cmake_policy(VERSION 2.8.11) # old enough to not set CMP0044
+ cmake_policy(VERSION 2.8.12) # old enough to not set CMP0044
endif()
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt b/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt
index aa0a9d3..4a30a04 100644
--- a/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt
+++ b/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt
@@ -1,5 +1,3 @@
-\-\- Install configuration:[^
-]*
\-\- Installing:[^
]*
\-\- Installing:[^
diff --git a/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt b/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt
index 61a52b0..9c059b0 100644
--- a/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt
+++ b/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt
@@ -1,30 +1,15 @@
-\[1\/5\] [^
-]*
-\-\- Install configuration:[^
-]*
+\[1\/5\] .*
\-\- Installing:[^
]*
-\[2\/5\] [^
-]*
-\-\- Install configuration:[^
-]*
+\[2\/5\] .*
\-\- Installing:[^
]*
-\[3\/5\] [^
-]*
-\-\- Install configuration:[^
-]*
+\[3\/5\] .*
\-\- Installing:[^
]*
-\[4\/5\] [^
-]*
-\-\- Install configuration:[^
-]*
+\[4\/5\] .*
\-\- Installing:[^
]*
-\[5\/5\] [^
-]*
-\-\- Install configuration:[^
-]*
+\[5\/5\] .*
\-\- Installing:[^
]*
diff --git a/Tests/RunCMake/LinkWarningAsError/CMakeLists.txt b/Tests/RunCMake/LinkWarningAsError/CMakeLists.txt
new file mode 100644
index 0000000..7053dbb
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.31...3.32)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/LinkWarningAsError/RunCMakeTest.cmake b/Tests/RunCMake/LinkWarningAsError/RunCMakeTest.cmake
new file mode 100644
index 0000000..cc81ec6
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/RunCMakeTest.cmake
@@ -0,0 +1,19 @@
+include(RunCMake)
+
+function(run_link_warn test)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ run_cmake_with_options(${test} ${ARGN})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(ARGN MATCHES "--link-no-warning-as-error")
+ # Cause the build system to re-run CMake to verify that this option is preserved.
+ run_cmake_command(${test}-Touch ${CMAKE_COMMAND} -E touch_nocreate CMakeCache.txt)
+ endif()
+ run_cmake_command(${test}-Build ${CMAKE_COMMAND} --build . --verbose)
+endfunction()
+
+run_link_warn(WarnErrorOn1)
+run_link_warn(WarnErrorOn2)
+run_link_warn(WarnErrorOff1)
+run_link_warn(WarnErrorOff2)
+run_link_warn(WarnErrorOnIgnore "--link-no-warning-as-error")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnError-validation.cmake b/Tests/RunCMake/LinkWarningAsError/WarnError-validation.cmake
new file mode 100644
index 0000000..3b8c55f
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnError-validation.cmake
@@ -0,0 +1,20 @@
+
+set(reference_file "${RunCMake_TEST_BINARY_DIR}/WARNING_AS_ERROR.txt")
+if (NOT EXISTS "${reference_file}")
+ set (RunCMake_TEST_FAILED "${reference_file}: Reference file not found.")
+ return()
+endif()
+file(READ "${reference_file}" linker_WarnError)
+
+if(NOT linker_WarnError STREQUAL "UNDEFINED")
+ if(WARNING_AS_ERROR)
+ # Add regex [^-] to avoid matching of MSVC compiler flag /WX-
+ if(NOT actual_stdout MATCHES "${linker_WarnError}[^-]")
+ set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag is missing.")
+ endif()
+ else()
+ if(actual_stdout MATCHES "${linker_WarnError}[^-]")
+ set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag unexpectedly present.")
+ endif()
+ endif()
+endif()
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnError.cmake b/Tests/RunCMake/LinkWarningAsError/WarnError.cmake
new file mode 100644
index 0000000..e4818bf
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnError.cmake
@@ -0,0 +1,54 @@
+
+if(NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR)
+ set(linker_WarnError "UNDEFINED")
+else()
+ set(cfg_dir)
+ get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ if(_isMultiConfig)
+ set(cfg_dir /Debug)
+ endif()
+ set(DUMP_EXE "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/dump${CMAKE_EXECUTABLE_SUFFIX}")
+
+ add_executable(dump dump.c)
+ set_property(TARGET dump PROPERTY LINK_WARNING_AS_ERROR OFF)
+
+ # ensure no temp file nor response file will be used
+ set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+
+ add_executable(main main.c)
+ if (NOT DEFINED CMAKE_LINK_WARNING_AS_ERROR)
+ set_property(TARGET main PROPERTY LINK_WARNING_AS_ERROR ${link_warning_as_error})
+ endif()
+ # use LAUNCH facility to dump linker command
+ set_property(TARGET main PROPERTY RULE_LAUNCH_LINK "\"${DUMP_EXE}\"")
+
+ add_dependencies(main dump)
+
+
+ # generate reference for WARNING_AS_ERROR flag
+ string(REPLACE "LINKER:" "" linker_WarnError "${CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR}")
+ if (CMAKE_C_LINKER_WRAPPER_FLAG)
+ set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+ list(GET linker_flag -1 linker_space)
+ if (linker_space STREQUAL " ")
+ list(REMOVE_AT linker_flag -1)
+ else()
+ set(linker_space)
+ endif()
+ list(JOIN linker_flag " " linker_flag)
+ if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+ string(REPLACE "," "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}" linker_WarnError "${linker_WarnError}")
+ set(linker_WarnError "${linker_flag}${linker_space}${linker_WarnError}")
+ else()
+ set(linker_prefix "${linker_flag}${linker_space}")
+ string(REPLACE "," ";" linker_WarnError "${linker_WarnError}")
+ list(TRANSFORM linker_WarnError PREPEND "${linker_prefix}")
+ list(JOIN linker_WarnError " " linker_WarnError)
+ endif()
+ else()
+ string(REPLACE "," " " linker_WarnError "${linker_WarnError}")
+ endif()
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WARNING_AS_ERROR.txt" "${linker_WarnError}")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOff1-Build-check.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff1-Build-check.cmake
new file mode 100644
index 0000000..77f6de4
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff1-Build-check.cmake
@@ -0,0 +1,4 @@
+
+set(WARNING_AS_ERROR OFF)
+
+include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOff1.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff1.cmake
new file mode 100644
index 0000000..d4e7ba1
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff1.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+
+set(link_warning_as_error OFF)
+
+include(WarnError.cmake)
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOff2-Build-check.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff2-Build-check.cmake
new file mode 100644
index 0000000..77f6de4
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff2-Build-check.cmake
@@ -0,0 +1,4 @@
+
+set(WARNING_AS_ERROR OFF)
+
+include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOff2.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff2.cmake
new file mode 100644
index 0000000..14f1a4c
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOff2.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+
+set(CMAKE_LINK_WARNING_AS_ERROR OFF)
+
+include(WarnError.cmake)
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOn1-Build-check.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn1-Build-check.cmake
new file mode 100644
index 0000000..c395cda
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn1-Build-check.cmake
@@ -0,0 +1,4 @@
+
+set(WARNING_AS_ERROR ON)
+
+include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOn1.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn1.cmake
new file mode 100644
index 0000000..0fa198b
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn1.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+
+set(link_warning_as_error ON)
+
+include(WarnError.cmake)
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOn2-Build-check.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn2-Build-check.cmake
new file mode 100644
index 0000000..c395cda
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn2-Build-check.cmake
@@ -0,0 +1,4 @@
+
+set(WARNING_AS_ERROR ON)
+
+include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOn2.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn2.cmake
new file mode 100644
index 0000000..4fe0f00
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOn2.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+
+set(CMAKE_LINK_WARNING_AS_ERROR ON)
+
+include(WarnError.cmake)
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOnIgnore-Build-check.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOnIgnore-Build-check.cmake
new file mode 100644
index 0000000..77f6de4
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOnIgnore-Build-check.cmake
@@ -0,0 +1,4 @@
+
+set(WARNING_AS_ERROR OFF)
+
+include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
diff --git a/Tests/RunCMake/LinkWarningAsError/WarnErrorOnIgnore.cmake b/Tests/RunCMake/LinkWarningAsError/WarnErrorOnIgnore.cmake
new file mode 100644
index 0000000..0fa198b
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/WarnErrorOnIgnore.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+
+set(link_warning_as_error ON)
+
+include(WarnError.cmake)
diff --git a/Tests/RunCMake/LinkWarningAsError/dump.c b/Tests/RunCMake/LinkWarningAsError/dump.c
new file mode 100644
index 0000000..8baa313
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/dump.c
@@ -0,0 +1,13 @@
+
+#include "stdio.h"
+
+int main(int argc, char* argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ printf("%s ", argv[i]);
+ printf("\n");
+
+ return 0;
+}
diff --git a/Tests/RunCMake/LinkWarningAsError/main.c b/Tests/RunCMake/LinkWarningAsError/main.c
new file mode 100644
index 0000000..402eac3
--- /dev/null
+++ b/Tests/RunCMake/LinkWarningAsError/main.c
@@ -0,0 +1,5 @@
+
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt
index b664fa0..01d446c 100644
--- a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt
@@ -19,7 +19,7 @@
.*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\)
.*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\)
.*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\)
- .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env/test\.cmake:10 \(ctest_read_custom_files\)
+ .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env/test\.cmake:5 \(ctest_read_custom_files\)
Problem reading custom configuration: .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt
index bc89703..2e81bcb 100644
--- a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt
@@ -19,7 +19,7 @@
.*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\)
.*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\)
.*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\)
- .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var/test\.cmake:10 \(ctest_read_custom_files\)
+ .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var/test\.cmake:5 \(ctest_read_custom_files\)
Problem reading custom configuration: .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt
index b10b26d..0586d4f 100644
--- a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt
@@ -11,41 +11,41 @@
Maximum recursion depth of 10 exceeded
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_10\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_10\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_9\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_9\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_8\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_8\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_7\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_7\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_6\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_6\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_5\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_5\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_4\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_4\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_3\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_3\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_2\.cmake:13 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_2\.cmake:8 \(message\):
Nested script failed
-CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var/test\.cmake:19 \(message\):
+CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var/test\.cmake:14 \(message\):
Nested script failed$
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in
index d4f28c4..5646a00 100644
--- a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in
+++ b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in
@@ -1,12 +1,7 @@
cmake_minimum_required(VERSION 3.12)
-set(CTEST_RUN_CURRENT_SCRIPT 0)
message("@LEVEL_CURRENT@")
-set(CTEST_SOURCE_DIRECTORY "@CTEST_SOURCE_DIRECTORY@")
-set(CTEST_BINARY_DIRECTORY "@CTEST_BINARY_DIRECTORY@")
-set(CTEST_COMMAND "@CTEST_COMMAND@")
-
ctest_run_script("${CMAKE_CURRENT_LIST_DIR}/ctest_run_script_@LEVEL_NEXT@.cmake" RETURN_VALUE val)
if(NOT val EQUAL 0)
diff --git a/Tests/RunCMake/MaxRecursionDepth/test.cmake.in b/Tests/RunCMake/MaxRecursionDepth/test.cmake.in
index fd1fc10..62c8e41 100644
--- a/Tests/RunCMake/MaxRecursionDepth/test.cmake.in
+++ b/Tests/RunCMake/MaxRecursionDepth/test.cmake.in
@@ -1,9 +1,4 @@
cmake_minimum_required(VERSION 3.12)
-set(CTEST_RUN_CURRENT_SCRIPT 0)
-
-set(CTEST_SOURCE_DIRECTORY "@RunCMake_SOURCE_DIR@")
-set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@")
-set(CTEST_COMMAND "${CMAKE_CTEST_COMMAND}")
if(TEST_NAME STREQUAL "ctest_read_custom_files")
set(x 2)
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index f1e8b30..aef8870 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -470,6 +470,19 @@
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
+# cmake --install test
+block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/cmake--install-build)
+ run_cmake_with_options(cmake--install
+ -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install
+ -DCMAKE_CROSS_CONFIGS=all
+ -DCMAKE_DEFAULT_CONFIGS=Debug\\\\;Release
+ )
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(cmake--install-build ${CMAKE_COMMAND} --build .)
+ run_cmake_command(cmake--install-install ${CMAKE_COMMAND} --install .)
+endblock()
+
# CudaSimple uses separable compilation, which is currently only supported on NVCC.
if(CMake_TEST_CUDA)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build)
diff --git a/Tests/RunCMake/NinjaMultiConfig/cmake--install-install-check.cmake b/Tests/RunCMake/NinjaMultiConfig/cmake--install-install-check.cmake
new file mode 100644
index 0000000..e6a9f95
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/cmake--install-install-check.cmake
@@ -0,0 +1,4 @@
+if (NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/install/bin/Debug/exe${CMAKE_EXECUTABLE_SUFFIX} OR
+ NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/install/bin/Release/exe${CMAKE_EXECUTABLE_SUFFIX})
+ set(RunCMake_TEST_FAILED "Multi-Config Install with CMAKE_DEFAULT_CONFIGS set did not install all specified configs by default")
+endif()
diff --git a/Tests/RunCMake/NinjaMultiConfig/cmake--install.cmake b/Tests/RunCMake/NinjaMultiConfig/cmake--install.cmake
new file mode 100644
index 0000000..e0c31b5
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/cmake--install.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Install.cmake)
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 6251ca0..30af8a5 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -113,6 +113,9 @@
if(RunCMake_TEST_LCC AND NOT RunCMake_TEST_NO_CMP0129)
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0129=NEW)
endif()
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "AIX")
+ list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0182=NEW)
+ endif()
if(RunCMake_MAKE_PROGRAM)
list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}")
endif()
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 4015ae8..0e57ffd 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -44,6 +44,8 @@
\* CMP0160
\* CMP0162
\* CMP0179
+ \* CMP0181
+ \* CMP0182
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
index 78996e4..423262b 100644
--- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
+++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
@@ -8,10 +8,16 @@
endfunction()
run_cmake(unitybuild_c)
+run_cmake(unitybuild_c_absolute_path)
+run_cmake(unitybuild_c_relocatable_path)
run_cmake(unitybuild_c_batch)
run_cmake(unitybuild_c_group)
run_cmake(unitybuild_cxx)
+run_cmake(unitybuild_cxx_absolute_path)
+run_cmake(unitybuild_cxx_relocatable_path)
run_cmake(unitybuild_cxx_group)
+run_cmake(unitybuild_c_and_cxx_absolute_path)
+run_cmake(unitybuild_c_and_cxx_relocatable_path)
run_cmake(unitybuild_c_and_cxx)
run_cmake(unitybuild_c_and_cxx_group)
if(CMake_TEST_OBJC)
@@ -37,6 +43,7 @@
run_build(unitybuild_anon_ns)
run_build(unitybuild_anon_ns_no_unity_build)
run_build(unitybuild_anon_ns_group_mode)
+run_cmake(unitybuild_relocatable_locations)
function(run_per_config name)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
diff --git a/Tests/RunCMake/UnityBuild/relocatable/foo.c b/Tests/RunCMake/UnityBuild/relocatable/foo.c
new file mode 100644
index 0000000..de1160c
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/relocatable/foo.c
@@ -0,0 +1,5 @@
+int foo(int x)
+{
+ (void)x;
+ return 0;
+}
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-check.cmake
new file mode 100644
index 0000000..e716e93
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-check.cmake
@@ -0,0 +1,17 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_c} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-build/s1\.c"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-build/s2\.c"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-build/s3\.c"]]
+)
+
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain absolute paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path.cmake
new file mode 100644
index 0000000..0fe6fbf
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path.cmake
@@ -0,0 +1,13 @@
+project(unitybuild_c_absolute_path C)
+
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE FALSE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-check.cmake
new file mode 100644
index 0000000..aa41f78
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-check.cmake
@@ -0,0 +1,35 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s1\.c"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s2\.c"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s3\.c"]]
+)
+
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain absolute paths")
+ return()
+endif()
+
+set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx")
+if(NOT EXISTS "${unitybuild_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_cxx} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT_CXX
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s1\.cxx"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s2\.cxx"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s3\.cxx"]]
+)
+
+file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings)
+if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT_CXX}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain absolute paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path.cmake
new file mode 100644
index 0000000..9c6b0e4
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path.cmake
@@ -0,0 +1,18 @@
+project(unitybuild_c_and_cxx_absolute_path C CXX)
+
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src_c}" "int s${s}(void) { return 0; }\n")
+
+ set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src_cxx}" "int s${s}(void) { return 0; }\n")
+
+ list(APPEND srcs "${src_c}")
+ list(APPEND srcs "${src_cxx}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE FALSE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path-check.cmake
new file mode 100644
index 0000000..e5fd4df
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path-check.cmake
@@ -0,0 +1,35 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "\.\./\.\./\.\./s1\.c"]]
+ [[#include "\.\./\.\./\.\./s2\.c"]]
+ [[#include "\.\./\.\./\.\./s3\.c"]]
+)
+
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain relative paths")
+ return()
+endif()
+
+set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx")
+if(NOT EXISTS "${unitybuild_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_cxx} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT_CXX
+ [[#include "\.\./\.\./\.\./s1\.cxx"]]
+ [[#include "\.\./\.\./\.\./s2\.cxx"]]
+ [[#include "\.\./\.\./\.\./s3\.cxx"]]
+)
+
+file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings)
+if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT_CXX}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain relative paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path.cmake
new file mode 100644
index 0000000..21257f4
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path.cmake
@@ -0,0 +1,18 @@
+project(unitybuild_c_and_cxx_relocatable_path C CXX)
+
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src_c}" "int s${s}(void) { return 0; }\n")
+
+ set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src_cxx}" "int s${s}(void) { return 0; }\n")
+
+ list(APPEND srcs "${src_c}")
+ list(APPEND srcs "${src_cxx}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path-check.cmake
new file mode 100644
index 0000000..f8e41ce
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path-check.cmake
@@ -0,0 +1,17 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_c} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "\.\./\.\./\.\./s1\.c"]]
+ [[#include "\.\./\.\./\.\./s2\.c"]]
+ [[#include "\.\./\.\./\.\./s3\.c"]]
+)
+
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain relative paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path.cmake
new file mode 100644
index 0000000..e6046e6
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path.cmake
@@ -0,0 +1,14 @@
+project(unitybuild_c_relocatable_path C)
+
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE TRUE
+ UNITY_BUILD_UNIQUE_ID "anon")
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-check.cmake
new file mode 100644
index 0000000..95d96ec
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-check.cmake
@@ -0,0 +1,17 @@
+set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx")
+if(NOT EXISTS "${unitybuild_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_cxx} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-build/s1\.cxx"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-build/s2\.cxx"]]
+ [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-build/s3\.cxx"]]
+)
+
+file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings)
+if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain absolute paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path.cmake
new file mode 100644
index 0000000..07543f4
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path.cmake
@@ -0,0 +1,13 @@
+project(unitybuild_cxx_absolute_path CXX)
+
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE FALSE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path-check.cmake
new file mode 100644
index 0000000..d06547d
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path-check.cmake
@@ -0,0 +1,17 @@
+set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx")
+if(NOT EXISTS "${unitybuild_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_cxx} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "\.\./\.\./\.\./s1\.cxx"]]
+ [[#include "\.\./\.\./\.\./s2\.cxx"]]
+ [[#include "\.\./\.\./\.\./s3\.cxx"]]
+)
+
+file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings)
+if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain relative paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path.cmake
new file mode 100644
index 0000000..abf672d
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path.cmake
@@ -0,0 +1,13 @@
+project(unitybuild_cxx_relocatable_path CXX)
+
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations-check.cmake
new file mode 100644
index 0000000..565920c
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations-check.cmake
@@ -0,0 +1,22 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_c} does not exist.")
+ return()
+endif()
+
+string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT
+ [[#include "\.\./\.\./\.\./s1\.c"]]
+ [[#include "\.\./\.\./\.\./s2\.c"]]
+ [[#include "\.\./\.\./\.\./s3\.c"]]
+ [[#include "\.\./\.\./\.\./subFolder/sub1\.c"]]
+ [[#include "\.\./\.\./\.\./subFolder/sub2\.c"]]
+ [[#include "\.\./\.\./\.\./subFolder/sub3\.c"]]
+ [[#include "f\.c"]]
+ [[#include "relocatable/foo\.c"]]
+)
+
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}")
+ set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain relative paths")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations.cmake b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations.cmake
new file mode 100644
index 0000000..a28d89e
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations.cmake
@@ -0,0 +1,23 @@
+project(unitybuild_relocatable_locations C)
+
+# Binary path relative source file
+set(srcs "")
+foreach(s RANGE 1 3)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+foreach(s RANGE 1 3)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/subFolder/sub${s}.c")
+ file(WRITE "${src}" "int sub${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+# Source path relative source file
+list(APPEND srcs "${CMAKE_SOURCE_DIR}/f.c")
+list(APPEND srcs "${CMAKE_SOURCE_DIR}/relocatable/foo.c")
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/CSharpSourceGroup/Images/empty.bmp
similarity index 100%
rename from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
rename to Tests/RunCMake/VS10Project/CSharpSourceGroup/Images/empty.bmp
diff --git a/Tests/RunCMake/VS10Project/CustomCommandParallelDisable-check.cmake b/Tests/RunCMake/VS10Project/CustomCommandParallelDisable-check.cmake
new file mode 100644
index 0000000..e0608f6
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CustomCommandParallelDisable-check.cmake
@@ -0,0 +1,42 @@
+# Check whether the 'BuildInParallel' setting is set as expected for a specified project file.
+# Note: if the setting is not present in the project file then it is assumed to be implicitly 'false'.
+function(check_build_in_parallel_setting projectFile expectedEnabled)
+ set(SettingEnabledRegex "<BuildInParallel.*>true</BuildInParallel>")
+ set(SettingDisabledRegex "<BuildInParallel.*>false</BuildInParallel>")
+
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file '${projectFile}' does not exist." PARENT_SCOPE)
+ return()
+ endif()
+
+ set(settingEnabled FALSE)
+ set(settingExplicitlyDisabled FALSE)
+
+ file(STRINGS "${projectFile}" lines)
+
+ foreach(line IN LISTS lines)
+ if(line MATCHES "${SettingEnabledRegex}")
+ set(settingEnabled TRUE)
+ elseif(line MATCHES "${SettingDisabledRegex}")
+ set(settingExplicitlyDisabled TRUE)
+ endif()
+ endforeach()
+
+ if(expectedEnabled)
+ if(NOT settingEnabled)
+ set(RunCMake_TEST_FAILED "Expected 'BuildInParallel' to be enabled for projectFile '${projectFile}' but it was not!" PARENT_SCOPE)
+ endif()
+ if(settingExplicitlyDisabled)
+ set(RunCMake_TEST_FAILED "Expected 'BuildInParallel' to be enabled for projectFile '${projectFile}' but instead found it explicitly disabled!" PARENT_SCOPE)
+ endif()
+ else()
+ if(settingEnabled)
+ set(RunCMake_TEST_FAILED "Expected 'BuildInParallel' to be disabled for projectFile '${projectFile}' but it was not!")
+ endif()
+ endif()
+endfunction()
+
+check_build_in_parallel_setting("${RunCMake_TEST_BINARY_DIR}/foo1.vcxproj" TRUE)
+check_build_in_parallel_setting("${RunCMake_TEST_BINARY_DIR}/bar1.vcxproj" FALSE)
+check_build_in_parallel_setting("${RunCMake_TEST_BINARY_DIR}/foo2.vcxproj" FALSE)
+check_build_in_parallel_setting("${RunCMake_TEST_BINARY_DIR}/bar2.vcxproj" FALSE)
diff --git a/Tests/RunCMake/VS10Project/CustomCommandParallelDisable.cmake b/Tests/RunCMake/VS10Project/CustomCommandParallelDisable.cmake
new file mode 100644
index 0000000..b9ea3ab
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CustomCommandParallelDisable.cmake
@@ -0,0 +1,21 @@
+block()
+ cmake_policy(SET CMP0147 NEW) # Build custom commands in parallel by default
+
+ add_custom_command(OUTPUT "foo.out.txt" COMMAND echo Foo > foo.out.txt MAIN_DEPENDENCY "foo.txt")
+ add_custom_command(OUTPUT "bar.out.txt" COMMAND echo Bar > bar.out.txt MAIN_DEPENDENCY "bar.txt")
+ set_property(SOURCE "bar.txt" PROPERTY VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD TRUE)
+
+ add_custom_target(foo1 SOURCES foo.txt)
+ add_custom_target(bar1 SOURCES bar.txt)
+endblock()
+
+block()
+ cmake_policy(SET CMP0147 OLD) # Don't build custom commands in parallel by default
+
+ add_custom_command(OUTPUT "foo.out.cpp" COMMAND echo Foo > foo.out.txt MAIN_DEPENDENCY "foo.cpp")
+ add_custom_command(OUTPUT "bar.out.cpp" COMMAND echo Bar > bar.out.txt MAIN_DEPENDENCY "bar.cpp")
+ set_property(SOURCE "bar.cpp" PROPERTY VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD TRUE)
+
+ add_custom_target(foo2 SOURCES foo.cpp)
+ add_custom_target(bar2 SOURCES bar.cpp)
+endblock()
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index bbd8c8b..49c345c 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -10,6 +10,7 @@
run_cmake(CustomCommandGenex)
if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio 1[1-5] ")
run_cmake(CustomCommandParallel)
+ run_cmake(CustomCommandParallelDisable)
endif()
run_cmake_with_options(VsCharacterSet -DSET_CHARSET=MultiByte)
run_cmake_with_options(VsCharacterSet -DSET_CHARSET=Unicode)
diff --git a/Tests/RunCMake/VS10Project/SolutionItems-check.cmake b/Tests/RunCMake/VS10Project/SolutionItems-check.cmake
new file mode 100644
index 0000000..a917e0b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/SolutionItems-check.cmake
@@ -0,0 +1,351 @@
+function(MapAppend map key value)
+ list(APPEND "${map}_k" "${key}")
+ list(APPEND "${map}_v" "${value}")
+
+ set("${map}_k" "${${map}_k}" PARENT_SCOPE)
+ set("${map}_v" "${${map}_v}" PARENT_SCOPE)
+endfunction()
+
+function(MapLength map out_variable)
+ list(LENGTH "${map}_k" length)
+ set("${out_variable}" "${length}" PARENT_SCOPE)
+endfunction()
+
+function(MapFind map key out_variable)
+ list(FIND "${map}_k" "${key}" index)
+ if("${index}" LESS 0)
+ unset("${out_variable}" PARENT_SCOPE)
+ else()
+ list(GET "${map}_v" "${index}" value)
+ set("${out_variable}" "${value}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+macro(MapPropagateToParentScope map)
+ set("${map}_k" "${${map}_k}" PARENT_SCOPE)
+ set("${map}_v" "${${map}_v}" PARENT_SCOPE)
+endmacro()
+
+
+function(ParseSln vcSlnFile)
+ if(NOT EXISTS "${vcSlnFile}")
+ set(RunCMake_TEST_FAILED "Solution file ${vcSlnFile} does not exist." PARENT_SCOPE)
+ return()
+ endif()
+
+ set(SCOPE "")
+
+ set(IN_SOLUTION_ITEMS FALSE)
+ set(IN_NESTED_PROJECTS FALSE)
+
+ set(REGUID "\\{[0-9A-F-]+\\}")
+
+ file(STRINGS "${vcSlnFile}" lines)
+ foreach(line IN LISTS lines)
+ string(STRIP "${line}" line)
+
+ # Project(...)
+ if(line MATCHES "Project\\(\"(${REGUID})\"\\) = \"([^\"]+)\", \"([^\"]+)\", \"(${REGUID})\"")
+ if(NOT "${SCOPE}" STREQUAL "")
+ set(RunCMake_TEST_FAILED "Improper nesting of Project" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "Project")
+
+ if("${CMAKE_MATCH_1}" STREQUAL "{2150E333-8FDC-42A3-9474-1A3956D46DE8}")
+ set(GROUP_NAME "${CMAKE_MATCH_2}")
+
+ MapFind(GROUP_PATHS "${GROUP_NAME}" existing_path)
+ if(DEFINED existing_path)
+ set(RunCMake_TEST_FAILED "Duplicate solution items project '${GROUP_NAME}'" PARENT_SCOPE)
+ return()
+ endif()
+
+ MapAppend(GROUP_PATHS "${GROUP_NAME}" "${CMAKE_MATCH_3}")
+ MapAppend(GROUP_GUIDS "${GROUP_NAME}" "${CMAKE_MATCH_4}")
+ endif()
+
+ # EndProject
+ elseif(line STREQUAL "EndProject")
+ if(NOT "${SCOPE}" STREQUAL "Project")
+ set(RunCMake_TEST_FAILED "Improper nesting of EndProject" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "")
+
+ unset(GROUP_NAME)
+
+ # ProjectSection
+ elseif(line MATCHES "ProjectSection\\(([a-zA-Z]+)\\) = ([a-zA-Z]+)")
+ if(NOT "${SCOPE}" STREQUAL "Project")
+ set(RunCMake_TEST_FAILED "Improper nesting of ProjectSection" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "ProjectSection")
+
+ if("${CMAKE_MATCH_1}" STREQUAL "SolutionItems")
+ if(NOT "${CMAKE_MATCH_2}" STREQUAL "preProject")
+ set(RunCMake_TEST_FAILED "SolutionItems must be preProject" PARENT_SCOPE)
+ return()
+ endif()
+
+ set(IN_SOLUTION_ITEMS TRUE)
+ endif()
+
+ # EndProjectSection
+ elseif(line STREQUAL "EndProjectSection")
+ if(NOT "${SCOPE}" STREQUAL "ProjectSection")
+ set(RunCMake_TEST_FAILED "Improper nesting of EndProjectSection" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "Project")
+
+ set(IN_SOLUTION_ITEMS FALSE)
+
+ # Global
+ elseif(line STREQUAL "Global")
+ if(NOT "${SCOPE}" STREQUAL "")
+ set(RunCMake_TEST_FAILED "Improper nesting of Global" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "Global")
+
+ # EndGlobal
+ elseif(line STREQUAL "EndGlobal")
+ if(NOT "${SCOPE}" STREQUAL "Global")
+ set(RunCMake_TEST_FAILED "Improper nesting of EndGlobal" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "")
+
+ # GlobalSection
+ elseif(line MATCHES "GlobalSection\\(([a-zA-Z]+)\\) = ([a-zA-Z]+)")
+ if(NOT "${SCOPE}" STREQUAL "Global")
+ set(RunCMake_TEST_FAILED "Improper nesting of GlobalSection" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "GlobalSection")
+
+ if("${CMAKE_MATCH_1}" STREQUAL "NestedProjects")
+ if(NOT "${CMAKE_MATCH_2}" STREQUAL "preSolution")
+ set(RunCMake_TEST_FAILED "NestedProjects must be preSolution" PARENT_SCOPE)
+ return()
+ endif()
+
+ set(IN_NESTED_PROJECTS TRUE)
+ endif()
+
+ # EndGlobalSection
+ elseif(line STREQUAL "EndGlobalSection")
+ if(NOT "${SCOPE}" STREQUAL "GlobalSection")
+ set(RunCMake_TEST_FAILED "Improper nesting of EndGlobalSection" PARENT_SCOPE)
+ return()
+ endif()
+ set(SCOPE "Global")
+
+ set(IN_NESTED_PROJECTS FALSE)
+
+ # .../solution-item-0-1.txt = .../solution-item-0-1.txt
+ elseif(${IN_SOLUTION_ITEMS})
+ if(NOT line MATCHES "([^=]+)=([^=]+)")
+ set(RunCMake_TEST_FAILED "Invalid solution item paths 1" PARENT_SCOPE)
+ return()
+ endif()
+
+ string(STRIP "${CMAKE_MATCH_1}" CMAKE_MATCH_1)
+ string(STRIP "${CMAKE_MATCH_2}" CMAKE_MATCH_2)
+
+ if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CMAKE_MATCH_2}")
+ set(RunCMake_TEST_FAILED "Invalid solution item paths 2" PARENT_SCOPE)
+ return()
+ endif()
+
+ cmake_path(GET CMAKE_MATCH_1 FILENAME filename)
+ MapAppend(SOLUTION_ITEMS "${filename}" "${GROUP_NAME}")
+
+ # {1EB55F5E...} = {A11E84C6...}
+ elseif(${IN_NESTED_PROJECTS})
+ if(NOT line MATCHES "(${REGUID}) = (${REGUID})")
+ set(RunCMake_TEST_FAILED "Invalid nested project guids" PARENT_SCOPE)
+ return()
+ endif()
+
+ MapFind(PROJECT_PARENTS "${CMAKE_MATCH_1}" existing_parent)
+ if(DEFINED existing_parent)
+ set(RunCMake_TEST_FAILED "Duplicate nested project: '${CMAKE_MATCH_1}'" PARENT_SCOPE)
+ return()
+ endif()
+
+ MapAppend(PROJECT_PARENTS "${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}")
+
+ endif()
+
+ MapPropagateToParentScope(GROUP_PATHS)
+ MapPropagateToParentScope(GROUP_GUIDS)
+ MapPropagateToParentScope(PROJECT_PARENTS)
+ MapPropagateToParentScope(SOLUTION_ITEMS)
+ endforeach()
+endfunction()
+
+
+# Check the root solution:
+block()
+ ParseSln("${RunCMake_TEST_BINARY_DIR}/SolutionItems.sln")
+
+ if(DEFINED RunCMake_TEST_FAILED)
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+ return()
+ endif()
+
+
+ # Check group guids and nesting:
+
+ MapFind(GROUP_GUIDS "Solution Items" root_group_guid)
+ if(NOT DEFINED root_group_guid)
+ set(RunCMake_TEST_FAILED "Solution Items not found" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(GROUP_PATHS "Solution Items" root_group_path)
+ if(NOT "${root_group_path}" STREQUAL "Solution Items")
+ set(RunCMake_TEST_FAILED "Invalid Solution Items path: '${root_group_path}'" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(PROJECT_PARENTS "${root_group_guid}" root_group_parent_guid)
+ if(DEFINED root_group_parent_guid)
+ set(RunCMake_TEST_FAILED "Solution Items is nested" PARENT_SCOPE)
+ return()
+ endif()
+
+ MapFind(GROUP_GUIDS "Outer Group" outer_group_guid)
+ if(NOT DEFINED outer_group_guid)
+ set(RunCMake_TEST_FAILED "Outer Group not found" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(GROUP_PATHS "Outer Group" outer_group_path)
+ if(NOT "${outer_group_path}" STREQUAL "Outer Group")
+ set(RunCMake_TEST_FAILED "Invalid Outer Group path: '${outer_group_path}'" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(PROJECT_PARENTS "${outer_group_guid}" outer_group_parent_guid)
+ if(DEFINED outer_group_parent_guid)
+ set(RunCMake_TEST_FAILED "Outer Group is nested" PARENT_SCOPE)
+ return()
+ endif()
+
+ MapFind(GROUP_GUIDS "Inner Group" inner_group_guid)
+ if(NOT DEFINED inner_group_guid)
+ set(RunCMake_TEST_FAILED "Inner Group not found" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(GROUP_PATHS "Inner Group" inner_group_path)
+ if(NOT "${inner_group_path}" STREQUAL "Outer Group\\Inner Group")
+ set(RunCMake_TEST_FAILED "Invalid Inner Group path: '${inner_group_path}'" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(PROJECT_PARENTS "${inner_group_guid}" inner_group_parent_guid)
+ if(NOT DEFINED inner_group_parent_guid)
+ set(RunCMake_TEST_FAILED "Inner Group is not nested" PARENT_SCOPE)
+ return()
+ endif()
+ if(NOT "${inner_group_parent_guid}" STREQUAL "${outer_group_guid}")
+ set(RunCMake_TEST_FAILED "Inner Group is not nested within Outer Group" PARENT_SCOPE)
+ return()
+ endif()
+
+
+ # Check solution items and nesting:
+ MapLength(SOLUTION_ITEMS solution_item_count)
+ if(NOT "${solution_item_count}" EQUAL 4)
+ set(RunCMake_TEST_FAILED "Unexpected number of solution items: ${solution_item_count}")
+ return()
+ endif()
+
+ MapFind(SOLUTION_ITEMS "solution-item-0-1.txt" group_name)
+ if(NOT DEFINED group_name)
+ set(RunCMake_TEST_FAILED "Solution item not found: solution-item-0-1.txt")
+ return()
+ endif()
+ if(NOT "${group_name}" STREQUAL "Solution Items")
+ set(RunCMake_TEST_FAILED "Invalid group for solution-item-0-1.txt: '${group_name}'")
+ return()
+ endif()
+
+ MapFind(SOLUTION_ITEMS "solution-item-1-1.txt" group_name)
+ if(NOT DEFINED group_name)
+ set(RunCMake_TEST_FAILED "Solution item not found: solution-item-1-1.txt")
+ return()
+ endif()
+ if(NOT "${group_name}" STREQUAL "Outer Group")
+ set(RunCMake_TEST_FAILED "Invalid group for solution-item-1-1.txt: '${group_name}'")
+ return()
+ endif()
+
+ MapFind(SOLUTION_ITEMS "solution-item-2-1.txt" group_name)
+ if(NOT DEFINED group_name)
+ set(RunCMake_TEST_FAILED "Solution item not found: solution-item-2-1.txt")
+ return()
+ endif()
+ if(NOT "${group_name}" STREQUAL "Inner Group")
+ set(RunCMake_TEST_FAILED "Invalid group for solution-item-2-1.txt: '${group_name}'")
+ return()
+ endif()
+
+ MapFind(SOLUTION_ITEMS "solution-item-2-2.txt" group_name)
+ if(NOT DEFINED group_name)
+ set(RunCMake_TEST_FAILED "Solution item not found: solution-item-2-2.txt")
+ return()
+ endif()
+ if(NOT "${group_name}" STREQUAL "Inner Group")
+ set(RunCMake_TEST_FAILED "Invalid group for solution-item-2-2.txt: '${group_name}'")
+ return()
+ endif()
+endblock()
+
+
+# Check the nested solution:
+block()
+ ParseSln("${RunCMake_TEST_BINARY_DIR}/SolutionItems/SolutionItemsSubproject.sln")
+
+ if(DEFINED RunCMake_TEST_FAILED)
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+ return()
+ endif()
+
+
+ # Check group guids and nesting:
+
+ MapFind(GROUP_GUIDS "Extraneous" root_group_guid)
+ if(NOT DEFINED root_group_guid)
+ set(RunCMake_TEST_FAILED "Extraneous not found" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(GROUP_PATHS "Extraneous" root_group_path)
+ if(NOT "${root_group_path}" STREQUAL "Extraneous")
+ set(RunCMake_TEST_FAILED "Invalid Extraneous path: '${root_group_path}'" PARENT_SCOPE)
+ return()
+ endif()
+ MapFind(PROJECT_PARENTS "${root_group_guid}" root_group_parent_guid)
+ if(DEFINED root_group_parent_guid)
+ set(RunCMake_TEST_FAILED "Extraneous is nested" PARENT_SCOPE)
+ return()
+ endif()
+
+
+ # Check solution items and nesting:
+
+ MapLength(SOLUTION_ITEMS solution_item_count)
+ if(NOT "${solution_item_count}" EQUAL 1)
+ set(RunCMake_TEST_FAILED "Unexpected number of solution items: ${solution_item_count}" PARENT_SCOPE)
+ return()
+ endif()
+
+ MapFind(SOLUTION_ITEMS "extraneous.txt" group_name)
+ if(NOT DEFINED group_name)
+ set(RunCMake_TEST_FAILED "Solution item not found: extraneous.txt" PARENT_SCOPE)
+ return()
+ endif()
+ if(NOT "${group_name}" STREQUAL "Extraneous")
+ set(RunCMake_TEST_FAILED "Invalid group for extraneous.txt: '${group_name}'" PARENT_SCOPE)
+ return()
+ endif()
+endblock()
diff --git a/Tests/RunCMake/VS10Project/SolutionItems.cmake b/Tests/RunCMake/VS10Project/SolutionItems.cmake
new file mode 100644
index 0000000..ae4f5a4
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/SolutionItems.cmake
@@ -0,0 +1,4 @@
+set_property(DIRECTORY APPEND PROPERTY VS_SOLUTION_ITEMS solution-item-0-1.txt solution-item-1-1.txt solution-item-2-1.txt solution-item-2-2.txt)
+source_group("Outer Group" FILES solution-item-1-1.txt)
+source_group("Outer Group/Inner Group" REGULAR_EXPRESSION "solution-item-2-[0-9]+\\.txt")
+add_subdirectory(SolutionItems)
diff --git a/Tests/RunCMake/VS10Project/SolutionItems/CMakeLists.txt b/Tests/RunCMake/VS10Project/SolutionItems/CMakeLists.txt
new file mode 100644
index 0000000..320b7a5
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/SolutionItems/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
+project(SolutionItemsSubproject)
+set_property(DIRECTORY APPEND PROPERTY VS_SOLUTION_ITEMS extraneous.txt)
+source_group("Extraneous" REGULAR_EXPRESSION "[^.]+\\.txt")
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/SolutionItems/extraneous.txt
similarity index 100%
copy from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
copy to Tests/RunCMake/VS10Project/SolutionItems/extraneous.txt
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
index 9c9409c..5d1ee3e 100644
--- a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
@@ -11,7 +11,7 @@
set(SOURCE_GROUPS_TO_FIND
"CSharpSourceGroup\\\\foo\\.cs"
"CSharpSourceGroup\\\\nested\\\\baz\\.cs"
- "CSharpSourceGroup\\\\images\\\\empty\\.bmp"
+ "Images\\\\empty\\.bmp"
"VsCsharpSourceGroup\\.png"
"AssemblyInfo\\.cs"
)
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/solution-item-0-1.txt
similarity index 100%
copy from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
copy to Tests/RunCMake/VS10Project/solution-item-0-1.txt
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/solution-item-1-1.txt
similarity index 100%
copy from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
copy to Tests/RunCMake/VS10Project/solution-item-1-1.txt
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/solution-item-2-1.txt
similarity index 100%
copy from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
copy to Tests/RunCMake/VS10Project/solution-item-2-1.txt
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/solution-item-2-2.txt
similarity index 100%
copy from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
copy to Tests/RunCMake/VS10Project/solution-item-2-2.txt
diff --git a/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt b/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt
index da89317..a0098e7 100644
--- a/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt
+++ b/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt
@@ -1 +1 @@
-Failed to change working directory to .*[/\\]buildAndTestNoBuildDir[/\\]CMakeLists.txt :
+Failed to change working directory to ".*[/\\]buildAndTestNoBuildDir[/\\]CMakeLists.txt": (Not a directory|Invalid argument)
diff --git a/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt b/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt
index 3cea890..21d288e 100644
--- a/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt
+++ b/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt
@@ -1 +1 @@
-Failed to change working directory to .*[/\\]dirNotExist-build[/\\]thisDirWillNotExist :
+Failed to change working directory to ".*[/\\]dirNotExist-build[/\\]thisDirWillNotExist": No such file or directory
diff --git a/Tests/RunCMake/XcFramework/RunCMakeTest.cmake b/Tests/RunCMake/XcFramework/RunCMakeTest.cmake
index 64505ff..8c8d970 100644
--- a/Tests/RunCMake/XcFramework/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcFramework/RunCMakeTest.cmake
@@ -104,17 +104,17 @@
create_xcframework(incomplete framework "tvos;watchos")
create_executables(library library)
create_executables(framework framework)
-run_cmake_with_options(create-executable-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+run_cmake_with_options(create-executable-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DCMAKE_OSX_SYSROOT=macosx -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
create_executables(target-library library)
create_executables(target-framework framework)
-run_cmake_with_options(create-executable-target-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+run_cmake_with_options(create-executable-target-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DCMAKE_OSX_SYSROOT=macosx -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
if(RunCMake_GENERATOR STREQUAL "Xcode" AND CMake_TEST_XCODE_VERSION VERSION_GREATER_EQUAL 12)
create_executables(library-link-phase library)
create_executables(framework-link-phase framework)
- run_cmake_with_options(create-executable-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+ run_cmake_with_options(create-executable-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DCMAKE_OSX_SYSROOT=macosx -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
create_executables(target-library-link-phase library)
create_executables(target-framework-link-phase framework)
- run_cmake_with_options(create-executable-target-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+ run_cmake_with_options(create-executable-target-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DCMAKE_OSX_SYSROOT=macosx -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
endif()
# Ensure that .xcframework is found before .framework
diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake
index b42e933..2fafdab 100644
--- a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake
+++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake
@@ -45,6 +45,7 @@
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/ExternalFrameworks/CMakeLists.txt
[[
+cmake_minimum_required(VERSION 3.31)
project(ExternalFrameworks)
add_library(staticFrameworkExt STATIC func6.c)
add_library(sharedFrameworkExt SHARED func7.c)
diff --git a/Tests/RunCMake/block/Scope-POLICIES-stderr.txt b/Tests/RunCMake/block/Scope-POLICIES-stderr.txt
new file mode 100644
index 0000000..84b99aa
--- /dev/null
+++ b/Tests/RunCMake/block/Scope-POLICIES-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Scope-POLICIES\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0139 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/block/Scope-VARIABLES-stderr.txt b/Tests/RunCMake/block/Scope-VARIABLES-stderr.txt
new file mode 100644
index 0000000..458daa7
--- /dev/null
+++ b/Tests/RunCMake/block/Scope-VARIABLES-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Scope-VARIABLES\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0139 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/block/Scope-stderr.txt b/Tests/RunCMake/block/Scope-stderr.txt
new file mode 100644
index 0000000..af84e88
--- /dev/null
+++ b/Tests/RunCMake/block/Scope-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Scope\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0139 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/cmake_host_system_information/MacOS-stdout.txt b/Tests/RunCMake/cmake_host_system_information/MacOS-stdout.txt
new file mode 100644
index 0000000..c86ae92
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MacOS-stdout.txt
@@ -0,0 +1 @@
+-- os_name='(macOS|Mac OS X)'
diff --git a/Tests/RunCMake/cmake_host_system_information/MacOS.cmake b/Tests/RunCMake/cmake_host_system_information/MacOS.cmake
new file mode 100644
index 0000000..d0d213a
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MacOS.cmake
@@ -0,0 +1,3 @@
+set(ENV{MallocGuardEdges} 1) # test tolerating sw_vers stderr
+cmake_host_system_information(RESULT os_name QUERY OS_NAME)
+message(STATUS "os_name='${os_name}'")
diff --git a/Tests/RunCMake/cmake_host_system_information/Registry_BadView2-stderr.txt b/Tests/RunCMake/cmake_host_system_information/Registry_BadView2-stderr.txt
index 201d93a..5a80e7e 100644
--- a/Tests/RunCMake/cmake_host_system_information/Registry_BadView2-stderr.txt
+++ b/Tests/RunCMake/cmake_host_system_information/Registry_BadView2-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at Registry_BadView2.cmake:[0-9]+ \(cmake_host_system_information\):
- cmake_host_system_information given invalid value for "VIEW": BAD_VIEW.
+ cmake_host_system_information given invalid value for VIEW: BAD_VIEW.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
index 76dff4f..3917913 100644
--- a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
@@ -14,6 +14,10 @@
run_cmake(CentOS6)
run_cmake(Debian6)
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+ run_cmake(MacOS)
+endif()
+
run_cmake(UserFallbackScript)
if(RunCMake_GENERATOR MATCHES "Visual Studio")
diff --git a/Tests/RunCMake/cmake_path/RELATIVE_PATH.cmake b/Tests/RunCMake/cmake_path/RELATIVE_PATH.cmake
index 522a899..781d4b0 100644
--- a/Tests/RunCMake/cmake_path/RELATIVE_PATH.cmake
+++ b/Tests/RunCMake/cmake_path/RELATIVE_PATH.cmake
@@ -65,7 +65,7 @@
if (NOT path STREQUAL "")
list (APPEND errors "'${path}' instead of ''")
endif()
-elseif()
+else()
set (path "/a/d")
cmake_path(RELATIVE_PATH path BASE_DIRECTORY "e/d/c")
if (NOT path STREQUAL "")
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt
index af95b5c..9e27918 100644
--- a/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt
+++ b/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt
@@ -1 +1,4 @@
-Upload file not specified
+^CMake Error at .*Tests/RunCMake/ctest_submit/CDashUploadNone/test.cmake:[0-9]+ \(ctest_submit\):
+ Error after keyword "CDASH_UPLOAD":
+
+ missing required value
diff --git a/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt
index 6e17c75..3951524 100644
--- a/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt
+++ b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt
@@ -1,2 +1,2 @@
CMake Error at .*/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE/test.cmake:[0-9]+ \(ctest_submit\):
- Called with more than one value for RETURN_VALUE
+ ctest_submit called with more than one value for RETURN_VALUE
diff --git a/Tests/RunCMake/find_file/REGISTRY_VIEW-no-view-stderr.txt b/Tests/RunCMake/find_file/REGISTRY_VIEW-no-view-stderr.txt
index 28e3e12..bf08f91 100644
--- a/Tests/RunCMake/find_file/REGISTRY_VIEW-no-view-stderr.txt
+++ b/Tests/RunCMake/find_file/REGISTRY_VIEW-no-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_file\):
- find_file missing required argument for "REGISTRY_VIEW"
+ find_file missing required argument for REGISTRY_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/REGISTRY_VIEW-wrong-view-stderr.txt b/Tests/RunCMake/find_file/REGISTRY_VIEW-wrong-view-stderr.txt
index 42843f3..b1630f6 100644
--- a/Tests/RunCMake/find_file/REGISTRY_VIEW-wrong-view-stderr.txt
+++ b/Tests/RunCMake/find_file/REGISTRY_VIEW-wrong-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_file\):
- find_file given invalid value for "REGISTRY_VIEW": WRONG_VIEW
+ find_file given invalid value for REGISTRY_VIEW: WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/Registry-query-stderr.txt b/Tests/RunCMake/find_file/Registry-query-stderr.txt
new file mode 100644
index 0000000..0532022
--- /dev/null
+++ b/Tests/RunCMake/find_file/Registry-query-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0134 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt
index 4d49649..3b0e784 100644
--- a/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt
+++ b/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_file\):
- find_file missing required argument for "VALIDATOR"
+ find_file missing required argument for VALIDATOR
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt
index 7e0eda0..81ede79 100644
--- a/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt
+++ b/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_file\):
- find_file command specified for "VALIDATOR" is not a function: check.
+ find_file command specified for VALIDATOR is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt
index b4125e6..4e8564e 100644
--- a/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt
+++ b/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_file\):
- find_file command specified for "VALIDATOR" is undefined: undefined.
+ find_file command specified for VALIDATOR is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/REGISTRY_VIEW-no-view-stderr.txt b/Tests/RunCMake/find_library/REGISTRY_VIEW-no-view-stderr.txt
index ec1877c..cc387ad 100644
--- a/Tests/RunCMake/find_library/REGISTRY_VIEW-no-view-stderr.txt
+++ b/Tests/RunCMake/find_library/REGISTRY_VIEW-no-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_library\):
- find_library missing required argument for "REGISTRY_VIEW"
+ find_library missing required argument for REGISTRY_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/REGISTRY_VIEW-wrong-view-stderr.txt b/Tests/RunCMake/find_library/REGISTRY_VIEW-wrong-view-stderr.txt
index 3e7f814..1a93992 100644
--- a/Tests/RunCMake/find_library/REGISTRY_VIEW-wrong-view-stderr.txt
+++ b/Tests/RunCMake/find_library/REGISTRY_VIEW-wrong-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_library\):
- find_library given invalid value for "REGISTRY_VIEW": WRONG_VIEW
+ find_library given invalid value for REGISTRY_VIEW: WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/Registry-query-stderr.txt b/Tests/RunCMake/find_library/Registry-query-stderr.txt
new file mode 100644
index 0000000..0532022
--- /dev/null
+++ b/Tests/RunCMake/find_library/Registry-query-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0134 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt
index 6c04aa4..4334b40 100644
--- a/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt
+++ b/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_library\):
- find_library missing required argument for "VALIDATOR"
+ find_library missing required argument for VALIDATOR
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt
index 03e7df9..271434d 100644
--- a/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt
+++ b/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_library\):
- find_library command specified for "VALIDATOR" is not a function: check.
+ find_library command specified for VALIDATOR is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt
index dc7ad9e..ea2ab37 100644
--- a/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt
+++ b/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_library\):
- find_library command specified for "VALIDATOR" is undefined: undefined.
+ find_library command specified for VALIDATOR is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_package/REGISTRY_VIEW-no-view-stderr.txt b/Tests/RunCMake/find_package/REGISTRY_VIEW-no-view-stderr.txt
index 9dbcc93..d628da0 100644
--- a/Tests/RunCMake/find_package/REGISTRY_VIEW-no-view-stderr.txt
+++ b/Tests/RunCMake/find_package/REGISTRY_VIEW-no-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_package\):
- find_package missing required argument for "REGISTRY_VIEW"
+ find_package missing required argument for REGISTRY_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_package/REGISTRY_VIEW-wrong-view-stderr.txt b/Tests/RunCMake/find_package/REGISTRY_VIEW-wrong-view-stderr.txt
index e65af62..3820e14 100644
--- a/Tests/RunCMake/find_package/REGISTRY_VIEW-wrong-view-stderr.txt
+++ b/Tests/RunCMake/find_package/REGISTRY_VIEW-wrong-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_package\):
- find_package given invalid value for "REGISTRY_VIEW": WRONG_VIEW
+ find_package given invalid value for REGISTRY_VIEW: WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_package/Registry-query-stderr.txt b/Tests/RunCMake/find_package/Registry-query-stderr.txt
new file mode 100644
index 0000000..0532022
--- /dev/null
+++ b/Tests/RunCMake/find_package/Registry-query-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0134 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_path/REGISTRY_VIEW-no-view-stderr.txt b/Tests/RunCMake/find_path/REGISTRY_VIEW-no-view-stderr.txt
index 662d2d3..91c467d 100644
--- a/Tests/RunCMake/find_path/REGISTRY_VIEW-no-view-stderr.txt
+++ b/Tests/RunCMake/find_path/REGISTRY_VIEW-no-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_path\):
- find_path missing required argument for "REGISTRY_VIEW"
+ find_path missing required argument for REGISTRY_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/REGISTRY_VIEW-wrong-view-stderr.txt b/Tests/RunCMake/find_path/REGISTRY_VIEW-wrong-view-stderr.txt
index 075d6af..8f6512b 100644
--- a/Tests/RunCMake/find_path/REGISTRY_VIEW-wrong-view-stderr.txt
+++ b/Tests/RunCMake/find_path/REGISTRY_VIEW-wrong-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_path\):
- find_path given invalid value for "REGISTRY_VIEW": WRONG_VIEW
+ find_path given invalid value for REGISTRY_VIEW: WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/Registry-query-stderr.txt b/Tests/RunCMake/find_path/Registry-query-stderr.txt
new file mode 100644
index 0000000..0532022
--- /dev/null
+++ b/Tests/RunCMake/find_path/Registry-query-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0134 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt
index 1dfd064..60b6e14 100644
--- a/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt
+++ b/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_path\):
- find_path missing required argument for "VALIDATOR"
+ find_path missing required argument for VALIDATOR
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt
index 92ee17e..fef7539 100644
--- a/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt
+++ b/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_path\):
- find_path command specified for "VALIDATOR" is not a function: check.
+ find_path command specified for VALIDATOR is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt
index d3e0517..10a5995 100644
--- a/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt
+++ b/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_path\):
- find_path command specified for "VALIDATOR" is undefined: undefined.
+ find_path command specified for VALIDATOR is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/REGISTRY_VIEW-no-view-stderr.txt b/Tests/RunCMake/find_program/REGISTRY_VIEW-no-view-stderr.txt
index dbe38a1..3fe7b7f 100644
--- a/Tests/RunCMake/find_program/REGISTRY_VIEW-no-view-stderr.txt
+++ b/Tests/RunCMake/find_program/REGISTRY_VIEW-no-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_program\):
- find_program missing required argument for "REGISTRY_VIEW"
+ find_program missing required argument for REGISTRY_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/REGISTRY_VIEW-wrong-view-stderr.txt b/Tests/RunCMake/find_program/REGISTRY_VIEW-wrong-view-stderr.txt
index de07095..4a5cfaf 100644
--- a/Tests/RunCMake/find_program/REGISTRY_VIEW-wrong-view-stderr.txt
+++ b/Tests/RunCMake/find_program/REGISTRY_VIEW-wrong-view-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_program\):
- find_program given invalid value for "REGISTRY_VIEW": WRONG_VIEW
+ find_program given invalid value for REGISTRY_VIEW: WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/Registry-query-stderr.txt b/Tests/RunCMake/find_program/Registry-query-stderr.txt
new file mode 100644
index 0000000..0532022
--- /dev/null
+++ b/Tests/RunCMake/find_program/Registry-query-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0134 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt
index b8868af..48486f4 100644
--- a/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt
+++ b/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_program\):
- find_program missing required argument for "VALIDATOR"
+ find_program missing required argument for VALIDATOR
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt
index 1ae5148..fd51d07 100644
--- a/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt
+++ b/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_program\):
- find_program command specified for "VALIDATOR" is not a function: check.
+ find_program command specified for VALIDATOR is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt
index a89ffa0..889a2ca 100644
--- a/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt
+++ b/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_program\):
- find_program command specified for "VALIDATOR" is undefined: undefined.
+ find_program command specified for VALIDATOR is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index c2762ad..93f9270 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -1,7 +1,7 @@
# Assertion macro
macro(check desc actual expect)
if(NOT "x${actual}" STREQUAL "x${expect}")
- message(SEND_ERROR "${desc}: got \"${actual}\", not \"${expect}\"")
+ message(SEND_ERROR "${desc}: got\n \"${actual}\"\nnot\n \"${expect}\"")
endif()
endmacro()
@@ -159,3 +159,11 @@
message(SEND_ERROR "${thisVar} not found in regular variable list.")
endif()
endforeach()
+
+if(UNIX)
+ file(MAKE_DIRECTORY . "${CMAKE_CURRENT_BINARY_DIR}/subdir")
+ file(CREATE_LINK . "${CMAKE_CURRENT_BINARY_DIR}/subdir/symlink-to-dot" SYMBOLIC)
+ get_filename_component(realpath_actual "${CMAKE_CURRENT_BINARY_DIR}/subdir/symlink-to-dot/.." REALPATH)
+ get_filename_component(realpath_expect "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+ check("symlink parent" "${realpath_actual}" "${realpath_expect}")
+endif(UNIX)
diff --git a/Tests/RunCMake/install/RuntimeDependencies-COMPONENTS.cmake b/Tests/RunCMake/install/RuntimeDependencies-COMPONENTS.cmake
index 4727de3..bb32690 100644
--- a/Tests/RunCMake/install/RuntimeDependencies-COMPONENTS.cmake
+++ b/Tests/RunCMake/install/RuntimeDependencies-COMPONENTS.cmake
@@ -34,6 +34,6 @@
check_components("bin1;fw1;fw2;lib1;lib2")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
check_components("bin1;bin2;lib1")
-elseif()
+else()
check_components("bin1;lib1;lib2")
endif()
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake
index 58c5273..ddf94cc 100644
--- a/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake
+++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
add_executable(exe main.c)
add_library(lib1 SHARED obj1.c)
set_property(TARGET lib1 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj3.h)
diff --git a/Tests/RunCMake/install/TARGETS-Defaults.cmake b/Tests/RunCMake/install/TARGETS-Defaults.cmake
index a580657..5c3dfde 100644
--- a/Tests/RunCMake/install/TARGETS-Defaults.cmake
+++ b/Tests/RunCMake/install/TARGETS-Defaults.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
add_executable(exe main.c)
add_library(lib1 SHARED obj1.c)
set_property(TARGET lib1 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj3.h)
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake
index 0e684e1..2195706 100644
--- a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
macro(add_versioned_library NAME)
add_library(${NAME} SHARED obj1.c)
set_target_properties(${NAME} PROPERTIES
diff --git a/Tests/RunCMake/install/TARGETS-OUTPUT_NAME.cmake b/Tests/RunCMake/install/TARGETS-OUTPUT_NAME.cmake
index 67e7069..58a7fe0 100644
--- a/Tests/RunCMake/install/TARGETS-OUTPUT_NAME.cmake
+++ b/Tests/RunCMake/install/TARGETS-OUTPUT_NAME.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
add_executable(test1 main.c)
set_property(TARGET test1 PROPERTY OUTPUT_NAME test1out)
set_property(TARGET test1 PROPERTY RELEASE_OUTPUT_NAME test1rel)
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
index 65c708c..c84d729 100644
--- a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
add_library (func SHARED func.c)
set (binary_dir "${CMAKE_BINARY_DIR}")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/CMakeLists.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/CMakeLists.txt
new file mode 100644
index 0000000..a8cb6d1
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.30...3.32)
+
+project(${RunCMake_TEST} LANGUAGES NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-CMP0181-OLD-validation.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-CMP0181-OLD-validation.cmake
new file mode 100644
index 0000000..45855bc
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-CMP0181-OLD-validation.cmake
@@ -0,0 +1,5 @@
+
+if (NOT actual_stdout MATCHES "LINKER:-foo,bar")
+ set (RunCMake_TEST_FAILED "LINKER: prefix was expanded.")
+ return()
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_CONSUMER-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_CONSUMER-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_CONSUMER-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_SHELL-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_SHELL-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_SHELL-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-validation.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-validation.cmake
new file mode 100644
index 0000000..27adde6
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-validation.cmake
@@ -0,0 +1,15 @@
+
+if (actual_stdout MATCHES "LINKER:" AND NOT linker_prefix_expected)
+ set (RunCMake_TEST_FAILED "LINKER: prefix was not expanded.")
+ return()
+endif()
+
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${reference_file}")
+ set (RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/${reference_file}: Reference file not found.")
+ return()
+endif()
+file(READ "${RunCMake_TEST_BINARY_DIR}/${reference_file}" linker_flag)
+
+if (NOT actual_stdout MATCHES "${linker_flag}")
+ set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion.cmake
new file mode 100644
index 0000000..f71efbd
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion.cmake
@@ -0,0 +1,63 @@
+
+enable_language(C)
+
+set(cfg_dir)
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+ set(cfg_dir /Debug)
+endif()
+set(DUMP_EXE "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/dump${CMAKE_EXECUTABLE_SUFFIX}")
+
+add_executable(dump dump.c)
+
+# ensure no temp file nor response file will be used
+set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
+string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+
+function (add_test_library target_name)
+ add_library(${target_name} SHARED LinkOptionsLib.c)
+
+ # use LAUNCH facility to dump linker command
+ set_property(TARGET ${target_name} PROPERTY RULE_LAUNCH_LINK "\"${DUMP_EXE}\"")
+
+ add_dependencies(${target_name} dump)
+endfunction()
+
+# Use LINKER alone
+add_test_library(linker)
+target_link_libraries(linker PRIVATE "LINKER:-foo,bar")
+
+# Use LINKER with SHELL
+add_test_library(linker_shell)
+target_link_libraries(linker_shell PRIVATE "LINKER:SHELL:-foo bar")
+
+# Propagate LINKER
+add_library(linker_interface INTERFACE)
+target_link_libraries(linker_interface INTERFACE "LINKER:-foo,bar")
+add_test_library(linker_consumer)
+target_link_libraries(linker_consumer PRIVATE linker_interface)
+
+# generate reference for LINKER flag
+if (CMAKE_C_LINKER_WRAPPER_FLAG)
+ set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+ list(GET linker_flag -1 linker_space)
+ if (linker_space STREQUAL " ")
+ list(REMOVE_AT linker_flag -1)
+ else()
+ set(linker_space)
+ endif()
+ list (JOIN linker_flag " " linker_flag)
+ if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+ set(linker_sep "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}")
+
+ string (APPEND linker_flag "${linker_space}" "-foo${linker_sep}bar")
+ else()
+ set(linker_prefix "${linker_flag}${linker_space}")
+
+ set (linker_flag "${linker_prefix}-foo ${linker_prefix}bar")
+ endif()
+else()
+ set(linker_flag "-foo bar")
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-EXE_LINKER_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-EXE_LINKER_FLAGS-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-EXE_LINKER_FLAGS-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-EXE_LINKER_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-EXE_LINKER_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-EXE_LINKER_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-MODULE_LINKER_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-MODULE_LINKER_FLAGS-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-MODULE_LINKER_FLAGS-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-MODULE_LINKER_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-MODULE_LINKER_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-MODULE_LINKER_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-SHARED_LINKER_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-SHARED_LINKER_FLAGS-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-SHARED_LINKER_FLAGS-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-SHARED_LINKER_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-SHARED_LINKER_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-NEW-SHARED_LINKER_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-EXE_LINKER_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-EXE_LINKER_FLAGS-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-EXE_LINKER_FLAGS-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-EXE_LINKER_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-EXE_LINKER_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-EXE_LINKER_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-MODULE_LINKER_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-MODULE_LINKER_FLAGS-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-MODULE_LINKER_FLAGS-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-MODULE_LINKER_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-MODULE_LINKER_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-MODULE_LINKER_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-SHARED_LINKER_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-SHARED_LINKER_FLAGS-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-SHARED_LINKER_FLAGS-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-SHARED_LINKER_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-SHARED_LINKER_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2-CMP0181-OLD-SHARED_LINKER_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2.cmake
new file mode 100644
index 0000000..7cf333a
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion2.cmake
@@ -0,0 +1,56 @@
+
+enable_language(C)
+
+cmake_policy(SET CMP0181 ${CMP0181})
+
+# ensure command line is always displayed and do not use any response file
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+
+if (CMAKE_GENERATOR MATCHES "Borland|NMake")
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
+endif()
+
+
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} LINKER:-foo,bar")
+add_executable(exe_linker_flags main.c)
+
+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} LINKER:-foo,bar")
+add_library(shared_linker_flags SHARED LinkOptionsLib.c)
+
+set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} LINKER:-foo,bar")
+add_library(module_linker_flags MODULE LinkOptionsLib.c)
+
+
+# generate reference for LINKER flag
+if (CMP0181 STREQUAL "NEW")
+ if (CMAKE_C_LINKER_WRAPPER_FLAG)
+ set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+ list(GET linker_flag -1 linker_space)
+ if (linker_space STREQUAL " ")
+ list(REMOVE_AT linker_flag -1)
+ else()
+ set(linker_space)
+ endif()
+ list (JOIN linker_flag " " linker_flag)
+ if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+ set(linker_sep "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}")
+
+ string (APPEND linker_flag "${linker_space}" "-foo${linker_sep}bar")
+ else()
+ set(linker_prefix "${linker_flag}${linker_space}")
+
+ set (linker_flag "${linker_prefix}-foo ${linker_prefix}bar")
+ endif()
+ else()
+ set(linker_flag "-foo bar")
+ endif()
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_EXE_CREATE_LINK_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_EXE_CREATE_LINK_FLAGS-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_EXE_CREATE_LINK_FLAGS-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_EXE_CREATE_LINK_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_EXE_CREATE_LINK_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_EXE_CREATE_LINK_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_MODULE_CREATE_LINK_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_MODULE_CREATE_LINK_FLAGS-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_MODULE_CREATE_LINK_FLAGS-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_MODULE_CREATE_LINK_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_MODULE_CREATE_LINK_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_MODULE_CREATE_LINK_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_SHARED_CREATE_LINK_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_SHARED_CREATE_LINK_FLAGS-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_SHARED_CREATE_LINK_FLAGS-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_SHARED_CREATE_LINK_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_SHARED_CREATE_LINK_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-NEW-C_SHARED_CREATE_LINK_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_EXE_CREATE_LINK_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_EXE_CREATE_LINK_FLAGS-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_EXE_CREATE_LINK_FLAGS-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_EXE_CREATE_LINK_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_EXE_CREATE_LINK_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_EXE_CREATE_LINK_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_MODULE_CREATE_LINK_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_MODULE_CREATE_LINK_FLAGS-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_MODULE_CREATE_LINK_FLAGS-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_MODULE_CREATE_LINK_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_MODULE_CREATE_LINK_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_MODULE_CREATE_LINK_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_SHARED_CREATE_LINK_FLAGS-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_SHARED_CREATE_LINK_FLAGS-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_SHARED_CREATE_LINK_FLAGS-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_SHARED_CREATE_LINK_FLAGS-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_SHARED_CREATE_LINK_FLAGS-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3-CMP0181-OLD-C_SHARED_CREATE_LINK_FLAGS-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3.cmake
new file mode 100644
index 0000000..301570b
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion3.cmake
@@ -0,0 +1,55 @@
+
+enable_language(C)
+
+cmake_policy(SET CMP0181 ${CMP0181})
+
+# ensure command line is always displayed and do not use any response file
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+
+if (CMAKE_GENERATOR MATCHES "Borland|NMake")
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
+endif()
+
+
+set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} LINKER:-foo,bar")
+add_executable(c_exe_create_link_flags main.c)
+
+set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} LINKER:-foo,bar")
+add_library(c_shared_create_link_flags SHARED LinkOptionsLib.c)
+
+set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} LINKER:-foo,bar")
+add_library(c_module_create_link_flags MODULE LinkOptionsLib.c)
+
+# generate reference for LINKER flag
+if (CMP0181 STREQUAL "NEW")
+ if (CMAKE_C_LINKER_WRAPPER_FLAG)
+ set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+ list(GET linker_flag -1 linker_space)
+ if (linker_space STREQUAL " ")
+ list(REMOVE_AT linker_flag -1)
+ else()
+ set(linker_space)
+ endif()
+ list (JOIN linker_flag " " linker_flag)
+ if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+ set(linker_sep "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}")
+
+ string (APPEND linker_flag "${linker_space}" "-foo${linker_sep}bar")
+ else()
+ set(linker_prefix "${linker_flag}${linker_space}")
+
+ set (linker_flag "${linker_prefix}-foo ${linker_prefix}bar")
+ endif()
+ else()
+ set(linker_flag "-foo bar")
+ endif()
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_CONSOLE_EXE-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_CONSOLE_EXE-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_CONSOLE_EXE-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_CONSOLE_EXE-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_CONSOLE_EXE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_CONSOLE_EXE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_WIN32_EXE-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_WIN32_EXE-check.cmake
new file mode 100644
index 0000000..99f5aa3
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_WIN32_EXE-check.cmake
@@ -0,0 +1,3 @@
+
+set(reference_file "LINKER.txt")
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_WIN32_EXE-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_WIN32_EXE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-NEW-C_CREATE_WIN32_EXE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_CONSOLE_EXE-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_CONSOLE_EXE-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_CONSOLE_EXE-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_CONSOLE_EXE-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_CONSOLE_EXE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_CONSOLE_EXE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_WIN32_EXE-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_WIN32_EXE-check.cmake
new file mode 100644
index 0000000..e0d406f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_WIN32_EXE-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_WIN32_EXE-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_WIN32_EXE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4-CMP0181-OLD-C_CREATE_WIN32_EXE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4.cmake
new file mode 100644
index 0000000..4e88e91
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion4.cmake
@@ -0,0 +1,47 @@
+
+enable_language(C)
+
+cmake_policy(SET CMP0181 ${CMP0181})
+
+# ensure command line is always displayed and do not use any response file
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+
+if (CMAKE_GENERATOR MATCHES "Borland|NMake")
+ string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
+endif()
+
+
+set(CMAKE_C_CREATE_WIN32_EXE "${CMAKE_C_CREATE_WIN32_EXE} LINKER:-foo,bar")
+add_executable (c_create_win32_exe WIN32 main.c)
+
+set(CMAKE_C_CREATE_CONSOLE_EXE "${CMAKE_C_CREATE_CONSOLE_EXE} LINKER:-foo,bar")
+add_executable(c_create_console_exe main.c)
+
+
+# generate reference for LINKER flag
+if (CMP0181 STREQUAL "NEW")
+ if (CMAKE_C_LINKER_WRAPPER_FLAG)
+ set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+ list(GET linker_flag -1 linker_space)
+ if (linker_space STREQUAL " ")
+ list(REMOVE_AT linker_flag -1)
+ else()
+ set(linker_space)
+ endif()
+ list (JOIN linker_flag " " linker_flag)
+ if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+ set(linker_sep "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}")
+
+ string (APPEND linker_flag "${linker_space}" "-foo${linker_sep}bar")
+ else()
+ set(linker_prefix "${linker_flag}${linker_space}")
+
+ set (linker_flag "${linker_prefix}-foo ${linker_prefix}bar")
+ endif()
+ else()
+ set(linker_flag "-foo bar")
+ endif()
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LinkOptionsLib.c b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LinkOptionsLib.c
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LinkOptionsLib.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/RunCMakeTest.cmake
new file mode 100644
index 0000000..5cfd519
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/RunCMakeTest.cmake
@@ -0,0 +1,59 @@
+
+include(RunCMake)
+
+macro(run_cmake_target test subtest target)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN})
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endmacro()
+
+
+run_cmake(bad_SHELL_usage)
+
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+ run_cmake(LINKER_expansion)
+
+ run_cmake_target(LINKER_expansion LINKER linker)
+ run_cmake_target(LINKER_expansion LINKER_SHELL linker_shell)
+ run_cmake_target(LINKER_expansion LINKER_CONSUMER linker_consumer)
+endif()
+
+# Some environments are excluded because they are not able to honor verbose mode
+if (RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode|Visual Studio"
+ AND NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+
+ foreach(policy IN ITEMS OLD NEW)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LINKER_expansion2-CMP0181-${policy}-build)
+ run_cmake_with_options(LINKER_expansion2 -DCMP0181=${policy})
+
+ run_cmake_target(LINKER_expansion2-CMP0181-${policy} EXE_LINKER_FLAGS exe_linker_flags --verbose)
+ run_cmake_target(LINKER_expansion2-CMP0181-${policy} SHARED_LINKER_FLAGS shared_linker_flags --verbose)
+ run_cmake_target(LINKER_expansion2-CMP0181-${policy} MODULE_LINKER_FLAGS module_linker_flags --verbose)
+
+
+ if (NOT (RunCMake_GENERATOR MATCHES "Visual Studio" OR CMAKE_C_COMPILER_ID MATCHES "Borland|Embarcadero"))
+ # Visual Studio generator and Borland, Embarcadero compilers do not use these variables
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LINKER_expansion3-CMP0181-${policy}-build)
+ run_cmake_with_options(LINKER_expansion3 -DCMP0181=${policy})
+
+ run_cmake_target(LINKER_expansion3-CMP0181-${policy} C_EXE_CREATE_LINK_FLAGS c_exe_create_link_flags --verbose)
+ if (NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
+ # MSVC compiler does not use these variables
+ run_cmake_target(LINKER_expansion3-CMP0181-${policy} C_SHARED_CREATE_LINK_FLAGS c_shared_create_link_flags --verbose)
+ run_cmake_target(LINKER_expansion3-CMP0181-${policy} C_MODULE_CREATE_LINK_FLAGS c_module_create_link_flags --verbose)
+ endif()
+
+ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LINKER_expansion4-CMP0181-${policy}-build)
+ run_cmake_with_options(LINKER_expansion4 -DCMP0181=${policy})
+
+ run_cmake_target(LINKER_expansion4-CMP0181-${policy} C_CREATE_WIN32_EXE c_create_win32_exe --verbose)
+ run_cmake_target(LINKER_expansion4-CMP0181-${policy} C_CREATE_CONSOLE_EXE c_create_console_exe --verbose)
+ endif()
+ endif()
+ endforeach()
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-stderr.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-stderr.txt
new file mode 100644
index 0000000..d6a298d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at bad_SHELL_usage.cmake:[0-9]+ \(add_library\):
+ 'SHELL:' prefix is not supported as part of 'LINKER:' arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage.cmake
new file mode 100644
index 0000000..e25bef6
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(example SHARED LinkOptionsLib.c)
+target_link_libraries(example PRIVATE "LINKER:-foo,SHELL:-bar")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/dump.c b/Tests/RunCMake/target_link_libraries-LINKER-prefix/dump.c
new file mode 100644
index 0000000..8baa313
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/dump.c
@@ -0,0 +1,13 @@
+
+#include "stdio.h"
+
+int main(int argc, char* argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ printf("%s ", argv[i]);
+ printf("\n");
+
+ return 0;
+}
diff --git a/Tests/FindPackageTest/Exporter/dummy.c b/Tests/RunCMake/target_link_libraries-LINKER-prefix/main.c
similarity index 100%
copy from Tests/FindPackageTest/Exporter/dummy.c
copy to Tests/RunCMake/target_link_libraries-LINKER-prefix/main.c
diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake
index fea2f91..1179c69 100644
--- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake
+++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
# ensure command line is always displayed and do not use any response file
set(CMAKE_VERBOSE_MAKEFILE TRUE)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake
index 0aa11be..86e4c34 100644
--- a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake
+++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
+
if(CMP0156 STREQUAL "NEW")
cmake_policy(SET CMP0156 NEW)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LIBRARIES_PROCESSING.cmake" "set(CMAKE_C_LINK_LIBRARIES_PROCESSING \"${CMAKE_C_LINK_LIBRARIES_PROCESSING}\")\n")
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2.cmake
index f8b3546..f87a684 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-WARN)
+enable_language(CXX)
cmake_policy(SET CMP0023 NEW)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-NEW.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-NEW.cmake
index f0aa63f..211029b 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-NEW.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-NEW.cmake
@@ -1,5 +1,5 @@
-project(CMP0022-WARN)
+enable_language(CXX)
cmake_policy(SET CMP0023 NEW)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
index a5bf2fb..a175a61 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
@@ -1,5 +1,5 @@
cmake_policy(VERSION 2.8.11)
-project(CMP0022-WARN)
+enable_language(CXX)
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
index d6f34a1..7fbb70e 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
@@ -1,5 +1,5 @@
cmake_policy(VERSION 2.8.11)
-project(CMP0022-WARN)
+enable_language(CXX)
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
diff --git a/Tests/RunCMake/while/CMP0130-OLD-stderr.txt b/Tests/RunCMake/while/CMP0130-OLD-stderr.txt
new file mode 100644
index 0000000..e673966
--- /dev/null
+++ b/Tests/RunCMake/while/CMP0130-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0130-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0130 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/SBCS/CMakeLists.txt b/Tests/SBCS/CMakeLists.txt
index b3c3c2c..12905d8 100644
--- a/Tests/SBCS/CMakeLists.txt
+++ b/Tests/SBCS/CMakeLists.txt
@@ -1,4 +1,4 @@
-# a SBCS test case
+cmake_minimum_required(VERSION 3.10)
project (SBCS)
add_definitions(-D_SBCS)
diff --git a/Tests/SharedLibraryArchive/CMakeLists.txt b/Tests/SharedLibraryArchive/CMakeLists.txt
index cc961f1..e02b3a2 100644
--- a/Tests/SharedLibraryArchive/CMakeLists.txt
+++ b/Tests/SharedLibraryArchive/CMakeLists.txt
@@ -42,3 +42,24 @@
if(aix_sla)
message(FATAL_ERROR "AIX_SHARED_LIBRARY_ARCHIVE initialized on imported target")
endif()
+
+unset(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE)
+cmake_policy(SET CMP0182 NEW)
+
+add_library(sla_CMP0182 SHARED sla.c)
+get_property(aix_sla_CMP0182 TARGET sla_CMP0182 PROPERTY AIX_SHARED_LIBRARY_ARCHIVE)
+if(aix_sla_CMP0182)
+ message(FATAL_ERROR "AIX_SHARED_LIBRARY_ARCHIVE initialized without CMAKE_AIX_SHARED_LIBRARY_ARCHIVE")
+endif()
+add_custom_command(TARGET sla_CMP0182 POST_BUILD VERBATIM
+ COMMAND ${CMAKE_COMMAND} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -Dsla=$<TARGET_FILE:sla_CMP0182> -Dname=sla_CMP0182 -Dsoversion= -P${CMAKE_CURRENT_SOURCE_DIR}/sla-check.cmake
+ )
+
+add_executable(UseSLA_CMP0182 use_sla.c)
+target_link_libraries(UseSLA_CMP0182 PRIVATE sla_CMP0182)
+
+add_library(nosla_CMP0182 SHARED sla.c)
+set_property(TARGET nosla_CMP0182 PROPERTY AIX_SHARED_LIBRARY_ARCHIVE OFF)
+add_custom_command(TARGET nosla_CMP0182 POST_BUILD VERBATIM
+ COMMAND ${CMAKE_COMMAND} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -Dnosla=$<TARGET_FILE:nosla_CMP0182> -Dname=nosla_CMP0182 -P${CMAKE_CURRENT_SOURCE_DIR}/nosla-check.cmake
+ )
diff --git a/Tests/SharedLibraryArchive/nosla-check.cmake b/Tests/SharedLibraryArchive/nosla-check.cmake
new file mode 100644
index 0000000..de4f072
--- /dev/null
+++ b/Tests/SharedLibraryArchive/nosla-check.cmake
@@ -0,0 +1,6 @@
+if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ set(nosla_regex "/lib${name}\\.so$")
+ if(NOT nosla MATCHES "${nosla_regex}")
+ message(FATAL_ERROR "nosla library does not look like a shared object:\n ${nosla}")
+ endif()
+endif()
diff --git a/Tests/SubDirSpaces/CMakeLists.txt b/Tests/SubDirSpaces/CMakeLists.txt
index 050ce93..de21068 100644
--- a/Tests/SubDirSpaces/CMakeLists.txt
+++ b/Tests/SubDirSpaces/CMakeLists.txt
@@ -74,4 +74,3 @@
if(CMAKE_PAREN)
target_link_libraries(TestWithAuxSourceDir testOddPath)
endif()
-
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index ba36c10..26f75f3 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -32,6 +32,8 @@
add_subdirectory(SubD)
add_subdirectory(SubE)
+add_subdirectory("Sub Space")
+
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
add_executable(SwiftOnly main.swift)
diff --git a/Tests/SwiftOnly/Sub Space/CMakeLists.txt b/Tests/SwiftOnly/Sub Space/CMakeLists.txt
new file mode 100644
index 0000000..ac4cd18
--- /dev/null
+++ b/Tests/SwiftOnly/Sub Space/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(SubSpace SubSpace.swift)
diff --git a/Tests/SwiftOnly/Sub Space/SubSpace.swift b/Tests/SwiftOnly/Sub Space/SubSpace.swift
new file mode 100644
index 0000000..d17aa41
--- /dev/null
+++ b/Tests/SwiftOnly/Sub Space/SubSpace.swift
@@ -0,0 +1 @@
+public func space() { print("space") }
diff --git a/Tests/TestDriver/CMakeLists.txt b/Tests/TestDriver/CMakeLists.txt
index 20b265d..070a034 100644
--- a/Tests/TestDriver/CMakeLists.txt
+++ b/Tests/TestDriver/CMakeLists.txt
@@ -12,4 +12,3 @@
EXTRA_INCLUDE testArgs.h FUNCTION testProccessArgs)
add_executable(TestDriverTest ${testSrcs} ${Extra_SRCS})
-
diff --git a/Tests/Testing/DartConfig.cmake b/Tests/Testing/DartConfig.cmake
index de6ea4b..7c2171b 100644
--- a/Tests/Testing/DartConfig.cmake
+++ b/Tests/Testing/DartConfig.cmake
@@ -21,4 +21,3 @@
# set (SMTP_MAILHOST "")
# set (CONTINUOUS_MONITOR_LIST "")
# set (CONTINUOUS_BASE_URL "")
-
diff --git a/Tests/VSExternalInclude/Lib1/CMakeLists.txt b/Tests/VSExternalInclude/Lib1/CMakeLists.txt
index 9dfac86..333acd1 100644
--- a/Tests/VSExternalInclude/Lib1/CMakeLists.txt
+++ b/Tests/VSExternalInclude/Lib1/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
set(CMAKE_SUPPRESS_REGENERATION 1)
project(LIB1)
diff --git a/Tests/VSExternalInclude/Lib2/CMakeLists.txt b/Tests/VSExternalInclude/Lib2/CMakeLists.txt
index f451354..9d5ce10 100644
--- a/Tests/VSExternalInclude/Lib2/CMakeLists.txt
+++ b/Tests/VSExternalInclude/Lib2/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.10)
set(CMAKE_SUPPRESS_REGENERATION 1)
project(VSEXTERNAL_LIB2)
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 111bd6f..64f9a3f 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index ed7b631..a919b91 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in
index dca6794..8ff9b0e 100644
--- a/Utilities/Sphinx/conf.py.in
+++ b/Utilities/Sphinx/conf.py.in
@@ -91,7 +91,8 @@
linkcheck_ignore = [
r'about:',
r'https://gitlab\.kitware\.com/cmake/community/-/wikis/doc/cpack',
- r'https://www.intel.com/',
+ r'https://www\.intel\.com/',
+ r'https://www\.tasking\.com($|/)',
]
linkcheck_allowed_redirects = {
diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h
index 42e3446..94113d1 100644
--- a/Utilities/cmlibuv/include/uv.h
+++ b/Utilities/cmlibuv/include/uv.h
@@ -1087,7 +1087,13 @@
* search for the exact file name before trying variants with
* extensions like '.exe' or '.cmd'.
*/
- UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7)
+ UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7),
+ /*
+ * Spawn the child process with the error mode of its parent.
+ * This option is only meaningful on Windows systems. On Unix
+ * it is silently ignored.
+ */
+ UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE = (1 << 8)
};
/*
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c
index ebe185d..729a44b 100644
--- a/Utilities/cmlibuv/src/unix/process.c
+++ b/Utilities/cmlibuv/src/unix/process.c
@@ -1033,7 +1033,8 @@
UV_PROCESS_WINDOWS_HIDE |
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
UV_PROCESS_WINDOWS_HIDE_GUI |
- UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
+ UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE)));
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
QUEUE_INIT(&process->queue);
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c
index 5cf9fb8..59db8f8 100644
--- a/Utilities/cmlibuv/src/win/process.c
+++ b/Utilities/cmlibuv/src/win/process.c
@@ -90,7 +90,6 @@
info.BasicLimitInformation.LimitFlags =
JOB_OBJECT_LIMIT_BREAKAWAY_OK |
JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK |
- JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION |
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
uv_global_job_handle_ = CreateJobObjectW(&attr, NULL);
@@ -993,7 +992,8 @@
UV_PROCESS_WINDOWS_HIDE |
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
UV_PROCESS_WINDOWS_HIDE_GUI |
- UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
+ UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE)));
err = uv__utf8_to_utf16_alloc(options->file, &application);
if (err)
@@ -1097,7 +1097,10 @@
startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);
- process_flags = CREATE_UNICODE_ENVIRONMENT;
+ process_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_DEFAULT_ERROR_MODE;
+ if (options->flags & UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE) {
+ process_flags &= ~(CREATE_DEFAULT_ERROR_MODE);
+ }
if ((options->flags & UV_PROCESS_WINDOWS_HIDE_CONSOLE) ||
(options->flags & UV_PROCESS_WINDOWS_HIDE)) {
diff --git a/bootstrap b/bootstrap
index 53358d5..b41197f 100755
--- a/bootstrap
+++ b/bootstrap
@@ -315,7 +315,6 @@
cmCMakePolicyCommand \
cmCPackPropertiesGenerator \
cmCacheManager \
- cmCommand \
cmCommandArgumentParserHelper \
cmCommands \
cmCommonTargetGenerator \
@@ -459,6 +458,7 @@
cmOutputConverter \
cmParseArgumentsCommand \
cmPathLabel \
+ cmPathResolver \
cmPolicies \
cmProcessOutput \
cmProjectCommand \
@@ -843,7 +843,6 @@
s/@KWSYS_NAME_IS_KWSYS@/${KWSYS_NAME_IS_KWSYS}/g;
s/@KWSYS_STL_HAS_WSTRING@/${KWSYS_STL_HAS_WSTRING}/g;
s/@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@/${KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H}/g;
- s/@KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP@/${KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP}/g;
}" "${INFILE}" >> "${OUTFILE}${_tmp}"
if test -f "${OUTFILE}${_tmp}"; then
if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
@@ -1563,7 +1562,6 @@
KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=0
KWSYS_CXX_HAS_UTIMENSAT=0
KWSYS_CXX_HAS_UTIMES=0
-KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP=1
if cmake_try_run "${cmake_cxx_compiler}" \
"${cmake_cxx_flags} ${cmake_ld_flags} -DTEST_KWSYS_CXX_HAS_SETENV" \