Merge topic 'cray-cleanup'

d59159afdb Cray: clean up CrayPrgEnv and CrayLinuxEnvironment modules

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2945
diff --git a/Help/command/list.rst b/Help/command/list.rst
index bfcdf34..6c86c2a 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -21,6 +21,9 @@
     list(`APPEND`_ <list> [<element>...])
     list(`FILTER`_ <list> {INCLUDE | EXCLUDE} REGEX <regex>)
     list(`INSERT`_ <list> <index> [<element>...])
+    list(`POP_BACK`_ <list> [<out-var>...])
+    list(`POP_FRONT`_ <list> [<out-var>...])
+    list(`PREPEND`_ <list> [<element>...])
     list(`REMOVE_ITEM`_ <list> <value>...)
     list(`REMOVE_AT`_ <list> <index>...)
     list(`REMOVE_DUPLICATES`_ <list>)
@@ -33,8 +36,9 @@
 Introduction
 ^^^^^^^^^^^^
 
-The list subcommands ``APPEND``, ``INSERT``, ``FILTER``, ``REMOVE_AT``,
-``REMOVE_ITEM``, ``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create
+The list subcommands ``APPEND``, ``INSERT``, ``FILTER``, ``PREPEND``,
+``POP_BACK``, ``POP_FRONT``, ``REMOVE_AT``, ``REMOVE_ITEM``,
+``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create
 new values for the list within the current CMake variable scope.  Similar to
 the :command:`set` command, the LIST command creates new variable values in
 the current scope, even if the list itself is actually defined in a parent
@@ -142,6 +146,34 @@
 
 Inserts elements to the list to the specified location.
 
+.. _POP_BACK:
+
+.. code-block:: cmake
+
+  list(POP_BACK <list> [<out-var>...])
+
+If no variable name is given, removes exactly one element. Otherwise,
+assign the last element's value to the given variable and removes it,
+up to the last variable name given.
+
+.. _POP_FRONT:
+
+.. code-block:: cmake
+
+  list(POP_FRONT <list> [<out-var>...])
+
+If no variable name is given, removes exactly one element. Otherwise,
+assign the first element's value to the given variable and removes it,
+up to the last variable name given.
+
+.. _PREPEND:
+
+.. code-block:: cmake
+
+  list(PREPEND <list> [<element> ...])
+
+Insert elements to the 0th position in the list.
+
 .. _REMOVE_ITEM:
 
 .. code-block:: cmake
diff --git a/Help/release/dev/list-prepend-and-pop-subcommands.rst b/Help/release/dev/list-prepend-and-pop-subcommands.rst
new file mode 100644
index 0000000..16b14f1
--- /dev/null
+++ b/Help/release/dev/list-prepend-and-pop-subcommands.rst
@@ -0,0 +1,4 @@
+list-prepend-and-pop-subcommands
+--------------------------------
+
+* :command:`list` learned new sub-commands ``PREPEND``, ``POP_FRONT`` and ``POP_BACK``.
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index dbc41c8..ac27f87 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -83,7 +83,7 @@
   set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_XL "XL C")
 
   list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS MSVC )
-  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "/?")
+  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "-?")
   set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft")
 
   list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI )
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 83ce392..8ba4246 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -824,7 +824,7 @@
   endif()
 
   # Test whether an MSVC-like command-line option works.
-  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" /?
+  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -?
     RESULT_VARIABLE _clang_result
     OUTPUT_VARIABLE _clang_stdout
     ERROR_VARIABLE _clang_stderr)
diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake
index 9edc309..a3c4d9c 100644
--- a/Modules/CMakeDetermineVSServicePack.cmake
+++ b/Modules/CMakeDetermineVSServicePack.cmake
@@ -79,7 +79,7 @@
 function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR  _VERSION_VAR)
     if(EXISTS ${CMAKE_CXX_COMPILER})
       execute_process(
-          COMMAND ${CMAKE_CXX_COMPILER} /?
+          COMMAND ${CMAKE_CXX_COMPILER} -?
           ERROR_VARIABLE _output
           OUTPUT_QUIET
         )
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 9c45022..b324571 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 14)
-set(CMake_VERSION_PATCH 20190219)
+set(CMake_VERSION_PATCH 20190220)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index f522ce2..045d93d 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -618,7 +618,7 @@
 
   std::string mainSourceFilePath = this->CPackTopLevel + "/main.wxs";
 
-  if (!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath.c_str())) {
+  if (!ConfigureFile(wixTemplate, mainSourceFilePath)) {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
                   "Failed creating '" << mainSourceFilePath
                                       << "'' from template." << std::endl);
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index fc34ef8..575254e 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -1245,7 +1245,8 @@
   return true;
 }
 
-bool cmCPackGenerator::ConfigureFile(const char* inName, const char* outName,
+bool cmCPackGenerator::ConfigureFile(const std::string& inName,
+                                     const std::string& outName,
                                      bool copyOnly /* = false */)
 {
   return this->MakefileMap->ConfigureFile(inName, outName, copyOnly, true,
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 9e4bf43..3c06d41 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -169,7 +169,8 @@
   virtual const char* GetPackagingInstallPrefix();
 
   virtual std::string FindTemplate(const char* name);
-  virtual bool ConfigureFile(const char* inName, const char* outName,
+  virtual bool ConfigureFile(const std::string& inName,
+                             const std::string& outName,
                              bool copyOnly = false);
   virtual bool ConfigureString(const std::string& input, std::string& output);
   virtual int InitializeInternal();
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index c77eebc..6afd7d5 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -292,9 +292,8 @@
     this->SetOption("CPACK_NSIS_DEFINES", defines.c_str());
   }
 
-  this->ConfigureFile(nsisInInstallOptions.c_str(),
-                      nsisInstallOptions.c_str());
-  this->ConfigureFile(nsisInFileName.c_str(), nsisFileName.c_str());
+  this->ConfigureFile(nsisInInstallOptions, nsisInstallOptions);
+  this->ConfigureFile(nsisInFileName, nsisFileName);
   std::string nsisCmd = "\"";
   nsisCmd += this->GetOption("CPACK_INSTALLER_PROGRAM");
   nsisCmd += "\" \"" + nsisFileName + "\"";
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 85248c6..90e0afe 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -83,7 +83,7 @@
       return 0;
     }
     std::string destFileName = resourcesDirectory + "/" + iconFileName;
-    this->ConfigureFile(iconFile, destFileName.c_str(), true);
+    this->ConfigureFile(iconFile, destFileName, true);
     this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName.c_str());
   }
 
