瀏覽代碼

ENH: add cmExternalMakefileProjectGenerator, which should make it easier to
write generators for IDE projects, which use already existing makefiles
(current the kdevelop generator)
-first stept of the export interface, iniitial export() command
-more replacements for the FIND_XXX docs

Alex

Alexander Neundorf 18 年之前
父節點
當前提交
0ddc9f62e5

+ 1 - 0
Source/cmBootstrapCommands.cxx

@@ -37,6 +37,7 @@
 #include "cmEndForEachCommand.cxx"
 #include "cmEndIfCommand.cxx"
 #include "cmExecProgramCommand.cxx"
+#include "cmExternalMakefileProjectGenerator.cxx"
 #include "cmFindBase.cxx"
 #include "cmFileCommand.cxx"
 #include "cmFindFileCommand.cxx"

+ 2 - 0
Source/cmCommands.cxx

@@ -24,6 +24,7 @@
 #include "cmEndMacroCommand.cxx"
 #include "cmEndWhileCommand.cxx"
 #include "cmExecuteProcessCommand.cxx"
+#include "cmExportCommand.cxx"
 #include "cmExportLibraryDependencies.cxx"
 #include "cmFLTKWrapUICommand.cxx"
 #include "cmGetDirectoryPropertyCommand.cxx"
@@ -76,6 +77,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
   commands.push_back(new cmEndMacroCommand);
   commands.push_back(new cmEndWhileCommand);
   commands.push_back(new cmExecuteProcessCommand);
+  commands.push_back(new cmExportCommand);
   commands.push_back(new cmExportLibraryDependenciesCommand);
   commands.push_back(new cmFLTKWrapUICommand);
   commands.push_back(new cmGetDirectoryPropertyCommand);

+ 233 - 0
Source/cmExportCommand.cxx

@@ -0,0 +1,233 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmExportCommand.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmake.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+// cmExportCommand
+bool cmExportCommand
+::InitialPass(std::vector<std::string> const& args)
+{
+  if(args.size() < 2 )
+    {
+    this->SetError("called with too few arguments");
+    return false;
+    }
+
+  std::string filename;
+  std::string prefix;
+  std::string exportName;
+  std::vector<std::string> targets;
+  bool append = false;
+  if (!this->ParseArgs(args, filename, prefix, exportName, targets, append))
+    {
+    return false;
+    }
+
+  if ( !this->Makefile->CanIWriteThisFile(filename.c_str()) )
+    {
+    std::string e = "attempted to write a file: " + filename
+      + " into a source directory.";
+    this->SetError(e.c_str());
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+    }
+
+  if ((targets.empty()) || (filename.empty()))
+    {
+    return true;
+    }
+
+  // Use copy-if-different if not appending.
+  cmsys::auto_ptr<std::ofstream> foutPtr;
+  if(append)
+    {
+    cmsys::auto_ptr<std::ofstream> ap(
+      new std::ofstream(filename.c_str(), std::ios::app));
+    foutPtr = ap;
+    }
+  else
+    {
+    cmsys::auto_ptr<cmGeneratedFileStream> ap(
+      new cmGeneratedFileStream(filename.c_str(), true));
+    ap->SetCopyIfDifferent(true);
+    foutPtr = ap;
+    }
+  std::ostream& fout = *foutPtr.get();
+
+  if (!fout)
+    {
+    cmSystemTools::Error("Error Writing ", filename.c_str());
+    cmSystemTools::ReportLastSystemError("");
+    return true;
+    }
+
+  // the following code may move into an "export generator"
+  // Compute the set of configurations.
+  std::vector<std::string> configurationTypes;
+  if(const char* types =
+     this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
+    {
+    cmSystemTools::ExpandListArgument(types, configurationTypes);
+    }
+  if(configurationTypes.empty())
+    {
+    const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+    if (config!=0)
+      {
+      configurationTypes.push_back(config);
+      }
+    }
+
+  for(std::vector<std::string>::const_iterator currentTarget = targets.begin();
+      currentTarget != targets.end();
+      ++currentTarget)
+    {
+    // Look for a CMake target with the given name, which is an executable
+    // and which can be run
+    cmTarget* target = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, currentTarget->c_str(), true);
+    if ((target != 0)
+       && ((target->GetType() == cmTarget::EXECUTABLE)
+        || (target->GetType() == cmTarget::STATIC_LIBRARY)
+        || (target->GetType() == cmTarget::SHARED_LIBRARY)
+        || (target->GetType() == cmTarget::MODULE_LIBRARY)))
+      {
+      switch (target->GetType())
+        {
+        case cmTarget::EXECUTABLE:
+          fout << "ADD_EXECUTABLE(" << prefix.c_str() << currentTarget->c_str() << " IMPORT )\n";
+          break;
+        case cmTarget::STATIC_LIBRARY:
+          fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " STATIC IMPORT )\n";
+          break;
+        case cmTarget::SHARED_LIBRARY:
+          fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " SHARED IMPORT )\n";
+          break;
+        case cmTarget::MODULE_LIBRARY:
+          fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " MODULE IMPORT )\n";
+          break;
+        default:  // should never happen
+          break;
+        }
+
+      fout << "SET_TARGET_PROPERTIES(" << prefix.c_str() << currentTarget->c_str() << " PROPERTIES \n";
+      fout << "                      LOCATION " << target->GetLocation(0) << "\n";
+      for(std::vector<std::string>::const_iterator currentConfig = configurationTypes.begin();
+          currentConfig != configurationTypes.end();
+          ++currentConfig)
+        {
+        if (!currentConfig->empty())
+          {
+          const char* loc = target->GetLocation(currentConfig->c_str());
+          if (loc && *loc)
+            {
+            fout << "                      " << currentConfig->c_str()<< "_LOCATION " << loc << "\n";
+            }
+          }
+        }
+      fout << "                     )\n\n";
+      }
+    else
+      {
+      }
+    }
+
+  return true;
+}
+
+bool cmExportCommand::ParseArgs(const std::vector<std::string>& args,
+                                std::string& filename,
+                                std::string& prefix,
+                                std::string& exportName,
+                                std::vector<std::string>& targets,
+                                bool& append) const
+{
+  bool doingFile = false;
+  bool doingPrefix = false;
+  bool doingTargets = false;
+  bool doingName = true;
+  for(std::vector<std::string>::const_iterator it = args.begin();
+      it != args.end();
+      ++it)
+    {
+    if (*it == "FILE")
+      {
+      doingFile = true;
+      doingPrefix = false;
+      doingName = false;
+      doingTargets = false;
+      }
+    else if (*it == "PREFIX")
+      {
+      doingFile = false;
+      doingPrefix = true;
+      doingName = false;
+      doingTargets = false;
+      }
+    else if (*it == "TARGETS")
+      {
+      doingFile = false;
+      doingPrefix = false;
+      doingName = false;
+      doingTargets = true;
+      }
+    else if (*it == "APPEND")
+      {
+      append = true;
+      doingFile = false;
+      doingPrefix = false;
+      doingName = false;
+      doingTargets = false;
+      }
+    else if (doingFile)
+      {
+      filename = *it;
+      doingFile = false;
+      doingPrefix = false;
+      doingName = false;
+      doingTargets = false;
+      }
+    else if (doingPrefix)
+      {
+      prefix = *it;
+      doingFile = false;
+      doingPrefix = false;
+      doingName = false;
+      doingTargets = false;
+      }
+    else if (doingTargets)
+      {
+      targets.push_back(*it);
+      }
+    else if (doingName)
+      {
+      exportName = *it;
+      doingFile = false;
+      doingPrefix = false;
+      doingName = false;
+      doingTargets = false;
+      }
+    else
+      {
+      }
+    }
+  return true;
+}

