Просмотр исходного кода

Refactor extra generator registration to use factories

This will allow additional information about the availability
and capabilities of extra generators to be queried without
actually creating them.

Instead of a static NewFactory() method like the main generator
factories have, use a static GetFactory() method to get a pointer to a
statically allocated extra generator factory.  This simplifies memory
management.
Tobias Hunger 9 лет назад
Родитель
Сommit
a354f60ce0

+ 29 - 20
Source/cmExternalMakefileProjectGenerator.cxx

@@ -33,28 +33,37 @@ std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
   return fullName;
 }
 
-std::string cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
-  const std::string& fullName)
+cmExternalMakefileProjectGeneratorFactory::
+  cmExternalMakefileProjectGeneratorFactory(const std::string& n,
+                                            const std::string& doc)
+  : Name(n)
+  , Documentation(doc)
 {
-  // at least one global generator must be supported
-  assert(!this->SupportedGlobalGenerators.empty());
+}
 
-  if (fullName.empty()) {
-    return "";
-  }
+cmExternalMakefileProjectGeneratorFactory::
+  ~cmExternalMakefileProjectGeneratorFactory()
+{
+}
 
-  // if we get only the short name, take the first global generator as default
-  if (fullName == this->GetName()) {
-    return this->SupportedGlobalGenerators[0];
-  }
+std::string cmExternalMakefileProjectGeneratorFactory::GetName() const
+{
+  return this->Name;
+}
 
-  // otherwise search for the matching global generator
-  for (std::vector<std::string>::const_iterator it =
-         this->SupportedGlobalGenerators.begin();
-       it != this->SupportedGlobalGenerators.end(); ++it) {
-    if (this->CreateFullGeneratorName(*it, this->GetName()) == fullName) {
-      return *it;
-    }
-  }
-  return "";
+std::string cmExternalMakefileProjectGeneratorFactory::GetDocumentation() const
+{
+  return this->Documentation;
+}
+
+std::vector<std::string>
+cmExternalMakefileProjectGeneratorFactory::GetSupportedGlobalGenerators() const
+{
+  return this->SupportedGlobalGenerators;
+}
+
+void cmExternalMakefileProjectGeneratorFactory::AddSupportedGlobalGenerator(
+  const std::string& base)
+{
+  this->SupportedGlobalGenerators.push_back(base);
 }

+ 48 - 7
Source/cmExternalMakefileProjectGenerator.h

@@ -35,11 +35,6 @@ class cmExternalMakefileProjectGenerator
 public:
   virtual ~cmExternalMakefileProjectGenerator() {}
 
-  ///! Get the name for this generator.
-  virtual std::string GetName() const = 0;
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry,
-                                const std::string& fullName) const = 0;
   virtual void EnableLanguage(std::vector<std::string> const& languages,
                               cmMakefile*, bool optional);
 
@@ -55,8 +50,6 @@ public:
     return this->SupportedGlobalGenerators;
   }
 
-  ///! Get the name of the global generator for the given full name
-  std::string GetGlobalGeneratorName(const std::string& fullName);
   /** Create a full name from the given global generator name and the
    * extra generator name
    */
@@ -66,11 +59,59 @@ public:
   ///! Generate the project files, the Makefiles have already been generated
   virtual void Generate() = 0;
 
+  void SetName(const std::string& n) { Name = n; }
+  std::string GetName() const { return Name; }
+
 protected:
   ///! Contains the names of the global generators support by this generator.
   std::vector<std::string> SupportedGlobalGenerators;
   ///! the global generator which creates the makefiles
   const cmGlobalGenerator* GlobalGenerator;
