Merge topic 'findgit-imported-target'

97700e9f5b FindGit: Add imported target

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2790
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 62f5f70..497feed 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 13)
-set(CMake_VERSION_PATCH 20190121)
+set(CMake_VERSION_PATCH 20190122)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 4fb3273..6e1ada1 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -111,8 +111,8 @@
     , Revisions(revs)
     , Section(SectionHeader)
   {
-    this->SetLog(&cvs->Log, prefix),
-      this->RegexRevision.compile("^revision +([^ ]*) *$");
+    this->SetLog(&cvs->Log, prefix);
+    this->RegexRevision.compile("^revision +([^ ]*) *$");
     this->RegexBranches.compile("^branches: .*$");
     this->RegexPerson.compile("^date: +([^;]+); +author: +([^;]+);");
   }
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 444a980..72cce9f 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -751,6 +751,7 @@
   if (dialog.exec() == QDialog::Accepted) {
     dialog.saveToSettings();
     this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
+    this->CMakeThread->cmakeInstance()->setPlatform(dialog.getPlatform());
     this->CMakeThread->cmakeInstance()->setToolset(dialog.getToolset());
 
     QCMakeCacheModel* m = this->CacheValues->cacheModel();
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index 88ce7cb..ae5179c 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -16,8 +16,12 @@
   this->GeneratorOptions = new QComboBox(this);
   l->addWidget(this->GeneratorOptions);
 
+  // Add the generator platform
+  this->PlatformFrame = CreatePlatformWidgets();
+  l->addWidget(PlatformFrame);
+
   // Add the ability to specify toolset (-T parameter)
-  ToolsetFrame = CreateToolsetWidgets();
+  this->ToolsetFrame = CreateToolsetWidgets();
   l->addWidget(ToolsetFrame);
 
   l->addSpacing(6);
@@ -45,7 +49,7 @@
                    SLOT(onSelectionChanged(bool)));
   QObject::connect(this->CompilerSetupOptions[3], SIGNAL(toggled(bool)), this,
                    SLOT(onSelectionChanged(bool)));
-  QObject::connect(GeneratorOptions,
+  QObject::connect(this->GeneratorOptions,
                    SIGNAL(currentIndexChanged(QString const&)), this,
                    SLOT(onGeneratorChanged(QString const&)));
 }
@@ -65,6 +69,23 @@
   return frame;
 }
 
+QFrame* StartCompilerSetup::CreatePlatformWidgets()
+{
+  QFrame* frame = new QFrame(this);
+  QVBoxLayout* l = new QVBoxLayout(frame);
+  l->setContentsMargins(0, 0, 0, 0);
+
+  this->PlatformLabel = new QLabel(tr("Optional platform for generator"));
+  l->addWidget(this->PlatformLabel);
+
+  this->PlatformOptions = new QComboBox(frame);
+  this->PlatformOptions->setEditable(true);
+
+  l->addWidget(this->PlatformOptions);
+
+  return frame;
+}
+
 StartCompilerSetup::~StartCompilerSetup()
 {
 }
