Ken Martin 23 years ago
parent
commit
25ff4552b3

+ 24 - 18
Source/CMakeLists.txt

@@ -5,7 +5,6 @@ cmake.cxx
 cmakewizard.cxx
 cmMakeDepend.cxx
 cmMakefile.cxx
-cmMakefileGenerator.cxx
 cmRegularExpression.cxx
 cmSourceFile.cxx
 cmSystemTools.cxx
@@ -17,6 +16,10 @@ cmCustomCommand.cxx
 cmCacheManager.cxx
 cmSourceGroup.cxx
 cmListFileCache.cxx
+cmGlobalGenerator.cxx
+cmGlobalUnixMakefileGenerator.cxx
+cmLocalGenerator.cxx
+cmLocalUnixMakefileGenerator.cxx
 cmake.h
 cmakewizard.h
 cmMakeDepend.h
@@ -33,6 +36,10 @@ cmCustomCommand.h
 cmCacheManager.h
 cmSourceGroup.h
 cmListFileCache.h
+cmGlobalGenerator.h
+cmGlobalUnixMakefileGenerator.h
+cmLocalGenerator.h
+cmLocalUnixMakefileGenerator.h
 )
 
 # configure the .h file
@@ -50,18 +57,22 @@ ADD_DEFINITIONS(-DCMAKE_BUILD_WITH_CMAKE)
 IF (WIN32)
   IF(NOT UNIX)
     SET(SRCS ${SRCS}
-                    cmDSWWriter.cxx 
-                    cmDSPWriter.cxx 
-                    cmMSProjectGenerator.cxx
-                    cmBorlandMakefileGenerator.cxx
-                    cmNMakeMakefileGenerator.cxx
-                    cmMSDotNETGenerator.cxx
-                    cmDSWWriter.h 
-                    cmDSPWriter.h 
-                    cmMSProjectGenerator.h
-                    cmBorlandMakefileGenerator.h
-                    cmNMakeMakefileGenerator.h
-                    cmMSDotNETGenerator.h
+                    cmGlobalBorlandMakefileGenerator.cxx
+                    cmLocalBorlandMakefileGenerator.cxx
+                    cmGlobalNMakeMakefileGenerator.cxx
+                    cmLocalNMakeMakefileGenerator.cxx
+                    cmGlobalVisualStudio6Generator.cxx
+                    cmLocalVisualStudio6Generator.cxx
+                    cmGlobalVisualStudio7Generator.cxx
+                    cmLocalVisualStudio7Generator.cxx
+                    cmGlobalBorlandMakefileGenerator.h
+                    cmLocalBorlandMakefileGenerator.h
+                    cmGlobalNMakeMakefileGenerator.h
+                    cmLocalNMakeMakefileGenerator.h
+                    cmGlobalVisualStudio6Generator.h
+                    cmLocalVisualStudio6Generator.h
+                    cmGlobalVisualStudio7Generator.h
+                    cmLocalVisualStudio7Generator.h
                     )
     IF(  NOT BORLAND )
       LINK_LIBRARIES( rpcrt4.lib )
@@ -70,8 +81,6 @@ IF (WIN32)
   ENDIF(NOT UNIX)
 ENDIF (WIN32)
 
-SET(SRCS ${SRCS} cmUnixMakefileGenerator.cxx cmUnixMakefileGenerator.h)
-
 # create a library used by the command line and the GUI
 ADD_LIBRARY(CMakeLib ${SRCS})
 