+
+  std::string Name;
+};
+
+class cmExternalMakefileProjectGeneratorFactory
+{
+public:
+  cmExternalMakefileProjectGeneratorFactory(const std::string& n,
+                                            const std::string& doc);
+  virtual ~cmExternalMakefileProjectGeneratorFactory();
+
+  std::string GetName() const;
+  std::string GetDocumentation() const;
+  std::vector<std::string> GetSupportedGlobalGenerators() const;
+  std::vector<std::string> Aliases;
+
+  virtual cmExternalMakefileProjectGenerator*
+  CreateExternalMakefileProjectGenerator() const = 0;
+
+  void AddSupportedGlobalGenerator(const std::string& base);
+
+private:
+  std::string Name;
+  std::string Documentation;
+  std::vector<std::string> SupportedGlobalGenerators;
+};
+
+template <class T>
+class cmExternalMakefileProjectGeneratorSimpleFactory
+  : public cmExternalMakefileProjectGeneratorFactory
+{
+public:
+  cmExternalMakefileProjectGeneratorSimpleFactory(const std::string& n,
+                                                  const std::string& doc)
+    : cmExternalMakefileProjectGeneratorFactory(n, doc)
+  {
+  }
+
+  cmExternalMakefileProjectGenerator* CreateExternalMakefileProjectGenerator()
+    const
+  {
+    T* p = new T;
+    p->SetName(GetName());
+    return p;
+  }
 };
 
 #endif

+ 17 - 11
Source/cmExtraCodeBlocksGenerator.cxx

@@ -36,24 +36,30 @@ Discussion:
 http://forums.codeblocks.org/index.php/topic,6789.0.html
 */
 
-void cmExtraCodeBlocksGenerator::GetDocumentation(cmDocumentationEntry& entry,
-                                                  const std::string&) const
+cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
+  : cmExternalMakefileProjectGenerator()
 {
-  entry.Name = this->GetName();
-  entry.Brief = "Generates CodeBlocks project files.";
 }
 
-cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
-  : cmExternalMakefileProjectGenerator()
+cmExternalMakefileProjectGeneratorFactory*
+cmExtraCodeBlocksGenerator::GetFactory()
 {
+  static cmExternalMakefileProjectGeneratorSimpleFactory<
+    cmExtraCodeBlocksGenerator>
+    factory("CodeBlocks", "Generates CodeBlocks project files.");
+
+  if (factory.GetSupportedGlobalGenerators().empty()) {
 #if defined(_WIN32)
-  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
-  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
+    factory.AddSupportedGlobalGenerator("NMake Makefiles");
 // disable until somebody actually tests it:
-//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
+// this->AddSupportedGlobalGenerator("MSYS Makefiles");
 #endif
-  this->SupportedGlobalGenerators.push_back("Ninja");
-  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+    factory.AddSupportedGlobalGenerator("Ninja");
+    factory.AddSupportedGlobalGenerator("Unix Makefiles");
+  }
+
+  return &factory;
 }
 
 void cmExtraCodeBlocksGenerator::Generate()

+ 1 - 12
Source/cmExtraCodeBlocksGenerator.h

@@ -28,18 +28,7 @@ class cmExtraCodeBlocksGenerator : public cmExternalMakefileProjectGenerator
 public:
   cmExtraCodeBlocksGenerator();
 
-  std::string GetName() const CM_OVERRIDE
-  {
-    return cmExtraCodeBlocksGenerator::GetActualName();
-  }
-  static std::string GetActualName() { return "CodeBlocks"; }
-  static cmExternalMakefileProjectGenerator* New()
-  {
-    return new cmExtraCodeBlocksGenerator;
-  }
-  /** Get the documentation entry for this generator.  */
-  void GetDocumentation(cmDocumentationEntry& entry,
-                        const std::string& fullName) const CM_OVERRIDE;
+  static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
   void Generate() CM_OVERRIDE;
 

+ 17 - 11
Source/cmExtraCodeLiteGenerator.cxx

@@ -27,24 +27,30 @@
 #include <cmsys/SystemInformation.hxx>
 #include <cmsys/SystemTools.hxx>
 