@@ -80,6 +101,26 @@
   for (it = gens.begin(); it != gens.end(); ++it) {
     generator_list.append(QString::fromLocal8Bit(it->name.c_str()));
 
+    if (it->supportsPlatform) {
+      this->GeneratorsSupportingPlatform.append(
+        QString::fromLocal8Bit(it->name.c_str()));
+
+      this
+        ->GeneratorDefaultPlatform[QString::fromLocal8Bit(it->name.c_str())] =
+        QString::fromLocal8Bit(it->defaultPlatform.c_str());
+
+      std::vector<std::string>::const_iterator platformIt =
+        it->supportedPlatforms.cbegin();
+      while (platformIt != it->supportedPlatforms.cend()) {
+
+        this->GeneratorSupportedPlatforms.insert(
+          QString::fromLocal8Bit(it->name.c_str()),
+          QString::fromLocal8Bit((*platformIt).c_str()));
+
+        platformIt++;
+      }
+    }
+
     if (it->supportsToolset) {
       this->GeneratorsSupportingToolset.append(
         QString::fromLocal8Bit(it->name.c_str()));
@@ -102,6 +143,11 @@
   return this->GeneratorOptions->currentText();
 };
 
+QString StartCompilerSetup::getPlatform() const
+{
+  return this->PlatformOptions->currentText();
+};
+
 QString StartCompilerSetup::getToolset() const
 {
   return this->Toolset->text();
@@ -136,6 +182,31 @@
 
 void StartCompilerSetup::onGeneratorChanged(QString const& name)
 {
+  // Display the generator platform for the generators supporting it
+  if (GeneratorsSupportingPlatform.contains(name)) {
+
+    // Change the label title to include the default platform
+    std::string label = "Optional platform for generator";
+    label += "(if empty, generator uses: ";
+    label += this->GeneratorDefaultPlatform[name].toStdString();
+    label += ")";
+    this->PlatformLabel->setText(tr(label.c_str()));
+
+    // Regenerate the list of supported platform
+    this->PlatformOptions->clear();
+    QStringList platform_list;
+    platform_list.append("");
+
+    QList<QString> platforms = this->GeneratorSupportedPlatforms.values(name);
+    platform_list.append(platforms);
+
+    this->PlatformOptions->addItems(platform_list);
+    PlatformFrame->show();
+  } else {
+    PlatformFrame->hide();
+  }
+
+  // Display the toolset box for the generators supporting it
   if (GeneratorsSupportingToolset.contains(name)) {
     ToolsetFrame->show();
   } else {
@@ -390,6 +461,11 @@
   return this->mStartCompilerSetupPage->getGenerator();
 }
 
+QString FirstConfigure::getPlatform() const
+{
+  return this->mStartCompilerSetupPage->getPlatform();
+}
+
 QString FirstConfigure::getToolset() const
 {
   return this->mStartCompilerSetupPage->getToolset();
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
index abfa03f..d1db5bf 100644
--- a/Source/QtDialog/FirstConfigure.h
+++ b/Source/QtDialog/FirstConfigure.h
@@ -35,6 +35,7 @@
   void setCurrentGenerator(const QString& gen);
   QString getGenerator() const;
   QString getToolset() const;
+  QString getPlatform() const;
 
   bool defaultSetup() const;
   bool compilerSetup() const;
@@ -56,10 +57,17 @@
   QFrame* ToolsetFrame;
   QLineEdit* Toolset;
   QLabel* ToolsetLabel;
+  QFrame* PlatformFrame;
+  QComboBox* PlatformOptions;
+  QLabel* PlatformLabel;
   QStringList GeneratorsSupportingToolset;
+  QStringList GeneratorsSupportingPlatform;
+  QMultiMap<QString, QString> GeneratorSupportedPlatforms;
+  QMap<QString, QString> GeneratorDefaultPlatform;
 
 private:
   QFrame* CreateToolsetWidgets();
+  QFrame* CreatePlatformWidgets();
 };
 
 //! the page that gives basic options for native compilers
@@ -159,6 +167,7 @@
 
   void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
   QString getGenerator() const;
+  QString getPlatform() const;
   QString getToolset() const;
 
   bool defaultSetup() const;
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 9a6784e..2eecce6 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -35,7 +35,8 @@
   cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
 
   std::vector<cmake::GeneratorInfo> generators;
-  this->CMakeInstance->GetRegisteredGenerators(generators);
+  this->CMakeInstance->GetRegisteredGenerators(
+    generators, /*includeNamesWithPlatform=*/false);
 
   std::vector<cmake::GeneratorInfo>::const_iterator it;
   for (it = generators.begin(); it != generators.end(); ++it) {
@@ -74,6 +75,7 @@
     cmState* state = this->CMakeInstance->GetState();
     this->setGenerator(QString());
     this->setToolset(QString());
+    this->setPlatform(QString());
     if (!this->CMakeInstance->LoadCache(
           this->BinaryDirectory.toLocal8Bit().data())) {
       QDir testDir(this->BinaryDirectory);
@@ -102,6 +104,12 @@
       this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
     }
 
+    const char* platform =
+      state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
+    if (platform) {
+      this->setPlatform(QString::fromLocal8Bit(platform));
+    }
+
     const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
     if (toolset) {
       this->setToolset(QString::fromLocal8Bit(toolset));
@@ -119,6 +127,14 @@
   }
 }
 
+void QCMake::setPlatform(const QString& platform)
+{
+  if (this->Platform != platform) {
+    this->Platform = platform;
+    emit this->platformChanged(this->Platform);
+  }
+}
+
 void QCMake::setToolset(const QString& toolset)
 {
   if (this->Toolset != toolset) {
@@ -140,7 +156,8 @@
   this->CMakeInstance->SetGlobalGenerator(
     this->CMakeInstance->CreateGlobalGenerator(
       this->Generator.toLocal8Bit().data()));
-  this->CMakeInstance->SetGeneratorPlatform("");
+  this->CMakeInstance->SetGeneratorPlatform(
+    this->Platform.toLocal8Bit().data());
   this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
   this->CMakeInstance->LoadCache();
   this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 4b3920a..c84da58 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -75,6 +75,8 @@
   /// set the desired generator to use
   void setGenerator(const QString& generator);
   /// set the desired generator to use
+  void setPlatform(const QString& platform);
+  /// set the desired generator to use
   void setToolset(const QString& toolset);
   /// do the configure step
   void configure();
@@ -155,6 +157,8 @@
   void debugOutputChanged(bool);
   /// signal when the toolset changes
   void toolsetChanged(const QString& toolset);
+  /// signal when the platform changes
+  void platformChanged(const QString& platform);
   /// signal when open is done
   void openDone(bool successful);
   /// signal when open is done
@@ -175,6 +179,7 @@
   QString SourceDirectory;
   QString BinaryDirectory;
   QString Generator;
+  QString Platform;
   QString Toolset;
   std::vector<cmake::GeneratorInfo> AvailableGenerators;
   QString CMakeExecutable;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 5f71520..4e2f275 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -2807,13 +2807,13 @@
     if ((res == cmsysProcess_Pipe_STDOUT || res == cmsysProcess_Pipe_STDERR) &&
         this->ExtraVerbose) {
       processOutput.DecodeText(data, length, strdata);
-      cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+      cmSystemTools::Stdout(strdata);
     }
   }
   if (this->ExtraVerbose) {
     processOutput.DecodeText(std::string(), strdata);
     if (!strdata.empty()) {
-      cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+      cmSystemTools::Stdout(strdata);
     }
   }
 
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 2acb015..3b3783a 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -13,7 +13,7 @@
 #include <string.h>
 #include <utility>
 
-cmDepends::cmDepends(cmLocalGenerator* lg, const char* targetDir)
+cmDepends::cmDepends(cmLocalGenerator* lg, const std::string& targetDir)
   : LocalGenerator(lg)
   , TargetDirectory(targetDir)
   , Dependee(new char[MaxPath])
@@ -65,12 +65,13 @@
   return true;
 }
 
-bool cmDepends::Check(const char* makeFile, const char* internalFile,
+bool cmDepends::Check(const std::string& makeFile,
+                      const std::string& internalFile,
                       std::map<std::string, DependencyVector>& validDeps)
 {
   // Check whether dependencies must be regenerated.
   bool okay = true;
-  cmsys::ifstream fin(internalFile);
+  cmsys::ifstream fin(internalFile.c_str());
   if (!(fin && this->CheckDependencies(fin, internalFile, validDeps))) {
     // Clear all dependencies so they will be regenerated.
     this->Clear(makeFile);
@@ -81,13 +82,13 @@
   return okay;
 }
 
-void cmDepends::Clear(const char* file)
+void cmDepends::Clear(const std::string& file)
 {
   // Print verbose output.
   if (this->Verbose) {
     std::ostringstream msg;
     msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
-    cmSystemTools::Stdout(msg.str().c_str());
+    cmSystemTools::Stdout(msg.str());
   }
 
   // Write an empty dependency file.
@@ -107,7 +108,7 @@
 }
 
 bool cmDepends::CheckDependencies(
-  std::istream& internalDepends, const char* internalDependsFileName,
+  std::istream& internalDepends, const std::string& internalDependsFileName,
   std::map<std::string, DependencyVector>& validDeps)
 {
   // Parse dependencies from the stream.  If any dependee is missing
@@ -170,7 +171,7 @@
         std::ostringstream msg;
         msg << "Dependee \"" << dependee << "\" does not exist for depender \""
             << depender << "\"." << std::endl;
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
     } else {
       if (dependerExists) {
@@ -187,15 +188,15 @@
             std::ostringstream msg;
             msg << "Dependee \"" << dependee << "\" is newer than depender \""
                 << depender << "\"." << std::endl;
-            cmSystemTools::Stdout(msg.str().c_str());
+            cmSystemTools::Stdout(msg.str());
           }
         }
       } else {
         // The dependee exists, but the depender doesn't. Regenerate if the
         // internalDepends file is older than the dependee.
         int result = 0;
-        if ((!this->FileComparison->FileTimeCompare(internalDependsFileName,
-                                                    dependee, &result) ||
+        if ((!this->FileComparison->FileTimeCompare(
+               internalDependsFileName.c_str(), dependee, &result) ||
              result < 0)) {
           // The depends-file is older than the dependee.
           regenerate = true;
@@ -206,7 +207,7 @@
             msg << "Dependee \"" << dependee
                 << "\" is newer than depends file \""
                 << internalDependsFileName << "\"." << std::endl;
-            cmSystemTools::Stdout(msg.str().c_str());
+            cmSystemTools::Stdout(msg.str());
           }
         }
       }
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index 705d215..b0b5bb5 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -29,7 +29,7 @@
 public:
   /** Instances need to know the build directory name and the relative
       path from the build directory to the target file.  */
-  cmDepends(cmLocalGenerator* lg = nullptr, const char* targetDir = "");
+  cmDepends(cmLocalGenerator* lg = nullptr, const std::string& targetDir = "");
 
   /** Set the local generator for the directory in which we are
       scanning dependencies.  This is not a full local generator; it
@@ -41,7 +41,10 @@
   void SetLanguage(const std::string& lang) { this->Language = lang; }
 
   /** Set the target build directory.  */
-  void SetTargetDirectory(const char* dir) { this->TargetDirectory = dir; }
+  void SetTargetDirectory(const std::string& dir)
+  {
+    this->TargetDirectory = dir;
+  }
 
   /** should this be verbose in its output */
   void SetVerbose(bool verb) { this->Verbose = verb; }
@@ -61,11 +64,11 @@
       they must be generated Clear has already been called to wipe out
       the old dependencies.
       Dependencies which are still valid will be stored in validDeps. */
-  bool Check(const char* makeFile, const char* internalFile,
+  bool Check(const std::string& makeFile, const std::string& internalFile,
              std::map<std::string, DependencyVector>& validDeps);
 
   /** Clear dependencies for the target file so they will be regenerated.  */
-  void Clear(const char* file);
+  void Clear(const std::string& file);
 
   /** Set the file comparison object */
   void SetFileComparison(cmFileTimeComparison* fc)
@@ -85,7 +88,7 @@
   // Return false if dependencies must be regenerated and true
   // otherwise.
   virtual bool CheckDependencies(
-    std::istream& internalDepends, const char* internalDependsFileName,
+    std::istream& internalDepends, const std::string& internalDependsFileName,
     std::map<std::string, DependencyVector>& validDeps);
 
   // Finalize the dependency information for the target.
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 072d116..f6ac4f2 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -24,7 +24,7 @@
 }
 
 cmDependsC::cmDependsC(
-  cmLocalGenerator* lg, const char* targetDir, const std::string& lang,
+  cmLocalGenerator* lg, const std::string& targetDir, const std::string& lang,
   const std::map<std::string, DependencyVector>* validDeps)
   : cmDepends(lg, targetDir)
   , ValidDeps(validDeps)
@@ -53,8 +53,8 @@
   }
 
   this->IncludeRegexLine.compile(INCLUDE_REGEX_LINE);
-  this->IncludeRegexScan.compile(scanRegex.c_str());
-  this->IncludeRegexComplain.compile(complainRegex.c_str());
+  this->IncludeRegexScan.compile(scanRegex);
+  this->IncludeRegexComplain.compile(complainRegex);
   this->IncludeRegexLineString = INCLUDE_REGEX_LINE_MARKER INCLUDE_REGEX_LINE;
   this->IncludeRegexScanString = INCLUDE_REGEX_SCAN_MARKER;
   this->IncludeRegexScanString += scanRegex;
@@ -212,7 +212,7 @@
               // Scan this file for new dependencies.  Pass the directory
               // containing the file to handle double-quote includes.
               std::string dir = cmSystemTools::GetFilenamePath(fullName);
-              this->Scan(fin, dir.c_str(), fullName);
+              this->Scan(fin, dir, fullName);
             } else {
               // Skip file with encoding we do not implement.
             }
@@ -342,7 +342,7 @@
   }
 }
 
-void cmDependsC::Scan(std::istream& is, const char* directory,
+void cmDependsC::Scan(std::istream& is, const std::string& directory,
                       const std::string& fullName)
 {
   cmIncludeLines* newCacheEntry = new cmIncludeLines;
@@ -418,7 +418,7 @@
       sep = "|";
     }
     xform += ")[ \t]*\\(([^),]*)\\)";
-    this->IncludeRegexTransform.compile(xform.c_str());
+    this->IncludeRegexTransform.compile(xform);
 
     // Build a string that encodes all transformation rules and will
     // change when rules are changed.
@@ -460,11 +460,11 @@
   // Construct the transformed line.
   std::string newline = this->IncludeRegexTransform.match(1);
   std::string arg = this->IncludeRegexTransform.match(4);
-  for (const char* c = tri->second.c_str(); *c; ++c) {
-    if (*c == '%') {
+  for (char c : tri->second) {
+    if (c == '%') {
       newline += arg;
     } else {
-      newline += *c;
+      newline += c;
     }
   }
 
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index f833888..af2b06e 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -28,7 +28,7 @@
   /** Checking instances need to know the build directory name and the
       relative path from the build directory to the target file.  */
   cmDependsC();
-  cmDependsC(cmLocalGenerator* lg, const char* targetDir,
+  cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
              const std::string& lang,
              const std::map<std::string, DependencyVector>* validDeps);
 
@@ -42,7 +42,7 @@
                          std::ostream& internalDepends) override;
 
   // Method to scan a single file.
-  void Scan(std::istream& is, const char* directory,
+  void Scan(std::istream& is, const std::string& directory,
             const std::string& fullName);
 
   // Regular expression to identify C preprocessor include directives.
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index e51f81e..6c5f647 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -7,7 +7,6 @@
 #include <iostream>
 #include <map>
 #include <stdlib.h>
-#include <string.h>
 #include <utility>
 
 #include "cmAlgorithms.h"
@@ -54,7 +53,8 @@
   typedef std::map<std::string, cmFortranSourceInfo> ObjectInfoMap;
   ObjectInfoMap ObjectInfo;
 
-  cmFortranSourceInfo& CreateObjectInfo(const char* obj, const char* src)
+  cmFortranSourceInfo& CreateObjectInfo(const std::string& obj,
+                                        const std::string& src)
   {
     std::map<std::string, cmFortranSourceInfo>::iterator i =
       this->ObjectInfo.find(obj);
@@ -121,8 +121,7 @@
   bool okay = true;
   for (std::string const& src : sources) {
     // Get the information object for this source.
-    cmFortranSourceInfo& info =
-      this->Internal->CreateObjectInfo(obj.c_str(), src.c_str());
+    cmFortranSourceInfo& info = this->Internal->CreateObjectInfo(obj, src);
 
     // Create the parser object. The constructor takes info by reference,
     // so we may look into the resulting objects later.
@@ -153,7 +152,7 @@
   this->LocateModules();
 
   // Get the directory in which stamp files will be stored.
-  const char* stamp_dir = this->TargetDirectory.c_str();
+  const std::string& stamp_dir = this->TargetDirectory;
 
   // Get the directory in which module files will be created.
   cmMakefile* mf = this->LocalGenerator->GetMakefile();
@@ -167,9 +166,8 @@
   typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
   ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
   for (auto const& i : objInfo) {
-    if (!this->WriteDependenciesReal(i.first.c_str(), i.second, mod_dir,
-                                     stamp_dir, makeDepends,
-                                     internalDepends)) {
+    if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir,
+                                     makeDepends, internalDepends)) {
       return false;
     }
   }
@@ -256,22 +254,22 @@
     std::string fname = targetDir + "/fortran.internal";
     cmsys::ifstream fin(fname.c_str());
     if (fin) {
-      this->MatchRemoteModules(fin, targetDir.c_str());
+      this->MatchRemoteModules(fin, targetDir);
     }
   }
 }
 
 void cmDependsFortran::MatchLocalModules()
 {
-  const char* stampDir = this->TargetDirectory.c_str();
+  std::string const& stampDir = this->TargetDirectory;
   std::set<std::string> const& provides = this->Internal->TargetProvides;
   for (std::string const& i : provides) {
-    this->ConsiderModule(i.c_str(), stampDir);
+    this->ConsiderModule(i, stampDir);
   }
 }
 
 void cmDependsFortran::MatchRemoteModules(std::istream& fin,
-                                          const char* stampDir)
+                                          const std::string& stampDir)
 {
   std::string line;
   bool doing_provides = false;
@@ -300,7 +298,8 @@
   }
 }
 
-void cmDependsFortran::ConsiderModule(const char* name, const char* stampDir)
+void cmDependsFortran::ConsiderModule(const std::string& name,
+                                      const std::string& stampDir)
 {
   // Locate each required module.
   typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
@@ -317,17 +316,17 @@
   }
 }
 