@@ -111,9 +120,6 @@ CONFIGURE_FILE(
 ADD_EXECUTABLE(cmaketest cmaketest.cxx)
 TARGET_LINK_LIBRARIES(cmaketest CMakeLib)
 
-#ADD_LIBRARY(TEST_PLUGIN SHARED cmSimpleCommandPlugin.c)
-#TARGET_LINK_LIBRARIES(TEST_PLUGIN CMakeLib)
-
 IF(BUILD_TESTING)
     ADD_TEST(DumpDocumentation ${CMake_BINARY_DIR}/Source/DumpDocumentation
       ${CMake_BINARY_DIR}/CMakeDoc.html)

+ 43 - 40
Source/MFCDialog/CMakeSetupDialog.cpp

@@ -12,7 +12,7 @@
 #include "CMakeCommandLineInfo.h" 
 #include "../cmCacheManager.h"
 #include "../cmake.h"
-#include "../cmMakefileGenerator.h"
+#include "../cmGlobalGenerator.h"
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #undef THIS_FILE
@@ -52,7 +52,7 @@ class CAboutDlg : public CDialog
 public:
   CAboutDlg();
 
-// Dialog Data
+  // Dialog Data
   //{{AFX_DATA(CAboutDlg)
   enum { IDD = IDD_ABOUTBOX };
   //}}AFX_DATA
@@ -146,7 +146,7 @@ CMakeSetupDialog::CMakeSetupDialog(const CMakeCommandLineInfo& cmdInfo,
 
   m_oldCX = -1;
   m_deltaXRemainder = 0;
-  m_CMakeInstance = 0;
+  m_CMakeInstance = new cmake;
 }
 
 void CMakeSetupDialog::DoDataExchange(CDataExchange* pDX)
@@ -184,15 +184,15 @@ BEGIN_MESSAGE_MAP(CMakeSetupDialog, CDialog)
   ON_CBN_SELCHANGE(IDC_WhereBuild, OnSelendokWhereBuild)
   ON_CBN_EDITCHANGE(IDC_WhereSource, OnChangeWhereSource)
   ON_CBN_SELENDOK(IDC_WhereSource, OnSelendokWhereSource)
-	ON_WM_SIZE()
+  ON_WM_SIZE()
   ON_WM_GETMINMAXINFO()
-	ON_BN_CLICKED(IDC_OK, OnOk)
-	ON_CBN_EDITCHANGE(IDC_Generator, OnEditchangeGenerator)
-	ON_BN_CLICKED(IDC_HELP_BUTTON, OnHelpButton)
+  ON_BN_CLICKED(IDC_OK, OnOk)
+  ON_CBN_EDITCHANGE(IDC_Generator, OnEditchangeGenerator)
+  ON_BN_CLICKED(IDC_HELP_BUTTON, OnHelpButton)
   ON_BN_CLICKED(IDCANCEL, OnCancel)
-	ON_BN_CLICKED(IDC_AdvancedValues, OnAdvancedValues)
-	ON_BN_DOUBLECLICKED(IDC_AdvancedValues, OnDoubleclickedAdvancedValues)
-	//}}AFX_MSG_MAP
+  ON_BN_CLICKED(IDC_AdvancedValues, OnAdvancedValues)
+  ON_BN_DOUBLECLICKED(IDC_AdvancedValues, OnDoubleclickedAdvancedValues)
+  //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
 /////////////////////////////////////////////////////////////////////////////
@@ -245,7 +245,6 @@ BOOL CMakeSetupDialog::OnInitDialog()
   SetIcon(m_hIcon, FALSE);		// Set small icon
   // Load source and build dirs from registry
   this->LoadFromRegistry();
-  this->m_CMakeInstance = new cmake;
   std::vector<std::string> names;
   this->m_CMakeInstance->GetRegisteredGenerators(names);
   for(std::vector<std::string>::iterator i = names.begin();
@@ -266,8 +265,8 @@ BOOL CMakeSetupDialog::OnInitDialog()
     
   // Set the version number
   char tmp[1024];
-  sprintf(tmp,"Version %d.%d - %s", cmMakefile::GetMajorVersion(),
-          cmMakefile::GetMinorVersion(), cmMakefile::GetReleaseVersion());
+  sprintf(tmp,"Version %d.%d - %s", cmake::GetMajorVersion(),
+          cmake::GetMinorVersion(), cmake::GetReleaseVersion());
   SetDlgItemText(IDC_CMAKE_VERSION, tmp);
   this->UpdateData(FALSE);
   return TRUE;  // return TRUE  unless you set the focus to a control
@@ -560,38 +559,37 @@ void CMakeSetupDialog::RunCMake(bool generateProjectFiles)
   this->UpdateData();
   // always save the current gui values to disk
   this->SaveCacheFromGUI();
-  // free the old cmake and create a new one here
-  if (this->m_CMakeInstance)
-    {
-    delete this->m_CMakeInstance;
-    this->m_CMakeInstance = 0;
-    }
-  this->m_CMakeInstance = new cmake;
   // Make sure we are working from the cache on disk
   this->LoadCacheFromDiskToGUI(); 
   m_OKButton.EnableWindow(false);
-  // create the arguments for the cmake object
-  std::vector<std::string> args;
-  args.push_back((const char*)m_PathToExecutable);
-  std::string arg;
-  arg = "-H";
-  arg += m_WhereSource;
-  args.push_back(arg);
-  arg = "-B";
-  arg += m_WhereBuild;
-  args.push_back(arg);
-  arg = "-G";
-  arg += m_GeneratorChoiceString;
-  args.push_back(arg);
-  // run the generate process
-  if(this->m_CMakeInstance->Generate(args, generateProjectFiles) != 0)
+
+  // setup the cmake instance
+  if (generateProjectFiles)
     {
-    cmSystemTools::Error(
-      "Error in generation process, project files may be invalid");
+    if(m_CMakeInstance->Generate() != 0)
+      {
+      cmSystemTools::Error(
+        "Error in generation process, project files may be invalid");
+      }
     }
-  // update the GUI with any new values in the caused by the
-  // generation process
-  this->LoadCacheFromDiskToGUI();
+  else
+    {
+    m_CMakeInstance->SetHomeDirectory(m_WhereSource);
+    m_CMakeInstance->SetStartDirectory(m_WhereSource);
+    m_CMakeInstance->SetHomeOutputDirectory(m_WhereBuild);
+    m_CMakeInstance->SetStartOutputDirectory(m_WhereBuild);
+    m_CMakeInstance->SetGlobalGenerator(
+      m_CMakeInstance->CreateGlobalGenerator(m_GeneratorChoiceString));
+    if(m_CMakeInstance->Configure(m_PathToExecutable) != 0)
+      {
+      cmSystemTools::Error(
+        "Error in configuration process, project files may be invalid");
+      }
+    // update the GUI with any new values in the caused by the
+    // generation process
+    this->LoadCacheFromDiskToGUI();
+    }
+
   // save source and build paths to registry
   this->SaveToRegistry();
   // path is up-to-date now
@@ -647,6 +645,11 @@ void CMakeSetupDialog::OnChangeWhereBuild()
 
   std::string path = this->m_WhereBuild;
   cmSystemTools::ConvertToUnixSlashes(path);
+
+  // adjust the cmake instance
+  m_CMakeInstance->SetHomeOutputDirectory(m_WhereBuild);
+  m_CMakeInstance->SetStartOutputDirectory(m_WhereBuild);
+
   std::string cache_file = path;
   cache_file += "/CMakeCache.txt";
 

+ 1 - 1
Source/MFCDialog/CMakeSetupDialog.h

@@ -55,7 +55,7 @@ protected:
 			 const char *aadefault);
   void ShowAdvancedValues();
   void RemoveAdvancedValues();
-// Dialog Data
+  // Dialog Data
   //{{AFX_DATA(CMakeSetupDialog)
 	enum { IDD = IDD_CMakeSetupDialog_DIALOG };
 	CButton	m_HelpButton;

+ 8 - 4
Source/Makefile.in

@@ -19,12 +19,14 @@ cmakewizard.o  \
 cmakemain.o \
 cmMakeDepend.o \
 cmMakefile.o \
-cmMakefileGenerator.o \
+cmGlobalGenerator.o \
+cmLocalGenerator.o \
 cmRegularExpression.o \
 cmSourceFile.o \
 cmSystemTools.o \
 cmDirectory.o \
-cmUnixMakefileGenerator.o \
+cmGlobalUnixMakefileGenerator.o \
+cmLocalUnixMakefileGenerator.o \
 cmCommands.o \
 cmTarget.o \
 cmCustomCommand.o \
@@ -39,13 +41,15 @@ cmake.o  : $(DEPENDS)
 cmakemain.o  : $(DEPENDS)
 cmMakeDepend.o : $(DEPENDS)
 cmMakefile.o : $(DEPENDS)
-cmMakefileGenerator.o : $(DEPENDS)
+cmGlobalGenerator.o : $(DEPENDS)
+cmLocalGenerator.o : $(DEPENDS)
 cmAuxSourceDirectoryCommand.o : $(DEPENDS)
 cmRegularExpression.o : $(DEPENDS)
 cmSourceFile.o : $(DEPENDS)
 cmDirectory.o : $(DEPENDS)
 cmCustomCommand.o : $(DEPENDS)
-cmUnixMakefileGenerator.o : $(DEPENDS)
+cmGlobalUnixMakefileGenerator.o : $(DEPENDS)
+cmLocalUnixMakefileGenerator.o : $(DEPENDS)
 cmCommands.o : $(DEPENDS) $(srcdir)/*Command*.cxx
 cmTarget.o : $(DEPENDS)
 cmCacheManager.o : $(DEPENDS)

+ 7 - 4
Source/cmGlobalGenerator.cxx

@@ -52,6 +52,9 @@ void cmGlobalGenerator::ClearEnabledLanguages()
 
 void cmGlobalGenerator::Configure()
 {
+  // reset theLanguages
+  m_LanguagesEnabled = false;
+  
   // Delete any existing cmLocalGenerators
   int i;
   for (i = 0; i < m_LocalGenerators.size(); ++i)
@@ -65,8 +68,8 @@ void cmGlobalGenerator::Configure()
   m_LocalGenerators.push_back(lg);
 
   // set the Start directories
-  lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetHomeDirectory());
-  lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetHomeOutputDirectory());
+  lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetStartDirectory());
+  lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetStartOutputDirectory());
   lg->GetMakefile()->MakeStartDirectoriesCurrent();
   
   // now do it
@@ -124,8 +127,8 @@ void cmGlobalGenerator::LocalGenerate()
   cmLocalGenerator *lg = this->CreateLocalGenerator();
 
   // set the Start directories
-  lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetHomeDirectory());
-  lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetHomeOutputDirectory());
+  lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetStartDirectory());
+  lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetStartOutputDirectory());
   lg->GetMakefile()->MakeStartDirectoriesCurrent();
   
   // now do trhe configure

+ 60 - 49
Source/cmGlobalUnixMakefileGenerator.cxx

@@ -17,6 +17,7 @@
 #include "cmGlobalUnixMakefileGenerator.h"
 #include "cmLocalUnixMakefileGenerator.h"
 #include "cmMakefile.h"
+#include "cmake.h"
 
 void cmGlobalUnixMakefileGenerator::EnableLanguage(const char* lang, 
                                                    cmMakefile *mf)
@@ -25,58 +26,68 @@ void cmGlobalUnixMakefileGenerator::EnableLanguage(const char* lang,
     {
     m_LanguagesEnabled = true;
     
-    // see man putenv for explaination of this stupid code....
-    static char envCXX[5000];
-    static char envCC[5000];
-    if(mf->GetDefinition("CMAKE_CXX_COMPILER"))
+    // only do for global runs 
+    if (!m_CMakeInstance->GetLocal())
       {
-      std::string env = "CXX=${CMAKE_CXX_COMPILER}";
-      mf->ExpandVariablesInString(env);
-      strncpy(envCXX, env.c_str(), 4999);
-      envCXX[4999] = 0;
-      putenv(envCXX);
-      }
-    if(mf->GetDefinition("CMAKE_C_COMPILER"))
-      {
-      std::string env = "CC=${CMAKE_C_COMPILER}";
-      mf->ExpandVariablesInString(env);
-      strncpy(envCC, env.c_str(), 4999);
-      envCC[4999] = 0;
-      putenv(envCC);
-      }
-    std::string output;
-    std::string root 
-      = cmSystemTools::ConvertToOutputPath(mf->GetDefinition("CMAKE_ROOT"));
-    // if no lang specified use CXX
-    if(!lang )
-      {
-      lang = "CXX";
-      }
-    // if CXX or C,  then enable C
-    if((!this->GetLanguageEnabled(lang) && lang[0] == 'C'))
-      {
-      std::string cmd = root;
-      cmd += "/Templates/cconfigure";
-      cmSystemTools::RunCommand(cmd.c_str(), output, 
-                                cmSystemTools::ConvertToOutputPath(mf->GetHomeOutputDirectory()).c_str());
-      std::string fpath = mf->GetHomeOutputDirectory();
-      fpath += "/CCMakeSystemConfig.cmake";
-      mf->ReadListFile(NULL,fpath.c_str());
-      this->SetLanguageEnabled("C");
-      }
-    // if CXX 
-    if(!this->GetLanguageEnabled(lang)  || strcmp(lang, "CXX") == 0)
-      {
-      std::string cmd = root;
-      cmd += "/Templates/cxxconfigure";
-      cmSystemTools::RunCommand(cmd.c_str(), output, 
-                                cmSystemTools::ConvertToOutputPath(mf->GetHomeOutputDirectory()).c_str());
-      std::string fpath = mf->GetHomeOutputDirectory();
-      fpath += "/CXXCMakeSystemConfig.cmake";
-      mf->ReadListFile(NULL,fpath.c_str());
-      this->SetLanguageEnabled("CXX");
+      // see man putenv for explaination of this stupid code....
+      static char envCXX[5000];
+      static char envCC[5000];
+      if(mf->GetDefinition("CMAKE_CXX_COMPILER"))
+        {
+        std::string env = "CXX=${CMAKE_CXX_COMPILER}";
+        mf->ExpandVariablesInString(env);
+        strncpy(envCXX, env.c_str(), 4999);
+        envCXX[4999] = 0;
+        putenv(envCXX);
+        }
+      if(mf->GetDefinition("CMAKE_C_COMPILER"))
+        {
+        std::string env = "CC=${CMAKE_C_COMPILER}";
+        mf->ExpandVariablesInString(env);
+        strncpy(envCC, env.c_str(), 4999);
+        envCC[4999] = 0;
+        putenv(envCC);
+        }
+      std::string output;
+      std::string root 
+        = cmSystemTools::ConvertToOutputPath(mf->GetDefinition("CMAKE_ROOT"));
+      // if no lang specified use CXX
+      if(!lang )
+        {
+        lang = "CXX";
+        }
+      // if CXX or C,  then enable C
+      if((!this->GetLanguageEnabled(lang) && lang[0] == 'C'))
+        {
+        std::string cmd = root;
+        cmd += "/Templates/cconfigure";
+        cmSystemTools::RunCommand(cmd.c_str(), output, 
+                                  cmSystemTools::ConvertToOutputPath(mf->GetHomeOutputDirectory()).c_str());
+        std::string fpath = mf->GetHomeOutputDirectory();
+        fpath += "/CCMakeSystemConfig.cmake";
+        mf->ReadListFile(NULL,fpath.c_str());
+        this->SetLanguageEnabled("C");
+        }
+      // if CXX 
+      if(!this->GetLanguageEnabled(lang)  || strcmp(lang, "CXX") == 0)
+        {
+        std::string cmd = root;
+        cmd += "/Templates/cxxconfigure";
+        cmSystemTools::RunCommand(cmd.c_str(), output, 
+                                  cmSystemTools::ConvertToOutputPath(mf->GetHomeOutputDirectory()).c_str());
+        std::string fpath = mf->GetHomeOutputDirectory();
+        fpath += "/CXXCMakeSystemConfig.cmake";
+        mf->ReadListFile(NULL,fpath.c_str());
+        this->SetLanguageEnabled("CXX");
+        }
       }
     }
+
+  if (!m_CMakeInstance->GetLocal())
+    {
+    // if we are from the top, always define this
+    mf->AddDefinition("RUN_CONFIGURE", true);
+    }
 }
 
 ///! Create a local generator appropriate to this Global Generator

+ 3 - 1
Source/cmLocalUnixMakefileGenerator.cxx

@@ -97,7 +97,9 @@ void cmLocalUnixMakefileGenerator::Generate(bool fromTheTop)
     this->ProcessDepends(md);
     }
   // output the makefile fragment
-  this->OutputMakefile("Makefile", !fromTheTop); 
+  std::string dest = m_Makefile->GetStartOutputDirectory();
+  dest += "/Makefile";
+  this->OutputMakefile(dest.c_str(), !fromTheTop); 
 }
 
 void cmLocalUnixMakefileGenerator::ProcessDepends(const cmMakeDepend &md)

+ 53 - 100
Source/cmMakefile.cxx

@@ -20,7 +20,8 @@
 #include "cmSourceFile.h"
 #include "cmDirectory.h"
 #include "cmSystemTools.h"
-#include "cmMakefileGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
 #include "cmCommands.h"
 #include "cmCacheManager.h"
 #include "cmFunctionBlocker.h"
@@ -48,8 +49,7 @@ cmMakefile::cmMakefile()
   m_HeaderFileExtensions.push_back( "in" );
   
   m_DefineFlags = " ";
-  m_MakefileGenerator = 0;
-  m_CacheManager = 0;
+  m_LocalGenerator = 0;
   this->AddSourceGroup("", "^.*$");
   this->AddSourceGroup("Source Files", "\\.(cpp|C|c|cxx|rc|def|r|odl|idl|hpj|bat)$");
   this->AddSourceGroup("Header Files", "\\.(h|hh|hpp|hxx|hm|inl)$");
@@ -59,20 +59,20 @@ cmMakefile::cmMakefile()
 
 unsigned int cmMakefile::GetCacheMajorVersion()
 {
-  if(!this->m_CacheManager->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
+  if(!this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
     {
     return 0;
     }
-  return atoi(this->m_CacheManager->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"));
+  return atoi(this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"));
 }
 
 unsigned int cmMakefile::GetCacheMinorVersion()
 {
-  if(!this->m_CacheManager->GetCacheValue("Cmake_Cache_MINOR_VERSION"))
+  if(!this->GetCacheManager()->GetCacheValue("Cmake_Cache_MINOR_VERSION"))
     {
     return 0;
     }
-  return atoi(this->m_CacheManager->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"));
+  return atoi(this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"));
 }
 
 
@@ -132,7 +132,6 @@ cmMakefile::~cmMakefile()
     m_FunctionBlockers.remove(*pos);
     delete b;
     }
-  delete m_MakefileGenerator;
 }
 
 void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>& v) const
@@ -384,15 +383,9 @@ void cmMakefile::AddCommand(cmCommand* wg)
 }
 
   // Set the make file 
-void cmMakefile::SetMakefileGenerator(cmMakefileGenerator* mf)
+void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
 {
-  if(mf == m_MakefileGenerator)
-  {
-    return;
-  }
-  delete m_MakefileGenerator;
-  m_MakefileGenerator = mf;
-  mf->SetMakefile(this);
+  m_LocalGenerator = lg;
 }
 
 void cmMakefile::FinalPass()
@@ -430,8 +423,6 @@ void cmMakefile::GenerateMakefile()
       }
     l->second.AnalyzeLibDependencies(*this);
     }
-  // now do the generation
-  m_MakefileGenerator->GenerateMakefile();
 }
 
 
@@ -462,10 +453,10 @@ void cmMakefile::AddCustomCommand(const char* source,
     m_Targets[target].GetCustomCommands().push_back(cc);
     std::string cacheCommand = command;
     this->ExpandVariablesInString(cacheCommand);
-    if(this->m_CacheManager->GetCacheValue(cacheCommand.c_str()))
+    if(this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
       {
       m_Targets[target].AddUtility(
-        this->m_CacheManager->GetCacheValue(cacheCommand.c_str()));
+        this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()));
       }
     }
 }
@@ -596,7 +587,7 @@ void cmMakefile::AddCacheDefinition(const char* name, const char* value,
                                     const char* doc,
                                     cmCacheManager::CacheEntryType type)
 {
-  this->m_CacheManager->AddCacheEntry(name, value, doc, type);
+  this->GetCacheManager()->AddCacheEntry(name, value, doc, type);
   this->AddDefinition(name, value);
 }
 
@@ -618,7 +609,7 @@ void cmMakefile::AddDefinition(const char* name, bool value)
 
 void cmMakefile::AddCacheDefinition(const char* name, bool value, const char* doc)
 {
-  this->m_CacheManager->AddCacheEntry(name, value, doc);
+  this->GetCacheManager()->AddCacheEntry(name, value, doc);
   this->AddDefinition(name, value);
 }
 
@@ -671,7 +662,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
   // hence useless.
   std::string depname = lname;
   depname += "_LIB_DEPENDS";
-  this->m_CacheManager->
+  this->GetCacheManager()->
     AddCacheEntry(depname.c_str(), "",
                   "Dependencies for target", cmCacheManager::STATIC);
 
@@ -684,7 +675,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
   // Add an entry into the cache 
   std::string libPath = lname;
   libPath += "_CMAKE_PATH";
-  this->m_CacheManager->
+  this->GetCacheManager()->
     AddCacheEntry(libPath.c_str(),
                   this->GetCurrentOutputDirectory(),
                   "Path to a library", cmCacheManager::INTERNAL);
@@ -695,26 +686,26 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
   switch (shared)
     {
     case 0:
-      this->m_CacheManager->AddCacheEntry(ltname.c_str(),"STATIC",
+      this->GetCacheManager()->AddCacheEntry(ltname.c_str(),"STATIC",
 		      "Whether a library is static, shared or module.",
 		      cmCacheManager::INTERNAL);
       break;
     case 1:
-      this->m_CacheManager->
+      this->GetCacheManager()->
 	AddCacheEntry(ltname.c_str(),
 		      "SHARED",
 		      "Whether a library is static, shared or module.",
 		      cmCacheManager::INTERNAL);
       break;
     case 2:
-      this->m_CacheManager->
+      this->GetCacheManager()->
 	AddCacheEntry(ltname.c_str(),
 		      "MODULE",
 		      "Whether a library is static, shared or module.",
 		      cmCacheManager::INTERNAL);
       break;
     default:
-      this->m_CacheManager->
+      this->GetCacheManager()->
 	AddCacheEntry(ltname.c_str(),
 		      "STATIC",
 		      "Whether a library is static, shared or module.",
@@ -751,7 +742,7 @@ void cmMakefile::AddExecutable(const char *exeName,
   // Add an entry into the cache 
   std::string exePath = exeName;
   exePath += "_CMAKE_PATH";
-  this->m_CacheManager->
+  this->GetCacheManager()->
     AddCacheEntry(exePath.c_str(),
                   this->GetCurrentOutputDirectory(),
                   "Path to an executable", cmCacheManager::INTERNAL);
@@ -904,7 +895,7 @@ const char* cmMakefile::GetDefinition(const char* name) const
     {
     return (*pos).second.c_str();
     }
-  return this->m_CacheManager->GetCacheValue(name);
+  return this->GetCacheManager()->GetCacheValue(name);
 }
 
 int cmMakefile::DumpDocumentationToFile(std::ostream& f)
@@ -1126,59 +1117,6 @@ void cmMakefile::RemoveVariablesInString(std::string& source,
     }
 }
 
-// recursive function to create a vector of cmMakefile objects
-// This is done by reading the sub directory CMakeLists.txt files,
-// then calling this function with the new cmMakefile object
-void 
-cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>& makefiles)
-{ 
-  // loop over all the sub directories of this makefile
-  const std::vector<std::string>& subdirs = this->GetSubDirectories();
-  for(std::vector<std::string>::const_iterator i = subdirs.begin();
-      i != subdirs.end(); ++i)
-    {
-    std::string subdir = *i;
-    // Create a path to the list file in the sub directory
-    std::string listFile = this->GetCurrentDirectory();
-    listFile += "/";
-    listFile += subdir;
-    listFile += "/CMakeLists.txt";
-    // if there is a CMakeLists.txt file read it
-    if(!cmSystemTools::FileExists(listFile.c_str()))
-      {
-      cmSystemTools::Error("CMakeLists.txt file missing from sub directory:",
-                           listFile.c_str());
-      }
-    else
-      {
-      cmMakefile* mf = new cmMakefile;
-      mf->SetMakefileGenerator(m_MakefileGenerator->CreateObject());
-      mf->SetCacheManager(this->m_CacheManager);
-      makefiles.push_back(mf);
-      // initialize new makefile
-      mf->SetHomeOutputDirectory(this->GetHomeOutputDirectory());
-      mf->SetHomeDirectory(this->GetHomeDirectory());
-      // add the subdir to the start output directory
-      std::string outdir = this->GetStartOutputDirectory();
-      outdir += "/";
-      outdir += subdir;
-      mf->SetStartOutputDirectory(outdir.c_str());
-      // add the subdir to the start source directory
-      std::string currentDir = this->GetStartDirectory();
-      currentDir += "/";
-      currentDir += subdir;
-      mf->SetStartDirectory(currentDir.c_str());
-      // Parse the CMakeLists.txt file
-      currentDir += "/CMakeLists.txt";
-      mf->MakeStartDirectoriesCurrent();
-      mf->ReadListFile(currentDir.c_str());
-      // recurse into nextDir
-      mf->FindSubDirectoryCMakeListsFiles(makefiles);
-      }
-    }
-}
-
-
 /**
  * Add the default definitions to the makefile.  These values must not
  * be dependent on anything that isn't known when this cmMakefile instance
@@ -1399,7 +1337,7 @@ cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
   
 void cmMakefile::EnableLanguage(const char* lang)
 {
-  m_MakefileGenerator->EnableLanguage(lang);
+  m_LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this);
 }
 
 void cmMakefile::ExpandSourceListArguments(
@@ -1437,7 +1375,7 @@ void cmMakefile::ExpandSourceListArguments(
 int cmMakefile::TryCompile(const char *srcdir, const char *bindir, 
                            const char *projectName)
 {
-  if (!m_MakefileGenerator)
+  if (!m_LocalGenerator)
     {
     cmSystemTools::Error("Internal CMake error, Attempt to call Try Compile without the generator being set");
     return 1;
@@ -1454,43 +1392,58 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
   std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
   cmSystemTools::ChangeDirectory(bindir);
   
-  std::vector<std::string> args;
-  
   // make sure the same generator is used
   // use this program as the cmake to be run, it should not
   // be run that way but the cmake object requires a vailid path
   std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
-  args.push_back(cmakeCommand.c_str());
-  args.push_back(srcdir);
+  cmake cm;
+  cmGlobalGenerator *gg = 
+    cm.CreateGlobalGenerator(this->GetDefinition("CMAKE_GENERATOR"));
+  if (!gg)
+    {
+    cmSystemTools::Error(
+      "Internal CMake error, TryCompile bad GlobalGenerator");
+    // return to the original directory
+    cmSystemTools::ChangeDirectory(cwd.c_str());
+    return 1;
+    }
   
-  std::string generator = "-G";
-  generator += this->GetDefinition("CMAKE_GENERATOR");
-  args.push_back(generator);
+  // do a configure
+  cm.SetHomeDirectory(srcdir);
+  cm.SetHomeOutputDirectory(bindir);
+  cm.SetStartDirectory(srcdir);
+  cm.SetStartOutputDirectory(bindir);
   
-  cmake cm;
-  if (cm.Generate(args) != 0)
+  if (cm.Configure(cmakeCommand.c_str()) != 0)
     {
     cmSystemTools::Error(
-      "Internal CMake error, TryCompile execution of cmake failed");
+      "Internal CMake error, TryCompile configure of cmake failed");
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd.c_str());
     return 1;
     }
 
-  cmake cm2;
-  if (cm2.Generate(args) != 0)
+  if (cm.Generate() != 0)
     {
     cmSystemTools::Error(
-      "Internal CMake error, TryCompile execution of cmake failed");
+      "Internal CMake error, TryCompile generation of cmake failed");
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd.c_str());
     return 1;
     }
 
   // finally call the generator to actually build the resulting project
-  m_MakefileGenerator->TryCompile(srcdir,bindir,projectName);
-  cmSystemTools::ChangeDirectory(cwd.c_str());
+  gg->TryCompile(srcdir,bindir,projectName);
 
+  cmSystemTools::ChangeDirectory(cwd.c_str());
   return 0;
 }
 
+cmCacheManager *cmMakefile::GetCacheManager() const
+{
+  if (m_LocalGenerator)
+    {
+    return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->GetCacheManager();
+    }
+  return 0;
+}

+ 6 - 20
Source/cmMakefile.h

@@ -27,7 +27,7 @@
 
 class cmFunctionBlocker;
 class cmCommand;
-class cmMakefileGenerator;
+class cmLocalGenerator;
 class cmMakeDepend;
 
 /** \class cmMakefile
@@ -96,11 +96,11 @@ public:
    * dependent, although the interface is through a generic
    * superclass.
    */
-  void SetMakefileGenerator(cmMakefileGenerator*);
+  void SetLocalGenerator(cmLocalGenerator*);
   
   ///! Get the current makefile generator.
-  cmMakefileGenerator* GetMakefileGenerator() 
-    { return m_MakefileGenerator;}
+  cmLocalGenerator* GetLocalGenerator() 
+    { return m_LocalGenerator;}
 
   /**
    * Produce the output makefile.
@@ -485,15 +485,6 @@ public:
    */
   void ExpandVariables();  
 
-  /** Recursivly read and create a cmMakefile object for
-   *  all CMakeLists.txt files in the GetSubDirectories list.
-   *  Once the file is found, it ReadListFile is called on
-   *  the cmMakefile created for it.  CreateObject is called on 
-   *  the prototype to create a cmMakefileGenerator for each cmMakefile that 
-   *  is created.
-   */
-  void FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>& makefiles);
-  
   /**
    * find what source group this source is in
    */