-void cmExtraCodeLiteGenerator::GetDocumentation(cmDocumentationEntry& entry,
-                                                const std::string&) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates CodeLite project files.";
-}
-
 cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator()
   : cmExternalMakefileProjectGenerator()
   , ConfigName("NoConfig")
   , CpuCount(2)
 {
+}
+
+cmExternalMakefileProjectGeneratorFactory*
+cmExtraCodeLiteGenerator::GetFactory()
+{
+  static cmExternalMakefileProjectGeneratorSimpleFactory<
+    cmExtraCodeLiteGenerator>
+    factory("CodeLite", "Generates CodeLite project files.");
+
+  if (factory.GetSupportedGlobalGenerators().empty()) {
 #if defined(_WIN32)
-  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
-  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
+    factory.AddSupportedGlobalGenerator("NMake Makefiles");
 #endif
-  this->SupportedGlobalGenerators.push_back("Ninja");
-  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+    factory.AddSupportedGlobalGenerator("Ninja");
+    factory.AddSupportedGlobalGenerator("Unix Makefiles");
+  }
+
+  return &factory;
 }
 
 void cmExtraCodeLiteGenerator::Generate()

+ 1 - 12
Source/cmExtraCodeLiteGenerator.h

@@ -36,18 +36,7 @@ protected:
 public:
   cmExtraCodeLiteGenerator();
 
-  std::string GetName() const CM_OVERRIDE
-  {
-    return cmExtraCodeLiteGenerator::GetActualName();
-  }
-  static std::string GetActualName() { return "CodeLite"; }
-  static cmExternalMakefileProjectGenerator* New()
-  {
-    return new cmExtraCodeLiteGenerator;
-  }
-  /** Get the documentation entry for this generator.  */
-  void GetDocumentation(cmDocumentationEntry& entry,
-                        const std::string& fullName) const CM_OVERRIDE;
+  static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
   void Generate() CM_OVERRIDE;
   void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);

+ 19 - 14
Source/cmExtraEclipseCDT4Generator.cxx

@@ -46,16 +46,6 @@ void AppendDictionary(cmXMLWriter& xml, const char* key, T const& value)
 cmExtraEclipseCDT4Generator::cmExtraEclipseCDT4Generator()
   : cmExternalMakefileProjectGenerator()
 {
-// TODO: Verify if __CYGWIN__ should be checked.
-//#if defined(_WIN32) && !defined(__CYGWIN__)
-#if defined(_WIN32)
-  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
-  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
-//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
-#endif
-  this->SupportedGlobalGenerators.push_back("Ninja");
-  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
-
   this->SupportsVirtualFolders = true;
   this->GenerateLinkedResources = true;
   this->SupportsGmakeErrorParser = true;
@@ -64,11 +54,26 @@ cmExtraEclipseCDT4Generator::cmExtraEclipseCDT4Generator()
   this->CXXEnabled = false;
 }
 
-void cmExtraEclipseCDT4Generator::GetDocumentation(cmDocumentationEntry& entry,
-                                                   const std::string&) const
+cmExternalMakefileProjectGeneratorFactory*
+cmExtraEclipseCDT4Generator::GetFactory()
 {
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Eclipse CDT 4.0 project files.";
+  static cmExternalMakefileProjectGeneratorSimpleFactory<
+    cmExtraEclipseCDT4Generator>
+    factory("Eclipse CDT4", "Generates Eclipse CDT 4.0 project files.");
+
+  if (factory.GetSupportedGlobalGenerators().empty()) {
+// TODO: Verify if __CYGWIN__ should be checked.
+//#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32)
+    factory.AddSupportedGlobalGenerator("NMake Makefiles");
+    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
+// factory.AddSupportedGlobalGenerator("MSYS Makefiles");
+#endif
+    factory.AddSupportedGlobalGenerator("Ninja");
+    factory.AddSupportedGlobalGenerator("Unix Makefiles");
+  }
+
+  return &factory;
 }
 
 void cmExtraEclipseCDT4Generator::EnableLanguage(

+ 1 - 13
Source/cmExtraEclipseCDT4Generator.h

@@ -35,20 +35,8 @@ public:
 
   cmExtraEclipseCDT4Generator();
 
-  static cmExternalMakefileProjectGenerator* New()
-  {
-    return new cmExtraEclipseCDT4Generator;
-  }
-
-  std::string GetName() const CM_OVERRIDE
-  {
-    return cmExtraEclipseCDT4Generator::GetActualName();
-  }
-
-  static std::string GetActualName() { return "Eclipse CDT4"; }
+  static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
-  void GetDocumentation(cmDocumentationEntry& entry,
-                        const std::string& fullName) const CM_OVERRIDE;
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
                       bool optional) CM_OVERRIDE;
 

