diff options
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" |