@@ -519,14 +510,9 @@ public:
    * Set/Get the name of the parent directories CMakeLists file
    * given a current CMakeLists file name
    */
-  void SetCacheManager(cmCacheManager *cm) {
-    this->m_CacheManager = cm; }
-  cmCacheManager *GetCacheManager() {
-    return m_CacheManager; }
+  cmCacheManager *GetCacheManager() const;
 
 protected:
-  cmCacheManager *m_CacheManager;
-  
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(const char* name, cmTarget& target);
   
@@ -573,7 +559,7 @@ protected:
   DefinitionMap m_Definitions;
   RegisteredCommandsMap m_Commands;
   std::vector<cmCommand*> m_UsedCommands;
-  cmMakefileGenerator* m_MakefileGenerator;
+  cmLocalGenerator* m_LocalGenerator;
   bool IsFunctionBlocked(const char *name, std::vector<std::string> const& args);
   
 private:

+ 349 - 252
Source/cmake.cxx

@@ -17,39 +17,34 @@
 #include "cmake.h"
 #include "time.h"
 #include "cmCacheManager.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
 
 // include the generator
 #if defined(_WIN32) && !defined(__CYGWIN__)
-#include "cmMSProjectGenerator.h"
-#include "cmMSDotNETGenerator.h"
-#include "cmBorlandMakefileGenerator.h"
-#include "cmNMakeMakefileGenerator.h"
+#include "cmGlobalVisualStudio6Generator.h"
+#include "cmGlobalVisualStudio7Generator.h"
+#include "cmGlobalBorlandMakefileGenerator.h"
+#include "cmGlobalNMakeMakefileGenerator.h"
 #else