+ 15 - 11
Source/cmExtraKateGenerator.cxx

@@ -22,24 +22,28 @@
 
 #include <cmsys/SystemTools.hxx>
 
-void cmExtraKateGenerator::GetDocumentation(cmDocumentationEntry& entry,
-                                            const std::string&) const
+cmExtraKateGenerator::cmExtraKateGenerator()
+  : cmExternalMakefileProjectGenerator()
 {
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Kate project files.";
 }
 
-cmExtraKateGenerator::cmExtraKateGenerator()
-  : cmExternalMakefileProjectGenerator()
+cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory()
 {
+  static cmExternalMakefileProjectGeneratorSimpleFactory<cmExtraKateGenerator>
+    factory("Kate", "Generates Kate project files.");
+
+  if (factory.GetSupportedGlobalGenerators().empty()) {
 #if defined(_WIN32)
-  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
-  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
+    factory.AddSupportedGlobalGenerator("NMake Makefiles");
 // disable until somebody actually tests it:
-//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
+// factory.AddSupportedGlobalGenerator("MSYS Makefiles");
 #endif
-  this->SupportedGlobalGenerators.push_back("Ninja");
-  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+    factory.AddSupportedGlobalGenerator("Ninja");
+    factory.AddSupportedGlobalGenerator("Unix Makefiles");
+  }
+
+  return &factory;
 }
 
 void cmExtraKateGenerator::Generate()

+ 1 - 12
Source/cmExtraKateGenerator.h

@@ -26,18 +26,7 @@ class cmExtraKateGenerator : public cmExternalMakefileProjectGenerator
 public:
   cmExtraKateGenerator();
 
-  std::string GetName() const CM_OVERRIDE
-  {
-    return cmExtraKateGenerator::GetActualName();
-  }
-  static std::string GetActualName() { return "Kate"; }
-  static cmExternalMakefileProjectGenerator* New()
-  {
-    return new cmExtraKateGenerator;
-  }
-  /** Get the documentation entry for this generator.  */
-  void GetDocumentation(cmDocumentationEntry& entry,
-                        const std::string& fullName) const CM_OVERRIDE;
+  static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
   void Generate() CM_OVERRIDE;
 

+ 18 - 12
Source/cmExtraSublimeTextGenerator.cxx

@@ -38,24 +38,30 @@ http://www.sublimetext.com/docs/2/projects.html
 http://sublimetext.info/docs/en/reference/build_systems.html
 */
 
-void cmExtraSublimeTextGenerator::GetDocumentation(cmDocumentationEntry& entry,
-                                                   const std::string&) const
+cmExternalMakefileProjectGeneratorFactory*
+cmExtraSublimeTextGenerator::GetFactory()
 {
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Sublime Text 2 project files.";
+  static cmExternalMakefileProjectGeneratorSimpleFactory<
+    cmExtraSublimeTextGenerator>
+    factory("Sublime Text 2", "Generates Sublime Text 2 project files.");
+
+  if (factory.GetSupportedGlobalGenerators().empty()) {
+#if defined(_WIN32)
+    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
+    factory.AddSupportedGlobalGenerator("NMake Makefiles");
+// disable until somebody actually tests it:
+// factory.AddSupportedGlobalGenerator("MSYS Makefiles");
+#endif
+    factory.AddSupportedGlobalGenerator("Ninja");
+    factory.AddSupportedGlobalGenerator("Unix Makefiles");
+  }
+
+  return &factory;
 }
 
 cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator()
   : cmExternalMakefileProjectGenerator()
 {
-#if defined(_WIN32)
-  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
-  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
-// disable until somebody actually tests it:
-//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
-#endif
-  this->SupportedGlobalGenerators.push_back("Ninja");
-  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
 }
 
 void cmExtraSublimeTextGenerator::Generate()

+ 1 - 13
Source/cmExtraSublimeTextGenerator.h

