summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/string.rst7
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst2
-rw-r--r--Help/release/dev/FeatureSummary_enhancement.rst22
-rw-r--r--Help/release/dev/SOURCE_DATE_EPOCH.rst5
-rw-r--r--Help/release/dev/if-genex.rst7
-rw-r--r--Help/release/dev/timestamp-percent.rst5
-rw-r--r--Modules/Compiler/GNU-C-DetermineCompiler.cmake (renamed from Modules/Compiler/GNU-DetermineCompiler.cmake)0
-rw-r--r--Modules/Compiler/GNU-CXX-DetermineCompiler.cmake15
-rw-r--r--Modules/FeatureSummary.cmake330
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGeneratorExpressionNode.cxx22
-rw-r--r--Source/cmTimestamp.cxx12
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt17
-rw-r--r--Tests/GeneratorExpression/check-part3.cmake19
-rw-r--r--Tests/GeneratorExpression/check-part4.cmake5
-rw-r--r--Tests/Preprocess/CMakeLists.txt14
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-stderr.txt9
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault.cmake8
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stdout.txt17
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired.cmake16
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stdout.txt17
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA.cmake16
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stdout.txt17
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB.cmake16
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes-stdout.txt29
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes.cmake36
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stdout.txt17
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages.cmake12
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages-stdout.txt14
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages.cmake11
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends-stdout.txt10
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends.cmake12
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose-stdout.txt16
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose.cmake16
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty-stdout.txt5
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty.cmake14
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryTypes-stdout.txt45
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryTypes.cmake48
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription-stdout.txt32
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription.cmake28
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt4
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt4
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt2
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake4
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt2
-rw-r--r--Tests/RunCMake/FeatureSummary/FindBar.cmake2
-rw-r--r--Tests/RunCMake/FeatureSummary/FindBaz.cmake2
-rw-r--r--Tests/RunCMake/FeatureSummary/FindFoo.cmake4
-rw-r--r--Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadIF-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadIF-stderr.txt15
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadIF.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/string/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/string/Timestamp-result.txt1
-rw-r--r--Tests/RunCMake/string/Timestamp-stderr.txt1
-rw-r--r--Tests/RunCMake/string/Timestamp.cmake3
-rw-r--r--Tests/RunCMake/string/TimestampEmpty-result.txt1
-rw-r--r--Tests/RunCMake/string/TimestampEmpty-stderr.txt1
-rw-r--r--Tests/RunCMake/string/TimestampEmpty.cmake3
-rw-r--r--Tests/RunCMake/string/TimestampInvalid-result.txt1
-rw-r--r--Tests/RunCMake/string/TimestampInvalid-stderr.txt1
-rw-r--r--Tests/RunCMake/string/TimestampInvalid.cmake3
-rw-r--r--Tests/RunCMake/string/TimestampInvalid2-result.txt1
-rw-r--r--Tests/RunCMake/string/TimestampInvalid2-stderr.txt1
-rw-r--r--Tests/RunCMake/string/TimestampInvalid2.cmake3
-rw-r--r--Utilities/.gitattributes1
-rw-r--r--Utilities/GitSetup/.gitattributes5
-rw-r--r--Utilities/GitSetup/README7
-rw-r--r--Utilities/GitSetup/config.sample10
-rwxr-xr-xUtilities/GitSetup/git-gerrit-push74
-rwxr-xr-xUtilities/GitSetup/git-gitlab-push177
-rwxr-xr-xUtilities/GitSetup/setup-gerrit15
-rwxr-xr-xUtilities/GitSetup/setup-gitlab140
-rwxr-xr-xUtilities/GitSetup/setup-hooks1
-rwxr-xr-xUtilities/GitSetup/setup-stage9
-rwxr-xr-xUtilities/GitSetup/setup-upstream104
-rwxr-xr-xUtilities/Scripts/update-gitsetup.bash20
87 files changed, 1478 insertions, 142 deletions
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 77538f6..698a91d 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -296,6 +296,7 @@ specifiers:
::
+ %% A literal percent sign (%).
%d The day of the current month (01-31).
%H The hour on a 24-hour clock (00-23).
%I The hour on a 12-hour clock (01-12).
@@ -329,6 +330,12 @@ If no explicit ``<format string>`` is given it will default to:
Write a string which can be used as an identifier in C.
+.. note::
+
+ If the ``SOURCE_DATE_EPOCH`` environment variable is set,
+ its value will be used instead of the current time.
+ See https://reproducible-builds.org/specs/source-date-epoch/ for details.
+
UUID
""""
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 64d15a9..3a225ad 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -51,6 +51,8 @@ Available logical expressions are:
``0`` if all ``?`` are ``0``, else ``1``
``$<NOT:?>``
``0`` if ``?`` is ``1``, else ``1``
+``$<IF:?,true-value...,false-value...>```
+ ``true-value...`` if ``?`` is ``1``, ``false-value...`` if ``?`` is ``0``
``$<STREQUAL:a,b>``
``1`` if ``a`` is STREQUAL ``b``, else ``0``
``$<EQUAL:a,b>``
diff --git a/Help/release/dev/FeatureSummary_enhancement.rst b/Help/release/dev/FeatureSummary_enhancement.rst
new file mode 100644
index 0000000..3a5d85f
--- /dev/null
+++ b/Help/release/dev/FeatureSummary_enhancement.rst
@@ -0,0 +1,22 @@
+FeatureSummary_enhancement
+--------------------------
+
+* The :command:`set_package_info`, :command:`set_feature_info`,
+ :command:`print_enabled_features` and :command:`print_disabled_features`
+ commands from the the :module:`FeatureSummary` module are now deprecated.
+
+* The :command:`set_package_properties` command no longer forces the package
+ type to ``OPTIONAL`` when the type is not explicitly set.
+
+* The :command:`feature_summary` command in the :module:`FeatureSummary` module
+ accepts the new ``QUIET_ON_EMPTY`` option that will suppresses the output when
+ the list of packages that belong to the selected category is empty.
+
+* The :command:`add_feature_info` in the :module:`FeatureSummary` module learned
+ to accept lists of dependencies for deciding whether a feature is enabled or
+ not.
+
+* The package types accepted by the the :module:`FeatureSummary` module can now
+ be tweaked by changing the :variable:`FeatureSummary_PKG_TYPES`,
+ :variable:`FeatureSummary_REQUIRED_PKG_TYPES` and
+ :variable:`FeatureSummary_DEFAULT_PKG_TYPE` global properties.
diff --git a/Help/release/dev/SOURCE_DATE_EPOCH.rst b/Help/release/dev/SOURCE_DATE_EPOCH.rst
new file mode 100644
index 0000000..576e1da
--- /dev/null
+++ b/Help/release/dev/SOURCE_DATE_EPOCH.rst
@@ -0,0 +1,5 @@
+SOURCE_DATE_EPOCH
+-----------------
+
+* The :command:`string(TIMESTAMP)` will now honor the ``SOURCE_DATE_EPOCH``
+ environment variable and use its value instead of the current time.
diff --git a/Help/release/dev/if-genex.rst b/Help/release/dev/if-genex.rst
new file mode 100644
index 0000000..62be3a7
--- /dev/null
+++ b/Help/release/dev/if-genex.rst
@@ -0,0 +1,7 @@
+genex-if
+--------
+
+* A new logical generator expression for immediate-if was added:
+ ``$<IF:cond,true-value,false-value>``. It takes three arguments: One
+ condition, a true-value, and a false-value. Resolves to the true-value if the
+ condition is ``1``, and resolves to the false-value if the condition is ``0``.
diff --git a/Help/release/dev/timestamp-percent.rst b/Help/release/dev/timestamp-percent.rst
new file mode 100644
index 0000000..046d6c5
--- /dev/null
+++ b/Help/release/dev/timestamp-percent.rst
@@ -0,0 +1,5 @@
+timestamp-percent
+-----------------
+
+* The :command:`string(TIMESTAMP)` command learned to treat ``%%``
+ as a way to encode plain ``%``.
diff --git a/Modules/Compiler/GNU-DetermineCompiler.cmake b/Modules/Compiler/GNU-C-DetermineCompiler.cmake
index 6ddc566..6ddc566 100644
--- a/Modules/Compiler/GNU-DetermineCompiler.cmake
+++ b/Modules/Compiler/GNU-C-DetermineCompiler.cmake
diff --git a/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake b/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake
new file mode 100644
index 0000000..c25b147
--- /dev/null
+++ b/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake
@@ -0,0 +1,15 @@
+
+set(_compiler_id_pp_test "defined(__GNUC__) || defined(__GNUG__)")
+
+set(_compiler_id_version_compute "
+# if defined(__GNUC__)
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__GNUC__)
+# else
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__GNUG__)
+# endif
+# if defined(__GNUC_MINOR__)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
+# endif
+# if defined(__GNUC_PATCHLEVEL__)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__GNUC_PATCHLEVEL__)
+# endif")
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index 78d9df3..8910be7 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -14,30 +14,93 @@ packages and/or feature for a build tree such as::
LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org>
* Enables HTML-import in MyWordProcessor
* Enables odt-export in MyWordProcessor
- PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
+ PNG, A PNG image library., <http://www.libpng.org/pub/png/>
* Enables saving screenshots
-- The following OPTIONAL packages have not been found:
- Lua51 , The Lua scripting language. , <http://www.lua.org>
+ Lua51, The Lua scripting language., <http://www.lua.org>
* Enables macros in MyWordProcessor
- Foo , Foo provides cool stuff.
+ Foo, Foo provides cool stuff.
+
+Global Properties
+^^^^^^^^^^^^^^^^^
+
+.. variable:: FeatureSummary_PKG_TYPES
+
+The global property :variable:`FeatureSummary_PKG_TYPES` defines the type of
+packages used by `FeatureSummary`.
+
+The order in this list is important, the first package type in the list is the
+least important, the last is the most important. the of a package can only be
+changed to higher types.
+
+The default package types are , ``RUNTIME``, ``OPTIONAL``, ``RECOMMENDED`` and
+``REQUIRED``, and their importance is
+``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``.
+
+
+.. variable:: FeatureSummary_REQUIRED_PKG_TYPES
+
+The global property :variable:`FeatureSummary_REQUIRED_PKG_TYPES` defines which
+package types are required.
+
+If one or more package in this categories has not been found, CMake will abort
+when calling :cmd;`feature_summary` with the
+'FATAL_ON_MISSING_REQUIRED_PACKAGES' option enabled.
+
+The default value for this global property is ``REQUIRED``.
+
+
+.. variable:: FeatureSummary_DEFAULT_PKG_TYPE
+
+The global property :variable:`FeatureSummary_DEFAULT_PKG_TYPE` defines which
+package type is the default one.
+When calling :cmd;`feature_summary`, if the user did not set the package type
+explicitly, the package will be assigned to this category.
+
+This value must be one of the types defined in the
+:variable:`FeatureSummary_PKG_TYPES` global property unless the package type
+is set for all the packages.
+
+The default value for this global property is ``OPTIONAL``.
+
+#]=======================================================================]
+
+get_property(_fsPkgTypeIsSet GLOBAL PROPERTY FeatureSummary_PKG_TYPES SET)
+if(NOT _fsPkgTypeIsSet)
+ set_property(GLOBAL PROPERTY FeatureSummary_PKG_TYPES RUNTIME OPTIONAL RECOMMENDED REQUIRED)
+endif()
+
+get_property(_fsReqPkgTypesIsSet GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES SET)
+if(NOT _fsReqPkgTypesIsSet)
+ set_property(GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES REQUIRED)
+endif()
+
+get_property(_fsDefaultPkgTypeIsSet GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE SET)
+if(NOT _fsDefaultPkgTypeIsSet)
+ set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE OPTIONAL)
+endif()
+
+#[=======================================================================[.rst:
Functions
^^^^^^^^^
#]=======================================================================]
+include(CMakeParseArguments)
+
function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
+ get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES)
+ get_property(_fsDefaultPkgType GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE)
+
set(_type "ANY")
- if("${_property}" MATCHES "REQUIRED_")
- set(_type "REQUIRED")
- elseif("${_property}" MATCHES "RECOMMENDED_")
- set(_type "RECOMMENDED")
- elseif("${_property}" MATCHES "RUNTIME_")
- set(_type "RUNTIME")
- elseif("${_property}" MATCHES "OPTIONAL_")
- set(_type "OPTIONAL")
- endif()
+ foreach(_fsPkgType ${_fsPkgTypes})
+ if("${_property}" MATCHES "${_fsPkgType}_PACKAGES_(NOT_)?FOUND")
+ set(_type "${_fsPkgType}")
+ break()
+ endif()
+ endforeach()
if("${_property}" MATCHES "PACKAGES_FOUND")
set(_property "PACKAGES_FOUND")
@@ -57,15 +120,30 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
# does this package belong to the type we currently want to list ?
get_property(_currentType GLOBAL PROPERTY _CMAKE_${_currentFeature}_TYPE)
if(NOT _currentType)
- set(_currentType OPTIONAL)
+ list(FIND _fsPkgTypes "${_fsDefaultPkgType}" _defaultInPkgTypes)
+ if("${_defaultInPkgTypes}" STREQUAL "-1")
+ string(REGEX REPLACE ";([^;]+)$" " and \\1" _fsPkgTypes_msg "${_fsPkgTypes}")
+ string(REPLACE ";" ", " _fsPkgTypes_msg "${_fsPkgTypes_msg}")
+ message(FATAL_ERROR "Bad package property type ${_fsDefaultPkgType} used in global property FeatureSummary_DEFAULT_PKG_TYPE. "
+ "Valid types are ${_fsPkgTypes_msg}. "
+ "Either update FeatureSummary_DEFAULT_PKG_TYPE or add ${_fsDefaultPkgType} to the FeatureSummary_PKG_TYPES global property.")
+ endif()
+ set(_currentType ${_fsDefaultPkgType})
endif()
if("${_type}" STREQUAL ANY OR "${_type}" STREQUAL "${_currentType}")
-
# check whether the current feature/package should be in the output depending on whether it was QUIET or not
set(includeThisOne TRUE)
+ set(_required FALSE)
# skip QUIET packages, except if they are REQUIRED or INCLUDE_QUIET_PACKAGES has been set
- if((NOT "${_currentType}" STREQUAL "REQUIRED") AND NOT _includeQuiet)
+ get_property(_fsReqPkgTypes GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES)
+ foreach(_fsReqPkgType ${_fsReqPkgTypes})
+ if("${_currentType}" STREQUAL "${_fsReqPkgType}")
+ set(_required TRUE)
+ break()
+ endif()
+ endforeach()
+ if(NOT _required AND NOT _includeQuiet)
get_property(_isQuiet GLOBAL PROPERTY _CMAKE_${_currentFeature}_QUIET)
if(_isQuiet)
set(includeThisOne FALSE)
@@ -87,11 +165,11 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
endif()
get_property(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_DESCRIPTION)
if(_info)
- string(APPEND _currentFeatureText " , ${_info}")
+ string(APPEND _currentFeatureText ", ${_info}")
endif()
get_property(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_URL)
if(_info)
- string(APPEND _currentFeatureText " , <${_info}>")
+ string(APPEND _currentFeatureText ", <${_info}>")
endif()
get_property(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_PURPOSE)
@@ -119,6 +197,7 @@ endfunction()
[INCLUDE_QUIET_PACKAGES]
[FATAL_ON_MISSING_REQUIRED_PACKAGES]
[DESCRIPTION "Found packages:"]
+ [QUIET_ON_EMPTY]
WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
| ENABLED_FEATURES | DISABLED_FEATURES)
)
@@ -143,22 +222,15 @@ endfunction()
the list of all packages which have been found
``PACKAGES_NOT_FOUND``
the list of all packages which have not been found
- ``OPTIONAL_PACKAGES_FOUND``
- only those packages which have been found which have the type OPTIONAL
- ``OPTIONAL_PACKAGES_NOT_FOUND``
- only those packages which have not been found which have the type OPTIONAL
- ``RECOMMENDED_PACKAGES_FOUND``
- only those packages which have been found which have the type RECOMMENDED
- ``RECOMMENDED_PACKAGES_NOT_FOUND``
- only those packages which have not been found which have the type RECOMMENDED
- ``REQUIRED_PACKAGES_FOUND``
- only those packages which have been found which have the type REQUIRED
- ``REQUIRED_PACKAGES_NOT_FOUND``
- only those packages which have not been found which have the type REQUIRED
- ``RUNTIME_PACKAGES_FOUND``
- only those packages which have been found which have the type RUNTIME
- ``RUNTIME_PACKAGES_NOT_FOUND``
- only those packages which have not been found which have the type RUNTIME
+
+ For each package type ``<TYPE>`` defined by the
+ :variable:`FeatureSummary_PKG_TYPES` global property, the following
+ information can also be used:
+
+ ``<TYPE>_PACKAGES_FOUND``
+ only those packages which have been found which have the type <TYPE>
+ ``<TYPE>_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type <TYPE>
With the exception of the ``ALL`` value, these values can be combined
in order to customize the output. For example:
@@ -177,7 +249,20 @@ endfunction()
packages which have been searched with ``find_package(... QUIET)`` will
also be listed. By default they are skipped. If
``FATAL_ON_MISSING_REQUIRED_PACKAGES`` is given, CMake will abort if a
- package which is marked as ``REQUIRED`` has not been found.
+ package which is marked as one of the package types listed in the
+ :variable:`FeatureSummary_REQUIRED_PKG_TYPES` global property has not been
+ found.
+ The default value for the :variable:`FeatureSummary_REQUIRED_PKG_TYPES` global
+ property is ``REQUIRED``.
+
+ The :variable:`FeatureSummary_DEFAULT_PKG_TYPE` global property can be
+ modified to change the default package type assigned when not explicitly
+ assigned by the user.
+
+ If the ``QUIET_ON_EMPTY`` option is used, if only one type of package was
+ requested, and no packages belonging to that category were found, then no
+ output (including the ``DESCRIPTION``) is printed or added to the ``VAR``
+ variable.
Example 1, append everything to a file:
@@ -198,11 +283,28 @@ endfunction()
DESCRIPTION "Enabled Features:"
VAR enabledFeaturesText)
message(STATUS "${enabledFeaturesText}")
+
+ Example 3, change default package types and print only the categories that
+ are not empty:
+
+ .. code-block:: cmake
+
+ include(FeatureSummary)
+ set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD)
+ find_package(FOO)
+ set_package_properties(FOO PROPERTIES TYPE BUILD)
+ feature_summary(WHAT BUILD_PACKAGES_FOUND
+ Description "Build tools found:"
+ QUIET_ON_EMPTY)
+ feature_summary(WHAT BUILD_PACKAGES_NOT_FOUND
+ Description "Build tools not found:"
+ QUIET_ON_EMPTY)
+
#]=======================================================================]
function(FEATURE_SUMMARY)
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
- set(options APPEND INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
+ set(options APPEND INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES QUIET_ON_EMPTY)
set(oneValueArgs FILENAME VAR DESCRIPTION)
set(multiValueArgs WHAT)
@@ -219,40 +321,42 @@ function(FEATURE_SUMMARY)
set(validWhatParts "ENABLED_FEATURES"
"DISABLED_FEATURES"
"PACKAGES_FOUND"
- "PACKAGES_NOT_FOUND"
- "OPTIONAL_PACKAGES_FOUND"
- "OPTIONAL_PACKAGES_NOT_FOUND"
- "RECOMMENDED_PACKAGES_FOUND"
- "RECOMMENDED_PACKAGES_NOT_FOUND"
- "REQUIRED_PACKAGES_FOUND"
- "REQUIRED_PACKAGES_NOT_FOUND"
- "RUNTIME_PACKAGES_FOUND"
- "RUNTIME_PACKAGES_NOT_FOUND")
+ "PACKAGES_NOT_FOUND")
+
+ get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES)
+ get_property(_fsReqPkgTypes GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES)
+ foreach(_fsPkgType ${_fsPkgTypes})
+ list(APPEND validWhatParts "${_fsPkgType}_PACKAGES_FOUND"
+ "${_fsPkgType}_PACKAGES_NOT_FOUND")
+ endforeach()
list(FIND validWhatParts "${_FS_WHAT}" indexInList)
if(NOT "${indexInList}" STREQUAL "-1")
_FS_GET_FEATURE_SUMMARY( ${_FS_WHAT} _featureSummary ${_FS_INCLUDE_QUIET_PACKAGES} )
- set(_fullText "${_FS_DESCRIPTION}${_featureSummary}\n")
- if (("${_FS_WHAT}" STREQUAL "REQUIRED_PACKAGES_NOT_FOUND") AND _featureSummary)
- set(requiredPackagesNotFound TRUE)
+ if(_featureSummary OR NOT _FS_QUIET_ON_EMPTY)
+ set(_fullText "${_FS_DESCRIPTION}${_featureSummary}\n")
+ endif()
+
+ if(_featureSummary)
+ foreach(_fsReqPkgType ${_fsReqPkgTypes})
+ if("${_FS_WHAT}" STREQUAL "${_fsReqPkgType}_PACKAGES_NOT_FOUND")
+ set(requiredPackagesNotFound TRUE)
+ break()
+ endif()
+ endforeach()
endif()
else()
if("${_FS_WHAT}" STREQUAL "ALL")
- set(allWhatParts "ENABLED_FEATURES"
- "RUNTIME_PACKAGES_FOUND"
- "OPTIONAL_PACKAGES_FOUND"
- "RECOMMENDED_PACKAGES_FOUND"
- "REQUIRED_PACKAGES_FOUND"
-
- "DISABLED_FEATURES"
- "RUNTIME_PACKAGES_NOT_FOUND"
- "OPTIONAL_PACKAGES_NOT_FOUND"
- "RECOMMENDED_PACKAGES_NOT_FOUND"
- "REQUIRED_PACKAGES_NOT_FOUND"
- )
-
+ set(allWhatParts "ENABLED_FEATURES")
+ foreach(_fsPkgType ${_fsPkgTypes})
+ list(APPEND allWhatParts "${_fsPkgType}_PACKAGES_FOUND")
+ endforeach()
+ list(APPEND allWhatParts "DISABLED_FEATURES")
+ foreach(_fsPkgType ${_fsPkgTypes})
+ list(APPEND allWhatParts "${_fsPkgType}_PACKAGES_NOT_FOUND")
+ endforeach()
else()
set(allWhatParts)
foreach(part ${_FS_WHAT})
@@ -273,45 +377,49 @@ function(FEATURE_SUMMARY)
set(title_DISABLED_FEATURES "The following features have been disabled:")
set(title_PACKAGES_FOUND "The following packages have been found:")
set(title_PACKAGES_NOT_FOUND "The following packages have not been found:")
- set(title_OPTIONAL_PACKAGES_FOUND "The following OPTIONAL packages have been found:")
- set(title_OPTIONAL_PACKAGES_NOT_FOUND "The following OPTIONAL packages have not been found:")
- set(title_RECOMMENDED_PACKAGES_FOUND "The following RECOMMENDED packages have been found:")
- set(title_RECOMMENDED_PACKAGES_NOT_FOUND "The following RECOMMENDED packages have not been found:")
- set(title_REQUIRED_PACKAGES_FOUND "The following REQUIRED packages have been found:")
- set(title_REQUIRED_PACKAGES_NOT_FOUND "The following REQUIRED packages have not been found:")
- set(title_RUNTIME_PACKAGES_FOUND "The following RUNTIME packages have been found:")
- set(title_RUNTIME_PACKAGES_NOT_FOUND "The following RUNTIME packages have not been found:")
+ foreach(_fsPkgType ${_fsPkgTypes})
+ set(title_${_fsPkgType}_PACKAGES_FOUND "The following ${_fsPkgType} packages have been found:")
+ set(title_${_fsPkgType}_PACKAGES_NOT_FOUND "The following ${_fsPkgType} packages have not been found:")
+ endforeach()
set(_fullText "${_FS_DESCRIPTION}")
foreach(part ${allWhatParts})
set(_tmp)
_FS_GET_FEATURE_SUMMARY( ${part} _tmp ${_FS_INCLUDE_QUIET_PACKAGES})
if(_tmp)
- string(APPEND _fullText "\n-- ${title_${part}}\n${_tmp}\n")
- if("${part}" STREQUAL "REQUIRED_PACKAGES_NOT_FOUND")
- set(requiredPackagesNotFound TRUE)
+ if(_fullText)
+ string(APPEND _fullText "\n-- ")
endif()
+ string(APPEND _fullText "${title_${part}}\n${_tmp}\n")
+ foreach(_fsReqPkgType ${_fsReqPkgTypes})
+ if("${part}" STREQUAL "${_fsReqPkgType}_PACKAGES_NOT_FOUND")
+ set(requiredPackagesNotFound TRUE)
+ break()
+ endif()
+ endforeach()
endif()
endforeach()
endif()
- if(_FS_FILENAME)
- if(_FS_APPEND)
- file(APPEND "${_FS_FILENAME}" "${_fullText}")
+ if(_fullText OR NOT _FS_QUIET_ON_EMPTY)
+ if(_FS_FILENAME)
+ if(_FS_APPEND)
+ file(APPEND "${_FS_FILENAME}" "${_fullText}")
+ else()
+ file(WRITE "${_FS_FILENAME}" "${_fullText}")
+ endif()
+
else()
- file(WRITE "${_FS_FILENAME}" "${_fullText}")
+ if(NOT _FS_VAR)
+ message(STATUS "${_fullText}")
+ endif()
endif()
- else()
- if(NOT _FS_VAR)
- message(STATUS "${_fullText}")
+ if(_FS_VAR)
+ set(${_FS_VAR} "${_fullText}" PARENT_SCOPE)
endif()
endif()
- if(_FS_VAR)
- set(${_FS_VAR} "${_fullText}" PARENT_SCOPE)
- endif()
-
if(requiredPackagesNotFound AND _FS_FATAL_ON_MISSING_REQUIRED_PACKAGES)
message(FATAL_ERROR "feature_summary() Error: REQUIRED package(s) are missing, aborting CMake run.")
endif()
@@ -362,7 +470,8 @@ endfunction()
TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs are
ignored. The ``TYPE`` property is project-specific, so it cannot be set
by the Find-module, but must be set in the project.
-
+ Type accepted can be changed by setting the
+ :variable:`FeatureSummary_PKG_TYPES` global property.
``PURPOSE <purpose>``
This describes which features this package enables in the
@@ -435,25 +544,28 @@ function(SET_PACKAGE_PROPERTIES _name _props)
set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
endif()
- # handle the TYPE
- if(NOT _SPP_TYPE)
- set(_SPP_TYPE OPTIONAL)
- endif()
+ get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES)
+ get_property(_fsDefaultPkgType GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE)
- # List the supported types, according to their priority
- set(validTypes "RUNTIME" "OPTIONAL" "RECOMMENDED" "REQUIRED" )
- list(FIND validTypes ${_SPP_TYPE} _typeIndexInList)
- if("${_typeIndexInList}" STREQUAL "-1" )
- message(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
- "Valid types are OPTIONAL, RECOMMENDED, REQUIRED and RUNTIME." )
- endif()
+ # handle the TYPE
+ if(DEFINED _SPP_TYPE)
+ # Supported types are listed in FeatureSummary_PKG_TYPES according to their priority
+ get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES)
+ list(FIND _fsPkgTypes ${_SPP_TYPE} _typeIndexInList)
+ if("${_typeIndexInList}" STREQUAL "-1" )
+ string(REGEX REPLACE ";([^;]+)$" " and \\1" _fsPkgTypes_msg "${_fsPkgTypes}")
+ string(REPLACE ";" ", " _fsPkgTypes_msg "${_fsPkgTypes_msg}")
+ message(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
+ "Valid types are ${_fsPkgTypes_msg}." )
+ endif()
- get_property(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
- list(FIND validTypes "${_previousType}" _prevTypeIndexInList)
+ get_property(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
+ list(FIND _fsPkgTypes "${_previousType}" _prevTypeIndexInList)
- # make sure a previously set TYPE is not overridden with a lower new TYPE:
- if("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
+ # make sure a previously set TYPE is not overridden with a lower new TYPE:
+ if("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
+ endif()
endif()
endfunction()
@@ -466,7 +578,8 @@ endfunction()
add_feature_info(<name> <enabled> <description>)
Use this macro to add information about a feature with the given ``<name>``.
- ``<enabled>`` contains whether this feature is enabled or not.
+ ``<enabled>`` contains whether this feature is enabled or not. It can be a
+ variable or a list of conditions.
``<description>`` is a text describing the feature. The information can
be displayed using ``feature_summary()`` for ``ENABLED_FEATURES`` and
``DISABLED_FEATURES`` respectively.
@@ -478,7 +591,16 @@ endfunction()
option(WITH_FOO "Help for foo" ON)
add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
#]=======================================================================]
-function(ADD_FEATURE_INFO _name _enabled _desc)
+function(ADD_FEATURE_INFO _name _depends _desc)
+ set(_enabled 1)
+ foreach(_d ${_depends})
+ string(REGEX REPLACE " +" ";" _d "${_d}")
+ if(${_d})
+ else()
+ set(_enabled 0)
+ break()
+ endif()
+ endforeach()
if (${_enabled})
set_property(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
else ()
@@ -511,6 +633,7 @@ CMake versions:
can be set are added automatically by the ``find_package()`` command.
#]=======================================================================]
function(SET_PACKAGE_INFO _name _desc)
+ message(DEPRECATION "SET_PACKAGE_INFO is deprecated. Use SET_PACKAGE_PROPERTIES instead.")
unset(_url)
unset(_purpose)
if(ARGC GREATER 2)
@@ -540,6 +663,7 @@ endfunction()
set_package_info(<name> <description> <url>)
#]=======================================================================]
function(SET_FEATURE_INFO)
+ message(DEPRECATION "SET_FEATURE_INFO is deprecated. Use ADD_FEATURE_INFO instead.")
SET_PACKAGE_INFO(${ARGN})
endfunction()
@@ -557,6 +681,8 @@ endfunction()
feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
#]=======================================================================]
function(PRINT_ENABLED_FEATURES)
+ message(DEPRECATION "PRINT_ENABLED_FEATURES is deprecated. Use
+ feature_summary(WHAT ENABLED_FEATURES DESCRIPTION \"Enabled features:\")")
FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
endfunction()
@@ -574,5 +700,7 @@ endfunction()
feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
#]=======================================================================]
function(PRINT_DISABLED_FEATURES)
+ message(DEPRECATION "PRINT_DISABLED_FEATURES is deprecated. Use
+ feature_summary(WHAT DISABLED_FEATURES DESCRIPTION \"Disabled features:\")")
FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
endfunction()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 93f128f..8621bdf 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 7)
-set(CMake_VERSION_PATCH 20170126)
+set(CMake_VERSION_PATCH 20170131)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 398f95b..66202df 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -162,6 +162,27 @@ static const struct BoolNode : public cmGeneratorExpressionNode
}
} boolNode;
+static const struct IfNode : public cmGeneratorExpressionNode
+{
+ IfNode() {}
+
+ int NumExpectedParameters() const CM_OVERRIDE { return 3; }
+
+ std::string Evaluate(const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker*) const CM_OVERRIDE
+ {
+ if (parameters[0] != "1" && parameters[0] != "0") {
+ reportError(context, content->GetOriginalExpression(),
+ "First parameter to $<IF> must resolve to exactly one '0' "
+ "or '1' value.");
+ return std::string();
+ }
+ return parameters[0] == "1" ? parameters[1] : parameters[2];
+ }
+} ifNode;
+
static const struct StrEqualNode : public cmGeneratorExpressionNode
{
StrEqualNode() {}
@@ -1757,6 +1778,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["UPPER_CASE"] = &upperCaseNode;
nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode;
nodeMap["BOOL"] = &boolNode;
+ nodeMap["IF"] = &ifNode;
nodeMap["ANGLE-R"] = &angle_rNode;
nodeMap["COMMA"] = &commaNode;
nodeMap["SEMICOLON"] = &semicolonNode;
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 4a97114..3d42e26 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -5,6 +5,7 @@
#include <cmConfigure.h>
#include <cstring>
#include <sstream>
+#include <stdlib.h>
#include "cmSystemTools.h"
@@ -12,6 +13,16 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString,
bool utcFlag)
{
time_t currentTimeT = time(CM_NULLPTR);
+ std::string source_date_epoch;
+ cmSystemTools::GetEnv("SOURCE_DATE_EPOCH", source_date_epoch);
+ if (!source_date_epoch.empty()) {
+ std::istringstream iss(source_date_epoch);
+ iss >> currentTimeT;
+ if (iss.fail() || !iss.eof()) {
+ cmSystemTools::Error("Cannot parse SOURCE_DATE_EPOCH as integer");
+ exit(27);
+ }
+ }
if (currentTimeT == time_t(-1)) {
return std::string();
}
@@ -125,6 +136,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
case 'w':
case 'y':
case 'Y':
+ case '%':
break;
case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
{
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index f0d6abf..adc87cd 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -145,13 +145,13 @@ add_library(imported1 SHARED IMPORTED)
set_property(TARGET imported1 PROPERTY IMPORTED_LOCATION_RELEASE release_loc)
set_property(TARGET imported1 PROPERTY IMPORTED_LOCATION_DEBUG debug_loc)
set_property(TARGET imported1 PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
-set_property(TARGET imported1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES /imported1/include)
+set_property(TARGET imported1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/imported1/include/with space")
add_library(imported2 SHARED IMPORTED)
set_property(TARGET imported2 PROPERTY IMPORTED_LOCATION_RELEASE release_loc)
set_property(TARGET imported2 PROPERTY IMPORTED_LOCATION_DEBUG debug_loc)
set_property(TARGET imported2 PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
-set_property(TARGET imported2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES /imported2/include)
+set_property(TARGET imported2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/imported2/include/with space")
add_library(imported3 SHARED IMPORTED)
set_property(TARGET imported3 PROPERTY IMPORTED_LOCATION_RELEASE release_loc)
@@ -161,6 +161,10 @@ set_property(TARGET imported3 APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:DEBUG>:$<TARGET_PROPERTY:imported1,INTERFACE_INCLUDE_DIRECTORIES>>)
set_property(TARGET imported3 APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELEASE>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
+set_property(TARGET imported3 APPEND PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELWITHDEBINFO>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
+set_property(TARGET imported3 APPEND PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:MINSIZEREL>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
add_library(imported4 SHARED IMPORTED)
set_property(TARGET imported4 APPEND PROPERTY
@@ -187,10 +191,7 @@ add_custom_target(check-part3 ALL
-Dtest_version_equal_1=$<VERSION_EQUAL:1.0.1,1.1>
-Dtest_version_equal_2=$<VERSION_EQUAL:1.1,1.1>
-Dconfig=$<CONFIGURATION>
- -Dtest_imported_debug=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
- -Dtest_imported_release=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
- -Dtest_imported_relwithdebinfo=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
- -Dtest_imported_minsizerel=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
+ -Dtest_imported_includes=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
-Dtest_imported_fallback=$<STREQUAL:$<TARGET_FILE_NAME:importedFallback>,fallback_loc>
-Dtest_alias_file_exe=$<STREQUAL:$<TARGET_FILE:Alias::SomeExe>,$<TARGET_FILE:someexe>>
-Dtest_alias_file_lib=$<STREQUAL:$<TARGET_FILE:Alias::SomeLib>,$<TARGET_FILE:empty1>>
@@ -246,6 +247,10 @@ add_custom_target(check-part4 ALL
# CMake as command-line argument
-Dtest_shell_path=${path_prefix}$<SHELL_PATH:${test_shell_path}>
-Dpath_prefix=${path_prefix}
+ -Dif_1=$<IF:1,a,b>
+ -Dif_2=$<IF:0,a,b>
+ -Dif_3=$<IF:$<EQUAL:10,30>,a,b>
+ -Dif_4=$<IF:$<EQUAL:30,30>,a,b>
-DWIN32=${WIN32}
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part4.cmake
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index e12d8c6..9014406 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -8,18 +8,15 @@ check(test_version_less_2 "1")
check(test_version_equal_1 "0")
check(test_version_equal_2 "1")
-foreach(c debug release relwithdebinfo minsizerel)
- if(config AND NOT config STREQUAL NoConfig)
- if(NOT "${test_imported_${c}}" MATCHES "^;/imported2/include$"
- AND NOT "${test_imported_${c}}" MATCHES "^/imported1/include;$")
- message(SEND_ERROR "test_imported_${c} is not correct: ${test_imported_${c}}")
- endif()
- else()
- if(NOT "${test_imported_${c}}" MATCHES "^;$")
- message(SEND_ERROR "test_imported_${c} is not an empty list: ${test_imported_${c}}")
- endif()
+if(config AND NOT config STREQUAL NoConfig)
+ if(NOT "${test_imported_includes}" MATCHES "^;*/imported[12]/include/with space;*$")
+ message(SEND_ERROR "test_imported_includes is not correct: ${test_imported_includes}")
endif()
-endforeach()
+else()
+ if(NOT "${test_imported_includes}" MATCHES "^;;;$")
+ message(SEND_ERROR "test_imported_includes is not an empty list: ${test_imported_includes}")
+ endif()
+endif()
check(test_imported_fallback "1")
diff --git a/Tests/GeneratorExpression/check-part4.cmake b/Tests/GeneratorExpression/check-part4.cmake
index 9e516d5..f5d14dd 100644
--- a/Tests/GeneratorExpression/check-part4.cmake
+++ b/Tests/GeneratorExpression/check-part4.cmake
@@ -13,3 +13,8 @@ if(WIN32)
else()
check(test_shell_path [[/shell/path]])
endif()
+
+check(if_1 "a")
+check(if_2 "b")
+check(if_3 "b")
+check(if_4 "a")
diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt
index 15f0338..807a427 100644
--- a/Tests/Preprocess/CMakeLists.txt
+++ b/Tests/Preprocess/CMakeLists.txt
@@ -214,18 +214,24 @@ set(FILE_PATH "${Preprocess_SOURCE_DIR}/file_def.h")
set(TARGET_PATH "${Preprocess_SOURCE_DIR}/target_def.h")
# Set some definition properties.
-foreach(c "" "_DEBUG" "_RELEASE")
+foreach(c "" "_DEBUG" "_RELEASE" "_RELWITHDEBINFO" "_MINSIZEREL")
+ set(FLAVOR "${c}")
+ # Treat RelWithDebInfo and MinSizeRel as Release to avoid having
+ # an exponentional matrix of inclusions and exclusions of defines
+ if("${c}" STREQUAL "_RELWITHDEBINFO" OR "${c}" STREQUAL "_MINSIZEREL")
+ set(FLAVOR "_RELEASE")
+ endif()
set_property(
DIRECTORY .
- APPEND PROPERTY COMPILE_DEFINITIONS${c} "DIRECTORY_DEF${c}"
+ APPEND PROPERTY COMPILE_DEFINITIONS${c} "DIRECTORY_DEF${FLAVOR}"
)
set_property(
TARGET Preprocess
- PROPERTY COMPILE_DEFINITIONS${c} "TARGET_DEF${c}"
+ PROPERTY COMPILE_DEFINITIONS${c} "TARGET_DEF${FLAVOR}"
)
set_property(
SOURCE preprocess.c preprocess.cxx
- PROPERTY COMPILE_DEFINITIONS${c} "FILE_DEF${c}"
+ PROPERTY COMPILE_DEFINITIONS${c} "FILE_DEF${FLAVOR}"
)
endforeach()
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-stderr.txt
new file mode 100644
index 0000000..58f6125
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ Bad package property type OPTIONAL used in global property
+ FeatureSummary_DEFAULT_PKG_TYPE. Valid types are TYPE1, TYPE2 and TYPE3.
+ Either update FeatureSummary_DEFAULT_PKG_TYPE or add OPTIONAL to the
+ FeatureSummary_PKG_TYPES global property.
+Call Stack \(most recent call first\):
+ .*/Modules/FeatureSummary\.cmake:[0-9]+. \(_FS_GET_FEATURE_SUMMARY\)
+ FeatureSummaryCustomBadDefault.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault.cmake
new file mode 100644
index 0000000..7e2fd55
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomBadDefault.cmake
@@ -0,0 +1,8 @@
+include(FeatureSummary)
+set_property(GLOBAL PROPERTY FeatureSummary_PKG_TYPES TYPE1 TYPE2 TYPE3)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Foo)
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stderr.txt
new file mode 100644
index 0000000..e37b9f5
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ feature_summary\(\) Error: REQUIRED package\(s\) are missing, aborting CMake
+ run.
+Call Stack \(most recent call first\):
+ FeatureSummaryCustomRequired.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stdout.txt
new file mode 100644
index 0000000..ecca71f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired-stdout.txt
@@ -0,0 +1,17 @@
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE2 packages have not been found:
+
+ \* Bar
+
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE3 packages have not been found:
+
+ \* Bar
+
+-- Configuring incomplete, errors occurred!
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired.cmake
new file mode 100644
index 0000000..11cf04c
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequired.cmake
@@ -0,0 +1,16 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+set_property(GLOBAL PROPERTY FeatureSummary_PKG_TYPES TYPE1 TYPE2 TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE TYPE2)
+
+find_package(Foo)
+find_package(Bar)
+
+set_package_properties(Foo PROPERTIES TYPE TYPE3)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+set_package_properties(Bar PROPERTIES TYPE TYPE3)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stderr.txt
new file mode 100644
index 0000000..c9d8b4b
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ feature_summary\(\) Error: REQUIRED package\(s\) are missing, aborting CMake
+ run.
+Call Stack \(most recent call first\):
+ FeatureSummaryCustomRequiredListA.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stdout.txt
new file mode 100644
index 0000000..b12d53a
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA-stdout.txt
@@ -0,0 +1,17 @@
+-- The following TYPE2 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE1 packages have not been found:
+
+ \* Bar
+
+-- The following TYPE2 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE2 packages have not been found:
+
+ \* Bar
+
+-- Configuring incomplete, errors occurred!
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA.cmake
new file mode 100644
index 0000000..53111be
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListA.cmake
@@ -0,0 +1,16 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+set_property(GLOBAL PROPERTY FeatureSummary_PKG_TYPES TYPE1 TYPE2 TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES TYPE2 TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE TYPE1)
+
+find_package(Foo)
+find_package(Bar)
+
+set_package_properties(Foo PROPERTIES TYPE TYPE2)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+set_package_properties(Bar PROPERTIES TYPE TYPE2)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stderr.txt
new file mode 100644
index 0000000..8ef7a8d
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ feature_summary\(\) Error: REQUIRED package\(s\) are missing, aborting CMake
+ run.
+Call Stack \(most recent call first\):
+ FeatureSummaryCustomRequiredListB.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stdout.txt
new file mode 100644
index 0000000..5f07173
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB-stdout.txt
@@ -0,0 +1,17 @@
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE1 packages have not been found:
+
+ \* Bar
+
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE3 packages have not been found:
+
+ \* Bar
+
+-- Configuring incomplete, errors occurred!
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB.cmake
new file mode 100644
index 0000000..526b979
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomRequiredListB.cmake
@@ -0,0 +1,16 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+set_property(GLOBAL PROPERTY FeatureSummary_PKG_TYPES TYPE1 TYPE2 TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES TYPE2 TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE TYPE1)
+
+find_package(Foo)
+find_package(Bar)
+
+set_package_properties(Foo PROPERTIES TYPE TYPE3)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+set_package_properties(Bar PROPERTIES TYPE TYPE3)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes-stdout.txt
new file mode 100644
index 0000000..a7f973b
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes-stdout.txt
@@ -0,0 +1,29 @@
+-- The following TYPE2 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE1 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE2 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE2 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following TYPE3 packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- Configuring done
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes.cmake
new file mode 100644
index 0000000..34b0c1f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryCustomTypes.cmake
@@ -0,0 +1,36 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+set_property(GLOBAL PROPERTY FeatureSummary_PKG_TYPES TYPE1 TYPE2 TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_REQUIRED_PKG_TYPES TYPE3)
+set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE TYPE2)
+
+find_package(Foo)
+
+# Type not set => TYPE2
+feature_summary(WHAT ALL)
+
+# TYPE1 > not set => TYPE1
+set_package_properties(Foo PROPERTIES TYPE TYPE1)
+feature_summary(WHAT ALL)
+
+# TYPE2 > TYPE1 => TYPE2
+set_package_properties(Foo PROPERTIES TYPE TYPE2)
+feature_summary(WHAT ALL)
+
+# TYPE1 < TYPE2 => TYPE2
+set_package_properties(Foo PROPERTIES TYPE TYPE2)
+feature_summary(WHAT ALL)
+
+# TYPE3 > TYPE2 => TYPE3
+set_package_properties(Foo PROPERTIES TYPE TYPE3)
+feature_summary(WHAT ALL)
+
+# TYPE2 < TYPE3 => TYPE3
+set_package_properties(Foo PROPERTIES TYPE TYPE2)
+feature_summary(WHAT ALL)
+
+# TYPE1 < TYPE3 => TYPE3
+set_package_properties(Foo PROPERTIES TYPE TYPE1)
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stderr.txt
new file mode 100644
index 0000000..214d74a
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ feature_summary\(\) Error: REQUIRED package\(s\) are missing, aborting CMake
+ run.
+Call Stack \(most recent call first\):
+ FeatureSummaryFatalOnMissingRequiredPackages.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stdout.txt
new file mode 100644
index 0000000..6bd6427
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages-stdout.txt
@@ -0,0 +1,17 @@
+-- The following REQUIRED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have not been found:
+
+ \* Bar
+
+-- The following REQUIRED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following REQUIRED packages have not been found:
+
+ \* Bar
+
+-- Configuring incomplete, errors occurred!
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages.cmake
new file mode 100644
index 0000000..9563186
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryFatalOnMissingRequiredPackages.cmake
@@ -0,0 +1,12 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Foo)
+find_package(Bar)
+
+set_package_properties(Foo PROPERTIES TYPE REQUIRED)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+set_package_properties(Bar PROPERTIES TYPE REQUIRED)
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages-stdout.txt
new file mode 100644
index 0000000..58599e0
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages-stdout.txt
@@ -0,0 +1,14 @@
+-- The following OPTIONAL packages have not been found:
+
+ \* Baz
+
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have not been found:
+
+ \* Bar
+ \* Baz
+
+-- Configuring done
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages.cmake
new file mode 100644
index 0000000..5cdb443
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryIncludeQuietPackages.cmake
@@ -0,0 +1,11 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Foo QUIET)
+find_package(Bar QUIET)
+find_package(Baz)
+
+feature_summary(WHAT ALL)
+
+feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends-stdout.txt
new file mode 100644
index 0000000..d5875e0
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends-stdout.txt
@@ -0,0 +1,10 @@
+-- The following features have been enabled:
+
+ \* Bar, Bar\.
+ \* Baz, Baz\.
+ \* Goo, Goo\.
+
+-- The following features have been disabled:
+
+ \* Foo, Foo\.
+ \* Fez, Fez\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends.cmake
new file mode 100644
index 0000000..f355ae7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryMultipleDepends.cmake
@@ -0,0 +1,12 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo "WITH_FOO;WITH_BAR" "Foo.")
+add_feature_info(Bar "WITH_FOO;NOT WITH_BAR" "Bar.")
+add_feature_info(Baz "WITH_FOO AND NOT WITH_BAR" "Baz.")
+add_feature_info(Goo "WITH_FOO OR WITH_BAR" "Goo.")
+add_feature_info(Fez "NOT WITH_FOO OR WITH_BAR" "Fez.")
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose-stdout.txt
new file mode 100644
index 0000000..78e4fe1
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose-stdout.txt
@@ -0,0 +1,16 @@
+The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+ Because everyone needs some Foo.
+
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+ Because everyone needs some Foo.
+ Because Foo is better than Bar.
+
+-- Configuring done
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose.cmake
new file mode 100644
index 0000000..64735b6
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryPurpose.cmake
@@ -0,0 +1,16 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Foo)
+
+# Purpose not set
+feature_summary(WHAT ALL)
+
+# Purpose set once
+set_package_properties(Foo PROPERTIES PURPOSE "Because everyone needs some Foo.")
+feature_summary(WHAT ALL)
+
+# Purpose set twice
+set_package_properties(Foo PROPERTIES PURPOSE "Because Foo is better than Bar.")
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty-stdout.txt
new file mode 100644
index 0000000..65e97e0
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty-stdout.txt
@@ -0,0 +1,5 @@
+-- Enabled features:
+ \* Foo, Foo\.
+ \* Bar, Bar\.
+
+-- Configuring done
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty.cmake
new file mode 100644
index 0000000..8d1d007
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryQuietOnEmpty.cmake
@@ -0,0 +1,14 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 1)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT ENABLED_FEATURES
+ DESCRIPTION "Enabled features:"
+ QUIET_ON_EMPTY)
+feature_summary(WHAT DISABLED_FEATURES
+ DESCRIPTION "Disabled features:"
+ QUIET_ON_EMPTY)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryTypes-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryTypes-stdout.txt
new file mode 100644
index 0000000..79bb1e3
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryTypes-stdout.txt
@@ -0,0 +1,45 @@
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following RUNTIME packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following RECOMMENDED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following RECOMMENDED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following RECOMMENDED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following REQUIRED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following REQUIRED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following REQUIRED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following REQUIRED packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- Configuring done
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryTypes.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryTypes.cmake
new file mode 100644
index 0000000..09d1e7a
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryTypes.cmake
@@ -0,0 +1,48 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Foo)
+
+# Type not set => OPTIONAL
+feature_summary(WHAT ALL)
+
+# RUNTIME > not set => RUNTIME
+set_package_properties(Foo PROPERTIES TYPE RUNTIME)
+feature_summary(WHAT ALL)
+
+# OPTIONAL > RUNTIME => OPTIONAL
+set_package_properties(Foo PROPERTIES TYPE OPTIONAL)
+feature_summary(WHAT ALL)
+
+# RUNTIME < OPTIONAL => OPTIONAL
+set_package_properties(Foo PROPERTIES TYPE OPTIONAL)
+feature_summary(WHAT ALL)
+
+# RECOMMENDED > OPTIONAL => RECOMMENDED
+set_package_properties(Foo PROPERTIES TYPE RECOMMENDED)
+feature_summary(WHAT ALL)
+
+# OPTIONAL < RECOMMENDED => RECOMMENDED
+set_package_properties(Foo PROPERTIES TYPE OPTIONAL)
+feature_summary(WHAT ALL)
+
+# RUNTIME < RECOMMENDED => RECOMMENDED
+set_package_properties(Foo PROPERTIES TYPE RUNTIME)
+feature_summary(WHAT ALL)
+
+# REQUIRED > RECOMMENDED => REQUIRED
+set_package_properties(Foo PROPERTIES TYPE REQUIRED)
+feature_summary(WHAT ALL)
+
+# RECOMMENDED < REQUIRED => REQUIRED
+set_package_properties(Foo PROPERTIES TYPE RECOMMENDED)
+feature_summary(WHAT ALL)
+
+# OPTIONAL < REQUIRED => REQUIRED
+set_package_properties(Foo PROPERTIES TYPE OPTIONAL)
+feature_summary(WHAT ALL)
+
+# RUNTIME < REQUIRED => REQUIRED
+set_package_properties(Foo PROPERTIES TYPE RUNTIME)
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription-stdout.txt
new file mode 100644
index 0000000..6a55bdf
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription-stdout.txt
@@ -0,0 +1,32 @@
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have not been found:
+
+ \* Bar
+ \* Baz
+
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, The Foo package, <https://foo.example/>
+
+-- The following OPTIONAL packages have not been found:
+
+ \* Bar, <https://bar.net/>
+ \* Baz, A Baz package
+
+-- Warning: Property DESCRIPTION for package Foo already set to "The Foo package", overriding it with "A Foo package"
+-- Warning: Property URL already set to "https://foo.example/", overriding it with "https://foo.net/"
+-- Warning: Property URL already set to "https://bar.net/", overriding it with "https://bar.example/"
+-- Warning: Property DESCRIPTION for package Baz already set to "A Baz package", overriding it with "The Baz package"
+-- The following OPTIONAL packages have been found:
+
+ \* Foo, A Foo package, <https://foo.net/>
+
+-- The following OPTIONAL packages have not been found:
+
+ \* Bar, The Bar package, <https://bar.example/>
+ \* Baz, The Baz package, <https://baz.example/>
+
+-- Configuring done
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription.cmake
new file mode 100644
index 0000000..77fcf28
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryURLDescription.cmake
@@ -0,0 +1,28 @@
+include(FeatureSummary)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Foo) # URL and DESCRIPTION are set in the FindFoo.cmake file
+find_package(Bar) # URL and DESCRIPTION are not set
+find_package(Baz) # URL and DESCRIPTION are not set
+
+feature_summary(WHAT ALL)
+
+set_package_properties(Bar PROPERTIES URL "https://bar.net/") # URL and no DESCRIPTION
+set_package_properties(Baz PROPERTIES DESCRIPTION "A Baz package") # DESCRIPTION and no URL
+feature_summary(WHAT ALL)
+
+# Overwrite with the same value (no warning)
+set_package_properties(Foo PROPERTIES URL "https://foo.example/"
+ DESCRIPTION "The Foo package")
+set_package_properties(Bar PROPERTIES URL "https://bar.net/")
+set_package_properties(Baz PROPERTIES DESCRIPTION "A Baz package")
+
+# Overwrite with different values (warnings)
+set_package_properties(Foo PROPERTIES URL "https://foo.net/"
+ DESCRIPTION "A Foo package") # Overwrite URL and DESCRIPTION
+set_package_properties(Bar PROPERTIES URL "https://bar.example/"
+ DESCRIPTION "The Bar package") # Overwrite URL and add DESCRIPTION
+set_package_properties(Baz PROPERTIES URL "https://baz.example/"
+ DESCRIPTION "The Baz package") # Overwrite URL and add DESCRIPTION
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt
index 9a3f023..f0631ae 100644
--- a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt
@@ -1,7 +1,7 @@
-- The following features have been enabled:
- \* Foo , Foo\.
+ \* Foo, Foo\.
-- The following features have been disabled:
- \* Bar , Bar\.
+ \* Bar, Bar\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt
index 4d8f25f..f121417 100644
--- a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt
@@ -1,7 +1,7 @@
-- The following features have been disabled:
- \* Bar , Bar\.
+ \* Bar, Bar\.
-- The following features have been enabled:
- \* Foo , Foo\.
+ \* Foo, Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt
index 39be105..8b4cd43 100644
--- a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt
@@ -1,4 +1,4 @@
--( )
- \* Foo , Foo decscription\.
+ \* Foo, Foo description\.
+
--
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake
index 545fb92..eaea40e 100644
--- a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake
@@ -2,7 +2,7 @@ include(FeatureSummary)
set(WITH_FOO 1)
-add_feature_info(Foo WITH_FOO "Foo decscription.")
-add_feature_info(Foo WITH_FOO "Foo decscription.")
+add_feature_info(Foo WITH_FOO "Foo description.")
+add_feature_info(Foo WITH_FOO "Foo description.")
feature_summary(WHAT ENABLED_FEATURES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt
index 240632d..7485df9 100644
--- a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt
@@ -1 +1 @@
- \* Foo , Foo\.
+ \* Foo, Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FindBar.cmake b/Tests/RunCMake/FeatureSummary/FindBar.cmake
new file mode 100644
index 0000000..45f4d54
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FindBar.cmake
@@ -0,0 +1,2 @@
+include(FeatureSummary)
+set(Bar_FOUND 0)
diff --git a/Tests/RunCMake/FeatureSummary/FindBaz.cmake b/Tests/RunCMake/FeatureSummary/FindBaz.cmake
new file mode 100644
index 0000000..73aafcd
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FindBaz.cmake
@@ -0,0 +1,2 @@
+include(FeatureSummary)
+set(Baz_FOUND 0)
diff --git a/Tests/RunCMake/FeatureSummary/FindFoo.cmake b/Tests/RunCMake/FeatureSummary/FindFoo.cmake
new file mode 100644
index 0000000..baec987
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FindFoo.cmake
@@ -0,0 +1,4 @@
+include(FeatureSummary)
+set_package_properties(Foo PROPERTIES URL "https://foo.example/"
+ DESCRIPTION "The Foo package")
+set(Foo_FOUND 1)
diff --git a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
index 6a5fc28..9caee4c 100644
--- a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
@@ -7,3 +7,15 @@ run_cmake(FeatureSummaryWhatList)
run_cmake(FeatureSummaryWhatListUnknown)
run_cmake(FeatureSummaryWhatListAll)
run_cmake(FeatureSummaryWhatOnce)
+run_cmake(FeatureSummaryPurpose)
+run_cmake(FeatureSummaryURLDescription)
+run_cmake(FeatureSummaryTypes)
+run_cmake(FeatureSummaryFatalOnMissingRequiredPackages)
+run_cmake(FeatureSummaryIncludeQuietPackages)
+run_cmake(FeatureSummaryQuietOnEmpty)
+run_cmake(FeatureSummaryMultipleDepends)
+run_cmake(FeatureSummaryCustomTypes)
+run_cmake(FeatureSummaryCustomBadDefault)
+run_cmake(FeatureSummaryCustomRequired)
+run_cmake(FeatureSummaryCustomRequiredListA)
+run_cmake(FeatureSummaryCustomRequiredListB)
diff --git a/Tests/RunCMake/GeneratorExpression/BadIF-result.txt b/Tests/RunCMake/GeneratorExpression/BadIF-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadIF-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadIF-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadIF-stderr.txt
new file mode 100644
index 0000000..7c7506c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadIF-stderr.txt
@@ -0,0 +1,15 @@
+CMake Error at BadIF.cmake:2 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<IF:asdf,a,b>
+
+ First parameter to \$<IF> must resolve to exactly one '0' or '1' value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadIF.cmake:2 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<IF:asdf,a>
+
+ \$<IF> expression requires 3 comma separated parameters, but got 2 instead.
diff --git a/Tests/RunCMake/GeneratorExpression/BadIF.cmake b/Tests/RunCMake/GeneratorExpression/BadIF.cmake
new file mode 100644
index 0000000..583f68d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadIF.cmake
@@ -0,0 +1,5 @@
+
+add_custom_target(check ALL COMMAND check
+ $<IF:asdf,a,b>
+ $<IF:asdf,a>
+ )
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index f5584d5..084b5c3 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -1,5 +1,6 @@
include(RunCMake)
+run_cmake(BadIF)
run_cmake(BadCONFIG)
run_cmake(BadOR)
run_cmake(BadAND)
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake
index 8067d9d..38a77b0 100644
--- a/Tests/RunCMake/string/RunCMakeTest.cmake
+++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -6,6 +6,11 @@ run_cmake(AppendNoArgs)
run_cmake(Concat)
run_cmake(ConcatNoArgs)
+run_cmake(Timestamp)
+run_cmake(TimestampEmpty)
+run_cmake(TimestampInvalid)
+run_cmake(TimestampInvalid2)
+
run_cmake(Uuid)
run_cmake(UuidMissingNamespace)
run_cmake(UuidMissingNamespaceValue)
diff --git a/Tests/RunCMake/string/Timestamp-result.txt b/Tests/RunCMake/string/Timestamp-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/string/Timestamp-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/string/Timestamp-stderr.txt b/Tests/RunCMake/string/Timestamp-stderr.txt
new file mode 100644
index 0000000..653974c
--- /dev/null
+++ b/Tests/RunCMake/string/Timestamp-stderr.txt
@@ -0,0 +1 @@
+RESULT=2005-08-07 23:19:49 Sun Aug 05 day=219 wd=0 week=32 %I=11 epoch=1123456789
diff --git a/Tests/RunCMake/string/Timestamp.cmake b/Tests/RunCMake/string/Timestamp.cmake
new file mode 100644
index 0000000..d242039
--- /dev/null
+++ b/Tests/RunCMake/string/Timestamp.cmake
@@ -0,0 +1,3 @@
+set(ENV{SOURCE_DATE_EPOCH} "1123456789")
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %a %b %y day=%j wd=%w week=%U %%I=%I epoch=%s" UTC)
+message("RESULT=${RESULT}")
diff --git a/Tests/RunCMake/string/TimestampEmpty-result.txt b/Tests/RunCMake/string/TimestampEmpty-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampEmpty-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/string/TimestampEmpty-stderr.txt b/Tests/RunCMake/string/TimestampEmpty-stderr.txt
new file mode 100644
index 0000000..35cbd3c
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampEmpty-stderr.txt
@@ -0,0 +1 @@
+RESULT=2
diff --git a/Tests/RunCMake/string/TimestampEmpty.cmake b/Tests/RunCMake/string/TimestampEmpty.cmake
new file mode 100644
index 0000000..21b770f
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampEmpty.cmake
@@ -0,0 +1,3 @@
+set(ENV{SOURCE_DATE_EPOCH} "")
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S" UTC)
+message("RESULT=${RESULT}")
diff --git a/Tests/RunCMake/string/TimestampInvalid-result.txt b/Tests/RunCMake/string/TimestampInvalid-result.txt
new file mode 100644
index 0000000..f64f5d8
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampInvalid-result.txt
@@ -0,0 +1 @@
+27
diff --git a/Tests/RunCMake/string/TimestampInvalid-stderr.txt b/Tests/RunCMake/string/TimestampInvalid-stderr.txt
new file mode 100644
index 0000000..75566da
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampInvalid-stderr.txt
@@ -0,0 +1 @@
+CMake Error: Cannot parse SOURCE_DATE_EPOCH as integer
diff --git a/Tests/RunCMake/string/TimestampInvalid.cmake b/Tests/RunCMake/string/TimestampInvalid.cmake
new file mode 100644
index 0000000..ab36270
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampInvalid.cmake
@@ -0,0 +1,3 @@
+set(ENV{SOURCE_DATE_EPOCH} "invalid-integer")
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S" UTC)
+message("RESULT=${RESULT}")
diff --git a/Tests/RunCMake/string/TimestampInvalid2-result.txt b/Tests/RunCMake/string/TimestampInvalid2-result.txt
new file mode 100644
index 0000000..f64f5d8
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampInvalid2-result.txt
@@ -0,0 +1 @@
+27
diff --git a/Tests/RunCMake/string/TimestampInvalid2-stderr.txt b/Tests/RunCMake/string/TimestampInvalid2-stderr.txt
new file mode 100644
index 0000000..75566da
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampInvalid2-stderr.txt
@@ -0,0 +1 @@
+CMake Error: Cannot parse SOURCE_DATE_EPOCH as integer
diff --git a/Tests/RunCMake/string/TimestampInvalid2.cmake b/Tests/RunCMake/string/TimestampInvalid2.cmake
new file mode 100644
index 0000000..5cc61b8
--- /dev/null
+++ b/Tests/RunCMake/string/TimestampInvalid2.cmake
@@ -0,0 +1,3 @@
+set(ENV{SOURCE_DATE_EPOCH} "123trailing-garbage")
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S" UTC)
+message("RESULT=${RESULT}")
diff --git a/Utilities/.gitattributes b/Utilities/.gitattributes
index e3a9e61..c6345eb 100644
--- a/Utilities/.gitattributes
+++ b/Utilities/.gitattributes
@@ -1,2 +1,3 @@
/Git export-ignore
+/GitSetup export-ignore
SetupForDevelopment.sh export-ignore
diff --git a/Utilities/GitSetup/.gitattributes b/Utilities/GitSetup/.gitattributes
index facbbb2..e96d1f8 100644
--- a/Utilities/GitSetup/.gitattributes
+++ b/Utilities/GitSetup/.gitattributes
@@ -1,7 +1,6 @@
.git* export-ignore
-# Exclude from source archives files specific to Git work tree.
-* export-ignore
-
+config* eol=lf whitespace=indent-with-non-tab
+git-* eol=lf whitespace=indent-with-non-tab
tips eol=lf whitespace=indent-with-non-tab
setup-* eol=lf whitespace=indent-with-non-tab
diff --git a/Utilities/GitSetup/README b/Utilities/GitSetup/README
index cf468fb..2f9f1ec 100644
--- a/Utilities/GitSetup/README
+++ b/Utilities/GitSetup/README
@@ -37,6 +37,13 @@ Commit the merge with an informative message:
the general GitSetup repository "setup" branch.
------------------------------------------------------------------------
+Optionally add to the project ".gitattributes" file the line
+
+ /Utilities/GitSetup export-ignore
+
+to exclude the GitSetup directory from inclusion by "git archive"
+since it does not make sense in source tarballs.
+
Configuration
-------------
diff --git a/Utilities/GitSetup/config.sample b/Utilities/GitSetup/config.sample
index bba2382..eeb468b 100644
--- a/Utilities/GitSetup/config.sample
+++ b/Utilities/GitSetup/config.sample
@@ -20,3 +20,13 @@
site = http://review.source.kitware.com
# pushurl placeholder "$username" is literal
pushurl = $username@review.source.kitware.com:Project
+
+[upstream]
+ url = git://public.kitware.com/Project.git
+
+[gitlab]
+ host = gitlab.kitware.com
+ group-path = group
+ group-name = Group
+ project-path = project
+ project-name = Project
diff --git a/Utilities/GitSetup/git-gerrit-push b/Utilities/GitSetup/git-gerrit-push
new file mode 100755
index 0000000..b46f753
--- /dev/null
+++ b/Utilities/GitSetup/git-gerrit-push
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+USAGE="[<remote>] [--no-topic] [--dry-run] [--]"
+OPTIONS_SPEC=
+SUBDIRECTORY_OK=Yes
+. "$(git --exec-path)/git-sh-setup"
+
+#-----------------------------------------------------------------------------
+
+remote=''
+refspecs=''
+no_topic=''
+dry_run=''
+
+# Parse the command line options.
+while test $# != 0; do
+ case "$1" in
+ --no-topic) no_topic=1 ;;
+ --dry-run) dry_run=--dry-run ;;
+ --) shift; break ;;
+ -*) usage ;;
+ *) test -z "$remote" || usage ; remote="$1" ;;
+ esac
+ shift
+done
+test $# = 0 || usage
+
+# Default remote.
+test -n "$remote" || remote="gerrit"
+
+if test -z "$no_topic"; then
+ # Identify and validate the topic branch name.
+ head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic=''
+ if test -z "$topic" -o "$topic" = "master"; then
+ die 'Please name your topic:
+ git checkout -b descriptive-name'
+ fi
+ # The topic branch will be pushed by name.
+ refspecs="HEAD:refs/for/master/$topic $refspecs"
+fi
+
+# Fetch the current upstream master branch head.
+# This helps computation of a minimal pack to push.
+echo "Fetching $remote master"
+fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out"
+
+# Exit early if we have nothing to push.
+if test -z "$refspecs"; then
+ echo 'Nothing to push!'
+ exit 0
+fi
+
+# Push. Save output and exit code.
+echo "Pushing to $remote"
+push_stdout=$(git push --porcelain $dry_run "$remote" $refspecs); push_exit=$?
+echo "$push_stdout"
+
+# Reproduce the push exit code.
+exit $push_exit
diff --git a/Utilities/GitSetup/git-gitlab-push b/Utilities/GitSetup/git-gitlab-push
new file mode 100755
index 0000000..768f853
--- /dev/null
+++ b/Utilities/GitSetup/git-gitlab-push
@@ -0,0 +1,177 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+USAGE='[<remote>] [<options>...] [--]
+
+OPTIONS
+
+--dry-run
+ Show what would be pushed without actually updating the destination
+
+-f,--force
+ Force-push the topic HEAD to rewrite the destination branch
+
+--no-default
+ Do not push the default branch (e.g. master)
+
+--no-topic
+ Do not push the topic HEAD.
+'
+OPTIONS_SPEC=
+SUBDIRECTORY_OK=Yes
+. "$(git --exec-path)/git-sh-setup"
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+# Load the project configuration.
+gitlab_upstream='' &&
+gitlab_configured='' &&
+config="${BASH_SOURCE%/*}/config" &&
+protocol=$(git config -f "$config" --get gitlab.protocol ||
+ echo "https") &&
+host=$(git config -f "$config" --get gitlab.host) &&
+site=$(git config -f "$config" --get gitlab.site ||
+ echo "$protocol://$host") &&
+group_path=$(git config -f "$config" --get gitlab.group-path) &&
+project_path=$(git config -f "$config" --get gitlab.project-path) &&
+gitlab_upstream="$site/$group_path/$project_path.git" &&
+gitlab_pushurl=$(git config --get remote.gitlab.pushurl ||
+ git config --get remote.gitlab.url) &&
+gitlab_configured=1
+
+#-----------------------------------------------------------------------------
+
+remote=''
+refspecs=''
+force=''
+lease=false
+lease_flag=''
+no_topic=''
+no_default=''
+dry_run=''
+
+# Parse the command line options.
+while test $# != 0; do
+ case "$1" in
+ -f|--force) force='+'; lease=true ;;
+ --no-topic) no_topic=1 ;;
+ --dry-run) dry_run=--dry-run ;;
+ --no-default) no_default=1 ;;
+ --) shift; break ;;
+ -*) usage ;;
+ *) test -z "$remote" || usage ; remote="$1" ;;
+ esac
+ shift
+done
+test $# = 0 || usage
+
+# Default remote.
+test -n "$remote" || remote="gitlab"
+
+if test -z "$no_topic"; then
+ # Identify and validate the topic branch name.
+ head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic=''
+ if test -z "$topic" -o "$topic" = "master"; then
+ die 'Please name your topic:
+ git checkout -b descriptive-name'
+ fi
+
+ if $lease; then
+ have_ref=false
+ remoteref="refs/remotes/$remote/$topic"
+ if git rev-parse --verify -q "$remoteref"; then
+ have_ref=true
+ else
+ die "It seems that a local ref for the branch is
+missing; forcing a push is dangerous and may overwrite
+previous work. Fetch from the $remote remote first or
+push without '-f' or '--force'."
+ fi
+
+ have_lease_flag=false
+ if git push -h | egrep-q -e '--force-with-lease'; then
+ have_lease_flag=true
+ fi
+
+ if $have_lease_flag && $have_ref; then
+ # Set the lease flag.
+ lease_flag="--force-with-lease=$topic:$remoteref"
+ # Clear the force string.
+ force=''
+ fi
+ fi
+
+ # The topic branch will be pushed by name.
+ refspecs="${force}HEAD:refs/heads/$topic $refspecs"
+fi
+
+# Fetch the current remote master branch head.
+# This helps computation of a minimal pack to push.
+echo "Fetching $remote master"
+fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out"
+gitlab_head=$(git rev-parse FETCH_HEAD) || exit
+
+# Fetch the current upstream master branch head.
+if origin_fetchurl=$(git config --get remote.origin.url) &&
+ test "$origin_fetchurl" = "$gitlab_upstream"; then
+ upstream_remote='origin'
+else
+ upstream_remote="$gitlab_upstream"
+fi
+echo "Fetching $upstream_remote master"
+fetch_out=$(git fetch "$upstream_remote" master 2>&1) || die "$fetch_out"
+upstream_head=$(git rev-parse FETCH_HEAD) || exit
+
+# Add a refspec to keep the remote master up to date if possible.
+if test -z "$no_default" &&
+ base=$(git merge-base "$gitlab_head" "$upstream_head") &&
+ test "$base" = "$gitlab_head"; then
+ refspecs="$upstream_head:refs/heads/master $refspecs"
+fi
+
+# Exit early if we have nothing to push.
+if test -z "$refspecs"; then
+ echo 'Nothing to push!'
+ exit 0
+fi
+
+# Push. Save output and exit code.
+echo "Pushing to $remote"
+push_config='-c advice.pushUpdateRejected=false'
+push_stdout=$(git $push_config push $lease_flag --porcelain $dry_run "$remote" $refspecs); push_exit=$?
+echo "$push_stdout"
+
+if test "$push_exit" -ne 0 && test -z "$force"; then
+ # Advise the user to fetch if needed.
+ if echo "$push_stdout" | egrep-q 'stale info'; then
+ echo "
+You have pushed to your branch from another machine; you may be overwriting
+commits unintentionally. Fetch from the $remote remote and check that you are
+not pushing an outdated branch."
+ fi
+
+ # Advise the user to force-push if needed.
+ if echo "$push_stdout" | egrep-q 'non-fast-forward'; then
+ echo '
+Add "-f" or "--force" to push a rewritten topic.'
+ fi
+fi
+
+# Reproduce the push exit code.
+exit $push_exit
diff --git a/Utilities/GitSetup/setup-gerrit b/Utilities/GitSetup/setup-gerrit
index 9e8fa62..6d46e3c 100755
--- a/Utilities/GitSetup/setup-gerrit
+++ b/Utilities/GitSetup/setup-gerrit
@@ -28,6 +28,7 @@
# gerrit.pushurl = Review site push URL with "$username" placeholder
# gerrit.remote = Gerrit remote name, if not "gerrit"
# gerrit.url = Gerrit project URL, if not "$site/p/$project"
+# optionally with "$username" placeholder
die() {
echo 1>&2 "$@" ; exit 1
@@ -39,11 +40,12 @@ cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
site=$(git config -f config --get gerrit.site) &&
project=$(git config -f config --get gerrit.project) &&
-pushurl_=$(git config -f config --get gerrit.pushurl) &&
remote=$(git config -f config --get gerrit.remote ||
echo "gerrit") &&
-fetchurl=$(git config -f config --get gerrit.url ||
- echo "$site/p/$project") ||
+fetchurl_=$(git config -f config --get gerrit.url ||
+ echo "$site/p/$project") &&
+pushurl_=$(git config -f config --get gerrit.pushurl ||
+ git config -f config --get gerrit.url) ||
die 'This project is not configured to use Gerrit.'
# Get current gerrit push URL.
@@ -67,7 +69,7 @@ else
'"$project"' changes must be pushed to our Gerrit Code Review site:
- '"$fetchurl"'
+ '"$site/p/$project"'
Register a Gerrit account and select a username (used below).
You will need an OpenID:
@@ -96,13 +98,16 @@ Add your SSH public keys at
if test -z "$gu"; then
gu="$USER"
fi &&
+ fetchurl="${fetchurl_/\$username/$gu}" &&
if test -z "$pushurl"; then
git remote add "$remote" "$fetchurl"
else
git config remote."$remote".url "$fetchurl"
fi &&
pushurl="${pushurl_/\$username/$gu}" &&
- git config remote."$remote".pushurl "$pushurl" &&
+ if test "$pushurl" != "$fetchurl"; then
+ git config remote."$remote".pushurl "$pushurl"
+ fi &&
echo 'Remote "'"$remote"'" is now configured to push to
'"$pushurl"'
diff --git a/Utilities/GitSetup/setup-gitlab b/Utilities/GitSetup/setup-gitlab
new file mode 100755
index 0000000..9c7574d
--- /dev/null
+++ b/Utilities/GitSetup/setup-gitlab
@@ -0,0 +1,140 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+# Run this script to set up the local Git repository to push to
+# a personal fork for this project in GitLab.
+
+# Project configuration instructions:
+#
+# - Run a GitLab server
+#
+# - Populate adjacent "config" file with:
+# gitlab.protocol = Top GitLab protocol, if not 'https'
+# gitlab.host = Top GitLab fully qualified host name
+# gitlab.site = Top GitLab URL, if not "<protocol>://<host>"
+# gitlab.group-name = Name of group containing project in GitLab
+# gitlab.group-path = Path of group containing project in GitLab
+# gitlab.project-name = Name of project within GitLab group
+# gitlab.project-path = Path of project within GitLab group
+# gitlab.url = GitLab push URL with "$username" placeholder,
+# if not "<site>/$username/<project-path>.git"
+# gitlab.pushurl = GitLab push URL with "$username" placeholder,
+# if not "git@<host>:$username/<project-path>.git"
+# gitlab.remote = GitLab remote name, if not "gitlab"
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+protocol=$(git config -f config --get gitlab.protocol ||
+ echo "https") &&
+host=$(git config -f config --get gitlab.host) &&
+site=$(git config -f config --get gitlab.site ||
+ echo "$protocol://$host") &&
+group_path=$(git config -f config --get gitlab.group-path) &&
+group_name=$(git config -f config --get gitlab.group-name) &&
+project_name=$(git config -f config --get gitlab.project-name) &&
+project_path=$(git config -f config --get gitlab.project-path) &&
+pushurl_=$(git config -f config --get gitlab.pushurl ||
+ echo "git@$host:\$username/$project_path.git") &&
+remote=$(git config -f config --get gitlab.remote ||
+ echo "gitlab") &&
+fetchurl_=$(git config -f config --get gitlab.url ||
+ echo "$site/\$username/$project_path.git") ||
+die 'This project is not configured to use GitLab.'
+
+# Get current gitlab push URL.
+pushurl=$(git config --get remote."$remote".pushurl ||
+ git config --get remote."$remote".url || echo '') &&
+
+# Tell user about current configuration.
+if test -n "$pushurl"; then
+ echo 'Remote "'"$remote"'" is currently configured to push to
+
+ '"$pushurl"'
+' &&
+ read -ep 'Reconfigure GitLab? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ setup=1
+ else
+ setup=''
+ fi
+else
+ echo 'Remote "'"$remote"'" is not yet configured.
+' &&
+ read -ep 'Configure GitLab to contribute to '"$project_name"'? [Y/n]: ' ans &&
+ if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
+ exit 0
+ else
+ setup=1
+ fi
+fi &&
+
+setup_instructions='Add your SSH public keys at
+
+ '"$site"'/profile/keys
+
+Then visit the main repository at:
+
+ '"$site/$group_path/$project_path"'
+
+and use the Fork button in the upper right.
+'
+
+# Perform setup if necessary.
+if test -n "$setup"; then
+ echo 'Sign-in to GitLab to get/set your username at
+
+ '"$site/profile/account"'
+
+'"$setup_instructions" &&
+ read -ep "GitLab username? [$USER]: " gu &&
+ if test -z "$gu"; then
+ gu="$USER"
+ fi &&
+ fetchurl="${fetchurl_/\$username/$gu}" &&
+ if test -z "$pushurl"; then
+ git remote add "$remote" "$fetchurl"
+ else
+ git config remote."$remote".url "$fetchurl"
+ fi &&
+ pushurl="${pushurl_/\$username/$gu}" &&
+ git config remote."$remote".pushurl "$pushurl" &&
+ echo 'Remote "'"$remote"'" is now configured to push to
+
+ '"$pushurl"'
+'
+fi &&
+
+# Optionally test GitLab access.
+if test -n "$pushurl"; then
+ read -ep 'Test access to GitLab (SSH)? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ echo -n 'Testing GitLab access by SSH...'
+ if git ls-remote --heads "$pushurl" >/dev/null; then
+ echo 'passed.'
+ else
+ echo 'failed.' &&
+ die 'Could not access your GitLab fork of this project.
+'"$setup_instructions"
+ fi
+ fi
+fi
diff --git a/Utilities/GitSetup/setup-hooks b/Utilities/GitSetup/setup-hooks
index c07985a..ca07712 100755
--- a/Utilities/GitSetup/setup-hooks
+++ b/Utilities/GitSetup/setup-hooks
@@ -55,6 +55,7 @@ fi &&
# Populate ".git/hooks".
echo 'Setting up git hooks...' &&
git_dir=$(git rev-parse --git-dir) &&
+mkdir -p "$git_dir/hooks" &&
cd "$git_dir/hooks" &&
if ! test -e .git; then
git init -q || die 'Could not run git init for hooks.'
diff --git a/Utilities/GitSetup/setup-stage b/Utilities/GitSetup/setup-stage
index 323e47a..ce6ec45 100755
--- a/Utilities/GitSetup/setup-stage
+++ b/Utilities/GitSetup/setup-stage
@@ -37,8 +37,8 @@ die() {
cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
-fetchurl=$(git config -f config --get stage.url) &&
-pushurl_=$(git config -f config --get stage.pushurl || echo '') &&
+fetchurl_=$(git config -f config --get stage.url) &&
+pushurl_=$(git config -f config --get stage.pushurl || echo "$fetchurl_") &&
remote=$(git config -f config --get stage.remote || echo 'stage') ||
die 'This project is not configured to use a topic stage.'
@@ -65,13 +65,16 @@ fi
# Perform setup if necessary.
if test -n "$setup"; then
echo 'Setting up the topic stage...' &&
+ fetchurl="${fetchurl_}" &&
if test -z "$pushurl"; then
git remote add "$remote" "$fetchurl"
else
git config remote."$remote".url "$fetchurl"
fi &&
pushurl="${pushurl_}" &&
- git config remote."$remote".pushurl "$pushurl" &&
+ if test "$pushurl" != "$fetchurl"; then
+ git config remote."$remote".pushurl "$pushurl"
+ fi &&
echo 'Remote "'"$remote"'" is now configured to push to
'"$pushurl"'
diff --git a/Utilities/GitSetup/setup-upstream b/Utilities/GitSetup/setup-upstream
new file mode 100755
index 0000000..92ce1da
--- /dev/null
+++ b/Utilities/GitSetup/setup-upstream
@@ -0,0 +1,104 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+# Run this script to set up the local Git repository to use the
+# preferred upstream repository URLs.
+
+# Project configuration instructions:
+#
+# - Populate adjacent "config" file with:
+# upstream.url = Preferred fetch url for upstream remote
+# upstream.remote = Preferred name for upstream remote, if not "origin"
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+url=$(git config -f config --get upstream.url) &&
+remote=$(git config -f config --get upstream.remote ||
+ echo 'origin') ||
+die 'This project is not configured to use a preferred upstream repository.'
+
+# Get current upstream URLs.
+fetchurl=$(git config --get remote."$remote".url || echo '') &&
+pushurl=$(git config --get remote."$remote".pushurl || echo '') &&
+
+if test "$fetchurl" = "$url"; then
+ echo 'Remote "'"$remote"'" already uses recommended upstream repository.'
+ exit 0
+fi
+
+upstream_recommend='
+We recommended configuring the "'"$remote"'" remote to fetch from upstream at
+
+ '"$url"'
+'
+
+# Tell user about current configuration.
+if test -n "$fetchurl"; then
+ echo 'Remote "'"$remote"'" is currently configured to fetch from
+
+ '"$fetchurl"'
+' &&
+ if test -n "$pushurl"; then
+ echo 'and push to
+
+ '"$pushurl"
+ fi &&
+ echo "$upstream_recommend" &&
+ if test -n "$pushurl"; then
+ echo 'and to never push to it directly.
+'
+ fi &&
+
+ read -ep 'Reconfigure "'"$remote"'" remote as recommended? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ setup=1
+ else
+ setup=''
+ fi
+else
+ echo 'Remote "'"$remote"'" is not yet configured.' &&
+ echo "$upstream_recommend" &&
+ read -ep 'Configure "'"$remote"'" remote as recommended? [Y/n]: ' ans &&
+ if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
+ exit 0
+ else
+ setup=1
+ fi
+fi &&
+
+# Perform setup if necessary.
+if test -n "$setup"; then
+ if test -z "$fetchurl"; then
+ git remote add "$remote" "$url"
+ else
+ git config remote."$remote".url "$url" &&
+ if old=$(git config --get remote."$remote".pushurl); then
+ git config --unset remote."$remote".pushurl ||
+ echo 'Warning: failed to unset remote.'"$remote"'.pushurl'
+ fi
+ fi &&
+ echo 'Remote "'"$remote"'" is now configured to fetch from
+
+ '"$url"'
+'
+fi
diff --git a/Utilities/Scripts/update-gitsetup.bash b/Utilities/Scripts/update-gitsetup.bash
new file mode 100755
index 0000000..8f0da76
--- /dev/null
+++ b/Utilities/Scripts/update-gitsetup.bash
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="GitSetup"
+readonly ownership="GitSetup Upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/GitSetup"
+readonly repo="https://gitlab.kitware.com/utils/gitsetup.git"
+readonly tag="setup"
+readonly shortlog=false
+readonly paths="
+"
+
+extract_source () {
+ git_archive
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"