+ 85 - 0
Source/cmExportCommand.h

@@ -0,0 +1,85 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmExportCommand_h
+#define cmExportCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmExportLibraryDependenciesCommand
+ * \brief Add a test to the lists of tests to run.
+ *
+ * cmExportLibraryDependenciesCommand adds a test to the list of tests to run
+ *
+ */
+class cmExportCommand : public cmCommand
+{
+public:
+  /**
+   * This is a virtual constructor for the command.
+   */
+  virtual cmCommand* Clone()
+    {
+    return new cmExportCommand;
+    }
+
+  /**
+   * This is called when the command is first encountered in
+   * the CMakeLists.txt file.
+   */
+  virtual bool InitialPass(std::vector<std::string> const& args);
+
+  /**
+   * The name of the command as specified in CMakeList.txt.
+   */
+  virtual const char* GetName() { return "EXPORT";}
+
+  /**
+   * Succinct documentation.
+   */
+  virtual const char* GetTerseDocumentation()
+    {
+    return
+      "Write out the dependency information for all targets of a project.";
+    }
+
+  /**
+   * More documentation.
+   */
+  virtual const char* GetFullDocumentation()
+    {
+    return
+      "  EXPORT(TARGETS tgt1 tgt2 ...  [PREFIX <prefix>] FILE <filename> [APPEND])\n"
+      "Create a file that can be included into a CMake listfile with the "
+      "INCLUDE command.  The file will contain a number of SET commands "
+      "that will set all the variables needed for library dependency "
+      "information.  This should be the last command in the top level "
+      "CMakeLists.txt file of the project.  If the APPEND option is "
+      "specified, the SET commands will be appended to the given file "
+      "instead of replacing it.";
+    }
+
+  cmTypeMacro(cmExportCommand, cmCommand);
+
+private:
+  bool ParseArgs(const std::vector<std::string>& args, std::string& filename,
+                 std::string& prefix, std::string& exportName,
+                 std::vector<std::string>& targets, bool& append ) const;
+
+};
+
+
+#endif

+ 70 - 0
Source/cmExternalMakefileProjectGenerator.cxx

@@ -0,0 +1,70 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2007 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include <assert.h>
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+                                                   const char* globalGenerator,
+                                                   const char* extraGenerator)
+{
+  std::string fullName;
+  if (globalGenerator)
+    {
+    fullName = globalGenerator;
+    if (extraGenerator && *extraGenerator)
+      {
+      fullName += " - ";
+      fullName += extraGenerator;
+      }
+    }
+  return fullName;
+}
+
+const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
+                                                          const char* fullName)
+{
+  // at least one global generator must be supported
+  assert(!this->SupportedGlobalGenerators.empty());
+
+  if (fullName==0)
+    {
+    return 0;
+    }
+
+  std::string currentName = fullName;
+  // if we get only the short name, take the first global generator as default
+  if (currentName == this->GetName())
+    {
+    return this->SupportedGlobalGenerators[0].c_str();
+    }
+
+  // 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->c_str(), this->GetName())
+                                                                == currentName)
+      {
+        return it->c_str();
+      }
+    }
+  return 0;
+}

+ 73 - 0
Source/cmExternalMakefileProjectGenerator.h

@@ -0,0 +1,73 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2007 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmExternalMakefileProjectGenerator_h
+#define cmExternalMakefileProjectGenerator_h
+
+#include <vector>
+#include <string>
+
+#include "cmDocumentation.h"
+
+class cmGlobalGenerator;
+
+/** \class cmExternalMakefileProjectGenerator
+ * \brief Base class for generators for "External Makefile based IDE projects".
+ *
+ * cmExternalMakefileProjectGenerator is a base class for generators
+ * for "external makefile based projects", i.e. IDE projects which work 
+ * an already existing makefiles.
+ * See cmGlobalKdevelopGenerator as an example.
+ * After the makefiles have been generated by one of the Makefile 
+ * generators, the Generate() method is called and this generator
+ * can iterate over the local generators and/or projects to produce the 
+ * project files for the IDE.
+ */
+class cmExternalMakefileProjectGenerator
+{
+public:
+  ///! Get the name for this generator.
+  virtual const char* GetName() const = 0;
+  /** Get the documentation entry for this generator.  */
+  virtual void GetDocumentation(cmDocumentationEntry& entry, 
+                                const char* fullName) const = 0;
+
+  ///! set the global generator which will generate the makefiles
+  virtual void SetGlobalGenerator(cmGlobalGenerator* generator)
+                                           {this->GlobalGenerator = generator;}
+
+  ///! Return the list of global generators supported by this extra generator
+  const std::vector<std::string>& GetSupportedGlobalGenerators() const 
+                                      {return this->SupportedGlobalGenerators;}
+
+  ///! Get the name of the global generator for the given full name
+  const char* GetGlobalGeneratorName(const char* fullName);
+  /** Create a full name from the given global generator name and the
+   * extra generator name
+   */
+  static std::string CreateFullGeneratorName(const char* globalGenerator, 
+                                             const char* extraGenerator);
+
+  ///! Generate the project files, the Makefiles have already been generated
+  virtual void Generate() = 0;
+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;
+};
+
+#endif

+ 4 - 0
Source/cmFindLibraryCommand.cxx

@@ -32,6 +32,10 @@ cmFindLibraryCommand::cmFindLibraryCommand()
                                "SEARCH_XXX_DESC", "library");
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                "SEARCH_XXX", "library");
+  cmSystemTools::ReplaceString(this->GenericDocumentation,
+                               "CMAKE_FIND_ROOT_PATH_MODE_XXX", 
+                               "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
+
   this->GenericDocumentation += 
     "\n"
     "If the library found is a framework, then VAR will be set to "

+ 4 - 0
Source/cmFindPathCommand.cxx

@@ -36,6 +36,10 @@ cmFindPathCommand::cmFindPathCommand()
                                "directory containing the named file");
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                "SEARCH_XXX", "file in a directory");
+  cmSystemTools::ReplaceString(this->GenericDocumentation,
+                               "CMAKE_FIND_ROOT_PATH_MODE_XXX", 
+                               "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
+
   this->ExtraDocAdded = false;
 }
 

+ 3 - 0
Source/cmFindProgramCommand.cxx

@@ -37,6 +37,9 @@ cmFindProgramCommand::cmFindProgramCommand()
                                "SEARCH_XXX_DESC", "program");
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                "SEARCH_XXX", "program");
+  cmSystemTools::ReplaceString(this->GenericDocumentation,
+                               "CMAKE_FIND_ROOT_PATH_MODE_XXX", 
+                               "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
 }
 
 // cmFindProgramCommand

+ 171 - 146
Source/cmGlobalGenerator.cxx

@@ -9,20 +9,21 @@
   Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
   See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
 
-     This software is distributed WITHOUT ANY WARRANTY; without even 
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
      PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
+#include "cmExternalMakefileProjectGenerator.h"
 #include "cmake.h"
 #include "cmMakefile.h"
 #include "cmVersion.h"
 
 #include <stdlib.h> // required for atof
 
-#if defined(_WIN32) && !defined(__CYGWIN__) 
+#if defined(_WIN32) && !defined(__CYGWIN__)
 #include <windows.h>
 #endif
 
@@ -47,10 +48,12 @@ cmGlobalGenerator::cmGlobalGenerator()
 
   // how long to let try compiles run
   this->TryCompileTimeout = 0;
+
+  this->ExtraGenerator = 0;
 }
 
 cmGlobalGenerator::~cmGlobalGenerator()