@@ -27,22 +27,10 @@ class cmGeneratorTarget;
 class cmExtraSublimeTextGenerator : public cmExternalMakefileProjectGenerator
 {
 public:
+  static cmExternalMakefileProjectGeneratorFactory* GetFactory();
   typedef std::map<std::string, std::vector<std::string> > MapSourceFileFlags;
   cmExtraSublimeTextGenerator();
 
-  std::string GetName() const CM_OVERRIDE
-  {
-    return cmExtraSublimeTextGenerator::GetActualName();
-  }
-  static std::string GetActualName() { return "Sublime Text 2"; }
-  static cmExternalMakefileProjectGenerator* New()
-  {
-    return new cmExtraSublimeTextGenerator;
-  }
-  /** Get the documentation entry for this generator.  */
-  void GetDocumentation(cmDocumentationEntry& entry,
-                        const std::string& fullName) const CM_OVERRIDE;
-
   void Generate() CM_OVERRIDE;
 
 private:

+ 16 - 8
Source/cmGlobalKdevelopGenerator.cxx

@@ -25,20 +25,28 @@
 #include <cmsys/FStream.hxx>
 #include <cmsys/SystemTools.hxx>
 
-void cmGlobalKdevelopGenerator::GetDocumentation(cmDocumentationEntry& entry,
-                                                 const std::string&) const
+cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
+  : cmExternalMakefileProjectGenerator()
 {
-  entry.Name = this->GetName();
-  entry.Brief = "Generates KDevelop 3 project files.";
 }
 
-cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
-  : cmExternalMakefileProjectGenerator()
+cmExternalMakefileProjectGeneratorFactory*
+cmGlobalKdevelopGenerator::GetFactory()
 {
-  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+  static cmExternalMakefileProjectGeneratorSimpleFactory<
+    cmGlobalKdevelopGenerator>
+    factory("KDevelop3", "Generates KDevelop 3 project files.");
+
+  if (factory.GetSupportedGlobalGenerators().empty()) {
+    factory.AddSupportedGlobalGenerator("Unix Makefiles");
 #ifdef CMAKE_USE_NINJA
-  this->SupportedGlobalGenerators.push_back("Ninja");
+    factory.AddSupportedGlobalGenerator("Ninja");
 #endif
+
+    factory.Aliases.push_back("KDevelop3");
+  }
+
+  return &factory;
 }
 
 void cmGlobalKdevelopGenerator::Generate()

+ 1 - 12
Source/cmGlobalKdevelopGenerator.h

@@ -33,18 +33,7 @@ class cmGlobalKdevelopGenerator : public cmExternalMakefileProjectGenerator
 public:
   cmGlobalKdevelopGenerator();
 
-  std::string GetName() const CM_OVERRIDE
-  {
-    return cmGlobalKdevelopGenerator::GetActualName();
-  }
-  static std::string GetActualName() { return "KDevelop3"; }
-  static cmExternalMakefileProjectGenerator* New()
-  {
-    return new cmGlobalKdevelopGenerator;
-  }
-  /** Get the documentation entry for this generator.  */
-  void GetDocumentation(cmDocumentationEntry& entry,
-                        const std::string& fullName) const CM_OVERRIDE;
+  static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
   void Generate() CM_OVERRIDE;
 

+ 86 - 59
Source/cmake.cxx

@@ -793,53 +793,21 @@ int cmake::AddCMakePaths()
   return 1;
 }
 
-void cmake::AddExtraGenerator(const std::string& name,
-                              CreateExtraGeneratorFunctionType newFunction)
-{
-  cmExternalMakefileProjectGenerator* extraGenerator = newFunction();
-  const std::vector<std::string>& supportedGlobalGenerators =
-    extraGenerator->GetSupportedGlobalGenerators();
-
-  for (std::vector<std::string>::const_iterator it =
-         supportedGlobalGenerators.begin();
-       it != supportedGlobalGenerators.end(); ++it) {
-    std::string fullName =
-      cmExternalMakefileProjectGenerator::CreateFullGeneratorName(*it, name);
-    this->ExtraGenerators[fullName] = newFunction;
-  }
-  delete extraGenerator;
-}
-
 void cmake::AddDefaultExtraGenerators()
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-#if defined(_WIN32) && !defined(__CYGWIN__)
-// e.g. kdevelop4 ?
-#endif
-
-  this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(),
-                          &cmExtraCodeBlocksGenerator::New);
-  this->AddExtraGenerator(cmExtraCodeLiteGenerator::GetActualName(),
-                          &cmExtraCodeLiteGenerator::New);
-  this->AddExtraGenerator(cmExtraSublimeTextGenerator::GetActualName(),
-                          &cmExtraSublimeTextGenerator::New);
-  this->AddExtraGenerator(cmExtraKateGenerator::GetActualName(),
-                          &cmExtraKateGenerator::New);
+  this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
+  this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
+  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
+  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
 
 #ifdef CMAKE_USE_ECLIPSE
