1
0
Эх сурвалжийг харах

cmLocalGenerator: modernize memory management

Marc Chevrier 5 жил өмнө
parent
commit
36c8cae2e8
32 өөрчлөгдсөн 331 нэмэгдсэн , 304 устгасан
  1. 2 3
      Source/cmComputeTargetDepends.cxx
  2. 2 3
      Source/cmExtraCodeLiteGenerator.cxx
  3. 19 19
      Source/cmExtraEclipseCDT4Generator.cxx
  4. 1 1
      Source/cmExtraEclipseCDT4Generator.h
  5. 18 20
      Source/cmExtraKateGenerator.cxx
  6. 4 4
      Source/cmExtraKateGenerator.h
  7. 2 1
      Source/cmFileAPICMakeFiles.cxx
  8. 4 4
      Source/cmFileAPICodemodel.cxx
  9. 8 5
      Source/cmGlobalBorlandMakefileGenerator.cxx
  10. 3 1
      Source/cmGlobalBorlandMakefileGenerator.h
  11. 2 2
      Source/cmGlobalCommonGenerator.cxx
  12. 33 35
      Source/cmGlobalGenerator.cxx
  13. 7 5
      Source/cmGlobalGenerator.h
  14. 6 3
      Source/cmGlobalGhsMultiGenerator.cxx
  15. 3 1
      Source/cmGlobalGhsMultiGenerator.h
  16. 17 16
      Source/cmGlobalNinjaGenerator.cxx
  17. 2 6
      Source/cmGlobalNinjaGenerator.h
  18. 134 129
      Source/cmGlobalUnixMakefileGenerator3.cxx
  19. 8 5
      Source/cmGlobalUnixMakefileGenerator3.h
  20. 6 3
      Source/cmGlobalVisualStudio10Generator.cxx
  21. 4 1
      Source/cmGlobalVisualStudio10Generator.h
  22. 7 6
      Source/cmGlobalVisualStudio7Generator.cxx
  23. 4 1
      Source/cmGlobalVisualStudio7Generator.h
  24. 17 15
      Source/cmGlobalVisualStudio8Generator.cxx
  25. 5 3
      Source/cmGlobalXCodeGenerator.cxx
  26. 3 1
      Source/cmGlobalXCodeGenerator.h
  27. 1 1
      Source/cmGraphVizWriter.cxx
  28. 1 2
      Source/cmLocalUnixMakefileGenerator3.cxx
  29. 4 4
      Source/cmQtAutoGenGlobalInitializer.cxx
  30. 1 1
      Source/cmQtAutoGenGlobalInitializer.h
  31. 2 2
      Source/cmake.cxx
  32. 1 1
      Source/cmcmd.cxx

+ 2 - 3
Source/cmComputeTargetDepends.cxx

