summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--Help/command/message.rst5
-rw-r--r--Help/command/string.rst175
-rw-r--r--Help/guide/tutorial/index.rst14
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/release/dev/cpack-install-scripts.rst5
-rw-r--r--Help/release/dev/message-indent.rst5
-rw-r--r--Help/variable/CMAKE_MESSAGE_INDENT.rst30
-rw-r--r--Help/variable/CPACK_INSTALL_SCRIPT.rst8
-rw-r--r--Modules/CPack.cmake16
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackGenerator.cxx16
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx17
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx305
-rw-r--r--Source/CTest/cmCTestTestHandler.h13
-rw-r--r--Source/cmCPluginAPI.cxx2
-rw-r--r--Source/cmCommand.cxx42
-rw-r--r--Source/cmCommand.h33
-rw-r--r--Source/cmCommands.cxx9
-rw-r--r--Source/cmConditionEvaluator.cxx4
-rw-r--r--Source/cmDisallowedCommand.cxx6
-rw-r--r--Source/cmEnableTestingCommand.cxx11
-rw-r--r--Source/cmEnableTestingCommand.h26
-rw-r--r--Source/cmExecutionStatus.h19
-rw-r--r--Source/cmFileCopier.cxx7
-rw-r--r--Source/cmForEachCommand.cxx2
-rw-r--r--Source/cmFunctionCommand.cxx74
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx4
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h2
-rw-r--r--Source/cmGeneratorTarget.cxx533
-rw-r--r--Source/cmIfCommand.cxx19
-rw-r--r--Source/cmIfCommand.h39
-rw-r--r--Source/cmLoadCommandCommand.cxx3
-rw-r--r--Source/cmLocalGenerator.cxx12
-rw-r--r--Source/cmMacroCommand.cxx54
-rw-r--r--Source/cmMakefile.cxx13
-rw-r--r--Source/cmMessageCommand.cxx52
-rw-r--r--Source/cmReturnCommand.cxx4
-rw-r--r--Source/cmReturnCommand.h30
-rw-r--r--Source/cmState.cxx78
-rw-r--r--Source/cmState.h20
-rw-r--r--Source/cmUnexpectedCommand.cxx22
-rw-r--r--Source/cmUnexpectedCommand.h40
-rw-r--r--Source/cmVariableWatchCommand.cxx2
-rw-r--r--Source/cmWhileCommand.cxx14
-rw-r--r--Source/cmWhileCommand.h34
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake11
-rw-r--r--Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/ExpectedFiles.cmake (renamed from Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake)0
-rw-r--r--Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake26
-rw-r--r--Tests/RunCMake/message/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/message/message-indent-multiline-stderr.txt3
-rw-r--r--Tests/RunCMake/message/message-indent-multiline-stdout.txt8
-rw-r--r--Tests/RunCMake/message/message-indent-multiline.cmake13
-rw-r--r--Tests/RunCMake/message/message-indent-stdout.txt13
-rw-r--r--Tests/RunCMake/message/message-indent.cmake19
-rw-r--r--Utilities/cmcurl/CMakeLists.txt7
-rwxr-xr-xbootstrap22
60 files changed, 1013 insertions, 951 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 399e79c..5efa077 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -429,10 +429,7 @@ macro (CMAKE_BUILD_UTILITIES)
set(_CMAKE_USE_OPENSSL_DEFAULT OFF)
if(NOT DEFINED CMAKE_USE_OPENSSL AND NOT WIN32 AND NOT APPLE
AND CMAKE_SYSTEM_NAME MATCHES "(Linux|FreeBSD)")
- find_package(OpenSSL QUIET)
- if(OPENSSL_FOUND)
- set(_CMAKE_USE_OPENSSL_DEFAULT ON)
- endif()
+ set(_CMAKE_USE_OPENSSL_DEFAULT ON)
endif()
option(CMAKE_USE_OPENSSL "Use OpenSSL." ${_CMAKE_USE_OPENSSL_DEFAULT})
mark_as_advanced(CMAKE_USE_OPENSSL)
diff --git a/Help/command/message.rst b/Help/command/message.rst
index 5dca6b4..3002842 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -60,6 +60,11 @@ messages one at a time on a status line and other messages in an
interactive pop-up box. The ``--loglevel`` command-line option to each of
these tools can be used to control which messages will be shown.
+Messages of log levels ``NOTICE`` and below will also have each line preceded
+by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
+a single string by concatenating its list items). For ``STATUS`` to ``TRACE``
+messages, this indenting content will be inserted after the hyphens.
+
CMake Warning and Error message text displays using a simple markup
language. Non-indented text is formatted in line-wrapped paragraphs
delimited by newlines. Indented text is considered pre-formatted.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 2e89d7b..81a2061 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -22,8 +22,8 @@ Synopsis
string(`PREPEND`_ <string-var> [<input>...])
string(`CONCAT`_ <out-var> [<input>...])
string(`JOIN`_ <glue> <out-var> [<input>...])
- string(`TOLOWER`_ <string1> <out-var>)
- string(`TOUPPER`_ <string1> <out-var>)
+ string(`TOLOWER`_ <string> <out-var>)
+ string(`TOUPPER`_ <string> <out-var>)
string(`LENGTH`_ <string> <out-var>)
string(`SUBSTRING`_ <string> <begin> <length> <out-var>)
string(`STRIP`_ <string> <out-var>)
@@ -38,7 +38,7 @@ Synopsis
`Generation`_
string(`ASCII`_ <number>... <out-var>)
- string(`CONFIGURE`_ <string1> <out-var> [...])
+ string(`CONFIGURE`_ <string> <out-var> [...])
string(`MAKE_C_IDENTIFIER`_ <string> <out-var>)
string(`RANDOM`_ [<option>...] <out-var>)
string(`TIMESTAMP`_ <out-var> [<format string>] [UTC])
@@ -51,23 +51,28 @@ Search and Replace
.. code-block:: cmake
- string(FIND <string> <substring> <output variable> [REVERSE])
+ string(FIND <string> <substring> <output_variable> [REVERSE])
-Return the position where the given substring was found in
-the supplied string. If the ``REVERSE`` flag was used, the command will
+Return the position where the given ``<substring>`` was found in
+the supplied ``<string>``. If the ``REVERSE`` flag was used, the command will
search for the position of the last occurrence of the specified
-substring. If the substring is not found, a position of -1 is returned.
+``<substring>``. If the ``<substring>`` is not found, a position of -1 is
+returned.
+
+The ``string(FIND)`` subcommand treats all strings as ASCII-only characters.
+The index stored in ``<output_variable>`` will also be counted in bytes,
+so strings containing multi-byte characters may lead to unexpected results.
.. _REPLACE:
.. code-block:: cmake
string(REPLACE <match_string>
- <replace_string> <output variable>
+ <replace_string> <output_variable>
<input> [<input>...])
-Replace all occurrences of ``match_string`` in the input
-with ``replace_string`` and store the result in the output.
+Replace all occurrences of ``<match_string>`` in the ``<input>``
+with ``<replace_string>`` and store the result in the ``<output_variable>``.
Regular Expressions
^^^^^^^^^^^^^^^^^^^
@@ -77,9 +82,10 @@ Regular Expressions
.. code-block:: cmake
string(REGEX MATCH <regular_expression>
- <output variable> <input> [<input>...])
+ <output_variable> <input> [<input>...])
-Match the regular expression once and store the match in the output variable.
+Match the ``<regular_expression>`` once and store the match in the
+``<output_variable>``.
All ``<input>`` arguments are concatenated before matching.
.. _`REGEX MATCHALL`:
@@ -87,10 +93,10 @@ All ``<input>`` arguments are concatenated before matching.
.. code-block:: cmake
string(REGEX MATCHALL <regular_expression>
- <output variable> <input> [<input>...])
+ <output_variable> <input> [<input>...])
-Match the regular expression as many times as possible and store the matches
-in the output variable as a list.
+Match the ``<regular_expression>`` as many times as possible and store the
+matches in the ``<output_variable>`` as a list.
All ``<input>`` arguments are concatenated before matching.
.. _`REGEX REPLACE`:
@@ -98,16 +104,17 @@ All ``<input>`` arguments are concatenated before matching.
.. code-block:: cmake
string(REGEX REPLACE <regular_expression>
- <replace_expression> <output variable>
+ <replacement_expression> <output_variable>
<input> [<input>...])
-Match the regular expression as many times as possible and substitute the
-replacement expression for the match in the output.
+Match the ``<regular_expression>`` as many times as possible and substitute
+the ``<replacement_expression>`` for the match in the output.
All ``<input>`` arguments are concatenated before matching.
-The replace expression may refer to paren-delimited subexpressions of the
-match using ``\1``, ``\2``, ..., ``\9``. Note that two backslashes (``\\1``)
-are required in CMake code to get a backslash through argument parsing.
+The ``<replacement_expression>`` may refer to parenthesis-delimited
+subexpressions of the match using ``\1``, ``\2``, ..., ``\9``. Note that
+two backslashes (``\\1``) are required in CMake code to get a backslash
+through argument parsing.
.. _`Regex Specification`:
@@ -180,103 +187,109 @@ Manipulation
.. code-block:: cmake
- string(APPEND <string variable> [<input>...])
+ string(APPEND <string_variable> [<input>...])
-Append all the input arguments to the string.
+Append all the ``<input>`` arguments to the string.
.. _PREPEND:
.. code-block:: cmake
- string(PREPEND <string variable> [<input>...])
+ string(PREPEND <string_variable> [<input>...])
-Prepend all the input arguments to the string.
+Prepend all the ``<input>`` arguments to the string.
.. _CONCAT:
.. code-block:: cmake
- string(CONCAT <output variable> [<input>...])
+ string(CONCAT <output_variable> [<input>...])
-Concatenate all the input arguments together and store
-the result in the named output variable.
+Concatenate all the ``<input>`` arguments together and store
+the result in the named ``<output_variable>``.
.. _JOIN:
.. code-block:: cmake
- string(JOIN <glue> <output variable> [<input>...])
+ string(JOIN <glue> <output_variable> [<input>...])
-Join all the input arguments together using the glue
-string and store the result in the named output variable.
+Join all the ``<input>`` arguments together using the ``<glue>``
+string and store the result in the named ``<output_variable>``.
-To join list's elements, use preferably the ``JOIN`` operator
-from :command:`list` command. This allows for the elements to have
+To join a list's elements, prefer to use the ``JOIN`` operator
+from the :command:`list` command. This allows for the elements to have
special characters like ``;`` in them.
.. _TOLOWER:
.. code-block:: cmake
- string(TOLOWER <string1> <output variable>)
+ string(TOLOWER <string> <output_variable>)
-Convert string to lower characters.
+Convert ``<string>`` to lower characters.
.. _TOUPPER:
.. code-block:: cmake
- string(TOUPPER <string1> <output variable>)
+ string(TOUPPER <string> <output_variable>)
-Convert string to upper characters.
+Convert ``<string>`` to upper characters.
.. _LENGTH:
.. code-block:: cmake
- string(LENGTH <string> <output variable>)
+ string(LENGTH <string> <output_variable>)
-Store in an output variable a given string's length.
+Store in an ``<output_variable>`` a given string's length in bytes.
+Note that this means if ``<string>`` contains multi-byte characters, the
+result stored in ``<output_variable>`` will *not* be the number of characters.
.. _SUBSTRING:
.. code-block:: cmake
- string(SUBSTRING <string> <begin> <length> <output variable>)
+ string(SUBSTRING <string> <begin> <length> <output_variable>)
+
+Store in an ``<output_variable>`` a substring of a given ``<string>``. If
+``<length>`` is ``-1`` the remainder of the string starting at ``<begin>``
+will be returned. If ``<string>`` is shorter than ``<length>`` then the
+end of the string is used instead.
-Store in an output variable a substring of a given string. If length is
-``-1`` the remainder of the string starting at begin will be returned.
-If string is shorter than length then end of string is used instead.
+Both ``<begin>`` and ``<length>`` are counted in bytes, so care must
+be exercised if ``<string>`` could contain multi-byte characters.
.. note::
- CMake 3.1 and below reported an error if length pointed past
- the end of string.
+ CMake 3.1 and below reported an error if ``<length>`` pointed past
+ the end of ``<string>``.
.. _STRIP:
.. code-block:: cmake
- string(STRIP <string> <output variable>)
+ string(STRIP <string> <output_variable>)
-Store in an output variable a substring of a given string with leading and
-trailing spaces removed.
+Store in an ``<output_variable>`` a substring of a given ``<string>`` with
+leading and trailing spaces removed.
.. _GENEX_STRIP:
.. code-block:: cmake
- string(GENEX_STRIP <input string> <output variable>)
+ string(GENEX_STRIP <string> <output_variable>)
Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
-from the ``input string`` and store the result in the ``output variable``.
+from the input ``<string>`` and store the result in the ``<output_variable>``.
.. _REPEAT:
.. code-block:: cmake
- string(REPEAT <input string> <count> <output variable>)
+ string(REPEAT <string> <count> <output_variable>)
-Produce the output string as repetion of ``input string`` ``count`` times.
+Produce the output string as the input ``<string>`` repeated ``<count>`` times.
Comparison
^^^^^^^^^^
@@ -285,14 +298,14 @@ Comparison
.. code-block:: cmake
- string(COMPARE LESS <string1> <string2> <output variable>)
- string(COMPARE GREATER <string1> <string2> <output variable>)
- string(COMPARE EQUAL <string1> <string2> <output variable>)
- string(COMPARE NOTEQUAL <string1> <string2> <output variable>)
- string(COMPARE LESS_EQUAL <string1> <string2> <output variable>)
- string(COMPARE GREATER_EQUAL <string1> <string2> <output variable>)
+ string(COMPARE LESS <string1> <string2> <output_variable>)
+ string(COMPARE GREATER <string1> <string2> <output_variable>)
+ string(COMPARE EQUAL <string1> <string2> <output_variable>)
+ string(COMPARE NOTEQUAL <string1> <string2> <output_variable>)
+ string(COMPARE LESS_EQUAL <string1> <string2> <output_variable>)
+ string(COMPARE GREATER_EQUAL <string1> <string2> <output_variable>)
-Compare the strings and store true or false in the output variable.
+Compare the strings and store true or false in the ``<output_variable>``.
.. _`Supported Hash Algorithms`:
@@ -303,9 +316,9 @@ Hashing
.. code-block:: cmake
- string(<HASH> <output variable> <input>)
+ string(<HASH> <output_variable> <input>)
-Compute a cryptographic hash of the input string.
+Compute a cryptographic hash of the ``<input>`` string.
The supported ``<HASH>`` algorithm names are:
``MD5``
@@ -336,7 +349,7 @@ Generation
.. code-block:: cmake
- string(ASCII <number> [<number> ...] <output variable>)
+ string(ASCII <number> [<number> ...] <output_variable>)
Convert all numbers into corresponding ASCII characters.
@@ -344,31 +357,31 @@ Convert all numbers into corresponding ASCII characters.
.. code-block:: cmake
- string(CONFIGURE <string1> <output variable>
+ string(CONFIGURE <string> <output_variable>
[@ONLY] [ESCAPE_QUOTES])
-Transform a string like :command:`configure_file` transforms a file.
+Transform a ``<string>`` like :command:`configure_file` transforms a file.
.. _MAKE_C_IDENTIFIER:
.. code-block:: cmake
- string(MAKE_C_IDENTIFIER <input string> <output variable>)
+ string(MAKE_C_IDENTIFIER <string> <output_variable>)
-Convert each non-alphanumeric character in the ``<input string>`` to an
-underscore and store the result in the ``<output variable>``. If the first
-character of the string is a digit, an underscore will also be prepended to
-the result.
+Convert each non-alphanumeric character in the input ``<string>`` to an
+underscore and store the result in the ``<output_variable>``. If the first
+character of the ``<string>`` is a digit, an underscore will also be prepended
+to the result.
.. _RANDOM:
.. code-block:: cmake
string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
- [RANDOM_SEED <seed>] <output variable>)
+ [RANDOM_SEED <seed>] <output_variable>)
-Return a random string of given length consisting of
-characters from the given alphabet. Default length is 5 characters
+Return a random string of given ``<length>`` consisting of
+characters from the given ``<alphabet>``. Default length is 5 characters
and default alphabet is all numbers and upper and lower case letters.
If an integer ``RANDOM_SEED`` is given, its value will be used to seed the
random number generator.
@@ -377,18 +390,18 @@ random number generator.
.. code-block:: cmake
- string(TIMESTAMP <output variable> [<format string>] [UTC])
+ string(TIMESTAMP <output_variable> [<format_string>] [UTC])
Write a string representation of the current date
-and/or time to the output variable.
+and/or time to the ``<output_variable>``.
-Should the command be unable to obtain a timestamp the output variable
-will be set to the empty string "".
+If the command is unable to obtain a timestamp, the ``<output_variable>``
+will be set to the empty string ``""``.
The optional ``UTC`` flag requests the current date/time representation to
be in Coordinated Universal Time (UTC) rather than local time.
-The optional ``<format string>`` may contain the following format
+The optional ``<format_string>`` may contain the following format
specifiers:
::
@@ -415,7 +428,7 @@ specifiers:
Unknown format specifiers will be ignored and copied to the output
as-is.
-If no explicit ``<format string>`` is given it will default to:
+If no explicit ``<format_string>`` is given, it will default to:
::
@@ -432,7 +445,7 @@ If no explicit ``<format string>`` is given it will default to:
.. code-block:: cmake
- string(UUID <output variable> NAMESPACE <namespace> NAME <name>
+ string(UUID <output_variable> NAMESPACE <namespace> NAME <name>
TYPE <MD5|SHA1> [UPPER])
Create a universally unique identifier (aka GUID) as per RFC4122
@@ -441,6 +454,6 @@ based on the hash of the combined values of ``<namespace>``
The hash algorithm can be either ``MD5`` (Version 3 UUID) or
``SHA1`` (Version 5 UUID).
A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``
-where each `x` represents a lower case hexadecimal character.
-Where required an uppercase representation can be requested
+where each ``x`` represents a lower case hexadecimal character.
+Where required, an uppercase representation can be requested
with the optional ``UPPER`` flag.
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index db8e7a0..41ed0c4 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -228,7 +228,8 @@ remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
CMakeLists.
Once this is done, run **cmake** or **cmake-gui** to configure the project
-and then build it with your chosen build tool.
+and then build it with your chosen build tool or by using ``cmake --build .``
+from the build directory.
Installing and Testing (Step 4)
===============================
@@ -258,14 +259,15 @@ And the to top-level ``CMakeLists.txt`` we add:
That is all that is needed to create a basic local install of the tutorial.
Run **cmake** or **cmake-gui** to configure the project and then build it
-with your chosen build tool. Build the ``install`` target by typing
-``make install`` from the command line or build the ``INSTALL`` target from
-an IDE. This will install the appropriate header files, libraries, and
-executables.
+with your chosen build tool. Run the install step by typing
+``cmake --install .`` or from the command line, or build the ``INSTALL``
+target from an IDE. This will install the appropriate header files, libraries,
+and executables.
Verify that the installed Tutorial runs. Note: The CMake variable
``CMAKE_INSTALL_PREFIX`` is used to determine the root of where the files will
-be installed.
+be installed. If using ``cmake --install`` a custom installation directory can
+be given via ``--prefix`` argument.
Testing Support
---------------
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index e0ce6f7..c3f6f8a 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -69,6 +69,7 @@ Variables that Provide Information
/variable/CMAKE_MAKE_PROGRAM
/variable/CMAKE_MATCH_COUNT
/variable/CMAKE_MATCH_n
+ /variable/CMAKE_MESSAGE_INDENT
/variable/CMAKE_MINIMUM_REQUIRED_VERSION
/variable/CMAKE_MINOR_VERSION
/variable/CMAKE_NETRC
@@ -609,7 +610,6 @@ Variables for CPack
/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY
/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
- /variable/CPACK_INSTALL_SCRIPT
/variable/CPACK_PACKAGING_INSTALL_PREFIX
/variable/CPACK_SET_DESTDIR
/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
diff --git a/Help/release/dev/cpack-install-scripts.rst b/Help/release/dev/cpack-install-scripts.rst
new file mode 100644
index 0000000..7b80d33
--- /dev/null
+++ b/Help/release/dev/cpack-install-scripts.rst
@@ -0,0 +1,5 @@
+cpack-install-scripts
+---------------------
+
+* The ``CPACK_INSTALL_SCRIPT`` variable has been deprecated in favor of the
+ new, more accurately named :variable:`CPACK_INSTALL_SCRIPTS` variable.
diff --git a/Help/release/dev/message-indent.rst b/Help/release/dev/message-indent.rst
new file mode 100644
index 0000000..b170708
--- /dev/null
+++ b/Help/release/dev/message-indent.rst
@@ -0,0 +1,5 @@
+message-indent
+--------------
+
+* The :command:`message` command learned indentation control with the new
+ :variable:`CMAKE_MESSAGE_INDENT` variable.
diff --git a/Help/variable/CMAKE_MESSAGE_INDENT.rst b/Help/variable/CMAKE_MESSAGE_INDENT.rst
new file mode 100644
index 0000000..f7975ab
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_INDENT.rst
@@ -0,0 +1,30 @@
+CMAKE_MESSAGE_INDENT
+--------------------
+
+The :command:`message` command joins the strings from this list and for
+log levels of ``NOTICE`` and below, it prepends the resultant string to
+each line of the message.
+
+Example:
+
+.. code-block:: cmake
+
+ list(APPEND listVar one two three)
+
+ message(VERBOSE [[Collected items in the "listVar":]])
+ list(APPEND CMAKE_MESSAGE_INDENT " ")
+
+ foreach(item IN LISTS listVar)
+ message(VERBOSE ${item})
+ endforeach()
+
+ list(POP_BACK CMAKE_MESSAGE_INDENT)
+ message(VERBOSE "No more indent")
+
+Which results in the following output:
+
+ -- Collected items in the "listVar":
+ -- one
+ -- two
+ -- tree
+ -- No more indent
diff --git a/Help/variable/CPACK_INSTALL_SCRIPT.rst b/Help/variable/CPACK_INSTALL_SCRIPT.rst
deleted file mode 100644
index 12a48a4..0000000
--- a/Help/variable/CPACK_INSTALL_SCRIPT.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-CPACK_INSTALL_SCRIPT
---------------------
-
-Extra CMake script provided by the user.
-
-If set this CMake script will be executed by CPack during its local
-[CPack-private] installation which is done right before packaging the
-files. The script is not called by e.g.: ``make install``.
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index c9008db..8a6a712 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -325,7 +325,21 @@ The following variables are for advanced uses of CPack:
.. variable:: CPACK_INSTALL_COMMANDS
- Extra commands to install components.
+ Extra commands to install components. The environment variable
+ ``CMAKE_INSTALL_PREFIX`` is set to the temporary install directory
+ during execution.
+
+.. variable:: CPACK_INSTALL_SCRIPTS
+
+ Extra CMake scripts executed by CPack during its local staging
+ installation, which is done right before packaging the files.
+ The scripts are not called by a standalone install (e.g.: ``make install``).
+ For every script, the following variables will be set:
+ :variable:`CMAKE_CURRENT_SOURCE_DIR`, :variable:`CMAKE_CURRENT_BINARY_DIR`
+ and :variable:`CMAKE_INSTALL_PREFIX` (which is set to the staging install
+ directory). The singular form ``CMAKE_INSTALL_SCRIPT`` is supported as
+ an alternative variable for historical reasons, but its value is ignored if
+ ``CMAKE_INSTALL_SCRIPTS`` is set and a warning will be issued.
.. variable:: CPACK_INSTALLED_DIRECTORIES
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 0316532..8117916 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -662,8 +662,6 @@ set(SRCS
cmTryCompileCommand.h
cmTryRunCommand.cxx
cmTryRunCommand.h
- cmUnexpectedCommand.cxx
- cmUnexpectedCommand.h
cmUnsetCommand.cxx
cmUnsetCommand.h
cmUseMangledMesaCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 1a0e0d3..5833058 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 15)
-set(CMake_VERSION_PATCH 20190720)
+set(CMake_VERSION_PATCH 20190723)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 4a91698..350ebed 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -235,7 +235,7 @@ int cmCPackGenerator::InstallProject()
return 0;
}
- // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
+ // If the CPackConfig file sets CPACK_INSTALL_SCRIPT(S) then run them
// as listed
if (!this->InstallProjectViaInstallScript(setDestDir,
tempInstallDirectory)) {
@@ -448,7 +448,19 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
int cmCPackGenerator::InstallProjectViaInstallScript(
bool setDestDir, const std::string& tempInstallDirectory)
{
- const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPT");
+ const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPTS");
+ {
+ const char* const cmakeScript = this->GetOption("CPACK_INSTALL_SCRIPT");
+ if (cmakeScript && cmakeScripts) {
+ cmCPackLogger(
+ cmCPackLog::LOG_WARNING,
+ "Both CPACK_INSTALL_SCRIPTS and CPACK_INSTALL_SCRIPT are set, "
+ "the latter will be ignored."
+ << std::endl);
+ } else if (cmakeScript && !cmakeScripts) {
+ cmakeScripts = cmakeScript;
+ }
+ }
if (cmakeScripts && *cmakeScripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install scripts: " << cmakeScripts << std::endl);
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index adf9553..2b73d40 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -4,6 +4,7 @@
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
@@ -13,8 +14,6 @@
#include <sstream>
#include <stdlib.h>
-class cmExecutionStatus;
-
cmCTestHandlerCommand::cmCTestHandlerCommand()
{
const size_t INIT_SIZE = 100;
@@ -86,7 +85,7 @@ private:
}
bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+ cmExecutionStatus& status)
{
// save error state and restore it if needed
SaveRestoreErrorState errorState;
@@ -126,7 +125,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
if (capureCMakeError) {
this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
"-1");
- std::string const err = this->GetName() + " " + this->GetError();
+ 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");
}
@@ -195,8 +194,8 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
if (capureCMakeError) {
this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
"-1");
- const char* err = this->GetError();
- if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
+ 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;
@@ -220,7 +219,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
"-1");
cmCTestLog(this->CTest, ERROR_MESSAGE,
- this->GetName() << " " << this->GetError() << "\n");
+ this->GetName() << " " << status.GetError() << "\n");
// return success because failure is recorded in CAPTURE_CMAKE_ERROR
return true;
}
@@ -240,10 +239,10 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
const char* returnString = "0";
if (cmSystemTools::GetErrorOccuredFlag()) {
returnString = "-1";
- const char* err = this->GetError();
+ std::string const& err = status.GetError();
// print out the error if it is not "unknown error" which means
// there was no message
- if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
+ if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
cmCTestLog(this->CTest, ERROR_MESSAGE, err);
}
}
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index c2748e1..cfbdad0 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -423,54 +423,11 @@ int cmCTestTestHandler::PostProcessHandler()
return 1;
}
-// clearly it would be nice if this were broken up into a few smaller
-// functions and commented...
int cmCTestTestHandler::ProcessHandler()
{
- // Update internal data structure from generic one
- this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
- this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
- if (cmSystemTools::IsOn(this->GetOption("ScheduleRandom"))) {
- this->CTest->SetScheduleType("Random");
- }
- if (this->GetOption("ParallelLevel")) {
- this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
- }
-
- const char* val;
- val = this->GetOption("LabelRegularExpression");
- if (val) {
- this->UseIncludeLabelRegExpFlag = true;
- this->IncludeLabelRegExp = val;
- }
- val = this->GetOption("ExcludeLabelRegularExpression");
- if (val) {
- this->UseExcludeLabelRegExpFlag = true;
- this->ExcludeLabelRegExp = val;
- }
- val = this->GetOption("IncludeRegularExpression");
- if (val) {
- this->UseIncludeRegExp();
- this->SetIncludeRegExp(val);
- }
- val = this->GetOption("ExcludeRegularExpression");
- if (val) {
- 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;
+ if (!this->ProcessOptions()) {
+ return -1;
}
- this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed")));
this->TestResults.clear();
@@ -490,7 +447,6 @@ int cmCTestTestHandler::ProcessHandler()
std::vector<std::string> passed;
std::vector<std::string> failed;
- int total;
// start the real time clock
auto clock_start = std::chrono::steady_clock::now();
@@ -499,9 +455,7 @@ int cmCTestTestHandler::ProcessHandler()
auto clock_finish = std::chrono::steady_clock::now();
- total = int(passed.size()) + int(failed.size());
-
- if (total == 0) {
+ if (passed.size() + failed.size() == 0) {
if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"No tests were found!!!" << std::endl);
@@ -519,9 +473,6 @@ int cmCTestTestHandler::ProcessHandler()
}
}
- typedef std::set<cmCTestTestHandler::cmCTestTestResult,
- cmCTestTestResultLess>
- SetOfTests;
SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end());
std::vector<cmCTestTestHandler::cmCTestTestResult> disabledTests;
@@ -532,92 +483,182 @@ int cmCTestTestHandler::ProcessHandler()
}
}
- float percent = float(passed.size()) * 100.0f / float(total);
- if (!failed.empty() && percent > 99) {
- percent = 99;
- }
+ cmDuration durationInSecs = clock_finish - clock_start;
+ this->LogTestSummary(passed, failed, durationInSecs);
- std::string passColorCode;
- std::string failedColorCode;
- if (failed.empty()) {
- passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN);
- } else {
- failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED);
- }
+ this->LogDisabledTests(disabledTests);
+
+ this->LogFailedTests(failed, resultsSet);
+ }
+
+ if (!this->GenerateXML()) {
+ return 1;
+ }
+
+ if (!this->PostProcessHandler()) {
+ this->LogFile = nullptr;
+ return -1;
+ }
+
+ if (!failed.empty()) {
+ this->LogFile = nullptr;
+ return -1;
+ }
+ this->LogFile = nullptr;
+ return 0;
+}
+
+bool cmCTestTestHandler::ProcessOptions()
+{
+ // Update internal data structure from generic one
+ this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
+ this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
+ if (cmSystemTools::IsOn(this->GetOption("ScheduleRandom"))) {
+ this->CTest->SetScheduleType("Random");
+ }
+ if (this->GetOption("ParallelLevel")) {
+ this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
+ }
+
+ const char* val;
+ val = this->GetOption("LabelRegularExpression");
+ if (val) {
+ this->UseIncludeLabelRegExpFlag = true;
+ this->IncludeLabelRegExp = val;
+ }
+ val = this->GetOption("ExcludeLabelRegularExpression");
+ if (val) {
+ this->UseExcludeLabelRegExpFlag = true;
+ this->ExcludeLabelRegExp = val;
+ }
+ val = this->GetOption("IncludeRegularExpression");
+ if (val) {
+ this->UseIncludeRegExp();
+ this->SetIncludeRegExp(val);
+ }
+ val = this->GetOption("ExcludeRegularExpression");
+ if (val) {
+ 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;
+ }
+ this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed")));
+
+ return true;
+}
+
+void cmCTestTestHandler::LogTestSummary(const std::vector<std::string>& passed,
+ const std::vector<std::string>& failed,
+ const cmDuration& durationInSecs)
+{
+ std::size_t total = passed.size() + failed.size();
+
+ float percent = float(passed.size()) * 100.0f / float(total);
+ if (!failed.empty() && percent > 99) {
+ percent = 99;
+ }
+
+ std::string passColorCode;
+ std::string failedColorCode;
+ if (failed.empty()) {
+ passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN);
+ } else {
+ failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED);
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ std::endl
+ << passColorCode << std::lround(percent) << "% tests passed"
+ << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+ << ", " << failedColorCode << failed.size() << " tests failed"
+ << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+ << " out of " << total << std::endl);
+ if ((!this->CTest->GetLabelsForSubprojects().empty() &&
+ this->CTest->GetSubprojectSummary())) {
+ this->PrintLabelOrSubprojectSummary(true);
+ }
+ if (this->CTest->GetLabelSummary()) {
+ this->PrintLabelOrSubprojectSummary(false);
+ }
+ char realBuf[1024];
+ sprintf(realBuf, "%6.2f sec", durationInSecs.count());
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "\nTotal Test time (real) = " << realBuf << "\n",
+ this->Quiet);
+}
+
+void cmCTestTestHandler::LogDisabledTests(
+ const std::vector<cmCTestTestResult>& disabledTests)
+{
+ if (!disabledTests.empty()) {
+ cmGeneratedFileStream ofs;
cmCTestLog(this->CTest, HANDLER_OUTPUT,
std::endl
- << passColorCode << std::lround(percent) << "% tests passed"
- << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
- << ", " << failedColorCode << failed.size() << " tests failed"
- << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
- << " out of " << total << std::endl);
- if ((!this->CTest->GetLabelsForSubprojects().empty() &&
- this->CTest->GetSubprojectSummary())) {
- this->PrintLabelOrSubprojectSummary(true);
- }
- if (this->CTest->GetLabelSummary()) {
- this->PrintLabelOrSubprojectSummary(false);
- }
- char realBuf[1024];
- cmDuration durationInSecs = clock_finish - clock_start;
- sprintf(realBuf, "%6.2f sec", durationInSecs.count());
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- "\nTotal Test time (real) = " << realBuf << "\n",
- this->Quiet);
+ << "The following tests did not run:" << std::endl);
+ this->StartLogFile("TestsDisabled", ofs);
- if (!disabledTests.empty()) {
- cmGeneratedFileStream ofs;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- std::endl
- << "The following tests did not run:" << std::endl);
- this->StartLogFile("TestsDisabled", ofs);
-
- const char* disabled_reason;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetColorCode(cmCTest::Color::BLUE));
- for (cmCTestTestResult const& dt : disabledTests) {
- ofs << dt.TestCount << ":" << dt.Name << std::endl;
- if (dt.CompletionStatus == "Disabled") {
- disabled_reason = "Disabled";
- } else {
- disabled_reason = "Skipped";
- }
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name
- << " (" << disabled_reason << ")" << std::endl);
+ const char* disabled_reason;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetColorCode(cmCTest::Color::BLUE));
+ for (cmCTestTestResult const& dt : disabledTests) {
+ ofs << dt.TestCount << ":" << dt.Name << std::endl;
+ if (dt.CompletionStatus == "Disabled") {
+ disabled_reason = "Disabled";
+ } else {
+ disabled_reason = "Skipped";
}
cmCTestLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR));
+ "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name
+ << " (" << disabled_reason << ")" << std::endl);
}
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR));
+ }
+}
- if (!failed.empty()) {
- cmGeneratedFileStream ofs;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- std::endl
- << "The following tests FAILED:" << std::endl);
- this->StartLogFile("TestsFailed", ofs);
-
- for (cmCTestTestResult const& ft : resultsSet) {
- if (ft.Status != cmCTestTestHandler::COMPLETED &&
- !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") &&
- ft.CompletionStatus != "Disabled") {
- ofs << ft.TestCount << ":" << ft.Name << std::endl;
- auto testColor = cmCTest::Color::RED;
- if (this->GetTestStatus(ft) == "Not Run") {
- testColor = cmCTest::Color::YELLOW;
- }
- cmCTestLog(
- this->CTest, HANDLER_OUTPUT,
- "\t" << this->CTest->GetColorCode(testColor) << std::setw(3)
- << ft.TestCount << " - " << ft.Name << " ("
- << this->GetTestStatus(ft) << ")"
- << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
- << std::endl);
+void cmCTestTestHandler::LogFailedTests(const std::vector<std::string>& failed,
+ const SetOfTests& resultsSet)
+{
+ if (!failed.empty()) {
+ cmGeneratedFileStream ofs;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ std::endl
+ << "The following tests FAILED:" << std::endl);
+ this->StartLogFile("TestsFailed", ofs);
+
+ for (cmCTestTestResult const& ft : resultsSet) {
+ if (ft.Status != cmCTestTestHandler::COMPLETED &&
+ !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") &&
+ ft.CompletionStatus != "Disabled") {
+ ofs << ft.TestCount << ":" << ft.Name << std::endl;
+ auto testColor = cmCTest::Color::RED;
+ if (this->GetTestStatus(ft) == "Not Run") {
+ testColor = cmCTest::Color::YELLOW;
}
+ cmCTestLog(
+ this->CTest, HANDLER_OUTPUT,
+ "\t" << this->CTest->GetColorCode(testColor) << std::setw(3)
+ << ft.TestCount << " - " << ft.Name << " ("
+ << this->GetTestStatus(ft) << ")"
+ << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+ << std::endl);
}
}
}
+}
+bool cmCTestTestHandler::GenerateXML()
+{
if (this->CTest->GetProduceXML()) {
cmGeneratedFileStream xmlfile;
if (!this->StartResultingXML(
@@ -628,23 +669,13 @@ int cmCTestTestHandler::ProcessHandler()
<< (this->MemCheck ? "memory check" : "testing")
<< " XML file" << std::endl);
this->LogFile = nullptr;
- return 1;
+ return false;
}
cmXMLWriter xml(xmlfile);
this->GenerateDartOutput(xml);
}
- if (!this->PostProcessHandler()) {
- this->LogFile = nullptr;
- return -1;
- }
-
- if (!failed.empty()) {
- this->LogFile = nullptr;
- return -1;
- }
- this->LogFile = nullptr;
- return 0;
+ return true;
}
void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 5bbc68e..9345185 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -191,12 +191,25 @@ public:
typedef std::vector<cmCTestTestProperties> ListOfTests;
protected:
+ typedef std::set<cmCTestTestHandler::cmCTestTestResult,
+ cmCTestTestResultLess>
+ SetOfTests;
+
// compute a final test list
virtual int PreProcessHandler();
virtual int PostProcessHandler();
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
int ExecuteCommands(std::vector<std::string>& vec);
+ bool ProcessOptions();
+ void LogTestSummary(const std::vector<std::string>& passed,
+ const std::vector<std::string>& failed,
+ const cmDuration& durationInSecs);
+ void LogDisabledTests(const std::vector<cmCTestTestResult>& disabledTests);
+ void LogFailedTests(const std::vector<std::string>& failed,
+ const SetOfTests& resultsSet);
+ bool GenerateXML();
+
void WriteTestResultHeader(cmXMLWriter& xml,
cmCTestTestResult const& result);
void WriteTestResultFooter(cmXMLWriter& xml,
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 255a8e6..8c2d987 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -421,7 +421,7 @@ int CCONV cmExecuteCommand(void* arg, const char* name, int numArgs,
// Assume all arguments are quoted.
lff.Arguments.emplace_back(args[i], cmListFileArgument::Quoted, 0);
}
- cmExecutionStatus status;
+ cmExecutionStatus status(*mf);
return mf->ExecuteCommand(lff, status);
}
diff --git a/Source/cmCommand.cxx b/Source/cmCommand.cxx
index d349c91..0c2734e 100644
--- a/Source/cmCommand.cxx
+++ b/Source/cmCommand.cxx
@@ -2,11 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCommand.h"
+#include <utility>
+
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
struct cmListFileArgument;
+void cmCommand::SetExecutionStatus(cmExecutionStatus* status)
+{
+ this->Status = status;
+ this->Makefile = &status->GetMakefile();
+}
+
bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
cmExecutionStatus& status)
{
@@ -19,15 +27,33 @@ bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
return this->InitialPass(expandedArguments, status);
}
-const char* cmCommand::GetError()
+void cmCommand::SetError(const std::string& e)
{
- if (this->Error.empty()) {
- return "unknown error.";
- }
- return this->Error.c_str();
+ this->Status->SetError(e);
}
-void cmCommand::SetError(const std::string& 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
{
- this->Error = e;
+ auto cmd = this->Command->Clone();
+ cmd->SetExecutionStatus(&status);
+ return cmd->InvokeInitialPass(args, status);
}
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index b210f27..bcb178d 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -42,16 +42,18 @@ public:
/**
* Specify the makefile.
*/
- void SetMakefile(cmMakefile* m) { this->Makefile = m; }
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.
*/
- virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus& status);
+ bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus& status);
/**
* This is called when the command is first encountered in
@@ -66,11 +68,6 @@ public:
virtual std::unique_ptr<cmCommand> Clone() = 0;
/**
- * Return the last error string.
- */
- const char* GetError();
-
- /**
* Set the error message
*/
void SetError(const std::string& e);
@@ -79,7 +76,25 @@ protected:
cmMakefile* Makefile = nullptr;
private:
- std::string Error;
+ 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;
};
#endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 96c7105..f351ff8 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -147,7 +147,7 @@ void GetScriptingCommands(cmState* state)
cm::make_unique<cmGetFilenameComponentCommand>());
state->AddBuiltinCommand("get_property",
cm::make_unique<cmGetPropertyCommand>());
- state->AddBuiltinCommand("if", cm::make_unique<cmIfCommand>());
+ state->AddBuiltinCommand("if", cmIfCommand);
state->AddBuiltinCommand("include", cm::make_unique<cmIncludeCommand>());
state->AddBuiltinCommand("include_guard",
cm::make_unique<cmIncludeGuardCommand>());
@@ -162,7 +162,7 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>());
state->AddBuiltinCommand("cmake_parse_arguments",
cm::make_unique<cmParseArgumentsCommand>());
- state->AddBuiltinCommand("return", cm::make_unique<cmReturnCommand>());
+ state->AddBuiltinCommand("return", cmReturnCommand);
state->AddBuiltinCommand("separate_arguments",
cm::make_unique<cmSeparateArgumentsCommand>());
state->AddBuiltinCommand("set", cm::make_unique<cmSetCommand>());
@@ -173,7 +173,7 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("site_name", cm::make_unique<cmSiteNameCommand>());
state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>());
state->AddBuiltinCommand("unset", cm::make_unique<cmUnsetCommand>());
- state->AddBuiltinCommand("while", cm::make_unique<cmWhileCommand>());
+ state->AddBuiltinCommand("while", cmWhileCommand);
state->AddUnexpectedCommand(
"else",
@@ -255,8 +255,7 @@ void GetProjectCommands(cmState* state)
cm::make_unique<cmDefinePropertyCommand>());
state->AddBuiltinCommand("enable_language",
cm::make_unique<cmEnableLanguageCommand>());
- state->AddBuiltinCommand("enable_testing",
- cm::make_unique<cmEnableTestingCommand>());
+ state->AddBuiltinCommand("enable_testing", cmEnableTestingCommand);
state->AddBuiltinCommand("get_source_file_property",
cm::make_unique<cmGetSourceFilePropertyCommand>());
state->AddBuiltinCommand("get_target_property",
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index e7e91c1..2907f4a 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -4,6 +4,7 @@
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
+#include <functional>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
@@ -17,7 +18,6 @@
#include "cmSystemTools.h"
#include "cmake.h"
-class cmCommand;
class cmTest;
static std::string const keyAND = "AND";
@@ -452,7 +452,7 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
}
// does a command exist
if (this->IsKeyword(keyCOMMAND, *arg) && argP1 != newArgs.end()) {
- cmCommand* command =
+ cmState::Command command =
this->Makefile.GetState()->GetCommand(argP1->c_str());
this->HandlePredicate(command != nullptr, reducible, arg, newArgs,
argP1, argP2);
diff --git a/Source/cmDisallowedCommand.cxx b/Source/cmDisallowedCommand.cxx
index 418d98c..aa1f90b 100644
--- a/Source/cmDisallowedCommand.cxx
+++ b/Source/cmDisallowedCommand.cxx
@@ -24,8 +24,6 @@ bool cmDisallowedCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
- this->Command->SetMakefile(this->GetMakefile());
- bool const ret = this->Command->InitialPass(args, status);
- this->SetError(this->Command->GetError());
- return ret;
+ this->Command->SetExecutionStatus(this->GetExecutionStatus());
+ return this->Command->InitialPass(args, status);
}
diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx
index 6a64450..89212c8 100644
--- a/Source/cmEnableTestingCommand.cxx
+++ b/Source/cmEnableTestingCommand.cxx
@@ -2,15 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmEnableTestingCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// we do this in the final pass so that we now the subdirs have all
-// been defined
-bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&)
+bool cmEnableTestingCommand(std::vector<std::string> const&,
+ cmExecutionStatus& status)
{
- this->Makefile->AddDefinition("CMAKE_TESTING_ENABLED", "1");
+ status.GetMakefile().AddDefinition("CMAKE_TESTING_ENABLED", "1");
return true;
}
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index fd50ebc..e4593f2 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -8,13 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmEnableTestingCommand
+/**
* \brief Enable testing for this directory and below.
*
* Produce the output testfile. This produces a file in the build directory
@@ -27,23 +23,7 @@ class cmExecutionStatus;
* Note that CTest expects to find this file in the build directory root;
* therefore, this command should be in the source directory root too.
*/
-class cmEnableTestingCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmEnableTestingCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override;
-};
+bool cmEnableTestingCommand(std::vector<std::string> const&,
+ cmExecutionStatus&);
#endif
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index 56199dd..bcacc2f 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -3,6 +3,11 @@
#ifndef cmExecutionStatus_h
#define cmExecutionStatus_h
+#include <cmConfigure.h> // IWYU pragma: keep
+#include <string>
+
+class cmMakefile;
+
/** \class cmExecutionStatus
* \brief Superclass for all command status classes
*
@@ -11,14 +16,26 @@
class cmExecutionStatus
{
public:
+ cmExecutionStatus(cmMakefile& makefile)
+ : Makefile(makefile)
+ , Error("unknown error.")
+ {
+ }
+
void Clear()
{
+ this->Error = "unknown error.";
this->ReturnInvoked = false;
this->BreakInvoked = false;
this->ContinueInvoked = false;
this->NestedError = false;
}
+ cmMakefile& GetMakefile() { return this->Makefile; }
+
+ void SetError(std::string const& e) { this->Error = e; }
+ std::string const& GetError() const { return this->Error; }
+
void SetReturnInvoked() { this->ReturnInvoked = true; }
bool GetReturnInvoked() const { return this->ReturnInvoked; }
@@ -32,6 +49,8 @@ public:
bool GetNestedError() const { return this->NestedError; }
private:
+ cmMakefile& Makefile;
+ std::string Error;
bool ReturnInvoked = false;
bool BreakInvoked = false;
bool ContinueInvoked = false;
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 49e8cd5..4f1a158 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -174,11 +174,8 @@ bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode)
cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
for (const auto& arg : items) {
if (!this->CheckPermissions(arg, **mode)) {
- std::ostringstream e;
- e << this->FileCommand->GetError()
- << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "
- "variable.";
- this->FileCommand->SetError(e.str());
+ this->FileCommand->SetError(
+ " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable.");
return false;
}
}
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index a30ebe1..e3918b5 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -55,7 +55,7 @@ bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
// set the variable to the loop value
mf.AddDefinition(this->Args[0], arg.c_str());
// Invoke all the functions that were collected in the block.
- cmExecutionStatus status;
+ cmExecutionStatus status(mf);
for (cmListFileFunction const& func : this->Functions) {
status.Clear();
mf.ExecuteCommand(func, status);
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 6d06531..8b664ad 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -5,8 +5,6 @@
#include <sstream>
#include <utility>
-#include "cm_memory.hxx"
-
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -15,35 +13,15 @@
#include "cmState.h"
// define the class for function commands
-class cmFunctionHelperCommand : public cmCommand
+class cmFunctionHelperCommand
{
public:
/**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto newC = cm::make_unique<cmFunctionHelperCommand>();
- // we must copy when we clone
- newC->Args = this->Args;
- newC->Functions = this->Functions;
- newC->Policies = this->Policies;
- newC->FilePath = this->FilePath;
- return std::unique_ptr<cmCommand>(std::move(newC));
- }
-
- /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const;
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
@@ -51,12 +29,15 @@ public:
std::string FilePath;
};
-bool cmFunctionHelperCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
+bool cmFunctionHelperCommand::operator()(
+ std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const
{
+ cmMakefile& makefile = inStatus.GetMakefile();
+
// Expand the argument list to the function.
std::vector<std::string> expandedArgs;
- this->Makefile->ExpandArguments(args, expandedArgs);
+ makefile.ExpandArguments(args, expandedArgs);
// make sure the number of arguments passed is at least the number
// required by the signature
@@ -64,30 +45,30 @@ bool cmFunctionHelperCommand::InvokeInitialPass(
std::string errorMsg =
"Function invoked with incorrect arguments for function named: ";
errorMsg += this->Args[0];
- this->SetError(errorMsg);
+ inStatus.SetError(errorMsg);
return false;
}
- cmMakefile::FunctionPushPop functionScope(this->Makefile, this->FilePath,
+ cmMakefile::FunctionPushPop functionScope(&makefile, this->FilePath,
this->Policies);
// set the value of argc
std::ostringstream strStream;
strStream << expandedArgs.size();
- this->Makefile->AddDefinition("ARGC", strStream.str().c_str());
- this->Makefile->MarkVariableAsUsed("ARGC");
+ makefile.AddDefinition("ARGC", strStream.str().c_str());
+ makefile.MarkVariableAsUsed("ARGC");
// set the values for ARGV0 ARGV1 ...
for (unsigned int t = 0; t < expandedArgs.size(); ++t) {
std::ostringstream tmpStream;
tmpStream << "ARGV" << t;
- this->Makefile->AddDefinition(tmpStream.str(), expandedArgs[t].c_str());
- this->Makefile->MarkVariableAsUsed(tmpStream.str());
+ makefile.AddDefinition(tmpStream.str(), expandedArgs[t].c_str());
+ makefile.MarkVariableAsUsed(tmpStream.str());
}
// define the formal arguments
for (unsigned int j = 1; j < this->Args.size(); ++j) {
- this->Makefile->AddDefinition(this->Args[j], expandedArgs[j - 1].c_str());
+ makefile.AddDefinition(this->Args[j], expandedArgs[j - 1].c_str());
}
// define ARGV and ARGN
@@ -95,17 +76,16 @@ bool cmFunctionHelperCommand::InvokeInitialPass(
std::vector<std::string>::const_iterator eit =
expandedArgs.begin() + (this->Args.size() - 1);
std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
- this->Makefile->AddDefinition("ARGV", argvDef.c_str());
- this->Makefile->MarkVariableAsUsed("ARGV");
- this->Makefile->AddDefinition("ARGN", argnDef.c_str());
- this->Makefile->MarkVariableAsUsed("ARGN");
+ makefile.AddDefinition("ARGV", argvDef.c_str());
+ makefile.MarkVariableAsUsed("ARGV");
+ makefile.AddDefinition("ARGN", argnDef.c_str());
+ makefile.MarkVariableAsUsed("ARGN");
// Invoke all the functions that were collected in the block.
// for each function
for (cmListFileFunction const& func : this->Functions) {
- cmExecutionStatus status;
- if (!this->Makefile->ExecuteCommand(func, status) ||
- status.GetNestedError()) {
+ cmExecutionStatus status(makefile);
+ if (!makefile.ExecuteCommand(func, status) || status.GetNestedError()) {
// The error message should have already included the call stack
// so we do not need to report an error here.
functionScope.Quiet();
@@ -132,11 +112,11 @@ bool cmFunctionFunctionBlocker::IsFunctionBlocked(
// if this is the endfunction for this function then execute
if (!this->Depth) {
// create a new command and add it to cmake
- auto f = cm::make_unique<cmFunctionHelperCommand>();
- f->Args = this->Args;
- f->Functions = this->Functions;
- f->FilePath = this->GetStartingContext().FilePath;
- mf.RecordPolicies(f->Policies);
+ cmFunctionHelperCommand f;
+ f.Args = this->Args;
+ f.Functions = this->Functions;
+ f.FilePath = this->GetStartingContext().FilePath;
+ mf.RecordPolicies(f.Policies);
mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
// remove the function blocker now that the function is defined
mf.RemoveFunctionBlocker(this, lff);
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 728f2a4..817f41e 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -68,9 +68,7 @@ void cmGeneratorExpressionDAGChecker::Initialize()
return;
}
}
- const_cast<cmGeneratorExpressionDAGChecker*>(top)
- ->Seen[this->Target]
- .insert(this->Property);
+ top->Seen[this->Target].insert(this->Property);
}
}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index e1fba5e..6d7d6ef 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -88,7 +88,7 @@ private:
const cmGeneratorExpressionDAGChecker* const Parent;
cmGeneratorTarget const* Target;
const std::string Property;
- std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
+ mutable std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
const GeneratorExpressionContent* const Content;
const cmListFileBacktrace Backtrace;
Result CheckResult;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index d3e8248..6e6c917 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -92,9 +92,6 @@ public:
virtual bool GetHadContextSensitiveCondition() const { return false; }
cmLinkImplItem const& LinkImplItem;
-
-private:
- cmListFileBacktrace Backtrace;
};
cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
@@ -209,6 +206,63 @@ void CreatePropertyGeneratorExpressions(
}
}
+namespace {
+// Represent a target property entry after evaluating generator expressions
+// and splitting up lists.
+struct EvaluatedTargetPropertyEntry
+{
+ EvaluatedTargetPropertyEntry(cmLinkImplItem const& item,
+ cmListFileBacktrace bt)
+ : LinkImplItem(item)
+ , Backtrace(std::move(bt))
+ {
+ }
+
+ // Move-only.
+ EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default;
+ EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry const&) = delete;
+ EvaluatedTargetPropertyEntry& operator=(EvaluatedTargetPropertyEntry&&) =
+ delete;
+ EvaluatedTargetPropertyEntry& operator=(
+ EvaluatedTargetPropertyEntry const&) = delete;
+
+ cmLinkImplItem const& LinkImplItem;
+ cmListFileBacktrace Backtrace;
+ std::vector<std::string> Values;
+ bool ContextDependent = false;
+};
+
+EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+ cmGeneratorTarget::TargetPropertyEntry* entry)
+{
+ EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace());
+ cmSystemTools::ExpandListArgument(
+ entry->Evaluate(thisTarget->GetLocalGenerator(), config, false, thisTarget,
+ dagChecker, lang),
+ ee.Values);
+ if (entry->GetHadContextSensitiveCondition()) {
+ ee.ContextDependent = true;
+ }
+ return ee;
+}
+
+std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*> const& in)
+{
+ std::vector<EvaluatedTargetPropertyEntry> out;
+ out.reserve(in.size());
+ for (cmGeneratorTarget::TargetPropertyEntry* entry : in) {
+ out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
+ dagChecker, entry));
+ }
+ return out;
+}
+}
+
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
: Target(t)
, FortranModuleDirectoryCreated(false)
@@ -654,12 +708,14 @@ std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
return nullptr;
}
-static void handleSystemIncludesDep(
- cmLocalGenerator* lg, cmGeneratorTarget const* depTgt,
- const std::string& config, cmGeneratorTarget const* headTarget,
- cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::string>& result, bool excludeImported,
- std::string const& language)
+namespace {
+void handleSystemIncludesDep(cmLocalGenerator* lg,
+ cmGeneratorTarget const* depTgt,
+ const std::string& config,
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<std::string>& result,
+ bool excludeImported, std::string const& language)
{
if (const char* dirs =
depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
@@ -682,6 +738,7 @@ static void handleSystemIncludesDep(
result);
}
}
+}
/* clang-format off */
#define IMPLEMENT_VISIT(KIND) \
@@ -1084,77 +1141,91 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
return this->Target->GetPropertyAsBool(prop);
}
-static void AddInterfaceEntries(
- cmGeneratorTarget const* thisTarget, std::string const& config,
- std::string const& prop,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+namespace {
+void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
+ std::string const& config, std::string const& prop,
+ std::string const& lang,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
{
if (cmLinkImplementationLibraries const* impl =
- thisTarget->GetLinkImplementationLibraries(config)) {
+ headTarget->GetLinkImplementationLibraries(config)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target) {
std::string uniqueName =
- thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
+ headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
lib.Target);
std::string genex =
"$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">";
cmGeneratorExpression ge(lib.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
- entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib));
+
+ EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+ cmSystemTools::ExpandListArgument(
+ cge->Evaluate(headTarget->GetLocalGenerator(), config, false,
+ headTarget, dagChecker, lang),
+ ee.Values);
+ if (cge->GetHadContextSensitiveCondition()) {
+ ee.ContextDependent = true;
+ }
+ entries.emplace_back(std::move(ee));
}
}
}
}
-static void AddObjectEntries(
- cmGeneratorTarget const* thisTarget, std::string const& config,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+void AddObjectEntries(cmGeneratorTarget const* headTarget,
+ std::string const& config,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
{
if (cmLinkImplementationLibraries const* impl =
- thisTarget->GetLinkImplementationLibraries(config)) {
+ headTarget->GetLinkImplementationLibraries(config)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target &&
lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::string uniqueName =
- thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
+ headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
lib.Target);
std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">";
cmGeneratorExpression ge(lib.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
- entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib));
+
+ EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+ cmSystemTools::ExpandListArgument(
+ cge->Evaluate(headTarget->GetLocalGenerator(), config, false,
+ headTarget, dagChecker),
+ ee.Values);
+ if (cge->GetHadContextSensitiveCondition()) {
+ ee.ContextDependent = true;
+ }
+ entries.emplace_back(std::move(ee));
}
}
}
}
-static bool processSources(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& srcs,
- std::unordered_set<std::string>& uniqueSrcs,
- cmGeneratorExpressionDAGChecker* dagChecker, std::string const& config,
- bool debugSources)
+bool processSources(cmGeneratorTarget const* tgt,
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
+ std::vector<BT<std::string>>& srcs,
+ std::unordered_set<std::string>& uniqueSrcs,
+ bool debugSources)
{
cmMakefile* mf = tgt->Target->GetMakefile();
bool contextDependent = false;
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- cmLinkImplItem const& item = entry->LinkImplItem;
- std::string const& targetName = item.AsStr();
- std::vector<std::string> entrySources;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt, tgt,
- dagChecker),
- entrySources);
-
- if (entry->GetHadContextSensitiveCondition()) {
+ for (EvaluatedTargetPropertyEntry& entry : entries) {
+ if (entry.ContextDependent) {
contextDependent = true;
}
- for (std::string& src : entrySources) {
+ cmLinkImplItem const& item = entry.LinkImplItem;
+ std::string const& targetName = item.AsStr();
+
+ for (std::string& src : entry.Values) {
cmSourceFile* sf = mf->GetOrCreateSource(src);
std::string e;
std::string fullPath = sf->GetFullPath(&e);
@@ -1183,9 +1254,9 @@ static bool processSources(
src = fullPath;
}
std::string usedSources;
- for (std::string const& src : entrySources) {
+ for (std::string const& src : entry.Values) {
if (uniqueSrcs.insert(src).second) {
- srcs.emplace_back(src, entry->GetBacktrace());
+ srcs.emplace_back(src, entry.Backtrace);
if (debugSources) {
usedSources += " * " + src + "\n";
}
@@ -1196,11 +1267,12 @@ static bool processSources(
MessageType::LOG,
std::string("Used sources for target ") + tgt->GetName() + ":\n" +
usedSources,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
return contextDependent;
}
+}
std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
std::string const& config) const
@@ -1248,28 +1320,28 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
nullptr);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
+ this->SourceEntries);
+
std::unordered_set<std::string> uniqueSrcs;
bool contextDependentDirectSources =
- processSources(this, this->SourceEntries, files, uniqueSrcs, &dagChecker,
- config, debugSources);
+ processSources(this, entries, files, uniqueSrcs, debugSources);
// Collect INTERFACE_SOURCES of all direct link-dependencies.
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceSourcesEntries;
- AddInterfaceEntries(this, config, "INTERFACE_SOURCES",
- linkInterfaceSourcesEntries);
+ std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries;
+ AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
+ &dagChecker, linkInterfaceSourcesEntries);
std::vector<std::string>::size_type numFilesBefore = files.size();
- bool contextDependentInterfaceSources =
- processSources(this, linkInterfaceSourcesEntries, files, uniqueSrcs,
- &dagChecker, config, debugSources);
+ bool contextDependentInterfaceSources = processSources(
+ this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources);
// Collect TARGET_OBJECTS of direct object link-dependencies.
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkObjectsEntries;
- AddObjectEntries(this, config, linkObjectsEntries);
+ std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries;
+ AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
std::vector<std::string>::size_type numFilesBefore2 = files.size();
bool contextDependentObjects =
- processSources(this, linkObjectsEntries, files, uniqueSrcs, &dagChecker,
- config, debugSources);
+ processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources);
if (!contextDependentDirectSources &&
!(contextDependentInterfaceSources && numFilesBefore < files.size()) &&
@@ -1277,8 +1349,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
this->LinkImplementationLanguageIsContextDependent = false;
}
- cmDeleteAll(linkInterfaceSourcesEntries);
- cmDeleteAll(linkObjectsEntries);
return files;
}
@@ -1855,16 +1925,17 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return this->GetLibraryNames(config).SharedObject;
}
-static bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level)
+namespace {
+bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level)
{
return level == cmGeneratorTarget::FullLevel;
}
-static bool shouldAddContentLevel(
- cmGeneratorTarget::BundleDirectoryLevel level)
+bool shouldAddContentLevel(cmGeneratorTarget::BundleDirectoryLevel level)
{
return level == cmGeneratorTarget::ContentLevel || shouldAddFullLevel(level);
}
+}
std::string cmGeneratorTarget::GetAppBundleDirectory(
const std::string& config, BundleDirectoryLevel level) const
@@ -2767,27 +2838,22 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
}
return "";
}
-static void processIncludeDirectories(
+
+namespace {
+void processIncludeDirectories(
cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
std::vector<BT<std::string>>& includes,
- std::unordered_set<std::string>& uniqueIncludes,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugIncludes, const std::string& language)
+ std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes)
{
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- cmLinkImplItem const& item = entry->LinkImplItem;
+ for (EvaluatedTargetPropertyEntry& entry : entries) {
+ cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
bool const fromImported = item.Target && item.Target->IsImported();
bool const checkCMP0027 = item.FromGenex;
- std::vector<std::string> entryIncludes;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt,
- dagChecker, language),
- entryIncludes);
std::string usedIncludes;
- for (std::string& entryInclude : entryIncludes) {
+ for (std::string& entryInclude : entry.Values) {
if (fromImported && !cmSystemTools::FileExists(entryInclude)) {
std::ostringstream e;
MessageType messageType = MessageType::FATAL_ERROR;
@@ -2859,12 +2925,11 @@ static void processIncludeDirectories(
if (!cmSystemTools::IsOff(entryInclude)) {
cmSystemTools::ConvertToUnixSlashes(entryInclude);
}
- std::string inc = entryInclude;
- if (uniqueIncludes.insert(inc).second) {
- includes.emplace_back(inc, entry->GetBacktrace());
+ if (uniqueIncludes.insert(entryInclude).second) {
+ includes.emplace_back(entryInclude, entry.Backtrace);
if (debugIncludes) {
- usedIncludes += " * " + inc + "\n";
+ usedIncludes += " * " + entryInclude + "\n";
}
}
}
@@ -2873,10 +2938,11 @@ static void processIncludeDirectories(
MessageType::LOG,
std::string("Used includes for target ") + tgt->GetName() + ":\n" +
usedIncludes,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
}
+}
std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
const std::string& config, const std::string& lang) const
@@ -2902,14 +2968,12 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
this->DebugIncludesDone = true;
}
- processIncludeDirectories(this, this->IncludeDirectoriesEntries, includes,
- uniqueIncludes, &dagChecker, config, debugIncludes,
- lang);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
+ this->IncludeDirectoriesEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceIncludeDirectoriesEntries;
- AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES",
- linkInterfaceIncludeDirectoriesEntries);
+ AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
+ &dagChecker, entries);
if (this->Makefile->IsOn("APPLE")) {
cmLinkImplementationLibraries const* impl =
@@ -2925,16 +2989,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
libDir = frameworkCheck.match(1);
- linkInterfaceIncludeDirectoriesEntries.push_back(
- CreateTargetPropertyEntry(libDir));
+ EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
+ ee.Values.emplace_back(std::move(libDir));
+ entries.emplace_back(std::move(ee));
}
}
- processIncludeDirectories(this, linkInterfaceIncludeDirectoriesEntries,
- includes, uniqueIncludes, &dagChecker, config,
- debugIncludes, lang);
-
- cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+ processIncludeDirectories(this, entries, includes, uniqueIncludes,
+ debugIncludes);
return includes;
}
@@ -2945,33 +3007,26 @@ enum class OptionsParse
Shell
};
-static void processOptionsInternal(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, const char* logName, std::string const& language,
- OptionsParse parse)
-{
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- std::vector<std::string> entryOptions;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt,
- dagChecker, language),
- entryOptions);
+namespace {
+void processOptions(cmGeneratorTarget const* tgt,
+ std::vector<EvaluatedTargetPropertyEntry> const& entries,
+ std::vector<BT<std::string>>& options,
+ std::unordered_set<std::string>& uniqueOptions,
+ bool debugOptions, const char* logName, OptionsParse parse)
+{
+ for (EvaluatedTargetPropertyEntry const& entry : entries) {
std::string usedOptions;
- for (std::string const& opt : entryOptions) {
+ for (std::string const& opt : entry.Values) {
if (uniqueOptions.insert(opt).second) {
if (parse == OptionsParse::Shell &&
cmHasLiteralPrefix(opt, "SHELL:")) {
std::vector<std::string> tmp;
cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
for (std::string& o : tmp) {
- options.emplace_back(std::move(o), entry->GetBacktrace());
+ options.emplace_back(std::move(o), entry.Backtrace);
}
} else {
- options.emplace_back(opt, entry->GetBacktrace());
+ options.emplace_back(opt, entry.Backtrace);
}
if (debugOptions) {
usedOptions += " * " + opt + "\n";
@@ -2983,22 +3038,10 @@ static void processOptionsInternal(
MessageType::LOG,
std::string("Used ") + logName + std::string(" for target ") +
tgt->GetName() + ":\n" + usedOptions,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
}
-
-static void processCompileOptions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "compile options", language,
- OptionsParse::Shell);
}
void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
@@ -3036,37 +3079,19 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
this->DebugCompileOptionsDone = true;
}
- processCompileOptions(this, this->CompileOptionsEntries, result,
- uniqueOptions, &dagChecker, config, debugOptions,
- language);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->CompileOptionsEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceCompileOptionsEntries;
+ AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
+ &dagChecker, entries);
- AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS",
- linkInterfaceCompileOptionsEntries);
+ processOptions(this, entries, result, uniqueOptions, debugOptions,
+ "compile options", OptionsParse::Shell);
- processCompileOptions(this, linkInterfaceCompileOptionsEntries, result,
- uniqueOptions, &dagChecker, config, debugOptions,
- language);
-
- cmDeleteAll(linkInterfaceCompileOptionsEntries);
return result;
}
-static void processCompileFeatures(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "compile features",
- std::string(), OptionsParse::None);
-}
-
void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
const std::string& config) const
{
@@ -3101,34 +3126,19 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
this->DebugCompileFeaturesDone = true;
}
- processCompileFeatures(this, this->CompileFeaturesEntries, result,
- uniqueFeatures, &dagChecker, config, debugFeatures);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
+ this->CompileFeaturesEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceCompileFeaturesEntries;
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
- linkInterfaceCompileFeaturesEntries);
+ std::string(), &dagChecker, entries);
- processCompileFeatures(this, linkInterfaceCompileFeaturesEntries, result,
- uniqueFeatures, &dagChecker, config, debugFeatures);
+ processOptions(this, entries, result, uniqueFeatures, debugFeatures,
+ "compile features", OptionsParse::None);
- cmDeleteAll(linkInterfaceCompileFeaturesEntries);
return result;
}
-static void processCompileDefinitions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "compile definitions", language,
- OptionsParse::None);
-}
-
void cmGeneratorTarget::GetCompileDefinitions(
std::vector<std::string>& result, const std::string& config,
const std::string& language) const
@@ -3165,14 +3175,13 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
this->DebugCompileDefinitionsDone = true;
}
- processCompileDefinitions(this, this->CompileDefinitionsEntries, list,
- uniqueOptions, &dagChecker, config, debugDefines,
- language);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->CompileDefinitionsEntries);
+
+ AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
+ &dagChecker, entries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceCompileDefinitionsEntries;
- AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS",
- linkInterfaceCompileDefinitionsEntries);
if (!config.empty()) {
std::string configPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
@@ -3187,8 +3196,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
CM_FALLTHROUGH;
}
case cmPolicies::OLD: {
- linkInterfaceCompileDefinitionsEntries.push_back(
+ std::unique_ptr<TargetPropertyEntry> entry(
CreateTargetPropertyEntry(configProp));
+ entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, entry.get()));
} break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_ALWAYS:
@@ -3198,29 +3209,12 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
}
- processCompileDefinitions(this, linkInterfaceCompileDefinitionsEntries, list,
- uniqueOptions, &dagChecker, config, debugDefines,
- language);
+ processOptions(this, entries, list, uniqueOptions, debugDefines,
+ "compile definitions", OptionsParse::None);
- cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
return list;
}
-namespace {
-void processLinkOptions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "link options", language,
- OptionsParse::Shell);
-}
-}
-
void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
@@ -3256,20 +3250,15 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
this->DebugLinkOptionsDone = true;
}
- processLinkOptions(this, this->LinkOptionsEntries, result, uniqueOptions,
- &dagChecker, config, debugOptions, language);
-
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceLinkOptionsEntries;
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->LinkOptionsEntries);
- AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS",
- linkInterfaceLinkOptionsEntries);
+ AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
+ &dagChecker, entries);
- processLinkOptions(this, linkInterfaceLinkOptionsEntries, result,
- uniqueOptions, &dagChecker, config, debugOptions,
- language);
-
- cmDeleteAll(linkInterfaceLinkOptionsEntries);
+ processOptions(this, entries, result, uniqueOptions, debugOptions,
+ "link options", OptionsParse::Shell);
// Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper
@@ -3375,21 +3364,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
return result;
}
-namespace {
-void processStaticLibraryLinkOptions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, false, "static library link options",
- language, OptionsParse::Shell);
-}
-}
-
void cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<std::string>& result, const std::string& config,
const std::string& language) const
@@ -3406,47 +3380,41 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::string const& config, std::string const& language) const
{
std::vector<BT<std::string>> result;
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
nullptr, nullptr);
+ std::vector<EvaluatedTargetPropertyEntry> entries;
if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
std::vector<std::string> options;
cmSystemTools::ExpandListArgument(linkOptions, options);
for (const auto& option : options) {
- entries.push_back(CreateTargetPropertyEntry(option));
+ std::unique_ptr<TargetPropertyEntry> entry(
+ CreateTargetPropertyEntry(option));
+ entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, entry.get()));
}
}
- processStaticLibraryLinkOptions(this, entries, result, uniqueOptions,
- &dagChecker, config, language);
+ processOptions(this, entries, result, uniqueOptions, false,
+ "static library link options", OptionsParse::Shell);
- cmDeleteAll(entries);
return result;
}
namespace {
-void processLinkDirectories(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& directories,
- std::unordered_set<std::string>& uniqueDirectories,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugDirectories, std::string const& language)
-{
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- cmLinkImplItem const& item = entry->LinkImplItem;
+void processLinkDirectories(cmGeneratorTarget const* tgt,
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
+ std::vector<BT<std::string>>& directories,
+ std::unordered_set<std::string>& uniqueDirectories,
+ bool debugDirectories)
+{
+ for (EvaluatedTargetPropertyEntry& entry : entries) {
+ cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
- std::vector<std::string> entryDirectories;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt,
- dagChecker, language),
- entryDirectories);
-
std::string usedDirectories;
- for (std::string& entryDirectory : entryDirectories) {
+ for (std::string& entryDirectory : entry.Values) {
if (!cmSystemTools::FileIsFullPath(entryDirectory)) {
std::ostringstream e;
bool noMessage = false;
@@ -3499,7 +3467,7 @@ void processLinkDirectories(
MessageType::LOG,
std::string("Used link directories for target ") + tgt->GetName() +
":\n" + usedDirectories,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
}
@@ -3541,39 +3509,19 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
this->DebugLinkDirectoriesDone = true;
}
- processLinkDirectories(this, this->LinkDirectoriesEntries, result,
- uniqueDirectories, &dagChecker, config,
- debugDirectories, language);
-
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceLinkDirectoriesEntries;
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->LinkDirectoriesEntries);
- AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES",
- linkInterfaceLinkDirectoriesEntries);
+ AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
+ &dagChecker, entries);
- processLinkDirectories(this, linkInterfaceLinkDirectoriesEntries, result,
- uniqueDirectories, &dagChecker, config,
- debugDirectories, language);
+ processLinkDirectories(this, entries, result, uniqueDirectories,
+ debugDirectories);
- cmDeleteAll(linkInterfaceLinkDirectoriesEntries);
return result;
}
-namespace {
-void processLinkDepends(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, false, "link depends", language,
- OptionsParse::None);
-}
-}
-
void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
@@ -3589,24 +3537,27 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
std::string const& config, std::string const& language) const
{
std::vector<BT<std::string>> result;
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
nullptr);
+ std::vector<EvaluatedTargetPropertyEntry> entries;
if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
std::vector<std::string> depends;
cmSystemTools::ExpandListArgument(linkDepends, depends);
for (const auto& depend : depends) {
- linkDependsEntries.push_back(CreateTargetPropertyEntry(depend));
+ std::unique_ptr<TargetPropertyEntry> entry(
+ CreateTargetPropertyEntry(depend));
+ entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, entry.get()));
}
}
- AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS",
- linkDependsEntries);
- processLinkDepends(this, linkDependsEntries, result, uniqueOptions,
- &dagChecker, config, language);
+ AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
+ &dagChecker, entries);
+
+ processOptions(this, entries, result, uniqueOptions, false, "link depends",
+ OptionsParse::None);
- cmDeleteAll(linkDependsEntries);
return result;
}
@@ -4346,8 +4297,9 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
}
}
-static std::string intersect(const std::set<std::string>& s1,
- const std::set<std::string>& s2)
+namespace {
+std::string intersect(const std::set<std::string>& s1,
+ const std::set<std::string>& s2)
{
std::set<std::string> intersect;
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
@@ -4358,9 +4310,9 @@ static std::string intersect(const std::set<std::string>& s1,
return "";
}
-static std::string intersect(const std::set<std::string>& s1,
- const std::set<std::string>& s2,
- const std::set<std::string>& s3)
+std::string intersect(const std::set<std::string>& s1,
+ const std::set<std::string>& s2,
+ const std::set<std::string>& s3)
{
std::string result;
result = intersect(s1, s2);
@@ -4374,10 +4326,10 @@ static std::string intersect(const std::set<std::string>& s1,
return intersect(s2, s3);
}
-static std::string intersect(const std::set<std::string>& s1,
- const std::set<std::string>& s2,
- const std::set<std::string>& s3,
- const std::set<std::string>& s4)
+std::string intersect(const std::set<std::string>& s1,
+ const std::set<std::string>& s2,
+ const std::set<std::string>& s3,
+ const std::set<std::string>& s4)
{
std::string result;
result = intersect(s1, s2);
@@ -4394,6 +4346,7 @@ static std::string intersect(const std::set<std::string>& s1,
}
return intersect(s2, s3, s4);
}
+}
void cmGeneratorTarget::CheckPropertyCompatibility(
cmComputeLinkInformation* info, const std::string& config) const
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 625dd45..385022c 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -13,6 +13,7 @@
#include "cmSystemTools.h"
#include "cmake.h"
+#include <string>
#include <utility>
static std::string cmIfCommandError(
@@ -47,7 +48,7 @@ bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
}
// execute the functions for the true parts of the if statement
- cmExecutionStatus status;
+ cmExecutionStatus status(mf);
int scopeDepth = 0;
for (cmListFileFunction const& func : this->Functions) {
// keep track of scope depth
@@ -176,19 +177,19 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
}
//=========================================================================
-bool cmIfCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
+bool cmIfCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus)
{
+ cmMakefile& makefile = inStatus.GetMakefile();
std::string errorString;
std::vector<cmExpandedCommandArgument> expandedArguments;
- this->Makefile->ExpandArguments(args, expandedArguments);
+ makefile.ExpandArguments(args, expandedArguments);
MessageType status;
cmConditionEvaluator conditionEvaluator(
- *(this->Makefile), this->Makefile->GetExecutionContext(),
- this->Makefile->GetBacktrace());
+ makefile, makefile.GetExecutionContext(), makefile.GetBacktrace());
bool isTrue =
conditionEvaluator.IsTrue(expandedArguments, errorString, status);
@@ -197,11 +198,11 @@ bool cmIfCommand::InvokeInitialPass(
std::string err = "if " + cmIfCommandError(expandedArguments);
err += errorString;
if (status == MessageType::FATAL_ERROR) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err);
+ makefile.IssueMessage(MessageType::FATAL_ERROR, err);
cmSystemTools::SetFatalErrorOccured();
return true;
}
- this->Makefile->IssueMessage(status, err);
+ makefile.IssueMessage(status, err);
}
{
@@ -213,7 +214,7 @@ bool cmIfCommand::InvokeInitialPass(
fb->HasRun = true;
}
fb->Args = args;
- this->Makefile->AddFunctionBlocker(std::move(fb));
+ makefile.AddFunctionBlocker(std::move(fb));
}
return true;
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index 4a67760..775e609 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -5,17 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
class cmExecutionStatus;
-class cmExpandedCommandArgument;
class cmMakefile;
class cmIfFunctionBlocker : public cmFunctionBlocker
@@ -34,37 +29,7 @@ public:
};
/// Starts an if block
-class cmIfCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmIfCommand>();
- }
-
- /**
- * This overrides the default InvokeInitialPass implementation.
- * It records the arguments before expansion.
- */
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
-
- // Filter the given variable definition based on policy CMP0054.
- static const char* GetDefinitionIfUnquoted(
- const cmMakefile* mf, cmExpandedCommandArgument const& argument);
-};
+bool cmIfCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index f5da2ee..78f4f83 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -247,7 +247,8 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
// function blocker
if (initFunction) {
this->Makefile->GetState()->AddScriptedCommand(
- args[0], cm::make_unique<cmLoadedCommand>(initFunction));
+ args[0],
+ cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
return true;
}
this->SetError("Attempt to load command failed. "
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 4ffd6e0..d177278 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1134,11 +1134,13 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags,
std::string const& linkLanguage,
cmGeneratorTarget* target)
{
- this->AppendFlags(
- flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
- if (!config.empty()) {
- std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
- this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name));
+ if (linkLanguage != "Swift") {
+ this->AppendFlags(
+ flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
+ if (!config.empty()) {
+ std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
+ this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name));
+ }
}
this->AppendFlags(flags, target->GetProperty("STATIC_LIBRARY_FLAGS"));
if (!config.empty()) {
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 6e65c6b..22748b4 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -17,35 +17,15 @@
#include "cmSystemTools.h"
// define the class for macro commands
-class cmMacroHelperCommand : public cmCommand
+class cmMacroHelperCommand
{
public:
/**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- auto newC = cm::make_unique<cmMacroHelperCommand>();
- // we must copy when we clone
- newC->Args = this->Args;
- newC->Functions = this->Functions;
- newC->FilePath = this->FilePath;
- newC->Policies = this->Policies;
- return std::unique_ptr<cmCommand>(std::move(newC));
- }
-
- /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const;
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
@@ -53,12 +33,15 @@ public:
std::string FilePath;
};
-bool cmMacroHelperCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
+bool cmMacroHelperCommand::operator()(
+ std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const
{
+ cmMakefile& makefile = inStatus.GetMakefile();
+
// Expand the argument list to the macro.
std::vector<std::string> expandedArgs;
- this->Makefile->ExpandArguments(args, expandedArgs);
+ makefile.ExpandArguments(args, expandedArgs);
// make sure the number of arguments passed is at least the number
// required by the signature
@@ -66,11 +49,11 @@ bool cmMacroHelperCommand::InvokeInitialPass(
std::string errorMsg =
"Macro invoked with incorrect arguments for macro named: ";
errorMsg += this->Args[0];
- this->SetError(errorMsg);
+ inStatus.SetError(errorMsg);
return false;
}
- cmMakefile::MacroPushPop macroScope(this->Makefile, this->FilePath,
+ cmMakefile::MacroPushPop macroScope(&makefile, this->FilePath,
this->Policies);
// set the value of argc
@@ -132,9 +115,8 @@ bool cmMacroHelperCommand::InvokeInitialPass(
arg.Line = k.Line;
newLFF.Arguments.push_back(std::move(arg));
}
- cmExecutionStatus status;
- if (!this->Makefile->ExecuteCommand(newLFF, status) ||
- status.GetNestedError()) {
+ cmExecutionStatus status(makefile);
+ if (!makefile.ExecuteCommand(newLFF, status) || status.GetNestedError()) {
// The error message should have already included the call stack
// so we do not need to report an error here.
macroScope.Quiet();
@@ -166,11 +148,11 @@ bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
if (!this->Depth) {
mf.AppendProperty("MACROS", this->Args[0].c_str());
// create a new command and add it to cmake
- auto f = cm::make_unique<cmMacroHelperCommand>();
- f->Args = this->Args;
- f->Functions = this->Functions;
- f->FilePath = this->GetStartingContext().FilePath;
- mf.RecordPolicies(f->Policies);
+ cmMacroHelperCommand f;
+ f.Args = this->Args;
+ f.Functions = this->Functions;
+ f.FilePath = this->GetStartingContext().FilePath;
+ mf.RecordPolicies(f.Policies);
mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
// remove the function blocker now that the macro is defined
mf.RemoveFunctionBlocker(this, lff);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 1723c5a..3177adc 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -16,7 +16,6 @@
#include <utility>
#include "cmAlgorithms.h"
-#include "cmCommand.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
@@ -388,12 +387,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
}
// Lookup the command prototype.
- if (cmCommand* proto =
+ if (cmState::Command command =
this->GetState()->GetCommandByExactName(lff.Name.Lower)) {
- // Clone the prototype.
- std::unique_ptr<cmCommand> pcmd(proto->Clone());
- pcmd->SetMakefile(this);
-
// Decide whether to invoke the command.
if (!cmSystemTools::GetFatalErrorOccured()) {
// if trace is enabled, print out invoke information
@@ -401,13 +396,13 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
this->PrintCommandTrace(lff);
}
// Try invoking the command.
- bool invokeSucceeded = pcmd->InvokeInitialPass(lff.Arguments, status);
+ bool invokeSucceeded = command(lff.Arguments, status);
bool hadNestedError = status.GetNestedError();
if (!invokeSucceeded || hadNestedError) {
if (!hadNestedError) {
// The command invocation requested that we report an error.
std::string const error =
- std::string(lff.Name.Original) + " " + pcmd->GetError();
+ std::string(lff.Name.Original) + " " + status.GetError();
this->IssueMessage(MessageType::FATAL_ERROR, error);
}
result = false;
@@ -657,7 +652,7 @@ void cmMakefile::ReadListFile(cmListFile const& listFile,
// Run the parsed commands.
const size_t numberFunctions = listFile.Functions.size();
for (size_t i = 0; i < numberFunctions; ++i) {
- cmExecutionStatus status;
+ cmExecutionStatus status(*this);
this->ExecuteCommand(listFile.Functions[i], status);
if (cmSystemTools::GetFatalErrorOccured()) {
break;
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 5320ec5..58f3b2f 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -25,7 +25,6 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
auto i = args.cbegin();
auto type = MessageType::MESSAGE;
- auto status = false;
auto fatal = false;
auto level = cmake::LogLevel::LOG_UNDEFINED;
if (*i == "SEND_ERROR") {
@@ -55,19 +54,15 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
}
++i;
} else if (*i == "STATUS") {
- status = true;
level = cmake::LogLevel::LOG_STATUS;
++i;
} else if (*i == "VERBOSE") {
- status = true;
level = cmake::LogLevel::LOG_VERBOSE;
++i;
} else if (*i == "DEBUG") {
- status = true;
level = cmake::LogLevel::LOG_DEBUG;
++i;
} else if (*i == "TRACE") {
- status = true;
level = cmake::LogLevel::LOG_TRACE;
++i;
} else if (*i == "DEPRECATION") {
@@ -105,17 +100,46 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
- if (type != MessageType::MESSAGE) {
- // we've overridden the message type, above, so display it directly
- cmMessenger* m = this->Makefile->GetMessenger();
- m->DisplayMessage(type, message, this->Makefile->GetBacktrace());
- } else {
- if (status) {
- this->Makefile->DisplayStatus(message, -1);
- } else {
+ if (cmake::LogLevel::LOG_NOTICE <= level) {
+ // Check if any indentation has requested:
+ // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
+ // to be joined and prepended to the message lines.
+ auto indent =
+ cmJoin(cmSystemTools::ExpandedListArgument(
+ this->Makefile->GetSafeDefinition("CMAKE_MESSAGE_INDENT")),
+ "");
+ // Make every line of the `message` indented
+ // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
+ // here cuz it appends `\n` to the EOM ;-(
+ cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
+ message = indent + message;
+ }
+
+ switch (level) {
+ case cmake::LogLevel::LOG_ERROR:
+ case cmake::LogLevel::LOG_WARNING:
+ // we've overridden the message type, above, so display it directly
+ this->Makefile->GetMessenger()->DisplayMessage(
+ type, message, this->Makefile->GetBacktrace());
+ break;
+
+ case cmake::LogLevel::LOG_NOTICE:
cmSystemTools::Message(message);
- }
+ break;
+
+ case cmake::LogLevel::LOG_STATUS:
+ case cmake::LogLevel::LOG_VERBOSE:
+ case cmake::LogLevel::LOG_DEBUG:
+ case cmake::LogLevel::LOG_TRACE:
+ this->Makefile->DisplayStatus(message, -1);
+ break;
+
+ default:
+ assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
+ false);
+ break;
}
+
if (fatal) {
cmSystemTools::SetFatalErrorOccured();
}
diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx
index ceea8b4..5905669 100644
--- a/Source/cmReturnCommand.cxx
+++ b/Source/cmReturnCommand.cxx
@@ -5,8 +5,8 @@
#include "cmExecutionStatus.h"
// cmReturnCommand
-bool cmReturnCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus& status)
+bool cmReturnCommand(std::vector<std::string> const&,
+ cmExecutionStatus& status)
{
status.SetReturnInvoked();
return true;
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index e9264d2..2404a36 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -8,34 +8,10 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmReturnCommand
- * \brief Return from a directory or function
- *
- * cmReturnCommand returns from a directory or function
- */
-class cmReturnCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmReturnCommand>();
- }
-
- /**
- * 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;
-};
+/// Return from a directory or function
+bool cmReturnCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 9748cf5..0b12a65 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -5,8 +5,8 @@
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <assert.h>
+#include <stdlib.h>
#include <string.h>
-#include <type_traits>
#include <utility>
#include "cm_memory.hxx"
@@ -16,12 +16,13 @@
#include "cmCommand.h"
#include "cmDefinitions.h"
#include "cmDisallowedCommand.h"
+#include "cmExecutionStatus.h"
#include "cmGlobVerificationManager.h"
#include "cmListFileCache.h"
+#include "cmMakefile.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
-#include "cmUnexpectedCommand.h"
#include "cmake.h"
cmState::cmState()
@@ -421,11 +422,31 @@ void cmState::SetIsGeneratorMultiConfig(bool 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));
assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
- this->BuiltinCommands.insert(
- std::map<std::string, std::unique_ptr<cmCommand>>::value_type(
- name, std::move(command)));
+ this->BuiltinCommands.emplace(name, std::move(command));
+}
+
+void cmState::AddBuiltinCommand(std::string const& name,
+ BuiltinCommand command)
+{
+ this->AddBuiltinCommand(
+ name,
+ [command](const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus& status) -> bool {
+ std::vector<std::string> expandedArguments;
+ if (!status.GetMakefile().ExpandArguments(args, expandedArguments)) {
+ // There was an error expanding arguments. It was already
+ // reported, so we can skip this command without error.
+ return true;
+ }
+ return command(expandedArguments, status);
+ });
}
void cmState::AddDisallowedCommand(std::string const& name,
@@ -440,49 +461,46 @@ void cmState::AddDisallowedCommand(std::string const& name,
void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
{
- this->AddBuiltinCommand(name,
- cm::make_unique<cmUnexpectedCommand>(name, error));
+ this->AddBuiltinCommand(
+ name,
+ [name, error](std::vector<cmListFileArgument> const&,
+ cmExecutionStatus& status) -> bool {
+ const char* versionValue =
+ status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
+ if (name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) {
+ return true;
+ }
+ status.SetError(error);
+ return false;
+ });
}
-void cmState::AddScriptedCommand(std::string const& name,
- std::unique_ptr<cmCommand> command)
+void cmState::AddScriptedCommand(std::string const& name, Command command)
{
std::string sName = cmSystemTools::LowerCase(name);
// if the command already exists, give a new name to the old command.
- if (cmCommand* oldCmd = this->GetCommand(sName)) {
- std::string const newName = "_" + sName;
- auto pos = this->ScriptedCommands.find(newName);
- if (pos != this->ScriptedCommands.end()) {
- this->ScriptedCommands.erase(pos);
- }
- this->ScriptedCommands.insert(std::make_pair(newName, oldCmd->Clone()));
+ if (Command oldCmd = this->GetCommand(sName)) {
+ this->ScriptedCommands["_" + sName] = oldCmd;
}
- // if the command already exists, free the old one
- auto pos = this->ScriptedCommands.find(sName);
- if (pos != this->ScriptedCommands.end()) {
- this->ScriptedCommands.erase(pos);
- }
- this->ScriptedCommands.insert(
- std::map<std::string, std::unique_ptr<cmCommand>>::value_type(
- sName, std::move(command)));
+ this->ScriptedCommands[sName] = std::move(command);
}
-cmCommand* cmState::GetCommand(std::string const& name) const
+cmState::Command cmState::GetCommand(std::string const& name) const
{
return GetCommandByExactName(cmSystemTools::LowerCase(name));
}
-cmCommand* cmState::GetCommandByExactName(std::string const& name) const
+cmState::Command cmState::GetCommandByExactName(std::string const& name) const
{
auto pos = this->ScriptedCommands.find(name);
if (pos != this->ScriptedCommands.end()) {
- return pos->second.get();
+ return pos->second;
}
pos = this->BuiltinCommands.find(name);
if (pos != this->BuiltinCommands.end()) {
- return pos->second.get();
+ return pos->second;
}
return nullptr;
}
@@ -507,9 +525,7 @@ std::vector<std::string> cmState::GetCommandNames() const
void cmState::RemoveBuiltinCommand(std::string const& name)
{
assert(name == cmSystemTools::LowerCase(name));
- auto i = this->BuiltinCommands.find(name);
- assert(i != this->BuiltinCommands.end());
- this->BuiltinCommands.erase(i);
+ this->BuiltinCommands.erase(name);
}
void cmState::RemoveUserDefinedCommands()
diff --git a/Source/cmState.h b/Source/cmState.h
index 7e88030..8847f3b 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <functional>
#include <map>
#include <memory>
#include <set>
@@ -27,6 +28,7 @@ class cmGlobVerificationManager;
class cmPropertyDefinition;
class cmStateSnapshot;
class cmMessenger;
+class cmExecutionStatus;
class cmState
{
@@ -141,19 +143,25 @@ public:
bool GetIsGeneratorMultiConfig() const;
void SetIsGeneratorMultiConfig(bool b);
+ using Command = std::function<bool(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus&)>;
+ using BuiltinCommand = bool (*)(std::vector<std::string> const&,
+ cmExecutionStatus&);
+
// Returns a command from its name, case insensitive, or nullptr
- cmCommand* GetCommand(std::string const& name) const;
+ Command GetCommand(std::string const& name) const;
// Returns a command from its name, or nullptr
- cmCommand* GetCommandByExactName(std::string const& name) const;
+ 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 AddDisallowedCommand(std::string const& name,
std::unique_ptr<cmCommand> command,
cmPolicies::PolicyID policy, const char* message);
void AddUnexpectedCommand(std::string const& name, const char* error);
- void AddScriptedCommand(std::string const& name,
- std::unique_ptr<cmCommand> command);
+ void AddScriptedCommand(std::string const& name, Command command);
void RemoveBuiltinCommand(std::string const& name);
void RemoveUserDefinedCommands();
std::vector<std::string> GetCommandNames() const;
@@ -212,8 +220,8 @@ private:
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
std::vector<std::string> EnabledLanguages;
- std::map<std::string, std::unique_ptr<cmCommand>> BuiltinCommands;
- std::map<std::string, std::unique_ptr<cmCommand>> ScriptedCommands;
+ std::map<std::string, Command> BuiltinCommands;
+ std::map<std::string, Command> ScriptedCommands;
cmPropertyMap GlobalProperties;
std::unique_ptr<cmCacheManager> CacheManager;
std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager;
diff --git a/Source/cmUnexpectedCommand.cxx b/Source/cmUnexpectedCommand.cxx
deleted file mode 100644
index a8de9e6..0000000
--- a/Source/cmUnexpectedCommand.cxx
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmUnexpectedCommand.h"
-
-#include <stdlib.h>
-
-#include "cmMakefile.h"
-
-class cmExecutionStatus;
-
-bool cmUnexpectedCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&)
-{
- const char* versionValue =
- this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
- if (this->Name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) {
- return true;
- }
-
- this->SetError(this->Error);
- return false;
-}
diff --git a/Source/cmUnexpectedCommand.h b/Source/cmUnexpectedCommand.h
deleted file mode 100644
index 6e4cee5..0000000
--- a/Source/cmUnexpectedCommand.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmUnexpectedCommand_h
-#define cmUnexpectedCommand_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
-class cmExecutionStatus;
-
-class cmUnexpectedCommand : public cmCommand
-{
-public:
- cmUnexpectedCommand(std::string name, const char* error)
- : Name(std::move(name))
- , Error(error)
- {
- }
-
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmUnexpectedCommand>(this->Name, this->Error);
- }
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- std::string Name;
- const char* Error;
-};
-
-#endif
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index afc0b76..83a774d 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -55,7 +55,7 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999);
newLFF.Name = data->Command;
newLFF.Line = 9999;
- cmExecutionStatus status;
+ cmExecutionStatus status(*makefile);
if (!makefile->ExecuteCommand(newLFF, status)) {
std::ostringstream error;
error << "Error in cmake code at\nUnknown:0:\n"
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index a902964..37d1c74 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -11,6 +11,7 @@
#include "cmMessageType.h"
#include "cmSystemTools.h"
+#include <string>
#include <utility>
cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf)
@@ -82,7 +83,7 @@ bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
// Invoke all the functions that were collected in the block.
for (cmListFileFunction const& fn : this->Functions) {
- cmExecutionStatus status;
+ cmExecutionStatus status(mf);
mf.ExecuteCommand(fn, status);
if (status.GetReturnInvoked()) {
inStatus.SetReturnInvoked();
@@ -129,19 +130,20 @@ bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
return false;
}
-bool cmWhileCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
+bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// create a function blocker
{
- auto fb = cm::make_unique<cmWhileFunctionBlocker>(this->Makefile);
+ cmMakefile& makefile = status.GetMakefile();
+ auto fb = cm::make_unique<cmWhileFunctionBlocker>(&makefile);
fb->Args = args;
- this->Makefile->AddFunctionBlocker(std::move(fb));
+ makefile.AddFunctionBlocker(std::move(fb));
}
return true;
}
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index 857d1c8..2257799 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -5,12 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
@@ -35,33 +31,7 @@ private:
};
/// \brief Starts a while loop
-class cmWhileCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmWhileCommand>();
- }
-
- /**
- * This overrides the default InvokeInitialPass implementation.
- * It records the arguments before expansion.
- */
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
-};
+bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 37df57c..d93f280 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -33,6 +33,6 @@ run_cpack_test(TIMESTAMPS "DEB.TIMESTAMPS;TGZ" false "COMPONENT")
unset(ENVIRONMENT)
run_cpack_test(USER_FILELIST "RPM.USER_FILELIST" false "MONOLITHIC")
run_cpack_test(MD5SUMS "DEB.MD5SUMS" false "MONOLITHIC;COMPONENT")
-run_cpack_test(CPACK_INSTALL_SCRIPT "ZIP" false "MONOLITHIC")
+run_cpack_test_subtests(CPACK_INSTALL_SCRIPTS "singular;plural;both" "ZIP" false "MONOLITHIC")
run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB.DEB_PACKAGE_VERSION_BACK_COMPATIBILITY" false "MONOLITHIC;COMPONENT")
run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake
deleted file mode 100644
index e3fe0ca..0000000
--- a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/abc.txt" "test content")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake"
- "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/foo\"
- TYPE FILE FILES \"${CMAKE_CURRENT_BINARY_DIR}/abc.txt\")")
-set(CPACK_INSTALL_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake")
-
-function(run_after_include_cpack)
- file(READ "${CPACK_OUTPUT_CONFIG_FILE}" conf_file_)
- string(REGEX REPLACE "SET\\(CPACK_INSTALL_CMAKE_PROJECTS [^)]*\\)" "" conf_file_ "${conf_file_}")
- file(WRITE "${CPACK_OUTPUT_CONFIG_FILE}" "${conf_file_}")
-endfunction()
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/ExpectedFiles.cmake
index 02a7821..02a7821 100644
--- a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/ExpectedFiles.cmake
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt
new file mode 100644
index 0000000..666030e
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt
@@ -0,0 +1 @@
+CPack Warning: Both CPACK_INSTALL_SCRIPTS and CPACK_INSTALL_SCRIPT are set, the latter will be ignored.
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake
new file mode 100644
index 0000000..249d2e6
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake
@@ -0,0 +1,26 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/abc.txt" "test content")
+set(user_script_ "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake")
+file(WRITE "${user_script_}"
+ "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/foo\"
+ TYPE FILE FILES \"${CMAKE_CURRENT_BINARY_DIR}/abc.txt\")")
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "both")
+ set(CPACK_INSTALL_SCRIPT "${user_script_}")
+ set(CPACK_INSTALL_SCRIPTS "${CPACK_INSTALL_SCRIPT}")
+
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "singular")
+ set(CPACK_INSTALL_SCRIPT "${user_script_}")
+
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "plural")
+ set(CPACK_INSTALL_SCRIPTS "${user_script_}")
+
+else()
+ message(FATAL_ERROR "Unexpected subtest name: ${RunCMake_SUBTEST_SUFFIX}")
+
+endif()
+
+function(run_after_include_cpack)
+ file(READ "${CPACK_OUTPUT_CONFIG_FILE}" conf_file_)
+ string(REGEX REPLACE "SET\\(CPACK_INSTALL_CMAKE_PROJECTS [^)]*\\)" "" conf_file_ "${conf_file_}")
+ file(WRITE "${CPACK_OUTPUT_CONFIG_FILE}" "${conf_file_}")
+endfunction()
diff --git a/Tests/RunCMake/message/RunCMakeTest.cmake b/Tests/RunCMake/message/RunCMakeTest.cmake
index cecfc7f..3c7e51c 100644
--- a/Tests/RunCMake/message/RunCMakeTest.cmake
+++ b/Tests/RunCMake/message/RunCMakeTest.cmake
@@ -52,3 +52,12 @@ run_cmake_command(
message-loglevel-trace
${CMAKE_COMMAND} --loglevel=trace -P ${RunCMake_SOURCE_DIR}/message-all-loglevels.cmake
)
+
+run_cmake_command(
+ message-indent
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent.cmake
+ )
+run_cmake_command(
+ message-indent-multiline
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent-multiline.cmake
+ )
diff --git a/Tests/RunCMake/message/message-indent-multiline-stderr.txt b/Tests/RunCMake/message/message-indent-multiline-stderr.txt
new file mode 100644
index 0000000..5853a31
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-multiline-stderr.txt
@@ -0,0 +1,3 @@
+ >This is
+ >the multiline
+ >message
diff --git a/Tests/RunCMake/message/message-indent-multiline-stdout.txt b/Tests/RunCMake/message/message-indent-multiline-stdout.txt
new file mode 100644
index 0000000..ae0c72e
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-multiline-stdout.txt
@@ -0,0 +1,8 @@
+-- >This is
+ >the multiline
+ >message
+ >
+ >
+-- >This is
+ >the multiline
+ >message
diff --git a/Tests/RunCMake/message/message-indent-multiline.cmake b/Tests/RunCMake/message/message-indent-multiline.cmake
new file mode 100644
index 0000000..0f789bf
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-multiline.cmake
@@ -0,0 +1,13 @@
+# NOTE Use non-space indent string, to check indentation
+# of line endings and "empty" lines.
+# ALERT Do not put any space characters after the non-space!
+list(APPEND CMAKE_MESSAGE_INDENT " >")
+set(msg [[This is
+the multiline
+message]]) # No `\n` at the end!
+# NOTE Two empty lines after the text
+message(STATUS "${msg}\n\n")
+message(STATUS "${msg}")
+# This is just to make sure NOTICE messages are also get indented:
+# https://gitlab.kitware.com/cmake/cmake/issues/19418#note_588011
+message(NOTICE "${msg}")
diff --git a/Tests/RunCMake/message/message-indent-stdout.txt b/Tests/RunCMake/message/message-indent-stdout.txt
new file mode 100644
index 0000000..b2c3c60
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-stdout.txt
@@ -0,0 +1,13 @@
+-- COUNTING:
+-- COUNTING_ENGLISH:
+-- one
+-- two
+-- three
+-- four
+-- five
+-- COUNTING_BAHASA:
+-- satu
+-- dua
+-- tiga
+-- empat
+-- lima
diff --git a/Tests/RunCMake/message/message-indent.cmake b/Tests/RunCMake/message/message-indent.cmake
new file mode 100644
index 0000000..c07ff45
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent.cmake
@@ -0,0 +1,19 @@
+function(debug_list LIST_VAR)
+ message(STATUS "${LIST_VAR}:")
+ list(APPEND CMAKE_MESSAGE_INDENT " ")
+ foreach(_item IN LISTS ${LIST_VAR})
+ list(LENGTH ${_item} _item_len)
+ if(_item_len GREATER 1)
+ debug_list(${_item})
+ else()
+ message(STATUS "${_item}")
+ endif()
+ endforeach()
+endfunction()
+
+list(APPEND COUNTING_ENGLISH one two three four five)
+list(APPEND COUNTING_BAHASA satu dua tiga empat lima)
+
+list(APPEND COUNTING COUNTING_ENGLISH COUNTING_BAHASA)
+
+debug_list(COUNTING)
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 37522fc..bc8a7dc 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -449,7 +449,12 @@ if(CMAKE_USE_SECTRANSP)
endif()
if(CMAKE_USE_OPENSSL)
- find_package(OpenSSL REQUIRED)
+ find_package(OpenSSL)
+ if(NOT OpenSSL_FOUND)
+ message(FATAL_ERROR
+ "Could not find OpenSSL. Install an OpenSSL development package or "
+ "configure CMake with -DCMAKE_USE_OPENSSL=OFF to build without OpenSSL.")
+ endif()
set(SSL_ENABLED ON)
set(USE_OPENSSL ON)
set(HAVE_LIBCRYPTO ON)
diff --git a/bootstrap b/bootstrap
index c2194fe..7d9631c 100755
--- a/bootstrap
+++ b/bootstrap
@@ -440,7 +440,6 @@ CMAKE_CXX_SOURCES="\
cmTimestamp \
cmTryCompileCommand \
cmTryRunCommand \
- cmUnexpectedCommand \
cmUnsetCommand \
cmUVHandlePtr \
cmUVProcessChain \
@@ -1125,6 +1124,25 @@ echo '
#error "SunPro <= 5.13 mode not supported due to bug in move semantics."
#endif
+#if __cplusplus > 201103L
+#include <iterator>
+int check_cxx14()
+{
+ int a[] = { 0, 1, 2 };
+ auto ai = std::cbegin(a);
+
+ int b[] = { 2, 1, 0 };
+ auto bi = std::cend(b);
+
+ return *ai + *(bi - 1);
+}
+#else
+int check_cxx14()
+{
+ return 0;
+}
+#endif
+
class Class
{
public:
@@ -1135,7 +1153,7 @@ private:
int main()
{
auto const c = std::unique_ptr<Class>(new Class);
- std::cout << c->Get() << std::endl;
+ std::cout << c->Get() << check_cxx14() << std::endl;
return 0;
}
' > "${TMPFILE}.cxx"