-{ 
+{
   // Delete any existing cmLocalGenerators
   unsigned int i;
   for (i = 0; i < this->LocalGenerators.size(); ++i)
@@ -58,6 +61,11 @@ cmGlobalGenerator::~cmGlobalGenerator()
     delete this->LocalGenerators[i];
     }
   this->LocalGenerators.clear();
+
+  if (this->ExtraGenerator)
+    {
+    delete this->ExtraGenerator;
+    }
 }
 
 // Find the make program for the generator, required for try compiles
@@ -72,13 +80,13 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
   if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
      || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
     {
-    std::string setMakeProgram = 
+    std::string setMakeProgram =
       mf->GetModulesFile(this->FindMakeProgramFile.c_str());
     if(setMakeProgram.size())
       {
       mf->ReadListFile(0, setMakeProgram.c_str());
       }
-    } 
+    }
   if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
      || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
     {
@@ -120,12 +128,12 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
     // it will stop forwarding output, and let the build finish.
     // Then it will retry the build.  It will continue this
     // untill no text file busy errors occur.
-    std::string cmakexbuild = 
+    std::string cmakexbuild =
       this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
     cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
     cmakexbuild += "cmakexbuild";
-    
-    mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", 
+
+    mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM",
                            cmakexbuild.c_str(),
                            "make program",
                            cmCacheManager::FILEPATH);
@@ -135,49 +143,49 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
 // enable the given language
 //
 // The following files are loaded in this order:
-// 
+//
 // First figure out what OS we are running on:
-// 
+//
 // CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake
-//   CMakeDetermineSystem.cmake - figure out os info and create 
-//                                CMakeSystem.cmake IFF CMAKE_SYSTEM_NAME 
+//   CMakeDetermineSystem.cmake - figure out os info and create
+//                                CMakeSystem.cmake IFF CMAKE_SYSTEM_NAME
 //                                not set
-//   CMakeSystem.cmake - configured file created by 
-//                       CMakeDetermineSystem.cmake IFF CMAKE_SYSTEM_LOADED 
+//   CMakeSystem.cmake - configured file created by
+//                       CMakeDetermineSystem.cmake IFF CMAKE_SYSTEM_LOADED
 
 // Next try and enable all languages found in the languages vector
-// 
+//
 // FOREACH LANG in languages
-//   CMake(LANG)Compiler.cmake - configured file create by 
+//   CMake(LANG)Compiler.cmake - configured file create by
 //                               CMakeDetermine(LANG)Compiler.cmake
-//     CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and 
+//     CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
 //                                          creates CMake(LANG)Compiler.cmake
-//     CMake(LANG)Compiler.cmake - configured file created by 
-//                                 CMakeDetermine(LANG)Compiler.cmake       
+//     CMake(LANG)Compiler.cmake - configured file created by
+//                                 CMakeDetermine(LANG)Compiler.cmake
 //
-// CMakeSystemSpecificInformation.cmake 
+// CMakeSystemSpecificInformation.cmake
 //   - includes Platform/${CMAKE_SYSTEM_NAME}.cmake
 //     may use compiler stuff
 
 // FOREACH LANG in languages
-//   CMake(LANG)Information.cmake 
+//   CMake(LANG)Information.cmake
 //     - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake
 //   CMakeTest(LANG)Compiler.cmake
-//     - Make sure the compiler works with a try compile if 
+//     - Make sure the compiler works with a try compile if
 //       CMakeDetermine(LANG) was loaded
-// 
+//
 // Now load a few files that can override values set in any of the above
 // CMake(PROJECTNAME)Compatibility.cmake
 //   - load any backwards compatibility stuff for current project
 // ${CMAKE_USER_MAKE_RULES_OVERRIDE}
-//   - allow users a chance to override system variables 
+//   - allow users a chance to override system variables
 //
 //
 
-void 
+void
 cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
                                   cmMakefile *mf)
-{  
+{
   if(languages.size() == 0)
     {
     cmSystemTools::Error("EnableLanguage must have a lang specified!");
@@ -187,7 +195,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
   mf->AddDefinition("RUN_CONFIGURE", true);
   std::string rootBin = mf->GetHomeOutputDirectory();
   rootBin += cmake::GetCMakeFilesDirectory();
-  
+
   // If the configuration files path has been set,
   // then we are in a try compile and need to copy the enable language
   // files from the parent cmake bin dir, into the try compile bin dir
@@ -206,8 +214,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     }
 
   // set the dir for parent files so they can be used by modules
-  mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str());  
-                    
+  mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str());
+
   // find and make sure CMAKE_MAKE_PROGRAM is defined
   this->FindMakeProgram(mf);
 
@@ -225,7 +233,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
   // what platform we are running on
   if (!mf->GetDefinition("CMAKE_SYSTEM_NAME"))
     {
-#if defined(_WIN32) && !defined(__CYGWIN__) 
+#if defined(_WIN32) && !defined(__CYGWIN__)
     /* Windows version number data.  */
     OSVERSIONINFO osvi;
     ZeroMemory(&osvi, sizeof(osvi));
@@ -247,9 +255,9 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     mf->ReadListFile(0,fpath.c_str());
     }
   std::map<cmStdString, bool> needTestLanguage;
-  // foreach language 
+  // foreach language
   // load the CMakeDetermine(LANG)Compiler.cmake file to find
-  // the compiler 
+  // the compiler
 
   for(std::vector<std::string>::const_iterator l = languages.begin();
       l != languages.end(); ++l)
@@ -283,19 +291,19 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
         {
         if(!mf->ReadListFile(0,fpath.c_str()))
           {
-          cmSystemTools::Error("Could not find cmake module file:", 
+          cmSystemTools::Error("Could not find cmake module file:",
                                fpath.c_str());
           }
         // if this file was found then the language was already determined
         // to be working
         needTestLanguage[lang] = false;
-        this->SetLanguageEnabled(lang, mf); 
+        this->SetLanguageEnabled(lang, mf);
         // this can only be called after loading CMake(LANG)Compiler.cmake
         }
       }
-      
+
     if(!this->GetLanguageEnabled(lang) )
-      {  
+      {
       if (this->CMakeInstance->GetIsInTryCompile())
         {
         cmSystemTools::Error("This should not have happen. "
@@ -303,18 +311,18 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
                              "using a broken CMakeLists.txt file or a "
                              "problematic release of CMake");
         }
-      // if the CMake(LANG)Compiler.cmake file was not found then 
+      // if the CMake(LANG)Compiler.cmake file was not found then
       // load CMakeDetermine(LANG)Compiler.cmake
       std::string determineCompiler = "CMakeDetermine";
       determineCompiler += lang;
       determineCompiler += "Compiler.cmake";
-      std::string determineFile = 
+      std::string determineFile =
         mf->GetModulesFile(determineCompiler.c_str());
       if(!mf->ReadListFile(0,determineFile.c_str()))
         {
-        cmSystemTools::Error("Could not find cmake module file:", 
+        cmSystemTools::Error("Could not find cmake module file:",
                              determineFile.c_str());
-        }      
+        }
       needTestLanguage[lang] = true;
       determineLanguageCalled = true;
       // Some generators like visual studio should not use the env variables
@@ -331,15 +339,15 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
         compilerEnv += lang;
         compilerEnv += "_COMPILER_ENV_VAR";
         std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str());
-        std::string envVarValue = 
+        std::string envVarValue =
           mf->GetRequiredDefinition(compilerName.c_str());
         std::string env = envVar;
         env += "=";
         env += envVarValue;
         cmSystemTools::PutEnv(env.c_str());
         }