-bool cmDependsFortran::WriteDependenciesReal(const char* obj,
+bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
                                              cmFortranSourceInfo const& info,
                                              std::string const& mod_dir,
-                                             const char* stamp_dir,
+                                             std::string const& stamp_dir,
                                              std::ostream& makeDepends,
                                              std::ostream& internalDepends)
 {
   typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
 
   // Get the source file for this object.
-  const char* src = info.Source.c_str();
+  std::string const& src = info.Source;
 
   // Write the include dependencies to the output stream.
   std::string binDir = this->LocalGenerator->GetBinaryDirectory();
@@ -502,8 +501,7 @@
   cmFortranModuleAppendUpperLower(cmSystemTools::GetFilenameName(mod),
                                   mod_upper, mod_lower);
   if (cmSystemTools::FileExists(mod_upper, true)) {
-    if (cmDependsFortran::ModulesDiffer(mod_upper.c_str(), stamp.c_str(),
-                                        compilerId.c_str())) {
+    if (cmDependsFortran::ModulesDiffer(mod_upper, stamp, compilerId)) {
       if (!cmSystemTools::CopyFileAlways(mod_upper, stamp)) {
         std::cerr << "Error copying Fortran module from \"" << mod_upper
                   << "\" to \"" << stamp << "\".\n";
@@ -513,8 +511,7 @@
     return true;
   }
   if (cmSystemTools::FileExists(mod_lower, true)) {
-    if (cmDependsFortran::ModulesDiffer(mod_lower.c_str(), stamp.c_str(),
-                                        compilerId.c_str())) {
+    if (cmDependsFortran::ModulesDiffer(mod_lower, stamp, compilerId)) {
       if (!cmSystemTools::CopyFileAlways(mod_lower, stamp)) {
         std::cerr << "Error copying Fortran module from \"" << mod_lower
                   << "\" to \"" << stamp << "\".\n";
@@ -581,9 +578,9 @@
   return true;
 }
 
-bool cmDependsFortran::ModulesDiffer(const char* modFile,
-                                     const char* stampFile,
-                                     const char* compilerId)
+bool cmDependsFortran::ModulesDiffer(const std::string& modFile,
+                                     const std::string& stampFile,
+                                     const std::string& compilerId)
 {
   /*
   gnu >= 4.9:
@@ -617,16 +614,17 @@
    * source is compiled twice
    *   -SunPro
    */
-  if (strcmp(compilerId, "SunPro") == 0) {
+  if (compilerId == "SunPro") {
     return cmSystemTools::FilesDiffer(modFile, stampFile);
   }
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-  cmsys::ifstream finModFile(modFile, std::ios::in | std::ios::binary);
-  cmsys::ifstream finStampFile(stampFile, std::ios::in | std::ios::binary);
+  cmsys::ifstream finModFile(modFile.c_str(), std::ios::in | std::ios::binary);
+  cmsys::ifstream finStampFile(stampFile.c_str(),
+                               std::ios::in | std::ios::binary);
 #else
-  cmsys::ifstream finModFile(modFile);
-  cmsys::ifstream finStampFile(stampFile);
+  cmsys::ifstream finModFile(modFile.c_str());
+  cmsys::ifstream finStampFile(stampFile.c_str());
 #endif
   if (!finModFile || !finStampFile) {
     // At least one of the files does not exist.  The modules differ.
@@ -641,7 +639,7 @@
    * Eat the stream content until all recompile only related changes
    * are left behind.
    */
-  if (strcmp(compilerId, "GNU") == 0) {
+  if (compilerId == "GNU") {
     // GNU Fortran 4.9 and later compress .mod files with gzip
     // but also do not include a date so we can fall through to
     // compare them without skipping any prefix.
@@ -664,7 +662,7 @@
         return true;
       }
     }
-  } else if (strcmp(compilerId, "Intel") == 0) {
+  } else if (compilerId == "Intel") {
     const char seq[2] = { '\n', '\0' };
     const int seqlen = 2;
 
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 5d96dd4..f5f5be2 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -44,8 +44,9 @@
 
   /** Determine if a mod file and the corresponding mod.stamp file
       are representing  different module information. */
-  static bool ModulesDiffer(const char* modFile, const char* stampFile,
-                            const char* compilerId);
+  static bool ModulesDiffer(const std::string& modFile,
+                            const std::string& stampFile,
+                            const std::string& compilerId);
 
 protected:
   // Finalize the dependency information for the target.
@@ -55,8 +56,8 @@
   // Find all the modules required by the target.
   void LocateModules();
   void MatchLocalModules();
-  void MatchRemoteModules(std::istream& fin, const char* stampDir);
-  void ConsiderModule(const char* name, const char* stampDir);
+  void MatchRemoteModules(std::istream& fin, const std::string& stampDir);
+  void ConsiderModule(const std::string& name, const std::string& stampDir);
   bool FindModule(std::string const& name, std::string& module);
 
   // Implement writing/checking methods required by superclass.
@@ -65,8 +66,10 @@
                          std::ostream& internalDepends) override;
 
   // Actually write the dependencies to the streams.
-  bool WriteDependenciesReal(const char* obj, cmFortranSourceInfo const& info,
-                             std::string const& mod_dir, const char* stamp_dir,
+  bool WriteDependenciesReal(std::string const& obj,
+                             cmFortranSourceInfo const& info,
+                             std::string const& mod_dir,
+                             std::string const& stamp_dir,
                              std::ostream& makeDepends,
                              std::ostream& internalDepends);
 
diff --git a/Source/cmDependsJava.cxx b/Source/cmDependsJava.cxx
index 29938ba..b44b3a2 100644
--- a/Source/cmDependsJava.cxx
+++ b/Source/cmDependsJava.cxx
@@ -27,7 +27,8 @@
 }
 
 bool cmDependsJava::CheckDependencies(
-  std::istream& /*internalDepends*/, const char* /*internalDependsFileName*/,
+  std::istream& /*internalDepends*/,
+  const std::string& /*internalDependsFileName*/,
   std::map<std::string, DependencyVector>& /*validDeps*/)
 {
   return true;
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
index d070840..1928c51 100644
--- a/Source/cmDependsJava.h
+++ b/Source/cmDependsJava.h
@@ -33,7 +33,7 @@
                          const std::string& file, std::ostream& makeDepends,
                          std::ostream& internalDepends) override;
   bool CheckDependencies(
-    std::istream& internalDepends, const char* internalDependsFileName,
+    std::istream& internalDepends, const std::string& internalDependsFileName,
     std::map<std::string, DependencyVector>& validDeps) override;
 };
 
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index ea4cd40..75a7786 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -217,11 +217,11 @@
   int p;
   cmProcessOutput processOutput(encoding);
   std::string strdata;
-  while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
+  while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
     if (p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR) {
       if (verbose) {
         processOutput.DecodeText(data, length, strdata);
-        cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+        cmSystemTools::Stdout(strdata);
       }
       output.append(data, length);
     }
@@ -230,7 +230,7 @@
   if (verbose) {
     processOutput.DecodeText(std::string(), strdata);
     if (!strdata.empty()) {
-      cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+      cmSystemTools::Stdout(strdata);
     }
   }
 
@@ -270,7 +270,7 @@
     }
     msg += "\n";
     if (verbose) {
-      cmSystemTools::Stdout(msg.c_str());
+      cmSystemTools::Stdout(msg);
     }
     output += msg;
 #else
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 8de012a..8c67cdb 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -244,19 +244,19 @@
   int p;
   cmProcessOutput processOutput(encoding);
   std::string strdata;
-  while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
+  while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
     // Put the output in the right place.
     if (p == cmsysProcess_Pipe_STDOUT && !output_quiet) {
       if (output_variable.empty()) {
         processOutput.DecodeText(data, length, strdata, 1);
-        cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+        cmSystemTools::Stdout(strdata);
       } else {
         cmExecuteProcessCommandAppend(tempOutput, data, length);
       }
     } else if (p == cmsysProcess_Pipe_STDERR && !error_quiet) {
       if (error_variable.empty()) {
         processOutput.DecodeText(data, length, strdata, 2);
-        cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+        cmSystemTools::Stderr(strdata);
       } else {
         cmExecuteProcessCommandAppend(tempError, data, length);
       }
@@ -265,13 +265,13 @@
   if (!output_quiet && output_variable.empty()) {
     processOutput.DecodeText(std::string(), strdata, 1);
     if (!strdata.empty()) {
-      cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+      cmSystemTools::Stdout(strdata);
     }
   }
   if (!error_quiet && error_variable.empty()) {
     processOutput.DecodeText(std::string(), strdata, 2);
     if (!strdata.empty()) {
-      cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+      cmSystemTools::Stderr(strdata);
     }
   }
 
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index 4e3e770..d4f772b 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -30,13 +30,20 @@
   virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
 
   /** Get the names of the current registered generators */
-  virtual void GetGenerators(std::vector<std::string>& names) const = 0;
+  virtual std::vector<std::string> GetGeneratorNames() const = 0;
+  virtual std::vector<std::string> GetGeneratorNamesWithPlatform() const = 0;
 
   /** Determine whether or not this generator supports toolsets */
   virtual bool SupportsToolset() const = 0;
 
   /** Determine whether or not this generator supports platforms */
   virtual bool SupportsPlatform() const = 0;
+
+  /** Get the list of supported platforms name for this generator */
+  virtual std::vector<std::string> GetKnownPlatforms() const = 0;
+
+  /** If the generator suports platforms, get its default.  */
+  virtual std::string GetDefaultPlatformName() const = 0;
 };
 
 template <class T>
@@ -60,9 +67,15 @@
   }
 
   /** Get the names of the current registered generators */
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(T::GetActualName());
+    return names;
+  }
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    return std::vector<std::string>();
   }
 
   /** Determine whether or not this generator supports toolsets */
@@ -70,6 +83,15 @@
 
   /** Determine whether or not this generator supports platforms */
   bool SupportsPlatform() const override { return T::SupportsPlatform(); }
+
+  /** Get the list of supported platforms name for this generator */
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    // default is no platform supported
+    return std::vector<std::string>();
+  }
+
+  std::string GetDefaultPlatformName() const override { return std::string(); }
 };
 
 #endif
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 79757a8..dbe582b 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -74,15 +74,34 @@
                   "Optional [arch] can be \"Win64\" or \"IA64\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs10generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    std::vector<std::string> names;
     names.push_back(vs10generatorName + std::string(" IA64"));
     names.push_back(vs10generatorName + std::string(" Win64"));
+    return names;
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("Itanium");
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override { return "Win32"; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 36eb492..4eb78ba 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -69,9 +69,16 @@
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs11generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    std::vector<std::string> names;
     names.push_back(vs11generatorName + std::string(" ARM"));
     names.push_back(vs11generatorName + std::string(" Win64"));
 
@@ -80,10 +87,30 @@
     for (std::string const& i : installedSDKs) {
       names.push_back(std::string(vs11generatorName) + " " + i);
     }
+
+    return names;
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("ARM");
+
+    std::set<std::string> installedSDKs =
+      cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
+    for (std::string const& i : installedSDKs) {
+      platforms.emplace_back(i);
+    }
+
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override { return "Win32"; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 61034a7..8b50684 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -58,15 +58,34 @@
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs12generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    std::vector<std::string> names;
     names.push_back(vs12generatorName + std::string(" ARM"));
     names.push_back(vs12generatorName + std::string(" Win64"));
+    return names;
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("ARM");
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override { return "Win32"; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 5ea5e67..a0a9558 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -58,15 +58,34 @@
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs14generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    std::vector<std::string> names;
     names.push_back(vs14generatorName + std::string(" ARM"));
     names.push_back(vs14generatorName + std::string(" Win64"));
+    return names;
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("ARM");
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override { return "Win32"; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index 445b40c..6e61d26 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -59,9 +59,16 @@
                   "Optional [arch] can be \"Win64\" or \"IA64\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs9generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    std::vector<std::string> names;
     names.push_back(vs9generatorName + std::string(" Win64"));
     names.push_back(vs9generatorName + std::string(" IA64"));
     cmVisualStudioWCEPlatformParser parser;
@@ -71,10 +78,29 @@
     for (std::string const& i : availablePlatforms) {
       names.push_back("Visual Studio 9 2008 " + i);
     }
+    return names;
   }
 
   bool SupportsToolset() const override { return false; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("Itanium");
+    cmVisualStudioWCEPlatformParser parser;
+    parser.ParseVersion("9.0");
+    const std::vector<std::string>& availablePlatforms =
+      parser.GetAvailablePlatforms();
+    for (std::string const& i : availablePlatforms) {
+      platforms.emplace_back(i);
+    }
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override { return "Win32"; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 99f9503..31f585c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -19,6 +19,20 @@
 #  include "cmsys/SystemInformation.hxx"
 #endif
 
+static std::string VSHostPlatformName()
+{
+#ifdef HOST_PLATFORM_NAME
+  return HOST_PLATFORM_NAME;
+#else
+  cmsys::SystemInformation info;
+  if (info.Is64Bits()) {
+    return "x64";
+  } else {
+    return "Win32";
+  }
+#endif
+}
+
 static unsigned int VSVersionToMajor(
   cmGlobalVisualStudioGenerator::VSVersion v)
 {
@@ -118,15 +132,35 @@
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs15generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    std::vector<std::string> names;
     names.push_back(vs15generatorName + std::string(" ARM"));
     names.push_back(vs15generatorName + std::string(" Win64"));
+    return names;
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("ARM");
+    platforms.emplace_back("ARM64");
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override { return "Win32"; }
 };
 
 cmGlobalGeneratorFactory*
@@ -178,13 +212,35 @@
                   "Use -A option to specify architecture.";
   }
 
-  virtual void GetGenerators(std::vector<std::string>& names) const
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(vs16generatorName);
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    return std::vector<std::string>();
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return true; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    std::vector<std::string> platforms;
+    platforms.emplace_back("x64");
+    platforms.emplace_back("Win32");
+    platforms.emplace_back("ARM");
+    platforms.emplace_back("ARM64");
+    return platforms;
+  }
+
+  std::string GetDefaultPlatformName() const override
+  {
+    return VSHostPlatformName();
+  }
 };
 
 cmGlobalGeneratorFactory*
@@ -206,16 +262,7 @@
   this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
   if (this->Version >= cmGlobalVisualStudioGenerator::VS16) {
-#ifdef HOST_PLATFORM_NAME
-    this->DefaultPlatformName = HOST_PLATFORM_NAME;
-#else
-    cmsys::SystemInformation info;
-    if (info.Is64Bits()) {
-      this->DefaultPlatformName = "x64";
-    } else {
-      this->DefaultPlatformName = "Win32";
-    }
-#endif
+    this->DefaultPlatformName = VSHostPlatformName();
   }
 }
 
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 80ccd73..79d77e7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -133,13 +133,27 @@
     cmGlobalXCodeGenerator::GetDocumentation(entry);
   }
 
-  void GetGenerators(std::vector<std::string>& names) const override
+  std::vector<std::string> GetGeneratorNames() const override
   {
+    std::vector<std::string> names;
     names.push_back(cmGlobalXCodeGenerator::GetActualName());
+    return names;
+  }
+
+  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+  {
+    return std::vector<std::string>();
   }
 
   bool SupportsToolset() const override { return true; }
   bool SupportsPlatform() const override { return false; }
+
+  std::vector<std::string> GetKnownPlatforms() const override
+  {
+    return std::vector<std::string>();
+  }
+
+  std::string GetDefaultPlatformName() const override { return std::string(); }
 };
 
 cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(
@@ -177,12 +191,14 @@
   std::string versionFile;
   {
     std::string out;
-    std::string::size_type pos = 0;
-    if (cmSystemTools::RunSingleCommand("xcode-select --print-path", &out,
-                                        nullptr, nullptr, nullptr,
-                                        cmSystemTools::OUTPUT_NONE) &&
-        (pos = out.find(".app/"), pos != std::string::npos)) {
-      versionFile = out.substr(0, pos + 5) + "Contents/version.plist";
+    bool commandResult = cmSystemTools::RunSingleCommand(
+      "xcode-select --print-path", &out, nullptr, nullptr, nullptr,
+      cmSystemTools::OUTPUT_NONE);
+    if (commandResult) {
+      std::string::size_type pos = out.find(".app/");
+      if (pos != std::string::npos) {
+        versionFile = out.substr(0, pos + 5) + "Contents/version.plist";
+      }
     }
   }
   if (!versionFile.empty() && cmSystemTools::FileExists(versionFile.c_str())) {
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index e590e52..5b9d108 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1286,7 +1286,7 @@
         std::ostringstream msg;
         msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
             << internalDependFile << "\"." << std::endl;
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       needRescanDependInfo = true;
     }
@@ -1307,7 +1307,7 @@
         std::ostringstream msg;
         msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \""
             << internalDependFile << "\"." << std::endl;
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       needRescanDirInfo = true;
     }
@@ -1333,8 +1333,8 @@
     // dependency vector. This means that in the normal case, when only
     // few or one file have been edited, then also only this one file is
     // actually scanned again, instead of all files for this target.
-    needRescanDependencies = !checker.Check(
-      dependFile.c_str(), internalDependFile.c_str(), validDependencies);
+    needRescanDependencies =
+      !checker.Check(dependFile, internalDependFile, validDependencies);
   }
 
   if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
@@ -1347,7 +1347,7 @@
                                        cmsysTerminal_Color_ForegroundBold,
                                      message.c_str(), true, color);
 