@@ -236,7 +236,7 @@
   cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
                 << (inFileName ? inFileName : "(NULL)")
                 << " to " << destFileName << std::endl);
-  this->ConfigureFile(inFileName, destFileName.c_str());
+  this->ConfigureFile(inFileName, destFileName);
   return true;
 }
 */
@@ -266,7 +266,7 @@
   cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                 "Configure file: " << inFileName << " to " << destFileName
                                    << std::endl);
-  this->ConfigureFile(inFileName.c_str(), destFileName.c_str(), copyOnly);
+  this->ConfigureFile(inFileName, destFileName, copyOnly);
   return true;
 }
 
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index d54ab56..8c22c65 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -105,7 +105,7 @@
 
   // Create the distribution.dist file in the metapackage to turn it
   // into a distribution package.
-  this->ConfigureFile(distributionTemplate.c_str(), distributionFile.c_str());
+  this->ConfigureFile(distributionTemplate, distributionFile);
 }
 
 void cmCPackPKGGenerator::CreateChoiceOutline(
@@ -294,7 +294,7 @@
   cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                 "Configure file: " << (inFileName ? inFileName : "(NULL)")
                                    << " to " << destFileName << std::endl);
-  this->ConfigureFile(inFileName, destFileName.c_str());
+  this->ConfigureFile(inFileName, destFileName);
   return true;
 }
 
@@ -322,7 +322,7 @@
   cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                 "Configure file: " << inFileName << " to " << destFileName
                                    << std::endl);
-  this->ConfigureFile(inFileName.c_str(), destFileName.c_str());
+  this->ConfigureFile(inFileName, destFileName);
   return true;
 }
 
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 8224a0f..0917d11 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -102,7 +102,7 @@
 
 int cmConfigureFileCommand::ConfigureFile()
 {
-  return this->Makefile->ConfigureFile(
-    this->InputFile.c_str(), this->OutputFile.c_str(), this->CopyOnly,
-    this->AtOnly, this->EscapeQuotes, this->NewLineStyle);
+  return this->Makefile->ConfigureFile(this->InputFile, this->OutputFile,
+                                       this->CopyOnly, this->AtOnly,
+                                       this->EscapeQuotes, this->NewLineStyle);
 }
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 69532e6..b78493f 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -136,8 +136,7 @@
   this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES",
                                 functionMapCode.c_str());
   bool res = true;
-  if (!this->Makefile->ConfigureFile(configFile.c_str(), driver.c_str(), false,
-                                     true, false)) {
+  if (!this->Makefile->ConfigureFile(configFile, driver, false, true, false)) {
     res = false;
   }
 
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 2d54c33..6509b56 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -158,14 +158,22 @@
                                                          bool required)
 {
   // Find the default version of the Windows 10 SDK.
-  this->WindowsTargetPlatformVersion = this->GetWindows10SDKVersion();
-  if (required && this->WindowsTargetPlatformVersion.empty()) {
+  std::string const version = this->GetWindows10SDKVersion();
+  if (required && version.empty()) {
     std::ostringstream e;
     e << "Could not find an appropriate version of the Windows 10 SDK"
       << " installed on this machine";
     mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
     return false;
   }
+  this->SetWindowsTargetPlatformVersion(version, mf);
+  return true;
+}
+
+void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion(
+  std::string const& version, cmMakefile* mf)
+{
+  this->WindowsTargetPlatformVersion = version;
   if (!cmSystemTools::VersionCompareEqual(this->WindowsTargetPlatformVersion,
                                           this->SystemVersion)) {
     std::ostringstream e;
@@ -175,7 +183,6 @@
   }
   mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
                     this->WindowsTargetPlatformVersion.c_str());
-  return true;
 }
 
 bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index 32008b0..6e12d3e 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -40,6 +40,9 @@
 
   virtual bool SelectWindows10SDK(cmMakefile* mf, bool required);
 
+  void SetWindowsTargetPlatformVersion(std::string const& version,
+                                       cmMakefile* mf);
+
   // Used to verify that the Desktop toolset for the current generator is
   // installed on the machine.
   bool IsWindowsDesktopToolsetInstalled() const override;
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 913fc4a..2f9eb3f 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -401,6 +401,12 @@
   // If the Win 8.1 SDK is installed then we can select a SDK matching
   // the target Windows version.
   if (this->IsWin81SDKInstalled()) {
+    // VS 2019 does not default to 8.1 so specify it explicitly when needed.
+    if (this->Version >= cmGlobalVisualStudioGenerator::VS16 &&
+        !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) {
+      this->SetWindowsTargetPlatformVersion("8.1", mf);
+      return true;
+    }
     return cmGlobalVisualStudio14Generator::InitializeWindows(mf);
   }
   // Otherwise we must choose a Win 10 SDK even if we are not targeting
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 4e4e1bb..11cc98e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1976,7 +1976,7 @@
         // so let it replace the framework name. This avoids creating
         // a per-configuration Info.plist file.
         this->CurrentLocalGenerator->GenerateFrameworkInfoPList(
-          gtgt, "$(EXECUTABLE_NAME)", plist.c_str());
+          gtgt, "$(EXECUTABLE_NAME)", plist);
         buildSettings->AddAttribute("INFOPLIST_FILE",
                                     this->CreateString(plist));
         buildSettings->AddAttribute("MACH_O_TYPE",
@@ -2017,7 +2017,7 @@
         // a per-configuration Info.plist file. The cfbundle plist
         // is very similar to the application bundle plist
         this->CurrentLocalGenerator->GenerateAppleInfoPList(
-          gtgt, "$(EXECUTABLE_NAME)", plist.c_str());
+          gtgt, "$(EXECUTABLE_NAME)", plist);
         buildSettings->AddAttribute("INFOPLIST_FILE",
                                     this->CreateString(plist));
       } else {
@@ -2051,7 +2051,7 @@
         // so let it replace the framework name. This avoids creating
         // a per-configuration Info.plist file.
         this->CurrentLocalGenerator->GenerateFrameworkInfoPList(
-          gtgt, "$(EXECUTABLE_NAME)", plist.c_str());
+          gtgt, "$(EXECUTABLE_NAME)", plist);
         buildSettings->AddAttribute("INFOPLIST_FILE",
                                     this->CreateString(plist));
       } else {
@@ -2089,7 +2089,7 @@
         // so let it replace the executable name.  This avoids creating
         // a per-configuration Info.plist file.
         this->CurrentLocalGenerator->GenerateAppleInfoPList(
-          gtgt, "$(EXECUTABLE_NAME)", plist.c_str());
+          gtgt, "$(EXECUTABLE_NAME)", plist);
         buildSettings->AddAttribute("INFOPLIST_FILE",
                                     this->CreateString(plist));
       }
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 297babf..fdbd5ba 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -42,6 +42,15 @@
   if (subCommand == "APPEND") {
     return this->HandleAppendCommand(args);
   }