-      } // end if(!this->GetLanguageEnabled(lang) )  
-    // if determineLanguage was called then load the file it 
+      } // end if(!this->GetLanguageEnabled(lang) )
+    // if determineLanguage was called then load the file it
     // configures CMake(LANG)Compiler.cmake
     if(determineLanguageCalled)
       {
@@ -349,10 +357,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
       fpath += "Compiler.cmake";
       if(!mf->ReadListFile(0,fpath.c_str()))
         {
-        cmSystemTools::Error("Could not find cmake module file:", 
+        cmSystemTools::Error("Could not find cmake module file:",
                              fpath.c_str());
         }
-      this->SetLanguageEnabled(lang, mf); 
+      this->SetLanguageEnabled(lang, mf);
       // this can only be called after loading CMake(LANG)Compiler.cmake
       // the language must be enabled for try compile to work, but we do
       // not know if it is a working compiler yet so set the test language
@@ -360,14 +368,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
       needTestLanguage[lang] = true;
       }
     }  // end loop over languages
-  
+
   // **** Load the system specific information if not yet loaded
   if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
     {
     fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
     if(!mf->ReadListFile(0,fpath.c_str()))
       {
-      cmSystemTools::Error("Could not find cmake module file:", 
+      cmSystemTools::Error("Could not find cmake module file:",
                            fpath.c_str());
       }
     }
@@ -386,14 +394,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     langLoadedVar += lang;
     langLoadedVar += "_INFORMATION_LOADED";
     if (!mf->GetDefinition(langLoadedVar.c_str()))
-      { 
+      {
       fpath = "CMake";
       fpath +=  lang;
       fpath += "Information.cmake";
       fpath = mf->GetModulesFile(fpath.c_str());
       if(!mf->ReadListFile(0,fpath.c_str()))
         {
-        cmSystemTools::Error("Could not find cmake module file:", 
+        cmSystemTools::Error("Could not find cmake module file:",
                              fpath.c_str());
         }
       }
@@ -411,7 +419,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
         std::string ifpath = mf->GetModulesFile(testLang.c_str());
         if(!mf->ReadListFile(0,ifpath.c_str()))
           {
-          cmSystemTools::Error("Could not find cmake module file:", 
+          cmSystemTools::Error("Could not find cmake module file:",
                                ifpath.c_str());
           }
         std::string compilerWorks = "CMAKE_";
@@ -421,7 +429,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
         // CMake(LANG)Compiler.cmake file so that it will get tested the
         // next time cmake is run
         if(!mf->IsOn(compilerWorks.c_str()))
-          { 
+          {
           fpath = rootBin;
           fpath += "/CMake";
           fpath += lang;
@@ -441,22 +449,22 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
             {
             if(strcmp(lang, "C") == 0)
               {
-              ifpath =  
+              ifpath =
                 mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake");
-              mf->ReadListFile(0,ifpath.c_str()); 
+              mf->ReadListFile(0,ifpath.c_str());
               }
             if(strcmp(lang, "CXX") == 0)
               {
               ifpath =
                 mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake");
-              mf->ReadListFile(0,ifpath.c_str()); 
+              mf->ReadListFile(0,ifpath.c_str());
               }
             }
           }
         } // end if in try compile
       } // end need test language
     } // end for each language
-  
+
   // Now load files that can override any settings on the platform or for
   // the project First load the project compatibility file if it is in
   // cmake
@@ -466,14 +474,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
   projectCompatibility += "Compatibility.cmake";
   if(cmSystemTools::FileExists(projectCompatibility.c_str()))
     {
-    mf->ReadListFile(0,projectCompatibility.c_str()); 
+    mf->ReadListFile(0,projectCompatibility.c_str());
     }
 }
 
 const char* cmGlobalGenerator
 ::GetLanguageOutputExtensionForLanguage(const char* lang)
 {
-  if(!lang) 
+  if(!lang)
     {
     return "";
     }
@@ -527,7 +535,7 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
     {
     return;
     }
-  std::string outputExtensionVar = std::string("CMAKE_") + 
+  std::string outputExtensionVar = std::string("CMAKE_") +
     std::string(l) + std::string("_OUTPUT_EXTENSION");
   const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str());
   if(outputExtension)
@@ -539,8 +547,8 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
       this->OutputExtensions[outputExtension+1] = outputExtension+1;
       }
     }
-  
-  std::string linkerPrefVar = std::string("CMAKE_") + 
+
+  std::string linkerPrefVar = std::string("CMAKE_") +
     std::string(l) + std::string("_LINKER_PREFERENCE");
   const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
   if(!linkerPref)
@@ -548,10 +556,10 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
     linkerPref = "None";
     }
   this->LanguageToLinkerPreference[l] = linkerPref;
-  
-  std::string extensionsVar = std::string("CMAKE_") + 
+
+  std::string extensionsVar = std::string("CMAKE_") +
     std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS");
-  std::string ignoreExtensionsVar = std::string("CMAKE_") + 
+  std::string ignoreExtensionsVar = std::string("CMAKE_") +
     std::string(l) + std::string("_IGNORE_EXTENSIONS");
   std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str());
   std::string exts = mf->GetSafeDefinition(extensionsVar.c_str());