-    return this->ScanDependencies(dir.c_str(), validDependencies);
+    return this->ScanDependencies(dir, validDependencies);
   }
 
   // The dependencies are already up-to-date.
@@ -1355,7 +1355,7 @@
 }
 
 bool cmLocalUnixMakefileGenerator3::ScanDependencies(
-  const char* targetDir,
+  const std::string& targetDir,
   std::map<std::string, cmDepends::DependencyVector>& validDeps)
 {
   // Read the directory information file.
@@ -1392,12 +1392,9 @@
     cmSystemTools::Error("Directory Information file not found");
   }
 
-  // create the file stream for the depends file
-  std::string dir = targetDir;
-
   // Open the make depends file.  This should be copy-if-different
   // because the make tool may try to reload it needlessly otherwise.
-  std::string ruleFileNameFull = dir;
+  std::string ruleFileNameFull = targetDir;
   ruleFileNameFull += "/depend.make";
   cmGeneratedFileStream ruleFileStream(
     ruleFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
@@ -1409,7 +1406,7 @@
   // Open the cmake dependency tracking file.  This should not be
   // copy-if-different because dependencies are re-scanned when it is
   // older than the DependInfo.cmake.
-  std::string internalRuleFileNameFull = dir;
+  std::string internalRuleFileNameFull = targetDir;
   internalRuleFileNameFull += "/depend.internal";
   cmGeneratedFileStream internalRuleFileStream(
     internalRuleFileNameFull, false,
@@ -1450,7 +1447,7 @@
       scanner->SetFileComparison(
         this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
       scanner->SetLanguage(lang);
-      scanner->SetTargetDirectory(dir.c_str());
+      scanner->SetTargetDirectory(targetDir);
       scanner->Write(ruleFileStream, internalRuleFileStream);
 
       // free the scanner for this language
@@ -1488,7 +1485,7 @@
         msg << "Deleting primary custom command output \"" << dependee
             << "\" because another output \"" << depender
             << "\" does not exist." << std::endl;
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       cmSystemTools::RemoveFile(dependee);
     }
@@ -1719,7 +1716,7 @@
 
     // Clear the implicit dependency makefile.
     std::string dependFile = dir + "/depend.make";
-    clearer.Clear(dependFile.c_str());
+    clearer.Clear(dependFile);
 
     // Remove the internal dependency check file to force
     // regeneration.
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index ee6b37b..c0d0e13 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -245,7 +245,7 @@
 
   // Helper methods for dependency updates.
   bool ScanDependencies(
-    const char* targetDir,
+    const std::string& targetDir,
     std::map<std::string, cmDepends::DependencyVector>& validDeps);
   void CheckMultipleOutputs(bool verbose);
 
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index facde5d..a2bc16f 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -16,7 +16,7 @@
   cmProcessOutput processOutput(encoding);
   std::string strdata;
   while ((out || err) &&
-         (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
+         (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
     if (out && p == cmsysProcess_Pipe_STDOUT) {
       processOutput.DecodeText(data, length, strdata, 1);
       if (!out->Process(strdata.c_str(), int(strdata.size()))) {
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index c5d5d7c..e2d7deb 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -54,7 +54,7 @@
   }
   {
     std::lock_guard<std::mutex> lock(Mutex_);
-    cmSystemTools::Stdout(msg.c_str(), msg.size());
+    cmSystemTools::Stdout(msg);
   }
 }
 
@@ -78,7 +78,7 @@
   msg.push_back('\n');
   {
     std::lock_guard<std::mutex> lock(Mutex_);
-    cmSystemTools::Stdout(msg.c_str(), msg.size());
+    cmSystemTools::Stdout(msg);
   }
 }
 
@@ -107,7 +107,7 @@
   msg.push_back('\n');
   {
     std::lock_guard<std::mutex> lock(Mutex_);
-    cmSystemTools::Stderr(msg.c_str(), msg.size());
+    cmSystemTools::Stderr(msg);
   }
 }
 
@@ -149,7 +149,7 @@
   msg.push_back('\n');
   {
     std::lock_guard<std::mutex> lock(Mutex_);
-    cmSystemTools::Stderr(msg.c_str(), msg.size());
+    cmSystemTools::Stderr(msg);
   }
 }
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 71a9cb4..9abc5f3 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -302,33 +302,21 @@
   s_StderrCallbackClientData = clientData;
 }
 
-void cmSystemTools::Stdout(const char* s)
-{
-  cmSystemTools::Stdout(s, strlen(s));
-}
-
-void cmSystemTools::Stderr(const char* s)
-{
-  cmSystemTools::Stderr(s, strlen(s));
-}
-
-void cmSystemTools::Stderr(const char* s, size_t length)
+void cmSystemTools::Stderr(const std::string& s)
 {
   if (s_StderrCallback) {
-    (*s_StderrCallback)(s, length, s_StderrCallbackClientData);
+    (*s_StderrCallback)(s.c_str(), s.length(), s_StderrCallbackClientData);
   } else {
-    std::cerr.write(s, length);
-    std::cerr.flush();
+    std::cerr << s << std::flush;
   }
 }
 
-void cmSystemTools::Stdout(const char* s, size_t length)
+void cmSystemTools::Stdout(const std::string& s)
 {
   if (s_StdoutCallback) {
-    (*s_StdoutCallback)(s, length, s_StdoutCallbackClientData);
+    (*s_StdoutCallback)(s.c_str(), s.length(), s_StdoutCallbackClientData);
   } else {
-    std::cout.write(s, length);
-    std::cout.flush();
+    std::cout << s << std::flush;
   }
 }
 
@@ -792,7 +780,7 @@
       if (pipe == cmsysProcess_Pipe_STDOUT) {
         if (outputflag != OUTPUT_NONE) {
           processOutput.DecodeText(data, length, strdata, 1);
-          cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+          cmSystemTools::Stdout(strdata);
         }
         if (captureStdOut) {
           tempStdOut.insert(tempStdOut.end(), data, data + length);
@@ -800,7 +788,7 @@
       } else if (pipe == cmsysProcess_Pipe_STDERR) {
         if (outputflag != OUTPUT_NONE) {
           processOutput.DecodeText(data, length, strdata, 2);
-          cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+          cmSystemTools::Stderr(strdata);
         }
         if (captureStdErr) {
           tempStdErr.insert(tempStdErr.end(), data, data + length);
@@ -811,11 +799,11 @@
     if (outputflag != OUTPUT_NONE) {
       processOutput.DecodeText(std::string(), strdata, 1);
       if (!strdata.empty()) {
-        cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+        cmSystemTools::Stdout(strdata);
       }
       processOutput.DecodeText(std::string(), strdata, 2);
       if (!strdata.empty()) {
-        cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+        cmSystemTools::Stderr(strdata);
       }
     }
   }
@@ -1899,13 +1887,13 @@
     if (verbose) {
       if (extract) {
         cmSystemTools::Stdout("x ");
-        cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
+        cmSystemTools::Stdout(cm_archive_entry_pathname(entry));
       } else {
         list_item_verbose(stdout, entry);
       }
       cmSystemTools::Stdout("\n");
     } else if (!extract) {
-      cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
+      cmSystemTools::Stdout(cm_archive_entry_pathname(entry));
       cmSystemTools::Stdout("\n");
     }
     if (extract) {
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 489811d..7a209c6 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -79,13 +79,11 @@
   typedef void (*OutputCallback)(const char*, size_t length, void*);
 
   ///! Send a string to stdout
-  static void Stdout(const char* s);
-  static void Stdout(const char* s, size_t length);
+  static void Stdout(const std::string& s);
   static void SetStdoutCallback(OutputCallback, void* clientData = nullptr);
 
   ///! Send a string to stderr
-  static void Stderr(const char* s);
-  static void Stderr(const char* s, size_t length);
+  static void Stderr(const std::string& s);
   static void SetStderrCallback(OutputCallback, void* clientData = nullptr);
 
   typedef bool (*InterruptCallback)(void*);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index b97feab..b44c325 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -959,17 +959,25 @@
 #endif
 }
 
-void cmake::GetRegisteredGenerators(
-  std::vector<GeneratorInfo>& generators) const
+void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
+                                    bool includeNamesWithPlatform) const
 {
   for (cmGlobalGeneratorFactory* gen : this->Generators) {
-    std::vector<std::string> names;
-    gen->GetGenerators(names);
+    std::vector<std::string> names = gen->GetGeneratorNames();
+
+    if (includeNamesWithPlatform) {
+      std::vector<std::string> namesWithPlatform =
+        gen->GetGeneratorNamesWithPlatform();
+      names.insert(names.end(), namesWithPlatform.begin(),
+                   namesWithPlatform.end());
+    }
 
     for (std::string const& name : names) {
       GeneratorInfo info;
       info.supportsToolset = gen->SupportsToolset();
       info.supportsPlatform = gen->SupportsPlatform();
+      info.supportedPlatforms = gen->GetKnownPlatforms();
+      info.defaultPlatform = gen->GetDefaultPlatformName();
       info.name = name;
       info.baseName = name;
       info.isAlias = false;
@@ -2006,7 +2014,7 @@
     if (verbose) {
       std::ostringstream msg;
       msg << "Re-run cmake no build system arguments\n";
-      cmSystemTools::Stdout(msg.str().c_str());
+      cmSystemTools::Stdout(msg.str());
     }
     return 1;
   }
@@ -2017,7 +2025,7 @@
       std::ostringstream msg;
       msg << "Re-run cmake missing file: " << this->CheckBuildSystemArgument
           << "\n";
-      cmSystemTools::Stdout(msg.str().c_str());
+      cmSystemTools::Stdout(msg.str());
     }
     return 1;
   }
@@ -2037,7 +2045,7 @@
       std::ostringstream msg;
       msg << "Re-run cmake error reading : " << this->CheckBuildSystemArgument
           << "\n";
-      cmSystemTools::Stdout(msg.str().c_str());
+      cmSystemTools::Stdout(msg.str());
     }
     // There was an error reading the file.  Just rerun.
     return 1;
@@ -2071,7 +2079,7 @@
       if (verbose) {
         std::ostringstream msg;
         msg << "Re-run cmake, missing byproduct: " << p << "\n";
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       return 1;
     }
@@ -2092,7 +2100,7 @@
       std::ostringstream msg;
       msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
              "or CMAKE_MAKEFILE_OUTPUTS :\n";
-      cmSystemTools::Stdout(msg.str().c_str());
+      cmSystemTools::Stdout(msg.str());
     }
     return 1;
   }