+  if (subCommand == "PREPEND") {
+    return this->HandlePrependCommand(args);
+  }
+  if (subCommand == "POP_BACK") {
+    return this->HandlePopBackCommand(args);
+  }
+  if (subCommand == "POP_FRONT") {
+    return this->HandlePopFrontCommand(args);
+  }
   if (subCommand == "FIND") {
     return this->HandleFindCommand(args);
   }
@@ -222,20 +231,141 @@
     return true;
   }
 
-  const std::string& listName = args[1];
+  std::string const& listName = args[1];
   // expand the variable
   std::string listString;
   this->GetListString(listString, listName);
 
-  if (!listString.empty() && !args.empty()) {
-    listString += ";";
-  }
-  listString += cmJoin(cmMakeRange(args).advance(2), ";");
+  // If `listString` or `args` is empty, no need to append `;`,
+  // then index is going to be `1` and points to the end-of-string ";"
+  auto const offset =
+    std::string::size_type(listString.empty() || args.empty());
+  listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";");
 
   this->Makefile->AddDefinition(listName, listString.c_str());
   return true;
 }
 
+bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
+{
+  assert(args.size() >= 2);
+
+  // Skip if nothing to prepend.
+  if (args.size() < 3) {
+    return true;
+  }
+
+  std::string const& listName = args[1];
+  // expand the variable
+  std::string listString;
+  this->GetListString(listString, listName);
+
+  // If `listString` or `args` is empty, no need to append `;`,
+  // then `offset` is going to be `1` and points to the end-of-string ";"
+  auto const offset =
+    std::string::size_type(listString.empty() || args.empty());
+  listString.insert(0,
+                    cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]);
+
+  this->Makefile->AddDefinition(listName, listString.c_str());
+  return true;
+}
+
+bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args)
+{
+  assert(args.size() >= 2);
+
+  auto ai = args.cbegin();
+  ++ai; // Skip subcommand name
+  std::string const& listName = *ai++;
+  std::vector<std::string> varArgsExpanded;
+  if (!this->GetList(varArgsExpanded, listName)) {
+    // Can't get the list definition... undefine any vars given after.
+    for (; ai != args.cend(); ++ai) {
+      this->Makefile->RemoveDefinition(*ai);
+    }
+    return true;
+  }
+
+  if (!varArgsExpanded.empty()) {
+    if (ai == args.cend()) {
+      // No variables are given... Just remove one element.
+      varArgsExpanded.pop_back();
+    } else {
+      // Ok, assign elements to be removed to the given variables
+      for (; !varArgsExpanded.empty() && ai != args.cend(); ++ai) {
+        assert(!ai->empty());
+        this->Makefile->AddDefinition(*ai, varArgsExpanded.back().c_str());
+        varArgsExpanded.pop_back();
+      }
+      // Undefine the rest variables if the list gets empty earlier...
+      for (; ai != args.cend(); ++ai) {
+        this->Makefile->RemoveDefinition(*ai);
+      }
+    }
+
+    this->Makefile->AddDefinition(listName,
+                                  cmJoin(varArgsExpanded, ";").c_str());
+
+  } else if (ai !=
+             args.cend()) { // The list is empty, but some args were given
+    // Need to *undefine* 'em all, cuz there are no items to assign...
+    for (; ai != args.cend(); ++ai) {
+      this->Makefile->RemoveDefinition(*ai);
+    }
+  }
+
+  return true;
+}
+
+bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args)
+{
+  assert(args.size() >= 2);
+
+  auto ai = args.cbegin();
+  ++ai; // Skip subcommand name
+  std::string const& listName = *ai++;
+  std::vector<std::string> varArgsExpanded;
+  if (!this->GetList(varArgsExpanded, listName)) {
+    // Can't get the list definition... undefine any vars given after.
+    for (; ai != args.cend(); ++ai) {
+      this->Makefile->RemoveDefinition(*ai);
+    }
+    return true;
+  }
+
+  if (!varArgsExpanded.empty()) {
+    if (ai == args.cend()) {
+      // No variables are given... Just remove one element.
+      varArgsExpanded.erase(varArgsExpanded.begin());
+    } else {
+      // Ok, assign elements to be removed to the given variables
+      auto vi = varArgsExpanded.begin();
+      for (; vi != varArgsExpanded.end() && ai != args.cend(); ++ai, ++vi) {
+        assert(!ai->empty());
+        this->Makefile->AddDefinition(*ai, varArgsExpanded.front().c_str());
+      }
+      varArgsExpanded.erase(varArgsExpanded.begin(), vi);
+      // Undefine the rest variables if the list gets empty earlier...
+      for (; ai != args.cend(); ++ai) {
+        this->Makefile->RemoveDefinition(*ai);
+      }
+    }
+
+    this->Makefile->AddDefinition(listName,
+                                  cmJoin(varArgsExpanded, ";").c_str());
+
+  } else if (ai !=
+             args.cend()) { // The list is empty, but some args were given
+    // Need to *undefine* 'em all, cuz there are no items to assign...
+    for (; ai != args.cend(); ++ai) {
+      this->Makefile->RemoveDefinition(*ai);
+    }
+  }
+
+  return true;
+}
+
 bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
 {
   if (args.size() != 4) {
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index 76a9856..ea3d643 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -35,6 +35,9 @@
   bool HandleLengthCommand(std::vector<std::string> const& args);
   bool HandleGetCommand(std::vector<std::string> const& args);
   bool HandleAppendCommand(std::vector<std::string> const& args);
+  bool HandlePrependCommand(std::vector<std::string> const& args);
+  bool HandlePopBackCommand(std::vector<std::string> const& args);
+  bool HandlePopFrontCommand(std::vector<std::string> const& args);
   bool HandleFindCommand(std::vector<std::string> const& args);
   bool HandleInsertCommand(std::vector<std::string> const& args);
   bool HandleJoinCommand(std::vector<std::string> const& args);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 57b34a9..8393165 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2812,7 +2812,7 @@
 
 void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
                                               const std::string& targetName,
-                                              const char* fname)
+                                              const std::string& fname)
 {
   // Find the Info.plist template.
   const char* in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
@@ -2846,11 +2846,12 @@
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_VERSION");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_COPYRIGHT");
-  mf->ConfigureFile(inFile.c_str(), fname, false, false, false);
+  mf->ConfigureFile(inFile, fname, false, false, false);
 }
 
 void cmLocalGenerator::GenerateFrameworkInfoPList(
-  cmGeneratorTarget* target, const std::string& targetName, const char* fname)
+  cmGeneratorTarget* target, const std::string& targetName,
+  const std::string& fname)
 {
   // Find the Info.plist template.
   const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
@@ -2880,5 +2881,5 @@
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
-  mf->ConfigureFile(inFile.c_str(), fname, false, false, false);
+  mf->ConfigureFile(inFile, fname, false, false, false);
 }
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f9839f6..de12190 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -340,14 +340,14 @@
    */
   void GenerateAppleInfoPList(cmGeneratorTarget* target,
                               const std::string& targetName,
-                              const char* fname);
+                              const std::string& fname);
 
   /**
    * Generate a macOS framework Info.plist file.
    */
   void GenerateFrameworkInfoPList(cmGeneratorTarget* target,
                                   const std::string& targetName,
-                                  const char* fname);
+                                  const std::string& fname);
   /** Construct a comment for a custom command.  */
   std::string ConstructComment(cmCustomCommandGenerator const& ccg,
                                const char* default_comment = "");
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 560181f..0a0501b 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3729,22 +3729,23 @@
                                 lineNumber, true, true);
 }
 