@@ -598,12 +606,12 @@ bool cmGlobalGenerator::IsDependedOn(const char* project,
   // loop over local gens and get the targets for each one
   for(unsigned int i = 0; i < gens->size(); ++i)
     {
-    cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets(); 
+    cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets();
     for (cmTargets::iterator l = targets.begin();
          l != targets.end(); l++)
-      { 
+      {
       cmTarget& target = l->second;
-      std::set<cmStdString>::const_iterator pos = 
+      std::set<cmStdString>::const_iterator pos =
         target.GetUtilities().find(targetIn->GetName());
       if(pos != target.GetUtilities().end())
         {
@@ -611,7 +619,7 @@ bool cmGlobalGenerator::IsDependedOn(const char* project,
         }
       }
     }
-  return false; 
+  return false;
 }
 
 void cmGlobalGenerator::Configure()
@@ -639,10 +647,10 @@ void cmGlobalGenerator::Configure()
   lg->GetMakefile()->SetStartOutputDirectory
     (this->CMakeInstance->GetStartOutputDirectory());
   lg->GetMakefile()->MakeStartDirectoriesCurrent();
-  
+
   // now do it
   lg->Configure();
-  
+
   // update the cache entry for the number of local generators, this is used
   // for progress
   char num[100];
@@ -650,7 +658,7 @@ void cmGlobalGenerator::Configure()
   this->GetCMakeInstance()->AddCacheEntry
     ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
      "number of local generators", cmCacheManager::INTERNAL);
-  
+
   std::set<cmStdString> notFoundMap;
   // after it is all done do a ConfigureFinalPass
   cmCacheManager* manager = 0;
@@ -658,8 +666,8 @@ void cmGlobalGenerator::Configure()
     {
     manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager();
     this->LocalGenerators[i]->ConfigureFinalPass();
-    cmTargets & targets = 
-      this->LocalGenerators[i]->GetMakefile()->GetTargets(); 
+    cmTargets & targets =
+      this->LocalGenerators[i]->GetMakefile()->GetTargets();
     for (cmTargets::iterator l = targets.begin();
          l != targets.end(); l++)
       {
@@ -667,23 +675,23 @@ void cmGlobalGenerator::Configure()
       for(cmTarget::LinkLibraryVectorType::iterator lib = libs.begin();
           lib != libs.end(); ++lib)
         {
-        if(lib->first.size() > 9 && 
+        if(lib->first.size() > 9 &&
            cmSystemTools::IsNOTFOUND(lib->first.c_str()))
           {
           std::string varName = lib->first.substr(0, lib->first.size()-9);
           notFoundMap.insert(varName);
           }
         }
-      std::vector<std::string>& incs = 
+      std::vector<std::string>& incs =
         this->LocalGenerators[i]->GetMakefile()->GetIncludeDirectories();
-      
+
       for( std::vector<std::string>::iterator lib = incs.begin();
            lib != incs.end(); ++lib)
         {
-        if(lib->size() > 9 && 
+        if(lib->size() > 9 &&
            cmSystemTools::IsNOTFOUND(lib->c_str()))
           {
-          std::string varName = lib->substr(0, lib->size()-9); 
+          std::string varName = lib->substr(0, lib->size()-9);
           notFoundMap.insert(varName);
           }
         }
@@ -698,11 +706,11 @@ void cmGlobalGenerator::Configure()
     std::string notFoundVars;
     for(std::set<cmStdString>::iterator ii = notFoundMap.begin();
         ii != notFoundMap.end(); ++ii)
-      { 
+      {
       notFoundVars += *ii;
       if(manager)
         {
-        cmCacheManager::CacheIterator it = 
+        cmCacheManager::CacheIterator it =
           manager->GetCacheIterator(ii->c_str());
         if(it.GetPropertyAsBool("ADVANCED"))
           {
@@ -719,8 +727,8 @@ void cmGlobalGenerator::Configure()
   // at this point this->LocalGenerators has been filled,
   // so create the map from project name to vector of local generators
     this->FillProjectMap();
-  // now create project to target map 
-  // This will make sure that targets have all the 
+  // now create project to target map
+  // This will make sure that targets have all the
   // targets they depend on as part of the build.
     this->FillProjectToTargetMap();
 
@@ -740,7 +748,7 @@ void cmGlobalGenerator::Generate()
   this->CreateDefaultGlobalTargets(&globalTargets);
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    cmTargets* targets = 
+    cmTargets* targets =
       &(this->LocalGenerators[i]->GetMakefile()->GetTargets());
     cmTargets::iterator tarIt;
     for ( tarIt = targets->begin(); tarIt != targets->end(); ++ tarIt )
@@ -762,7 +770,7 @@ void cmGlobalGenerator::Generate()
       (*targets)[tit->first].SetMakefile(mf);
       }
     }
- 
+
   // Add generator specific helper commands
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
@@ -788,14 +796,20 @@ void cmGlobalGenerator::Generate()
     this->LocalGenerators[i]->Generate();
     this->LocalGenerators[i]->GenerateInstallRules();
     this->LocalGenerators[i]->GenerateTestFiles();
-    this->CMakeInstance->UpdateProgress("Generating", 
+    this->CMakeInstance->UpdateProgress("Generating",
                                     (i+1.0f)/this->LocalGenerators.size());
     }
+
+  if (this->ExtraGenerator != 0)
+    {
+    this->ExtraGenerator->Generate();
+    }
+
   this->CMakeInstance->UpdateProgress("Generating done", -1);
 }
 
-int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, 
-                                  const char *projectName, 
+int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
+                                  const char *projectName,
                                   const char *target,
                                   std::string *output, cmMakefile *mf)
 {
@@ -815,7 +829,7 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
 #if 0
 #if defined(_WIN32) || defined(__CYGWIN__)
     std::string tmp = target;
-    // if the target does not already end in . something 
+    // if the target does not already end in . something
     // then assume .exe
     if(tmp.size() < 4 || tmp[tmp.size()-4] != '.')
       {
@@ -827,12 +841,12 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
   const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
   return this->Build(srcdir,bindir,projectName,
                      newTarget.c_str(),
-                     output,makeCommand.c_str(),config,false,true, 
+                     output,makeCommand.c_str(),config,false,true,
                      this->TryCompileTimeout);
 }
 
 std::string cmGlobalGenerator
-::GenerateBuildCommand(const char* makeProgram, const char *projectName, 
+::GenerateBuildCommand(const char* makeProgram, const char *projectName,
                        const char* additionalOptions, const char *targetName,
                        const char* config, bool ignoreErrors, bool)
 {
@@ -840,7 +854,7 @@ std::string cmGlobalGenerator
   (void)projectName;
   (void)config;
 
-  std::string makeCommand = 
+  std::string makeCommand =
     cmSystemTools::ConvertToUnixOutputPath(makeProgram);
 
   // Since we have full control over the invocation of nmake, let us
@@ -865,18 +879,18 @@ std::string cmGlobalGenerator
     }
   return makeCommand;
 }
-  
+
 int cmGlobalGenerator::Build(
-  const char *, const char *bindir, 
+  const char *, const char *bindir,
   const char *projectName, const char *target,
-  std::string *output, 
+  std::string *output,
   const char *makeCommandCSTR,
   const char *config,
   bool clean, bool fast,
   double timeout)
 {
   *output += "\nTesting TryCompileWithoutMakefile\n";
-  
+
   /**
    * Run an executable command and put the stdout in output.
    */
@@ -890,10 +904,10 @@ int cmGlobalGenerator::Build(
   // should we do a clean first?
   if (clean)
     {
-    std::string cleanCommand = 
+    std::string cleanCommand =
       this->GenerateBuildCommand(makeCommandCSTR, projectName,
       0, "clean", config, false, fast);
-    if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), output, 
+    if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), output,
                                          &retVal, 0, false, timeout))
       {
       cmSystemTools::SetRunCommandHideConsole(hideconsole);
@@ -902,19 +916,19 @@ int cmGlobalGenerator::Build(
         {
         *output += "\nGenerator: execution of make clean failed.\n";
         }
-      
+
       // return to the original directory
       cmSystemTools::ChangeDirectory(cwd.c_str());
       return 1;
       }
     }
-  
+
   // now build
-  std::string makeCommand = 
+  std::string makeCommand =
     this->GenerateBuildCommand(makeCommandCSTR, projectName,
                                0, target, config, false, fast);
-  
-  if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), output, 
+
+  if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), output,
                                        &retVal, 0, false, timeout))
     {
     cmSystemTools::SetRunCommandHideConsole(hideconsole);
@@ -923,17 +937,17 @@ int cmGlobalGenerator::Build(
        makeCommand.c_str());
     if (output)
       {
-      *output += "\nGenerator: execution of make failed. Make command was: " 
+      *output += "\nGenerator: execution of make failed. Make command was: "
         + makeCommand + "\n";
       }
-    
+
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd.c_str());
     return 1;
     }
 
   cmSystemTools::SetRunCommandHideConsole(hideconsole);
-  
+
   // The SGI MipsPro 7.3 compiler does not return an error code when
   // the source has a #error in it!  This is a work-around for such
   // compilers.
@@ -941,26 +955,26 @@ int cmGlobalGenerator::Build(
     {
     retVal = 1;
     }
-  
+
   cmSystemTools::ChangeDirectory(cwd.c_str());
   return retVal;
 }
 
 void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
 {
-  this->LocalGenerators.push_back(lg); 
+  this->LocalGenerators.push_back(lg);
 
   // update progress
   // estimate how many lg there will be
-  const char *numGenC = 
+  const char *numGenC =
     this->CMakeInstance->GetCacheManager()->GetCacheValue
     ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
-  
+
   if (!numGenC)
     {
     return;
     }
-  
+
   int numGen = atoi(numGenC);
   float prog = 0.9f*this->LocalGenerators.size()/numGen;
   if (prog > 0.9f)
@@ -1017,7 +1031,7 @@ void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
   entry.full = "";
 }
 
-bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, 
+bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
                                    cmLocalGenerator* gen)
 {
   if(gen == root)
@@ -1039,7 +1053,7 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
 
 void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
 {
-  for(std::map<cmStdString, bool>::iterator i = 
+  for(std::map<cmStdString, bool>::iterator i =
         this->LanguageEnabled.begin(); i != this->LanguageEnabled.end(); ++i)
     {
     lang.push_back(i->first);
@@ -1056,15 +1070,15 @@ const char* cmGlobalGenerator::GetLinkerPreference(const char* lang)
 }
 
 void cmGlobalGenerator::FillProjectMap()
-{ 
+{
   this->ProjectMap.clear(); // make sure we start with a clean map
   unsigned int i;
   for(i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    // for each local generator add all projects 
+    // for each local generator add all projects
     cmLocalGenerator *lg = this->LocalGenerators[i];
     std::string name;
-    do 
+    do
       {
       if (name != lg->GetMakefile()->GetProjectName())
         {
@@ -1082,8 +1096,8 @@ void cmGlobalGenerator::FillProjectMap()
 void cmGlobalGenerator::FillProjectToTargetMap()
 {
   // loop over each project in the build
-  for(std::map<cmStdString, 
-        std::vector<cmLocalGenerator*> >::iterator m = 
+  for(std::map<cmStdString,
+        std::vector<cmLocalGenerator*> >::iterator m =
         this->ProjectMap.begin();
       m != this->ProjectMap.end(); ++m)
     {
@@ -1098,9 +1112,9 @@ void cmGlobalGenerator::FillProjectToTargetMap()
     const char* exclude = 0;
     std::string excludeSave;
     bool chain = false;
-    exclude = 
+    exclude =
       projectMakefile->GetProperties().
-      GetPropertyValue("EXCLUDE_FROM_ALL", 
+      GetPropertyValue("EXCLUDE_FROM_ALL",
                        cmProperty::DIRECTORY, chain);
     if(exclude)
       {
@@ -1112,7 +1126,7 @@ void cmGlobalGenerator::FillProjectToTargetMap()
     // now loop over all cmLocalGenerators in this project and pull
     // out all the targets that depend on each other, even if those
     // targets come from a target that is excluded.
-    for(std::vector<cmLocalGenerator*>::iterator lg = 
+    for(std::vector<cmLocalGenerator*>::iterator lg =
           lgs.begin(); lg != lgs.end(); ++lg)
       {
       cmMakefile* mf = (*lg)->GetMakefile();
@@ -1121,7 +1135,7 @@ void cmGlobalGenerator::FillProjectToTargetMap()
           t != targets.end(); ++t)
         {
         cmTarget& target = t->second;
-        // if the target is in all then add it to the project 
+        // if the target is in all then add it to the project
         if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
           {
           // add this target to the project
@@ -1131,9 +1145,9 @@ void cmGlobalGenerator::FillProjectToTargetMap()
           this->ProjectToTargetMap[projectName].insert(tgtdeps.begin(),
                                                        tgtdeps.end());
           }
-        } 
+        }
       }
-    // Now restore the EXCLUDE_FROM_ALL property on the project top 
+    // Now restore the EXCLUDE_FROM_ALL property on the project top
     // makefile
     if(exclude)
       {
@@ -1141,13 +1155,13 @@ void cmGlobalGenerator::FillProjectToTargetMap()
       }
     projectMakefile->SetProperty("EXCLUDE_FROM_ALL", exclude);
     }
-  // dump the map for debug purposes 
-  // right now this map is not being used, but it was 
-  // checked in to avoid constant conflicts.  
+  // dump the map for debug purposes
+  // right now this map is not being used, but it was
+  // checked in to avoid constant conflicts.
   // It is also the first step to creating sub projects
   // that contain all of the targets they need.
 #if 0
-  std::map<cmStdString, std::set<cmTarget*> >::iterator i = 
+  std::map<cmStdString, std::set<cmTarget*> >::iterator i =
     this->ProjectToTargetMap.begin();
   for(; i != this->ProjectToTargetMap.end(); ++i)
     {
@@ -1179,7 +1193,7 @@ cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
 }
 
 
-cmTarget* cmGlobalGenerator::FindTarget(const char* project, 
+cmTarget* cmGlobalGenerator::FindTarget(const char* project,
                                         const char* name,
                                         bool useImportedTargets)
 {
@@ -1189,7 +1203,7 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
     std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
     for(unsigned int i = 0; i < gens->size(); ++i)
       {
-      cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name, 
+      cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name,
                                                             useImportedTargets);
       if(ret)
         {
@@ -1206,7 +1220,7 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
       {
       return i->second;
       }
-    
+
     if ( useImportedTargets )
       {
       std::map<cmStdString,cmTarget *>::iterator importedTarget =
@@ -1271,7 +1285,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
   const char* packageSourceTargetName = this->GetPackageSourceTargetName();
   if ( packageSourceTargetName )
     {
-    cpackCommandLines.erase(cpackCommandLines.begin(), 
+    cpackCommandLines.erase(cpackCommandLines.begin(),
                             cpackCommandLines.end());
     singleLine.erase(singleLine.begin(), singleLine.end());
     depends.erase(depends.begin(), depends.end());
@@ -1293,7 +1307,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
   // Test
   if(mf->IsOn("CMAKE_TESTING_ENABLED"))
     {
-    cpackCommandLines.erase(cpackCommandLines.begin(), 
+    cpackCommandLines.erase(cpackCommandLines.begin(),
                             cpackCommandLines.end());
     singleLine.erase(singleLine.begin(), singleLine.end());
     depends.erase(depends.begin(), depends.end());
@@ -1318,7 +1332,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
   const char* editCacheTargetName = this->GetEditCacheTargetName();
   if ( editCacheTargetName )
     {
-    cpackCommandLines.erase(cpackCommandLines.begin(), 
+    cpackCommandLines.erase(cpackCommandLines.begin(),
                             cpackCommandLines.end());
     singleLine.erase(singleLine.begin(), singleLine.end());
     depends.erase(depends.begin(), depends.end());
@@ -1344,7 +1358,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
       cpackCommandLines.push_back(singleLine);
       (*targets)[editCacheTargetName] =
         this->CreateGlobalTarget(
-          editCacheTargetName, 
+          editCacheTargetName,
           "Running interactive CMake command-line interface...",
           &cpackCommandLines, depends);
       }
@@ -1354,7 +1368,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
   const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
   if ( rebuildCacheTargetName )
     {
-    cpackCommandLines.erase(cpackCommandLines.begin(), 
+    cpackCommandLines.erase(cpackCommandLines.begin(),
                             cpackCommandLines.end());
     singleLine.erase(singleLine.begin(), singleLine.end());
     depends.erase(depends.begin(), depends.end());
@@ -1374,7 +1388,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
     if(!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.')
       {
       std::set<cmStdString>* componentsSet = &this->InstallComponents;
-      cpackCommandLines.erase(cpackCommandLines.begin(), 
+      cpackCommandLines.erase(cpackCommandLines.begin(),
         cpackCommandLines.end());
       depends.erase(depends.begin(), depends.end());
       cmOStringStream ostr;
@@ -1535,21 +1549,21 @@ std::vector<cmTarget *>& cmGlobalGenerator
 ::GetTargetDepends(cmTarget& target)
 {
   // if the depends are already in the map then return
-  std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI = 
+  std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI =
     this->TargetDependencies.find(target.GetName());
   if (tgtI != this->TargetDependencies.end())
     {
     return tgtI->second;
     }
-  
+
   // A target should not depend on itself.
   std::set<cmStdString> emitted;
   emitted.insert(target.GetName());
-  
+
   // the vector of results
-  std::vector<cmTarget *>& result = 
+  std::vector<cmTarget *>& result =
     this->TargetDependencies[target.GetName()];
-  
+
   // Loop over all library dependencies but not for static libs
   if (target.GetType() != cmTarget::STATIC_LIBRARY)
     {
@@ -1560,7 +1574,7 @@ std::vector<cmTarget *>& cmGlobalGenerator
       // Don't emit the same library twice for this target.
       if(emitted.insert(lib->first).second)
         {
-        cmTarget *target2 = 
+        cmTarget *target2 =
           target.GetMakefile()->FindTarget(lib->first.c_str(), false);
 
         // search each local generator until a match is found
@@ -1568,7 +1582,7 @@ std::vector<cmTarget *>& cmGlobalGenerator
           {
           target2 = this->FindTarget(0,lib->first.c_str(), false);
           }
-        
+
         // if a match was found then ...
         if (target2)
           {
@@ -1578,7 +1592,7 @@ std::vector<cmTarget *>& cmGlobalGenerator
         }
       }
     }
-  
+
   // Loop over all utility dependencies.
   const std::set<cmStdString>& tutils = target.GetUtilities();
   for(std::set<cmStdString>::const_iterator util = tutils.begin();
@@ -1588,13 +1602,13 @@ std::vector<cmTarget *>& cmGlobalGenerator
     if(emitted.insert(*util).second)
       {
       cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str(), false);
-      
+
       // search each local generator until a match is found
       if (!target2)
         {
         target2 = this->FindTarget(0,util->c_str(), false);
         }
-      
+
       // if a match was found then ...
       if (target2)
         {
@@ -1617,3 +1631,14 @@ void cmGlobalGenerator::AddTarget(cmTargets::value_type &v)
     this->TotalTargets[v.first] = &v.second;
     }
 }
+
+void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
+                            cmExternalMakefileProjectGenerator *extraGenerator)
+{
+  this->ExtraGenerator = extraGenerator;
+  if (this->ExtraGenerator!=0)
+    {
+    this->ExtraGenerator->SetGlobalGenerator(this);
+    }
+}
+

+ 13 - 0
Source/cmGlobalGenerator.h

@@ -19,6 +19,7 @@
 #define cmGlobalGenerator_h
 
 #include "cmStandardIncludes.h"
+#include "cmExternalMakefileProjectGenerator.h"
 
 #include "cmTarget.h" // For cmTargets
 
@@ -123,6 +124,13 @@ public:
 
   void AddLocalGenerator(cmLocalGenerator *lg);
 
+  ///! Set an generator for an "external makefile based project"
+  void SetExternalMakefileProjectGenerator(
+                           cmExternalMakefileProjectGenerator *extraGenerator);
+
+  const char* GetExtraGeneratorName() const
+          {return this->ExtraGenerator!=0 ? this->ExtraGenerator->GetName():0;}
+
   void AddInstallComponent(const char* component);
   void EnableInstallTarget();
   
@@ -130,6 +138,8 @@ public:
   
   bool GetForceUnixPaths() {return this->ForceUnixPaths;}
   bool GetToolSupportsColor() { return this->ToolSupportsColor; }
+  bool SetToolSupportsColor(bool enable) { this->ToolSupportsColor = enable; }
+
   ///! return the language for the given extension
   const char* GetLanguageFromExtension(const char* ext);
   ///! is an extension to be ignored
@@ -196,6 +206,7 @@ public:
   // what targets does the specified target depend on
   std::vector<cmTarget *>& GetTargetDepends(cmTarget& target);
 
+  const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap() const {return this->ProjectMap;}
 protected:
   // Fill the ProjectMap, this must be called after LocalGenerators 
   // has been populated.
@@ -242,6 +253,8 @@ private:
   std::map<cmStdString,cmTarget *> ImportedTotalTargets;
   
   std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies;
+
+  cmExternalMakefileProjectGenerator* ExtraGenerator;
 };
 
 #endif

+ 27 - 19
Source/cmGlobalKdevelopGenerator.cxx

@@ -17,6 +17,7 @@
 =========================================================================*/
 
 #include "cmGlobalKdevelopGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmake.h"
@@ -25,18 +26,9 @@
 
 #include <cmsys/SystemTools.hxx>
 
-cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
-{
-  // This type of makefile always requires unix style paths
-  this->ForceUnixPaths = true;
-  this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
-  this->ToolSupportsColor = false;
-  this->SetForceVerboseMakefiles(true);
-}
-
 //----------------------------------------------------------------------------
 void cmGlobalKdevelopGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry, const char*) const
 {
   entry.name = this->GetName();
   entry.brief = "Generates KDevelop 3 project files.";
@@ -52,13 +44,31 @@ void cmGlobalKdevelopGenerator
     "default make target.  A \"make install\" target is also provided.";
 }
 
+cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
+:cmExternalMakefileProjectGenerator()
+{
+  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+}
+
+
+void cmGlobalKdevelopGenerator::SetGlobalGenerator(
+                                                  cmGlobalGenerator* generator)
+{
+  cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
+  cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*)
+                                                                     generator;
+  mf->SetToolSupportsColor(false);
+  mf->SetForceVerboseMakefiles(true);
+}
+
 void cmGlobalKdevelopGenerator::Generate()
 {
-  this->cmGlobalUnixMakefileGenerator3::Generate();
   // for each sub project in the project create 
   // a kdevelop project
-  std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
-  for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
+  for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator 
+       it = this->GlobalGenerator->GetProjectMap().begin(); 
+      it!= this->GlobalGenerator->GetProjectMap().end(); 
+      ++it)
     {
     cmMakefile* mf = it->second[0]->GetMakefile();
     std::string outputDir=mf->GetStartOutputDirectory();
@@ -66,10 +76,9 @@ void cmGlobalKdevelopGenerator::Generate()
     std::string projectName=mf->GetProjectName();
     std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
     std::string fileToOpen;
-    std::vector<cmLocalGenerator*>& lgs= it->second;
+    const std::vector<cmLocalGenerator*>& lgs= it->second;
     // create the project.kdevelop.filelist file
-    if(!this->CreateFilelistFile(it->second[0], lgs,
-                                 outputDir, projectDir,
+    if(!this->CreateFilelistFile(lgs, outputDir, projectDir,
                                  projectName, cmakeFilePattern, fileToOpen))
       {
       cmSystemTools::Error("Can not create filelist file");
@@ -104,8 +113,7 @@ void cmGlobalKdevelopGenerator::Generate()
 }
 
 bool cmGlobalKdevelopGenerator
-::CreateFilelistFile(cmLocalGenerator* ,
-                     std::vector<cmLocalGenerator*>& lgs,
+::CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
                      const std::string& outputDir, 
                      const std::string& projectDirIn,
                      const std::string& projectname,
@@ -252,7 +260,7 @@ bool cmGlobalKdevelopGenerator
       }
     }
   return true;
-}                             
+}
 
 
 /* create the project file, if it already exists, merge it with the

+ 16 - 18
Source/cmGlobalKdevelopGenerator.h

@@ -18,7 +18,9 @@
 #ifndef cmGlobalKdevelopGenerator_h
 #define cmGlobalKdevelopGenerator_h
 
-#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmLocalGenerator;
 
 /** \class cmGlobalKdevelopGenerator
  * \brief Write Unix Makefiles accompanied by KDevelop3 project files.
@@ -31,32 +33,27 @@
  * file, which lists the source files relative to the kdevelop project
  * directory. The kdevelop project directory is the base source directory.
  */
-class cmGlobalKdevelopGenerator : public cmGlobalUnixMakefileGenerator3
+class cmGlobalKdevelopGenerator : public cmExternalMakefileProjectGenerator
 {
 public:
   cmGlobalKdevelopGenerator();
-  static cmGlobalGenerator* New() { return new cmGlobalKdevelopGenerator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalKdevelopGenerator::GetActualName();}
-  static const char* GetActualName() {return "KDevelop3";}
+  virtual void SetGlobalGenerator(cmGlobalGenerator* generator);
 
+  virtual const char* GetName() const
+                          { return cmGlobalKdevelopGenerator::GetActualName();}
+  static const char* GetActualName()                     { return "KDevelop3";}
+  static cmExternalMakefileProjectGenerator* New() 
+                                      { return new cmGlobalKdevelopGenerator; }
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-  
- /**
-   * Generate the all required files for building this project/tree. This
-   * basically creates a series of LocalGenerators for each directory and
-   * requests that they Generate.  
-   */
-  virtual void Generate();
+  virtual void GetDocumentation(cmDocumentationEntry& entry, 
+                                const char* fullName) const;
 
+  virtual void Generate();
+private:
   /*** Create the foo.kdevelop.filelist file, return false if it doesn't
     succeed.  If the file already exists the contents will be merged.  
     */
-  bool CreateFilelistFile(cmLocalGenerator* lg,
-                          std::vector<cmLocalGenerator*>& lgs,
+  bool CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
                           const std::string& outputDir, 
                           const std::string& projectDirIn,
                           const std::string& projectname,
@@ -95,6 +92,7 @@ public:
                             const std::string& fileToOpen,
                             const std::string& sessionFilename);
 
+  
 };
 
 #endif

File diff suppressed because it is too large
+ 142 - 142
Source/cmMakefile.cxx


+ 78 - 15
Source/cmake.cxx

@@ -169,6 +169,7 @@ cmake::cmake()
 #endif
 
   this->AddDefaultGenerators();
+  this->AddDefaultExtraGenerators();
   this->AddDefaultCommands();
 
   // Make sure we can capture the build tool output.
@@ -1405,6 +1406,40 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
   return 1;
 }
 
+void cmake::AddExtraGenerator(const char* name, 
+                              CreateExtraGeneratorFunctionType newFunction)
+{
+  this->ExtraGenerators[name] = 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->c_str(), name);
+    this->ExtraGenerators[fullName.c_str()] = newFunction;
+    }
+  delete extraGenerator;
+}
+
+void cmake::AddDefaultExtraGenerators()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# if !defined(CMAKE_BOOT_MINGW)
+  // e.g. codeblocks, kdevelop4 ?
+# endif
+#endif
+// e.g. eclipse ?
+#ifdef CMAKE_USE_KDEVELOP
+  this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), &cmGlobalKdevelopGenerator::New);
+#endif
+}
+
+
 //----------------------------------------------------------------------------
 void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
 {
@@ -1417,17 +1452,30 @@ void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
 
 cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
 {
-  RegisteredGeneratorsMap::const_iterator i = this->Generators.find(name);
-  if(i != this->Generators.end())
+  cmGlobalGenerator* generator = 0;
+  cmExternalMakefileProjectGenerator* extraGenerator = 0;
+  RegisteredGeneratorsMap::const_iterator genIt = this->Generators.find(name);
+  if(genIt == this->Generators.end())
     {
-    cmGlobalGenerator* generator = (i->second)();
-    generator->SetCMakeInstance(this);
-    return generator;
-    }
-  else
-    {
-    return 0;
-    }
+    RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
+                                              this->ExtraGenerators.find(name);
+    if (extraGenIt == this->ExtraGenerators.end())
+      {
+      return 0;
+      }
+    extraGenerator = (extraGenIt->second)();
+    genIt=this->Generators.find(extraGenerator->GetGlobalGeneratorName(name));
+    if(genIt == this->Generators.end())
+      {
+      delete extraGenerator;
+      return 0;
+      }
+  }
+
+  generator = (genIt->second)();
+  generator->SetCMakeInstance(this);
+  generator->SetExternalMakefileProjectGenerator(extraGenerator);
+  return generator;
 }
 
 void cmake::SetHomeDirectory(const char* dir)
@@ -1599,9 +1647,13 @@ int cmake::Configure()
     {
     const char* genName = 
       this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
+    const char* extraGenName = 
+      this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR");
     if(genName)
       {
-      this->GlobalGenerator = this->CreateGlobalGenerator(genName);
+      std::string fullName = cmExternalMakefileProjectGenerator::
+                                CreateFullGeneratorName(genName, extraGenName);
+      this->GlobalGenerator = this->CreateGlobalGenerator(fullName.c_str());
       }
     if(this->GlobalGenerator)
       {
@@ -1688,6 +1740,10 @@ int cmake::Configure()
                                       this->GlobalGenerator->GetName(),
                                       "Name of generator.",
                                       cmCacheManager::INTERNAL);
+    this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR", 
+                                this->GlobalGenerator->GetExtraGeneratorName(),
+                                "Name of external makefile project generator.",
+                                cmCacheManager::INTERNAL);
     }
 
   // reset any system configuration information, except for when we are
@@ -1750,6 +1806,7 @@ int cmake::Configure()
     // We must have a bad generator selection.  Wipe the cache entry so the
     // user can select another.
     this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR");
+    this->CacheManager->RemoveCacheEntry("CMAKE_EMP_GENERATOR");
     }
   // only save the cache if there were no fatal errors
   if ( !this->ScriptMode )
@@ -2001,10 +2058,6 @@ void cmake::AddDefaultGenerators()
   this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
     &cmGlobalXCodeGenerator::New;
 #endif
-#ifdef CMAKE_USE_KDEVELOP
-  this->Generators[cmGlobalKdevelopGenerator::GetActualName()] =
-     &cmGlobalKdevelopGenerator::New;
-#endif
 }
 
 int cmake::LoadCache()
@@ -2121,6 +2174,16 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
     delete generator;
     v.push_back(e);
     }
+  for(RegisteredExtraGeneratorsMap::const_iterator 
+      i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
+    {
+    cmDocumentationEntry e;
+    cmExternalMakefileProjectGenerator* generator = (i->second)();
+    generator->GetDocumentation(e, i->first.c_str());
+    e.name = i->first.c_str();
+    delete generator;
+    v.push_back(e);
+    }
   cmDocumentationEntry empty = {0,0,0};
   v.push_back(empty);
 }

+ 10 - 1
Source/cmake.h

@@ -51,6 +51,7 @@ class cmMakefile;
 class cmCommand;
 class cmVariableWatch;
 class cmFileTimeComparison;
+class cmExternalMakefileProjectGenerator;
 
 class cmake
 {
@@ -305,14 +306,22 @@ protected:
   cmPropertyDefinitionMap DirectoryProperties;
   cmPropertyDefinitionMap TestProperties;
   cmPropertyDefinitionMap GlobalProperties;
-  
+
+  typedef 
+     cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
+  typedef std::map<cmStdString,
+                CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
+
   typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)();
   typedef std::map<cmStdString,
                    CreateGeneratorFunctionType> RegisteredGeneratorsMap;
   RegisteredCommandsMap Commands;
   RegisteredGeneratorsMap Generators;
+  RegisteredExtraGeneratorsMap ExtraGenerators;
   void AddDefaultCommands();
   void AddDefaultGenerators();
+  void AddDefaultExtraGenerators();
+  void AddExtraGenerator(const char* name, CreateExtraGeneratorFunctionType newFunction);
 
   cmGlobalGenerator *GlobalGenerator;
   cmCacheManager *CacheManager;

Some files were not shown because too many files changed in this diff