-#include "cmUnixMakefileGenerator.h"
+#include "cmGlobalUnixMakefileGenerator.h"
 #endif
 
 cmake::cmake()
 {
   m_Verbose = false;
-#if defined(_WIN32) && !defined(__CYGWIN__)  
-  this->RegisterGenerator(new cmMSProjectGenerator);
-  this->RegisterGenerator(new cmMSDotNETGenerator);
-  this->RegisterGenerator(new cmNMakeMakefileGenerator);
-  this->RegisterGenerator(new cmBorlandMakefileGenerator);
-#else
-  this->RegisterGenerator(new cmUnixMakefileGenerator);
-#endif
+  m_CacheManager = new cmCacheManager;
+  m_GlobalGenerator = 0;
 }
 
 cmake::~cmake()
 {
-  for(std::map<cmStdString, cmMakefileGenerator*>::iterator i
-        = m_RegisteredGenerators.begin(); 
-      i != m_RegisteredGenerators.end(); ++i)
+  delete m_CacheManager;
+  if (m_GlobalGenerator)
     {
-    delete i->second;
+    delete m_GlobalGenerator;
+    m_GlobalGenerator = 0;
     }
-   m_RegisteredGenerators = std::map<cmStdString, cmMakefileGenerator*>();
 }
 
 