-int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
-                              bool copyonly, bool atOnly, bool escapeQuotes,
+int cmMakefile::ConfigureFile(const std::string& infile,
+                              const std::string& outfile, bool copyonly,
+                              bool atOnly, bool escapeQuotes,
                               cmNewLineStyle newLine)
 {
   int res = 1;
   if (!this->CanIWriteThisFile(outfile)) {
-    cmSystemTools::Error("Attempt to write file: ", outfile,
+    cmSystemTools::Error("Attempt to write file: " + outfile +
                          " into a source directory.");
     return 0;
   }
   if (!cmSystemTools::FileExists(infile)) {
-    cmSystemTools::Error("File ", infile, " does not exist.");
+    cmSystemTools::Error("File " + infile + " does not exist.");
     return 0;
   }
   std::string soutfile = outfile;
-  std::string sinfile = infile;
+  const std::string& sinfile = infile;
   this->AddCMakeDependFile(sinfile);
   cmSystemTools::ConvertToUnixSlashes(soutfile);
 
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 0800ce4..88b4c2f 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -610,8 +610,8 @@
   /**
    * Copy file but change lines according to ConfigureString
    */
-  int ConfigureFile(const char* infile, const char* outfile, bool copyonly,
-                    bool atOnly, bool escapeQuotes,
+  int ConfigureFile(const std::string& infile, const std::string& outfile,
+                    bool copyonly, bool atOnly, bool escapeQuotes,
                     cmNewLineStyle = cmNewLineStyle());
 
   /**
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 3874f48..3784313 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -799,10 +799,9 @@
 
   std::string frameworkPath;
   std::string linkPath;
-  cmGeneratorTarget& genTarget = *this->GetGeneratorTarget();
 
-  std::string createRule = genTarget.GetCreateRuleVariable(
-    this->TargetLinkLanguage, this->GetConfigName());
+  std::string createRule =
+    gt.GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName());
   bool useWatcomQuote = mf->IsOn(createRule + "_USE_WATCOM_QUOTE");
   cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
 
@@ -815,9 +814,9 @@
       this->GetLocalGenerator()->GetStateSnapshot().GetDirectory()));
   linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
 
-  localGen.GetTargetFlags(
-    linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
-    vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, &genTarget);
+  localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(),
+                          vars["LINK_LIBRARIES"], vars["FLAGS"],
+                          vars["LINK_FLAGS"], frameworkPath, linkPath, &gt);
 
   // Add OS X version flags, if any.
   if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
@@ -838,7 +837,7 @@
 
   vars["LINK_PATH"] = frameworkPath + linkPath;
   std::string lwyuFlags;
-  if (genTarget.GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
+  if (gt.GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
     lwyuFlags = " -Wl,--no-as-needed";
   }
 
@@ -847,17 +846,16 @@
   // code between the Makefile executable and library generators.
   if (targetType == cmStateEnums::EXECUTABLE) {
     std::string t = vars["FLAGS"];
-    localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
+    localGen.AddArchitectureFlags(t, &gt, TargetLinkLanguage, cfgName);
     t += lwyuFlags;
     vars["FLAGS"] = t;
   } else {
     std::string t = vars["ARCH_FLAGS"];
-    localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
+    localGen.AddArchitectureFlags(t, &gt, TargetLinkLanguage, cfgName);
     vars["ARCH_FLAGS"] = t;
     t.clear();
     t += lwyuFlags;
-    localGen.AddLanguageFlagsForLinking(t, &genTarget, TargetLinkLanguage,
-                                        cfgName);
+    localGen.AddLanguageFlagsForLinking(t, &gt, TargetLinkLanguage, cfgName);
     vars["LANGUAGE_COMPILE_FLAGS"] = t;
   }
   if (this->GetGeneratorTarget()->HasSOName(cfgName)) {
@@ -880,7 +878,7 @@
       targetOutputImplib, cmOutputConverter::SHELL);
     vars["TARGET_IMPLIB"] = impLibPath;
     EnsureParentDirectoryExists(impLibPath);
-    if (genTarget.HasImportLibrary(cfgName)) {
+    if (gt.HasImportLibrary(cfgName)) {
       byproducts.push_back(targetOutputImplib);
     }
   }
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 8d2586d..6013cd0 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -455,6 +455,8 @@
     vars.SwiftAuxiliarySources = "$SWIFT_AUXILIARY_SOURCES";
     vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
     vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
+    vars.SwiftPartialModule = "$SWIFT_PARTIAL_MODULE";
+    vars.SwiftPartialDoc = "$SWIFT_PARTIAL_DOC";
   }
 
   // For some cases we do an explicit preprocessor invocation.
@@ -945,6 +947,18 @@
     cmGeneratorTarget::Names targetNames =
       this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
     vars["SWIFT_LIBRARY_NAME"] = targetNames.Base;
+
+    if (const char* partial = source->GetProperty("SWIFT_PARTIAL_MODULE")) {
+      vars["SWIFT_PARTIAL_MODULE"] = partial;
+    } else {
+      vars["SWIFT_PARTIAL_MODULE"] = objectFileName + ".swiftmodule";
+    }
+
+    if (const char* partial = source->GetProperty("SWIFT_PARTIAL_DOC")) {
+      vars["SWIFT_PARTIAL_DOC"] = partial;
+    } else {
+      vars["SWIFT_PARTIAL_DOC"] = objectFileName + ".swiftdoc";
+    }
   }
 
   if (!this->NeedDepTypeMSVC(language)) {
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 6857d5a..47a8df4 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -54,8 +54,7 @@
   plist += this->GT->GetAppBundleDirectory(this->ConfigName,
                                            cmGeneratorTarget::ContentLevel);
   plist += "/Info.plist";
-  this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName,
-                                               plist.c_str());
+  this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
   this->Makefile->AddCMakeOutputFile(plist);
   outpath = out;
 }
@@ -90,8 +89,7 @@
   }
   plist += "/Info.plist";
   std::string name = cmSystemTools::GetFilenameName(targetName);
-  this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name,
-                                                   plist.c_str());
+  this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
 
   // Generate Versions directory only for MacOSX frameworks
   if (this->Makefile->PlatformIsAppleEmbedded()) {
@@ -184,7 +182,7 @@
                                    cmGeneratorTarget::ContentLevel);
   plist += "/Info.plist";
   std::string name = cmSystemTools::GetFilenameName(targetName);
-  this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist.c_str());
+  this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
   this->Makefile->AddCMakeOutputFile(plist);
 }
 
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 95a297c..3ad91ee 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -6,10 +6,12 @@
 
 #include "cmAlgorithms.h"
 #include "cmCustomCommandLines.h"
+#include "cmDuration.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProcessOutput.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
@@ -183,6 +185,68 @@
   }
 }
 
+bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput(
+  std::string const& generator, std::string const& executable,
+  std::string& error, std::string* output)
+{
+  // Check if we have cached output
+  {
+    auto it = this->ExecutableTestOutputs_.find(executable);
+    if (it != this->ExecutableTestOutputs_.end()) {
+      // Return output on demand
+      if (output != nullptr) {
+        *output = it->second;
+      }
+      return true;
+    }
+  }
+
+  // Check if the executable exists
+  if (!cmSystemTools::FileExists(executable, true)) {
+    error = "The \"";
+    error += generator;
+    error += "\" executable ";
+    error += cmQtAutoGen::Quoted(executable);
+    error += " does not exist.";
+    return false;
+  }
+
+  // Test the executable
+  std::string stdOut;
+  {
+    std::string stdErr;
+    std::vector<std::string> command;
+    command.push_back(executable);
+    command.emplace_back("-h");
+    int retVal = 0;
+    const bool runResult = cmSystemTools::RunSingleCommand(
+      command, &stdOut, &stdErr, &retVal, nullptr, cmSystemTools::OUTPUT_NONE,
+      cmDuration::zero(), cmProcessOutput::Auto);
+    if (!runResult) {
+      error = "Test run of \"";
+      error += generator;
+      error += "\" executable ";
+      error += cmQtAutoGen::Quoted(executable) + " failed.\n";
+      error += cmQtAutoGen::QuotedCommand(command);
+      error += "\n";
+      error += stdOut;
+      error += "\n";
+      error += stdErr;
+      return false;
+    }
+  }
+
+  // Return executable output on demand
+  if (output != nullptr) {
+    *output = stdOut;
+  }
+
+  // Register executable and output
+  this->ExecutableTestOutputs_.emplace(executable, std::move(stdOut));
+
+  return true;
+}
+
 bool cmQtAutoGenGlobalInitializer::generate()
 {
   return (InitializeCustomTargets() && SetupCustomTargets());
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
index 9e6bac0..74184a0 100644
--- a/Source/cmQtAutoGenGlobalInitializer.h
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <memory> // IWYU pragma: keep
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 class cmLocalGenerator;
@@ -38,10 +39,15 @@
   void AddToGlobalAutoRcc(cmLocalGenerator* localGen,
                           std::string const& targetName);
 
+  bool GetExecutableTestOutput(std::string const& generator,
+                               std::string const& executable,
+                               std::string& error, std::string* output);
+
 private:
   std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_;
   std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_;
   std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_;
+  std::unordered_map<std::string, std::string> ExecutableTestOutputs_;
 };
 
 #endif
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index a96d574..614a88b 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1439,18 +1439,18 @@
   return res;
 }
 
-std::pair<bool, std::string> GetQtExecutable(
-  const cmQtAutoGen::IntegerVersion& qtVersion, cmGeneratorTarget* target,
+std::pair<bool, std::string> cmQtAutoGenInitializer::GetQtExecutable(
   const std::string& executable, bool ignoreMissingTarget, std::string* output)
 {
   const std::string upperExecutable = cmSystemTools::UpperCase(executable);
-  std::string result =
-    target->Target->GetSafeProperty("AUTO" + upperExecutable + "_EXECUTABLE");
+  std::string result = this->Target->Target->GetSafeProperty(
+    "AUTO" + upperExecutable + "_EXECUTABLE");
   if (!result.empty()) {
-    cmListFileBacktrace lfbt = target->Target->GetMakefile()->GetBacktrace();
+    cmListFileBacktrace lfbt =
+      this->Target->Target->GetMakefile()->GetBacktrace();
     cmGeneratorExpression ge(lfbt);
     std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(result);
-    result = cge->Evaluate(target->GetLocalGenerator(), "");
+    result = cge->Evaluate(this->Target->GetLocalGenerator(), "");
 
     return std::make_pair(true, result);
   }
@@ -1460,12 +1460,12 @@
   // Find executable
   {
     const std::string targetName =
-      GetQtExecutableTargetName(qtVersion, executable);
+      GetQtExecutableTargetName(this->QtVersion, executable);
     if (targetName.empty()) {
       err = "The AUTO" + upperExecutable + " feature ";
       err += "supports only Qt 4, Qt 5 and Qt 6.";
     } else {
-      cmLocalGenerator* localGen = target->GetLocalGenerator();
+      cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
       cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse(targetName);
       if (tgt != nullptr) {
         if (tgt->IsImported()) {
@@ -1485,36 +1485,14 @@
 
   // Test executable
   if (err.empty()) {
-    if (cmSystemTools::FileExists(result, true)) {
-      std::vector<std::string> command;
-      command.push_back(result);
-      command.emplace_back("-h");
-      std::string stdOut;
-      std::string stdErr;
-      int retVal = 0;
-      const bool runResult = cmSystemTools::RunSingleCommand(
-        command, &stdOut, &stdErr, &retVal, nullptr,
-        cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
-      if (!runResult) {
-        err = "Test of \"" + executable + "\" binary ";
-        err += cmQtAutoGen::Quoted(result) + " failed: ";
-        err += cmQtAutoGen::QuotedCommand(command);
-      } else {
-        if (output != nullptr) {
-          *output = stdOut;
-        }
-      }
-    } else {
-      err = "The \"" + executable + "\" binary ";
-      err += cmQtAutoGen::Quoted(result);
-      err += " does not exist";
-    }
+    this->GlobalInitializer->GetExecutableTestOutput(executable, result, err,
+                                                     output);
   }
 
   // Print error
   if (!err.empty()) {
     std::string msg = "AutoGen (";
-    msg += target->GetName();
+    msg += this->Target->GetName();
     msg += "): ";
     msg += err;
     cmSystemTools::Error(msg);
@@ -1526,16 +1504,14 @@
 
 bool cmQtAutoGenInitializer::GetMocExecutable()
 {
-  const auto result =
-    GetQtExecutable(this->QtVersion, this->Target, "moc", false, nullptr);
+  const auto result = this->GetQtExecutable("moc", false, nullptr);
   this->Moc.Executable = result.second;
   return result.first;
 }
 
 bool cmQtAutoGenInitializer::GetUicExecutable()
 {
-  const auto result =
-    GetQtExecutable(this->QtVersion, this->Target, "uic", true, nullptr);
+  const auto result = this->GetQtExecutable("uic", true, nullptr);
   this->Uic.Executable = result.second;
   return result.first;
 }
@@ -1543,8 +1519,7 @@
 bool cmQtAutoGenInitializer::GetRccExecutable()
 {
   std::string stdOut;
-  const auto result =
-    GetQtExecutable(this->QtVersion, this->Target, "rcc", false, &stdOut);
+  const auto result = this->GetQtExecutable("rcc", false, &stdOut);
   this->Rcc.Executable = result.second;
   if (!result.first) {
     return false;
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 10f0bf3..781dd15 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -110,6 +110,10 @@
                      std::vector<std::string>& files,
                      std::string& errorMessage);
 
+  std::pair<bool, std::string> GetQtExecutable(const std::string& executable,
+                                               bool ignoreMissingTarget,
+                                               std::string* output);
+
 private:
   cmQtAutoGenGlobalInitializer* GlobalInitializer;
   cmGeneratorTarget* Target;
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 5ebdd1b..18d00b1 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -177,6 +177,16 @@
       return replaceValues.SwiftLibraryName;
     }
   }
+  if (replaceValues.SwiftPartialDoc) {
+    if (variable == "SWIFT_PARTIAL_DOC") {
+      return replaceValues.SwiftPartialDoc;
+    }
+  }
+  if (replaceValues.SwiftPartialModule) {
+    if (variable == "SWIFT_PARTIAL_MODULE") {
+      return replaceValues.SwiftPartialModule;
+    }
+  }
   if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
       variable == "TARGET_INSTALLNAME_DIR") {
     // All these variables depend on TargetSOName
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 930eafd..93d0577 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -61,6 +61,8 @@
     const char* SwiftAuxiliarySources;
     const char* SwiftModuleName;
     const char* SwiftLibraryName;
+    const char* SwiftPartialModule;
+    const char* SwiftPartialDoc;
   };
 
   // Expand rule variables in CMake of the type found in language rules
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 201e1cc..51ecbd1 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -4,16 +4,10 @@
 
 #include "cmCryptoHash.h"
 
+#include <array>
 #include <string.h>
 
-cmUuid::cmUuid()
-{
-  Groups.push_back(4);
-  Groups.push_back(2);
-  Groups.push_back(2);
-  Groups.push_back(2);
-  Groups.push_back(6);
-}
+static const std::array<int, 5> kUuidGroups = { { 4, 2, 2, 2, 6 } };
 
 std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
                             std::string const& name) const
@@ -83,11 +77,11 @@
     return false;
   }
   size_t index = 0;
-  for (size_t i = 0; i < this->Groups.size(); ++i) {
+  for (size_t i = 0; i < kUuidGroups.size(); ++i) {
     if (i != 0 && input[index++] != '-') {
       return false;
     }
-    size_t digits = this->Groups[i] * 2;
+    size_t digits = kUuidGroups[i] * 2;
     if (!StringToBinaryImpl(input.substr(index, digits), output)) {
       return false;
     }
@@ -103,12 +97,12 @@
   std::string output;
 
   size_t inputIndex = 0;
-  for (size_t i = 0; i < this->Groups.size(); ++i) {
+  for (size_t i = 0; i < kUuidGroups.size(); ++i) {
     if (i != 0) {
       output += '-';
     }
 
-    size_t bytes = this->Groups[i];
+    size_t bytes = kUuidGroups[i];
     for (size_t j = 0; j < bytes; ++j) {
       unsigned char byte = input[inputIndex++];
       output += this->ByteToHex(byte);
diff --git a/Source/cmUuid.h b/Source/cmUuid.h
index 158ce6e..7de20dd 100644
--- a/Source/cmUuid.h
+++ b/Source/cmUuid.h
@@ -15,8 +15,6 @@
 class cmUuid
 {
 public:
-  cmUuid();
-
   std::string FromMd5(std::vector<unsigned char> const& uuidNamespace,
                       std::string const& name) const;
 
@@ -42,8 +40,6 @@
   std::string BinaryToString(const unsigned char* input) const;
 
   bool IntFromHexDigit(char input, char& output) const;
-
-  std::vector<int> Groups;
 };
 
 #endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 00a2d74..6ee82f4 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -622,8 +622,8 @@
         propsLocal += this->DefaultArtifactDir;
         propsLocal += "\\nasm.props";
         ConvertToWindowsSlash(propsLocal);
-        this->Makefile->ConfigureFile(propsTemplate.c_str(),
-                                      propsLocal.c_str(), false, true, true);
+        this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true,
+                                      true);
         Elem(e1, "Import").Attribute("Project", propsLocal);
       }
     }
diff --git a/Tests/RunCMake/list/POP_BACK-NoArgs-result.txt b/Tests/RunCMake/list/POP_BACK-NoArgs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/POP_BACK-NoArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/POP_BACK-NoArgs-stderr.txt b/Tests/RunCMake/list/POP_BACK-NoArgs-stderr.txt
new file mode 100644
index 0000000..83060b4
--- /dev/null
+++ b/Tests/RunCMake/list/POP_BACK-NoArgs-stderr.txt
@@ -0,0 +1 @@
+list must be called with at least two arguments
diff --git a/Tests/RunCMake/list/POP_BACK-NoArgs.cmake b/Tests/RunCMake/list/POP_BACK-NoArgs.cmake
new file mode 100644
index 0000000..518924d
--- /dev/null
+++ b/Tests/RunCMake/list/POP_BACK-NoArgs.cmake
@@ -0,0 +1 @@
+list(POP_FRONT)
diff --git a/Tests/RunCMake/list/POP_BACK.cmake b/Tests/RunCMake/list/POP_BACK.cmake
new file mode 100644
index 0000000..4794796
--- /dev/null
+++ b/Tests/RunCMake/list/POP_BACK.cmake
@@ -0,0 +1,79 @@
+cmake_policy(SET CMP0054 NEW)
+
+function(assert_expected_list_len list_var expected_size)
+    list(LENGTH ${list_var} _size)
+    if(NOT _size EQUAL ${expected_size})
+        message(FATAL_ERROR "list size expected to be `${expected_size}`, got `${_size}` instead")
+    endif()
+endfunction()
+
+# Pop from undefined list
+list(POP_BACK test)
+if(DEFINED test)
+    message(FATAL_ERROR "`test` expected to be undefined")
+endif()
+
+# Pop from empty list
+set(test)
+list(POP_BACK test)
+if(DEFINED test)
+    message(FATAL_ERROR "`test` expected to be undefined")
+endif()
+
+# Default pop from 1-item list
+list(APPEND test one)
+list(POP_BACK test)
+assert_expected_list_len(test 0)
+
+# Pop from 1-item list to var
+list(APPEND test one)
+list(POP_BACK test one)
+assert_expected_list_len(test 0)
+if(NOT DEFINED one)
+    message(FATAL_ERROR "`one` expected to be defined")
+endif()
+if(NOT one STREQUAL "one")
+    message(FATAL_ERROR "`one` has unexpected value `${one}`")
+endif()
+
+unset(one)
+unset(two)
+
+# Pop from 1-item list to vars
+list(APPEND test one)
+list(POP_BACK test one two)
+assert_expected_list_len(test 0)
+if(NOT DEFINED one)
+    message(FATAL_ERROR "`one` expected to be defined")
+endif()
+if(NOT one STREQUAL "one")
+    message(FATAL_ERROR "`one` has unexpected value `${one}`")
+endif()
+if(DEFINED two)
+    message(FATAL_ERROR "`two` expected to be undefined")
+endif()
+
+unset(one)
+unset(two)
+
+# Default pop from 2-item list
+list(APPEND test one two)
+list(POP_BACK test)
+assert_expected_list_len(test 1)
+if(NOT test STREQUAL "one")
+    message(FATAL_ERROR "`test` has unexpected value `${test}`")
+endif()
+
+# Pop from 2-item list
+list(APPEND test two)
+list(POP_BACK test two)
+assert_expected_list_len(test 1)
+if(NOT DEFINED two)
+    message(FATAL_ERROR "`two` expected to be defined")
+endif()
+if(NOT two STREQUAL "two")
+    message(FATAL_ERROR "`two` has unexpected value `${two}`")
+endif()
+if(NOT test STREQUAL "one")
+    message(FATAL_ERROR "`test` has unexpected value `${test}`")
+endif()
diff --git a/Tests/RunCMake/list/POP_FRONT-NoArgs-result.txt b/Tests/RunCMake/list/POP_FRONT-NoArgs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/POP_FRONT-NoArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/POP_FRONT-NoArgs-stderr.txt b/Tests/RunCMake/list/POP_FRONT-NoArgs-stderr.txt
new file mode 100644
index 0000000..83060b4
--- /dev/null
+++ b/Tests/RunCMake/list/POP_FRONT-NoArgs-stderr.txt
@@ -0,0 +1 @@
+list must be called with at least two arguments
diff --git a/Tests/RunCMake/list/POP_FRONT-NoArgs.cmake b/Tests/RunCMake/list/POP_FRONT-NoArgs.cmake
new file mode 100644
index 0000000..c5cf837
--- /dev/null
+++ b/Tests/RunCMake/list/POP_FRONT-NoArgs.cmake
@@ -0,0 +1 @@
+list(POP_BACK)
diff --git a/Tests/RunCMake/list/POP_FRONT.cmake b/Tests/RunCMake/list/POP_FRONT.cmake
new file mode 100644
index 0000000..a2f8f3c
--- /dev/null
+++ b/Tests/RunCMake/list/POP_FRONT.cmake
@@ -0,0 +1,79 @@
+cmake_policy(SET CMP0054 NEW)
+
+function(assert_expected_list_len list_var expected_size)
+    list(LENGTH ${list_var} _size)
+    if(NOT _size EQUAL ${expected_size})
+        message(FATAL_ERROR "list size expected to be `${expected_size}`, got `${_size}` instead")
+    endif()
+endfunction()
+
+# Pop from undefined list
+list(POP_FRONT test)
+if(DEFINED test)
+    message(FATAL_ERROR "`test` expected to be undefined")
+endif()
+
+# Pop from empty list
+set(test)
+list(POP_FRONT test)
+if(DEFINED test)
+    message(FATAL_ERROR "`test` expected to be undefined")
+endif()
+
+# Default pop from 1-item list
+list(APPEND test one)
+list(POP_FRONT test)
+assert_expected_list_len(test 0)
+
+# Pop from 1-item list to var
+list(APPEND test one)
+list(POP_FRONT test one)
+assert_expected_list_len(test 0)
+if(NOT DEFINED one)
+    message(FATAL_ERROR "`one` expected to be defined")
+endif()
+if(NOT one STREQUAL "one")
+    message(FATAL_ERROR "`one` has unexpected value `${one}`")
+endif()
+
+unset(one)
+unset(two)
+
+# Pop from 1-item list to vars
+list(APPEND test one)
+list(POP_FRONT test one two)
+assert_expected_list_len(test 0)
+if(NOT DEFINED one)
+    message(FATAL_ERROR "`one` expected to be defined")
+endif()
+if(NOT one STREQUAL "one")
+    message(FATAL_ERROR "`one` has unexpected value `${one}`")
+endif()
+if(DEFINED two)
+    message(FATAL_ERROR "`two` expected to be undefined")
+endif()
+
+unset(one)
+unset(two)
+
+# Default pop from 2-item list
+list(APPEND test one two)
+list(POP_FRONT test)
+assert_expected_list_len(test 1)
+if(NOT test STREQUAL "two")
+    message(FATAL_ERROR "`test` has unexpected value `${test}`")
+endif()
+
+# Pop from 2-item list
+list(PREPEND test one)
+list(POP_FRONT test one)
+assert_expected_list_len(test 1)
+if(NOT DEFINED one)
+    message(FATAL_ERROR "`one` expected to be defined")
+endif()
+if(NOT one STREQUAL "one")
+    message(FATAL_ERROR "`one` has unexpected value `${one}`")
+endif()
+if(NOT test STREQUAL "two")
+    message(FATAL_ERROR "`test` has unexpected value `${test}`")
+endif()
diff --git a/Tests/RunCMake/list/PREPEND-NoArgs-result.txt b/Tests/RunCMake/list/PREPEND-NoArgs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/PREPEND-NoArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/PREPEND-NoArgs-stderr.txt b/Tests/RunCMake/list/PREPEND-NoArgs-stderr.txt
new file mode 100644
index 0000000..83060b4
--- /dev/null
+++ b/Tests/RunCMake/list/PREPEND-NoArgs-stderr.txt
@@ -0,0 +1 @@
+list must be called with at least two arguments
diff --git a/Tests/RunCMake/list/PREPEND-NoArgs.cmake b/Tests/RunCMake/list/PREPEND-NoArgs.cmake
new file mode 100644
index 0000000..8935fa9
--- /dev/null
+++ b/Tests/RunCMake/list/PREPEND-NoArgs.cmake
@@ -0,0 +1 @@
+list(PREPEND)
diff --git a/Tests/RunCMake/list/PREPEND.cmake b/Tests/RunCMake/list/PREPEND.cmake
new file mode 100644
index 0000000..17b2921
--- /dev/null
+++ b/Tests/RunCMake/list/PREPEND.cmake
@@ -0,0 +1,33 @@
+list(PREPEND test)
+if(test)
+    message(FATAL_ERROR "failed")
+endif()
+
+list(PREPEND test satu)
+if(NOT test STREQUAL "satu")
+    message(FATAL_ERROR "failed")
+endif()
+
+list(PREPEND test dua)
+if(NOT test STREQUAL "dua;satu")
+    message(FATAL_ERROR "failed")
+endif()
+
+list(PREPEND test tiga)
+if(NOT test STREQUAL "tiga;dua;satu")
+    message(FATAL_ERROR "failed")
+endif()
+
+# Scope test
+function(foo)
+    list(PREPEND test empat)
+    if(NOT test STREQUAL "empat;tiga;dua;satu")
+        message(FATAL_ERROR "failed")
+    endif()
+endfunction()
+
+foo()
+
+if(NOT test STREQUAL "tiga;dua;satu")
+    message(FATAL_ERROR "failed")
+endif()
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index bf3d22d..59c7ea5 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -98,3 +98,15 @@
 
 # Successful tests
 run_cmake(SORT)
+
+# argument tests
+run_cmake(PREPEND-NoArgs)
+# Successful tests
+run_cmake(PREPEND)
+
+# argument tests
+run_cmake(POP_BACK-NoArgs)
+run_cmake(POP_FRONT-NoArgs)
+# Successful tests
+run_cmake(POP_BACK)
+run_cmake(POP_FRONT)