@@ -158,9 +158,8 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
 void cmComputeTargetDepends::CollectTargets()
 {
   // Collect all targets from all generators.
-  std::vector<cmLocalGenerator*> const& lgens =
-    this->GlobalGenerator->GetLocalGenerators();
-  for (cmLocalGenerator* lgen : lgens) {
+  auto const& lgens = this->GlobalGenerator->GetLocalGenerators();
+  for (const auto& lgen : lgens) {
     for (const auto& ti : lgen->GetGeneratorTargets()) {
       int index = static_cast<int>(this->Targets.size());
       this->TargetIndex[ti.get()] = index;

+ 2 - 3
Source/cmExtraCodeLiteGenerator.cxx

@@ -117,9 +117,8 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
 {
   std::vector<std::string> retval;
   // for each target in the workspace create a codelite project
-  const std::vector<cmLocalGenerator*>& lgs =
-    this->GlobalGenerator->GetLocalGenerators();
-  for (cmLocalGenerator* lg : lgs) {
+  const auto& lgs = this->GlobalGenerator->GetLocalGenerators();
+  for (const auto& lg : lgs) {
     for (const auto& lt : lg->GetGeneratorTargets()) {
       cmStateEnums::TargetType type = lt->GetType();
       std::string const& outputDir = lg->GetCurrentBinaryDirectory();

+ 19 - 19
Source/cmExtraEclipseCDT4Generator.cxx

@@ -99,7 +99,7 @@ void cmExtraEclipseCDT4Generator::EnableLanguage(
 
 void cmExtraEclipseCDT4Generator::Generate()
 {
-  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+  const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   const cmMakefile* mf = lg->GetMakefile();
 
   std::string eclipseVersion = mf->GetSafeDefinition("CMAKE_ECLIPSE_VERSION");
@@ -176,7 +176,7 @@ void cmExtraEclipseCDT4Generator::Generate()
 
 void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile()
 {
-  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+  const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   cmMakefile* mf = lg->GetMakefile();
 
   const std::string filename =
@@ -199,7 +199,7 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
   assert(this->HomeDirectory != this->HomeOutputDirectory);
 
   // set up the project name: <project>-Source@<baseSourcePathName>
-  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+  const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   std::string name = cmExtraEclipseCDT4Generator::GenerateProjectName(
     lg->GetProjectName(), "Source",
     cmExtraEclipseCDT4Generator::GetPathBasename(this->HomeDirectory));
@@ -232,9 +232,9 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
 
 void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
                                             const char* envVar,
-                                            cmLocalGenerator* lg)
+                                            cmLocalGenerator& lg)
 {
-  cmMakefile* mf = lg->GetMakefile();
+  cmMakefile* mf = lg.GetMakefile();
 
   // get the variables from the environment and from the cache and then
   // figure out which one to use:
@@ -244,7 +244,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
 
   std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar);
   const std::string* cacheValue =
-    lg->GetState()->GetInitializedCacheValue(cacheEntryName);
+    lg.GetState()->GetInitializedCacheValue(cacheEntryName);
 
   // now we have both, decide which one to use
   std::string valueToUse;
@@ -257,7 +257,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
     valueToUse = envVarValue;
     mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
                            cacheEntryName.c_str(), cmStateEnums::STRING, true);
-    mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
+    mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
   } else if (!envVarSet && cacheValue != nullptr) {
     // It is already in the cache, but not in the env, so use it from the cache
     valueToUse = *cacheValue;
@@ -273,7 +273,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
       mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
                              cacheEntryName.c_str(), cmStateEnums::STRING,
                              true);
-      mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
+      mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
     }
   }
 
@@ -284,7 +284,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
 
 void cmExtraEclipseCDT4Generator::CreateProjectFile()
 {
-  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+  const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   cmMakefile* mf = lg->GetMakefile();
 
   const std::string filename = this->HomeOutputDirectory + "/.project";
@@ -351,15 +351,15 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
   // set vsvars32.bat environment available at CMake time,
   //   but not necessarily when eclipse is open
   if (compilerId == "MSVC") {
-    AddEnvVar(environment, "PATH", lg);
-    AddEnvVar(environment, "INCLUDE", lg);
-    AddEnvVar(environment, "LIB", lg);
-    AddEnvVar(environment, "LIBPATH", lg);
+    AddEnvVar(environment, "PATH", *lg);
+    AddEnvVar(environment, "INCLUDE", *lg);
+    AddEnvVar(environment, "LIB", *lg);
+    AddEnvVar(environment, "LIBPATH", *lg);
   } else if (compilerId == "Intel") {
     // if the env.var is set, use this one and put it in the cache
     // if the env.var is not set, but the value is in the cache,
     // use it from the cache:
-    AddEnvVar(environment, "INTEL_LICENSE_FILE", lg);
+    AddEnvVar(environment, "INTEL_LICENSE_FILE", *lg);
   }
   AppendDictionary(xml, "org.eclipse.cdt.make.core.environment",
                    environment.str());
@@ -495,7 +495,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
   cmExtraEclipseCDT4Generator::AppendLinkedResource(
     xml, linkName, "virtual:/virtual", VirtualFolder);
 
-  for (cmLocalGenerator* lg : this->GlobalGenerator->GetLocalGenerators()) {
+  for (const auto& lg : this->GlobalGenerator->GetLocalGenerators()) {
     cmMakefile* makefile = lg->GetMakefile();
     const auto& targets = lg->GetGeneratorTargets();
 
@@ -606,7 +606,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 {
   std::set<std::string> emmited;
 
-  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+  const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   const cmMakefile* mf = lg->GetMakefile();
 
   const std::string filename = this->HomeOutputDirectory + "/.cproject";
@@ -752,7 +752,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 
   // add pre-processor definitions to allow eclipse to gray out sections
   emmited.clear();
-  for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
+  for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
 
     if (const char* cdefs =
           lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) {
@@ -859,7 +859,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 
   // include dirs
   emmited.clear();
-  for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
+  for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
     const auto& targets = lgen->GetGeneratorTargets();
     for (const auto& target : targets) {
       if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -914,7 +914,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 
   // add all executable and library targets and some of the GLOBAL
   // and UTILITY targets
-  for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
+  for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
     const auto& targets = lgen->GetGeneratorTargets();
     std::string subdir = lgen->MaybeConvertToRelativePath(
       this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory());

+ 1 - 1
Source/cmExtraEclipseCDT4Generator.h

@@ -86,7 +86,7 @@ private:
     std::set<std::string>& emittedDirs);
 
   static void AddEnvVar(std::ostream& out, const char* envVar,
-                        cmLocalGenerator* lg);
+                        cmLocalGenerator& lg);
 
   void WriteGroups(std::vector<cmSourceGroup> const& sourceGroups,
                    std::string& linkName, cmXMLWriter& xml);

+ 18 - 20
Source/cmExtraKateGenerator.cxx

@@ -41,21 +41,21 @@ cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory()
 
 void cmExtraKateGenerator::Generate()
 {
-  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+  const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   const cmMakefile* mf = lg->GetMakefile();
   this->ProjectName = this->GenerateProjectName(
     lg->GetProjectName(), mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
     this->GetPathBasename(lg->GetBinaryDirectory()));
   this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");
 
-  this->CreateKateProjectFile(lg);
-  this->CreateDummyKateProjectFile(lg);
+  this->CreateKateProjectFile(*lg);
+  this->CreateDummyKateProjectFile(*lg);
 }
 
 void cmExtraKateGenerator::CreateKateProjectFile(
-  const cmLocalGenerator* lg) const
+  const cmLocalGenerator& lg) const
 {
-  std::string filename = cmStrCat(lg->GetBinaryDirectory(), "/.kateproject");
+  std::string filename = cmStrCat(lg.GetBinaryDirectory(), "/.kateproject");
   cmGeneratedFileStream fout(filename);
   if (!fout) {
     return;
@@ -65,21 +65,21 @@ void cmExtraKateGenerator::CreateKateProjectFile(
   fout <<
     "{\n"
     "\t\"name\": \"" << this->ProjectName << "\",\n"
-    "\t\"directory\": \"" << lg->GetSourceDirectory() << "\",\n"
+    "\t\"directory\": \"" << lg.GetSourceDirectory() << "\",\n"
     "\t\"files\": [ { " << this->GenerateFilesString(lg) << "} ],\n";
   /* clang-format on */
   this->WriteTargets(lg, fout);
   fout << "}\n";
 }
 
-void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
+void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg,
                                         cmGeneratedFileStream& fout) const
 {
-  cmMakefile const* mf = lg->GetMakefile();
+  cmMakefile const* mf = lg.GetMakefile();
   const std::string& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
   const std::string& makeArgs =
     mf->GetSafeDefinition("CMAKE_KATE_MAKE_ARGUMENTS");
-  std::string const& homeOutputDir = lg->GetBinaryDirectory();
+  std::string const& homeOutputDir = lg.GetBinaryDirectory();
 
   /* clang-format off */
   fout <<
@@ -110,8 +110,7 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
 
   // add all executable and library targets and some of the GLOBAL
   // and UTILITY targets
-  for (cmLocalGenerator* localGen :
-       this->GlobalGenerator->GetLocalGenerators()) {
+  for (const auto& localGen : this->GlobalGenerator->GetLocalGenerators()) {
     const auto& targets = localGen->GetGeneratorTargets();
     std::string currentDir = localGen->GetCurrentBinaryDirectory();
     bool topLevel = (currentDir == localGen->GetBinaryDirectory());
@@ -205,10 +204,10 @@ void cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
 }
 
 void cmExtraKateGenerator::CreateDummyKateProjectFile(
-  const cmLocalGenerator* lg) const
+  const cmLocalGenerator& lg) const
 {
   std::string filename =
-    cmStrCat(lg->GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
+    cmStrCat(lg.GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
   cmGeneratedFileStream fout(filename);
   if (!fout) {
     return;
@@ -219,26 +218,25 @@ void cmExtraKateGenerator::CreateDummyKateProjectFile(
 }
 
 std::string cmExtraKateGenerator::GenerateFilesString(
-  const cmLocalGenerator* lg) const
+  const cmLocalGenerator& lg) const
 {
-  std::string s = cmStrCat(lg->GetSourceDirectory(), "/.git");
+  std::string s = cmStrCat(lg.GetSourceDirectory(), "/.git");
   if (cmSystemTools::FileExists(s)) {
     return "\"git\": 1 ";
   }
 
-  s = cmStrCat(lg->GetSourceDirectory(), "/.svn");
+  s = cmStrCat(lg.GetSourceDirectory(), "/.svn");
   if (cmSystemTools::FileExists(s)) {
     return "\"svn\": 1 ";
   }
 
-  s = cmStrCat(lg->GetSourceDirectory(), '/');
+  s = cmStrCat(lg.GetSourceDirectory(), '/');
 
   std::set<std::string> files;
   std::string tmp;
-  const std::vector<cmLocalGenerator*>& lgs =
-    this->GlobalGenerator->GetLocalGenerators();
+  const auto& lgs = this->GlobalGenerator->GetLocalGenerators();
 
-  for (cmLocalGenerator* lgen : lgs) {
+  for (const auto& lgen : lgs) {
     cmMakefile* makefile = lgen->GetMakefile();
     const std::vector<std::string>& listFiles = makefile->GetListFiles();
     for (std::string const& listFile : listFiles) {

+ 4 - 4
Source/cmExtraKateGenerator.h

@@ -25,16 +25,16 @@ public:
   void Generate() override;
 
 private:
-  void CreateKateProjectFile(const cmLocalGenerator* lg) const;
-  void CreateDummyKateProjectFile(const cmLocalGenerator* lg) const;
-  void WriteTargets(const cmLocalGenerator* lg,
+  void CreateKateProjectFile(const cmLocalGenerator& lg) const;
+  void CreateDummyKateProjectFile(const cmLocalGenerator& lg) const;
+  void WriteTargets(const cmLocalGenerator& lg,
                     cmGeneratedFileStream& fout) const;
   void AppendTarget(cmGeneratedFileStream& fout, const std::string& target,
                     const std::string& make, const std::string& makeArgs,
                     const std::string& path,
                     const std::string& homeOutputDir) const;
 
-  std::string GenerateFilesString(const cmLocalGenerator* lg) const;
+  std::string GenerateFilesString(const cmLocalGenerator& lg) const;
   std::string GetPathBasename(const std::string& path) const;
   std::string GenerateProjectName(const std::string& name,
                                   const std::string& type,

+ 2 - 1
Source/cmFileAPICMakeFiles.cxx

@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmFileAPICMakeFiles.h"
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -67,7 +68,7 @@ Json::Value CMakeFiles::DumpInputs()
 
   cmGlobalGenerator* gg =
     this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
-  for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
+  for (const auto& lg : gg->GetLocalGenerators()) {
     cmMakefile const* mf = lg->GetMakefile();
     for (std::string const& file : mf->GetListFiles()) {
       inputs.append(this->DumpInput(file));

+ 4 - 4
Source/cmFileAPICodemodel.cxx

@@ -469,17 +469,17 @@ void CodemodelConfig::ProcessDirectories()
 {
   cmGlobalGenerator* gg =
     this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
-  std::vector<cmLocalGenerator*> const& localGens = gg->GetLocalGenerators();
+  auto const& localGens = gg->GetLocalGenerators();
 
   // Add directories in forward order to process parents before children.
   this->Directories.reserve(localGens.size());
-  for (cmLocalGenerator* lg : localGens) {
+  for (const auto& lg : localGens) {
     auto directoryIndex =
       static_cast<Json::ArrayIndex>(this->Directories.size());
     this->Directories.emplace_back();
     Directory& d = this->Directories[directoryIndex];
     d.Snapshot = lg->GetStateSnapshot().GetBuildsystemDirectory();
-    d.LocalGenerator = lg;
+    d.LocalGenerator = lg.get();
     this->DirectoryMap[d.Snapshot] = directoryIndex;
 
     d.ProjectIndex = this->AddProject(d.Snapshot);
@@ -554,7 +554,7 @@ Json::Value CodemodelConfig::DumpTargets()
   std::vector<cmGeneratorTarget*> targetList;
   cmGlobalGenerator* gg =
     this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
-  for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
+  for (const auto& lg : gg->GetLocalGenerators()) {
     cmAppend(targetList, lg->GetGeneratorTargets());
   }
   std::sort(targetList.begin(), targetList.end(),

+ 8 - 5
Source/cmGlobalBorlandMakefileGenerator.cxx

@@ -2,6 +2,10 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmGlobalBorlandMakefileGenerator.h"
 
+#include <utility>
+
+#include <cm/memory>
+
 #include "cmDocumentationEntry.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
@@ -35,15 +39,14 @@ void cmGlobalBorlandMakefileGenerator::EnableLanguage(
 }
 
 //! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(
-  cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(cmMakefile* mf)
 {
-  cmLocalUnixMakefileGenerator3* lg =
-    new cmLocalUnixMakefileGenerator3(this, mf);
+  auto lg = cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf);
   lg->SetMakefileVariableSize(32);
   lg->SetMakeCommandEscapeTargetTwice(true);
   lg->SetBorlandMakeCurlyHack(true);
-  return lg;
+  return std::unique_ptr<cmLocalGenerator>(std::move(lg));
 }
 
 void cmGlobalBorlandMakefileGenerator::GetDocumentation(

+ 3 - 1
Source/cmGlobalBorlandMakefileGenerator.h

@@ -4,6 +4,7 @@
 #define cmGlobalBorlandMakefileGenerator_h
 
 #include <iosfwd>
+#include <memory>
 
 #include "cmGlobalNMakeMakefileGenerator.h"
 
@@ -33,7 +34,8 @@ public:
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   //! Create a local generator appropriate to this Global Generator
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
   /**
    * Try to determine system information such as shared library

+ 2 - 2
Source/cmGlobalCommonGenerator.cxx

@@ -25,11 +25,11 @@ std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
 cmGlobalCommonGenerator::ComputeDirectoryTargets() const
 {
   std::map<std::string, DirectoryTarget> dirTargets;
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     std::string const& currentBinaryDir(
       lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
     DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
-    dirTarget.LG = lg;
+    dirTarget.LG = lg.get();
 
     // The directory-level rule should depend on the target-level rules
     // for all targets in the directory.

+ 33 - 35
Source/cmGlobalGenerator.cxx

@@ -300,7 +300,7 @@ void cmGlobalGenerator::ForceLinkerLanguages()
 bool cmGlobalGenerator::CheckTargetsForMissingSources() const
 {
   bool failed = false;
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     for (const auto& target : localGen->GetGeneratorTargets()) {
       if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
           target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
@@ -340,7 +340,7 @@ bool cmGlobalGenerator::CheckTargetsForType() const
     return false;
   }
   bool failed = false;
-  for (cmLocalGenerator* generator : this->LocalGenerators) {
+  for (const auto& generator : this->LocalGenerators) {
     for (const auto& target : generator->GetGeneratorTargets()) {
       if (target->GetType() == cmStateEnums::EXECUTABLE &&
           target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
@@ -368,7 +368,7 @@ bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
     return false;
   }
   bool failed = false;
-  for (cmLocalGenerator* generator : this->LocalGenerators) {
+  for (const auto& generator : this->LocalGenerators) {
     for (const auto& target : generator->GetGeneratorTargets()) {
       if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
           target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
@@ -1204,13 +1204,12 @@ void cmGlobalGenerator::ClearEnabledLanguages()
 void cmGlobalGenerator::CreateLocalGenerators()
 {
   this->LocalGeneratorSearchIndex.clear();
-  cmDeleteAll(this->LocalGenerators);
   this->LocalGenerators.clear();
   this->LocalGenerators.reserve(this->Makefiles.size());
   for (cmMakefile* m : this->Makefiles) {
-    cmLocalGenerator* lg = this->CreateLocalGenerator(m);
-    this->LocalGenerators.push_back(lg);
-    this->IndexLocalGenerator(lg);
+    auto lg = this->CreateLocalGenerator(m);
+    this->IndexLocalGenerator(lg.get());
+    this->LocalGenerators.push_back(std::move(lg));
   }
 }
 
@@ -1300,7 +1299,7 @@ void cmGlobalGenerator::CreateImportedGenerationObjects(
   this->CreateGenerationObjects(ImportedOnly);
   auto const mfit =
     std::find(this->Makefiles.begin(), this->Makefiles.end(), mf);
-  cmLocalGenerator* lg =
+  auto& lg =
     this->LocalGenerators[std::distance(this->Makefiles.begin(), mfit)];
   for (std::string const& t : targets) {
     cmGeneratorTarget* gt = lg->FindGeneratorTargetToUse(t);
@@ -1353,7 +1352,7 @@ void cmGlobalGenerator::ComputeBuildFileGenerators()
     std::vector<cmExportBuildFileGenerator*> gens =
       this->Makefiles[i]->GetExportBuildFileGenerators();
     for (cmExportBuildFileGenerator* g : gens) {
-      g->Compute(this->LocalGenerators[i]);
+      g->Compute(this->LocalGenerators[i].get());
     }
   }
 }
@@ -1392,7 +1391,7 @@ bool cmGlobalGenerator::Compute()
   }
 
   // Add generator specific helper commands
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     localGen->AddHelperCommands();
   }
 
@@ -1402,16 +1401,16 @@ bool cmGlobalGenerator::Compute()
   // on the original cmTarget instance.  It accumulates features
   // across all configurations.  Some refactoring is needed to
   // compute a per-config resulta purely during generation.
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     if (!localGen->ComputeTargetCompileFeatures()) {
       return false;
     }
   }
 
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     cmMakefile* mf = localGen->GetMakefile();
     for (cmInstallGenerator* g : mf->GetInstallGenerators()) {
-      if (!g->Compute(localGen)) {
+      if (!g->Compute(localGen.get())) {
         return false;
       }
     }
@@ -1421,7 +1420,7 @@ bool cmGlobalGenerator::Compute()
 
   // Trace the dependencies, after that no custom commands should be added
   // because their dependencies might not be handled correctly
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     localGen->TraceDependencies();
   }
 
@@ -1433,7 +1432,7 @@ bool cmGlobalGenerator::Compute()
   this->ForceLinkerLanguages();
 
   // Compute the manifest of main targets generated.
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     localGen->ComputeTargetManifest();
   }
 
@@ -1450,7 +1449,7 @@ bool cmGlobalGenerator::Compute()
     return false;
   }
 
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     localGen->ComputeHomeRelativeOutputPath();
   }
 
@@ -1563,7 +1562,7 @@ bool cmGlobalGenerator::QtAutoGen()
 
 bool cmGlobalGenerator::AddAutomaticSources()
 {
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     lg->CreateEvaluationFileOutputs();
     for (const auto& gt : lg->GetGeneratorTargets()) {
       if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -1579,7 +1578,7 @@ bool cmGlobalGenerator::AddAutomaticSources()
   // Clear the source list and classification cache (KindedSources) of all
   // targets so that it will be recomputed correctly by the generators later
   // now that the above transformations are done for all targets.
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     for (const auto& gt : lg->GetGeneratorTargets()) {
       gt->ClearSourcesCache();
     }
@@ -1684,7 +1683,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
   for (unsigned int i = 0; i < this->Makefiles.size(); ++i) {
     cmMakefile* mf = this->Makefiles[i];
     for (cmTarget* ownedImpTgt : mf->GetOwnedImportedTargets()) {
-      cmLocalGenerator* lg = this->LocalGenerators[i];
+      cmLocalGenerator* lg = this->LocalGenerators[i].get();
       auto gt = cm::make_unique<cmGeneratorTarget>(ownedImpTgt, lg);
       importedMap[ownedImpTgt] = gt.get();
       lg->AddOwnedImportedGeneratorTarget(std::move(gt));
@@ -1694,7 +1693,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
   // Construct per-target generator information.
   for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
     this->CreateGeneratorTargets(targetTypes, this->Makefiles[i],
-                                 this->LocalGenerators[i], importedMap);
+                                 this->LocalGenerators[i].get(), importedMap);
   }
 }
 
@@ -1706,7 +1705,6 @@ void cmGlobalGenerator::ClearGeneratorMembers()
   cmDeleteAll(this->Makefiles);
   this->Makefiles.clear();
 
-  cmDeleteAll(this->LocalGenerators);
   this->LocalGenerators.clear();
 
   this->AliasTargets.clear();
@@ -2047,9 +2045,10 @@ void cmGlobalGenerator::EnableInstallTarget()
   this->InstallTargetEnabled = true;
 }
 
-cmLocalGenerator* cmGlobalGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalGenerator::CreateLocalGenerator(
+  cmMakefile* mf)
 {
-  return new cmLocalGenerator(this, mf);
+  return cm::make_unique<cmLocalGenerator>(this, mf);
 }
 
 void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator* gen,
@@ -2144,7 +2143,7 @@ int cmGlobalGenerator::GetLinkerPreference(const std::string& lang) const
 void cmGlobalGenerator::FillProjectMap()
 {
   this->ProjectMap.clear(); // make sure we start with a clean map
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     // for each local generator add all projects
     cmStateSnapshot snp = localGen->GetStateSnapshot();
     std::string name;
@@ -2152,7 +2151,7 @@ void cmGlobalGenerator::FillProjectMap()
       std::string snpProjName = snp.GetProjectName();
       if (name != snpProjName) {
         name = snpProjName;
-        this->ProjectMap[name].push_back(localGen);
+        this->ProjectMap[name].push_back(localGen.get());
       }
       snp = snp.GetBuildsystemDirectoryParent();
     } while (snp.IsValid());
@@ -2767,13 +2766,12 @@ void cmGlobalGenerator::GetFilesReplacedDuringGenerate(
             std::back_inserter(filenames));
 }
 
-void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
-                                      TargetDependSet& originalTargets,
-                                      cmLocalGenerator* root,
-                                      GeneratorVector const& generators)
+void cmGlobalGenerator::GetTargetSets(
+  TargetDependSet& projectTargets, TargetDependSet& originalTargets,
+  cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
 {
   // loop over all local generators
-  for (cmLocalGenerator* generator : generators) {
+  for (auto generator : generators) {
     // check to make sure generator is not excluded
     if (this->IsExcluded(root, generator)) {
       continue;
@@ -2963,7 +2961,7 @@ void cmGlobalGenerator::WriteSummary()
                                "/CMakeFiles/TargetDirectories.txt");
   cmGeneratedFileStream fout(fname);
 
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     for (const auto& tgt : lg->GetGeneratorTargets()) {
       if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
         continue;
@@ -3113,7 +3111,7 @@ cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const
 void cmGlobalGenerator::ProcessEvaluationFiles()
 {
   std::vector<std::string> generatedFiles;
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (auto& localGen : this->LocalGenerators) {
     localGen->ProcessEvaluationFiles(generatedFiles);
   }
 }
@@ -3129,7 +3127,7 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
   cmake::InstalledFilesMap const& installedFiles =
     this->CMakeInstance->GetInstalledFiles();
 
-  cmLocalGenerator* lg = this->LocalGenerators[0];
+  const auto& lg = this->LocalGenerators[0];
   cmMakefile* mf = lg->GetMakefile();
 
   std::vector<std::string> configs;
@@ -3148,8 +3146,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
   for (auto const& i : installedFiles) {
     cmInstalledFile const& installedFile = i.second;
 
-    cmCPackPropertiesGenerator cpackPropertiesGenerator(lg, installedFile,
-                                                        configs);
+    cmCPackPropertiesGenerator cpackPropertiesGenerator(
+      lg.get(), installedFile, configs);
 
     cpackPropertiesGenerator.Generate(file, config, configs);
   }

+ 7 - 5
Source/cmGlobalGenerator.h

@@ -90,11 +90,14 @@ struct GeneratedMakeCommand
 class cmGlobalGenerator
 {
 public:
+  using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;
+
   //! Free any memory allocated with the GlobalGenerator
   cmGlobalGenerator(cmake* cm);
   virtual ~cmGlobalGenerator();
 
-  virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
+  virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf);
 
   //! Get the name for this generator
   virtual std::string GetName() const { return "Generic"; }
@@ -249,7 +252,7 @@ public:
   {
     return this->Makefiles;
   }
-  const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
+  const LocalGeneratorVector& GetLocalGenerators() const
   {
     return this->LocalGenerators;
   }
@@ -477,12 +480,11 @@ public:
   int RecursionDepth;
 
 protected:
-  using GeneratorVector = std::vector<cmLocalGenerator*>;
   // for a project collect all its targets by following depend
   // information, and also collect all the targets
   void GetTargetSets(TargetDependSet& projectTargets,
                      TargetDependSet& originalTargets, cmLocalGenerator* root,
-                     GeneratorVector const&);
+                     std::vector<cmLocalGenerator*>& generators);
   bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
   void AddTargetDepends(const cmGeneratorTarget* target,
                         TargetDependSet& projectTargets);
@@ -541,7 +543,7 @@ protected:
   std::string ConfiguredFilesPath;
   cmake* CMakeInstance;
   std::vector<cmMakefile*> Makefiles;
-  std::vector<cmLocalGenerator*> LocalGenerators;
+  LocalGeneratorVector LocalGenerators;
   cmMakefile* CurrentConfigureMakefile;
   // map from project name to vector of local generators in that project
   std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;

+ 6 - 3
Source/cmGlobalGhsMultiGenerator.cxx

@@ -8,6 +8,8 @@
 #include <ostream>
 #include <utility>
 
+#include <cm/memory>
+
 #include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
 #include "cmGeneratedFileStream.h"
@@ -40,10 +42,11 @@ cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
 
 cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() = default;
 
-cmLocalGenerator* cmGlobalGhsMultiGenerator::CreateLocalGenerator(
-  cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalGhsMultiGenerator(this, mf);
+  return std::unique_ptr<cmLocalGenerator>(
+    cm::make_unique<cmLocalGhsMultiGenerator>(this, mf));
 }
 
 void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)

+ 3 - 1
Source/cmGlobalGhsMultiGenerator.h

@@ -4,6 +4,7 @@
 #define cmGhsMultiGenerator_h
 
 #include <iosfwd>
+#include <memory>
 #include <set>
 #include <string>
 #include <utility>
@@ -34,7 +35,8 @@ public:
   }
 
   //! create the correct local generator
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
   /// @return the name of this generator.
   static std::string GetActualName() { return "Green Hills MULTI"; }

+ 17 - 16
Source/cmGlobalNinjaGenerator.cxx

@@ -9,6 +9,7 @@
 #include <sstream>
 
 #include <cm/memory>
+#include <cmext/memory>
 
 #include "cmsys/FStream.hxx"
 
@@ -429,9 +430,11 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
 
 // Virtual public methods.
 
-cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator(
+  cmMakefile* mf)
 {
-  return new cmLocalNinjaGenerator(this, mf);
+  return std::unique_ptr<cmLocalGenerator>(
+    cm::make_unique<cmLocalNinjaGenerator>(this, mf));
 }
 
 codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
@@ -819,10 +822,10 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
     return f->second;
   }
 
-  cmLocalNinjaGenerator* ng =
-    static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
-  std::string const& bin_dir = ng->GetState()->GetBinaryDirectory();
-  std::string convPath = ng->MaybeConvertToRelativePath(bin_dir, path);
+  const auto& ng =
+    cm::static_reference_cast<cmLocalNinjaGenerator>(this->LocalGenerators[0]);
+  std::string const& bin_dir = ng.GetState()->GetBinaryDirectory();
+  std::string convPath = ng.MaybeConvertToRelativePath(bin_dir, path);
   convPath = this->NinjaOutputPath(convPath);
 #ifdef _WIN32
   std::replace(convPath.begin(), convPath.end(), '/', '\\');
@@ -1148,7 +1151,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
   // get the list of files that cmake itself has generated as a
   // product of configuration.
 
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     // get the vector of files created by this makefile and convert them
     // to ninja paths, which are all relative in respect to the build directory
     for (std::string const& file : lg->GetMakefile()->GetOutputFiles()) {
@@ -1268,7 +1271,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
   if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
     return;
   }
-  cmLocalGenerator* lg = this->LocalGenerators[0];
+  const auto& lg = this->LocalGenerators[0];
 
   {
     cmNinjaRule rule("RERUN_CMAKE");
@@ -1289,7 +1292,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
   reBuild.Comment = "Re-run CMake if any of its inputs changed.";
   reBuild.Outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
 
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     for (std::string const& fi : localGen->GetMakefile()->GetListFiles()) {
       reBuild.ImplicitDeps.push_back(this->ConvertToNinjaPath(fi));
     }
@@ -1376,14 +1379,14 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
 
 std::string cmGlobalNinjaGenerator::CMakeCmd() const
 {
-  cmLocalGenerator* lgen = this->LocalGenerators.at(0);
+  const auto& lgen = this->LocalGenerators.at(0);
   return lgen->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
                                      cmOutputConverter::SHELL);
 }
 
 std::string cmGlobalNinjaGenerator::NinjaCmd() const
 {
-  cmLocalGenerator* lgen = this->LocalGenerators[0];
+  const auto& lgen = this->LocalGenerators[0];
   if (lgen != nullptr) {
     return lgen->ConvertToOutputFormat(this->NinjaCommand,
                                        cmOutputConverter::SHELL);
@@ -1413,7 +1416,7 @@ bool cmGlobalNinjaGenerator::SupportsMultilineDepfile() const
 
 bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
 {
-  cmLocalGenerator* lgr = this->LocalGenerators.at(0);
+  const auto& lgr = this->LocalGenerators.at(0);
   std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
   std::string cleanScriptAbs =
     cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
@@ -1809,11 +1812,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
     snapshot.GetDirectory().SetRelativePathTopSource(dir_top_src.c_str());
     snapshot.GetDirectory().SetRelativePathTopBinary(dir_top_bld.c_str());
     auto mfd = cm::make_unique<cmMakefile>(this, snapshot);
-    std::unique_ptr<cmLocalNinjaGenerator> lgd(
-      static_cast<cmLocalNinjaGenerator*>(
-        this->CreateLocalGenerator(mfd.get())));
+    auto lgd = this->CreateLocalGenerator(mfd.get());
     this->Makefiles.push_back(mfd.release());
-    this->LocalGenerators.push_back(lgd.release());
+    this->LocalGenerators.push_back(std::move(lgd));
   }
 
   std::vector<cmDyndepObjectInfo> objects;

+ 2 - 6
Source/cmGlobalNinjaGenerator.h

@@ -156,7 +156,8 @@ public:
     return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>();
   }
 
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
   std::string GetName() const override
   {
@@ -295,11 +296,6 @@ public:
   void AppendTargetDependsClosure(cmGeneratorTarget const* target,
                                   cmNinjaOuts& outputs, bool omit_self);
 
-  const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
-  {
-    return LocalGenerators;
-  }
-
   int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
 
   void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);

+ 134 - 129
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -8,6 +8,7 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cmext/memory>
 
 #include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
@@ -61,10 +62,11 @@ void cmGlobalUnixMakefileGenerator3::EnableLanguage(
 }
 
 //! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(
-  cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalUnixMakefileGenerator3(this, mf);
+  return std::unique_ptr<cmLocalGenerator>(
+    cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf));
 }
 
 void cmGlobalUnixMakefileGenerator3::GetDocumentation(
@@ -144,11 +146,11 @@ void cmGlobalUnixMakefileGenerator3::Generate()
   for (auto& pmi : this->ProgressMap) {
     pmi.second.WriteProgressVariables(total, current);
   }
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     std::string markFileName =
       cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/progress.marks");
     cmGeneratedFileStream markFile(markFileName);
-    markFile << this->CountProgressMarksInAll(lg) << "\n";
+    markFile << this->CountProgressMarksInAll(*lg) << "\n";
   }
 
   // write the main makefile
@@ -203,11 +205,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
   }
 
   // get a local generator for some useful methods
-  cmLocalUnixMakefileGenerator3* lg =
-    static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+  auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+    this->LocalGenerators[0]);
 
   // Write the do not edit header.
-  lg->WriteDisclaimer(makefileStream);
+  lg.WriteDisclaimer(makefileStream);
 
   // Write the main entry point target.  This must be the VERY first
   // target so that make with no arguments will run it.
@@ -217,10 +219,10 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
   depends.emplace_back("all");
 
   // Write the rule.
-  lg->WriteMakeRule(makefileStream,
-                    "Default target executed when no arguments are "
-                    "given to make.",
-                    "default_target", depends, no_commands, true);
+  lg.WriteMakeRule(makefileStream,
+                   "Default target executed when no arguments are "
+                   "given to make.",
+                   "default_target", depends, no_commands, true);
 
   depends.clear();
 
@@ -231,7 +233,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
   }
 
   // Write out the "special" stuff
-  lg->WriteSpecialTargetsTop(makefileStream);
+  lg.WriteSpecialTargetsTop(makefileStream);
 
   // Write the directory level rules.
   for (auto const& it : this->ComputeDirectoryTargets()) {
@@ -239,13 +241,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
   }
 
   // Write the target convenience rules
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     this->WriteConvenienceRules2(
-      makefileStream, static_cast<cmLocalUnixMakefileGenerator3*>(localGen));
+      makefileStream,
+      cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen));
   }
 
   // Write special bottom targets
-  lg->WriteSpecialTargetsBottom(makefileStream);
+  lg.WriteSpecialTargetsBottom(makefileStream);
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
@@ -268,12 +271,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
   std::string makefileName =
     cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), "/Makefile");
 
-  // get a local generator for some useful methods
-  cmLocalUnixMakefileGenerator3* lg =
-    static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+  {
+    // get a local generator for some useful methods
+    auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+      this->LocalGenerators[0]);
 
-  // Write the do not edit header.
-  lg->WriteDisclaimer(cmakefileStream);
+    // Write the do not edit header.
+    lg.WriteDisclaimer(cmakefileStream);
+  }
 
   // Save the generator name
   cmakefileStream << "# The generator used is:\n"
@@ -282,7 +287,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
 
   // for each cmMakefile get its list of dependencies
   std::vector<std::string> lfiles;
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
+  for (const auto& localGen : this->LocalGenerators) {
     // Get the list of files contributing to this generation step.
     cmAppend(lfiles, localGen->GetMakefile()->GetListFiles());
   }
@@ -300,59 +305,61 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
   lfiles.erase(new_end, lfiles.end());
 #endif
 
-  // reset lg to the first makefile
-  lg = static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
-
-  std::string currentBinDir = lg->GetCurrentBinaryDirectory();
-  // Save the list to the cmake file.
-  cmakefileStream
-    << "# The top level Makefile was generated from the following files:\n"
-    << "set(CMAKE_MAKEFILE_DEPENDS\n"
-    << "  \"CMakeCache.txt\"\n";
-  for (std::string const& f : lfiles) {
-    cmakefileStream << "  \""
-                    << lg->MaybeConvertToRelativePath(currentBinDir, f)
-                    << "\"\n";
-  }
-  cmakefileStream << "  )\n\n";
-
-  // Build the path to the cache check file.
-  std::string check =
-    cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
-             "/CMakeFiles/cmake.check_cache");
-
-  // Set the corresponding makefile in the cmake file.
-  cmakefileStream << "# The corresponding makefile is:\n"
-                  << "set(CMAKE_MAKEFILE_OUTPUTS\n"
-                  << "  \""
-                  << lg->MaybeConvertToRelativePath(currentBinDir,
-                                                    makefileName)
-                  << "\"\n"
-                  << "  \""
-                  << lg->MaybeConvertToRelativePath(currentBinDir, check)
-                  << "\"\n";
-  cmakefileStream << "  )\n\n";
-
-  const std::string binDir = lg->GetBinaryDirectory();
-
-  // CMake must rerun if a byproduct is missing.
   {
-    cmakefileStream << "# Byproducts of CMake generate step:\n"
-                    << "set(CMAKE_MAKEFILE_PRODUCTS\n";
-    for (std::string const& outfile : lg->GetMakefile()->GetOutputFiles()) {
+    // reset lg to the first makefile
+    const auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+      this->LocalGenerators[0]);
+
+    const std::string& currentBinDir = lg.GetCurrentBinaryDirectory();
+    // Save the list to the cmake file.
+    cmakefileStream
+      << "# The top level Makefile was generated from the following files:\n"
+      << "set(CMAKE_MAKEFILE_DEPENDS\n"
+      << "  \"CMakeCache.txt\"\n";
+    for (std::string const& f : lfiles) {
       cmakefileStream << "  \""
-                      << lg->MaybeConvertToRelativePath(binDir, outfile)
+                      << lg.MaybeConvertToRelativePath(currentBinDir, f)
                       << "\"\n";
     }
+    cmakefileStream << "  )\n\n";
+
+    // Build the path to the cache check file.
+    std::string check =
+      cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
+               "/CMakeFiles/cmake.check_cache");
+
+    // Set the corresponding makefile in the cmake file.
+    cmakefileStream << "# The corresponding makefile is:\n"
+                    << "set(CMAKE_MAKEFILE_OUTPUTS\n"
+                    << "  \""
+                    << lg.MaybeConvertToRelativePath(currentBinDir,
+                                                     makefileName)
+                    << "\"\n"
+                    << "  \""
+                    << lg.MaybeConvertToRelativePath(currentBinDir, check)
+                    << "\"\n";
+    cmakefileStream << "  )\n\n";
+
+    const std::string& binDir = lg.GetBinaryDirectory();
+
+    // CMake must rerun if a byproduct is missing.
+    {
+      cmakefileStream << "# Byproducts of CMake generate step:\n"
+                      << "set(CMAKE_MAKEFILE_PRODUCTS\n";
+      for (std::string const& outfile : lg.GetMakefile()->GetOutputFiles()) {
+        cmakefileStream << "  \""
+                        << lg.MaybeConvertToRelativePath(binDir, outfile)
+                        << "\"\n";
+      }
+    }
 
     // add in all the directory information files
     std::string tmpStr;
-    for (cmLocalGenerator* localGen : this->LocalGenerators) {
-      lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
-      tmpStr = cmStrCat(lg->GetCurrentBinaryDirectory(),
+    for (const auto& localGen : this->LocalGenerators) {
+      tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(),
                         "/CMakeFiles/CMakeDirectoryInformation.cmake");
       cmakefileStream << "  \""
-                      << lg->MaybeConvertToRelativePath(binDir, tmpStr)
+                      << localGen->MaybeConvertToRelativePath(binDir, tmpStr)
                       << "\"\n";
     }
     cmakefileStream << "  )\n\n";
@@ -364,24 +371,23 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
 
 void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
   cmGeneratedFileStream& cmakefileStream,
-  std::vector<cmLocalGenerator*>& lGenerators)
+  std::vector<std::unique_ptr<cmLocalGenerator>>& lGenerators)
 {
-  cmLocalUnixMakefileGenerator3* lg;
-
   // now list all the target info files
   cmakefileStream << "# Dependency information for all targets:\n";
   cmakefileStream << "set(CMAKE_DEPEND_INFO_FILES\n";
-  for (cmLocalGenerator* lGenerator : lGenerators) {
-    lg = static_cast<cmLocalUnixMakefileGenerator3*>(lGenerator);
+  for (const auto& lGenerator : lGenerators) {
+    const auto& lg =
+      cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(lGenerator);
     // for all of out targets
-    for (const auto& tgt : lg->GetGeneratorTargets()) {
+    for (const auto& tgt : lg.GetGeneratorTargets()) {
       if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
           (tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
           (tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
           (tgt->GetType() == cmStateEnums::MODULE_LIBRARY) ||
           (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
           (tgt->GetType() == cmStateEnums::UTILITY)) {
-        std::string tname = cmStrCat(lg->GetRelativeTargetDirectory(tgt.get()),
+        std::string tname = cmStrCat(lg.GetRelativeTargetDirectory(tgt.get()),
                                      "/DependInfo.cmake");
         cmSystemTools::ConvertToUnixSlashes(tname);
         cmakefileStream << "  \"" << tname << "\"\n";
@@ -544,11 +550,11 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
   }
 
   // write the target convenience rules
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
-    cmLocalUnixMakefileGenerator3* lg =
-      static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
+  for (const auto& localGen : this->LocalGenerators) {
+    auto& lg =
+      cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen);
     // for each target Generate the rule files for each target.
-    for (const auto& gtarget : lg->GetGeneratorTargets()) {
+    for (const auto& gtarget : lg.GetGeneratorTargets()) {
       // Don't emit the same rule twice (e.g. two targets with the same
       // simple name)
       int type = gtarget->GetType();
@@ -563,23 +569,23 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
            (type == cmStateEnums::OBJECT_LIBRARY) ||
            (type == cmStateEnums::UTILITY))) {
         // Add a rule to build the target by name.
-        lg->WriteDivider(ruleFileStream);
+        lg.WriteDivider(ruleFileStream);
         ruleFileStream << "# Target rules for targets named " << name
                        << "\n\n";
 
         // Write the rule.
         commands.clear();
         std::string tmp = "CMakeFiles/Makefile2";
-        commands.push_back(lg->GetRecursiveMakeCall(tmp, name));
+        commands.push_back(lg.GetRecursiveMakeCall(tmp, name));
         depends.clear();
         if (regenerate) {
           depends.emplace_back("cmake_check_build_system");
         }
-        lg->WriteMakeRule(ruleFileStream, "Build rule for target.", name,
-                          depends, commands, true);
+        lg.WriteMakeRule(ruleFileStream, "Build rule for target.", name,
+                         depends, commands, true);
 
         // Add a fast rule to build the target
-        std::string localName = lg->GetRelativeTargetDirectory(gtarget.get());
+        std::string localName = lg.GetRelativeTargetDirectory(gtarget.get());
         std::string makefileName;
         makefileName = cmStrCat(localName, "/build.make");
         depends.clear();
@@ -587,23 +593,23 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
         std::string makeTargetName = cmStrCat(localName, "/build");
         localName = cmStrCat(name, "/fast");
         commands.push_back(
-          lg->GetRecursiveMakeCall(makefileName, makeTargetName));
-        lg->WriteMakeRule(ruleFileStream, "fast build rule for target.",
-                          localName, depends, commands, true);
+          lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+        lg.WriteMakeRule(ruleFileStream, "fast build rule for target.",
+                         localName, depends, commands, true);
 
         // Add a local name for the rule to relink the target before
         // installation.
-        if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
+        if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
           makeTargetName = cmStrCat(
-            lg->GetRelativeTargetDirectory(gtarget.get()), "/preinstall");
+            lg.GetRelativeTargetDirectory(gtarget.get()), "/preinstall");
           localName = cmStrCat(name, "/preinstall");
           depends.clear();
           commands.clear();
           commands.push_back(
-            lg->GetRecursiveMakeCall(makefileName, makeTargetName));
-          lg->WriteMakeRule(ruleFileStream,
-                            "Manual pre-install relink rule for target.",
-                            localName, depends, commands, true);
+            lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+          lg.WriteMakeRule(ruleFileStream,
+                           "Manual pre-install relink rule for target.",
+                           localName, depends, commands, true);
         }
       }
     }
@@ -611,7 +617,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
-  std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg)
+  std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& lg)
 {
   std::vector<std::string> depends;
   std::vector<std::string> commands;
@@ -624,7 +630,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
   }
 
   // for each target Generate the rule files for each target.
-  for (const auto& gtarget : lg->GetGeneratorTargets()) {
+  for (const auto& gtarget : lg.GetGeneratorTargets()) {
     int type = gtarget->GetType();
     std::string name = gtarget->GetName();
     if (!name.empty() &&
@@ -636,27 +642,27 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
          (type == cmStateEnums::UTILITY))) {
       std::string makefileName;
       // Add a rule to build the target by name.
-      localName = lg->GetRelativeTargetDirectory(gtarget.get());
+      localName = lg.GetRelativeTargetDirectory(gtarget.get());
       makefileName = cmStrCat(localName, "/build.make");
 
-      lg->WriteDivider(ruleFileStream);
+      lg.WriteDivider(ruleFileStream);
       ruleFileStream << "# Target rules for target " << localName << "\n\n";
 
       commands.clear();
       makeTargetName = cmStrCat(localName, "/depend");
       commands.push_back(
-        lg->GetRecursiveMakeCall(makefileName, makeTargetName));
+        lg.GetRecursiveMakeCall(makefileName, makeTargetName));
 
       makeTargetName = cmStrCat(localName, "/build");
       commands.push_back(
-        lg->GetRecursiveMakeCall(makefileName, makeTargetName));
+        lg.GetRecursiveMakeCall(makefileName, makeTargetName));
 
       // Write the rule.
       localName += "/all";
       depends.clear();
 
       cmLocalUnixMakefileGenerator3::EchoProgress progress;
-      progress.Dir = cmStrCat(lg->GetBinaryDirectory(), "/CMakeFiles");
+      progress.Dir = cmStrCat(lg.GetBinaryDirectory(), "/CMakeFiles");
       {
         std::ostringstream progressArg;
         const char* sep = "";
@@ -675,13 +681,13 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
       }
 
       if (targetMessages) {
-        lg->AppendEcho(commands, "Built target " + name,
-                       cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
+        lg.AppendEcho(commands, "Built target " + name,
+                      cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
       }
 
       this->AppendGlobalTargetDepends(depends, gtarget.get());
-      lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
-                        localName, depends, commands, true);
+      lg.WriteMakeRule(ruleFileStream, "All Build rule for target.", localName,
+                       depends, commands, true);
 
       // Write the rule.
       commands.clear();
@@ -691,7 +697,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
         std::ostringstream progCmd;
         progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
         // # in target
-        progCmd << lg->ConvertToOutputFormat(
+        progCmd << lg.ConvertToOutputFormat(
           cmSystemTools::CollapseFullPath(progress.Dir),
           cmOutputConverter::SHELL);
         //
@@ -701,11 +707,11 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
         commands.push_back(progCmd.str());
       }
       std::string tmp = "CMakeFiles/Makefile2";
-      commands.push_back(lg->GetRecursiveMakeCall(tmp, localName));
+      commands.push_back(lg.GetRecursiveMakeCall(tmp, localName));
       {
         std::ostringstream progCmd;
         progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
-        progCmd << lg->ConvertToOutputFormat(
+        progCmd << lg.ConvertToOutputFormat(
           cmSystemTools::CollapseFullPath(progress.Dir),
           cmOutputConverter::SHELL);
         progCmd << " 0";
@@ -716,39 +722,38 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
         depends.emplace_back("cmake_check_build_system");
       }
       localName =
-        cmStrCat(lg->GetRelativeTargetDirectory(gtarget.get()), "/rule");
-      lg->WriteMakeRule(ruleFileStream,
-                        "Build rule for subdir invocation for target.",
-                        localName, depends, commands, true);
+        cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()), "/rule");
+      lg.WriteMakeRule(ruleFileStream,
+                       "Build rule for subdir invocation for target.",
+                       localName, depends, commands, true);
 
       // Add a target with the canonical name (no prefix, suffix or path).
       commands.clear();
       depends.clear();
       depends.push_back(localName);
-      lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
-                        depends, commands, true);
+      lg.WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
+                       depends, commands, true);
 
       // Add rules to prepare the target for installation.
-      if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
-        localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget.get()),
+      if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
+        localName = cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()),
                              "/preinstall");
         depends.clear();
         commands.clear();
-        commands.push_back(lg->GetRecursiveMakeCall(makefileName, localName));
-        lg->WriteMakeRule(ruleFileStream,
-                          "Pre-install relink rule for target.", localName,
-                          depends, commands, true);
+        commands.push_back(lg.GetRecursiveMakeCall(makefileName, localName));
+        lg.WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.",
+                         localName, depends, commands, true);
       }
 
       // add the clean rule
-      localName = lg->GetRelativeTargetDirectory(gtarget.get());
+      localName = lg.GetRelativeTargetDirectory(gtarget.get());
       makeTargetName = cmStrCat(localName, "/clean");
       depends.clear();
       commands.clear();
       commands.push_back(
-        lg->GetRecursiveMakeCall(makefileName, makeTargetName));
-      lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
-                        makeTargetName, depends, commands, true);
+        lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+      lg.WriteMakeRule(ruleFileStream, "clean rule for target.",
+                       makeTargetName, depends, commands, true);
       commands.clear();
     }
   }
@@ -760,7 +765,7 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
 {
   this->DirectoryTargetsMap.clear();
   // Loop over all targets in all local generators.
-  for (cmLocalGenerator* lg : this->LocalGenerators) {
+  for (const auto& lg : this->LocalGenerators) {
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmLocalGenerator* tlg = gt->GetLocalGenerator();
 
@@ -810,12 +815,12 @@ size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInTarget(
 }
 
 size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInAll(
-  cmLocalGenerator* lg)
+  const cmLocalGenerator& lg)
 {
   size_t count = 0;
   std::set<cmGeneratorTarget const*> emitted;
   for (cmGeneratorTarget const* target :
-       this->DirectoryTargetsMap[lg->GetStateSnapshot()]) {
+       this->DirectoryTargetsMap[lg.GetStateSnapshot()]) {
     count += this->CountProgressMarksInTarget(target, emitted);
   }
   return count;
@@ -889,14 +894,14 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
   std::set<std::string> emittedTargets;
 
   // for each local generator
-  for (cmLocalGenerator* localGen : this->LocalGenerators) {
-    cmLocalUnixMakefileGenerator3* lg2 =
-      static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
+  for (const auto& localGen : this->LocalGenerators) {
+    const auto& lg2 =
+      cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen);
     // for the passed in makefile or if this is the top Makefile wripte out
     // the targets
-    if (lg2 == lg || lg->IsRootMakefile()) {
+    if (&lg2 == lg || lg->IsRootMakefile()) {
       // for each target Generate the rule files for each target.
-      for (const auto& target : lg2->GetGeneratorTargets()) {
+      for (const auto& target : lg2.GetGeneratorTargets()) {
         cmStateEnums::TargetType type = target->GetType();
         if ((type == cmStateEnums::EXECUTABLE) ||
             (type == cmStateEnums::STATIC_LIBRARY) ||

+ 8 - 5
Source/cmGlobalUnixMakefileGenerator3.h

@@ -8,6 +8,7 @@
 #include <cstddef>
 #include <iosfwd>
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
@@ -89,7 +90,8 @@ public:
   /** Get the documentation entry for this generator.  */
   static void GetDocumentation(cmDocumentationEntry& entry);
 
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
   /**
    * Try to determine system information such as shared library
@@ -107,8 +109,9 @@ public:
    */
   void Generate() override;
 
-  void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
-                                       std::vector<cmLocalGenerator*>&);
+  void WriteMainCMakefileLanguageRules(
+    cmGeneratedFileStream& cmakefileStream,
+    std::vector<std::unique_ptr<cmLocalGenerator>>&);
 
   // write out the help rule listing the valid targets
   void WriteHelpRule(std::ostream& ruleFileStream,
@@ -161,7 +164,7 @@ protected:
   void WriteMainCMakefile();
 
   void WriteConvenienceRules2(std::ostream& ruleFileStream,
-                              cmLocalUnixMakefileGenerator3*);
+                              cmLocalUnixMakefileGenerator3&);
 
   void WriteDirectoryRule2(std::ostream& ruleFileStream,
                            DirectoryTarget const& dt, const char* pass,
@@ -227,7 +230,7 @@ protected:
   size_t CountProgressMarksInTarget(
     cmGeneratorTarget const* target,
     std::set<cmGeneratorTarget const*>& emitted);
-  size_t CountProgressMarksInAll(cmLocalGenerator* lg);
+  size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
 
   cmGeneratedFileStream* CommandDatabase;
 

+ 6 - 3
Source/cmGlobalVisualStudio10Generator.cxx

@@ -4,6 +4,8 @@
 
 #include <algorithm>
 
+#include <cm/memory>
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
@@ -574,10 +576,11 @@ std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
 }
 
 //! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
-  cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalVisualStudio10Generator(this, mf);
+  return std::unique_ptr<cmLocalGenerator>(
+    cm::make_unique<cmLocalVisualStudio10Generator>(this, mf));
 }
 
 void cmGlobalVisualStudio10Generator::Generate()

+ 4 - 1
Source/cmGlobalVisualStudio10Generator.h

@@ -3,6 +3,8 @@
 #ifndef cmGlobalVisualStudio10Generator_h
 #define cmGlobalVisualStudio10Generator_h
 
+#include <memory>
+
 #include "cmGlobalVisualStudio8Generator.h"
 #include "cmVisualStudio10ToolsetOptions.h"
 
@@ -31,7 +33,8 @@ public:
       std::vector<std::string>()) override;
 
   //! create the correct local generator
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
   /**
    * Try to determine system information such as shared library

+ 7 - 6
Source/cmGlobalVisualStudio7Generator.cxx

@@ -2,8 +2,10 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmGlobalVisualStudio7Generator.h"
 
+#include <utility>
 #include <vector>
 
+#include <cm/memory>
 #include <cm/string_view>
 
 #include <windows.h>
@@ -263,12 +265,11 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
 }
 
 //! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalVisualStudio7Generator::CreateLocalGenerator(
-  cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmMakefile* mf)
 {
-  cmLocalVisualStudio7Generator* lg =
-    new cmLocalVisualStudio7Generator(this, mf);
-  return lg;
+  auto lg = cm::make_unique<cmLocalVisualStudio7Generator>(this, mf);
+  return std::unique_ptr<cmLocalGenerator>(std::move(lg));
 }
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -300,7 +301,7 @@ void cmGlobalVisualStudio7Generator::Generate()
   if (!cmSystemTools::GetErrorOccuredFlag() &&
       !this->LocalGenerators.empty()) {
     this->CallVisualStudioMacro(MacroReload,
-                                GetSLNFile(this->LocalGenerators[0]));
+                                GetSLNFile(this->LocalGenerators[0].get()));
   }
 }
 

+ 4 - 1
Source/cmGlobalVisualStudio7Generator.h

@@ -3,6 +3,8 @@
 #ifndef cmGlobalVisualStudio7Generator_h
 #define cmGlobalVisualStudio7Generator_h
 
+#include <memory>
+
 #include "cmGlobalGeneratorFactory.h"
 #include "cmGlobalVisualStudioGenerator.h"
 
@@ -20,7 +22,8 @@ public:
   ~cmGlobalVisualStudio7Generator();
 
   //! Create a local generator appropriate to this Global Generator
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
 #if !defined(CMAKE_BOOTSTRAP)
   Json::Value GetJson() const override;

+ 17 - 15
Source/cmGlobalVisualStudio8Generator.cxx

@@ -3,6 +3,7 @@
 #include "cmGlobalVisualStudio8Generator.h"
 
 #include <cm/memory>
+#include <cmext/memory>
 
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
@@ -98,21 +99,22 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
     return false;
   }
 
-  std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators;
-  cmLocalVisualStudio7Generator* lg =
-    static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
+  std::vector<std::unique_ptr<cmLocalGenerator>> const& generators =
+    this->LocalGenerators;
+  auto& lg =
+    cm::static_reference_cast<cmLocalVisualStudio7Generator>(generators[0]);
 
   const char* no_working_directory = nullptr;
   std::vector<std::string> no_byproducts;
   std::vector<std::string> no_depends;
   cmCustomCommandLines no_commands;
-  cmTarget* tgt = lg->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
-                                        no_working_directory, no_byproducts,
-                                        no_depends, no_commands);
+  cmTarget* tgt = lg.AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
+                                       no_working_directory, no_byproducts,
+                                       no_depends, no_commands);
 
-  auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+  auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
   auto gt = ptr.get();
-  lg->AddGeneratorTarget(std::move(ptr));
+  lg.AddGeneratorTarget(std::move(ptr));
 
   // Organize in the "predefined targets" folder:
   //
@@ -130,7 +132,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
                stampList);
     std::string stampFile;
     cmGeneratedFileStream fout(stampListFile.c_str());
-    for (cmLocalGenerator const* gi : generators) {
+    for (const auto& gi : generators) {
       stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(),
                            "/CMakeFiles/generate.stamp");
       fout << stampFile << "\n";
@@ -143,7 +145,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
     // Collect the input files used to generate all targets in this
     // project.
     std::vector<std::string> listFiles;
-    for (cmLocalGenerator* gen : generators) {
+    for (const auto& gen : generators) {
       cmAppend(listFiles, gen->GetMakefile()->GetListFiles());
     }
 
@@ -155,7 +157,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
       std::vector<std::string> byproducts;
       byproducts.push_back(cm->GetGlobVerifyStamp());
 
-      lg->AddCustomCommandToTarget(
+      lg.AddCustomCommandToTarget(
         CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends,
         verifyCommandLines, cmCustomCommandType::PRE_BUILD,
         "Checking File Globs", no_working_directory, false);
@@ -173,10 +175,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
     listFiles.erase(new_end, listFiles.end());
 
     // Create a rule to re-run CMake.
-    std::string argS = cmStrCat("-S", lg->GetSourceDirectory());
-    std::string argB = cmStrCat("-B", lg->GetBinaryDirectory());
+    std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
+    std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
     std::string const sln =
-      lg->GetBinaryDirectory() + "/" + lg->GetProjectName() + ".sln";
+      lg.GetBinaryDirectory() + "/" + lg.GetProjectName() + ".sln";
     cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
       { cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list",
         stampList, "--vs-solution-file", sln });
@@ -187,7 +189,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
     // (this could be avoided with per-target source files)
     std::string no_main_dependency;
     cmImplicitDependsList no_implicit_depends;
-    if (cmSourceFile* file = lg->AddCustomCommandToOutput(
+    if (cmSourceFile* file = lg.AddCustomCommandToOutput(
           stamps, no_byproducts, listFiles, no_main_dependency,
           no_implicit_depends, commandLines, "Checking Build System",
           no_working_directory, true, false)) {

+ 5 - 3
Source/cmGlobalXCodeGenerator.cxx

@@ -392,9 +392,11 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
 }
 
 //! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalXCodeGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalXCodeGenerator::CreateLocalGenerator(
+  cmMakefile* mf)
 {
-  return new cmLocalXCodeGenerator(this, mf);
+  return std::unique_ptr<cmLocalGenerator>(
+    cm::make_unique<cmLocalXCodeGenerator>(this, mf));
 }
 
 void cmGlobalXCodeGenerator::AddExtraIDETargets()
@@ -1363,7 +1365,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
 
 void cmGlobalXCodeGenerator::ForceLinkerLanguages()
 {
-  for (auto localGenerator : this->LocalGenerators) {
+  for (const auto& localGenerator : this->LocalGenerators) {
     // All targets depend on the build-system check target.
     for (const auto& tgt : localGenerator->GetGeneratorTargets()) {
       // This makes sure all targets link using the proper language.

+ 3 - 1
Source/cmGlobalXCodeGenerator.h

@@ -7,6 +7,7 @@
 
 #include <iosfwd>
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
@@ -47,7 +48,8 @@ public:
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   //! Create a local generator appropriate to this Global Generator
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+    cmMakefile* mf) override;
 
   /**
    * Try to determine system information such as shared library

+ 1 - 1
Source/cmGraphVizWriter.cxx

@@ -277,7 +277,7 @@ void cmGraphVizWriter::Write()
   std::set<cmGeneratorTarget const*, cmGeneratorTarget::StrictTargetComparison>
     sortedGeneratorTargets;
 
-  for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
+  for (const auto& lg : gg->GetLocalGenerators()) {
     for (const auto& gt : lg->GetGeneratorTargets()) {
       // Reserved targets have inconsistent names across platforms (e.g. 'all'
       // vs. 'ALL_BUILD'), which can disrupt the traversal ordering.

+ 1 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -1094,8 +1094,7 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
     return;
   }
 
-  cmLocalGenerator* rootLG =
-    this->GetGlobalGenerator()->GetLocalGenerators().at(0);
+  const auto& rootLG = this->GetGlobalGenerator()->GetLocalGenerators().at(0);
   std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory();
   std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory();
   std::string cleanfile =

+ 4 - 4
Source/cmQtAutoGenGlobalInitializer.cxx

@@ -40,9 +40,9 @@ cmQtAutoGenGlobalInitializer::Keywords::Keywords()
 }
 
 cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
-  std::vector<cmLocalGenerator*> const& localGenerators)
+  std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators)
 {
-  for (cmLocalGenerator* localGen : localGenerators) {
+  for (const auto& localGen : localGenerators) {
     // Detect global autogen and autorcc target names
     bool globalAutoGenTarget = false;
     bool globalAutoRccTarget = false;
@@ -55,7 +55,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
         if (targetName.empty()) {
           targetName = "autogen";
         }
-        GlobalAutoGenTargets_.emplace(localGen, std::move(targetName));
+        GlobalAutoGenTargets_.emplace(localGen.get(), std::move(targetName));
         globalAutoGenTarget = true;
       }
 
@@ -66,7 +66,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
         if (targetName.empty()) {
           targetName = "autorcc";
         }
-        GlobalAutoRccTargets_.emplace(localGen, std::move(targetName));
+        GlobalAutoRccTargets_.emplace(localGen.get(), std::move(targetName));
         globalAutoRccTarget = true;
       }
     }

+ 1 - 1
Source/cmQtAutoGenGlobalInitializer.h

@@ -48,7 +48,7 @@ public:
 
 public:
   cmQtAutoGenGlobalInitializer(
-    std::vector<cmLocalGenerator*> const& localGenerators);
+    std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators);
   ~cmQtAutoGenGlobalInitializer();
 
   Keywords const& kw() const { return Keywords_; };

+ 2 - 2
Source/cmake.cxx

@@ -538,7 +538,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
     std::vector<std::string> includeDirs = cmExpandedList(includes);
 
     gg->CreateGenerationObjects();
-    cmLocalGenerator* lg = gg->LocalGenerators[0];
+    const auto& lg = gg->LocalGenerators[0];
     std::string includeFlags =
       lg->GetIncludeFlags(includeDirs, nullptr, language);
 
@@ -2169,7 +2169,7 @@ int cmake::CheckBuildSystem()
     if (ggd) {
       cm.GetCurrentSnapshot().SetDefaultDefinitions();
       cmMakefile mfd(ggd.get(), cm.GetCurrentSnapshot());
-      std::unique_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator(&mfd));
+      auto lgd = ggd->CreateLocalGenerator(&mfd);
       lgd->ClearDependencies(&mfd, verbose);
     }
   }

+ 1 - 1
Source/cmcmd.cxx

@@ -1084,7 +1084,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
         snapshot.GetDirectory().SetCurrentBinary(startOutDir);
         snapshot.GetDirectory().SetCurrentSource(startDir);
         cmMakefile mf(ggd, snapshot);
-        std::unique_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator(&mf));
+        auto lgd = ggd->CreateLocalGenerator(&mf);
 
         // Actually scan dependencies.
         return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;