@@ -79,8 +74,7 @@ void cmake::Usage(const char* program)
 }
 
 // Parse the args
-void cmake::SetCacheArgs(cmMakefile& builder,
-                         const std::vector<std::string>& args)
+void cmake::SetCacheArgs(const std::vector<std::string>& args)
 { 
   for(unsigned int i=1; i < args.size(); ++i)
     {
@@ -92,9 +86,7 @@ void cmake::SetCacheArgs(cmMakefile& builder,
       cmCacheManager::CacheEntryType type;
       if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type))
         {
-          this->m_CacheManager.AddCacheEntry(
-            var.c_str(), 
-            value.c_str(),
+          this->m_CacheManager->AddCacheEntry(var.c_str(), value.c_str(),
             "No help, variable specified on the command line.",
             type);
         }
@@ -108,17 +100,46 @@ void cmake::SetCacheArgs(cmMakefile& builder,
       {
       std::string path = arg.substr(2);
       std::cerr << "loading initial cache file " << path.c_str() << "\n";
-      if(!builder.ReadListFile(path.c_str()))
-        {
-        std::cerr << "Error in reading cmake initial cache file:"
-                  << path.c_str() << "\n";
-        }
+      this->ReadListFile(path.c_str());
+      }
+    }
+}
+
+void cmake::ReadListFile(const char *path)
+{
+  // if a generator was not yet created, temporarily create one
+  cmGlobalGenerator *gg = this->GetGlobalGenerator();
+  bool created;
+  
+  // if a generator was not specified use a generic one
+  if (!gg)
+    {
+    gg = new cmGlobalGenerator;
+    gg->SetCMakeInstance(this);
+    created = true;
+    }
+
+  // read in the list file to fill the cache
+  if(path)
+    {
+    cmLocalGenerator *lg = gg->CreateLocalGenerator();
+    lg->SetGlobalGenerator(gg);
+    if (!lg->GetMakefile()->ReadListFile(path))
+      {
+      std::cerr << "Error in reading cmake initial cache file:"
+                << path << "\n";
       }
     }
+  
+  // free generic one if generated
+  if (created)
+    {
+    delete gg;
+    }
 }
 
 // Parse the args
-void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
+void cmake::SetArgs(const std::vector<std::string>& args)
 {
   m_Local = false;
   bool directoriesSet = false;
@@ -126,22 +147,22 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
   if (args.size() <= 2)
     {
     directoriesSet = true;
-    builder.SetHomeOutputDirectory
+    this->SetHomeOutputDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
-    builder.SetStartOutputDirectory
+    this->SetStartOutputDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
     if (args.size() == 2)
       {
-      builder.SetHomeDirectory
+      this->SetHomeDirectory
 	(cmSystemTools::CollapseFullPath(args[1].c_str()).c_str());
-      builder.SetStartDirectory
+      this->SetStartDirectory
 	(cmSystemTools::CollapseFullPath(args[1].c_str()).c_str());
       }
     else
       {
-      builder.SetHomeDirectory
+      this->SetHomeDirectory
 	(cmSystemTools::GetCurrentWorkingDirectory().c_str());
-      builder.SetStartDirectory
+      this->SetStartDirectory
 	(cmSystemTools::GetCurrentWorkingDirectory().c_str());
       }
     }
@@ -153,26 +174,26 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
       {
       directoriesSet = true;
       std::string path = arg.substr(2);
-      builder.SetHomeDirectory(path.c_str());
+      this->SetHomeDirectory(path.c_str());
       }
     else if(arg.find("-S",0) == 0)
       {
       directoriesSet = true;
       m_Local = true;
       std::string path = arg.substr(2);
-      builder.SetStartDirectory(path.c_str());
+      this->SetStartDirectory(path.c_str());
       }
     else if(arg.find("-O",0) == 0)
       {
       directoriesSet = true;
       std::string path = arg.substr(2);
-      builder.SetStartOutputDirectory(path.c_str());
+      this->SetStartOutputDirectory(path.c_str());
       }
     else if(arg.find("-B",0) == 0)
       {
       directoriesSet = true;
       std::string path = arg.substr(2);
-      builder.SetHomeOutputDirectory(path.c_str());
+      this->SetHomeOutputDirectory(path.c_str());
       }
     else if(arg.find("-V",0) == 0)
       {
@@ -189,8 +210,8 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
     else if(arg.find("-G",0) == 0)
       {
       std::string value = arg.substr(2);
-      cmMakefileGenerator* gen = 
-        this->CreateGenerator(value.c_str());
+      cmGlobalGenerator* gen = 
+        this->CreateGlobalGenerator(value.c_str());
       if(!gen)
         {
         cmSystemTools::Error("Could not create named generator ",
@@ -198,47 +219,47 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
         }
       else
         {
-        builder.SetMakefileGenerator(gen);
+        this->SetGlobalGenerator(gen);
         }
       }
     // no option assume it is the path to the source
     else
       {
       directoriesSet = true;
-      builder.SetHomeOutputDirectory
+      this->SetHomeOutputDirectory
         (cmSystemTools::GetCurrentWorkingDirectory().c_str());
-      builder.SetStartOutputDirectory
+      this->SetStartOutputDirectory
         (cmSystemTools::GetCurrentWorkingDirectory().c_str());
-      builder.SetHomeDirectory
+      this->SetHomeDirectory
         (cmSystemTools::CollapseFullPath(arg.c_str()).c_str());
-      builder.SetStartDirectory
+      this->SetStartDirectory
         (cmSystemTools::CollapseFullPath(arg.c_str()).c_str());
       }
     }
   if(!directoriesSet)
     {
-    builder.SetHomeOutputDirectory
+    this->SetHomeOutputDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
-    builder.SetStartOutputDirectory
+    this->SetStartOutputDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
-    builder.SetHomeDirectory
+    this->SetHomeDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
-    builder.SetStartDirectory
+    this->SetStartDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
     }
   if (!m_Local)
     {
-    builder.SetStartDirectory(builder.GetHomeDirectory());
-    builder.SetStartOutputDirectory(builder.GetHomeOutputDirectory());
+    this->SetStartDirectory(this->GetHomeDirectory());
+    this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
     }
 }
 
 // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache
-int cmake::AddCMakePaths(const std::vector<std::string>& args)
+int cmake::AddCMakePaths(const char *arg0)
 {
   // Find our own executable.
   std::vector<cmStdString> failures;
-  std::string cMakeSelf = args[0];
+  std::string cMakeSelf = arg0;
   cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
   failures.push_back(cMakeSelf);
   cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str());
@@ -268,7 +289,7 @@ int cmake::AddCMakePaths(const std::vector<std::string>& args)
     failures.push_back(cMakeSelf);
     cmStringStream msg;
     msg << "CMAKE can not find the command line program cmake.\n";
-    msg << "  argv[0] = \"" << args[0].c_str() << "\"\n";
+    msg << "  argv[0] = \"" << arg0 << "\"\n";
     msg << "  Attempted paths:\n";
     std::vector<cmStdString>::iterator i;
     for(i=failures.begin(); i != failures.end(); ++i)
@@ -279,7 +300,7 @@ int cmake::AddCMakePaths(const std::vector<std::string>& args)
     return 0;
     }
   // Save the value in the cache
-  this->m_CacheManager.AddCacheEntry
+  this->m_CacheManager->AddCacheEntry
     ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.",
      cmCacheManager::INTERNAL);
 