@@ -2111,7 +2119,7 @@
       if (verbose) {
         std::ostringstream msg;
         msg << "Re-run cmake: build system dependency is missing\n";
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       return 1;
     }
@@ -2131,7 +2139,7 @@
       if (verbose) {
         std::ostringstream msg;
         msg << "Re-run cmake: build system output is missing\n";
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       return 1;
     }
@@ -2147,7 +2155,7 @@
         std::ostringstream msg;
         msg << "Re-run cmake file: " << out_oldest
             << " older than: " << dep_newest << "\n";
-        cmSystemTools::Stdout(msg.str().c_str());
+        cmSystemTools::Stdout(msg.str());
       }
       return 1;
     }
diff --git a/Source/cmake.h b/Source/cmake.h
index cd8c622..38d0c62 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -104,6 +104,8 @@
     std::string extraName;
     bool supportsToolset;
     bool supportsPlatform;
+    std::vector<std::string> supportedPlatforms;
+    std::string defaultPlatform;
     bool isAlias;
   };
 
@@ -196,7 +198,8 @@
   void SetGlobalGenerator(cmGlobalGenerator*);
 
   ///! Get the names of the current registered generators
-  void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators) const;
+  void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
+                               bool includeNamesWithPlatform = true) const;
 
   ///! Set the name of the selected generator-specific instance.
   void SetGeneratorInstance(std::string const& instance)