diff --git a/Source/MFCDialog/CMakeSetup.cpp b/Source/MFCDialog/CMakeSetup.cpp index 707b9c6e6..e958b2f83 100644 --- a/Source/MFCDialog/CMakeSetup.cpp +++ b/Source/MFCDialog/CMakeSetup.cpp @@ -78,8 +78,6 @@ BOOL CMakeSetup::InitInstance() // clean up globals cmListFileCache::GetInstance()->ClearCache(); - cmMakefileGenerator::UnRegisterGenerators(); - cmCacheManager::DeleteInstance(); // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; diff --git a/Source/MFCDialog/CMakeSetupDialog.cpp b/Source/MFCDialog/CMakeSetupDialog.cpp index 9f1e20e39..4ddca5444 100644 --- a/Source/MFCDialog/CMakeSetupDialog.cpp +++ b/Source/MFCDialog/CMakeSetupDialog.cpp @@ -110,6 +110,7 @@ CMakeSetupDialog::CMakeSetupDialog(const CMakeCommandLineInfo& cmdInfo, { cmSystemTools::SetErrorCallback(MFCMessageCallback); m_RegistryKey = "Software\\Kitware\\CMakeSetup\\Settings\\StartPath"; + m_CacheEntriesList.m_CMakeSetupDialog = this; //{{AFX_DATA_INIT(CMakeSetupDialog) // Get the parameters from the command line info @@ -145,6 +146,7 @@ CMakeSetupDialog::CMakeSetupDialog(const CMakeCommandLineInfo& cmdInfo, m_oldCX = -1; m_deltaXRemainder = 0; + m_CMakeInstance = 0; } void CMakeSetupDialog::DoDataExchange(CDataExchange* pDX) @@ -243,9 +245,9 @@ BOOL CMakeSetupDialog::OnInitDialog() SetIcon(m_hIcon, FALSE); // Set small icon // Load source and build dirs from registry this->LoadFromRegistry(); - cmake m; // force a register of generators + this->m_CMakeInstance = new cmake; std::vector names; - cmMakefileGenerator::GetRegisteredGenerators(names); + this->m_CMakeInstance->GetRegisteredGenerators(names); for(std::vector::iterator i = names.begin(); i != names.end(); ++i) { @@ -558,11 +560,16 @@ 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 a cmake object - cmake make; // create the arguments for the cmake object std::vector args; args.push_back((const char*)m_PathToExecutable); @@ -577,7 +584,7 @@ void CMakeSetupDialog::RunCMake(bool generateProjectFiles) arg += m_GeneratorChoiceString; args.push_back(arg); // run the generate process - if(make.Generate(args, generateProjectFiles) != 0) + if(this->m_CMakeInstance->Generate(args, generateProjectFiles) != 0) { cmSystemTools::Error( "Error in generation process, project files may be invalid"); @@ -643,14 +650,14 @@ void CMakeSetupDialog::OnChangeWhereBuild() std::string cache_file = path; cache_file += "/CMakeCache.txt"; - cmCacheManager *cache = cmCacheManager::GetInstance(); + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); if (cmSystemTools::FileExists(cache_file.c_str()) && - cache->LoadCache(path.c_str()) && - cache->GetCacheEntry("CMAKE_HOME_DIRECTORY")) + cachem->LoadCache(path.c_str()) && + cachem->GetCacheEntry("CMAKE_HOME_DIRECTORY")) { path = ConvertToWindowsPath( - cache->GetCacheEntry("CMAKE_HOME_DIRECTORY")->m_Value.c_str()); + cachem->GetCacheEntry("CMAKE_HOME_DIRECTORY")->m_Value.c_str()); this->m_WhereSource = path.c_str(); this->m_WhereSourceControl.SetWindowText(this->m_WhereSource); this->OnChangeWhereSource(); @@ -666,6 +673,7 @@ void CMakeSetupDialog::OnChangeWhereBuild() // copy from the cache manager to the cache edit list box void CMakeSetupDialog::FillCacheGUIFromCacheManager() { + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); size_t size = m_CacheEntriesList.GetItems().size(); bool reverseOrder = false; // if there are already entries in the cache, then @@ -683,7 +691,7 @@ void CMakeSetupDialog::FillCacheGUIFromCacheManager() CPropertyItem* item = *i; item->m_NewValue = false; } - for(cmCacheManager::CacheIterator i = cmCacheManager::GetInstance()->NewIterator(); + for(cmCacheManager::CacheIterator i = cachem->NewIterator(); !i.IsAtEnd(); i.Next()) { const char* key = i.GetName(); @@ -700,7 +708,7 @@ void CMakeSetupDialog::FillCacheGUIFromCacheManager() if(!m_AdvancedValues) { - if(cmCacheManager::GetInstance()->IsAdvanced(key)) + if(cachem->IsAdvanced(key)) { m_CacheEntriesList.RemoveProperty(key); continue; @@ -758,7 +766,7 @@ void CMakeSetupDialog::FillCacheGUIFromCacheManager() } } m_OKButton.EnableWindow(false); - if(cmCacheManager::GetInstance()->GetSize() > 0 && !cmSystemTools::GetErrorOccuredFlag()) + if(cachem->GetSize() > 0 && !cmSystemTools::GetErrorOccuredFlag()) { bool enable = true; items = m_CacheEntriesList.GetItems(); @@ -787,13 +795,13 @@ void CMakeSetupDialog::FillCacheGUIFromCacheManager() // copy from the list box to the cache manager void CMakeSetupDialog::FillCacheManagerFromCacheGUI() { + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); std::set items = m_CacheEntriesList.GetItems(); for(std::set::iterator i = items.begin(); i != items.end(); ++i) { CPropertyItem* item = *i; - cmCacheManager::CacheEntry *entry = - cmCacheManager::GetInstance()->GetCacheEntry( + cmCacheManager::CacheEntry *entry = cachem->GetCacheEntry( (const char*)item->m_propName); if (entry) { @@ -820,14 +828,15 @@ void CMakeSetupDialog::FillCacheManagerFromCacheGUI() //! Load cache file from m_WhereBuild and display in GUI editor void CMakeSetupDialog::LoadCacheFromDiskToGUI() { + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); if(m_WhereBuild != "") { - cmCacheManager::GetInstance()->LoadCache(m_WhereBuild); + cachem->LoadCache(m_WhereBuild); this->FillCacheGUIFromCacheManager(); - if(cmCacheManager::GetInstance()->GetCacheEntry("CMAKE_GENERATOR")) + if(cachem->GetCacheEntry("CMAKE_GENERATOR")) { std::string curGen = - cmCacheManager::GetInstance()->GetCacheEntry("CMAKE_GENERATOR")->m_Value; + cachem->GetCacheEntry("CMAKE_GENERATOR")->m_Value; if(m_GeneratorChoiceString != curGen.c_str()) { m_GeneratorChoiceString = curGen.c_str(); @@ -840,10 +849,11 @@ void CMakeSetupDialog::LoadCacheFromDiskToGUI() //! Save GUI values to cmCacheManager and then save to disk. void CMakeSetupDialog::SaveCacheFromGUI() { + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); this->FillCacheManagerFromCacheGUI(); if(m_WhereBuild != "") { - cmCacheManager::GetInstance()->SaveCache(m_WhereBuild); + cachem->SaveCache(m_WhereBuild); } } @@ -958,7 +968,6 @@ void CMakeSetupDialog::OnOk() cmSystemTools::EnableMessages(); m_CacheEntriesList.ClearDirty(); this->RunCMake(true); - cmMakefileGenerator::UnRegisterGenerators(); if (!(::GetKeyState(VK_SHIFT) & 0x1000)) { CDialog::OnOK(); @@ -1111,12 +1120,13 @@ void CMakeSetupDialog::OnHelpButton() void CMakeSetupDialog::ShowAdvancedValues() { - for(cmCacheManager::CacheIterator i = cmCacheManager::GetInstance()->NewIterator(); + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); + for(cmCacheManager::CacheIterator i = cachem->NewIterator(); !i.IsAtEnd(); i.Next()) { const char* key = i.GetName(); const cmCacheManager::CacheEntry& value = i.GetEntry(); - if(!cmCacheManager::GetInstance()->IsAdvanced(key)) + if(!cachem->IsAdvanced(key)) { continue; } @@ -1175,12 +1185,14 @@ void CMakeSetupDialog::ShowAdvancedValues() void CMakeSetupDialog::RemoveAdvancedValues() { - for(cmCacheManager::CacheIterator i = cmCacheManager::GetInstance()->NewIterator(); + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); + + for(cmCacheManager::CacheIterator i = cachem->NewIterator(); !i.IsAtEnd(); i.Next()) { const char* key = i.GetName(); const cmCacheManager::CacheEntry& value = i.GetEntry(); - if(cmCacheManager::GetInstance()->IsAdvanced(key)) + if(cachem->IsAdvanced(key)) { m_CacheEntriesList.RemoveProperty(key); } @@ -1229,17 +1241,17 @@ void CMakeSetupDialog::ChangeDirectoriesFromFile(const char* buffer) std::string cache_file = path; cache_file += "/CMakeCache.txt"; - cmCacheManager *cache = cmCacheManager::GetInstance(); + cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager(); if (cmSystemTools::FileExists(cache_file.c_str()) && - cache->LoadCache(path.c_str()) && - cache->GetCacheEntry("CMAKE_HOME_DIRECTORY")) + cachem->LoadCache(path.c_str()) && + cachem->GetCacheEntry("CMAKE_HOME_DIRECTORY")) { path = ConvertToWindowsPath(path.c_str()); this->m_WhereBuild = path.c_str(); path = ConvertToWindowsPath( - cache->GetCacheEntry("CMAKE_HOME_DIRECTORY")->m_Value.c_str()); + cachem->GetCacheEntry("CMAKE_HOME_DIRECTORY")->m_Value.c_str()); this->m_WhereSource = path.c_str(); } else diff --git a/Source/MFCDialog/CMakeSetupDialog.h b/Source/MFCDialog/CMakeSetupDialog.h index d0c5ac12d..21ff68d5c 100644 --- a/Source/MFCDialog/CMakeSetupDialog.h +++ b/Source/MFCDialog/CMakeSetupDialog.h @@ -30,6 +30,7 @@ // CMakeSetupDialog dialog class CMakeCommandLineInfo; +class cmake; class CMakeSetupDialog : public CDialog { @@ -37,6 +38,9 @@ class CMakeSetupDialog : public CDialog public: CMakeSetupDialog(const CMakeCommandLineInfo& cmdInfo, CWnd* pParent = NULL); + // return the cmake that is currently being used + cmake *GetCMakeInstance() { + return m_CMakeInstance; } protected: //! Load cache file from m_WhereBuild and display in GUI editor void LoadCacheFromDiskToGUI(); @@ -119,8 +123,9 @@ protected: DECLARE_MESSAGE_MAP() int m_oldCX; - int m_oldCY; + int m_oldCY; float m_deltaXRemainder; + cmake *m_CMakeInstance; }; //{{AFX_INSERT_LOCATION}} diff --git a/Source/MFCDialog/PropertyList.cpp b/Source/MFCDialog/PropertyList.cpp index 4887fa4ad..1ef39506f 100644 --- a/Source/MFCDialog/PropertyList.cpp +++ b/Source/MFCDialog/PropertyList.cpp @@ -2,11 +2,13 @@ // #include "stdafx.h" -#include "PropertyList.h" +#include "shellapi.h" +#include "CMakeSetup.h" +#include "CMakeSetupDialog.h" #include "PathDialog.h" #include "../cmCacheManager.h" #include "../cmSystemTools.h" - +#include "../cmake.h" #define IDC_PROPCMBBOX 712 #define IDC_PROPEDITBOX 713 #define IDC_PROPBTNCTRL 714 @@ -655,7 +657,7 @@ void CPropertyList::OnDelete() return; } CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel); - cmCacheManager::GetInstance()->RemoveCacheEntry(pItem->m_propName); + m_CMakeSetupDialog->GetCMakeInstance()->GetCacheManager()->RemoveCacheEntry(pItem->m_propName); m_PropertyItems.erase(pItem); delete pItem; this->DeleteString(m_curSel); @@ -680,7 +682,8 @@ void CPropertyList::RemoveAll() for(int i =0; i < c; ++i) { CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(0); - cmCacheManager::GetInstance()->RemoveCacheEntry(pItem->m_propName); + m_CMakeSetupDialog->GetCMakeInstance()->GetCacheManager() + ->RemoveCacheEntry(pItem->m_propName); m_PropertyItems.erase(pItem); delete pItem; this->DeleteString(0); diff --git a/Source/MFCDialog/PropertyList.h b/Source/MFCDialog/PropertyList.h index 5cda18c2f..535f0d07e 100644 --- a/Source/MFCDialog/PropertyList.h +++ b/Source/MFCDialog/PropertyList.h @@ -20,6 +20,7 @@ #include "../cmStandardIncludes.h" +class CMakeSetupDialog; ///////////////////////////////////////////////////////////////////////////// //CPropertyList Items @@ -34,6 +35,7 @@ public: CString m_cmbItems; bool m_NewValue; bool m_Removed; + public: CPropertyItem(CString propName, CString curValue, CString helpString, @@ -70,6 +72,7 @@ public: // Attributes public: + CMakeSetupDialog *m_CMakeSetupDialog; // Operations public: diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index c73402874..683393505 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -32,13 +32,15 @@ void cmSetClientData(void *info, void *cd) ((cmLoadedCommandInfo *)info)->ClientData = cd; } -unsigned int cmGetCacheMajorVersion(void *) +unsigned int cmGetCacheMajorVersion(void *arg) { - return cmMakefile::GetCacheMajorVersion(); + cmMakefile *mf = static_cast(arg); + return mf->GetCacheMajorVersion(); } -unsigned int cmGetCacheMinorVersion(void *) +unsigned int cmGetCacheMinorVersion(void *arg) { - return cmMakefile::GetCacheMinorVersion(); + cmMakefile *mf = static_cast(arg); + return mf->GetCacheMinorVersion(); } unsigned int cmGetMajorVersion(void *) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index f15b4dbbd..598deb893 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -50,27 +50,6 @@ cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s) return STRING; } -void cmCacheManager::DeleteInstance() -{ - delete cmCacheManager::GetInstance(); - cmCacheManager::s_Instance = 0; -} - - - -cmCacheManager* cmCacheManager::s_Instance = 0; - -cmCacheManager* cmCacheManager::GetInstance() -{ - if(!cmCacheManager::s_Instance) - { - cmCacheManager::s_Instance = new cmCacheManager; - } - return cmCacheManager::s_Instance; -} - - - bool cmCacheManager::LoadCache(cmMakefile* mf) { return this->LoadCache(mf->GetHomeOutputDirectory()); @@ -523,8 +502,7 @@ bool cmCacheManager::IsAdvanced(const char* key) { std::string advancedVar = key; advancedVar += "-ADVANCED"; - const char* value = - cmCacheManager::GetInstance()->GetCacheValue(advancedVar.c_str()); + const char* value = this->GetCacheValue(advancedVar.c_str()); if(value) { return cmSystemTools::IsOn(value); diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index dca613fdb..0e8082253 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -69,9 +69,6 @@ public: * can be different than just a path input */ static CacheEntryType StringToType(const char*); - ///! Singleton pattern get instance of the cmCacheManager. - static cmCacheManager* GetInstance(); - static void DeleteInstance(); ///! Load a cache for given makefile. Loads from ouput home. bool LoadCache(cmMakefile*); @@ -122,7 +119,6 @@ protected: private: static void OutputHelpString(std::ofstream& fout, const std::string& helpString); - static cmCacheManager* s_Instance; CacheEntryMap m_Cache; // Only cmake and cmMakefile should be able to add cache values // the commands should never use the cmCacheManager directly diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index b60a114a0..7517bf064 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -76,6 +76,7 @@ #include "cmSubdirCommand.cxx" #include "cmSubdirDependsCommand.cxx" #include "cmTargetLinkLibrariesCommand.cxx" +#include "cmTryCompileCommand.cxx" #include "cmUseMangledMesaCommand.cxx" #include "cmUtilitySourceCommand.cxx" #include "cmVariableRequiresCommand.cxx" @@ -157,6 +158,7 @@ void GetPredefinedCommands(std::list& commands) commands.push_back(new cmSubdirCommand); commands.push_back(new cmSubdirDependsCommand); commands.push_back(new cmTargetLinkLibrariesCommand); + commands.push_back(new cmTryCompileCommand); commands.push_back(new cmUseMangledMesaCommand); commands.push_back(new cmUtilitySourceCommand); commands.push_back(new cmVariableRequiresCommand); diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index f4b2474aa..6141826e9 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -59,7 +59,7 @@ bool cmFindPathCommand::InitialPass(std::vector const& argsIn) if(cacheValue) { cmCacheManager::CacheEntry* e = - cmCacheManager::GetInstance()->GetCacheEntry(args[0].c_str()); + m_Makefile->GetCacheManager()->GetCacheEntry(args[0].c_str()); if(e) { helpString = e->m_HelpString; diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index c67597366..1efea588e 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -65,7 +65,7 @@ bool cmFindProgramCommand::InitialPass(std::vector const& argsIn) if(cacheValue) { cmCacheManager::CacheEntry* e = - cmCacheManager::GetInstance()->GetCacheEntry(args[0].c_str()); + m_Makefile->GetCacheManager()->GetCacheEntry(args[0].c_str()); if(e) { doc = e->m_HelpString; diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index aa9186a70..ea19afebe 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -80,7 +80,7 @@ bool cmLoadCacheCommand::InitialPass(std::vector const& argsIn) { break; } - cmCacheManager::GetInstance()->LoadCache(args[i].c_str(), false, + m_Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false, excludes, includes); } diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index a181f001e..16e16ee92 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -152,7 +152,7 @@ bool cmLoadCommandCommand::InitialPass(std::vector const& argsIn) // the file must exist std::string fullPath = cmDynamicLoader::LibPrefix(); - fullPath += argsIn[0] + cmDynamicLoader::LibExtension(); + fullPath += "cm" + argsIn[0] + cmDynamicLoader::LibExtension(); std::vector args; cmSystemTools::ExpandListArguments(argsIn, args); diff --git a/Source/cmMSDotNETGenerator.cxx b/Source/cmMSDotNETGenerator.cxx index 804eaa158..79e30d517 100644 --- a/Source/cmMSDotNETGenerator.cxx +++ b/Source/cmMSDotNETGenerator.cxx @@ -1380,3 +1380,50 @@ std::string cmMSDotNETGenerator::ConvertToXMLOutputPathSingle(const char* path) cmSystemTools::ReplaceString(ret, "\"", ""); return ret; } + + +int cmMSDotNETGenerator::TryCompile(const char *srcdir, + const char *bindir, + const char *projectName) +{ + // now build the test + std::string makeCommand = m_Makefile->GetDefinition("CMAKE_MAKE_PROGRAM"); + if(makeCommand.size() == 0) + { + cmSystemTools::Error( + "Generator cannot find the appropriate make command."); + return 1; + } + makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str()); + std::string lowerCaseCommand = makeCommand; + cmSystemTools::LowerCase(lowerCaseCommand); + + /** + * Run an executable command and put the stdout in output. + */ + std::string output; + + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + cmSystemTools::ChangeDirectory(bindir); + +#if defined(_WIN32) && !defined(__CYGWIN__) + if(makeCommand.find(' ') != std::string::npos) + { + cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + } +#endif + makeCommand += " "; + makeCommand += projectName; + makeCommand += ".sln /rebuild Debug /project ALL_BUILD"; + + if (!cmSystemTools::RunCommand(makeCommand.c_str(), output)) + { + cmSystemTools::Error("Generator: execution of devenv failed."); + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 0; +} + diff --git a/Source/cmMSDotNETGenerator.h b/Source/cmMSDotNETGenerator.h index b2c5f1b8d..7fb9ab828 100644 --- a/Source/cmMSDotNETGenerator.h +++ b/Source/cmMSDotNETGenerator.h @@ -66,6 +66,16 @@ public: */ virtual void EnableLanguage(const char*); + + /** + * Try running cmake and building a file. This is used for dynalically + * loaded commands, not as part of the usual build process. For the + * generator, it can assume that cmake has been run on the srcdir/bindir + * and it just needs to be compiled. + */ + virtual int TryCompile(const char *srcdir, const char *bindir, + const char *projectName); + protected: /** * Return array of created VCProj names in a STL vector. diff --git a/Source/cmMSProjectGenerator.cxx b/Source/cmMSProjectGenerator.cxx index c577efb51..9d0768eba 100644 --- a/Source/cmMSProjectGenerator.cxx +++ b/Source/cmMSProjectGenerator.cxx @@ -75,3 +75,51 @@ void cmMSProjectGenerator::EnableLanguage(const char*) } } +int cmMSProjectGenerator::TryCompile(const char *srcdir, + const char *bindir, + const char *projectName) +{ + // now build the test + std::string makeCommand = m_Makefile->GetDefinition("CMAKE_MAKE_PROGRAM"); + if(makeCommand.size() == 0) + { + cmSystemTools::Error( + "Generator cannot find the appropriate make command."); + return 1; + } + makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str()); + std::string lowerCaseCommand = makeCommand; + cmSystemTools::LowerCase(lowerCaseCommand); + + /** + * Run an executable command and put the stdout in output. + */ + std::string output; + + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + cmSystemTools::ChangeDirectory(bindir); + + // if there are spaces in the makeCommand, assume a full path + // and convert it to a path with no spaces in it as the + // RunCommand does not like spaces +#if defined(_WIN32) && !defined(__CYGWIN__) + if(makeCommand.find(' ') != std::string::npos) + { + cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + } +#endif + makeCommand += " "; + makeCommand += projectName; + makeCommand += ".dsw /MAKE \"ALL_BUILD - Debug\" /REBUILD"; + + if (!cmSystemTools::RunCommand(makeCommand.c_str(), output)) + { + cmSystemTools::Error("Generator: execution of msdev failed."); + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 0; +} + diff --git a/Source/cmMSProjectGenerator.h b/Source/cmMSProjectGenerator.h index d8d81a030..ff1762af0 100644 --- a/Source/cmMSProjectGenerator.h +++ b/Source/cmMSProjectGenerator.h @@ -75,6 +75,15 @@ public: */ virtual void EnableLanguage(const char*); + /** + * Try running cmake and building a file. This is used for dynalically + * loaded commands, not as part of the usual build process. For the + * generator, it can assume that cmake has been run on the srcdir/bindir + * and it just needs to be compiled. + */ + virtual int TryCompile(const char *srcdir, const char *bindir, + const char *projectName); + private: cmDSWWriter* m_DSWWriter; cmDSPWriter* m_DSPWriter; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 9948b90b3..ba036c29e 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -25,6 +25,7 @@ #include "cmCacheManager.h" #include "cmFunctionBlocker.h" #include "cmListFileCache.h" +#include "cmake.h" #include // required for sprintf // default is not to be building executables @@ -48,6 +49,7 @@ cmMakefile::cmMakefile() m_DefineFlags = " "; m_MakefileGenerator = 0; + m_CacheManager = 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)$"); @@ -57,24 +59,20 @@ cmMakefile::cmMakefile() unsigned int cmMakefile::GetCacheMajorVersion() { - if(!cmCacheManager::GetInstance()-> - GetCacheValue("CMAKE_CACHE_MAJOR_VERSION")) + if(!this->m_CacheManager->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION")) { return 0; } - return atoi(cmCacheManager::GetInstance()-> - GetCacheValue("CMAKE_CACHE_MAJOR_VERSION")); + return atoi(this->m_CacheManager->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION")); } unsigned int cmMakefile::GetCacheMinorVersion() { - if(!cmCacheManager::GetInstance()-> - GetCacheValue("Cmake_Cache_MINOR_VERSION")) + if(!this->m_CacheManager->GetCacheValue("Cmake_Cache_MINOR_VERSION")) { return 0; } - return atoi(cmCacheManager::GetInstance()-> - GetCacheValue("CMAKE_CACHE_MINOR_VERSION")); + return atoi(this->m_CacheManager->GetCacheValue("CMAKE_CACHE_MINOR_VERSION")); } @@ -464,10 +462,10 @@ void cmMakefile::AddCustomCommand(const char* source, m_Targets[target].GetCustomCommands().push_back(cc); std::string cacheCommand = command; this->ExpandVariablesInString(cacheCommand); - if(cmCacheManager::GetInstance()->GetCacheValue(cacheCommand.c_str())) + if(this->m_CacheManager->GetCacheValue(cacheCommand.c_str())) { m_Targets[target].AddUtility( - cmCacheManager::GetInstance()->GetCacheValue(cacheCommand.c_str())); + this->m_CacheManager->GetCacheValue(cacheCommand.c_str())); } } } @@ -598,7 +596,7 @@ void cmMakefile::AddCacheDefinition(const char* name, const char* value, const char* doc, cmCacheManager::CacheEntryType type) { - cmCacheManager::GetInstance()->AddCacheEntry(name, value, doc, type); + this->m_CacheManager->AddCacheEntry(name, value, doc, type); this->AddDefinition(name, value); } @@ -620,7 +618,7 @@ void cmMakefile::AddDefinition(const char* name, bool value) void cmMakefile::AddCacheDefinition(const char* name, bool value, const char* doc) { - cmCacheManager::GetInstance()->AddCacheEntry(name, value, doc); + this->m_CacheManager->AddCacheEntry(name, value, doc); this->AddDefinition(name, value); } @@ -673,7 +671,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared, // hence useless. std::string depname = lname; depname += "_LIB_DEPENDS"; - cmCacheManager::GetInstance()-> + this->m_CacheManager-> AddCacheEntry(depname.c_str(), "", "Dependencies for target", cmCacheManager::STATIC); @@ -686,7 +684,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared, // Add an entry into the cache std::string libPath = lname; libPath += "_CMAKE_PATH"; - cmCacheManager::GetInstance()-> + this->m_CacheManager-> AddCacheEntry(libPath.c_str(), this->GetCurrentOutputDirectory(), "Path to a library", cmCacheManager::INTERNAL); @@ -697,28 +695,26 @@ void cmMakefile::AddLibrary(const char* lname, int shared, switch (shared) { case 0: - cmCacheManager::GetInstance()-> - AddCacheEntry(ltname.c_str(), - "STATIC", + this->m_CacheManager->AddCacheEntry(ltname.c_str(),"STATIC", "Whether a library is static, shared or module.", cmCacheManager::INTERNAL); break; case 1: - cmCacheManager::GetInstance()-> + this->m_CacheManager-> AddCacheEntry(ltname.c_str(), "SHARED", "Whether a library is static, shared or module.", cmCacheManager::INTERNAL); break; case 2: - cmCacheManager::GetInstance()-> + this->m_CacheManager-> AddCacheEntry(ltname.c_str(), "MODULE", "Whether a library is static, shared or module.", cmCacheManager::INTERNAL); break; default: - cmCacheManager::GetInstance()-> + this->m_CacheManager-> AddCacheEntry(ltname.c_str(), "STATIC", "Whether a library is static, shared or module.", @@ -755,7 +751,7 @@ void cmMakefile::AddExecutable(const char *exeName, // Add an entry into the cache std::string exePath = exeName; exePath += "_CMAKE_PATH"; - cmCacheManager::GetInstance()-> + this->m_CacheManager-> AddCacheEntry(exePath.c_str(), this->GetCurrentOutputDirectory(), "Path to an executable", cmCacheManager::INTERNAL); @@ -908,7 +904,7 @@ const char* cmMakefile::GetDefinition(const char* name) const { return (*pos).second.c_str(); } - return cmCacheManager::GetInstance()->GetCacheValue(name); + return this->m_CacheManager->GetCacheValue(name); } int cmMakefile::DumpDocumentationToFile(std::ostream& f) @@ -1157,6 +1153,7 @@ cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector& makefiles) { 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()); @@ -1436,3 +1433,64 @@ void cmMakefile::ExpandSourceListArguments( } cmSystemTools::ExpandListArguments(tmpArgs, newargs); } + +int cmMakefile::TryCompile(const char *srcdir, const char *bindir, + const char *projectName) +{ + if (!m_MakefileGenerator) + { + cmSystemTools::Error("Internal CMake error, Attempt to call Try Compile without the generator being set"); + return 1; + } + + // does the binary directory exist ? If not create it... + if (!cmSystemTools::FileIsDirectory(bindir)) + { + cmSystemTools::MakeDirectory(bindir); + } + + // change to the tests directory and run cmake + // use the cmake object instead of calling cmake + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + cmSystemTools::ChangeDirectory(bindir); + + std::vector 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); + + std::string generator = "-G"; + generator += this->GetDefinition("CMAKE_GENERATOR"); + args.push_back(generator); + + cmake cm; + if (cm.Generate(args) != 0) + { + cmSystemTools::Error( + "Internal CMake error, TryCompile execution of cmake failed"); + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + + cmake cm2; + if (cm2.Generate(args) != 0) + { + cmSystemTools::Error( + "Internal CMake error, TryCompile execution 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()); + + return 0; +} + diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 7040fcaa6..4b3bbe3b4 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -52,8 +52,8 @@ public: * was used to write the currently loaded cache, note * this method will not work before the cache is loaded. */ - static unsigned int GetCacheMajorVersion(); - static unsigned int GetCacheMinorVersion(); + unsigned int GetCacheMajorVersion(); + unsigned int GetCacheMinorVersion(); /** * Construct an empty makefile. @@ -84,6 +84,13 @@ public: { m_FunctionBlockers.remove(fb);} void RemoveFunctionBlocker(const char *name, const std::vector &args); + /** + * Try running cmake and building a file. This is used for dynalically + * loaded commands, not as part of the usual build process. + */ + int TryCompile(const char *srcdir, const char *bindir, + const char *projectName); + /** * Specify the makefile generator. This is platform/compiler * dependent, although the interface is through a generic @@ -508,7 +515,18 @@ public: ///! Enable support for the named language, if null then all languages are enabled. void EnableLanguage(const char* ); + /** + * 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; } + protected: + cmCacheManager *m_CacheManager; + // add link libraries and directories to the target void AddGlobalLinkInformation(const char* name, cmTarget& target); diff --git a/Source/cmMakefileGenerator.cxx b/Source/cmMakefileGenerator.cxx index ef0c819d6..5718e99ae 100644 --- a/Source/cmMakefileGenerator.cxx +++ b/Source/cmMakefileGenerator.cxx @@ -17,8 +17,6 @@ #include "cmMakefileGenerator.h" // static list of registered generators -std::map -cmMakefileGenerator::s_RegisteredGenerators; std::map cmMakefileGenerator::s_LanguageEnabled; @@ -27,60 +25,6 @@ void cmMakefileGenerator::SetMakefile(cmMakefile* mf) m_Makefile = mf; } -void cmMakefileGenerator::UnRegisterGenerators() -{ - for(std::map::iterator i - = s_RegisteredGenerators.begin(); - i != s_RegisteredGenerators.end(); ++i) - { - delete i->second; - } - s_RegisteredGenerators = std::map(); -} - -void cmMakefileGenerator::GetRegisteredGenerators(std::vector& names) -{ - for(std::map::iterator i - = s_RegisteredGenerators.begin(); - i != s_RegisteredGenerators.end(); ++i) - { - names.push_back(i->first); - } -} - - -void -cmMakefileGenerator::RegisterGenerator(cmMakefileGenerator* mg) -{ - std::map::iterator i = - s_RegisteredGenerators.find(mg->GetName()); - // delete re-registered objects - if(i != s_RegisteredGenerators.end()) - { - delete i->second; - } - s_RegisteredGenerators[mg->GetName()] = mg; -} - - -cmMakefileGenerator* -cmMakefileGenerator::CreateGenerator(const char* name) -{ - std::map::iterator i; - for(i = s_RegisteredGenerators.begin(); - i != s_RegisteredGenerators.end(); ++i) - { - cmMakefileGenerator* gen = i->second; - if(strcmp(name, gen->GetName()) == 0) - { - return gen->CreateObject(); - } - } - return 0; -} - - - void cmMakefileGenerator::SetLanguageEnabled(const char* l) { s_LanguageEnabled[l] = true; diff --git a/Source/cmMakefileGenerator.h b/Source/cmMakefileGenerator.h index e00e86f6d..84a806cfb 100644 --- a/Source/cmMakefileGenerator.h +++ b/Source/cmMakefileGenerator.h @@ -31,15 +31,13 @@ class cmClassFile; class cmMakefileGenerator { public: - ///! Create a named generator - static cmMakefileGenerator* CreateGenerator(const char* name); - ///! Register a generator - static void RegisterGenerator(cmMakefileGenerator*); - ///! delete all registered generators, useful for clean up - static void UnRegisterGenerators(); - ///! Get the names of the current registered generators - static void GetRegisteredGenerators(std::vector& names); - + /** + * Try running cmake and building a file. This is used for dynalically + * loaded commands, not as part of the usual build process. + */ + virtual int TryCompile(const char *srcdir, const char *bindir, + const char *projectName) = 0; + ///! Get the name for the generator. virtual const char* GetName() = 0; @@ -82,7 +80,6 @@ public: protected: cmMakefile* m_Makefile; private: - static std::map s_RegisteredGenerators; static std::map s_LanguageEnabled; }; diff --git a/Source/cmNMakeMakefileGenerator.cxx b/Source/cmNMakeMakefileGenerator.cxx index 0be634b48..09c044b03 100644 --- a/Source/cmNMakeMakefileGenerator.cxx +++ b/Source/cmNMakeMakefileGenerator.cxx @@ -738,4 +738,3 @@ std::string cmNMakeMakefileGenerator::LowerCasePath(const char* path) { return cmSystemTools::LowerCase(path); } - diff --git a/Source/cmNMakeMakefileGenerator.h b/Source/cmNMakeMakefileGenerator.h index 29d6715cb..633d86daf 100644 --- a/Source/cmNMakeMakefileGenerator.h +++ b/Source/cmNMakeMakefileGenerator.h @@ -42,6 +42,7 @@ public: ///! figure out about the current system information virtual void EnableLanguage(const char*); + protected: std::string ShortPath(const char* path); std::string ShortPathCommand(const char* command); diff --git a/Source/cmUnixMakefileGenerator.cxx b/Source/cmUnixMakefileGenerator.cxx index 915493b09..6bd0cb973 100644 --- a/Source/cmUnixMakefileGenerator.cxx +++ b/Source/cmUnixMakefileGenerator.cxx @@ -2202,3 +2202,40 @@ void cmUnixMakefileGenerator::EnableLanguage(const char* lang) m_Makefile->AddDefinition("RUN_CONFIGURE", true); } } + +int cmUnixMakefileGenerator::TryCompile(const char *srcdir, + const char *bindir, + const char *) +{ + // now build the test + std::string makeCommand = m_Makefile->GetDefinition("CMAKE_MAKE_PROGRAM"); + if(makeCommand.size() == 0) + { + cmSystemTools::Error( + "Generator cannot find the appropriate make command."); + return 1; + } + makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str()); + + /** + * Run an executable command and put the stdout in output. + */ + std::string output; + + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + cmSystemTools::ChangeDirectory(bindir); + + // now build + makeCommand += " all"; + + if (!cmSystemTools::RunCommand(makeCommand.c_str(), output)) + { + cmSystemTools::Error("Generator: execution of make failed."); + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 0; +} + diff --git a/Source/cmUnixMakefileGenerator.h b/Source/cmUnixMakefileGenerator.h index d3a79394d..c93b3632c 100644 --- a/Source/cmUnixMakefileGenerator.h +++ b/Source/cmUnixMakefileGenerator.h @@ -172,6 +172,14 @@ protected: return std::string(path); } + /** + * Try running cmake and building a file. This is used for dynalically + * loaded commands, not as part of the usual build process. For the + * generator, it can assume that cmake has been run on the srcdir/bindir + * and it just needs to be compiled. + */ + virtual int TryCompile(const char *srcdir, const char *bindir, + const char *projectName); protected: std::string m_ExecutableOutputPath; diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 6d89c0d44..6ac0b77fd 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -47,7 +47,7 @@ void cmVariableRequiresCommand::FinalPass() requirementsMet = false; notSet += m_Arguments[i]; notSet += "\n"; - if(cmCacheManager::GetInstance()->IsAdvanced(m_Arguments[i].c_str())) + if(m_Makefile->GetCacheManager()->IsAdvanced(m_Arguments[i].c_str())) { hasAdvanced = true; } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 72d44655f..1772835a8 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -32,17 +32,24 @@ cmake::cmake() { m_Verbose = false; #if defined(_WIN32) && !defined(__CYGWIN__) - cmMakefileGenerator::RegisterGenerator(new cmMSProjectGenerator); - cmMakefileGenerator::RegisterGenerator(new cmMSDotNETGenerator); - cmMakefileGenerator::RegisterGenerator(new cmNMakeMakefileGenerator); - cmMakefileGenerator::RegisterGenerator(new cmBorlandMakefileGenerator); + this->RegisterGenerator(new cmMSProjectGenerator); + this->RegisterGenerator(new cmMSDotNETGenerator); + this->RegisterGenerator(new cmNMakeMakefileGenerator); + this->RegisterGenerator(new cmBorlandMakefileGenerator); #else - cmMakefileGenerator::RegisterGenerator(new cmUnixMakefileGenerator); + this->RegisterGenerator(new cmUnixMakefileGenerator); #endif } cmake::~cmake() { + for(std::map::iterator i + = m_RegisteredGenerators.begin(); + i != m_RegisteredGenerators.end(); ++i) + { + delete i->second; + } + m_RegisteredGenerators = std::map(); } @@ -60,7 +67,7 @@ void cmake::Usage(const char* program) errorStream << "\n-Cpath_to_initial_cache (a cmake list file that is used to pre-load the cache with values.)\n"; errorStream << "\n[-GgeneratorName] (where generator name can be one of these: "; std::vector names; - cmMakefileGenerator::GetRegisteredGenerators(names); + this->GetRegisteredGenerators(names); for(std::vector::iterator i =names.begin(); i != names.end(); ++i) { @@ -85,7 +92,7 @@ void cmake::SetCacheArgs(cmMakefile& builder, cmCacheManager::CacheEntryType type; if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type)) { - cmCacheManager::GetInstance()->AddCacheEntry( + this->m_CacheManager.AddCacheEntry( var.c_str(), value.c_str(), "No help, variable specified on the command line.", @@ -183,7 +190,7 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector& args) { std::string value = arg.substr(2); cmMakefileGenerator* gen = - cmMakefileGenerator::CreateGenerator(value.c_str()); + this->CreateGenerator(value.c_str()); if(!gen) { cmSystemTools::Error("Could not create named generator ", @@ -272,7 +279,7 @@ int cmake::AddCMakePaths(const std::vector& args) return 0; } // Save the value in the cache - cmCacheManager::GetInstance()->AddCacheEntry + this->m_CacheManager.AddCacheEntry ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.", cmCacheManager::INTERNAL); @@ -286,7 +293,7 @@ int cmake::AddCMakePaths(const std::vector& args) } if(cmSystemTools::FileExists(editCacheCommand.c_str())) { - cmCacheManager::GetInstance()->AddCacheEntry + this->m_CacheManager.AddCacheEntry ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(), "Path to cache edit program executable.", cmCacheManager::INTERNAL); } @@ -356,7 +363,7 @@ int cmake::AddCMakePaths(const std::vector& args) modules.c_str()); return 0; } - cmCacheManager::GetInstance()->AddCacheEntry + this->m_CacheManager.AddCacheEntry ("CMAKE_ROOT", cMakeRoot.c_str(), "Path to CMake installation.", cmCacheManager::INTERNAL); return 1; @@ -386,11 +393,13 @@ int cmake::Generate(const std::vector& args, bool buildMakefiles) } // 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(); - cmCacheManager::GetInstance()->LoadCache(&mf); + this->m_CacheManager.LoadCache(&mf); if(mf.GetDefinition("CMAKE_HOME_DIRECTORY")) { std::string cacheStart = mf.GetDefinition("CMAKE_HOME_DIRECTORY"); @@ -422,7 +431,7 @@ int cmake::Generate(const std::vector& args, bool buildMakefiles) const char* genName = mf.GetDefinition("CMAKE_GENERATOR"); if(genName) { - gen = cmMakefileGenerator::CreateGenerator(genName); + gen = this->CreateGenerator(genName); } else { @@ -510,24 +519,24 @@ int cmake::Generate(const std::vector& args, bool buildMakefiles) // so users can edit the values in the cache: // LIBRARY_OUTPUT_PATH // EXECUTABLE_OUTPUT_PATH - if(!cmCacheManager::GetInstance()->GetCacheValue("LIBRARY_OUTPUT_PATH")) + if(!this->m_CacheManager.GetCacheValue("LIBRARY_OUTPUT_PATH")) { - cmCacheManager::GetInstance()->AddCacheEntry("LIBRARY_OUTPUT_PATH", "", + this->m_CacheManager.AddCacheEntry("LIBRARY_OUTPUT_PATH", "", "Single output directory for building all libraries.", cmCacheManager::PATH); } - if(!cmCacheManager::GetInstance()->GetCacheValue("EXECUTABLE_OUTPUT_PATH")) + if(!this->m_CacheManager.GetCacheValue("EXECUTABLE_OUTPUT_PATH")) { - cmCacheManager::GetInstance()->AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "", + this->m_CacheManager.AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "", "Single output directory for building all executables.", cmCacheManager::PATH); } - cmCacheManager::GetInstance()->SaveCache(&mf); + this->m_CacheManager.SaveCache(&mf); if(m_Verbose) { - cmCacheManager::GetInstance()->PrintCache(std::cout); + this->m_CacheManager.PrintCache(std::cout); } if(cmSystemTools::GetErrorOccuredFlag()) @@ -666,3 +675,42 @@ int cmake::CMakeCommand(std::vector& args) ::CMakeCommandUsage(args[0].c_str()); return 1; } + +void cmake::GetRegisteredGenerators(std::vector& names) +{ + for(std::map::iterator i + = this->m_RegisteredGenerators.begin(); + i != this->m_RegisteredGenerators.end(); ++i) + { + names.push_back(i->first); + } +} + + +void cmake::RegisterGenerator(cmMakefileGenerator* mg) +{ + std::map::iterator i = + this->m_RegisteredGenerators.find(mg->GetName()); + // delete re-registered objects + if(i != this->m_RegisteredGenerators.end()) + { + delete i->second; + } + this->m_RegisteredGenerators[mg->GetName()] = mg; +} + +cmMakefileGenerator* cmake::CreateGenerator(const char* name) +{ + std::map::iterator i; + for(i = this->m_RegisteredGenerators.begin(); + i != this->m_RegisteredGenerators.end(); ++i) + { + cmMakefileGenerator* gen = i->second; + if(strcmp(name, gen->GetName()) == 0) + { + return gen->CreateObject(); + } + } + return 0; +} + diff --git a/Source/cmake.h b/Source/cmake.h index 9213759a1..906379485 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -14,7 +14,9 @@ PURPOSE. See the above copyright notices for more information. =========================================================================*/ - +// This class represents a cmake invocation. It is the top level class when +// running cmake. Most cmake based GUIS should primarily create an instance +// of this class and communicate with it. #include "cmMakefile.h" #include "cmStandardIncludes.h" @@ -62,6 +64,21 @@ class cmake */ cmake(); ~cmake(); + + ///! 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& names); + + ///! get the cmCachemManager used by this invocation of cmake + cmCacheManager *GetCacheManager() { + return &m_CacheManager; } + +protected: + std::map m_RegisteredGenerators; + cmCacheManager m_CacheManager; private: bool m_Verbose; bool m_Local; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 696624c4c..e5ad54bd8 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -52,13 +52,9 @@ int main(int ac, char** av) { cmakewizard wizard; wizard.RunWizard(args); - cmMakefileGenerator::UnRegisterGenerators(); - cmCacheManager::DeleteInstance(); return 0; } cmake cm; int ret = cm.Generate(args); - cmMakefileGenerator::UnRegisterGenerators(); - cmCacheManager::DeleteInstance(); return ret; } diff --git a/Source/cmakewizard.cxx b/Source/cmakewizard.cxx index 0b759c48a..2880a85b1 100644 --- a/Source/cmakewizard.cxx +++ b/Source/cmakewizard.cxx @@ -24,7 +24,8 @@ cmakewizard::cmakewizard() } -void cmakewizard::AskUser(const char* key, cmCacheManager::CacheEntry & entry) +void cmakewizard::AskUser(const char* key, cmCacheManager::CacheEntry & entry, + cmCacheManager *cacheManager) { std::cout << "Variable Name: " << key << "\n"; std::cout << "Description: " << entry.m_HelpString << "\n"; @@ -35,8 +36,7 @@ void cmakewizard::AskUser(const char* key, cmCacheManager::CacheEntry & entry) std::cin.getline(buffer, sizeof(buffer)); if(buffer[0]) { - cmCacheManager::CacheEntry *entry = - cmCacheManager::GetInstance()->GetCacheEntry(key); + cmCacheManager::CacheEntry *entry = cacheManager->GetCacheEntry(key); if(entry) { entry->m_Value = buffer; @@ -101,7 +101,7 @@ void cmakewizard::RunWizard(std::vector const& args) make.Generate(args); this->ShowMessage("\n"); // load the cache from disk - cmCacheManager *cachem = cmCacheManager::GetInstance(); + cmCacheManager *cachem = make.GetCacheManager(); cachem-> LoadCache(cmSystemTools::GetCurrentWorkingDirectory().c_str()); cmCacheManager::CacheIterator i = cachem->NewIterator(); @@ -120,25 +120,24 @@ void cmakewizard::RunWizard(std::vector const& args) cmCacheManager::CacheEntry& e = askedCache.find(key)->second; if(e.m_Value != ce.m_Value) { - if(m_ShowAdvanced || !cmCacheManager::GetInstance()->IsAdvanced(key.c_str())) + if(m_ShowAdvanced || !cachem->IsAdvanced(key.c_str())) { - this->AskUser(key.c_str(), ce); + this->AskUser(key.c_str(), ce, cachem); asked = true; } } } else { - if(m_ShowAdvanced || !cmCacheManager::GetInstance()->IsAdvanced(key.c_str())) + if(m_ShowAdvanced || !cachem->IsAdvanced(key.c_str())) { - this->AskUser(key.c_str(), ce); + this->AskUser(key.c_str(), ce, cachem); asked = true; } } askedCache[key] = i.GetEntry(); } - cmCacheManager::GetInstance()-> - SaveCache(cmSystemTools::GetCurrentWorkingDirectory().c_str()); + cachem->SaveCache(cmSystemTools::GetCurrentWorkingDirectory().c_str()); } while(asked); this->ShowMessage("CMake complete, run make to build project.\n"); diff --git a/Source/cmakewizard.h b/Source/cmakewizard.h index 7bc497fe6..b8d21bca8 100644 --- a/Source/cmakewizard.h +++ b/Source/cmakewizard.h @@ -31,7 +31,8 @@ public: /** * Prompt the User for a new value for key, the answer is put in entry. */ - virtual void AskUser(const char* key, cmCacheManager::CacheEntry & entry); + virtual void AskUser(const char* key, cmCacheManager::CacheEntry & entry, + cmCacheManager *cm); ///! Show a message to wait for cmake to run. virtual void ShowMessage(const char*);