@@ -293,7 +314,7 @@ int cmake::AddCMakePaths(const std::vector<std::string>& args)
     }
   if(cmSystemTools::FileExists(editCacheCommand.c_str()))
     {
-    this->m_CacheManager.AddCacheEntry
+    this->m_CacheManager->AddCacheEntry
       ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
        "Path to cache edit program executable.", cmCacheManager::INTERNAL);
     }
@@ -363,7 +384,7 @@ int cmake::AddCMakePaths(const std::vector<std::string>& args)
                          modules.c_str());
     return 0;
     }
-  this->m_CacheManager.AddCacheEntry
+  this->m_CacheManager->AddCacheEntry
     ("CMAKE_ROOT", cMakeRoot.c_str(),
      "Path to CMake installation.", cmCacheManager::INTERNAL);
   return 1;
@@ -371,182 +392,6 @@ int cmake::AddCMakePaths(const std::vector<std::string>& args)
 
 
 
-int cmake::Generate(const std::vector<std::string>& args, bool buildMakefiles)
-{
-   if(args.size() == 1 && !cmSystemTools::FileExists("CMakeLists.txt"))
-    {
-    this->Usage(args[0].c_str());
-    return -1;
-    }
-  // look for obvious request for help
-  for(unsigned int i=1; i < args.size(); ++i)
-    {
-    std::string arg = args[i];
-    if(arg.find("-help",0) != std::string::npos ||
-       arg.find("--help",0) != std::string::npos ||
-       arg.find("/?",0) != std::string::npos ||
-       arg.find("-usage",0) != std::string::npos)
-      {
-      this->Usage(args[0].c_str());
-      return -1;
-      }
-    }
-  // Create a makefile
-  cmMakefile mf;
-  mf.SetCacheManager(&this->m_CacheManager);
-  
-  // extract the directory arguments, could create a Generator
-  this->SetArgs(mf, args);
-  // Read and parse the input makefile
-  mf.MakeStartDirectoriesCurrent();
-  this->m_CacheManager.LoadCache(&mf);
-  if(mf.GetDefinition("CMAKE_HOME_DIRECTORY"))
-    {
-    std::string cacheStart = mf.GetDefinition("CMAKE_HOME_DIRECTORY");
-    cacheStart += "/CMakeLists.txt";
-    std::string currentStart = mf.GetHomeDirectory();
-    currentStart += "/CMakeLists.txt";
-    if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
-      {
-      std::string message = "Error: source : ";
-      message += currentStart;
-      message += "\nDoes not match source used to generate cache: ";
-      message += cacheStart;
-      message += "\nRe-run cmake with a different source directory.";
-      cmSystemTools::Error(message.c_str());
-      return -2;
-      }
-    }
-  mf.AddCacheDefinition("CMAKE_HOME_DIRECTORY", mf.GetHomeDirectory(),
-                        "Start directory with the top level CMakeLists.txt file for this project",
-                        cmCacheManager::INTERNAL);
-  
-  // extract command line arguments that might add cache entries
-  this->SetCacheArgs(mf, args);
-
-  // no generator specified on the command line
-  if(!mf.GetMakefileGenerator())
-    {
-    cmMakefileGenerator* gen;
-    const char* genName = mf.GetDefinition("CMAKE_GENERATOR");
-    if(genName)
-      {
-      gen = this->CreateGenerator(genName);
-      }
-    else
-      {
-#if defined(__BORLANDC__)
-      gen = new cmBorlandMakefileGenerator;
-#elif defined(_WIN32) && !defined(__CYGWIN__)  
-      gen = new cmMSProjectGenerator;
-#else
-      gen = new cmUnixMakefileGenerator;
-#endif
-      }
-    if(!gen)
-      {
-      cmSystemTools::Error("Could not create generator");
-      return -1;
-      }
-    mf.SetMakefileGenerator(gen);
-    // add the 
-    }
-  cmMakefileGenerator* gen = mf.GetMakefileGenerator();
-  gen->SetLocal(m_Local);
-  const char* genName = mf.GetDefinition("CMAKE_GENERATOR");
-  if(genName)
-    {
-    if(strcmp(gen->GetName(), genName) != 0)
-      {
-      std::string message = "Error: generator : ";
-      message += gen->GetName();
-      message += "\nDoes not match the generator used previously: ";
-      message += genName;
-      message +=
-        "\nEither remove the CMakeCache.txt file or choose a different"
-        " binary directory.";
-      cmSystemTools::Error(message.c_str());
-      return -2;
-      }
-    }
-  if(!mf.GetDefinition("CMAKE_GENERATOR"))
-    {
-    mf.AddCacheDefinition("CMAKE_GENERATOR",
-                          gen->GetName(),
-                          "Name of generator.",
-                          cmCacheManager::INTERNAL);
-    }
-  
-
-  // setup CMAKE_ROOT and CMAKE_COMMAND
-  if(!this->AddCMakePaths(args))
-    {
-    return -3;
-    }
-
-  // reset any system configuration information
-  cmMakefileGenerator::ClearEnabledLanguages();
-
-  std::string lf = mf.GetStartDirectory();
-  lf +=  "/CMakeLists.txt";
-  if(!mf.ReadListFile(lf.c_str()))
-    {
-    this->Usage(args[0].c_str());
-    return -1;
-    }
-  // if buildMakefiles, then call GenerateMakefile
-  if(buildMakefiles)
-    {
-    mf.GenerateMakefile();
-    }
-  else  // do not build, but let the commands finalize
-    {
-    std::vector<cmMakefile*> makefiles;
-    mf.FindSubDirectoryCMakeListsFiles(makefiles);
-    for(std::vector<cmMakefile*>::iterator i = makefiles.begin();
-      i != makefiles.end(); ++i)
-      {
-      cmMakefile* mf = *i;
-      mf->FinalPass();
-      delete mf;
-      }
-    mf.FinalPass();
-    }
-  
-  
-  // Before saving the cache
-  // if the project did not define one of the entries below, add them now
-  // so users can edit the values in the cache:
-  // LIBRARY_OUTPUT_PATH
-  // EXECUTABLE_OUTPUT_PATH
-  if(!this->m_CacheManager.GetCacheValue("LIBRARY_OUTPUT_PATH"))
-    {
-    this->m_CacheManager.AddCacheEntry("LIBRARY_OUTPUT_PATH", "",
-                                                 "Single output directory for building all libraries.",
-                                                 cmCacheManager::PATH);
-    } 
-  if(!this->m_CacheManager.GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
-    {
-    this->m_CacheManager.AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "",
-                                                 "Single output directory for building all executables.",
-                                                 cmCacheManager::PATH);
-    }  
-  
-  this->m_CacheManager.SaveCache(&mf);
-  
-  if(m_Verbose)
-    {
-    this->m_CacheManager.PrintCache(std::cout);
-    }
-  
-  if(cmSystemTools::GetErrorOccuredFlag())
-    {
-    return -1;
-    }
-  return 0;
-}
-
-
 void CMakeCommandUsage(const char* program)
 {
   cmStringStream errorStream;
@@ -678,39 +523,291 @@ int cmake::CMakeCommand(std::vector<std::string>& args)
 
 void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
 {
-  for(std::map<cmStdString, cmMakefileGenerator*>::iterator i
-        = this->m_RegisteredGenerators.begin(); 
-      i != this->m_RegisteredGenerators.end(); ++i)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  names.push_back(cmGlobalVisualStudio6Generator::GetActualName());
+  names.push_back(cmGlobalVisualStudio7Generator::GetActualName());
+  names.push_back(cmGlobalBorlandMakefileGenerator::GetActualName());
+  names.push_back(cmGlobalNMakeMakefileGenerator::GetActualName());
+#else
+  names.push_back(cmGlobalUnixMakefileGenerator::GetActualName());
+#endif
+}
+
+cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
+{
+  cmGlobalGenerator *ret = 0;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  if (!strcmp(name,cmGlobalNMakeMakefileGenerator::GetActualName()))
+    {
+    ret = new cmGlobalNMakeMakefileGenerator;
+    ret->SetCMakeInstance(this);
+    }
+  if (!strcmp(name,cmGlobalVisualStudio6Generator::GetActualName()))
+    {
+    ret = new cmGlobalVisualStudio6Generator;
+    ret->SetCMakeInstance(this);
+    }
+  if (!strcmp(name,cmGlobalVisualStudio7Generator::GetActualName()))
+    {
+    ret = new cmGlobalVisualStudio7Generator;
+    ret->SetCMakeInstance(this);
+    } 
+  if (!strcmp(name,cmGlobalBorlandMakefileGenerator::GetActualName()))
+    {
+    ret = new cmGlobalBorlandMakefileGenerator;
+    ret->SetCMakeInstance(this);
+    }
+#else
+  if (!strcmp(name,cmGlobalUnixMakefileGenerator::GetActualName()))
     {
-    names.push_back(i->first);
+    ret = new cmGlobalUnixMakefileGenerator;
+    ret->SetCMakeInstance(this);
     }
+#endif
+  return ret;
 }
 
+void cmake::SetHomeDirectory(const char* dir) 
+{
+  m_cmHomeDirectory = dir;
+  cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory);
+}
 
