summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeCPackOptions.cmake.in29
-rw-r--r--Help/command/cmake_parse_arguments.rst85
-rw-r--r--Help/manual/cmake-commands.7.rst1
-rw-r--r--Help/release/dev/CMakeParseArguments-native-impl.rst6
-rw-r--r--Modules/BundleUtilities.cmake4
-rw-r--r--Modules/CMakeParseArguments.cmake148
-rw-r--r--Modules/CPackWIX.cmake3
-rw-r--r--Modules/FindBoost.cmake16
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx13
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx12
-rw-r--r--Source/CPack/WiX/cmWIXPatch.h2
-rw-r--r--Source/cmBootstrapCommands1.cxx2
-rw-r--r--Source/cmParseArgumentsCommand.cxx192
-rw-r--r--Source/cmParseArgumentsCommand.h54
-rw-r--r--Source/kwsys/CMakeLists.txt58
-rw-r--r--Source/kwsys/FundamentalType.h.in139
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx96
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake15
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Errors-result.txt1
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt44
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Errors.cmake14
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Initialization.cmake68
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Mix.cmake24
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Utils.cmake20
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/test_utils.cmake20
-rw-r--r--Utilities/Release/WiX/WIX.template.in46
-rw-r--r--Utilities/Release/WiX/cmake_extra_dialog.wxs36
-rw-r--r--Utilities/Release/WiX/install_dir.wxs61
-rw-r--r--Utilities/Release/WiX/patch_desktop_shortcut.xml5
-rw-r--r--Utilities/Release/WiX/patch_path_env.xml26
-rw-r--r--Utilities/Release/WiX/ui_banner.jpg (renamed from Utilities/Release/cpack_wix_ui_banner.jpg)bin2607 -> 2607 bytes
-rw-r--r--Utilities/Release/WiX/ui_dialog.jpg (renamed from Utilities/Release/cpack_wix_ui_dialog.jpg)bin13369 -> 13369 bytes
-rwxr-xr-xUtilities/Scripts/update-kwsys.bash22
-rw-r--r--Utilities/Scripts/update-third-party.bash146
38 files changed, 975 insertions, 446 deletions
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
index 4ebf306..25af0c9 100644
--- a/CMakeCPackOptions.cmake.in
+++ b/CMakeCPackOptions.cmake.in
@@ -234,10 +234,35 @@ if("${CPACK_GENERATOR}" STREQUAL "WIX")
set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high")
set(CPACK_WIX_UI_BANNER
- "@CMake_SOURCE_DIR@/Utilities/Release/cpack_wix_ui_banner.jpg"
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/ui_banner.jpg"
)
set(CPACK_WIX_UI_DIALOG
- "@CMake_SOURCE_DIR@/Utilities/Release/cpack_wix_ui_dialog.jpg"
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/ui_dialog.jpg"
)
+
+ set(CPACK_WIX_EXTRA_SOURCES
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/install_dir.wxs"
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/cmake_extra_dialog.wxs"
+ )
+
+ set(CPACK_WIX_UI_REF "CMakeUI_InstallDir")
+
+ set(CPACK_WIX_PATCH_FILE
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/patch_path_env.xml"
+ )
+
+ set(CPACK_WIX_TEMPLATE
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/WIX.template.in"
+ )
+
+ set(BUILD_QtDialog "@BUILD_QtDialog@")
+
+ if(BUILD_QtDialog)
+ list(APPEND CPACK_WIX_PATCH_FILE
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/patch_desktop_shortcut.xml"
+ )
+
+ set(CPACK_WIX_CANDLE_EXTRA_FLAGS "-dBUILD_QtDialog=1")
+ endif()
endif()
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
new file mode 100644
index 0000000..6206611
--- /dev/null
+++ b/Help/command/cmake_parse_arguments.rst
@@ -0,0 +1,85 @@
+cmake_parse_arguments
+---------------------
+
+``cmake_parse_arguments`` is intended to be used in macros or functions for
+parsing the arguments given to that macro or function. It processes the
+arguments and defines a set of variables which hold the values of the
+respective options.
+
+::
+
+ cmake_parse_arguments(<prefix> <options> <one_value_keywords>
+ <multi_value_keywords> args...)
+
+
+The ``<options>`` argument contains all options for the respective macro,
+i.e. keywords which can be used when calling the macro without any value
+following, like e.g. the ``OPTIONAL`` keyword of the :command:`install`
+command.
+
+The ``<one_value_keywords>`` argument contains all keywords for this macro
+which are followed by one value, like e.g. ``DESTINATION`` keyword of the
+:command:`install` command.
+
+The ``<multi_value_keywords>`` argument contains all keywords for this
+macro which can be followed by more than one value, like e.g. the
+``TARGETS`` or ``FILES`` keywords of the :command:`install` command.
+
+.. note::
+
+ All keywords shall be unique. I.e. every keyword shall only be specified
+ once in either ``<options>``, ``<one_value_keywords>`` or
+ ``<multi_value_keywords>``. A warning will be emitted if uniqueness is
+ violated.
+
+When done, ``cmake_parse_arguments`` will have defined for each of the
+keywords listed in ``<options>``, ``<one_value_keywords>`` and
+``<multi_value_keywords>`` a variable composed of the given ``<prefix>``
+followed by ``"_"`` and the name of the respective keyword. These
+variables will then hold the respective value from the argument list.
+For the ``<options>`` keywords this will be ``TRUE`` or ``FALSE``.
+
+All remaining arguments are collected in a variable
+``<prefix>_UNPARSED_ARGUMENTS``, this can be checked afterwards to see
+whether your macro was called with unrecognized parameters.
+
+As an example here a ``my_install()`` macro, which takes similar arguments
+as the real :command:`install` command:
+
+.. code-block:: cmake
+
+ function(MY_INSTALL)
+ set(options OPTIONAL FAST)
+ set(oneValueArgs DESTINATION RENAME)
+ set(multiValueArgs TARGETS CONFIGURATIONS)
+ cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
+ "${multiValueArgs}" ${ARGN} )
+
+ # ...
+
+Assume ``my_install()`` has been called like this:
+
+.. code-block:: cmake
+
+ my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
+
+After the ``cmake_parse_arguments`` call the macro will have set the
+following variables::
+
+ MY_INSTALL_OPTIONAL = TRUE
+ MY_INSTALL_FAST = FALSE (was not used in call to my_install)
+ MY_INSTALL_DESTINATION = "bin"
+ MY_INSTALL_RENAME = "" (was not used)
+ MY_INSTALL_TARGETS = "foo;bar"
+ MY_INSTALL_CONFIGURATIONS = "" (was not used)
+ MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (nothing expected after "OPTIONAL")
+
+You can then continue and process these variables.
+
+Keywords terminate lists of values, e.g. if directly after a
+one_value_keyword another recognized keyword follows, this is
+interpreted as the beginning of the new option. E.g.
+``my_install(TARGETS foo DESTINATION OPTIONAL)`` would result in
+``MY_INSTALL_DESTINATION`` set to ``"OPTIONAL"``, but as ``OPTIONAL``
+is a keyword itself ``MY_INSTALL_DESTINATION`` will be empty and
+``MY_INSTALL_OPTIONAL`` will therefore be set to ``TRUE``.
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 5b92b51..d0c2986 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -29,6 +29,7 @@ These commands may be used freely in CMake projects.
/command/build_command
/command/cmake_host_system_information
/command/cmake_minimum_required
+ /command/cmake_parse_arguments
/command/cmake_policy
/command/configure_file
/command/continue
diff --git a/Help/release/dev/CMakeParseArguments-native-impl.rst b/Help/release/dev/CMakeParseArguments-native-impl.rst
new file mode 100644
index 0000000..114a099
--- /dev/null
+++ b/Help/release/dev/CMakeParseArguments-native-impl.rst
@@ -0,0 +1,6 @@
+CMakeParseArguments-native-impl
+-------------------------------
+
+* The :command:`cmake_parse_arguments` command is now implemented natively.
+ The :module:`CMakeParseArguments` module remains as an empty placeholder
+ for compatibility.
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index b7975d3..45dda40 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -424,7 +424,9 @@ function(get_item_rpaths item rpaths_var)
string(REGEX MATCHALL "rpath [^\n]+" load_cmds_ov "${load_cmds_ov}")
string(REGEX REPLACE "rpath " "" load_cmds_ov "${load_cmds_ov}")
if(load_cmds_ov)
- gp_append_unique(${rpaths_var} "${load_cmds_ov}")
+ foreach(rpath ${load_cmds_ov})
+ gp_append_unique(${rpaths_var} "${rpath}")
+ endforeach()
endif()
endif()
diff --git a/Modules/CMakeParseArguments.cmake b/Modules/CMakeParseArguments.cmake
index 8553f38..fc64ab9 100644
--- a/Modules/CMakeParseArguments.cmake
+++ b/Modules/CMakeParseArguments.cmake
@@ -2,86 +2,10 @@
# CMakeParseArguments
# -------------------
#
-#
-#
-# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords>
-# <multi_value_keywords> args...)
-#
-# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions
-# for parsing the arguments given to that macro or function. It
-# processes the arguments and defines a set of variables which hold the
-# values of the respective options.
-#
-# The <options> argument contains all options for the respective macro,
-# i.e. keywords which can be used when calling the macro without any
-# value following, like e.g. the OPTIONAL keyword of the install()
-# command.
-#
-# The <one_value_keywords> argument contains all keywords for this macro
-# which are followed by one value, like e.g. DESTINATION keyword of the
-# install() command.
-#
-# The <multi_value_keywords> argument contains all keywords for this
-# macro which can be followed by more than one value, like e.g. the
-# TARGETS or FILES keywords of the install() command.
-#
-# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
-# keywords listed in <options>, <one_value_keywords> and
-# <multi_value_keywords> a variable composed of the given <prefix>
-# followed by "_" and the name of the respective keyword. These
-# variables will then hold the respective value from the argument list.
-# For the <options> keywords this will be TRUE or FALSE.
-#
-# All remaining arguments are collected in a variable
-# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see
-# whether your macro was called with unrecognized parameters.
-#
-# As an example here a my_install() macro, which takes similar arguments
-# as the real install() command:
-#
-# ::
-#
-# function(MY_INSTALL)
-# set(options OPTIONAL FAST)
-# set(oneValueArgs DESTINATION RENAME)
-# set(multiValueArgs TARGETS CONFIGURATIONS)
-# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
-# "${multiValueArgs}" ${ARGN} )
-# ...
-#
-#
-#
-# Assume my_install() has been called like this:
-#
-# ::
-#
-# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
-#
-#
-#
-# After the cmake_parse_arguments() call the macro will have set the
-# following variables:
-#
-# ::
-#
-# MY_INSTALL_OPTIONAL = TRUE
-# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
-# MY_INSTALL_DESTINATION = "bin"
-# MY_INSTALL_RENAME = "" (was not used)
-# MY_INSTALL_TARGETS = "foo;bar"
-# MY_INSTALL_CONFIGURATIONS = "" (was not used)
-# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
-#
-#
-#
-# You can then continue and process these variables.
-#
-# Keywords terminate lists of values, e.g. if directly after a
-# one_value_keyword another recognized keyword follows, this is
-# interpreted as the beginning of the new option. E.g.
-# my_install(TARGETS foo DESTINATION OPTIONAL) would result in
-# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION
-# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
+# This module once implemented the :command:`cmake_parse_arguments` command
+# that is now implemented natively by CMake. It is now an empty placeholder
+# for compatibility with projects that include it to get the command from
+# CMake 3.4 and lower.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
@@ -95,67 +19,3 @@
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-
-
-if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
- return()
-endif()
-set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
-
-
-function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
- # first set all result variables to empty/FALSE
- foreach(arg_name ${_singleArgNames} ${_multiArgNames})
- set(${prefix}_${arg_name})
- endforeach()
-
- foreach(option ${_optionNames})
- set(${prefix}_${option} FALSE)
- endforeach()
-
- set(${prefix}_UNPARSED_ARGUMENTS)
-
- set(insideValues FALSE)
- set(currentArgName)
-
- # now iterate over all arguments and fill the result variables
- foreach(currentArg ${ARGN})
- list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
- list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
- list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
-
- if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
- if(insideValues)
- if("${insideValues}" STREQUAL "SINGLE")
- set(${prefix}_${currentArgName} ${currentArg})
- set(insideValues FALSE)
- elseif("${insideValues}" STREQUAL "MULTI")
- list(APPEND ${prefix}_${currentArgName} ${currentArg})
- endif()
- else()
- list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
- endif()
- else()
- if(NOT ${optionIndex} EQUAL -1)
- set(${prefix}_${currentArg} TRUE)
- set(insideValues FALSE)
- elseif(NOT ${singleArgIndex} EQUAL -1)
- set(currentArgName ${currentArg})
- set(${prefix}_${currentArgName})
- set(insideValues "SINGLE")
- elseif(NOT ${multiArgIndex} EQUAL -1)
- set(currentArgName ${currentArg})
- set(${prefix}_${currentArgName})
- set(insideValues "MULTI")
- endif()
- endif()
-
- endforeach()
-
- # propagate the result variables to the caller:
- foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
- set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
- endforeach()
- set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
-
-endfunction()
diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake
index bef8e16..4994005 100644
--- a/Modules/CPackWIX.cmake
+++ b/Modules/CPackWIX.cmake
@@ -119,7 +119,8 @@
#
# .. variable:: CPACK_WIX_PATCH_FILE
#
-# Optional XML file with fragments to be inserted into generated WiX sources
+# Optional list of XML files with fragments to be inserted into
+# generated WiX sources
#
# This optional variable can be used to specify an XML file that the
# WiX generator will use to inject fragments into its generated
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index e517a6a..edfed8e 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -707,6 +707,20 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret)
set(_Boost_TIMER_DEPENDENCIES chrono system)
set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 106000 AND Boost_VERSION VERSION_LESS 106100)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
else()
message(WARNING "Imported targets not available for Boost version ${Boost_VERSION}")
set(_Boost_IMPORTED_TARGETS FALSE)
@@ -807,7 +821,7 @@ else()
# information in _Boost_COMPONENT_DEPENDENCIES. See the
# instructions at the top of _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
-
+ "1.60.0" "1.60"
"1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55"
"1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
"1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1"
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 7515139..15feed4 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 4)
-set(CMake_VERSION_PATCH 20151218)
+set(CMake_VERSION_PATCH 20151221)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index da8b486..ece327a 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -242,7 +242,16 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if(patchFilePath)
{
- this->Patch->LoadFragments(patchFilePath);
+ std::vector<std::string> patchFilePaths;
+ cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths);
+
+ for(size_t i = 0; i < patchFilePaths.size(); ++i)
+ {
+ if(!this->Patch->LoadFragments(patchFilePaths[i]))
+ {
+ return false;
+ }
+ }
}
return true;
@@ -817,6 +826,8 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
fileDefinitions.AddAttribute("Id", componentId);
fileDefinitions.AddAttribute("Guid", "*");
+ this->Patch->ApplyFragment(componentId, fileDefinitions);
+
std::string registryKey = std::string("Software\\") +
cpackVendor + "\\" + cpackPackageName;
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index 471c3a4..07375da 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -20,10 +20,18 @@ cmWIXPatch::cmWIXPatch(cmCPackLog* logger):
}
-void cmWIXPatch::LoadFragments(std::string const& patchFilePath)
+bool cmWIXPatch::LoadFragments(std::string const& patchFilePath)
{
cmWIXPatchParser parser(Fragments, Logger);
- parser.ParseFile(patchFilePath.c_str());
+ if(!parser.ParseFile(patchFilePath.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Failed parsing XML patch file: '" <<
+ patchFilePath << "'" << std::endl);
+ return false;
+ }
+
+ return true;
}
void cmWIXPatch::ApplyFragment(
diff --git a/Source/CPack/WiX/cmWIXPatch.h b/Source/CPack/WiX/cmWIXPatch.h
index d53fcb4..2f31a01 100644
--- a/Source/CPack/WiX/cmWIXPatch.h
+++ b/Source/CPack/WiX/cmWIXPatch.h
@@ -26,7 +26,7 @@ class cmWIXPatch
public:
cmWIXPatch(cmCPackLog* logger);
- void LoadFragments(std::string const& patchFilePath);
+ bool LoadFragments(std::string const& patchFilePath);
void ApplyFragment(std::string const& id, cmWIXSourceWriter& writer);
diff --git a/Source/cmBootstrapCommands1.cxx b/Source/cmBootstrapCommands1.cxx
index 1184514..0782b3b 100644
--- a/Source/cmBootstrapCommands1.cxx
+++ b/Source/cmBootstrapCommands1.cxx
@@ -54,6 +54,7 @@
#include "cmFunctionCommand.cxx"
#include "cmPathLabel.cxx"
#include "cmSearchPath.cxx"
+#include "cmParseArgumentsCommand.cxx"
void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
{
@@ -91,4 +92,5 @@ void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
commands.push_back(new cmFindProgramCommand);
commands.push_back(new cmForEachCommand);
commands.push_back(new cmFunctionCommand);
+ commands.push_back(new cmParseArgumentsCommand);
}
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
new file mode 100644
index 0000000..a861965
--- /dev/null
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -0,0 +1,192 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Matthias Maennich <matthias@maennich.net>
+ Copyright 2010 Alexander Neundorf <neundorf@kde.org>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmParseArgumentsCommand.h"
+#include "cmAlgorithms.h"
+
+//----------------------------------------------------------------------------
+bool cmParseArgumentsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // cmake_parse_arguments(prefix options single multi <ARGN>)
+ // 1 2 3 4
+ if (args.size() < 4)
+ {
+ this->SetError("must be called with at least 4 arguments.");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator argIter = args.begin(),
+ argEnd = args.end();
+ // the first argument is the prefix
+ const std::string prefix = (*argIter++) + "_";
+
+ // define the result maps holding key/value pairs for
+ // options, single values and multi values
+ typedef std::map<std::string, bool> options_map;
+ typedef std::map<std::string, std::string> single_map;
+ typedef std::map<std::string, std::vector<std::string> > multi_map;
+ options_map options;
+ single_map single;
+ multi_map multi;
+
+ // anything else is put into a vector of unparsed strings
+ std::vector<std::string> unparsed;
+
+ // remember already defined keywords
+ std::set<std::string> used_keywords;
+ const std::string dup_warning = "keyword defined more than once: ";
+
+ // the second argument is a (cmake) list of options without argument
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
+ options[*iter]; // default initialize
+ }
+
+ // the third argument is a (cmake) list of single argument options
+ list.clear();
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
+ single[*iter]; // default initialize
+ }
+
+ // the fourth argument is a (cmake) list of multi argument options
+ list.clear();
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
+ multi[*iter]; // default initialize
+ }
+
+ enum insideValues
+ {
+ NONE,
+ SINGLE,
+ MULTI
+ } insideValues = NONE;
+ std::string currentArgName;
+
+ // now iterate over the remaining arguments
+ // and fill in the values where applicable
+ for(; argIter != argEnd; ++argIter)
+ {
+ const options_map::iterator optIter = options.find(*argIter);
+ if (optIter != options.end())
+ {
+ insideValues = NONE;
+ optIter->second = true;
+ continue;
+ }
+
+ const single_map::iterator singleIter = single.find(*argIter);
+ if (singleIter != single.end())
+ {
+ insideValues = SINGLE;
+ currentArgName = *argIter;
+ continue;
+ }
+
+ const multi_map::iterator multiIter = multi.find(*argIter);
+ if (multiIter != multi.end())
+ {
+ insideValues = MULTI;
+ currentArgName = *argIter;
+ continue;
+ }
+
+ switch(insideValues)
+ {
+ case SINGLE:
+ single[currentArgName] = *argIter;
+ insideValues = NONE;
+ break;
+ case MULTI:
+ multi[currentArgName].push_back(*argIter);
+ break;
+ default:
+ unparsed.push_back(*argIter);
+ break;
+ }
+ }
+
+ // now iterate over the collected values and update their definition
+ // within the current scope. undefine if necessary.
+
+ for (options_map::const_iterator iter = options.begin(), end = options.end();
+ iter != end; ++iter)
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ iter->second? "TRUE": "FALSE");
+ }
+ for (single_map::const_iterator iter = single.begin(), end = single.end();
+ iter != end; ++iter)
+ {
+ if (!iter->second.empty())
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ iter->second.c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + iter->first);
+ }
+ }
+
+ for (multi_map::const_iterator iter = multi.begin(), end = multi.end();
+ iter != end; ++iter)
+ {
+ if (!iter->second.empty())
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ cmJoin(cmMakeRange(iter->second), ";")
+ .c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + iter->first);
+ }
+ }
+
+ if (!unparsed.empty())
+ {
+ this->Makefile->AddDefinition(prefix + "UNPARSED_ARGUMENTS",
+ cmJoin(cmMakeRange(unparsed), ";").c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
+ }
+
+ return true;
+}
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
new file mode 100644
index 0000000..7fbf642
--- /dev/null
+++ b/Source/cmParseArgumentsCommand.h
@@ -0,0 +1,54 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Matthias Maennich <matthias@maennich.net>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseArgumentsCommand_h
+#define cmParseArgumentsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmParseArgumentsCommand
+ *
+ */
+class cmParseArgumentsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmParseArgumentsCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual std::string GetName() const { return "cmake_parse_arguments";}
+
+ cmTypeMacro(cmParseArgumentsCommand, cmCommand);
+
+};
+
+
+#endif
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index b859e79..8b15394 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -118,7 +118,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_System 1)
SET(KWSYS_USE_SystemTools 1)
SET(KWSYS_USE_CommandLineArguments 1)
- SET(KWSYS_USE_FundamentalType 1)
SET(KWSYS_USE_Terminal 1)
SET(KWSYS_USE_IOStream 1)
SET(KWSYS_USE_FStream 1)
@@ -374,61 +373,6 @@ IF(KWSYS_CXX_HAS___INT64)
ENDIF()
ENDIF()
-IF(KWSYS_USE_FundamentalType)
- # Look for type size helper macros.
- KWSYS_PLATFORM_INFO_TEST(C KWSYS_C_TYPE_MACROS
- "Checking for C type size macros")
- SET(macro_regex ".*INFO:macro\\[([^]]*)\\].*")
- FOREACH(info ${KWSYS_C_TYPE_MACROS})
- IF("${info}" MATCHES "${macro_regex}")
- STRING(REGEX REPLACE "${macro_regex}" "\\1" macro "${info}")
- SET(KWSYS_C_HAS_MACRO_${macro} 1)
- ENDIF()
- ENDFOREACH()
-
- # Determine type sizes at preprocessing time if possible, and
- # otherwise fall back to a try-compile.
- SET(KWSYS_C_TYPE_NAME_CHAR "char")
- SET(KWSYS_C_TYPE_NAME_SHORT "short")
- SET(KWSYS_C_TYPE_NAME_INT "int")
- SET(KWSYS_C_TYPE_NAME_LONG "long")
- SET(KWSYS_C_TYPE_NAME_LONG_LONG "long long")
- SET(KWSYS_C_TYPE_NAME___INT64 "__int64")
- FOREACH(type CHAR SHORT INT LONG LONG_LONG __INT64)
- IF(KWSYS_C_HAS_MACRO___SIZEOF_${type}__)
- # Use __SIZEOF_${type}__ macro.
- SET(KWSYS_SIZEOF_${type} TRUE)
- SET(KWSYS_C_CODE_SIZEOF_${type} "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} __SIZEOF_${type}__")
- ELSEIF(KWSYS_C_HAS_MACRO___${type}_MAX__)
- # Use __${type}_MAX__ macro.
- SET(KWSYS_SIZEOF_${type} TRUE)
- SET(KWSYS_C_CODE_SIZEOF_${type} "#if __${type}_MAX__ == 0x7f
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 1
-#elif __${type}_MAX__ == 0x7fff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 2
-#elif __${type}_MAX__ == 0x7fffffff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 4
-#elif __${type}_MAX__>>32 == 0x7fffffff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 8
-#else
-# error \"Cannot determine sizeof(${KWSYS_C_TYPE_NAME_${type}}).\"
-#endif")
- ELSE()
- # Configure a hard-coded type size.
- CHECK_TYPE_SIZE("${KWSYS_C_TYPE_NAME_${type}}" KWSYS_SIZEOF_${type})
- IF(NOT KWSYS_SIZEOF_${type})
- SET(KWSYS_SIZEOF_${type} 0)
- ENDIF()
- SET(KWSYS_C_CODE_SIZEOF_${type}
- "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} ${KWSYS_SIZEOF_${type}}")
- ENDIF()
- ENDFOREACH()
-
- # Check signedness of "char" type.
- KWSYS_PLATFORM_CXX_TEST_RUN(KWSYS_CHAR_IS_SIGNED
- "Checking whether char is signed" DIRECT)
-ENDIF()
-
IF(KWSYS_USE_Encoding)
# Look for type size helper macros.
KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING
@@ -741,7 +685,7 @@ ENDFOREACH()
# Add selected C components.
FOREACH(c
- Process Base64 Encoding FundamentalType MD5 Terminal System String
+ Process Base64 Encoding MD5 Terminal System String
)
IF(KWSYS_USE_${c})
# Use the corresponding header file.
diff --git a/Source/kwsys/FundamentalType.h.in b/Source/kwsys/FundamentalType.h.in
deleted file mode 100644
index e702a7a..0000000
--- a/Source/kwsys/FundamentalType.h.in
+++ /dev/null
@@ -1,139 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_FundamentalType_h
-#define @KWSYS_NAMESPACE@_FundamentalType_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Redefine all public interface symbol names to be in the proper
- namespace. These macros are used internally to kwsys only, and are
- not visible to user code. Use kwsysHeaderDump.pl to reproduce
- these macros after making changes to the interface. */
-#if !defined(KWSYS_NAMESPACE)
-# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-
-#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysFundamentalType kwsys_ns(FundamentalType)
-# define kwsysFundamentalType_Int8 kwsys_ns(FundamentalType_Int8)
-# define kwsysFundamentalType_UInt8 kwsys_ns(FundamentalType_UInt8)
-# define kwsysFundamentalType_Int16 kwsys_ns(FundamentalType_Int16)
-# define kwsysFundamentalType_UInt16 kwsys_ns(FundamentalType_UInt16)
-# define kwsysFundamentalType_Int32 kwsys_ns(FundamentalType_Int32)
-# define kwsysFundamentalType_UInt32 kwsys_ns(FundamentalType_UInt32)
-# define kwsysFundamentalType_Int64 kwsys_ns(FundamentalType_Int64)
-# define kwsysFundamentalType_UInt64 kwsys_ns(FundamentalType_UInt64)
-#endif
-
-/* The size of fundamental types. Types that do not exist have size 0. */
-@KWSYS_C_CODE_SIZEOF_CHAR@
-@KWSYS_C_CODE_SIZEOF_SHORT@
-@KWSYS_C_CODE_SIZEOF_INT@
-@KWSYS_C_CODE_SIZEOF_LONG@
-@KWSYS_C_CODE_SIZEOF_LONG_LONG@
-@KWSYS_C_CODE_SIZEOF___INT64@
-
-/* Whether types "long long" and "__int64" are enabled. If a type is
- enabled then it is a unique fundamental type. */
-#define @KWSYS_NAMESPACE@_USE_LONG_LONG @KWSYS_USE_LONG_LONG@
-#define @KWSYS_NAMESPACE@_USE___INT64 @KWSYS_USE___INT64@
-
-/* Whether type "char" is signed (it may be signed or unsigned). */
-#define @KWSYS_NAMESPACE@_CHAR_IS_SIGNED @KWSYS_CHAR_IS_SIGNED@
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Select an 8-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_CHAR == 1
-typedef signed char kwsysFundamentalType_Int8;
-typedef unsigned char kwsysFundamentalType_UInt8;
-#else
-# error "No native data type can represent an 8-bit integer."
-#endif
-
-/* Select a 16-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_SHORT == 2
-typedef short kwsysFundamentalType_Int16;
-typedef unsigned short kwsysFundamentalType_UInt16;
-#elif @KWSYS_NAMESPACE@_SIZEOF_INT == 2
-typedef int kwsysFundamentalType_Int16;
-typedef unsigned int kwsysFundamentalType_UInt16;
-#else
-# error "No native data type can represent a 16-bit integer."
-#endif
-
-/* Select a 32-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_INT == 4
-typedef int kwsysFundamentalType_Int32;
-typedef unsigned int kwsysFundamentalType_UInt32;
-#elif @KWSYS_NAMESPACE@_SIZEOF_LONG == 4
-typedef long kwsysFundamentalType_Int32;
-typedef unsigned long kwsysFundamentalType_UInt32;
-#else
-# error "No native data type can represent a 32-bit integer."
-#endif
-
-/* Select a 64-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_LONG == 8
-typedef signed long kwsysFundamentalType_Int64;
-typedef unsigned long kwsysFundamentalType_UInt64;
-#elif @KWSYS_NAMESPACE@_USE_LONG_LONG && @KWSYS_NAMESPACE@_SIZEOF_LONG_LONG == 8
-typedef signed long long kwsysFundamentalType_Int64;
-typedef unsigned long long kwsysFundamentalType_UInt64;
-#elif @KWSYS_NAMESPACE@_USE___INT64 && @KWSYS_NAMESPACE@_SIZEOF___INT64 == 8
-typedef signed __int64 kwsysFundamentalType_Int64;
-typedef unsigned __int64 kwsysFundamentalType_UInt64;
-#else
-# error "No native data type can represent a 64-bit integer."
-#endif
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsys .c or .cxx file, let it use these macros.
- Otherwise, undefine them to keep the namespace clean. */
-#if !defined(KWSYS_NAMESPACE)
-# undef kwsys_ns
-# undef kwsysEXPORT
-# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsysFundamentalType
-# undef kwsysFundamentalType_Int8
-# undef kwsysFundamentalType_UInt8
-# undef kwsysFundamentalType_Int16
-# undef kwsysFundamentalType_UInt16
-# undef kwsysFundamentalType_Int32
-# undef kwsysFundamentalType_UInt32
-# undef kwsysFundamentalType_Int64
-# undef kwsysFundamentalType_UInt64
-# endif
-#endif
-
-/* If building a C or C++ file in kwsys itself, give the source file
- access to the configured macros without a configured namespace. */
-#if defined(KWSYS_NAMESPACE)
-# define KWSYS_SIZEOF_CHAR @KWSYS_NAMESPACE@_SIZEOF_CHAR
-# define KWSYS_SIZEOF_SHORT @KWSYS_NAMESPACE@_SIZEOF_SHORT
-# define KWSYS_SIZEOF_INT @KWSYS_NAMESPACE@_SIZEOF_INT
-# define KWSYS_SIZEOF_LONG @KWSYS_NAMESPACE@_SIZEOF_LONG
-# define KWSYS_SIZEOF_LONG_LONG @KWSYS_NAMESPACE@_SIZEOF_LONG_LONG
-# define KWSYS_SIZEOF___INT64 @KWSYS_NAMESPACE@_SIZEOF___INT64
-# define KWSYS_USE_LONG_LONG @KWSYS_NAMESPACE@_USE_LONG_LONG
-# define KWSYS_USE___INT64 @KWSYS_NAMESPACE@_USE___INT64
-# define KWSYS_CHAR_IS_SIGNED @KWSYS_NAMESPACE@_CHAR_IS_SIGNED
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index aaa33b8..fc87f91 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -130,15 +130,6 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CHAR_IS_SIGNED
-/* Return 0 for char signed and 1 for char unsigned. */
-int main()
-{
- unsigned char uc = 255;
- return (*reinterpret_cast<char*>(&uc) < 0)?0:1;
-}
-#endif
-
#ifdef TEST_KWSYS_LFS_WORKS
/* Return 0 when LFS is available and 1 otherwise. */
#define _LARGEFILE_SOURCE
@@ -326,93 +317,6 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CXX_TYPE_INFO
-/* Collect fundamental type information and save it to a CMake script. */
-
-/* Include limits.h to get macros indicating long long and __int64.
- Note that certain compilers need special macros to define these
- macros in limits.h. */
-#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
-# define _MSC_EXTENSIONS
-#endif
-#if defined(__GNUC__) && __GNUC__ < 3
-# define _GNU_SOURCE
-#endif
-#include <limits.h>
-
-#include <stdio.h>
-#include <string.h>
-
-/* Due to shell differences and limitations of ADD_DEFINITIONS the
- KWSYS_CXX_TYPE_INFO_FILE macro will sometimes have double quotes
- and sometimes not. This macro will make sure the value is treated
- as a double-quoted string. */
-#define TO_STRING(x) TO_STRING0(x)
-#define TO_STRING0(x) TO_STRING1(x)
-#define TO_STRING1(x) #x
-
-void f() {}
-
-int main()
-{
- /* Construct the output file name. Some preprocessors will add an
- extra level of double quotes, so strip them. */
- char fbuf[] = TO_STRING(KWSYS_CXX_TYPE_INFO_FILE);
- char* fname = fbuf;
- if(fname[0] == '"')
- {
- ++fname;
- int len = static_cast<int>(strlen(fname));
- if(len > 0 && fname[len-1] == '"')
- {
- fname[len-1] = 0;
- }
- }
-
- /* Try to open the output file. */
- if(FILE* fout = fopen(fname, "w"))
- {
- /* Set the size of standard types. */
- fprintf(fout, "SET(KWSYS_SIZEOF_CHAR %d)\n", static_cast<int>(sizeof(char)));
- fprintf(fout, "SET(KWSYS_SIZEOF_SHORT %d)\n", static_cast<int>(sizeof(short)));
- fprintf(fout, "SET(KWSYS_SIZEOF_INT %d)\n", static_cast<int>(sizeof(int)));
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG %d)\n", static_cast<int>(sizeof(long)));
-
- /* Set the size of some non-standard but common types. */
- /* Check for a limits.h macro for long long to see if the type exists. */
-#if defined(LLONG_MAX) || defined(LONG_LONG_MAX) || defined(LONGLONG_MAX)
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG %d)\n", static_cast<int>(sizeof(long long)));
-#else
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG 0) # No long long available.\n");
-#endif
- /* Check for a limits.h macro for __int64 to see if the type exists. */
-#if defined(_I64_MIN)
- fprintf(fout, "SET(KWSYS_SIZEOF___INT64 %d)\n", static_cast<int>(sizeof(__int64)));
-#else
- fprintf(fout, "SET(KWSYS_SIZEOF___INT64 0) # No __int64 available.\n");
-#endif
-
- /* Set the size of some pointer types. */
- fprintf(fout, "SET(KWSYS_SIZEOF_PDATA %d)\n", static_cast<int>(sizeof(void*)));
- fprintf(fout, "SET(KWSYS_SIZEOF_PFUNC %d)\n", static_cast<int>(sizeof(&f)));
-
- /* Set whether the native type "char" is signed or unsigned. */
- unsigned char uc = 255;
- fprintf(fout, "SET(KWSYS_CHAR_IS_SIGNED %d)\n",
- (*reinterpret_cast<char*>(&uc) < 0)?1:0);
-
- fclose(fout);
- return 0;
- }
- else
- {
- fprintf(stderr, "Failed to write fundamental type info to \"%s\".\n",
- fname);
- return 1;
- }
-}
-#endif
-
#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
int main()
{
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index a6cbf86..0a388c5 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -177,6 +177,7 @@ add_RunCMake_test(build_command)
add_RunCMake_test(execute_process)
add_RunCMake_test(export)
add_RunCMake_test(cmake_minimum_required)
+add_RunCMake_test(cmake_parse_arguments)
add_RunCMake_test(continue)
add_RunCMake_test(ctest_build)
add_RunCMake_test(ctest_configure)
diff --git a/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt b/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt
new file mode 100644
index 0000000..6dd8cdf
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
new file mode 100644
index 0000000..9a727dd
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
@@ -0,0 +1,15 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# example from the documentation
+# OPTIONAL is a keyword and therefore terminates the definition of
+# the multi-value DEFINITION before even a single value has been added
+
+set(options OPTIONAL FAST)
+set(oneValueArgs DESTINATION RENAME)
+set(multiValueArgs TARGETS CONFIGURATIONS)
+cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
+ "${multiValueArgs}"
+ TARGETS foo DESTINATION OPTIONAL)
+
+TEST(MY_INSTALL_DESTINATION UNDEFINED)
+TEST(MY_INSTALL_OPTIONAL TRUE)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
new file mode 100644
index 0000000..f2ba9b8
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
@@ -0,0 +1,44 @@
+CMake Error at Errors\.cmake:2 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Error at Errors\.cmake:3 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Error at Errors\.cmake:4 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:8 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:9 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:10 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:12 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:13 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:14 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
new file mode 100644
index 0000000..6a38081
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
@@ -0,0 +1,14 @@
+# wrong argument count
+cmake_parse_arguments()
+cmake_parse_arguments(prefix OPT)
+cmake_parse_arguments(prefix OPT SINGLE)
+cmake_parse_arguments(prefix OPT SINGLE MULTI) # not an error
+
+# duplicate keywords
+cmake_parse_arguments(prefix "OPT;OPT" "" "")
+cmake_parse_arguments(prefix "" "OPT;OPT" "")
+cmake_parse_arguments(prefix "" "" "OPT;OPT")
+
+cmake_parse_arguments(prefix "OPT" "OPT" "")
+cmake_parse_arguments(prefix "" "OPT" "OPT")
+cmake_parse_arguments(prefix "OPT" "" "OPT")
diff --git a/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
new file mode 100644
index 0000000..462f923
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
@@ -0,0 +1,68 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# unparsed arguments
+cmake_parse_arguments(pref "" "" "")
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "" FOO)
+TEST(pref_UNPARSED_ARGUMENTS "FOO")
+cmake_parse_arguments(pref "" "" "" FOO BAR)
+TEST(pref_UNPARSED_ARGUMENTS "FOO;BAR")
+cmake_parse_arguments(pref "" "" "")
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+
+# options
+cmake_parse_arguments(pref "OPT1" "" "")
+TEST(pref_OPT1 FALSE)
+
+cmake_parse_arguments(pref "OPT1;OPT2" "" "")
+TEST(pref_OPT1 FALSE)
+TEST(pref_OPT2 FALSE)
+
+cmake_parse_arguments(pref "OPT1" "" "" OPT1)
+TEST(pref_OPT1 TRUE)
+cmake_parse_arguments(pref "OPT1;OPT2" "" "" OPT1 OPT2)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 TRUE)
+cmake_parse_arguments(pref "OPT1;OPT2" "" "")
+TEST(pref_OPT1 FALSE)
+TEST(pref_OPT2 FALSE)
+
+
+# single arguments
+cmake_parse_arguments(pref "" "SINGLE1" "")
+TEST(pref_SINGLE1 UNDEFINED)
+
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
+TEST(pref_SINGLE1 UNDEFINED)
+TEST(pref_SINGLE2 UNDEFINED)
+
+
+cmake_parse_arguments(pref "" "SINGLE1" "" SINGLE1 foo)
+TEST(pref_SINGLE1 foo)
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "" SINGLE1 foo SINGLE2 bar)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 bar)
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
+TEST(pref_SINGLE1 UNDEFINED)
+TEST(pref_SINGLE2 UNDEFINED)
+
+
+# multi arguments
+
+cmake_parse_arguments(pref "" "" "MULTI1")
+TEST(pref_MULTI1 UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
+TEST(pref_MULTI1 UNDEFINED)
+TEST(pref_MULTI2 UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "MULTI1" MULTI1 foo)
+TEST(pref_MULTI1 foo)
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2" MULTI1 foo bar MULTI2 bar foo)
+TEST(pref_MULTI1 foo bar)
+TEST(pref_MULTI2 bar foo)
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
+TEST(pref_MULTI1 UNDEFINED)
+TEST(pref_MULTI2 UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Mix.cmake b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
new file mode 100644
index 0000000..b3eff39
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
@@ -0,0 +1,24 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# specify two keywords for each category and set the first keyword of each
+# within ARGN
+cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
+ OPT1 SINGLE1 foo MULTI1 bar foo bar)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 FALSE)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 UNDEFINED)
+TEST(pref_MULTI1 bar foo bar)
+TEST(pref_MULTI2 UNDEFINED)
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+# same as above but reversed ARGN
+cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
+ MULTI1 bar foo bar SINGLE1 foo OPT1)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 FALSE)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 UNDEFINED)
+TEST(pref_MULTI1 bar foo bar)
+TEST(pref_MULTI2 UNDEFINED)
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
new file mode 100644
index 0000000..b89f1a5
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(Utils)
+run_cmake(Initialization)
+run_cmake(Mix)
+run_cmake(CornerCases)
+run_cmake(Errors)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Utils.cmake b/Tests/RunCMake/cmake_parse_arguments/Utils.cmake
new file mode 100644
index 0000000..3bbf115
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Utils.cmake
@@ -0,0 +1,20 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# test the TEST macro itself
+
+TEST(asdf UNDEFINED)
+
+SET (asdf FALSE)
+TEST(asdf FALSE)
+
+SET (asdf TRUE)
+TEST(asdf TRUE)
+
+SET (asdf TRUE)
+TEST(asdf TRUE)
+
+SET (asdf "some value")
+TEST(asdf "some value")
+
+SET (asdf some list)
+TEST(asdf "some;list")
diff --git a/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake b/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
new file mode 100644
index 0000000..f5425c2
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
@@ -0,0 +1,20 @@
+macro(TEST variable)
+ SET(expected "${ARGN}")
+ if ( "${expected}" STREQUAL "UNDEFINED" )
+ if (DEFINED ${variable})
+ message(FATAL_ERROR "'${variable}' shall be undefined but has value '${${variable}}'")
+ endif()
+ elseif( "${expected}" STREQUAL "FALSE" )
+ if (NOT ${variable} STREQUAL "FALSE")
+ message(FATAL_ERROR "'${variable}' shall be FALSE")
+ endif()
+ elseif( "${expected}" STREQUAL "TRUE" )
+ if (NOT ${variable} STREQUAL "TRUE")
+ message(FATAL_ERROR "'${variable}' shall be TRUE")
+ endif()
+ else()
+ if (NOT ${variable} STREQUAL "${expected}")
+ message(FATAL_ERROR "'${variable}' shall be '${expected}'")
+ endif()
+ endif()
+endmacro()
diff --git a/Utilities/Release/WiX/WIX.template.in b/Utilities/Release/WiX/WIX.template.in
new file mode 100644
index 0000000..094999f
--- /dev/null
+++ b/Utilities/Release/WiX/WIX.template.in
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?include "cpack_variables.wxi"?>
+
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
+ RequiredVersion="3.6.3303.0">
+
+ <Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
+ Name="$(var.CPACK_PACKAGE_NAME)"
+ Language="1033"
+ Version="$(var.CPACK_PACKAGE_VERSION)"
+ Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
+ UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
+
+ <Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine"/>
+
+ <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+
+ <MajorUpgrade
+ Schedule="afterInstallInitialize"
+ AllowDowngrades="yes"/>
+
+ <WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
+ <Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
+
+ <?ifdef CPACK_WIX_PRODUCT_ICON?>
+ <Property Id="ARPPRODUCTICON">ProductIcon.ico</Property>
+ <Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
+ <?endif?>
+
+ <?ifdef CPACK_WIX_UI_BANNER?>
+ <WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
+ <?endif?>
+
+ <?ifdef CPACK_WIX_UI_DIALOG?>
+ <WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
+ <?endif?>
+
+ <FeatureRef Id="ProductFeature"/>
+
+ <UIRef Id="$(var.CPACK_WIX_UI_REF)" />
+
+ <?include "properties.wxi"?>
+ <?include "product_fragment.wxi"?>
+ </Product>
+</Wix>
diff --git a/Utilities/Release/WiX/cmake_extra_dialog.wxs b/Utilities/Release/WiX/cmake_extra_dialog.wxs
new file mode 100644
index 0000000..0ee3d99
--- /dev/null
+++ b/Utilities/Release/WiX/cmake_extra_dialog.wxs
@@ -0,0 +1,36 @@
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <UI>
+ <Property Id="ADD_CMAKE_TO_PATH" Value="None"/>
+ <Dialog Id="CMakeExtraDialog" Width="370" Height="270" Title="Install Options">
+
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)"/>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)"/>
+
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="Choose options for installing CMake [ProductVersion]"/>
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="Install Options"/>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)"/>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0"/>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0"/>
+
+ <Control Id="Hint" Type="Text" X="26" Y="60" Width="250" Height="16" Transparent="yes" Text="By default CMake does not add its directory to the system PATH."/>
+
+ <Control Id="ADD_CMAKE_TO_PATHOption" Type="RadioButtonGroup" X="26" Y="100" Width="305" Height="65" Property="ADD_CMAKE_TO_PATH">
+ <RadioButtonGroup Property="ADD_CMAKE_TO_PATH">
+ <RadioButton Value="None" X="0" Y="0" Width="295" Height="16" Text="Do not add CMake to the system PATH"/>
+ <RadioButton Value="System" X="0" Y="20" Width="295" Height="16" Text="Add CMake to the system PATH for all users"/>
+ <RadioButton Value="User" X="0" Y="40" Width="295" Height="16" Text="Add CMake to the system PATH for the current user"/>
+ </RadioButtonGroup>
+ </Control>
+
+ <?ifdef BUILD_QtDialog ?>
+ <Control Id="DesktopShortcutCheckBox" Type="CheckBox" X="20" Y="170" Width="330" Height="18" CheckBoxValue="1" Property="DESKTOP_SHORTCUT_REQUESTED" Text="Create CMake Desktop Icon"/>
+ <?endif ?>
+ </Dialog>
+ </UI>
+ </Fragment>
+</Wix>
diff --git a/Utilities/Release/WiX/install_dir.wxs b/Utilities/Release/WiX/install_dir.wxs
new file mode 100644
index 0000000..883efba
--- /dev/null
+++ b/Utilities/Release/WiX/install_dir.wxs
@@ -0,0 +1,61 @@
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <UI Id="CMakeUI_InstallDir">
+ <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
+ <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
+ <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
+
+ <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
+ <Property Id="WixUI_Mode" Value="InstallDir" />
+
+ <DialogRef Id="CMakeExtraDialog" />
+
+ <DialogRef Id="BrowseDlg" />
+ <DialogRef Id="DiskCostDlg" />
+ <DialogRef Id="ErrorDlg" />
+ <DialogRef Id="FatalError" />
+ <DialogRef Id="FilesInUse" />
+ <DialogRef Id="MsiRMFilesInUse" />
+ <DialogRef Id="PrepareDlg" />
+ <DialogRef Id="ProgressDlg" />
+ <DialogRef Id="ResumeDlg" />
+ <DialogRef Id="UserExit" />
+
+ <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
+ <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
+
+ <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
+
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
+
+ <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="CMakeExtraDialog">LicenseAccepted = "1"</Publish>
+
+ <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="CMakeExtraDialog">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
+ <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
+
+ <Publish Dialog="CMakeExtraDialog" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ <Publish Dialog="CMakeExtraDialog" Control="Next" Event="NewDialog" Value="InstallDirDlg">1</Publish>
+
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
+
+ <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+
+ <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
+
+ <Property Id="ARPNOMODIFY" Value="1" />
+ </UI>
+
+ <UIRef Id="WixUI_Common" />
+ </Fragment>
+</Wix>
diff --git a/Utilities/Release/WiX/patch_desktop_shortcut.xml b/Utilities/Release/WiX/patch_desktop_shortcut.xml
new file mode 100644
index 0000000..d30705d
--- /dev/null
+++ b/Utilities/Release/WiX/patch_desktop_shortcut.xml
@@ -0,0 +1,5 @@
+<CPackWiXPatch>
+ <CPackWiXFragment Id="CM_SHORTCUT_DESKTOP">
+ <Condition>DESKTOP_SHORTCUT_REQUESTED = 1</Condition>
+ </CPackWiXFragment>
+</CPackWiXPatch>
diff --git a/Utilities/Release/WiX/patch_path_env.xml b/Utilities/Release/WiX/patch_path_env.xml
new file mode 100644
index 0000000..0e335c4
--- /dev/null
+++ b/Utilities/Release/WiX/patch_path_env.xml
@@ -0,0 +1,26 @@
+<CPackWiXPatch>
+ <CPackWiXFragment Id="CM_DP_bin">
+ <Component Id="CMakeSystemPathEntryCMP" KeyPath="yes" Guid="0E782367-5D68-4539-81D1-B9757AE496A1">
+
+ <Condition>ADD_CMAKE_TO_PATH = "System"</Condition>
+
+ <Environment Id="CMakeSystemPathEntryENV" Action="set" Part="last"
+ Name="PATH" Value="[INSTALL_ROOT]bin"
+ System="yes"/>
+ </Component>
+
+ <Component Id="CMakeUserPathEntryCMP" KeyPath="yes" Guid="392E524D-D5BF-4F16-A7AF-A82B07482CB9">
+
+ <Condition>ADD_CMAKE_TO_PATH = "User"</Condition>
+
+ <Environment Id="CMakeUserPathEntryENV" Action="set" Part="last"
+ Name="PATH" Value="[INSTALL_ROOT]bin"
+ System="no"/>
+ </Component>
+ </CPackWiXFragment>
+
+ <CPackWiXFragment Id="#PRODUCTFEATURE">
+ <ComponentRef Id="CMakeSystemPathEntryCMP"/>
+ <ComponentRef Id="CMakeUserPathEntryCMP"/>
+ </CPackWiXFragment>
+</CPackWiXPatch>
diff --git a/Utilities/Release/cpack_wix_ui_banner.jpg b/Utilities/Release/WiX/ui_banner.jpg
index 8d950a6..8d950a6 100644
--- a/Utilities/Release/cpack_wix_ui_banner.jpg
+++ b/Utilities/Release/WiX/ui_banner.jpg
Binary files differ
diff --git a/Utilities/Release/cpack_wix_ui_dialog.jpg b/Utilities/Release/WiX/ui_dialog.jpg
index bb6fa5b..bb6fa5b 100644
--- a/Utilities/Release/cpack_wix_ui_dialog.jpg
+++ b/Utilities/Release/WiX/ui_dialog.jpg
Binary files differ
diff --git a/Utilities/Scripts/update-kwsys.bash b/Utilities/Scripts/update-kwsys.bash
new file mode 100755
index 0000000..650841f
--- /dev/null
+++ b/Utilities/Scripts/update-kwsys.bash
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="KWSys"
+readonly ownership="KWSys Upstream <kwrobot@kitware.com>"
+readonly subtree="Source/kwsys"
+readonly repo="http://public.kitware.com/KWSys.git"
+readonly tag="master"
+readonly shortlog=true
+readonly paths="
+"
+
+extract_source () {
+ git_archive
+}
+
+export HOOKS_ALLOW_KWSYS=1
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/Scripts/update-third-party.bash b/Utilities/Scripts/update-third-party.bash
new file mode 100644
index 0000000..8925296
--- /dev/null
+++ b/Utilities/Scripts/update-third-party.bash
@@ -0,0 +1,146 @@
+########################################################################
+# Script for updating third party packages.
+#
+# This script should be sourced in a project-specific script which sets
+# the following variables:
+#
+# name
+# The name of the project.
+# ownership
+# A git author name/email for the commits.
+# subtree
+# The location of the thirdparty package within the main source
+# tree.
+# repo
+# The git repository to use as upstream.
+# tag
+# The tag, branch or commit hash to use for upstream.
+# shortlog
+# Optional. Set to 'true' to get a shortlog in the commit message.
+#
+# Additionally, an "extract_source" function must be defined. It will be
+# run within the checkout of the project on the requested tag. It should
+# should place the desired tree into $extractdir/$name-reduced. This
+# directory will be used as the newest commit for the project.
+#
+# For convenience, the function may use the "git_archive" function which
+# does a standard "git archive" extraction using the (optional) "paths"
+# variable to only extract a subset of the source tree.
+########################################################################
+
+########################################################################
+# Utility functions
+########################################################################
+git_archive () {
+ git archive --prefix="$name-reduced/" HEAD -- $paths | \
+ tar -C "$extractdir" -x
+}
+
+die () {
+ echo >&2 "$@"
+ exit 1
+}
+
+warn () {
+ echo >&2 "warning: $@"
+}
+
+readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
+readonly basehash_regex="$name $regex_date ([0-9a-f]*)"
+readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
+readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p}' | egrep '^[0-9a-f]+$' )"
+
+########################################################################
+# Sanity checking
+########################################################################
+[ -n "$name" ] || \
+ die "'name' is empty"
+[ -n "$ownership" ] || \
+ die "'ownership' is empty"
+[ -n "$subtree" ] || \
+ die "'subtree' is empty"
+[ -n "$repo" ] || \
+ die "'repo' is empty"
+[ -n "$tag" ] || \
+ die "'tag' is empty"
+[ -n "$basehash" ] || \
+ warn "'basehash' is empty; performing initial import"
+readonly do_shortlog="${shortlog-false}"
+
+readonly workdir="$PWD/work"
+readonly upstreamdir="$workdir/upstream"
+readonly extractdir="$workdir/extract"
+
+[ -d "$workdir" ] && \
+ die "error: workdir '$workdir' already exists"
+
+trap "rm -rf '$workdir'" EXIT
+
+# Get upstream
+git clone "$repo" "$upstreamdir"
+
+if [ -n "$basehash" ]; then
+ # Use the existing package's history
+ git worktree add "$extractdir" "$basehash"
+ # Clear out the working tree
+ pushd "$extractdir"
+ git ls-files | xargs rm -v
+ popd
+else
+ # Create a repo to hold this package's history
+ mkdir -p "$extractdir"
+ git -C "$extractdir" init
+fi
+
+# Extract the subset of upstream we care about
+pushd "$upstreamdir"
+git checkout "$tag"
+readonly upstream_hash="$( git rev-parse HEAD )"
+readonly upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
+readonly upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
+readonly upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
+if $do_shortlog && [ -n "$basehash" ]; then
+ readonly commit_shortlog="
+
+Upstream Shortlog
+-----------------
+
+$( git shortlog --no-merges --abbrev=8 --format='%h %s' "$upstream_old_short".."$upstream_hash" )"
+else
+ readonly commit_shortlog=""
+fi
+extract_source || \
+ die "failed to extract source"
+popd
+
+[ -d "$extractdir/$name-reduced" ] || \
+ die "expected directory to extract does not exist"
+readonly commit_summary="$name $upstream_date ($upstream_hash_short)"
+
+# Commit the subset
+pushd "$extractdir"
+mv -v "$name-reduced/"* .
+rmdir "$name-reduced/"
+git add -A .
+git commit -n --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
+$commit_summary
+
+Code extracted from:
+
+ $repo
+
+at commit $upstream_hash ($tag).$commit_shortlog
+EOF
+git branch -f "upstream-$name"
+popd
+
+# Merge the subset into this repository
+if [ -n "$basehash" ]; then
+ git merge --log -s recursive "-Xsubtree=$subtree/" --no-commit "upstream-$name"
+else
+ git fetch "$extractdir" "upstream-$name:upstream-$name"
+ git merge --log -s ours --no-commit "upstream-$name"
+ git read-tree -u --prefix="$subtree/" "upstream-$name"
+fi
+git commit --no-edit
+git branch -d "upstream-$name"