-  this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(),
-                          &cmExtraEclipseCDT4Generator::New);
+  this->ExtraGenerators.push_back(cmExtraEclipseCDT4Generator::GetFactory());
 #endif
 
 #ifdef CMAKE_USE_KDEVELOP
-  this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(),
-                          &cmGlobalKdevelopGenerator::New);
-  // for kdevelop also add the generator with just the name of the
-  // extra generator, since it was this way since cmake 2.2
-  this->ExtraGenerators[cmGlobalKdevelopGenerator::GetActualName()] =
-    &cmGlobalKdevelopGenerator::New;
+  this->ExtraGenerators.push_back(cmGlobalKdevelopGenerator::GetFactory());
 #endif
-
 #endif
 }
 
@@ -856,32 +824,74 @@ void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators)
       info.supportsToolset = (*i)->SupportsToolset();
       info.supportsPlatform = (*i)->SupportsPlatform();
       info.name = names[j];
+      info.isAlias = false;
       generators.push_back(info);
     }
   }
 
-  for (RegisteredExtraGeneratorsMap::const_iterator
+  for (RegisteredExtraGeneratorsVector::const_iterator
          i = this->ExtraGenerators.begin(),
          e = this->ExtraGenerators.end();
        i != e; ++i) {
-    GeneratorInfo info;
-    info.name = i->first;
-    info.supportsToolset = false;
-    info.supportsPlatform = false;
-    generators.push_back(info);
+    const std::vector<std::string> genList =
+      (*i)->GetSupportedGlobalGenerators();
+    for (std::vector<std::string>::const_iterator gen = genList.begin();
+         gen != genList.end(); ++gen) {
+      GeneratorInfo info;
+      info.name = cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+        (*i)->GetName(), *gen);
+      info.supportsPlatform = false;
+      info.supportsToolset = false;
+      info.isAlias = false;
+      generators.push_back(info);
+    }
+    for (std::vector<std::string>::const_iterator a = (*i)->Aliases.begin();
+         a != (*i)->Aliases.end(); ++a) {
+      GeneratorInfo info;
+      info.name = *a;
+      info.supportsPlatform = false;
+      info.supportsToolset = false;
+      info.isAlias = true;
+      generators.push_back(info);
+    }
   }
 }
 
-cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
+static std::pair<cmExternalMakefileProjectGenerator*, std::string>
+createExtraGenerator(
+  const std::vector<cmExternalMakefileProjectGeneratorFactory*>& in,
+  const std::string& name)
 {
-  cmExternalMakefileProjectGenerator* extraGenerator = CM_NULLPTR;
-  std::string name = gname;
-  RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
-    this->ExtraGenerators.find(name);
-  if (extraGenIt != this->ExtraGenerators.end()) {
-    extraGenerator = (extraGenIt->second)();
-    name = extraGenerator->GetGlobalGeneratorName(name);
+  for (std::vector<cmExternalMakefileProjectGeneratorFactory*>::const_iterator
+         i = in.begin();
+       i != in.end(); ++i) {
+    const std::vector<std::string> generators =
+      (*i)->GetSupportedGlobalGenerators();
+    if ((*i)->GetName() == name) { // Match aliases
+      return std::make_pair((*i)->CreateExternalMakefileProjectGenerator(),
+                            generators.at(0));
+    }
+    for (std::vector<std::string>::const_iterator g = generators.begin();
+         g != generators.end(); ++g) {
+      const std::string fullName =
+        cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+          *g, (*i)->GetName());
+      if (fullName == name) {
+        return std::make_pair((*i)->CreateExternalMakefileProjectGenerator(),
+                              *g);
+      }
+    }
   }
+  return std::make_pair(
+    static_cast<cmExternalMakefileProjectGenerator*>(CM_NULLPTR), name);
+}
+
+cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
+{
+  std::pair<cmExternalMakefileProjectGenerator*, std::string> extra =
+    createExtraGenerator(this->ExtraGenerators, gname);
+  cmExternalMakefileProjectGenerator* extraGenerator = extra.first;
+  const std::string name = extra.second;
 
   cmGlobalGenerator* generator = CM_NULLPTR;
   for (RegisteredGeneratorsVector::const_iterator i = this->Generators.begin();
@@ -1651,15 +1661,32 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
     (*i)->GetDocumentation(e);
     v.push_back(e);
   }
-  for (RegisteredExtraGeneratorsMap::const_iterator i =
+  for (RegisteredExtraGeneratorsVector::const_iterator i =
          this->ExtraGenerators.begin();
        i != this->ExtraGenerators.end(); ++i) {
-    cmDocumentationEntry e;
-    cmExternalMakefileProjectGenerator* generator = (i->second)();
-    generator->GetDocumentation(e, i->first);
-    e.Name = i->first;
-    delete generator;
-    v.push_back(e);
+    const std::string doc = (*i)->GetDocumentation();
+    const std::string name = (*i)->GetName();
+
+    // Aliases:
+    for (std::vector<std::string>::const_iterator a = (*i)->Aliases.begin();
+         a != (*i)->Aliases.end(); ++a) {
+      cmDocumentationEntry e;
+      e.Name = *a;
+      e.Brief = doc;
+      v.push_back(e);
+    }
+
+    // Full names:
+    const std::vector<std::string> generators =
+      (*i)->GetSupportedGlobalGenerators();
+    for (std::vector<std::string>::const_iterator g = generators.begin();
+         g != generators.end(); ++g) {
+      cmDocumentationEntry e;
+      e.Name =
+        cmExternalMakefileProjectGenerator::CreateFullGeneratorName(*g, name);
+      e.Brief = doc;
+      v.push_back(e);
+    }
   }
 }
 

+ 5 - 8
Source/cmake.h

@@ -27,7 +27,7 @@ class cmLocalGenerator;
 class cmMakefile;
 class cmVariableWatch;
 class cmFileTimeComparison;
-class cmExternalMakefileProjectGenerator;
+class cmExternalMakefileProjectGeneratorFactory;
 class cmDocumentationSection;
 class cmTarget;
 class cmGeneratedFileStream;
@@ -105,6 +105,7 @@ public:
     std::string name;
     bool supportsToolset;
     bool supportsPlatform;
+    bool isAlias;
   };
 
   typedef std::map<std::string, cmInstalledFile> InstalledFilesMap;
@@ -416,18 +417,14 @@ protected:
   void InitializeProperties();
   int HandleDeleteCacheVariables(const std::string& var);
 
-  typedef cmExternalMakefileProjectGenerator* (
-    *CreateExtraGeneratorFunctionType)();
-  typedef std::map<std::string, CreateExtraGeneratorFunctionType>
-    RegisteredExtraGeneratorsMap;
   typedef std::vector<cmGlobalGeneratorFactory*> RegisteredGeneratorsVector;
   RegisteredGeneratorsVector Generators;
-  RegisteredExtraGeneratorsMap ExtraGenerators;
+  typedef std::vector<cmExternalMakefileProjectGeneratorFactory*>
+    RegisteredExtraGeneratorsVector;
+  RegisteredExtraGeneratorsVector ExtraGenerators;
   void AddDefaultCommands();
   void AddDefaultGenerators();
   void AddDefaultExtraGenerators();
-  void AddExtraGenerator(const std::string& name,
-                         CreateExtraGeneratorFunctionType newFunction);
 
   cmGlobalGenerator* GlobalGenerator;
   std::map<std::string, DiagLevel> DiagLevels;