-void cmake::RegisterGenerator(cmMakefileGenerator* mg)
+void cmake::SetHomeOutputDirectory(const char* lib)
 {
-  std::map<cmStdString, cmMakefileGenerator*>::iterator i = 
-    this->m_RegisteredGenerators.find(mg->GetName());
-  // delete re-registered objects
-  if(i != this->m_RegisteredGenerators.end())
+  m_HomeOutputDirectory = lib;
+  cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory);
+}
+
+void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
+{
+  // delete the old generator
+  if (m_GlobalGenerator)
     {
-    delete i->second;
+    delete m_GlobalGenerator;
     }
-  this->m_RegisteredGenerators[mg->GetName()] = mg;
+  // set the new
+  m_GlobalGenerator = gg;
+  // set the cmake instance just to be sure
+  gg->SetCMakeInstance(this);
 }
 
-cmMakefileGenerator* cmake::CreateGenerator(const char* name)
+int cmake::Configure(const char *arg0, const std::vector<std::string>* args)
 {
-  std::map<cmStdString, cmMakefileGenerator*>::iterator i;
-  for(i = this->m_RegisteredGenerators.begin();
-      i != this->m_RegisteredGenerators.end(); ++i)
+  // Read in the cache
+  m_CacheManager->LoadCache(this->GetHomeOutputDirectory());
+  if(m_CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
+    {
+    std::string cacheStart = 
+      m_CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
+    cacheStart += "/CMakeLists.txt";
+    std::string currentStart = this->GetHomeDirectory();
+    currentStart += "/CMakeLists.txt";
+    if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
+      {
+      std::string message = "Error: source : ";
+      message += currentStart;
+      message += "\nDoes not match source used to generate cache: ";
+      message += cacheStart;
+      message += "\nRe-run cmake with a different source directory.";
+      cmSystemTools::Error(message.c_str());
+      return -2;
+      }
+    }
+  else
+    {
+    m_CacheManager->AddCacheEntry("CMAKE_HOME_DIRECTORY", 
+                                  this->GetHomeDirectory(),
+                                  "Start directory with the top level CMakeLists.txt file for this project",
+                                  cmCacheManager::INTERNAL);
+    }
+  
+  // extract command line arguments that might add cache entries
+  if (args)
+    {
+    this->SetCacheArgs(*args);
+    }
+
+  // setup CMAKE_ROOT and CMAKE_COMMAND
+  if(!this->AddCMakePaths(arg0))
+    {
+    return -3;
+    }
+  
+  // no generator specified on the command line
+  if(!m_GlobalGenerator)
+    {
+    const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
+    if(genName)
+      {
+      m_GlobalGenerator = this->CreateGlobalGenerator(genName);
+      }
+    else
+      {
+#if defined(__BORLANDC__)
+      this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
+#elif defined(_WIN32) && !defined(__CYGWIN__)  
+      this->SetGlobalGenerator(new cmGlobalVisualStudio6Generator);
+#else
+      this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator);
+#endif
+      }
+    if(!m_GlobalGenerator)
+      {
+      cmSystemTools::Error("Could not create generator");
+      return -1;
+      }
+    }
+
+  const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
+  if(genName)
     {
-    cmMakefileGenerator* gen = i->second;
-    if(strcmp(name, gen->GetName()) == 0)
+    if(strcmp(m_GlobalGenerator->GetName(), genName) != 0)
       {
-      return gen->CreateObject();
+      std::string message = "Error: generator : ";
+      message += m_GlobalGenerator->GetName();
+      message += "\nDoes not match the generator used previously: ";
+      message += genName;
+      message +=
+        "\nEither remove the CMakeCache.txt file or choose a different"
+        " binary directory.";
+      cmSystemTools::Error(message.c_str());
+      return -2;
       }
     }
+  if(!m_CacheManager->GetCacheValue("CMAKE_GENERATOR"))
+    {
+    m_CacheManager->AddCacheEntry("CMAKE_GENERATOR", m_GlobalGenerator->GetName(),
+                                  "Name of generator.",
+                                  cmCacheManager::INTERNAL);
+    }
+
+  // reset any system configuration information
+  m_GlobalGenerator->ClearEnabledLanguages();
+
+  // actually do the configure
+  m_GlobalGenerator->Configure();
+  
+  // Before saving the cache
+  // if the project did not define one of the entries below, add them now
+  // so users can edit the values in the cache:
+  // LIBRARY_OUTPUT_PATH
+  // EXECUTABLE_OUTPUT_PATH
+  if(!m_CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH"))
+    {
+    m_CacheManager->AddCacheEntry("LIBRARY_OUTPUT_PATH", "",
+                                  "Single output directory for building all libraries.",
+                                  cmCacheManager::PATH);
+    } 
+  if(!m_CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
+    {
+    m_CacheManager->AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "",
+                                  "Single output directory for building all executables.",
+                                  cmCacheManager::PATH);
+    }  
+  
+  this->m_CacheManager->SaveCache(this->GetHomeOutputDirectory());
+  if(cmSystemTools::GetErrorOccuredFlag())
+    {
+    return -1;
+    }
   return 0;
 }
 
+// handle a command line invocation
+int cmake::Run(const std::vector<std::string>& args)
+{
+  // a quick check for args
+  if(args.size() == 1 && !cmSystemTools::FileExists("CMakeLists.txt"))
+    {
+    this->Usage(args[0].c_str());
+    return -1;
+    }
+
+  // look for obvious request for help
+  for(unsigned int i=1; i < args.size(); ++i)
+    {
+    std::string arg = args[i];
+    if(arg.find("-help",0) != std::string::npos ||
+       arg.find("--help",0) != std::string::npos ||
+       arg.find("/?",0) != std::string::npos ||
+       arg.find("-usage",0) != std::string::npos)
+      {
+      this->Usage(args[0].c_str());
+      return -1;
+      }
+    }
+
+  // Process the arguments
+  this->SetArgs(args);
+  
+  // if we are local do the local thing, otherwise do global
+  if (m_Local)
+    {
+    return this->LocalGenerate();
+    }
+
+  // otherwise global
+  int ret = this->Configure(args[0].c_str(),&args);
+  if (ret)
+    {
+    return ret;
+    }
+  return this->Generate();
+}
+
+int cmake::Generate()
+{
+  m_GlobalGenerator->Generate();
+  if(cmSystemTools::GetErrorOccuredFlag())
+    {
+    return -1;
+    }
+  return 0;
+}
+
+int cmake::LocalGenerate()
+{
+  // Read in the cache
+  m_CacheManager->LoadCache(this->GetHomeOutputDirectory());
+
+  // create the generator based on the cache if it isn't already there
+  const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
+  if(genName)
+    {
+    m_GlobalGenerator = this->CreateGlobalGenerator(genName);
+    }
+  else
+    {
+    cmSystemTools::Error("Could local Generate called without the GENERATOR being specified in the CMakeCache");
+    return -1;
+    }
+  
+  // do the local generate
+  m_GlobalGenerator->LocalGenerate();
+  if(cmSystemTools::GetErrorOccuredFlag())
+    {
+    return -1;
+    }
+  return 0;
+}
+
+unsigned int cmake::GetMajorVersion() 
+{ 
+  return cmMakefile::GetMajorVersion();
+}
+
+unsigned int cmake::GetMinorVersion()
+{ 
+  return cmMakefile::GetMinorVersion();
+}
+
+const char *cmake::GetReleaseVersion()
+{ 
+  return cmMakefile::GetReleaseVersion();
+}
+
+const char* cmake::GetCacheDefinition(const char* name) const
+{
+  return m_CacheManager->GetCacheValue(name);
+}

+ 125 - 27
Source/cmake.h

@@ -18,18 +18,81 @@
 // running cmake. Most cmake based GUIS should primarily create an instance
 // of this class and communicate with it.
 
-#include "cmMakefile.h"
 #include "cmStandardIncludes.h"
+#include "cmSystemTools.h"
+
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmCacheManager;
+class cmMakefile;
 
 class cmake
 {
  public:
+  ///! construct an instance of cmake
+  cmake();
+  ///! destruct an instance of cmake
+  ~cmake();
 
   /**
-   * Generate the SourceFilesList from the SourceLists. This should only be
-   * done once to be safe.  
+   * Return major and minor version numbers for cmake.
    */
-  void Usage(const char *program);
+  static unsigned int GetMajorVersion(); 
+  static unsigned int GetMinorVersion(); 
+  static const char *GetReleaseVersion();
+
+  //@{
+  /**
+   * Set/Get the home directory (or output directory) in the project. The
+   * home directory is the top directory of the project. It is where
+   * cmake was run. Remember that CMake processes
+   * CMakeLists files by recursing up the tree starting at the StartDirectory
+   * and going up until it reaches the HomeDirectory.  
+   */
+  void SetHomeDirectory(const char* dir);
+  const char* GetHomeDirectory() const
+    {
+    return m_cmHomeDirectory.c_str();
+    }
+  void SetHomeOutputDirectory(const char* lib);
+  const char* GetHomeOutputDirectory() const
+    {
+    return m_HomeOutputDirectory.c_str();
+    }
+  //@}
+
+  //@{
+  /**
+   * Set/Get the start directory (or output directory). The start directory
+   * is the directory of the CMakeLists.txt file that started the current
+   * round of processing. Remember that CMake processes CMakeLists files by
+   * recursing up the tree starting at the StartDirectory and going up until
+   * it reaches the HomeDirectory.  
+   */
+  void SetStartDirectory(const char* dir) 
+    {
+      m_cmStartDirectory = dir;
+      cmSystemTools::ConvertToUnixSlashes(m_cmStartDirectory);
+    }
+  const char* GetStartDirectory() const
+    {
+      return m_cmStartDirectory.c_str();
+    }
+  void SetStartOutputDirectory(const char* lib)
+    {
+      m_StartOutputDirectory = lib;
+      cmSystemTools::ConvertToUnixSlashes(m_StartOutputDirectory);
+    }
+  const char* GetStartOutputDirectory() const
+    {
+      return m_StartOutputDirectory.c_str();
+    }
+  //@}
+
+  /**
+   * Handle a command line invocation of cmake.
+   */
+  int Run(const std::vector<std::string>&args);
 
   /**
    * Generate the SourceFilesList from the SourceLists. This should only be
@@ -41,7 +104,35 @@ class cmake
    * If you only want to parse the CMakeLists.txt files,
    * but not actually generate the makefiles, use buildMakefiles = false.
    */
-  int Generate(const std::vector<std::string>&, bool buildMakefiles = true);
+  int Generate();
+
+  /**
+   * Configure the cmMakefiles. This routine will create a GlobalGenerator if
+   * one has not already been set. It will then Call Configure on the
+   * GlobalGenerator. This in turn will read in an process all the CMakeList
+   * files for the tree. It will not produce any actual Makefiles, or
+   * workspaces. Generate does that.  */
+  int Configure(const char *cmakeexec, const std::vector<std::string> *args = 0);
+
+  ///! Create a GlobalGenerator
+  cmGlobalGenerator* CreateGlobalGenerator(const char* name);
+
+  ///! Return the global generator assigned to this instance of cmake
+  cmGlobalGenerator* GetGlobalGenerator() { return m_GlobalGenerator; };
+
+  ///! Return the global generator assigned to this instance of cmake
+  void SetGlobalGenerator(cmGlobalGenerator *);
+
+  ///! Get the names of the current registered generators
+  void GetRegisteredGenerators(std::vector<std::string>& names);
+
+  ///! get the cmCachemManager used by this invocation of cmake
+  cmCacheManager *GetCacheManager() { return m_CacheManager; }
+  
+  /**
+   * Given a variable name, return its value (as a string).
+   */
+  const char* GetCacheDefinition(const char*) const;
 
   /** 
    * Execute commands during the build process. Supports options such
@@ -49,36 +140,43 @@ class cmake
    */
   static int CMakeCommand(std::vector<std::string>&);
 
+  /**
+   * Is cmake in the process of a local cmake invocation. If so, we know the
+   * cache is already configured and ready to go. 
+   */
+  bool GetLocal() 
+    {
+      return m_Local;
+    }
+  
+  ///! Display command line useage
+  void Usage(const char *program);
+
   ///! Parse command line arguments
-  void SetArgs(cmMakefile& builder, const std::vector<std::string>&);
+  void SetArgs(const std::vector<std::string>&);
+
+protected:
+  cmGlobalGenerator *m_GlobalGenerator;
+  cmCacheManager *m_CacheManager;
+  std::string m_cmHomeDirectory; 
+  std::string m_HomeOutputDirectory;
+  std::string m_cmStartDirectory; 
+  std::string m_StartOutputDirectory;
+
   ///! Parse command line arguments that might set cache values
-  void SetCacheArgs(cmMakefile& builder, const std::vector<std::string>&);
+  void SetCacheArgs(const std::vector<std::string>&);
 
+  ///! read in a cmake list file to initialize the cache
+  void ReadListFile(const char *path);
+  
   /**
    * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
    */
-  int AddCMakePaths(const std::vector<std::string>&);
+  int AddCMakePaths(const char *arg0);
 
-  /**
-   * constructor
-   */
-  cmake();
-  ~cmake();
+  ///! used by Run
+  int LocalGenerate();
 
-  ///! Create a named generator
-  cmMakefileGenerator* CreateGenerator(const char* name);
-  ///! Register a generator
-  void RegisterGenerator(cmMakefileGenerator*);
-  ///! Get the names of the current registered generators
-  void GetRegisteredGenerators(std::vector<std::string>& names);
-
-  ///! get the cmCachemManager used by this invocation of cmake
-  cmCacheManager *GetCacheManager() {
-    return &m_CacheManager; }
-  
-protected:
-  std::map<cmStdString, cmMakefileGenerator*> m_RegisteredGenerators;
-  cmCacheManager m_CacheManager;
 private:
   bool m_Verbose;
   bool m_Local;

+ 1 - 1
Source/cmakemain.cxx

@@ -55,6 +55,6 @@ int main(int ac, char** av)
     return 0;
     }
   cmake cm;
-  int ret = cm.Generate(args);
+  int ret = cm.Run(args);
   return ret;  
 }

+ 2 - 2
Source/cmaketest.cxx

@@ -115,7 +115,7 @@ int main (int argc, char **argv)
   std::cout << "Generating build files...\n";
 
   cmake cm;
-  if (cm.Generate(args) != 0)
+  if (cm.Run(args) != 0)
     {
     std::cerr << "Error: cmake execution failed\n";
     // return to the original directory
@@ -126,7 +126,7 @@ int main (int argc, char **argv)
 
   cmake cm2;
   std::cout << "Generating build files (again)...\n";
-  if (cm2.Generate(args) != 0)
+  if (cm2.Run(args) != 0)
     {
     std::cerr << "Error: cmake execution failed\n";
     // return to the original directory

+ 2 - 1
Source/cmakewizard.cxx

@@ -98,7 +98,7 @@ void cmakewizard::RunWizard(std::vector<std::string> const& args)
     asked = false;
     // run cmake
     this->ShowMessage("Please wait while cmake processes CMakeLists.txt files....\n");
-    make.Generate(args);
+    make.Configure(args[0].c_str(),&args);
     this->ShowMessage("\n");
     // load the cache from disk
     cmCacheManager *cachem = make.GetCacheManager();
@@ -140,5 +140,6 @@ void cmakewizard::RunWizard(std::vector<std::string> const& args)
     cachem->SaveCache(cmSystemTools::GetCurrentWorkingDirectory().c_str());
     }
   while(asked);
+  make.Generate();
   this->ShowMessage("CMake complete, run make to build project.\n");
 }