diff options
Diffstat (limited to 'Source')
203 files changed, 4330 insertions, 4249 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 6f12785..6d012fd 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -233,8 +233,6 @@ set(SRCS cmExtraKateGenerator.h cmExtraSublimeTextGenerator.cxx cmExtraSublimeTextGenerator.h - cmExtraQbsGenerator.cxx - cmExtraQbsGenerator.h cmFileLock.cxx cmFileLock.h cmFileLockPool.cxx @@ -283,6 +281,7 @@ set(SRCS cmInstallTargetGenerator.cxx cmInstallDirectoryGenerator.h cmInstallDirectoryGenerator.cxx + cmLinkedTree.h cmListFileCache.cxx cmListFileCache.h cmListFileLexer.c @@ -301,6 +300,8 @@ set(SRCS cmMakefileUtilityTargetGenerator.cxx cmOSXBundleGenerator.cxx cmOSXBundleGenerator.h + cmOutputConverter.cxx + cmOutputConverter.h cmNewLineStyle.h cmNewLineStyle.cxx cmOrderDirectories.cxx @@ -349,6 +350,8 @@ set(SRCS cmXMLParser.h cmXMLSafe.cxx cmXMLSafe.h + cmXMLWriter.cxx + cmXMLWriter.h cmake.cxx cmake.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 060aedd..67be073 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) -set(CMake_VERSION_MINOR 2) -set(CMake_VERSION_PATCH 20150519) +set(CMake_VERSION_MINOR 3) +set(CMake_VERSION_PATCH 20150609) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 0137374..5049a3f 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -283,8 +283,6 @@ int cmCPackDebGenerator::PackageFiles() int cmCPackDebGenerator::createDeb() { - const char* cmakeExecutable = this->GetOption("CMAKE_COMMAND"); - // debian-binary file std::string dbfilename; dbfilename += this->GetOption("GEN_WDIR"); @@ -420,15 +418,15 @@ int cmCPackDebGenerator::createDeb() } else if(!strcmp(debian_compression_type, "bzip2")) { compression_suffix = ".bz2"; compression_modifier = "j"; - cmake_tar += "\"" + std::string(cmakeExecutable) + "\" -E "; + cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E "; } else if(!strcmp(debian_compression_type, "gzip")) { compression_suffix = ".gz"; compression_modifier = "z"; - cmake_tar += "\"" + std::string(cmakeExecutable) + "\" -E "; + cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E "; } else if(!strcmp(debian_compression_type, "none")) { compression_suffix = ""; compression_modifier = ""; - cmake_tar += "\"" + std::string(cmakeExecutable) + "\" -E "; + cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E "; } else { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error unrecognized compression type: " @@ -501,7 +499,7 @@ int cmCPackDebGenerator::createDeb() fileIt != packageFiles.end(); ++ fileIt ) { cmd = "\""; - cmd += cmakeExecutable; + cmd += cmSystemTools::GetCMakeCommand(); cmd += "\" -E md5sum \""; cmd += *fileIt; cmd += "\""; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index e254e9a..bf4df60 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -711,11 +711,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( } cmake cm; + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); cm.AddCMakePaths(); cm.SetProgressCallback(cmCPackGeneratorProgress, this); - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); + cmGlobalGenerator gg(&cm); + cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); std::string realInstallDirectory = tempInstallDirectory; if ( !installSubDirectory.empty() && installSubDirectory != "/" ) diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 2207873..c2fe763 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -198,10 +198,11 @@ int main (int argc, char const* const* argv) "Read CPack config file: " << cpackConfigFile << std::endl); cmake cminst; + cminst.SetHomeDirectory(""); + cminst.SetHomeOutputDirectory(""); cminst.GetState()->RemoveUnscriptableCommands(); - cmGlobalGenerator cmgg; - cmgg.SetCMakeInstance(&cminst); - cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator()); + cmGlobalGenerator cmgg(&cminst); + cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.MakeLocalGenerator()); cmMakefile* globalMF = cmlg->GetMakefile(); #if defined(__CYGWIN__) globalMF->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0"); diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 586070b..20d303d 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -204,6 +204,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) } cmake cm; + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); std::string cmakeOutString; cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString); static_cast<void>(captureRAII); diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 29e07ef..e141b60 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -18,7 +18,7 @@ #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" #include "cmGeneratedFileStream.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include "cmFileTimeComparison.h" #include "cmAlgorithms.h" @@ -68,13 +68,13 @@ static const char* cmCTestErrorMatches[] = { "^CMake Error.*:", ":[ \\t]cannot find", ":[ \\t]can't find", - ": \\*\\*\\* No rule to make target \\[`'].*\\'. Stop", + ": \\*\\*\\* No rule to make target [`'].*\\'. Stop", ": \\*\\*\\* No targets specified and no makefile found", ": Invalid loader fixup for symbol", ": Invalid fixups exist", ": Can't find library for", ": internal link edit command failed", - ": Unrecognized option \\[`'].*\\'", + ": Unrecognized option [`'].*\\'", "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([^WI]\\)", "ld: 0706-006 Cannot find or open library file: -l ", "ild: \\(argument error\\) can't find library argument ::", @@ -523,16 +523,17 @@ int cmCTestBuildHandler::ProcessHandler() << std::endl); return -1; } - this->GenerateXMLHeader(xofs); + cmXMLWriter xml(xofs); + this->GenerateXMLHeader(xml); if(this->UseCTestLaunch) { - this->GenerateXMLLaunched(xofs); + this->GenerateXMLLaunched(xml); } else { - this->GenerateXMLLogScraped(xofs); + this->GenerateXMLLogScraped(xml); } - this->GenerateXMLFooter(xofs, elapsed_build_time); + this->GenerateXMLFooter(xml, elapsed_build_time); if (res != cmsysProcess_State_Exited || retVal || this->TotalErrors > 0) { @@ -552,17 +553,14 @@ int cmCTestBuildHandler::ProcessHandler() } //---------------------------------------------------------------------------- -void cmCTestBuildHandler::GenerateXMLHeader(std::ostream& os) +void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml) { - this->CTest->StartXML(os, this->AppendXML); - os << "<Build>\n" - << "\t<StartDateTime>" << this->StartBuild << "</StartDateTime>\n" - << "\t<StartBuildTime>" << - static_cast<unsigned int>(this->StartBuildTime) - << "</StartBuildTime>\n" - << "<BuildCommand>" - << cmXMLSafe(this->GetMakeCommand()) - << "</BuildCommand>" << std::endl; + this->CTest->StartXML(xml, this->AppendXML); + xml.StartElement("Build"); + xml.Element("StartDateTime", this->StartBuild); + xml.Element("StartBuildTime", + static_cast<unsigned int>(this->StartBuildTime)); + xml.Element("BuildCommand", this->GetMakeCommand()); } //---------------------------------------------------------------------------- @@ -591,7 +589,7 @@ private: }; //---------------------------------------------------------------------------- -void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os) +void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml) { if(this->CTestLaunchDir.empty()) { @@ -632,12 +630,12 @@ void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os) for(Fragments::const_iterator fi = fragments.begin(); fi != fragments.end(); ++fi) { - this->GenerateXMLLaunchedFragment(os, fi->c_str()); + xml.FragmentFile(fi->c_str()); } } //---------------------------------------------------------------------------- -void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os) +void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml) { std::vector<cmCTestBuildErrorWarning>& ew = this->ErrorsAndWarnings; std::vector<cmCTestBuildErrorWarning>::iterator it; @@ -665,10 +663,9 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os) { numWarningsAllowed--; } - os << "\t<" << (cm->Error ? "Error" : "Warning") << ">\n" - << "\t\t<BuildLogLine>" << cm->LogLine << "</BuildLogLine>\n" - << "\t\t<Text>" << cmXMLSafe(cm->Text).Quotes(false) - << "\n</Text>" << std::endl; + xml.StartElement(cm->Error ? "Error" : "Warning"); + xml.Element("BuildLogLine", cm->LogLine); + xml.Element("Text", cm->Text); std::vector<cmCTestCompileErrorWarningRex>::iterator rit; for ( rit = this->ErrorWarningFileLineRegex.begin(); rit != this->ErrorWarningFileLineRegex.end(); ++ rit ) @@ -706,62 +703,48 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os) { if (!cm->SourceFile.empty()) { - os << "\t\t<SourceFile>" << cm->SourceFile << "</SourceFile>" - << std::endl; + xml.Element("SourceFile", cm->SourceFile); } if (!cm->SourceFileTail.empty()) { - os << "\t\t<SourceFileTail>" << cm->SourceFileTail - << "</SourceFileTail>" << std::endl; + xml.Element("SourceFileTail", cm->SourceFileTail); } if ( cm->LineNumber >= 0 ) { - os << "\t\t<SourceLineNumber>" << cm->LineNumber - << "</SourceLineNumber>" << std::endl; + xml.Element("SourceLineNumber", cm->LineNumber); } } - os << "\t\t<PreContext>" << cmXMLSafe(cm->PreContext).Quotes(false) - << "</PreContext>\n" - << "\t\t<PostContext>" << cmXMLSafe(cm->PostContext).Quotes(false); + xml.Element("PreContext", cm->PreContext); + xml.StartElement("PostContext"); + xml.Content(cm->PostContext); // is this the last warning or error, if so notify if ((cm->Error && !numErrorsAllowed) || (!cm->Error && !numWarningsAllowed)) { - os << "\nThe maximum number of reported warnings or errors has been " - "reached!!!\n"; + xml.Content("\nThe maximum number of reported warnings or errors " + "has been reached!!!\n"); } - os << "</PostContext>\n" - << "\t\t<RepeatCount>0</RepeatCount>\n" - << "</" << (cm->Error ? "Error" : "Warning") << ">\n\n" - << std::endl; + xml.EndElement(); // PostContext + xml.Element("RepeatCount", "0"); + xml.EndElement(); // "Error" / "Warning" } } } //---------------------------------------------------------------------------- -void cmCTestBuildHandler::GenerateXMLFooter(std::ostream& os, +void cmCTestBuildHandler::GenerateXMLFooter(cmXMLWriter& xml, double elapsed_build_time) { - os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n" - << "\t<EndDateTime>" << this->EndBuild << "</EndDateTime>\n" - << "\t<EndBuildTime>" << static_cast<unsigned int>(this->EndBuildTime) - << "</EndBuildTime>\n" - << "<ElapsedMinutes>" << static_cast<int>(elapsed_build_time/6)/10.0 - << "</ElapsedMinutes>" - << "</Build>" << std::endl; - this->CTest->EndXML(os); -} - -//---------------------------------------------------------------------------- -void cmCTestBuildHandler::GenerateXMLLaunchedFragment(std::ostream& os, - const char* fname) -{ - cmsys::ifstream fin(fname, std::ios::in | std::ios::binary); - std::string line; - while(cmSystemTools::GetLineFromStream(fin, line)) - { - os << line << "\n"; - } + xml.StartElement("Log"); + xml.Attribute("Encoding", "base64"); + xml.Attribute("Compression", "bin/gzip"); + xml.EndElement(); // Log + + xml.Element("EndDateTime", this->EndBuild); + xml.Element("EndBuildTime", static_cast<unsigned int>(this->EndBuildTime)); + xml.Element("ElapsedMinutes", static_cast<int>(elapsed_build_time/6)/10.0); + xml.EndElement(); // Build + this->CTest->EndXML(xml); } //---------------------------------------------------------------------------- diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h index d13d5cf..2e9b92a 100644 --- a/Source/CTest/cmCTestBuildHandler.h +++ b/Source/CTest/cmCTestBuildHandler.h @@ -22,6 +22,7 @@ #include <deque> class cmMakefile; +class cmXMLWriter; /** \class cmCTestBuildHandler * \brief A class that handles ctest -S invocations @@ -86,11 +87,10 @@ private: }; // generate the XML output - void GenerateXMLHeader(std::ostream& os); - void GenerateXMLLaunched(std::ostream& os); - void GenerateXMLLogScraped(std::ostream& os); - void GenerateXMLFooter(std::ostream& os, double elapsed_build_time); - void GenerateXMLLaunchedFragment(std::ostream& os, const char* fname); + void GenerateXMLHeader(cmXMLWriter& xml); + void GenerateXMLLaunched(cmXMLWriter& xml); + void GenerateXMLLogScraped(cmXMLWriter& xml); + void GenerateXMLFooter(cmXMLWriter& xml, double elapsed_build_time); bool IsLaunchedErrorFile(const char* fname); bool IsLaunchedWarningFile(const char* fname); diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index ab363d0..0fb3fec 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -13,7 +13,7 @@ #include "cmCTest.h" #include "cmSystemTools.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <cmsys/RegularExpression.hxx> #include <cmsys/FStream.hxx> @@ -266,13 +266,13 @@ void cmCTestCVS::LoadRevisions(std::string const& file, } //---------------------------------------------------------------------------- -void cmCTestCVS::WriteXMLDirectory(std::ostream& xml, +void cmCTestCVS::WriteXMLDirectory(cmXMLWriter& xml, std::string const& path, Directory const& dir) { const char* slash = path.empty()? "":"/"; - xml << "\t<Directory>\n" - << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n"; + xml.StartElement("Directory"); + xml.Element("Name", path); // Lookup the branch checked out in the working tree. std::string branchFlag = this->ComputeBranchFlag(path); @@ -298,11 +298,11 @@ void cmCTestCVS::WriteXMLDirectory(std::ostream& xml, File f(fi->second, &revisions[0], &revisions[1]); this->WriteXMLEntry(xml, path, fi->first, full, f); } - xml << "\t</Directory>\n"; + xml.EndElement(); // Directory } //---------------------------------------------------------------------------- -bool cmCTestCVS::WriteXMLUpdates(std::ostream& xml) +bool cmCTestCVS::WriteXMLUpdates(cmXMLWriter& xml) { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Gathering version information (one . per updated file):\n" diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h index 64e1747..f2c0a73 100644 --- a/Source/CTest/cmCTestCVS.h +++ b/Source/CTest/cmCTestCVS.h @@ -29,7 +29,7 @@ public: private: // Implement cmCTestVC internal API. virtual bool UpdateImpl(); - virtual bool WriteXMLUpdates(std::ostream& xml); + virtual bool WriteXMLUpdates(cmXMLWriter& xml); // Update status for files in each directory. class Directory: public std::map<std::string, PathStatus> {}; @@ -38,7 +38,7 @@ private: std::string ComputeBranchFlag(std::string const& dir); void LoadRevisions(std::string const& file, const char* branchFlag, std::vector<Revision>& revisions); - void WriteXMLDirectory(std::ostream& xml, std::string const& path, + void WriteXMLDirectory(cmXMLWriter& xml, std::string const& path, Directory const& dir); // Parsing helper classes. diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx index 3b444f2..2e8aeb9 100644 --- a/Source/CTest/cmCTestConfigureHandler.cxx +++ b/Source/CTest/cmCTestConfigureHandler.cxx @@ -15,7 +15,7 @@ #include "cmCTest.h" #include "cmGeneratedFileStream.h" #include "cmake.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <cmsys/Process.h> @@ -89,33 +89,22 @@ int cmCTestConfigureHandler::ProcessHandler() if ( os ) { - this->CTest->StartXML(os, this->AppendXML); - os << "<Configure>\n" - << "\t<StartDateTime>" << start_time << "</StartDateTime>" - << std::endl - << "\t<StartConfigureTime>" << start_time_time - << "</StartConfigureTime>\n"; - - if ( res == cmsysProcess_State_Exited && retVal ) - { - os << retVal; - } - os << "<ConfigureCommand>" << cCommand << "</ConfigureCommand>" - << std::endl; + cmXMLWriter xml(os); + this->CTest->StartXML(xml, this->AppendXML); + xml.StartElement("Configure"); + xml.Element("StartDateTime", start_time); + xml.Element("StartConfigureTime", start_time_time); + xml.Element("ConfigureCommand", cCommand); cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); - os << "<Log>" << cmXMLSafe(output) << "</Log>" << std::endl; - std::string end_time = this->CTest->CurrentTime(); - os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n" - << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" - << "\t<EndConfigureTime>" << - static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</EndConfigureTime>\n" - << "<ElapsedMinutes>" - << static_cast<int>( - (cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0 - << "</ElapsedMinutes>" - << "</Configure>" << std::endl; - this->CTest->EndXML(os); + xml.Element("Log", output); + xml.Element("ConfigureStatus", retVal); + xml.Element("EndDateTime", this->CTest->CurrentTime()); + xml.Element("EndConfigureTime", + static_cast<unsigned int>(cmSystemTools::GetTime())); + xml.Element("ElapsedMinutes", static_cast<int>( + (cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0); + xml.EndElement(); // Configure + this->CTest->EndXML(xml); } } else diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 790e488..f92f19a 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -22,7 +22,7 @@ #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmGeneratedFileStream.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <cmsys/Process.h> #include <cmsys/RegularExpression.hxx> @@ -185,14 +185,6 @@ bool cmCTestCoverageHandler::StartCoverageLogFile( << covLogFilename << std::endl); return false; } - std::string local_start_time = this->CTest->CurrentTime(); - this->CTest->StartXML(covLogFile, this->AppendXML); - covLogFile << "<CoverageLog>" << std::endl - << "\t<StartDateTime>" << local_start_time << "</StartDateTime>" - << "\t<StartTime>" - << static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</StartTime>" - << std::endl; return true; } @@ -200,13 +192,6 @@ bool cmCTestCoverageHandler::StartCoverageLogFile( void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount) { - std::string local_end_time = this->CTest->CurrentTime(); - ostr << "\t<EndDateTime>" << local_end_time << "</EndDateTime>" << std::endl - << "\t<EndTime>" << - static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</EndTime>" << std::endl - << "</CoverageLog>" << std::endl; - this->CTest->EndXML(ostr); char covLogFilename[1024]; sprintf(covLogFilename, "CoverageLog-%d.xml", logFileCount); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Close file: " @@ -215,6 +200,25 @@ void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr, } //---------------------------------------------------------------------- +void cmCTestCoverageHandler::StartCoverageLogXML(cmXMLWriter& xml) +{ + this->CTest->StartXML(xml, this->AppendXML); + xml.StartElement("CoverageLog"); + xml.Element("StartDateTime", this->CTest->CurrentTime()); + xml.Element("StartTime", + static_cast<unsigned int>(cmSystemTools::GetTime())); +} + +//---------------------------------------------------------------------- +void cmCTestCoverageHandler::EndCoverageLogXML(cmXMLWriter& xml) +{ + xml.Element("EndDateTime", this->CTest->CurrentTime()); + xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime())); + xml.EndElement(); // CoverageLog + this->CTest->EndXML(xml); +} + +//---------------------------------------------------------------------- bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, const char* srcDir, const char* binDir) @@ -451,6 +455,8 @@ int cmCTestCoverageHandler::ProcessHandler() } cmGeneratedFileStream covSumFile; cmGeneratedFileStream covLogFile; + cmXMLWriter covSumXML(covSumFile); + cmXMLWriter covLogXML(covLogFile); if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile)) { @@ -458,20 +464,21 @@ int cmCTestCoverageHandler::ProcessHandler() "Cannot open coverage summary file." << std::endl); return -1; } + covSumFile.setf(std::ios::fixed, std::ios::floatfield); + covSumFile.precision(2); - this->CTest->StartXML(covSumFile, this->AppendXML); + this->CTest->StartXML(covSumXML, this->AppendXML); // Produce output xml files - covSumFile << "<Coverage>" << std::endl - << "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>" - << std::endl - << "\t<StartTime>" << coverage_start_time_time << "</StartTime>" - << std::endl; + covSumXML.StartElement("Coverage"); + covSumXML.Element("StartDateTime", coverage_start_time); + covSumXML.Element("StartTime", coverage_start_time_time); int logFileCount = 0; if ( !this->StartCoverageLogFile(covLogFile, logFileCount) ) { return -1; } + this->StartCoverageLogXML(covLogXML); cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator fileIterator; int cnt = 0; long total_tested = 0; @@ -528,12 +535,14 @@ int cmCTestCoverageHandler::ProcessHandler() if ( ++cnt % 100 == 0 ) { + this->EndCoverageLogXML(covLogXML); this->EndCoverageLogFile(covLogFile, logFileCount); logFileCount ++; if ( !this->StartCoverageLogFile(covLogFile, logFileCount) ) { return -1; } + this->StartCoverageLogXML(covLogXML); } const std::string fileName @@ -542,9 +551,10 @@ int cmCTestCoverageHandler::ProcessHandler() this->CTest->GetShortPathToFile(fullFileName.c_str()); const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov = fileIterator->second; - covLogFile << "\t<File Name=\"" << cmXMLSafe(fileName) - << "\" FullPath=\"" << cmXMLSafe(shortFileName) << "\">\n" - << "\t\t<Report>" << std::endl; + covLogXML.StartElement("File"); + covLogXML.Attribute("Name", fileName); + covLogXML.Attribute("FullPath", shortFileName); + covLogXML.StartElement("Report"); cmsys::ifstream ifs(fullFileName.c_str()); if ( !ifs) @@ -576,9 +586,11 @@ int cmCTestCoverageHandler::ProcessHandler() error ++; break; } - covLogFile << "\t\t<Line Number=\"" << cc << "\" Count=\"" << fcov[cc] - << "\">" - << cmXMLSafe(line) << "</Line>" << std::endl; + covLogXML.StartElement("Line"); + covLogXML.Attribute("Number", cc); + covLogXML.Attribute("Count", fcov[cc]); + covLogXML.Content(line); + covLogXML.EndElement(); // Line if ( fcov[cc] == 0 ) { untested ++; @@ -605,24 +617,19 @@ int cmCTestCoverageHandler::ProcessHandler() } total_tested += tested; total_untested += untested; - covLogFile << "\t\t</Report>" << std::endl - << "\t</File>" << std::endl; - covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName) - << "\" FullPath=\"" << cmXMLSafe( - this->CTest->GetShortPathToFile(fullFileName.c_str())) - << "\" Covered=\"" << (tested+untested > 0 ? "true":"false") << "\">\n" - << "\t\t<LOCTested>" << tested << "</LOCTested>\n" - << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n" - << "\t\t<PercentCoverage>"; - covSumFile.setf(std::ios::fixed, std::ios::floatfield); - covSumFile.precision(2); - covSumFile << (cper) << "</PercentCoverage>\n" - << "\t\t<CoverageMetric>"; - covSumFile.setf(std::ios::fixed, std::ios::floatfield); - covSumFile.precision(2); - covSumFile << (cmet) << "</CoverageMetric>\n"; - this->WriteXMLLabels(covSumFile, shortFileName); - covSumFile << "\t</File>" << std::endl; + covLogXML.EndElement(); // Report + covLogXML.EndElement(); // File + covSumXML.StartElement("File"); + covSumXML.Attribute("Name", fileName); + covSumXML.Attribute("FullPath", + this->CTest->GetShortPathToFile(fullFileName.c_str())); + covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false"); + covSumXML.Element("LOCTested", tested); + covSumXML.Element("LOCUnTested", untested); + covSumXML.Element("PercentCoverage", cper); + covSumXML.Element("CoverageMetric", cmet); + this->WriteXMLLabels(covSumXML, shortFileName); + covSumXML.EndElement(); // File } //Handle all the files in the extra coverage globs that have no cov data @@ -632,9 +639,10 @@ int cmCTestCoverageHandler::ProcessHandler() std::string fileName = cmSystemTools::GetFilenameName(*i); std::string fullPath = cont.SourceDir + "/" + *i; - covLogFile << "\t<File Name=\"" << cmXMLSafe(fileName) - << "\" FullPath=\"" << cmXMLSafe(*i) << "\">\n" - << "\t\t<Report>" << std::endl; + covLogXML.StartElement("File"); + covLogXML.Attribute("Name", fileName); + covLogXML.Attribute("FullPath", *i); + covLogXML.StartElement("Report"); cmsys::ifstream ifs(fullPath.c_str()); if (!ifs) @@ -651,24 +659,30 @@ int cmCTestCoverageHandler::ProcessHandler() "Actually performing coverage for: " << *i << std::endl, this->Quiet); while (cmSystemTools::GetLineFromStream(ifs, line)) { - covLogFile << "\t\t<Line Number=\"" << untested << "\" Count=\"0\">" - << cmXMLSafe(line) << "</Line>" << std::endl; + covLogXML.StartElement("Line"); + covLogXML.Attribute("Number", untested); + covLogXML.Attribute("Count", 0); + covLogXML.Content(line); + covLogXML.EndElement(); // Line untested ++; } - covLogFile << "\t\t</Report>\n\t</File>" << std::endl; + covLogXML.EndElement(); // Report + covLogXML.EndElement(); // File total_untested += untested; - covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName) - << "\" FullPath=\"" << cmXMLSafe(i->c_str()) - << "\" Covered=\"true\">\n" - << "\t\t<LOCTested>0</LOCTested>\n" - << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n" - << "\t\t<PercentCoverage>0</PercentCoverage>\n" - << "\t\t<CoverageMetric>0</CoverageMetric>\n"; - this->WriteXMLLabels(covSumFile, *i); - covSumFile << "\t</File>" << std::endl; - } - + covSumXML.StartElement("File"); + covSumXML.Attribute("Name", fileName); + covSumXML.Attribute("FullPath", *i); + covSumXML.Attribute("Covered", "true"); + covSumXML.Element("LOCTested", 0); + covSumXML.Element("LOCUnTested", untested); + covSumXML.Element("PercentCoverage", 0); + covSumXML.Element("CoverageMetric", 0); + this->WriteXMLLabels(covSumXML, *i); + covSumXML.EndElement(); // File + } + + this->EndCoverageLogXML(covLogXML); this->EndCoverageLogFile(covLogFile, logFileCount); if (!errorsWhileAccumulating.empty()) @@ -696,22 +710,17 @@ int cmCTestCoverageHandler::ProcessHandler() std::string end_time = this->CTest->CurrentTime(); - covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n" - << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n" - << "\t<LOC>" << total_lines << "</LOC>\n" - << "\t<PercentCoverage>"; - covSumFile.setf(std::ios::fixed, std::ios::floatfield); - covSumFile.precision(2); - covSumFile << (percent_coverage)<< "</PercentCoverage>\n" - << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" - << "\t<EndTime>" << - static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</EndTime>\n"; - covSumFile << "<ElapsedMinutes>" << - static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0 - << "</ElapsedMinutes>" - << "</Coverage>" << std::endl; - this->CTest->EndXML(covSumFile); + covSumXML.Element("LOCTested", total_tested); + covSumXML.Element("LOCUntested", total_untested); + covSumXML.Element("LOC", total_lines); + covSumXML.Element("PercentCoverage", percent_coverage); + covSumXML.Element("EndDateTime", end_time); + covSumXML.Element("EndTime", + static_cast<unsigned int>(cmSystemTools::GetTime())); + covSumXML.Element("ElapsedMinutes", + static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0); + covSumXML.EndElement(); // Coverage + this->CTest->EndXML(covSumXML); cmCTestLog(this->CTest, HANDLER_OUTPUT, "" << std::endl << "\tCovered LOC: " @@ -1952,11 +1961,13 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( } // create the output stream for the CoverageLog-N.xml file cmGeneratedFileStream covLogFile; + cmXMLWriter covLogXML(covLogFile); int logFileCount = 0; if ( !this->StartCoverageLogFile(covLogFile, logFileCount) ) { return -1; } + this->StartCoverageLogXML(covLogXML); // for each file run covbr on that file to get the coverage // information for that file std::string outputFile; @@ -2009,20 +2020,22 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( // if we are in a valid file close it because a new one started if(valid) { - covLogFile << "\t\t</Report>" << std::endl - << "\t</File>" << std::endl; + covLogXML.EndElement(); // Report + covLogXML.EndElement(); // File } // only allow 100 files in each log file if ( count != 0 && count % 100 == 0 ) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "start a new log file: " << count << std::endl, this->Quiet); + this->EndCoverageLogXML(covLogXML); this->EndCoverageLogFile(covLogFile, logFileCount); logFileCount ++; if ( !this->StartCoverageLogFile(covLogFile, logFileCount) ) { return -1; } + this->StartCoverageLogXML(covLogXML); count++; // move on one } std::map<std::string, std::string>::iterator @@ -2036,19 +2049,20 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( "Produce coverage for file: " << file << " " << count << std::endl, this->Quiet); // start the file output - covLogFile << "\t<File Name=\"" - << cmXMLSafe(i->first) - << "\" FullPath=\"" << cmXMLSafe( - this->CTest->GetShortPathToFile( - i->second.c_str())) << "\">" << std::endl - << "\t\t<Report>" << std::endl; + covLogXML.StartElement("File"); + covLogXML.Attribute("Name", i->first); + covLogXML.Attribute("FullPath", + this->CTest->GetShortPathToFile(i->second.c_str())); + covLogXML.StartElement("Report"); // write the bullseye header line =0; for(int k =0; bullseyeHelp[k] != 0; ++k) { - covLogFile << "\t\t<Line Number=\"" << line << "\" Count=\"-1\">" - << cmXMLSafe(bullseyeHelp[k]) - << "</Line>" << std::endl; + covLogXML.StartElement("Line"); + covLogXML.Attribute("Number", line); + covLogXML.Attribute("Count", -1); + covLogXML.Content(bullseyeHelp[k]); + covLogXML.EndElement(); // Line line++; } valid = true; // we are in a valid file section @@ -2062,18 +2076,21 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( // we are not at a start file, and we are in a valid file output the line else if(valid) { - covLogFile << "\t\t<Line Number=\"" << line << "\" Count=\"-1\">" - << cmXMLSafe(lineIn) - << "</Line>" << std::endl; + covLogXML.StartElement("Line"); + covLogXML.Attribute("Number", line); + covLogXML.Attribute("Count", -1); + covLogXML.Content(lineIn); + covLogXML.EndElement(); // Line line++; } } // if we ran out of lines a valid file then close that file if(valid) { - covLogFile << "\t\t</Report>" << std::endl - << "\t</File>" << std::endl; + covLogXML.EndElement(); // Report + covLogXML.EndElement(); // File } + this->EndCoverageLogXML(covLogXML); this->EndCoverageLogFile(covLogFile, logFileCount); return 1; } @@ -2143,23 +2160,20 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( std::ostream& tmpLog = *cont->OFS; // copen the Coverage.xml file in the Testing directory cmGeneratedFileStream covSumFile; + cmXMLWriter xml(covSumFile); if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open coverage summary file." << std::endl); return 0; } - this->CTest->StartXML(covSumFile, this->AppendXML); + this->CTest->StartXML(xml, this->AppendXML); double elapsed_time_start = cmSystemTools::GetTime(); std::string coverage_start_time = this->CTest->CurrentTime(); - covSumFile << "<Coverage>" << std::endl - << "\t<StartDateTime>" - << coverage_start_time << "</StartDateTime>" - << std::endl - << "\t<StartTime>" - << static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</StartTime>" - << std::endl; + xml.StartElement("Coverage"); + xml.Element("StartDateTime", coverage_start_time); + xml.Element("StartTime", + static_cast<unsigned int>(cmSystemTools::GetTime())); std::string stdline; std::string errline; // expected output: @@ -2271,58 +2285,35 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( tmpLog << "percentBranch: " << percentBranch << "\n"; tmpLog << "percentCoverage: " << percent_coverage << "\n"; tmpLog << "coverage metric: " << cmet << "\n"; - covSumFile << "\t<File Name=\"" << cmXMLSafe(sourceFile) - << "\" FullPath=\"" << cmXMLSafe(shortFileName) - << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n" - << "\t\t<BranchesTested>" - << branchCovered - << "</BranchesTested>\n" - << "\t\t<BranchesUnTested>" - << totalBranches - branchCovered - << "</BranchesUnTested>\n" - << "\t\t<FunctionsTested>" - << functionsCalled - << "</FunctionsTested>\n" - << "\t\t<FunctionsUnTested>" - << totalFunctions - functionsCalled - << "</FunctionsUnTested>\n" - // Hack for conversion of function to loc assume a function - // has 100 lines of code - << "\t\t<LOCTested>" << functionsCalled *100 - << "</LOCTested>\n" - << "\t\t<LOCUnTested>" - << (totalFunctions - functionsCalled)*100 - << "</LOCUnTested>\n" - << "\t\t<PercentCoverage>"; - covSumFile.setf(std::ios::fixed, std::ios::floatfield); - covSumFile.precision(2); - covSumFile << (cper) << "</PercentCoverage>\n" - << "\t\t<CoverageMetric>"; - covSumFile.setf(std::ios::fixed, std::ios::floatfield); - covSumFile.precision(2); - covSumFile << (cmet) << "</CoverageMetric>\n"; - this->WriteXMLLabels(covSumFile, shortFileName); - covSumFile << "\t</File>" << std::endl; + xml.StartElement("File"); + xml.Attribute("Name", sourceFile); + xml.Attribute("FullPath", shortFileName); + xml.Attribute("Covered", cmet > 0 ? "true" : "false"); + xml.Element("BranchesTested", branchCovered); + xml.Element("BranchesUnTested", totalBranches - branchCovered); + xml.Element("FunctionsTested", functionsCalled); + xml.Element("FunctionsUnTested", totalFunctions - functionsCalled); + // Hack for conversion of function to loc assume a function + // has 100 lines of code + xml.Element("LOCTested", functionsCalled * 100); + xml.Element("LOCUnTested", (totalFunctions - functionsCalled) * 100); + xml.Element("PercentCoverage", cper); + xml.Element("CoverageMetric", cmet); + this->WriteXMLLabels(xml, shortFileName); + xml.EndElement(); // File } } std::string end_time = this->CTest->CurrentTime(); - covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n" - << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n" - << "\t<LOC>" << total_functions << "</LOC>\n" - << "\t<PercentCoverage>"; - covSumFile.setf(std::ios::fixed, std::ios::floatfield); - covSumFile.precision(2); - covSumFile - << SAFEDIV(percent_coverage,number_files)<< "</PercentCoverage>\n" - << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" - << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</EndTime>\n"; - covSumFile - << "<ElapsedMinutes>" << - static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0 - << "</ElapsedMinutes>" - << "</Coverage>" << std::endl; - this->CTest->EndXML(covSumFile); + xml.Element("LOCTested", total_tested); + xml.Element("LOCUntested", total_untested); + xml.Element("LOC", total_functions); + xml.Element("PercentCoverage", SAFEDIV(percent_coverage, number_files)); + xml.Element("EndDateTime", end_time); + xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime())); + xml.Element("ElapsedMinutes", + static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0); + xml.EndElement(); // Coverage + this->CTest->EndXML(xml); // Now create the coverage information for each file return this->RunBullseyeCoverageBranch(cont, @@ -2514,19 +2505,19 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir) } //---------------------------------------------------------------------- -void cmCTestCoverageHandler::WriteXMLLabels(std::ostream& os, +void cmCTestCoverageHandler::WriteXMLLabels(cmXMLWriter& xml, std::string const& source) { LabelMapType::const_iterator li = this->SourceLabels.find(source); if(li != this->SourceLabels.end() && !li->second.empty()) { - os << "\t\t<Labels>\n"; + xml.StartElement("Labels"); for(LabelSet::const_iterator lsi = li->second.begin(); lsi != li->second.end(); ++lsi) { - os << "\t\t\t<Label>" << cmXMLSafe(this->Labels[*lsi]) << "</Label>\n"; + xml.Element("Label", this->Labels[*lsi]); } - os << "\t\t</Labels>\n"; + xml.EndElement(); // Labels } } diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index 3258ddb..2ca123a 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -20,6 +20,7 @@ #include <cmsys/RegularExpression.hxx> class cmGeneratedFileStream; +class cmXMLWriter; class cmCTestCoverageHandlerContainer { public: @@ -65,6 +66,9 @@ private: bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount); void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount); + void StartCoverageLogXML(cmXMLWriter& xml); + void EndCoverageLogXML(cmXMLWriter& xml); + //! Handle coverage using GCC's GCov int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont); void FindGCovFiles(std::vector<std::string>& files); @@ -146,7 +150,7 @@ private: // Label reading and writing methods. void LoadLabels(); void LoadLabels(const char* dir); - void WriteXMLLabels(std::ostream& os, std::string const& source); + void WriteXMLLabels(cmXMLWriter& xml, std::string const& source); // Label-based filtering. std::set<int> LabelFilter; diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx index 5f570b5..c091ec4 100644 --- a/Source/CTest/cmCTestGlobalVC.cxx +++ b/Source/CTest/cmCTestGlobalVC.cxx @@ -13,7 +13,7 @@ #include "cmCTest.h" #include "cmSystemTools.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <cmsys/RegularExpression.hxx> @@ -91,36 +91,36 @@ void cmCTestGlobalVC::DoModification(PathStatus status, } //---------------------------------------------------------------------------- -void cmCTestGlobalVC::WriteXMLDirectory(std::ostream& xml, +void cmCTestGlobalVC::WriteXMLDirectory(cmXMLWriter& xml, std::string const& path, Directory const& dir) { const char* slash = path.empty()? "":"/"; - xml << "\t<Directory>\n" - << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n"; + xml.StartElement("Directory"); + xml.Element("Name", path); for(Directory::const_iterator fi = dir.begin(); fi != dir.end(); ++fi) { std::string full = path + slash + fi->first; this->WriteXMLEntry(xml, path, fi->first, full, fi->second); } - xml << "\t</Directory>\n"; + xml.EndElement(); // Directory } //---------------------------------------------------------------------------- -void cmCTestGlobalVC::WriteXMLGlobal(std::ostream& xml) +void cmCTestGlobalVC::WriteXMLGlobal(cmXMLWriter& xml) { if(!this->NewRevision.empty()) { - xml << "\t<Revision>" << this->NewRevision << "</Revision>\n"; + xml.Element("Revision", this->NewRevision); } if(!this->OldRevision.empty() && this->OldRevision != this->NewRevision) { - xml << "\t<PriorRevision>" << this->OldRevision << "</PriorRevision>\n"; + xml.Element("PriorRevision", this->OldRevision); } } //---------------------------------------------------------------------------- -bool cmCTestGlobalVC::WriteXMLUpdates(std::ostream& xml) +bool cmCTestGlobalVC::WriteXMLUpdates(cmXMLWriter& xml) { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Gathering version information (one . per revision):\n" diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h index 29e0a61..d0e9410 100644 --- a/Source/CTest/cmCTestGlobalVC.h +++ b/Source/CTest/cmCTestGlobalVC.h @@ -30,7 +30,7 @@ public: protected: // Implement cmCTestVC internal API. - virtual bool WriteXMLUpdates(std::ostream& xml); + virtual bool WriteXMLUpdates(cmXMLWriter& xml); /** Represent a vcs-reported action for one path in a revision. */ struct Change @@ -62,8 +62,8 @@ protected: virtual void LoadModifications() = 0; virtual void LoadRevisions() = 0; - virtual void WriteXMLGlobal(std::ostream& xml); - void WriteXMLDirectory(std::ostream& xml, std::string const& path, + virtual void WriteXMLGlobal(cmXMLWriter& xml); + void WriteXMLDirectory(cmXMLWriter& xml, std::string const& path, Directory const& dir); }; diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index de6ecde..0f588c5 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -13,7 +13,7 @@ #include "cmGeneratedFileStream.h" #include "cmSystemTools.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include "cmake.h" #include <cmsys/MD5.h> @@ -407,35 +407,32 @@ void cmCTestLaunch::WriteXML() // Use cmGeneratedFileStream to atomically create the report file. cmGeneratedFileStream fxml(logXML.c_str()); - fxml << "\t<Failure type=\"" - << (this->IsError()? "Error" : "Warning") << "\">\n"; - this->WriteXMLAction(fxml); - this->WriteXMLCommand(fxml); - this->WriteXMLResult(fxml); - this->WriteXMLLabels(fxml); - fxml << "\t</Failure>\n"; + cmXMLWriter xml(fxml, 2); + xml.StartElement("Failure"); + xml.Attribute("type", this->IsError() ? "Error" : "Warning"); + this->WriteXMLAction(xml); + this->WriteXMLCommand(xml); + this->WriteXMLResult(xml); + this->WriteXMLLabels(xml); + xml.EndElement(); // Failure } //---------------------------------------------------------------------------- -void cmCTestLaunch::WriteXMLAction(std::ostream& fxml) +void cmCTestLaunch::WriteXMLAction(cmXMLWriter& xml) { - fxml << "\t\t<!-- Meta-information about the build action -->\n"; - fxml << "\t\t<Action>\n"; + xml.Comment("Meta-information about the build action"); + xml.StartElement("Action"); // TargetName if(!this->OptionTargetName.empty()) { - fxml << "\t\t\t<TargetName>" - << cmXMLSafe(this->OptionTargetName) - << "</TargetName>\n"; + xml.Element("TargetName", this->OptionTargetName); } // Language if(!this->OptionLanguage.empty()) { - fxml << "\t\t\t<Language>" - << cmXMLSafe(this->OptionLanguage) - << "</Language>\n"; + xml.Element("Language", this->OptionLanguage); } // SourceFile @@ -454,17 +451,13 @@ void cmCTestLaunch::WriteXMLAction(std::ostream& fxml) source.c_str()); } - fxml << "\t\t\t<SourceFile>" - << cmXMLSafe(source) - << "</SourceFile>\n"; + xml.Element("SourceFile", source); } // OutputFile if(!this->OptionOutput.empty()) { - fxml << "\t\t\t<OutputFile>" - << cmXMLSafe(this->OptionOutput) - << "</OutputFile>\n"; + xml.Element("OutputFile", this->OptionOutput); } // OutputType @@ -494,103 +487,94 @@ void cmCTestLaunch::WriteXMLAction(std::ostream& fxml) } if(outputType) { - fxml << "\t\t\t<OutputType>" - << cmXMLSafe(outputType) - << "</OutputType>\n"; + xml.Element("OutputType", outputType); } - fxml << "\t\t</Action>\n"; + xml.EndElement(); // Action } //---------------------------------------------------------------------------- -void cmCTestLaunch::WriteXMLCommand(std::ostream& fxml) +void cmCTestLaunch::WriteXMLCommand(cmXMLWriter& xml) { - fxml << "\n"; - fxml << "\t\t<!-- Details of command -->\n"; - fxml << "\t\t<Command>\n"; + xml.Comment("Details of command"); + xml.StartElement("Command"); if(!this->CWD.empty()) { - fxml << "\t\t\t<WorkingDirectory>" - << cmXMLSafe(this->CWD) - << "</WorkingDirectory>\n"; + xml.Element("WorkingDirectory", this->CWD); } for(std::vector<std::string>::const_iterator ai = this->RealArgs.begin(); ai != this->RealArgs.end(); ++ai) { - fxml << "\t\t\t<Argument>" - << cmXMLSafe(ai->c_str()) - << "</Argument>\n"; + xml.Element("Argument", *ai); } - fxml << "\t\t</Command>\n"; + xml.EndElement(); // Command } //---------------------------------------------------------------------------- -void cmCTestLaunch::WriteXMLResult(std::ostream& fxml) +void cmCTestLaunch::WriteXMLResult(cmXMLWriter& xml) { - fxml << "\n"; - fxml << "\t\t<!-- Result of command -->\n"; - fxml << "\t\t<Result>\n"; + xml.Comment("Result of command"); + xml.StartElement("Result"); // StdOut - fxml << "\t\t\t<StdOut>"; - this->DumpFileToXML(fxml, this->LogOut); - fxml << "</StdOut>\n"; + xml.StartElement("StdOut"); + this->DumpFileToXML(xml, this->LogOut); + xml.EndElement(); // StdOut // StdErr - fxml << "\t\t\t<StdErr>"; - this->DumpFileToXML(fxml, this->LogErr); - fxml << "</StdErr>\n"; + xml.StartElement("StdErr"); + this->DumpFileToXML(xml, this->LogErr); + xml.EndElement(); // StdErr // ExitCondition - fxml << "\t\t\t<ExitCondition>"; + xml.StartElement("ExitCondition"); cmsysProcess* cp = this->Process; switch (cmsysProcess_GetState(cp)) { case cmsysProcess_State_Starting: - fxml << "No process has been executed"; break; + xml.Content("No process has been executed"); break; case cmsysProcess_State_Executing: - fxml << "The process is still executing"; break; + xml.Content("The process is still executing"); break; case cmsysProcess_State_Disowned: - fxml << "Disowned"; break; + xml.Content("Disowned"); break; case cmsysProcess_State_Killed: - fxml << "Killed by parent"; break; + xml.Content("Killed by parent"); break; case cmsysProcess_State_Expired: - fxml << "Killed when timeout expired"; break; + xml.Content("Killed when timeout expired"); break; case cmsysProcess_State_Exited: - fxml << this->ExitCode; break; + xml.Content(this->ExitCode); break; case cmsysProcess_State_Exception: - fxml << "Terminated abnormally: " - << cmXMLSafe(cmsysProcess_GetExceptionString(cp)); break; + xml.Content("Terminated abnormally: "); + xml.Content(cmsysProcess_GetExceptionString(cp)); break; case cmsysProcess_State_Error: - fxml << "Error administrating child process: " - << cmXMLSafe(cmsysProcess_GetErrorString(cp)); break; + xml.Content("Error administrating child process: "); + xml.Content(cmsysProcess_GetErrorString(cp)); break; }; - fxml << "</ExitCondition>\n"; + xml.EndElement(); // ExitCondition - fxml << "\t\t</Result>\n"; + xml.EndElement(); // Result } //---------------------------------------------------------------------------- -void cmCTestLaunch::WriteXMLLabels(std::ostream& fxml) +void cmCTestLaunch::WriteXMLLabels(cmXMLWriter& xml) { this->LoadLabels(); if(!this->Labels.empty()) { - fxml << "\n"; - fxml << "\t\t<!-- Interested parties -->\n"; - fxml << "\t\t<Labels>\n"; + xml.Comment("Interested parties"); + xml.StartElement("Labels"); for(std::set<std::string>::const_iterator li = this->Labels.begin(); li != this->Labels.end(); ++li) { - fxml << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n"; + xml.Element("Label", *li); } - fxml << "\t\t</Labels>\n"; + xml.EndElement(); // Labels } } //---------------------------------------------------------------------------- -void cmCTestLaunch::DumpFileToXML(std::ostream& fxml, +void cmCTestLaunch::DumpFileToXML(cmXMLWriter& xml, std::string const& fname) { cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary); @@ -605,7 +589,8 @@ void cmCTestLaunch::DumpFileToXML(std::ostream& fxml, continue; } - fxml << sep << cmXMLSafe(line).Quotes(false); + xml.Content(sep); + xml.Content(line); sep = "\n"; } } @@ -750,9 +735,10 @@ int cmCTestLaunch::Main(int argc, const char* const argv[]) void cmCTestLaunch::LoadConfig() { cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cmGlobalGenerator gg(&cm); + cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator()); cmMakefile* mf = lg->GetMakefile(); std::string fname = this->LogDir; fname += "CTestLaunchConfig.cmake"; diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h index bc90d28..b13e484 100644 --- a/Source/CTest/cmCTestLaunch.h +++ b/Source/CTest/cmCTestLaunch.h @@ -15,6 +15,8 @@ #include "cmStandardIncludes.h" #include <cmsys/RegularExpression.hxx> +class cmXMLWriter; + /** \class cmCTestLaunch * \brief Launcher for make rules to report results for ctest * @@ -92,11 +94,11 @@ private: // Methods to generate the xml fragment. void WriteXML(); - void WriteXMLAction(std::ostream& fxml); - void WriteXMLCommand(std::ostream& fxml); - void WriteXMLResult(std::ostream& fxml); - void WriteXMLLabels(std::ostream& fxml); - void DumpFileToXML(std::ostream& fxml, std::string const& fname); + void WriteXMLAction(cmXMLWriter& xml); + void WriteXMLCommand(cmXMLWriter& xml); + void WriteXMLResult(cmXMLWriter& xml); + void WriteXMLLabels(cmXMLWriter& xml); + void DumpFileToXML(cmXMLWriter& xml, std::string const& fname); // Configuration void LoadConfig(); diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 061f3fd..8f26716 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -21,7 +21,7 @@ #include <cmsys/Glob.hxx> #include <cmsys/FStream.hxx> #include "cmMakefile.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <stdlib.h> #include <math.h> @@ -352,55 +352,52 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf) } //---------------------------------------------------------------------- -void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) +void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml) { if ( !this->CTest->GetProduceXML() ) { return; } - this->CTest->StartXML(os, this->AppendXML); - os << "<DynamicAnalysis Checker=\""; + this->CTest->StartXML(xml, this->AppendXML); + xml.StartElement("DynamicAnalysis"); switch ( this->MemoryTesterStyle ) { case cmCTestMemCheckHandler::VALGRIND: - os << "Valgrind"; + xml.Attribute("Checker", "Valgrind"); break; case cmCTestMemCheckHandler::PURIFY: - os << "Purify"; + xml.Attribute("Checker", "Purify"); break; case cmCTestMemCheckHandler::BOUNDS_CHECKER: - os << "BoundsChecker"; + xml.Attribute("Checker", "BoundsChecker"); break; case cmCTestMemCheckHandler::ADDRESS_SANITIZER: - os << "AddressSanitizer"; + xml.Attribute("Checker", "AddressSanitizer"); break; case cmCTestMemCheckHandler::THREAD_SANITIZER: - os << "ThreadSanitizer"; + xml.Attribute("Checker", "ThreadSanitizer"); break; case cmCTestMemCheckHandler::MEMORY_SANITIZER: - os << "MemorySanitizer"; + xml.Attribute("Checker", "MemorySanitizer"); break; case cmCTestMemCheckHandler::UB_SANITIZER: - os << "UndefinedBehaviorSanitizer"; + xml.Attribute("Checker", "UndefinedBehaviorSanitizer"); break; default: - os << "Unknown"; + xml.Attribute("Checker", "Unknown"); } - os << "\">" << std::endl; - os << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n" - << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n" - << "\t<TestList>\n"; + xml.Element("StartDateTime", this->StartTest); + xml.Element("StartTestTime", this->StartTestTime); + xml.StartElement("TestList"); cmCTestMemCheckHandler::TestResultsVector::size_type cc; for ( cc = 0; cc < this->TestResults.size(); cc ++ ) { cmCTestTestResult *result = &this->TestResults[cc]; std::string testPath = result->Path + "/" + result->Name; - os << "\t\t<Test>" << cmXMLSafe( - this->CTest->GetShortPathToFile(testPath.c_str())) - << "</Test>" << std::endl; + xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str())); } - os << "\t</TestList>\n"; + xml.EndElement(); // TestList cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "-- Processing memory checking output: ", this->Quiet); size_t total = this->TestResults.size(); @@ -419,37 +416,33 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) } this->CleanTestOutput(memcheckstr, static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)); - this->WriteTestResultHeader(os, result); - os << "\t\t<Results>" << std::endl; + this->WriteTestResultHeader(xml, result); + xml.StartElement("Results"); for(std::vector<int>::size_type kk = 0; kk < memcheckresults.size(); ++kk) { if ( memcheckresults[kk] ) { - os << "\t\t\t<Defect type=\"" << this->ResultStringsLong[kk] - << "\">" - << memcheckresults[kk] - << "</Defect>" << std::endl; + xml.StartElement("Defect"); + xml.Attribute("type", this->ResultStringsLong[kk]); + xml.Content(memcheckresults[kk]); + xml.EndElement(); // Defect } this->GlobalResults[kk] += memcheckresults[kk]; } + xml.EndElement(); // Results - std::string logTag; + xml.StartElement("Log"); if(this->CTest->ShouldCompressMemCheckOutput()) { this->CTest->CompressString(memcheckstr); - logTag = "\t<Log compression=\"gzip\" encoding=\"base64\">\n"; - } - else - { - logTag = "\t<Log>\n"; + xml.Attribute("compression", "gzip"); + xml.Attribute("encoding", "base64"); } + xml.Content(memcheckstr); + xml.EndElement(); // Log - os - << "\t\t</Results>\n" - << logTag << cmXMLSafe(memcheckstr) << std::endl - << "\t</Log>\n"; - this->WriteTestResultFooter(os, result); + this->WriteTestResultFooter(xml, result); if ( current < cc ) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush, @@ -460,7 +453,7 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet); cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:" << std::endl, this->Quiet); - os << "\t<DefectList>" << std::endl; + xml.StartElement("DefectList"); for ( cc = 0; cc < this->GlobalResults.size(); cc ++ ) { if ( this->GlobalResults[cc] ) @@ -473,21 +466,20 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->ResultStringsLong[cc] << " - " << this->GlobalResults[cc] << std::endl, this->Quiet); - os << "\t\t<Defect Type=\"" << this->ResultStringsLong[cc] - << "\"/>" << std::endl; + xml.StartElement("Defect"); + xml.Attribute("Type", this->ResultStringsLong[cc]); + xml.EndElement(); } } - os << "\t</DefectList>" << std::endl; + xml.EndElement(); // DefectList - os << "\t<EndDateTime>" << this->EndTest << "</EndDateTime>" << std::endl; - os << "\t<EndTestTime>" << this->EndTestTime - << "</EndTestTime>" << std::endl; - os << "<ElapsedMinutes>" - << static_cast<int>(this->ElapsedTestingTime/6)/10.0 - << "</ElapsedMinutes>\n"; + xml.Element("EndDateTime", this->EndTest); + xml.Element("EndTestTime", this->EndTestTime); + xml.Element("ElapsedMinutes", + static_cast<int>(this->ElapsedTestingTime/6)/10.0); - os << "</DynamicAnalysis>" << std::endl; - this->CTest->EndXML(os); + xml.EndElement(); // DynamicAnalysis + this->CTest->EndXML(xml); } //---------------------------------------------------------------------- diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h index 69fdd9f..f1ac794 100644 --- a/Source/CTest/cmCTestMemCheckHandler.h +++ b/Source/CTest/cmCTestMemCheckHandler.h @@ -21,6 +21,7 @@ #include <string> class cmMakefile; +class cmXMLWriter; /** \class cmCTestMemCheckHandler * \brief A class that handles ctest -S invocations @@ -119,7 +120,7 @@ private: /** * Generate the Dart compatible output */ - void GenerateDartOutput(std::ostream& os); + void GenerateDartOutput(cmXMLWriter& xml); std::vector<std::string> CustomPreMemCheck; std::vector<std::string> CustomPostMemCheck; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index d7da2b4..d108592 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -57,8 +57,7 @@ bool cmCTestRunTest::CheckOutput() // Process has terminated and all output read. return false; } - else if(p == cmsysProcess_Pipe_STDOUT || - p == cmsysProcess_Pipe_STDERR) + else if(p == cmsysProcess_Pipe_STDOUT) { // Store this line of output. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -607,7 +606,7 @@ void cmCTestRunTest::DartProcessing() { if (this->TestHandler->DartStuff.find(this->ProcessOutput.c_str())) { - std::string dartString = this->TestHandler->DartStuff.match(1); + this->TestResult.DartString = this->TestHandler->DartStuff.match(1); // keep searching and replacing until none are left while (this->TestHandler->DartStuff1.find(this->ProcessOutput.c_str())) { @@ -615,8 +614,6 @@ void cmCTestRunTest::DartProcessing() cmSystemTools::ReplaceString(this->ProcessOutput, this->TestHandler->DartStuff1.match(1).c_str(), ""); } - this->TestResult.RegressionImages - = this->TestHandler->GenerateRegressionImages(dartString); } } } diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index 86dc2f2..f7bd1f9 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -14,7 +14,7 @@ #include "cmCTest.h" #include "cmSystemTools.h" #include "cmXMLParser.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <cmsys/RegularExpression.hxx> @@ -535,11 +535,11 @@ void cmCTestSVN::LoadModifications() } //---------------------------------------------------------------------------- -void cmCTestSVN::WriteXMLGlobal(std::ostream& xml) +void cmCTestSVN::WriteXMLGlobal(cmXMLWriter& xml) { this->cmCTestGlobalVC::WriteXMLGlobal(xml); - xml << "\t<SVNPath>" << this->RootInfo->Base << "</SVNPath>\n"; + xml.Element("SVNPath", this->RootInfo->Base); } //---------------------------------------------------------------------------- diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h index 17bf7cb..f9febc5 100644 --- a/Source/CTest/cmCTestSVN.h +++ b/Source/CTest/cmCTestSVN.h @@ -84,7 +84,7 @@ private: void DoRevisionSVN(Revision const& revision, std::vector<Change> const& changes); - void WriteXMLGlobal(std::ostream& xml); + void WriteXMLGlobal(cmXMLWriter& xml); // Parsing helper classes. class InfoParser; diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 0a34be8..1e493b0 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -336,11 +336,12 @@ void cmCTestScriptHandler::CreateCMake() delete this->LocalGenerator; } this->CMake = new cmake; + this->CMake->SetHomeDirectory(""); + this->CMake->SetHomeOutputDirectory(""); this->CMake->AddCMakePaths(); - this->GlobalGenerator = new cmGlobalGenerator; - this->GlobalGenerator->SetCMakeInstance(this->CMake); + this->GlobalGenerator = new cmGlobalGenerator(this->CMake); - this->LocalGenerator = this->GlobalGenerator->CreateLocalGenerator(); + this->LocalGenerator = this->GlobalGenerator->MakeLocalGenerator(); this->Makefile = this->LocalGenerator->GetMakefile(); this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest); diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 95cdf3b..70b7f5c 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -27,7 +27,7 @@ #include "cmLocalGenerator.h" #include "cmCommand.h" #include "cmSystemTools.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include "cm_utf8.h" #include <stdlib.h> @@ -633,7 +633,8 @@ int cmCTestTestHandler::ProcessHandler() this->LogFile = 0; return 1; } - this->GenerateDartOutput(xmlfile); + cmXMLWriter xml(xmlfile); + this->GenerateDartOutput(xml); } if ( ! this->PostProcessHandler() ) @@ -1142,54 +1143,53 @@ void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&, int) } //---------------------------------------------------------------------- -void cmCTestTestHandler::GenerateDartOutput(std::ostream& os) +void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml) { if ( !this->CTest->GetProduceXML() ) { return; } - this->CTest->StartXML(os, this->AppendXML); - os << "<Testing>\n" - << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n" - << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n" - << "\t<TestList>\n"; + this->CTest->StartXML(xml, this->AppendXML); + xml.StartElement("Testing"); + xml.Element("StartDateTime", this->StartTest); + xml.Element("StartTestTime", this->StartTestTime); + xml.StartElement("TestList"); cmCTestTestHandler::TestResultsVector::size_type cc; for ( cc = 0; cc < this->TestResults.size(); cc ++ ) { cmCTestTestResult *result = &this->TestResults[cc]; std::string testPath = result->Path + "/" + result->Name; - os << "\t\t<Test>" << cmXMLSafe( - this->CTest->GetShortPathToFile(testPath.c_str())) - << "</Test>" << std::endl; + xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str())); } - os << "\t</TestList>\n"; + xml.EndElement(); // TestList for ( cc = 0; cc < this->TestResults.size(); cc ++ ) { cmCTestTestResult *result = &this->TestResults[cc]; - this->WriteTestResultHeader(os, result); - os << "\t\t<Results>" << std::endl; + this->WriteTestResultHeader(xml, result); + xml.StartElement("Results"); if ( result->Status != cmCTestTestHandler::NOT_RUN ) { if ( result->Status != cmCTestTestHandler::COMPLETED || result->ReturnValue ) { - os << "\t\t\t<NamedMeasurement type=\"text/string\" " - "name=\"Exit Code\"><Value>" - << cmXMLSafe(this->GetTestStatus(result->Status)) - << "</Value>" - "</NamedMeasurement>\n" - << "\t\t\t<NamedMeasurement type=\"text/string\" " - "name=\"Exit Value\"><Value>" - << result->ReturnValue - << "</Value></NamedMeasurement>" - << std::endl; + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", "Exit Code"); + xml.Element("Value", this->GetTestStatus(result->Status)); + xml.EndElement(); // NamedMeasurement + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", "Exit Value"); + xml.Element("Value", result->ReturnValue); + xml.EndElement(); // NamedMeasurement } - os << result->RegressionImages; - os << "\t\t\t<NamedMeasurement type=\"numeric/double\" " - << "name=\"Execution Time\"><Value>" - << result->ExecutionTime - << "</Value></NamedMeasurement>\n"; + this->GenerateRegressionImages(xml, result->DartString); + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "numeric/double"); + xml.Attribute("name", "Execution Time"); + xml.Element("Value", result->ExecutionTime); + xml.EndElement(); // NamedMeasurement if(!result->Reason.empty()) { const char* reasonType = "Pass Reason"; @@ -1198,109 +1198,103 @@ void cmCTestTestHandler::GenerateDartOutput(std::ostream& os) { reasonType = "Fail Reason"; } - os << "\t\t\t<NamedMeasurement type=\"text/string\" " - << "name=\"" << reasonType << "\"><Value>" - << cmXMLSafe(result->Reason) - << "</Value></NamedMeasurement>\n"; + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", reasonType); + xml.Element("Value", result->Reason); + xml.EndElement(); // NamedMeasurement } - os - << "\t\t\t<NamedMeasurement type=\"text/string\" " - << "name=\"Completion Status\"><Value>" - << cmXMLSafe(result->CompletionStatus) - << "</Value></NamedMeasurement>\n"; - } - os - << "\t\t\t<NamedMeasurement type=\"text/string\" " - << "name=\"Command Line\"><Value>" - << cmXMLSafe(result->FullCommandLine) - << "</Value></NamedMeasurement>\n"; + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", "Completion Status"); + xml.Element("Value", result->CompletionStatus); + xml.EndElement(); // NamedMeasurement + } + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", "Command Line"); + xml.Element("Value", result->FullCommandLine); + xml.EndElement(); // NamedMeasurement std::map<std::string,std::string>::iterator measureIt; for ( measureIt = result->Properties->Measurements.begin(); measureIt != result->Properties->Measurements.end(); ++ measureIt ) { - os - << "\t\t\t<NamedMeasurement type=\"text/string\" " - << "name=\"" << measureIt->first << "\"><Value>" - << cmXMLSafe(measureIt->second) - << "</Value></NamedMeasurement>\n"; - } - os - << "\t\t\t<Measurement>\n" - << "\t\t\t\t<Value" - << (result->CompressOutput ? - " encoding=\"base64\" compression=\"gzip\">" - : ">"); - os << cmXMLSafe(result->Output); - os - << "</Value>\n" - << "\t\t\t</Measurement>\n" - << "\t\t</Results>\n"; - - this->AttachFiles(os, result); - this->WriteTestResultFooter(os, result); - } - - os << "\t<EndDateTime>" << this->EndTest << "</EndDateTime>\n" - << "\t<EndTestTime>" << this->EndTestTime << "</EndTestTime>\n" - << "<ElapsedMinutes>" - << static_cast<int>(this->ElapsedTestingTime/6)/10.0 - << "</ElapsedMinutes>" - << "</Testing>" << std::endl; - this->CTest->EndXML(os); + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", measureIt->first); + xml.Element("Value", measureIt->second); + xml.EndElement(); // NamedMeasurement + } + xml.StartElement("Measurement"); + xml.StartElement("Value"); + if (result->CompressOutput) + { + xml.Attribute("encoding", "base64"); + xml.Attribute("compression", "gzip"); + } + xml.Content(result->Output); + xml.EndElement(); // Value + xml.EndElement(); // Measurement + xml.EndElement(); // Results + + this->AttachFiles(xml, result); + this->WriteTestResultFooter(xml, result); + } + + xml.Element("EndDateTime", this->EndTest); + xml.Element("EndTestTime", this->EndTestTime); + xml.Element("ElapsedMinutes", + static_cast<int>(this->ElapsedTestingTime/6)/10.0); + xml.EndElement(); // Testing + this->CTest->EndXML(xml); } //---------------------------------------------------------------------------- -void cmCTestTestHandler::WriteTestResultHeader(std::ostream& os, +void cmCTestTestHandler::WriteTestResultHeader(cmXMLWriter& xml, cmCTestTestResult* result) { - os << "\t<Test Status=\""; + xml.StartElement("Test"); if ( result->Status == cmCTestTestHandler::COMPLETED ) { - os << "passed"; + xml.Attribute("Status", "passed"); } else if ( result->Status == cmCTestTestHandler::NOT_RUN ) { - os << "notrun"; + xml.Attribute("Status", "notrun"); } else { - os << "failed"; + xml.Attribute("Status", "failed"); } std::string testPath = result->Path + "/" + result->Name; - os << "\">\n" - << "\t\t<Name>" << cmXMLSafe(result->Name) << "</Name>\n" - << "\t\t<Path>" << cmXMLSafe( - this->CTest->GetShortPathToFile(result->Path.c_str())) << "</Path>\n" - << "\t\t<FullName>" << cmXMLSafe( - this->CTest->GetShortPathToFile(testPath.c_str())) << "</FullName>\n" - << "\t\t<FullCommandLine>" - << cmXMLSafe(result->FullCommandLine) - << "</FullCommandLine>\n"; + xml.Element("Name", result->Name); + xml.Element("Path", this->CTest->GetShortPathToFile(result->Path.c_str())); + xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str())); + xml.Element("FullCommandLine", result->FullCommandLine); } //---------------------------------------------------------------------------- -void cmCTestTestHandler::WriteTestResultFooter(std::ostream& os, +void cmCTestTestHandler::WriteTestResultFooter(cmXMLWriter& xml, cmCTestTestResult* result) { if(!result->Properties->Labels.empty()) { - os << "\t\t<Labels>\n"; + xml.StartElement("Labels"); std::vector<std::string> const& labels = result->Properties->Labels; for(std::vector<std::string>::const_iterator li = labels.begin(); li != labels.end(); ++li) { - os << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n"; + xml.Element("Label", *li); } - os << "\t\t</Labels>\n"; + xml.EndElement(); // Labels } - os - << "\t</Test>" << std::endl; + xml.EndElement(); // Test } //---------------------------------------------------------------------- -void cmCTestTestHandler::AttachFiles(std::ostream& os, +void cmCTestTestHandler::AttachFiles(cmXMLWriter& xml, cmCTestTestResult* result) { if(result->Status != cmCTestTestHandler::COMPLETED @@ -1317,11 +1311,14 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os, { const std::string &base64 = this->CTest->Base64GzipEncodeFile(*file); std::string fname = cmSystemTools::GetFilenameName(*file); - os << "\t\t<NamedMeasurement name=\"Attached File\" encoding=\"base64\" " - "compression=\"tar/gzip\" filename=\"" << fname << "\" type=\"file\">" - "\n\t\t\t<Value>\n\t\t\t" - << base64 - << "\n\t\t\t</Value>\n\t\t</NamedMeasurement>\n"; + xml.StartElement("NamedMeasurement"); + xml.Attribute("name", "Attached File"); + xml.Attribute("encoding", "base64"); + xml.Attribute("compression", "tar/gzip"); + xml.Attribute("filename", fname); + xml.Attribute("type", "file"); + xml.Element("Value", base64); + xml.EndElement(); // NamedMeasurement } } @@ -1571,9 +1568,10 @@ void cmCTestTestHandler::GetListOfTests() cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Constructing a list of tests" << std::endl, this->Quiet); cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cmGlobalGenerator gg(&cm); + cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); mf->AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType().c_str()); @@ -1826,8 +1824,8 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed() // Just for convenience #define SPACE_REGEX "[ \t\r\n]" //---------------------------------------------------------------------- -std::string cmCTestTestHandler::GenerateRegressionImages( - const std::string& xml) +void cmCTestTestHandler::GenerateRegressionImages( + cmXMLWriter& xml, const std::string& dart) { cmsys::RegularExpression twoattributes( "<DartMeasurement" @@ -1862,71 +1860,62 @@ std::string cmCTestTestHandler::GenerateRegressionImages( SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX "*>([^<]*)</DartMeasurementFile>"); - std::ostringstream ostr; bool done = false; - std::string cxml = xml; + std::string cxml = dart; while ( ! done ) { if ( twoattributes.find(cxml) ) { - ostr - << "\t\t\t<NamedMeasurement" - << " " << twoattributes.match(1) << "=\"" - << twoattributes.match(2) << "\"" - << " " << twoattributes.match(3) << "=\"" - << twoattributes.match(4) << "\"" - << "><Value>" << twoattributes.match(5) - << "</Value></NamedMeasurement>" - << std::endl; + xml.StartElement("NamedMeasurement"); + xml.Attribute(twoattributes.match(1).c_str(), + twoattributes.match(2)); + xml.Attribute(twoattributes.match(3).c_str(), + twoattributes.match(4)); + xml.Element("Value", twoattributes.match(5)); + xml.EndElement(); cxml.erase(twoattributes.start(), twoattributes.end() - twoattributes.start()); } else if ( threeattributes.find(cxml) ) { - ostr - << "\t\t\t<NamedMeasurement" - << " " << threeattributes.match(1) << "=\"" - << threeattributes.match(2) << "\"" - << " " << threeattributes.match(3) << "=\"" - << threeattributes.match(4) << "\"" - << " " << threeattributes.match(5) << "=\"" - << threeattributes.match(6) << "\"" - << "><Value>" << threeattributes.match(7) - << "</Value></NamedMeasurement>" - << std::endl; + xml.StartElement("NamedMeasurement"); + xml.Attribute(threeattributes.match(1).c_str(), + threeattributes.match(2)); + xml.Attribute(threeattributes.match(3).c_str(), + threeattributes.match(4)); + xml.Attribute(threeattributes.match(5).c_str(), + threeattributes.match(6)); + xml.Element("Value", twoattributes.match(7)); + xml.EndElement(); cxml.erase(threeattributes.start(), threeattributes.end() - threeattributes.start()); } else if ( fourattributes.find(cxml) ) { - ostr - << "\t\t\t<NamedMeasurement" - << " " << fourattributes.match(1) << "=\"" - << fourattributes.match(2) << "\"" - << " " << fourattributes.match(3) << "=\"" - << fourattributes.match(4) << "\"" - << " " << fourattributes.match(5) << "=\"" - << fourattributes.match(6) << "\"" - << " " << fourattributes.match(7) << "=\"" - << fourattributes.match(8) << "\"" - << "><Value>" << fourattributes.match(9) - << "</Value></NamedMeasurement>" - << std::endl; + xml.StartElement("NamedMeasurement"); + xml.Attribute(fourattributes.match(1).c_str(), + fourattributes.match(2)); + xml.Attribute(fourattributes.match(3).c_str(), + fourattributes.match(4)); + xml.Attribute(fourattributes.match(5).c_str(), + fourattributes.match(6)); + xml.Attribute(fourattributes.match(7).c_str(), + fourattributes.match(8)); + xml.Element("Value", twoattributes.match(9)); + xml.EndElement(); cxml.erase(fourattributes.start(), fourattributes.end() - fourattributes.start()); } else if ( cdatastart.find(cxml) && cdataend.find(cxml) ) { - ostr - << "\t\t\t<NamedMeasurement" - << " " << cdatastart.match(1) << "=\"" - << cdatastart.match(2) << "\"" - << " " << cdatastart.match(3) << "=\"" - << cdatastart.match(4) << "\"" - << "><Value><![CDATA[" - << cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end()) - << "]]></Value></NamedMeasurement>" - << std::endl; + xml.StartElement("NamedMeasurement"); + xml.Attribute(cdatastart.match(1).c_str(), cdatastart.match(2)); + xml.Attribute(cdatastart.match(3).c_str(), cdatastart.match(4)); + xml.StartElement("Value"); + xml.CData( + cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end())); + xml.EndElement(); // Value + xml.EndElement(); // NamedMeasurement cxml.erase(cdatastart.start(), cdataend.end() - cdatastart.start()); } @@ -1952,13 +1941,12 @@ std::string cmCTestTestHandler::GenerateRegressionImages( v2 = "text/string"; } - ostr - << "\t\t\t<NamedMeasurement" - << " " << k1 << "=\"" << v1 << "\"" - << " " << k2 << "=\"" << v2 << "\"" - << " encoding=\"none\"" - << "><Value>Image " << filename - << " is empty</Value></NamedMeasurement>"; + xml.StartElement("NamedMeasurement"); + xml.Attribute(k1.c_str(), v1); + xml.Attribute(k2.c_str(), v2); + xml.Attribute("encoding", "none"); + xml.Element("Value", "Image " + filename + " is empty"); + xml.EndElement(); } else { @@ -1976,14 +1964,13 @@ std::string cmCTestTestHandler::GenerateRegressionImages( size_t rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1); - ostr - << "\t\t\t<NamedMeasurement" - << " " << measurementfile.match(1) << "=\"" - << measurementfile.match(2) << "\"" - << " " << measurementfile.match(3) << "=\"" - << measurementfile.match(4) << "\"" - << " encoding=\"base64\"" - << ">" << std::endl << "\t\t\t\t<Value>"; + xml.StartElement("NamedMeasurement"); + xml.Attribute(measurementfile.match(1).c_str(), + measurementfile.match(2)); + xml.Attribute(measurementfile.match(3).c_str(), + measurementfile.match(4)); + xml.Attribute("encoding", "base64"); + std::stringstream ostr; for (size_t cc = 0; cc < rlen; cc ++ ) { ostr << encoded_buffer[cc]; @@ -1992,9 +1979,8 @@ std::string cmCTestTestHandler::GenerateRegressionImages( ostr << std::endl; } } - ostr - << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>" - << std::endl; + xml.Element("Value", ostr.str()); + xml.EndElement(); // NamedMeasurement delete [] file_buffer; delete [] encoded_buffer; } @@ -2006,13 +1992,11 @@ std::string cmCTestTestHandler::GenerateRegressionImages( { idx = 2; } - ostr - << "\t\t\t<NamedMeasurement" - << " name=\"" << measurementfile.match(idx) << "\"" - << " text=\"text/string\"" - << "><Value>File " << filename - << " not found</Value></NamedMeasurement>" - << std::endl; + xml.StartElement("NamedMeasurement"); + xml.Attribute("name", measurementfile.match(idx)); + xml.Attribute("text", "text/string"); + xml.Element("Value", "File " + filename + " not found"); + xml.EndElement(); cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename << "\" not found." << std::endl, this->Quiet); } @@ -2024,7 +2008,6 @@ std::string cmCTestTestHandler::GenerateRegressionImages( done = true; } } - return ostr.str(); } //---------------------------------------------------------------------- diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index fe43bb8..14067d5 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -18,6 +18,7 @@ #include <cmsys/RegularExpression.hxx> class cmMakefile; +class cmXMLWriter; /** \class cmCTestTestHandler * \brief A class that handles ctest -S invocations @@ -128,7 +129,7 @@ public: bool CompressOutput; std::string CompletionStatus; std::string Output; - std::string RegressionImages; + std::string DartString; int TestCount; cmCTestTestProperties* Properties; }; @@ -164,10 +165,10 @@ protected: virtual void GenerateTestCommand(std::vector<std::string>& args, int test); int ExecuteCommands(std::vector<std::string>& vec); - void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result); - void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result); + void WriteTestResultHeader(cmXMLWriter& xml, cmCTestTestResult* result); + void WriteTestResultFooter(cmXMLWriter& xml, cmCTestTestResult* result); // Write attached test files into the xml - void AttachFiles(std::ostream& os, cmCTestTestResult* result); + void AttachFiles(cmXMLWriter& xml, cmCTestTestResult* result); //! Clean test output to specified length bool CleanTestOutput(std::string& output, size_t length); @@ -204,7 +205,7 @@ private: /** * Generate the Dart compatible output */ - virtual void GenerateDartOutput(std::ostream& os); + virtual void GenerateDartOutput(cmXMLWriter& xml); void PrintLabelSummary(); /** @@ -270,7 +271,7 @@ private: cmsys::RegularExpression IncludeTestsRegularExpression; cmsys::RegularExpression ExcludeTestsRegularExpression; - std::string GenerateRegressionImages(const std::string& xml); + void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart); cmsys::RegularExpression DartStuff1; void CheckLabelFilter(cmCTestTestProperties& it); void CheckLabelFilterExclude(cmCTestTestProperties& it); diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 10927e7..8494d28 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -20,7 +20,7 @@ #include "cmVersion.h" #include "cmGeneratedFileStream.h" #include "cmXMLParser.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include "cmCLocaleEnvironmentScope.h" #include "cmCTestVC.h" @@ -224,24 +224,24 @@ int cmCTestUpdateHandler::ProcessHandler() bool updated = vc->Update(); std::string buildname = cmCTest::SafeBuildIdField( this->CTest->GetCTestConfiguration("BuildName")); - os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - << "<Update mode=\"Client\" Generator=\"ctest-" - << cmVersion::GetCMakeVersion() << "\">\n" - << "\t<Site>" << this->CTest->GetCTestConfiguration("Site") << "</Site>\n" - << "\t<BuildName>" << buildname - << "</BuildName>\n" - << "\t<BuildStamp>" << this->CTest->GetCurrentTag() << "-" - << this->CTest->GetTestModelString() << "</BuildStamp>" << std::endl; - os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n" - << "\t<StartTime>" << start_time_time << "</StartTime>\n" - << "\t<UpdateCommand>" - << cmXMLSafe(vc->GetUpdateCommandLine()).Quotes(false) - << "</UpdateCommand>\n" - << "\t<UpdateType>" << cmXMLSafe( - cmCTestUpdateHandlerUpdateToString(this->UpdateType)) - << "</UpdateType>\n"; - - vc->WriteXML(os); + + cmXMLWriter xml(os); + xml.StartDocument(); + xml.StartElement("Update"); + xml.Attribute("mode", "Client"); + xml.Attribute("Generator", + std::string("ctest-") + cmVersion::GetCMakeVersion()); + xml.Element("Site", this->CTest->GetCTestConfiguration("Site")); + xml.Element("BuildName", buildname); + xml.Element("BuildStamp", this->CTest->GetCurrentTag() + "-" + + this->CTest->GetTestModelString()); + xml.Element("StartDateTime", start_time); + xml.Element("StartTime", start_time_time); + xml.Element("UpdateCommand", vc->GetUpdateCommandLine()); + xml.Element("UpdateType", + cmCTestUpdateHandlerUpdateToString(this->UpdateType)); + + vc->WriteXML(xml); int localModifications = 0; int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated); @@ -265,29 +265,30 @@ int cmCTestUpdateHandler::ProcessHandler() cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); std::string end_time = this->CTest->CurrentTime(); - os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" - << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) - << "</EndTime>\n" - << "<ElapsedMinutes>" << - static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0 - << "</ElapsedMinutes>\n" - << "\t<UpdateReturnStatus>"; + xml.Element("EndDateTime", end_time); + xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime())); + xml.Element("ElapsedMinutes", + static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0); + + xml.StartElement("UpdateReturnStatus"); if(localModifications) { - os << "Update error: There are modified or conflicting files in the " - "repository"; + xml.Content("Update error: " + "There are modified or conflicting files in the repository"); cmCTestLog(this->CTest, ERROR_MESSAGE, " There are modified or conflicting files in the repository" << std::endl); } if(!updated) { - os << "Update command failed:\n" << vc->GetUpdateCommandLine(); + xml.Content("Update command failed:\n"); + xml.Content(vc->GetUpdateCommandLine()); cmCTestLog(this->CTest, ERROR_MESSAGE, " Update command failed: " << vc->GetUpdateCommandLine() << "\n"); } - os << "</UpdateReturnStatus>" << std::endl; - os << "</Update>" << std::endl; + xml.EndElement(); // UpdateReturnStatus + xml.EndElement(); // Update + xml.EndDocument(); return numUpdated; } diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx index 579190a..5c6b229 100644 --- a/Source/CTest/cmCTestUploadHandler.cxx +++ b/Source/CTest/cmCTestUploadHandler.cxx @@ -13,7 +13,7 @@ #include "cmGeneratedFileStream.h" #include "cmVersion.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" //---------------------------------------------------------------------------- cmCTestUploadHandler::cmCTestUploadHandler() @@ -47,32 +47,36 @@ int cmCTestUploadHandler::ProcessHandler() std::string buildname = cmCTest::SafeBuildIdField( this->CTest->GetCTestConfiguration("BuildName")); cmCTest::SetOfStrings::const_iterator it; - ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - << "<?xml-stylesheet type=\"text/xsl\" " + + cmXMLWriter xml(ofs); + xml.StartDocument(); + xml.ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" " "href=\"Dart/Source/Server/XSL/Build.xsl " - "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n" - << "<Site BuildName=\"" - << buildname - << "\" BuildStamp=\"" - << this->CTest->GetCurrentTag() << "-" - << this->CTest->GetTestModelString() << "\" Name=\"" - << this->CTest->GetCTestConfiguration("Site") << "\" Generator=\"ctest" - << cmVersion::GetCMakeVersion() - << "\">\n"; - this->CTest->AddSiteProperties(ofs); - ofs << "<Upload>\n"; + "<file:///Dart/Source/Server/XSL/Build.xsl> \""); + xml.StartElement("Site"); + xml.Attribute("BuildName", buildname); + xml.Attribute("BuildStamp", + this->CTest->GetCurrentTag() + "-" + this->CTest->GetTestModelString()); + xml.Attribute("Name", this->CTest->GetCTestConfiguration("Site")); + xml.Attribute("Generator", + std::string("ctest") + cmVersion::GetCMakeVersion()); + this->CTest->AddSiteProperties(xml); + xml.StartElement("Upload"); for ( it = this->Files.begin(); it != this->Files.end(); it ++ ) { cmCTestOptionalLog(this->CTest, OUTPUT, "\tUpload file: " << *it << std::endl, this->Quiet); - ofs << "<File filename=\"" << cmXMLSafe(*it) << "\">\n" - << "<Content encoding=\"base64\">\n"; - ofs << this->CTest->Base64EncodeFile(*it); - ofs << "\n</Content>\n" - << "</File>\n"; + xml.StartElement("File"); + xml.Attribute("filename", *it); + xml.StartElement("Content"); + xml.Attribute("encoding", "base64"); + xml.Content(this->CTest->Base64EncodeFile(*it)); + xml.EndElement(); // Content + xml.EndElement(); // File } - ofs << "</Upload>\n" - << "</Site>\n"; + xml.EndElement(); // Upload + xml.EndElement(); // Site + xml.EndDocument(); return 0; } diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index 6e93e95..8eff4d6 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -13,7 +13,7 @@ #include "cmCTest.h" #include "cmSystemTools.h" -#include "cmXMLSafe.h" +#include "cmXMLWriter.h" #include <cmsys/Process.h> @@ -202,7 +202,7 @@ bool cmCTestVC::UpdateImpl() } //---------------------------------------------------------------------------- -bool cmCTestVC::WriteXML(std::ostream& xml) +bool cmCTestVC::WriteXML(cmXMLWriter& xml) { this->Log << "--- Begin Revisions ---\n"; bool result = this->WriteXMLUpdates(xml); @@ -211,7 +211,7 @@ bool cmCTestVC::WriteXML(std::ostream& xml) } //---------------------------------------------------------------------------- -bool cmCTestVC::WriteXMLUpdates(std::ostream&) +bool cmCTestVC::WriteXMLUpdates(cmXMLWriter&) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "* CTest cannot extract updates for this VCS tool.\n"); @@ -219,7 +219,7 @@ bool cmCTestVC::WriteXMLUpdates(std::ostream&) } //---------------------------------------------------------------------------- -void cmCTestVC::WriteXMLEntry(std::ostream& xml, +void cmCTestVC::WriteXMLEntry(cmXMLWriter& xml, std::string const& path, std::string const& name, std::string const& full, @@ -228,21 +228,19 @@ void cmCTestVC::WriteXMLEntry(std::ostream& xml, static const char* desc[3] = { "Updated", "Modified", "Conflicting"}; Revision const& rev = f.Rev? *f.Rev : this->Unknown; std::string prior = f.PriorRev? f.PriorRev->Rev : std::string("Unknown"); - xml << "\t\t<" << desc[f.Status] << ">\n" - << "\t\t\t<File>" << cmXMLSafe(name) << "</File>\n" - << "\t\t\t<Directory>" << cmXMLSafe(path) << "</Directory>\n" - << "\t\t\t<FullName>" << cmXMLSafe(full) << "</FullName>\n" - << "\t\t\t<CheckinDate>" << cmXMLSafe(rev.Date) << "</CheckinDate>\n" - << "\t\t\t<Author>" << cmXMLSafe(rev.Author) << "</Author>\n" - << "\t\t\t<Email>" << cmXMLSafe(rev.EMail) << "</Email>\n" - << "\t\t\t<Committer>" << cmXMLSafe(rev.Committer) << "</Committer>\n" - << "\t\t\t<CommitterEmail>" << cmXMLSafe(rev.CommitterEMail) - << "</CommitterEmail>\n" - << "\t\t\t<CommitDate>" << cmXMLSafe(rev.CommitDate) - << "</CommitDate>\n" - << "\t\t\t<Log>" << cmXMLSafe(rev.Log) << "</Log>\n" - << "\t\t\t<Revision>" << cmXMLSafe(rev.Rev) << "</Revision>\n" - << "\t\t\t<PriorRevision>" << cmXMLSafe(prior) << "</PriorRevision>\n" - << "\t\t</" << desc[f.Status] << ">\n"; + xml.StartElement(desc[f.Status]); + xml.Element("File", name); + xml.Element("Directory", path); + xml.Element("FullName", full); + xml.Element("CheckinDate", rev.Date); + xml.Element("Author", rev.Author); + xml.Element("Email", rev.EMail); + xml.Element("Committer", rev.Committer); + xml.Element("CommitterEmail", rev.CommitterEMail); + xml.Element("CommitDate", rev.CommitDate); + xml.Element("Log", rev.Log); + xml.Element("Revision", rev.Rev); + xml.Element("PriorRevision", prior); + xml.EndElement(); ++this->PathCount[f.Status]; } diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h index 9dd0651..bc89302 100644 --- a/Source/CTest/cmCTestVC.h +++ b/Source/CTest/cmCTestVC.h @@ -15,6 +15,7 @@ #include "cmProcessTools.h" class cmCTest; +class cmXMLWriter; /** \class cmCTestVC * \brief Base class for version control system handlers @@ -51,7 +52,7 @@ public: { return this->UpdateCommandLine; } /** Write Update.xml entries for the updates found. */ - bool WriteXML(std::ostream& xml); + bool WriteXML(cmXMLWriter& xml); /** Enumerate non-trivial working tree states during update. */ enum PathStatus { PathUpdated, PathModified, PathConflicting }; @@ -65,7 +66,7 @@ protected: virtual void NoteOldRevision(); virtual bool UpdateImpl(); virtual void NoteNewRevision(); - virtual bool WriteXMLUpdates(std::ostream& xml); + virtual bool WriteXMLUpdates(cmXMLWriter& xml); #if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x510 public: // Sun CC 5.1 needs help to allow cmCTestSVN::Revision to see this @@ -110,7 +111,7 @@ protected: OutputParser* out, OutputParser* err = 0); /** Write xml element for one file. */ - void WriteXMLEntry(std::ostream& xml, std::string const& path, + void WriteXMLEntry(cmXMLWriter& xml, std::string const& path, std::string const& name, std::string const& full, File const& f); diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index e1bd02b..0c25f40 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -62,6 +62,7 @@ bool cmProcess::StartProcess() this->WorkingDirectory.c_str()); } cmsysProcess_SetTimeout(this->Process, this->Timeout); + cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1); cmsysProcess_Execute(this->Process); return (cmsysProcess_GetState(this->Process) == cmsysProcess_State_Executing); @@ -124,14 +125,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) for(;;) { // Look for lines already buffered. - if(this->StdOut.GetLine(line)) + if(this->Output.GetLine(line)) { return cmsysProcess_Pipe_STDOUT; } - else if(this->StdErr.GetLine(line)) - { - return cmsysProcess_Pipe_STDERR; - } // Check for more data from the process. char* data; @@ -143,11 +140,7 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) } else if(p == cmsysProcess_Pipe_STDOUT) { - this->StdOut.insert(this->StdOut.end(), data, data+length); - } - else if(p == cmsysProcess_Pipe_STDERR) - { - this->StdErr.insert(this->StdErr.end(), data, data+length); + this->Output.insert(this->Output.end(), data, data+length); } else // p == cmsysProcess_Pipe_None { @@ -157,14 +150,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) } // Look for partial last lines. - if(this->StdOut.GetLast(line)) + if(this->Output.GetLast(line)) { return cmsysProcess_Pipe_STDOUT; } - else if(this->StdErr.GetLast(line)) - { - return cmsysProcess_Pipe_STDERR; - } // No more data. Wait for process exit. if(!cmsysProcess_WaitForExit(this->Process, &timeout)) diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index 1479df0..eddeeab 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -48,8 +48,7 @@ public: * Read one line of output but block for no more than timeout. * Returns: * cmsysProcess_Pipe_None = Process terminated and all output read - * cmsysProcess_Pipe_STDOUT = Line came from stdout - * cmsysProcess_Pipe_STDOUT = Line came from stderr + * cmsysProcess_Pipe_STDOUT = Line came from stdout or stderr * cmsysProcess_Pipe_Timeout = Timeout expired while waiting */ int GetNextOutputLine(std::string& line, double timeout); @@ -68,13 +67,11 @@ private: bool GetLine(std::string& line); bool GetLast(std::string& line); }; - Buffer StdErr; - Buffer StdOut; + Buffer Output; std::string Command; std::string WorkingDirectory; std::vector<std::string> Arguments; std::vector<const char*> ProcessArgs; - std::string Output; int Id; int ExitValue; }; diff --git a/Source/Checks/cm_cxx11_unordered_map.cmake b/Source/Checks/cm_cxx11_unordered_map.cmake new file mode 100644 index 0000000..80fe391 --- /dev/null +++ b/Source/Checks/cm_cxx11_unordered_map.cmake @@ -0,0 +1,25 @@ + +if(CMAKE_CXX_STANDARD AND NOT DEFINED CMake_HAVE_CXX11_UNORDERED_MAP) + message(STATUS "Checking if compiler supports C++11 unordered_map") + try_compile(CMake_HAVE_CXX11_UNORDERED_MAP + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_LIST_DIR}/cm_cxx11_unordered_map.cpp + CMAKE_FLAGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + OUTPUT_VARIABLE OUTPUT + ) + if(CMake_HAVE_CXX11_UNORDERED_MAP) + message(STATUS "Checking if compiler supports C++11 unordered_map - yes") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if compiler supports C++11 unordered_map passed with the following output:\n" + "${OUTPUT}\n" + "\n" + ) + else() + message(STATUS "Checking if compiler supports C++11 unordered_map - no") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if compiler supports C++11 unordered_map failed with the following output:\n" + "${OUTPUT}\n" + "\n" + ) + endif() +endif() diff --git a/Source/Checks/cm_cxx11_unordered_map.cpp b/Source/Checks/cm_cxx11_unordered_map.cpp new file mode 100644 index 0000000..beeb31b --- /dev/null +++ b/Source/Checks/cm_cxx11_unordered_map.cpp @@ -0,0 +1,6 @@ +#include <unordered_map> +int main() { + std::unordered_map<int, int> map; + map[0] = 0; + return 0; +} diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index e013f81..5236e57 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -104,6 +104,8 @@ int main(int argc, char const* const* argv) if(doc.CheckOptions(argc, argv)) { cmake hcm; + hcm.SetHomeDirectory(""); + hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); std::vector<cmDocumentationEntry> generators; hcm.GetGeneratorDocumentation(generators); diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 2d336ee..38d6d44 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -68,6 +68,8 @@ int main(int argc, char** argv) { // Construct and print requested documentation. cmake hcm; + hcm.SetHomeDirectory(""); + hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); std::vector<cmDocumentationEntry> generators; diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx index cf24c13..368a0e6 100644 --- a/Source/cmCPackPropertiesGenerator.cxx +++ b/Source/cmCPackPropertiesGenerator.cxx @@ -1,6 +1,6 @@ #include "cmCPackPropertiesGenerator.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" cmCPackPropertiesGenerator::cmCPackPropertiesGenerator( cmMakefile* mf, @@ -29,15 +29,15 @@ void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os, cmInstalledFile::Property const& property = i->second; os << indent << "set_property(INSTALL " << - cmLocalGenerator::EscapeForCMake(expandedFileName) << " PROPERTY " << - cmLocalGenerator::EscapeForCMake(name); + cmOutputConverter::EscapeForCMake(expandedFileName) << " PROPERTY " << + cmOutputConverter::EscapeForCMake(name); for(cmInstalledFile::ExpressionVectorType::const_iterator j = property.ValueExpressions.begin(); j != property.ValueExpressions.end(); ++j) { std::string value = (*j)->Evaluate(this->Makefile, config); - os << " " << cmLocalGenerator::EscapeForCMake(value); + os << " " << cmOutputConverter::EscapeForCMake(value); } os << ")\n"; diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index c55ea35..0d24ed5 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -526,11 +526,9 @@ void * CCONV cmCreateSourceFile(void) return (void*)new cmCPluginAPISourceFile; } -void * CCONV cmCreateNewSourceFile(void *arg) +void * CCONV cmCreateNewSourceFile(void *) { - cmMakefile *mf = static_cast<cmMakefile *>(arg); cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile; - sf->Properties.SetCMakeInstance(mf->GetCMakeInstance()); return (void*)sf; } @@ -630,11 +628,7 @@ const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop) { return sf->FullPath.c_str(); } - bool chain = false; - // Ignore chain because old code will not expect it and it is a - // pain to implement here anyway. - return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, - chain); + return sf->Properties.GetPropertyValue(prop); } } @@ -662,7 +656,7 @@ void CCONV cmSourceFileSetProperty(void *arg,const char *prop, else if(prop) { if(!value) { value = "NOTFOUND"; } - sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE); + sf->Properties.SetProperty(prop, value); } } @@ -801,8 +795,7 @@ void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir, // Implement the old SetName method code here. if(headerFileOnly) { - sf->Properties.SetProperty("HEADER_FILE_ONLY", "1", - cmProperty::SOURCE_FILE); + sf->Properties.SetProperty("HEADER_FILE_ONLY", "1"); } sf->SourceName = name; std::string fname = sf->SourceName; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 403a459..e3b7a2b 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -28,6 +28,7 @@ #include "cmCTestStartCommand.h" #include "cmAlgorithms.h" #include "cmState.h" +#include "cmXMLWriter.h" #include "cmCTestBuildHandler.h" #include "cmCTestBuildAndTestHandler.h" @@ -510,9 +511,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) } cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cmGlobalGenerator gg(&cm); + cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), mf) ) { @@ -1488,7 +1490,7 @@ std::string cmCTest::SafeBuildIdField(const std::string& value) } //---------------------------------------------------------------------- -void cmCTest::StartXML(std::ostream& ostr, bool append) +void cmCTest::StartXML(cmXMLWriter& xml, bool append) { if(this->CurrentTag.empty()) { @@ -1511,42 +1513,45 @@ void cmCTest::StartXML(std::ostream& ostr, bool append) std::string site = cmCTest::SafeBuildIdField( this->GetCTestConfiguration("Site")); - ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - << "<Site BuildName=\"" << buildname << "\"\n" - << "\tBuildStamp=\"" << stamp << "\"\n" - << "\tName=\"" << site << "\"\n" - << "\tGenerator=\"ctest-" << cmVersion::GetCMakeVersion() << "\"\n" - << (append? "\tAppend=\"true\"\n":"") - << "\tCompilerName=\"" << this->GetCTestConfiguration("Compiler") - << "\"\n" + xml.StartDocument(); + xml.StartElement("Site"); + xml.Attribute("BuildName", buildname); + xml.BreakAttributes(); + xml.Attribute("BuildStamp", stamp); + xml.Attribute("Name", site); + xml.Attribute("Generator", + std::string("ctest-") + cmVersion::GetCMakeVersion()); + if(append) + { + xml.Attribute("Append", "true"); + } + xml.Attribute("CompilerName", this->GetCTestConfiguration("Compiler")); #ifdef _COMPILER_VERSION - << "\tCompilerVersion=\"_COMPILER_VERSION\"\n" + xml.Attribute("CompilerVersion", _COMPILER_VERSION); #endif - << "\tOSName=\"" << info.GetOSName() << "\"\n" - << "\tHostname=\"" << info.GetHostname() << "\"\n" - << "\tOSRelease=\"" << info.GetOSRelease() << "\"\n" - << "\tOSVersion=\"" << info.GetOSVersion() << "\"\n" - << "\tOSPlatform=\"" << info.GetOSPlatform() << "\"\n" - << "\tIs64Bits=\"" << info.Is64Bits() << "\"\n" - << "\tVendorString=\"" << info.GetVendorString() << "\"\n" - << "\tVendorID=\"" << info.GetVendorID() << "\"\n" - << "\tFamilyID=\"" << info.GetFamilyID() << "\"\n" - << "\tModelID=\"" << info.GetModelID() << "\"\n" - << "\tProcessorCacheSize=\"" << info.GetProcessorCacheSize() << "\"\n" - << "\tNumberOfLogicalCPU=\"" << info.GetNumberOfLogicalCPU() << "\"\n" - << "\tNumberOfPhysicalCPU=\""<< info.GetNumberOfPhysicalCPU() << "\"\n" - << "\tTotalVirtualMemory=\"" << info.GetTotalVirtualMemory() << "\"\n" - << "\tTotalPhysicalMemory=\""<< info.GetTotalPhysicalMemory() << "\"\n" - << "\tLogicalProcessorsPerPhysical=\"" - << info.GetLogicalProcessorsPerPhysical() << "\"\n" - << "\tProcessorClockFrequency=\"" - << info.GetProcessorClockFrequency() << "\"\n" - << ">" << std::endl; - this->AddSiteProperties(ostr); -} - -//---------------------------------------------------------------------- -void cmCTest::AddSiteProperties(std::ostream& ostr) + xml.Attribute("OSName", info.GetOSName()); + xml.Attribute("Hostname", info.GetHostname()); + xml.Attribute("OSRelease", info.GetOSRelease()); + xml.Attribute("OSVersion", info.GetOSVersion()); + xml.Attribute("OSPlatform", info.GetOSPlatform()); + xml.Attribute("Is64Bits", info.Is64Bits()); + xml.Attribute("VendorString", info.GetVendorString()); + xml.Attribute("VendorID", info.GetVendorID()); + xml.Attribute("FamilyID", info.GetFamilyID()); + xml.Attribute("ModelID", info.GetModelID()); + xml.Attribute("ProcessorCacheSize", info.GetProcessorCacheSize()); + xml.Attribute("NumberOfLogicalCPU", info.GetNumberOfLogicalCPU()); + xml.Attribute("NumberOfPhysicalCPU", info.GetNumberOfPhysicalCPU()); + xml.Attribute("TotalVirtualMemory", info.GetTotalVirtualMemory()); + xml.Attribute("TotalPhysicalMemory", info.GetTotalPhysicalMemory()); + xml.Attribute("LogicalProcessorsPerPhysical", + info.GetLogicalProcessorsPerPhysical()); + xml.Attribute("ProcessorClockFrequency", info.GetProcessorClockFrequency()); + this->AddSiteProperties(xml); +} + +//---------------------------------------------------------------------- +void cmCTest::AddSiteProperties(cmXMLWriter& xml) { cmCTestScriptHandler* ch = static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); @@ -1562,92 +1567,95 @@ void cmCTest::AddSiteProperties(std::ostream& ostr) ->GetGlobalProperty("SubProject"); if(subproject) { - ostr << "<Subproject name=\"" << subproject << "\">\n"; + xml.StartElement("Subproject"); + xml.Attribute("name", subproject); const char* labels = ch->GetCMake()->GetState() ->GetGlobalProperty("SubProjectLabels"); if(labels) { - ostr << " <Labels>\n"; + xml.StartElement("Labels"); std::string l = labels; std::vector<std::string> args; cmSystemTools::ExpandListArgument(l, args); for(std::vector<std::string>::iterator i = args.begin(); i != args.end(); ++i) { - ostr << " <Label>" << *i << "</Label>\n"; + xml.Element("Label", *i); } - ostr << " </Labels>\n"; + xml.EndElement(); } - ostr << "</Subproject>\n"; + xml.EndElement(); } // This code should stay when cdash only does label based sub-projects const char* label = cm->GetState()->GetGlobalProperty("Label"); if(label) { - ostr << "<Labels>\n"; - ostr << " <Label>" << label << "</Label>\n"; - ostr << "</Labels>\n"; + xml.StartElement("Labels"); + xml.Element("Label", label); + xml.EndElement(); } } - //---------------------------------------------------------------------- -void cmCTest::EndXML(std::ostream& ostr) +void cmCTest::EndXML(cmXMLWriter& xml) { - ostr << "</Site>" << std::endl; + xml.EndElement(); // Site + xml.EndDocument(); } //---------------------------------------------------------------------- -int cmCTest::GenerateCTestNotesOutput(std::ostream& os, +int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml, const cmCTest::VectorOfStrings& files) { std::string buildname = cmCTest::SafeBuildIdField( this->GetCTestConfiguration("BuildName")); cmCTest::VectorOfStrings::const_iterator it; - os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - << "<?xml-stylesheet type=\"text/xsl\" " + xml.StartDocument(); + xml.ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" " "href=\"Dart/Source/Server/XSL/Build.xsl " - "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n" - << "<Site BuildName=\"" << buildname - << "\" BuildStamp=\"" - << this->CurrentTag << "-" << this->GetTestModelString() << "\" Name=\"" - << this->GetCTestConfiguration("Site") << "\" Generator=\"ctest" - << cmVersion::GetCMakeVersion() - << "\">\n"; - this->AddSiteProperties(os); - os << "<Notes>" << std::endl; + "<file:///Dart/Source/Server/XSL/Build.xsl> \""); + xml.StartElement("Site"); + xml.Attribute("BuildName", buildname); + xml.Attribute("BuildStamp", this->CurrentTag+"-"+this->GetTestModelString()); + xml.Attribute("Name", this->GetCTestConfiguration("Site")); + xml.Attribute("Generator",std::string("ctest")+cmVersion::GetCMakeVersion()); + this->AddSiteProperties(xml); + xml.StartElement("Notes"); for ( it = files.begin(); it != files.end(); it ++ ) { cmCTestLog(this, OUTPUT, "\tAdd file: " << *it << std::endl); std::string note_time = this->CurrentTime(); - os << "<Note Name=\"" << cmXMLSafe(*it) << "\">\n" - << "<Time>" << cmSystemTools::GetTime() << "</Time>\n" - << "<DateTime>" << note_time << "</DateTime>\n" - << "<Text>" << std::endl; + xml.StartElement("Note"); + xml.Attribute("Name", *it); + xml.Element("Time", cmSystemTools::GetTime()); + xml.Element("DateTime", note_time); + xml.StartElement("Text"); cmsys::ifstream ifs(it->c_str()); if ( ifs ) { std::string line; while ( cmSystemTools::GetLineFromStream(ifs, line) ) { - os << cmXMLSafe(line) << std::endl; + xml.Content(line); + xml.Content("\n"); } ifs.close(); } else { - os << "Problem reading file: " << *it << std::endl; + xml.Content("Problem reading file: " + *it + "\n"); cmCTestLog(this, ERROR_MESSAGE, "Problem reading file: " << *it << " while creating notes" << std::endl); } - os << "</Text>\n" - << "</Note>" << std::endl; + xml.EndElement(); // Text + xml.EndElement(); // Note } - os << "</Notes>\n" - << "</Site>" << std::endl; + xml.EndElement(); // Notes + xml.EndElement(); // Site + xml.EndDocument(); return 1; } @@ -1660,8 +1668,8 @@ int cmCTest::GenerateNotesFile(const VectorOfStrings &files) cmCTestLog(this, ERROR_MESSAGE, "Cannot open notes file" << std::endl); return 1; } - - this->GenerateCTestNotesOutput(ofs, files); + cmXMLWriter xml(ofs); + this->GenerateCTestNotesOutput(xml, files); return 0; } diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 3f033d9..db3ea10 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -24,6 +24,7 @@ class cmGeneratedFileStream; class cmCTestCommand; class cmCTestScriptHandler; class cmCTestStartCommand; +class cmXMLWriter; #define cmCTestLog(ctSelf, logType, msg) \ do { \ @@ -273,10 +274,10 @@ public: static std::string SafeBuildIdField(const std::string& value); //! Start CTest XML output file - void StartXML(std::ostream& ostr, bool append); + void StartXML(cmXMLWriter& xml, bool append); //! End CTest XML output file - void EndXML(std::ostream& ostr); + void EndXML(cmXMLWriter& xml); //! Run command specialized for make and configure. Returns process status // and retVal is return value or exception. @@ -420,7 +421,7 @@ public: /** Direct process output to given streams. */ void SetStreams(std::ostream* out, std::ostream* err) { this->StreamOut = out; this->StreamErr = err; } - void AddSiteProperties(std::ostream& ); + void AddSiteProperties(cmXMLWriter& xml); bool GetLabelSummary() { return this->LabelSummary;} std::string GetCostDataFile(); @@ -553,7 +554,7 @@ private: bool UpdateCTestConfiguration(); //! Create note from files. - int GenerateCTestNotesOutput(std::ostream& os, + int GenerateCTestNotesOutput(cmXMLWriter& xml, const VectorOfStrings& files); //! Check if the argument is the one specified diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 289d0dc..54209c5 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -161,7 +161,6 @@ bool cmCacheManager::LoadCache(const std::string& path, // Format is key:type=value std::string helpString; CacheEntry e; - e.Properties.SetCMakeInstance(this->CMakeInstance); cmSystemTools::GetLineFromStream(fin, buffer); realbuffer = buffer.c_str(); while(*realbuffer != '0' && @@ -323,7 +322,6 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey, { // Create an entry and store the property. CacheEntry& ne = this->Cache[key]; - ne.Properties.SetCMakeInstance(this->CMakeInstance); ne.Type = cmState::UNINITIALIZED; ne.SetProperty(*p, e.Value.c_str()); } @@ -407,14 +405,9 @@ bool cmCacheManager::SaveCache(const std::string& path) " was created", cmState::INTERNAL); fout << "# This is the CMakeCache file.\n" - << "# For build in directory: " << currentcwd << "\n"; - cmCacheManager::CacheEntry* cmakeCacheEntry - = this->GetCacheEntry("CMAKE_COMMAND"); - if ( cmakeCacheEntry ) - { - fout << "# It was generated by CMake: " << - cmakeCacheEntry->Value << std::endl; - } + << "# For build in directory: " << currentcwd << "\n" + << "# It was generated by CMake: " + << cmSystemTools::GetCMakeCommand() << std::endl; fout << "# You can edit this file to change values found and used by cmake." << std::endl @@ -650,7 +643,6 @@ void cmCacheManager::AddCacheEntry(const std::string& key, cmState::CacheEntryType type) { CacheEntry& e = this->Cache[key]; - e.Properties.SetCMakeInstance(this->CMakeInstance); if ( value ) { e.Value = value; @@ -749,9 +741,7 @@ cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const { return this->Value.c_str(); } - bool c = false; - return - this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c); + return this->Properties.GetPropertyValue(prop); } //---------------------------------------------------------------------------- @@ -768,7 +758,7 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop, } else { - this->Properties.SetProperty(prop, value, cmProperty::CACHE); + this->Properties.SetProperty(prop, value); } } @@ -794,7 +784,7 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop, } else { - this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString); + this->Properties.AppendProperty(prop, value, asString); } } diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 0d1c86d..14e9e56 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -14,6 +14,7 @@ #include "cmSystemTools.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmOutputConverter.h" #include "cmCommandArgumentLexer.h" @@ -139,14 +140,15 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) this->Makefile->GetHomeOutputDirectory())) { std::ostringstream msg; - cmListFileBacktrace bt(this->Makefile->GetLocalGenerator()); cmListFileContext lfc; - lfc.FilePath = this->FileName; + cmOutputConverter converter(this->Makefile->GetStateSnapshot()); + lfc.FilePath = converter.Convert(this->FileName, + cmOutputConverter::HOME); + lfc.Line = this->FileLine; - bt.push_back(lfc); msg << "uninitialized variable \'" << var << "\'"; this->Makefile->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, - msg.str(), bt); + msg.str(), lfc); } } return 0; diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index d375ae6..387afc6 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -80,8 +80,6 @@ private: std::string::size_type InputBufferPos; std::string InputBuffer; std::vector<char> OutputBuffer; - int CurrentLine; - int Verbose; void Print(const char* place, const char* str); void SafePrintMissing(const char* str, int line, int cnt); @@ -94,12 +92,14 @@ private: std::vector<char*> Variables; const cmMakefile* Makefile; std::string Result; + std::string ErrorString; const char* FileName; + long FileLine; + int CurrentLine; + int Verbose; bool WarnUninitialized; bool CheckSystemVars; - long FileLine; bool EscapeQuotes; - std::string ErrorString; bool NoEscapeMode; bool ReplaceAtSyntax; bool RemoveEmpty; diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h index a2ce946..4dbac4a 100644 --- a/Source/cmComputeComponentGraph.h +++ b/Source/cmComputeComponentGraph.h @@ -67,17 +67,17 @@ private: int Root; int VisitIndex; }; - int TarjanWalkId; std::vector<int> TarjanVisited; std::vector<int> TarjanComponents; std::vector<TarjanEntry> TarjanEntries; + std::vector<NodeList> Components; std::stack<int> TarjanStack; + int TarjanWalkId; int TarjanIndex; void Tarjan(); void TarjanVisit(int i); // Connected components. - std::vector<NodeList> Components; }; #endif diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 09b9d70..51a08c5 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -61,14 +61,7 @@ private: cmMakefile* Makefile; cmGlobalGenerator const* GlobalGenerator; cmake* CMakeInstance; - bool DebugMode; - - // Configuration information. - bool HasConfig; std::string Config; - cmTarget::LinkLibraryType LinkType; - - // Output information. EntryVector FinalLinkEntries; typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType; @@ -131,7 +124,7 @@ private: void OrderLinkEntires(); std::vector<char> ComponentVisited; std::vector<int> ComponentOrder; - int ComponentOrderId; + struct PendingComponent { // The real component id. Needed because the map is indexed by @@ -158,11 +151,14 @@ private: // Record of the original link line. std::vector<int> OriginalEntries; + std::set<cmTarget const*> OldWrongConfigItems; + void CheckWrongConfigItem(cmLinkItem const& item); - // Compatibility help. + int ComponentOrderId; + cmTarget::LinkLibraryType LinkType; + bool HasConfig; + bool DebugMode; bool OldLinkDirMode; - void CheckWrongConfigItem(cmLinkItem const& item); - std::set<cmTarget const*> OldWrongConfigItems; }; #endif diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index e6cbe60..1f3046a 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -16,7 +16,7 @@ #include "cmGlobalGenerator.h" #include "cmState.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmMakefile.h" #include "cmTarget.h" #include "cmake.h" @@ -246,7 +246,6 @@ cmComputeLinkInformation // Store context information. this->Target = target; this->Makefile = this->Target->GetMakefile(); - this->LocalGenerator = this->Makefile->GetLocalGenerator(); this->GlobalGenerator = this->Makefile->GetGlobalGenerator(); this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance(); @@ -1395,7 +1394,8 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item) // Add the item using the -framework option. this->Items.push_back(Item("-framework", false)); - fw = this->LocalGenerator->EscapeForShell(fw); + cmOutputConverter converter(this->Makefile->GetStateSnapshot()); + fw = converter.EscapeForShell(fw); this->Items.push_back(Item(fw, false)); } diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 8847141..3afbb92 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -18,7 +18,6 @@ class cmake; class cmGlobalGenerator; -class cmLocalGenerator; class cmMakefile; class cmTarget; class cmOrderDirectories; @@ -75,14 +74,12 @@ private: // Context information. cmTarget const* Target; cmMakefile* Makefile; - cmLocalGenerator* LocalGenerator; cmGlobalGenerator* GlobalGenerator; cmake* CMakeInstance; // Configuration information. std::string Config; std::string LinkLanguage; - bool LinkDependsNoShared; // Modes for dealing with dependent shared libraries. enum SharedDepMode @@ -93,8 +90,6 @@ private: SharedDepModeLink // List file on link line }; - // System info. - bool UseImportLibrary; const char* LoaderFlag; std::string LibLinkFlag; std::string LibLinkFileFlag; @@ -102,22 +97,18 @@ private: std::string RuntimeFlag; std::string RuntimeSep; std::string RuntimeAlways; - bool RuntimeUseChrpath; - bool NoSONameUsesPath; - bool LinkWithRuntimePath; std::string RPathLinkFlag; SharedDepMode SharedDependencyMode; + enum LinkType { LinkUnknown, LinkStatic, LinkShared }; + void SetCurrentLinkType(LinkType lt); + // Link type adjustment. void ComputeLinkTypeInfo(); - enum LinkType { LinkUnknown, LinkStatic, LinkShared }; LinkType StartLinkType; LinkType CurrentLinkType; std::string StaticLinkTypeFlag; std::string SharedLinkTypeFlag; - bool LinkTypeEnabled; - void SetCurrentLinkType(LinkType lt); - bool ArchivesMayBeShared; // Link item parsing. void ComputeItemParserInfo(); @@ -129,7 +120,6 @@ private: cmsys::RegularExpression ExtractSharedLibraryName; cmsys::RegularExpression ExtractAnyLibraryName; std::string SharedRegexString; - bool OpenBSD; void AddLinkPrefix(const char* p); void AddLinkExtension(const char* e, LinkType type); std::string CreateExtensionRegex(std::vector<std::string> const& exts, @@ -173,20 +163,27 @@ private: std::set<std::string> OldLinkDirMask; std::vector<std::string> OldLinkDirItems; std::vector<std::string> OldUserFlagItems; - bool OldLinkDirMode; - - // CMP0060 warnings. - bool CMP0060Warn; std::set<std::string> CMP0060WarnItems; - + // Dependent library path computation. + cmOrderDirectories* OrderDependentRPath; // Runtime path computation. cmOrderDirectories* OrderRuntimeSearchPath; + + bool OldLinkDirMode; + bool OpenBSD; + bool LinkDependsNoShared; + bool UseImportLibrary; + bool RuntimeUseChrpath; + bool NoSONameUsesPath; + bool LinkWithRuntimePath; + bool LinkTypeEnabled; + bool ArchivesMayBeShared; + bool CMP0060Warn; + void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget const* target); void AddLibraryRuntimeInfo(std::string const& fullPath); - // Dependent library path computation. - cmOrderDirectories* OrderDependentRPath; }; #endif diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 73aface..61847d4 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -112,10 +112,7 @@ const char* cmConditionEvaluator::GetDefinitionIfUnquoted( if(def && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN) { - bool hasBeenReported = this->Makefile.HasCMP0054AlreadyBeenReported( - this->Makefile.GetBacktrace()[0]); - - if(!hasBeenReported) + if(!this->Makefile.HasCMP0054AlreadyBeenReported()) { std::ostringstream e; e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) << "\n"; @@ -161,10 +158,7 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword, if(isKeyword && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN) { - bool hasBeenReported = this->Makefile.HasCMP0054AlreadyBeenReported( - this->Makefile.GetBacktrace()[0]); - - if(!hasBeenReported) + if(!this->Makefile.HasCMP0054AlreadyBeenReported()) { std::ostringstream e; e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) << "\n"; diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in index c0a1aa9..62128a7 100644 --- a/Source/cmConfigure.cmake.h.in +++ b/Source/cmConfigure.cmake.h.in @@ -14,4 +14,5 @@ #cmakedefine CMAKE_USE_ELF_PARSER #cmakedefine CMAKE_USE_MACH_PARSER #cmakedefine CMAKE_ENCODING_UTF8 +#cmakedefine CMake_HAVE_CXX11_UNORDERED_MAP #define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@" diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index dd276a8..e1e1a5c 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -11,7 +11,7 @@ ============================================================================*/ #include "cmCoreTryCompile.h" #include "cmake.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmGlobalGenerator.h" #include "cmAlgorithms.h" #include "cmExportTryCompileFileGenerator.h" @@ -322,7 +322,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) std::string langFlags = "CMAKE_" + *li + "_FLAGS"; const char* flags = this->Makefile->GetDefinition(langFlags); fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li->c_str(), - cmLocalGenerator::EscapeForCMake(flags?flags:"").c_str()); + cmOutputConverter::EscapeForCMake(flags?flags:"").c_str()); fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}" " ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str()); } @@ -355,7 +355,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) const char* exeLinkFlags = this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS"); fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n", - cmLocalGenerator::EscapeForCMake( + cmOutputConverter::EscapeForCMake( exeLinkFlags ? exeLinkFlags : "").c_str()); } break; } diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 015825d..7c37e3b 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -17,7 +17,7 @@ //---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand() - : Backtrace(NULL) + : Backtrace() { this->HaveComment = false; this->EscapeOldStyle = true; @@ -26,46 +26,6 @@ cmCustomCommand::cmCustomCommand() } //---------------------------------------------------------------------------- -cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): - Outputs(r.Outputs), - Byproducts(r.Byproducts), - Depends(r.Depends), - CommandLines(r.CommandLines), - HaveComment(r.HaveComment), - Comment(r.Comment), - WorkingDirectory(r.WorkingDirectory), - EscapeAllowMakeVars(r.EscapeAllowMakeVars), - EscapeOldStyle(r.EscapeOldStyle), - Backtrace(r.Backtrace), - UsesTerminal(r.UsesTerminal) -{ -} - -//---------------------------------------------------------------------------- -cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r) -{ - if(this == &r) - { - return *this; - } - - this->Outputs = r.Outputs; - this->Byproducts= r.Byproducts; - this->Depends = r.Depends; - this->CommandLines = r.CommandLines; - this->HaveComment = r.HaveComment; - this->Comment = r.Comment; - this->WorkingDirectory = r.WorkingDirectory; - this->EscapeAllowMakeVars = r.EscapeAllowMakeVars; - this->EscapeOldStyle = r.EscapeOldStyle; - this->ImplicitDepends = r.ImplicitDepends; - this->Backtrace = r.Backtrace; - this->UsesTerminal = r.UsesTerminal; - - return *this; -} - -//---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand(cmMakefile const* mf, const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, @@ -77,15 +37,13 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf, Byproducts(byproducts), Depends(depends), CommandLines(commandLines), - HaveComment(comment?true:false), + Backtrace(), Comment(comment?comment:""), WorkingDirectory(workingDirectory?workingDirectory:""), + HaveComment(comment?true:false), EscapeAllowMakeVars(false), - EscapeOldStyle(true), - Backtrace(NULL) + EscapeOldStyle(true) { - this->EscapeOldStyle = true; - this->EscapeAllowMakeVars = false; if(mf) { this->Backtrace = mf->GetBacktrace(); @@ -93,11 +51,6 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf, } //---------------------------------------------------------------------------- -cmCustomCommand::~cmCustomCommand() -{ -} - -//---------------------------------------------------------------------------- const std::vector<std::string>& cmCustomCommand::GetOutputs() const { return this->Outputs; diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index 0bfaef2..f9b38c3 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -26,8 +26,6 @@ class cmCustomCommand public: /** Default and copy constructors for STL containers. */ cmCustomCommand(); - cmCustomCommand(const cmCustomCommand& r); - cmCustomCommand& operator=(cmCustomCommand const& r); /** Main constructor specifies all information for the command. */ cmCustomCommand(cmMakefile const* mf, @@ -38,8 +36,6 @@ public: const char* comment, const char* workingDirectory); - ~cmCustomCommand(); - /** Get the output file produced by the command. */ const std::vector<std::string>& GetOutputs() const; @@ -93,13 +89,13 @@ private: std::vector<std::string> Byproducts; std::vector<std::string> Depends; cmCustomCommandLines CommandLines; - bool HaveComment; + cmListFileBacktrace Backtrace; + ImplicitDependsList ImplicitDepends; std::string Comment; std::string WorkingDirectory; + bool HaveComment; bool EscapeAllowMakeVars; bool EscapeOldStyle; - cmListFileBacktrace Backtrace; - ImplicitDependsList ImplicitDepends; bool UsesTerminal; }; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index d23f815..11308c6 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -13,13 +13,13 @@ #include "cmMakefile.h" #include "cmCustomCommand.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmGeneratorExpression.h" //---------------------------------------------------------------------------- cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, const std::string& config, cmMakefile* mf): - CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), + CC(cc), Config(config), Makefile(mf), OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()), GE(new cmGeneratorExpression(&cc.GetBacktrace())), DependsDone(false) { @@ -96,7 +96,8 @@ cmCustomCommandGenerator } else { - cmd += this->LG->EscapeForShell(arg, this->MakeVars); + cmOutputConverter converter(this->Makefile->GetStateSnapshot()); + cmd += converter.EscapeForShell(arg, this->MakeVars); } } } diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index b4ae014..7ad95d1 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -16,7 +16,6 @@ class cmCustomCommand; class cmMakefile; -class cmLocalGenerator; class cmGeneratorExpression; class cmCustomCommandGenerator @@ -24,7 +23,6 @@ class cmCustomCommandGenerator cmCustomCommand const& CC; std::string Config; cmMakefile* Makefile; - cmLocalGenerator* LG; bool OldStyle; bool MakeVars; cmGeneratorExpression* GE; diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index f54bc4d..2dab169 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -18,35 +18,57 @@ cmDefinitions::Def cmDefinitions::NoDef; //---------------------------------------------------------------------------- cmDefinitions::Def const& cmDefinitions::GetInternal( - const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend) + const std::string& key, StackIter begin, StackIter end, bool raise) { - assert(rbegin != rend); - MapType::const_iterator i = rbegin->Map.find(key); - if (i != rbegin->Map.end()) + assert(begin != end); + MapType::iterator i = begin->Map.find(key); + if (i != begin->Map.end()) { + i->second.Used = true; return i->second; } - std::list<cmDefinitions>::reverse_iterator rit = rbegin; - ++rit; - if (rit == rend) + StackIter it = begin; + ++it; + if (it == end) { return cmDefinitions::NoDef; } - Def const& def = cmDefinitions::GetInternal(key, rit, rend); - return rbegin->Map.insert(MapType::value_type(key, def)).first->second; + Def const& def = cmDefinitions::GetInternal(key, it, end, raise); + if (!raise) + { + return def; + } + return begin->Map.insert(MapType::value_type(key, def)).first->second; } //---------------------------------------------------------------------------- const char* cmDefinitions::Get(const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend) + StackIter begin, StackIter end) { - Def const& def = cmDefinitions::GetInternal(key, rbegin, rend); + Def const& def = cmDefinitions::GetInternal(key, begin, end, false); return def.Exists? def.c_str() : 0; } +void cmDefinitions::Raise(const std::string& key, + StackIter begin, StackIter end) +{ + cmDefinitions::GetInternal(key, begin, end, true); +} + +bool cmDefinitions::HasKey(const std::string& key, + StackConstIter begin, StackConstIter end) +{ + for (StackConstIter it = begin; it != end; ++it) + { + MapType::const_iterator i = it->Map.find(key); + if (i != it->Map.end()) + { + return true; + } + } + return false; +} + //---------------------------------------------------------------------------- void cmDefinitions::Set(const std::string& key, const char* value) { @@ -54,13 +76,8 @@ void cmDefinitions::Set(const std::string& key, const char* value) this->Map[key] = def; } -void cmDefinitions::Erase(const std::string& key) -{ - this->Map.erase(key); -} - //---------------------------------------------------------------------------- -std::vector<std::string> cmDefinitions::LocalKeys() const +std::vector<std::string> cmDefinitions::UnusedKeys() const { std::vector<std::string> keys; keys.reserve(this->Map.size()); @@ -68,7 +85,7 @@ std::vector<std::string> cmDefinitions::LocalKeys() const for(MapType::const_iterator mi = this->Map.begin(); mi != this->Map.end(); ++mi) { - if (mi->second.Exists) + if (!mi->second.Used) { keys.push_back(mi->first); } @@ -77,36 +94,24 @@ std::vector<std::string> cmDefinitions::LocalKeys() const } //---------------------------------------------------------------------------- -cmDefinitions cmDefinitions::MakeClosure( - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend) +cmDefinitions cmDefinitions::MakeClosure(StackConstIter begin, + StackConstIter end) { - std::set<std::string> undefined; cmDefinitions closure; - closure.MakeClosure(undefined, rbegin, rend); - return closure; -} - -//---------------------------------------------------------------------------- -void -cmDefinitions::MakeClosure(std::set<std::string>& undefined, - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend) -{ - for (std::list<cmDefinitions>::const_reverse_iterator it = rbegin; - it != rend; ++it) + std::set<std::string> undefined; + for (StackConstIter it = begin; it != end; ++it) { // Consider local definitions. for(MapType::const_iterator mi = it->Map.begin(); mi != it->Map.end(); ++mi) { // Use this key if it is not already set or unset. - if(this->Map.find(mi->first) == this->Map.end() && + if(closure.Map.find(mi->first) == closure.Map.end() && undefined.find(mi->first) == undefined.end()) { if(mi->second.Exists) { - this->Map.insert(*mi); + closure.Map.insert(*mi); } else { @@ -115,22 +120,29 @@ cmDefinitions::MakeClosure(std::set<std::string>& undefined, } } } + return closure; } //---------------------------------------------------------------------------- std::vector<std::string> -cmDefinitions::ClosureKeys(std::set<std::string>& bound) const +cmDefinitions::ClosureKeys(StackConstIter begin, StackConstIter end) { + std::set<std::string> bound; std::vector<std::string> defined; - defined.reserve(this->Map.size()); - for(MapType::const_iterator mi = this->Map.begin(); - mi != this->Map.end(); ++mi) + + for (StackConstIter it = begin; it != end; ++it) { - // Use this key if it is not already set or unset. - if(bound.insert(mi->first).second && mi->second.Exists) + defined.reserve(defined.size() + it->Map.size()); + for(MapType::const_iterator mi = it->Map.begin(); + mi != it->Map.end(); ++mi) { - defined.push_back(mi->first); + // Use this key if it is not already set or unset. + if(bound.insert(mi->first).second && mi->second.Exists) + { + defined.push_back(mi->first); + } } } + return defined; } diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index b244793..5fdcaab 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -14,8 +14,12 @@ #include "cmStandardIncludes.h" #if defined(CMAKE_BUILD_WITH_CMAKE) +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP +#include <unordered_map> +#else #include "cmsys/hash_map.hxx" #endif +#endif #include <list> @@ -28,27 +32,26 @@ */ class cmDefinitions { + typedef std::list<cmDefinitions>::reverse_iterator StackIter; + typedef std::list<cmDefinitions>::const_reverse_iterator StackConstIter; public: - /** Get the value associated with a key; null if none. - Store the result locally if it came from a parent. */ static const char* Get(const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend); + StackIter begin, StackIter end); + + static void Raise(const std::string& key, StackIter begin, StackIter end); + + static bool HasKey(const std::string& key, + StackConstIter begin, StackConstIter end); /** Set (or unset if null) a value associated with a key. */ void Set(const std::string& key, const char* value); - void Erase(const std::string& key); + std::vector<std::string> UnusedKeys() const; - /** Get the set of all local keys. */ - std::vector<std::string> LocalKeys() const; + static std::vector<std::string> ClosureKeys(StackConstIter begin, + StackConstIter end); - std::vector<std::string> - ClosureKeys(std::set<std::string>& bound) const; - - static cmDefinitions MakeClosure( - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend); + static cmDefinitions MakeClosure(StackConstIter begin, StackConstIter end); private: // String with existence boolean. @@ -57,28 +60,32 @@ private: private: typedef std::string std_string; public: - Def(): std_string(), Exists(false) {} - Def(const char* v): std_string(v?v:""), Exists(v?true:false) {} - Def(const std_string& v): std_string(v), Exists(true) {} - Def(Def const& d): std_string(d), Exists(d.Exists) {} + Def(): std_string(), Exists(false), Used(false) {} + Def(const char* v) + : std_string(v ? v : ""), + Exists(v ? true : false), + Used(false) + {} + Def(const std_string& v): std_string(v), Exists(true), Used(false) {} + Def(Def const& d): std_string(d), Exists(d.Exists), Used(d.Used) {} bool Exists; + bool Used; }; static Def NoDef; - // Local definitions, set or unset. #if defined(CMAKE_BUILD_WITH_CMAKE) +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP + typedef std::unordered_map<std::string, Def> MapType; +#else typedef cmsys::hash_map<std::string, Def> MapType; +#endif #else typedef std::map<std::string, Def> MapType; #endif MapType Map; static Def const& GetInternal(const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend); - void MakeClosure(std::set<std::string>& undefined, - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend); + StackIter begin, StackIter end, bool raise); }; #endif diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 8854c36..b6c5fde 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -13,7 +13,6 @@ #define _cmDocumentation_h #include "cmStandardIncludes.h" -#include "cmProperty.h" #include "cmDocumentationFormatter.h" #include "cmDocumentationSection.h" #include "cmake.h" diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h index d4da5a4..201465d 100644 --- a/Source/cmExecutionStatus.h +++ b/Source/cmExecutionStatus.h @@ -12,47 +12,44 @@ #ifndef cmExecutionStatus_h #define cmExecutionStatus_h -#include "cmObject.h" +#include "cmStandardIncludes.h" /** \class cmExecutionStatus * \brief Superclass for all command status classes * * when a command is involked it may set values on a command status instance */ -class cmExecutionStatus : public cmObject +class cmExecutionStatus { public: - cmTypeMacro(cmExecutionStatus, cmObject); + cmExecutionStatus() { this->Clear(); } - cmExecutionStatus() { this->Clear();} - - virtual void SetReturnInvoked(bool val) + void SetReturnInvoked(bool val) { this->ReturnInvoked = val; } - virtual bool GetReturnInvoked() + bool GetReturnInvoked() { return this->ReturnInvoked; } - virtual void SetBreakInvoked(bool val) + void SetBreakInvoked(bool val) { this->BreakInvoked = val; } - virtual bool GetBreakInvoked() + bool GetBreakInvoked() { return this->BreakInvoked; } - virtual void SetContinueInvoked(bool val) + void SetContinueInvoked(bool val) { this->ContinueInvoked = val; } - virtual bool GetContinueInvoked() + bool GetContinueInvoked() { return this->ContinueInvoked; } - virtual void Clear() + void Clear() { this->ReturnInvoked = false; this->BreakInvoked = false; this->ContinueInvoked = false; this->NestedError = false; } - virtual void SetNestedError(bool val) { this->NestedError = val; } - virtual bool GetNestedError() { return this->NestedError; } - + void SetNestedError(bool val) { this->NestedError = val; } + bool GetNestedError() { return this->NestedError; } -protected: +private: bool ReturnInvoked; bool BreakInvoked; bool ContinueInvoked; diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index bf18deb..568ce89 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -18,7 +18,7 @@ //---------------------------------------------------------------------------- cmExportBuildFileGenerator::cmExportBuildFileGenerator() - : Backtrace(NULL) + : Backtrace() { this->Makefile = 0; this->ExportSet = 0; diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index eb8d193..dfb991b 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -99,8 +99,6 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target, || i->first.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0 || i->first.find("INTERFACE_LINK_LIBRARIES") == 0) { - const std::string libs = i->second.GetValue(); - std::string evalResult = this->FindTargets(i->first, target, emitted); @@ -118,6 +116,7 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target, } } } + std::string cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target, const std::string& config) diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 72a6a30..a81e53c 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -1008,7 +1008,6 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); const std::string makeArgs = mf->GetSafeDefinition( "CMAKE_ECLIPSE_MAKE_ARGUMENTS"); - const std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND"); cmGlobalGenerator* generator = const_cast<cmGlobalGenerator*>(this->GlobalGenerator); @@ -1096,11 +1095,12 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const std::string cleanArgs = "-E chdir \""; cleanArgs += makefile->GetCurrentBinaryDirectory(); cleanArgs += "\" \""; - cleanArgs += cmake; + cleanArgs += cmSystemTools::GetCMakeCommand(); cleanArgs += "\" -P \""; cleanArgs += (*it)->GetTargetDirectory(ti->second); cleanArgs += "/cmake_clean.cmake\""; - this->AppendTarget(fout, "Clean", cmake, cleanArgs, virtDir, "", ""); + this->AppendTarget(fout, "Clean", cmSystemTools::GetCMakeCommand(), + cleanArgs, virtDir, "", ""); } } break; diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index ec141a9..578e7d3 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -247,7 +247,7 @@ cmExtraKateGenerator::CreateDummyKateProjectFile(const cmMakefile* mf) const return; } - fout << "#Generated by " << mf->GetRequiredDefinition("CMAKE_COMMAND") + fout << "#Generated by " << cmSystemTools::GetCMakeCommand() << ", do not edit.\n"; } diff --git a/Source/cmExtraQbsGenerator.cxx b/Source/cmExtraQbsGenerator.cxx deleted file mode 100644 index 4cc4650..0000000 --- a/Source/cmExtraQbsGenerator.cxx +++ /dev/null @@ -1,260 +0,0 @@ -#include "cmExtraQbsGenerator.h" - -#include "cmGlobalGenerator.h" -#include "cmLocalGenerator.h" -#include "cmMakefile.h" -#include "cmGeneratedFileStream.h" -#include "cmSourceFile.h" - -cmExtraQbsGenerator::cmExtraQbsGenerator() -{ -#if defined(_WIN32) - this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); - this->SupportedGlobalGenerators.push_back("NMake Makefiles"); -#endif - this->SupportedGlobalGenerators.push_back("Ninja"); - this->SupportedGlobalGenerators.push_back("Unix Makefiles"); -} - -cmExtraQbsGenerator::~cmExtraQbsGenerator() {} - -void cmExtraQbsGenerator::GetDocumentation(cmDocumentationEntry &entry, - const std::string &) const -{ - entry.Name = this->GetName(); - entry.Brief = "Generates Qbs project files."; -} - -void cmExtraQbsGenerator::Generate() -{ - for (std::map<std::string, std::vector<cmLocalGenerator *> >::const_iterator - it = this->GlobalGenerator->GetProjectMap().begin(); - it != this->GlobalGenerator->GetProjectMap().end(); ++it) - { - // create a project file - this->CreateProjectFile(it->first, it->second); - } -} - -void cmExtraQbsGenerator::CreateProjectFile( - const std::string &name, - const std::vector<cmLocalGenerator *> &lgs) -{ - const cmMakefile *mf = lgs[0]->GetMakefile(); - std::string outputDir = mf->GetCurrentBinaryDirectory(); - - const std::string filename = outputDir + "/" + name + ".qbs"; - - this->CreateNewProjectFile(name, lgs, filename); -} - -void cmExtraQbsGenerator::CreateNewProjectFile( - const std::string &projectName, const std::vector<cmLocalGenerator *> &lgs, - const std::string &filename) -{ - cmGeneratedFileStream fout(filename.c_str()); - if (!fout) - { - return; - } - - fout << "import qbs\n" - << "import qbs.File\n\n" - << "Project {\n" - << "\tname:\"" << projectName << "\"\n"; - std::vector<cmLocalGenerator *>::const_iterator itr = lgs.begin(); - for (; itr != lgs.end(); ++itr) - { - cmLocalGenerator *lg = (*itr); - this->AppendSubProject(fout, lg); - } - fout << "}\n"; -} - -void cmExtraQbsGenerator::AppendSubProject(cmGeneratedFileStream &fout, - cmLocalGenerator *lg) -{ - const cmMakefile *mk = lg->GetMakefile(); - if (!mk || mk->GetTargets().size() == 0) - { - return; - } - - const std::string &relativePath = cmSystemTools::RelativePath( - mk->GetHomeDirectory(), mk->GetCurrentSourceDirectory()); - fout << "\tProject {\n" - << "\t\tname:\"" << relativePath << "\"\n"; - this->AppendProduct(fout, lg); - fout << "\t}\n"; -} - -void cmExtraQbsGenerator::AppendProduct(cmGeneratedFileStream &fout, - cmLocalGenerator *lg) -{ - const cmMakefile *mk = lg->GetMakefile(); - const cmTargets &ts = mk->GetTargets(); - std::string cfg = mk->GetSafeDefinition("CMAKE_BUILD_TYPE"); - cmTargets::const_iterator itr = ts.begin(); - for (; itr != ts.end(); ++itr) - { - const cmTarget &t = itr->second; - this->AppendTarget(fout, lg, t, cfg); - } -} - -void cmExtraQbsGenerator::AppendTarget(cmGeneratedFileStream &fout, - cmLocalGenerator *lg, const cmTarget &t, - const std::string &cfg) -{ - std::string type; - bool isBuildable = true; - switch (t.GetType()) - { - case cmTarget::EXECUTABLE: - type = "application"; - break; - case cmTarget::SHARED_LIBRARY: - type = "dynamiclibrary"; - break; - case cmTarget::STATIC_LIBRARY: - type = "staticlibrary"; - break; - default: - isBuildable = false; - break; - } - - if (type.empty()) - { - fout << "\t\tProject {\n"; - } - else - { - fout << "\t\tProduct {\n"; - fout << "\t\t\tdestinationDirectory: \"" << t.GetDirectory(cfg) << "\"\n"; - } - fout << "\t\t\tname:\"" << t.GetName() << "\"\n"; - - if (!type.empty()) - { - fout << "\t\t\ttype: \"" << type << "\"\n"; - fout << "\t\t\ttargetName: \"" << t.GetName() << "\"\n"; - } - - if (isBuildable) - { - fout << "\t\t\tDepends { name: \"cpp\" }\n"; - cmGeneratorTarget *gt = this->GlobalGenerator->GetGeneratorTarget(&t); - this->AppendSources(fout, gt, t, cfg); - - std::set<std::string> langs, incPaths, defs; - t.GetLanguages(langs, cfg); - for (std::set<std::string>::const_iterator lang = langs.begin(); - lang != langs.end(); - ++ lang) - { - const std::vector<std::string> &paths = - gt->GetIncludeDirectories(cfg, *lang); - std::copy(paths.begin(), paths.end(), - std::inserter(incPaths, incPaths.end())); - - lg->AddCompileDefinitions(defs, &t, cfg, *lang); - } - this->AppendIncludePaths(fout, incPaths); - this->AppendCompileDefinitions(fout, defs); - } - - fout << "\t\t}\n"; -} - -void cmExtraQbsGenerator::AppendSources(cmGeneratedFileStream &fout, - cmGeneratorTarget *gt, - const cmTarget &t, - const std::string &cfg) -{ - std::vector<cmSourceFile *> sources; - gt->GetSourceFiles(sources, cfg); - if (sources.empty()) - { - return; - } - - std::vector<cmSourceFile *> genSources; - std::vector<cmSourceFile *>::const_iterator itr = sources.begin(); - fout << "\t\t\tfiles: [\n" - << "\t\t\t\t\"" << t.GetMakefile()->GetCurrentListFile() << "\",\n"; - for (; itr != sources.end(); ++itr) - { - if (!(*itr)->GetPropertyAsBool("GENERATED")) - { - fout << "\t\t\t\t\"" << (*itr)->GetFullPath() << "\",\n"; - } - else - { - genSources.push_back(*itr); - } - } - fout << "\t\t\t]\n"; - - if (!genSources.empty()) - { - fout << "\t\t\tGroup {\n" - << "\t\t\t\tname:\"Generated\"\n" - << "\t\t\t\tfiles: [\n"; - itr = genSources.begin(); - std::string groupCondition; - bool initialCondition = true; - for (; itr != genSources.end(); ++itr) - { - const std::string &path = (*itr)->GetFullPath(); - fout << "\t\t\t\t\t\"" << path << "\",\n"; - if (initialCondition) - { - initialCondition = false; - } - else - { - groupCondition += "\t\t\t\t\t && "; - } - groupCondition += "File.exists(\"" + path + "\")\n"; - } - fout << "\t\t\t\t]\n" - << "\t\t\t\tcondition: " << groupCondition << "\t\t\t}\n"; - } -} - -void cmExtraQbsGenerator::AppendIncludePaths( - cmGeneratedFileStream &fout, - const std::set<std::string> &paths) -{ - if (paths.empty()) - { - return; - } - - std::set<std::string>::const_iterator itr = paths.begin(); - fout << "\t\t\tcpp.includePaths: [\n"; - for (; itr != paths.end(); ++ itr) - { - fout << "\t\t\t\t\"" << (*itr) << "\",\n"; - } - fout << "\t\t\t]\n"; -} - -void cmExtraQbsGenerator::AppendCompileDefinitions( - cmGeneratedFileStream &fout, - const std::set<std::string> &defs) -{ - if (defs.empty()) - { - return; - } - - std::set<std::string>::const_iterator itr = defs.begin(); - fout << "\t\t\tcpp.defines: [\n"; - for (; itr != defs.end(); ++ itr) - { - fout << "\t\t\t\t'" << (*itr) << "',\n"; - } - fout << "\t\t\t]\n"; -} diff --git a/Source/cmExtraQbsGenerator.h b/Source/cmExtraQbsGenerator.h deleted file mode 100644 index 531ccc9..0000000 --- a/Source/cmExtraQbsGenerator.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef CMEXTRAQBSGENERATOR_H -#define CMEXTRAQBSGENERATOR_H - -#include "cmExternalMakefileProjectGenerator.h" - -class cmGeneratorTarget; - -class cmExtraQbsGenerator : public cmExternalMakefileProjectGenerator -{ -public: - cmExtraQbsGenerator(); - ~cmExtraQbsGenerator(); - - virtual std::string GetName() const - { return cmExtraQbsGenerator::GetActualName(); } - static std::string GetActualName() { return "Qbs"; } - static cmExternalMakefileProjectGenerator *New() - { return new cmExtraQbsGenerator; } - - /** Get the documentation entry for this generator. */ - virtual void GetDocumentation(cmDocumentationEntry &entry, - const std::string &fullName) const; - - virtual void Generate(); - -private: - void CreateProjectFile(const std::string &name, - const std::vector<cmLocalGenerator *> &lgs); - void CreateNewProjectFile(const std::string &projectName, - const std::vector<cmLocalGenerator *> &lgs, - const std::string &filename); - void AppendSubProject(cmGeneratedFileStream &fout, cmLocalGenerator *lg); - void AppendProduct(cmGeneratedFileStream &fout, cmLocalGenerator *lg); - void AppendTarget(cmGeneratedFileStream &fout, - cmLocalGenerator *lg, - const cmTarget &t, - const std::string &cfg); - void AppendSources(cmGeneratedFileStream &fout, - cmGeneratorTarget *gt, - const cmTarget &t, - const std::string &cfg); - void AppendIncludePaths(cmGeneratedFileStream &fout, - const std::set<std::string> &paths); - void AppendCompileDefinitions(cmGeneratedFileStream &fout, - const std::set<std::string> &defs); -}; - -#endif // CMEXTRAQBSGENERATOR_H diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 0af4688..4698468 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2798,13 +2798,36 @@ namespace { static size_t - cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr, + cmFileCommandCurlDebugCallback(CURL *, curl_infotype type, char *chPtr, size_t size, void *data) { cmFileCommandVectorOfChar *vec = static_cast<cmFileCommandVectorOfChar*>(data); - vec->insert(vec->end(), chPtr, chPtr + size); - return size; + switch(type) + { + case CURLINFO_TEXT: + case CURLINFO_HEADER_IN: + case CURLINFO_HEADER_OUT: + vec->insert(vec->end(), chPtr, chPtr + size); + break; + case CURLINFO_DATA_IN: + case CURLINFO_DATA_OUT: + case CURLINFO_SSL_DATA_IN: + case CURLINFO_SSL_DATA_OUT: + { + char buf[128]; + int n = sprintf(buf, "[%" cmIML_INT_PRIu64 " bytes data]\n", + static_cast<cmIML_INT_uint64_t>(size)); + if (n > 0) + { + vec->insert(vec->end(), buf, buf + n); + } + } + break; + default: + break; + } + return 0; } @@ -2963,7 +2986,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) long timeout = 0; long inactivity_timeout = 0; - std::string verboseLog; + std::string logVar; std::string statusVar; bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY"); const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO"); @@ -3008,7 +3031,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) this->SetError("DOWNLOAD missing VAR for LOG."); return false; } - verboseLog = *i; + logVar = *i; } else if(*i == "STATUS") { @@ -3200,7 +3223,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: "); - if(!verboseLog.empty()) + if(!logVar.empty()) { res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); check_curl_result(res, "DOWNLOAD cannot set verbose: "); @@ -3287,22 +3310,10 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) } } - if(!chunkDebug.empty()) + if (!logVar.empty()) { chunkDebug.push_back(0); - if(CURLE_OPERATION_TIMEOUTED == res) - { - std::string output = &*chunkDebug.begin(); - - if(!verboseLog.empty()) - { - this->Makefile->AddDefinition(verboseLog, - &*chunkDebug.begin()); - } - } - - this->Makefile->AddDefinition(verboseLog, - &*chunkDebug.begin()); + this->Makefile->AddDefinition(logVar, &*chunkDebug.begin()); } return true; diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx index 5727470..13e2a66 100644 --- a/Source/cmFileTimeComparison.cxx +++ b/Source/cmFileTimeComparison.cxx @@ -13,8 +13,12 @@ // Use a hash table to avoid duplicate file time checks from disk. #if defined(CMAKE_BUILD_WITH_CMAKE) +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP +#include <unordered_map> +#else # include <cmsys/hash_map.hxx> #endif +#endif #include <cmsys/Encoding.hxx> @@ -47,9 +51,17 @@ private: { return h(s.c_str()); } +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP + std::hash<const char*> h; +#else cmsys::hash<const char*> h; +#endif }; +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP + typedef std::unordered_map<std::string, +#else typedef cmsys::hash_map<std::string, +#endif cmFileTimeComparison_Type, HashString> FileStatsMap; FileStatsMap Files; #endif diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 8e3510d..0dcda4d 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -44,8 +44,6 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, std::vector<std::string>::const_iterator j = this->Args.begin(); ++j; - std::string tmps; - cmListFileArgument arg; for( ; j != this->Args.end(); ++j) { // set the variable to the loop value diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index fdd1018..dc6d2d2 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -73,7 +73,6 @@ public: cmPolicies::PolicyMap Policies; }; - bool cmFunctionHelperCommand::InvokeInitialPass (const std::vector<cmListFileArgument>& args, cmExecutionStatus & inStatus) @@ -93,14 +92,8 @@ bool cmFunctionHelperCommand::InvokeInitialPass return false; } - // we push a scope on the makefile - cmMakefile::LexicalPushPop lexScope(this->Makefile); - cmMakefile::ScopePushPop varScope(this->Makefile); - static_cast<void>(varScope); - - // Push a weak policy scope which restores the policies recorded at - // function creation. - cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies); + cmMakefile::FunctionPushPop functionScope(this->Makefile, + this->Policies); // set the value of argc std::ostringstream strStream; @@ -145,8 +138,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass { // The error message should have already included the call stack // so we do not need to report an error here. - lexScope.Quiet(); - polScope.Quiet(); + functionScope.Quiet(); inStatus.SetNestedError(true); return false; } diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index a1c405b..3655a87 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -34,7 +34,7 @@ cmGeneratorExpression::Parse(std::string const& input) { return cmsys::auto_ptr<cmCompiledGeneratorExpression>( new cmCompiledGeneratorExpression( - this->Backtrace ? *this->Backtrace : cmListFileBacktrace(NULL), + this->Backtrace ? *this->Backtrace : cmListFileBacktrace(), input)); } diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index ff8790c..851aacd 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -35,7 +35,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *parent) : Parent(parent), Target(target), Property(property), - Content(content), Backtrace(NULL), TransitivePropertiesOnly(false) + Content(content), Backtrace(), TransitivePropertiesOnly(false) { Initialize(); } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index e2b8c45..67d0d54 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -353,6 +353,34 @@ void cmGeneratorTarget::ComputeObjectMapping() } //---------------------------------------------------------------------------- +const char* cmGeneratorTarget::GetFeature(const std::string& feature, + const std::string& config) const +{ + if(!config.empty()) + { + std::string featureConfig = feature; + featureConfig += "_"; + featureConfig += cmSystemTools::UpperCase(config); + if(const char* value = this->Target->GetProperty(featureConfig)) + { + return value; + } + } + if(const char* value = this->Target->GetProperty(feature)) + { + return value; + } + return this->LocalGenerator->GetFeature(feature, config); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::GetFeatureAsBool(const std::string& feature, + const std::string& config) const +{ + return cmSystemTools::IsOn(this->GetFeature(feature, config)); +} + +//---------------------------------------------------------------------------- const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file) { this->ComputeObjectMapping(); @@ -983,7 +1011,7 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang, case cmTarget::STATIC_LIBRARY: { std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY"; - if(this->Target->GetFeatureAsBool( + if(this->GetFeatureAsBool( "INTERPROCEDURAL_OPTIMIZATION", config)) { std::string varIPO = var + "_IPO"; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index c79aa72..a8edcb8 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -67,6 +67,11 @@ public: void ComputeObjectMapping(); + const char* GetFeature(const std::string& feature, + const std::string& config) const; + bool GetFeatureAsBool(const std::string& feature, + const std::string& config) const; + cmTarget* Target; cmMakefile* Makefile; cmLocalGenerator* LocalGenerator; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 76803c1..a460ca6 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -32,8 +32,7 @@ bool cmGetCMakePropertyCommand if ( args[1] == "VARIABLES" ) { - int cacheonly = 0; - std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly); + std::vector<std::string> vars = this->Makefile->GetDefinitions(); if (!vars.empty()) { output = cmJoin(vars, ";"); @@ -52,9 +51,11 @@ bool cmGetCMakePropertyCommand } else { - const char *prop = - this->Makefile->GetState() - ->GetGlobalProperty(args[1]); + const char *prop = 0; + if (!args[1].empty()) + { + prop = this->Makefile->GetState()->GetGlobalProperty(args[1]); + } if (prop) { output = prop; diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 4fe3318..228e53c 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -84,7 +84,11 @@ bool cmGetDirectoryPropertyCommand return true; } - const char *prop = dir->GetProperty(*i); + const char *prop = 0; + if (!i->empty()) + { + prop = dir->GetProperty(*i); + } if (prop) { this->Makefile->AddDefinition(variable, prop); diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index 250bd35..36b6c64 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -142,8 +142,7 @@ bool cmGetPropertyCommand { // Lookup brief documentation. std::string output; - if(cmPropertyDefinition* def = - this->Makefile->GetState()-> + if(cmPropertyDefinition const* def = this->Makefile->GetState()-> GetPropertyDefinition(this->PropertyName, scope)) { output = def->GetShortDescription(); @@ -158,8 +157,7 @@ bool cmGetPropertyCommand { // Lookup full documentation. std::string output; - if(cmPropertyDefinition* def = - this->Makefile->GetState()-> + if(cmPropertyDefinition const* def = this->Makefile->GetState()-> GetPropertyDefinition(this->PropertyName, scope)) { output = def->GetFullDescription(); diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 7667a85..46daa34 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -38,7 +38,11 @@ bool cmGetSourceFilePropertyCommand this->Makefile->AddDefinition(var, sf->GetLanguage().c_str()); return true; } - const char *prop = sf->GetPropertyForUser(args[2]); + const char *prop = 0; + if (!args[2].empty()) + { + prop = sf->GetPropertyForUser(args[2]); + } if (prop) { this->Makefile->AddDefinition(var, prop); diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 315e851..ca40bd0 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -40,7 +40,11 @@ bool cmGetTargetPropertyCommand else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName)) { cmTarget& target = *tgt; - const char* prop_cstr = target.GetProperty(args[2], this->Makefile); + const char* prop_cstr = 0; + if (!args[2].empty()) + { + prop_cstr = target.GetProperty(args[2], this->Makefile); + } if(prop_cstr) { prop = prop_cstr; diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx index b3df4c3..bf34589 100644 --- a/Source/cmGetTestPropertyCommand.cxx +++ b/Source/cmGetTestPropertyCommand.cxx @@ -29,7 +29,11 @@ bool cmGetTestPropertyCommand cmTest *test = this->Makefile->GetTest(testName); if (test) { - const char *prop = test->GetProperty(args[1]); + const char *prop = 0; + if (!args[1].empty()) + { + prop = test->GetProperty(args[1]); + } if (prop) { this->Makefile->AddDefinition(var, prop); diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index d191056..87665a0 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -14,14 +14,19 @@ #include "cmMakefile.h" #include "cmake.h" -cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator() +cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm) + : cmGlobalUnixMakefileGenerator3(cm) { this->EmptyRuleHackDepends = "NUL"; this->FindMakeProgramFile = "CMakeBorlandFindMake.cmake"; this->ForceUnixPaths = false; this->ToolSupportsColor = true; this->UseLinkScript = false; - this->WindowsShell = true; + cm->GetState()->SetWindowsShell(true); + this->IncludeDirective = "!include"; + this->DefineWindowsNULL = true; + this->PassMakeflags = true; + this->UnixCD = false; } @@ -39,15 +44,11 @@ void cmGlobalBorlandMakefileGenerator ///! Create a local generator appropriate to this Global Generator cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator( - cmLocalGenerator* parent) + cmLocalGenerator* parent, cmState::Snapshot snapshot) { cmLocalUnixMakefileGenerator3* lg = - new cmLocalUnixMakefileGenerator3(this, parent); - lg->SetIncludeDirective("!include"); - lg->SetDefineWindowsNULL(true); + new cmLocalUnixMakefileGenerator3(this, parent, snapshot); lg->SetMakefileVariableSize(32); - lg->SetPassMakeflags(true); - lg->SetUnixCD(false); lg->SetMakeCommandEscapeTargetTwice(true); lg->SetBorlandMakeCurlyHack(true); return lg; diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 4f24d2d..2ec510d 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -22,7 +22,7 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: - cmGlobalBorlandMakefileGenerator(); + cmGlobalBorlandMakefileGenerator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalBorlandMakefileGenerator>(); } @@ -36,7 +36,8 @@ public: static void GetDocumentation(cmDocumentationEntry& entry); ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /** * Try to determine system information such as shared library diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 1c9c475..bd949bb 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -48,7 +48,8 @@ #include <assert.h> -cmGlobalGenerator::cmGlobalGenerator() +cmGlobalGenerator::cmGlobalGenerator(cmake* cm) + : CMakeInstance(cm) { // By default the .SYMBOLIC dependency is not needed on symbolic rules. this->NeedSymbolicMark = false; @@ -69,15 +70,8 @@ cmGlobalGenerator::cmGlobalGenerator() this->TryCompileTimeout = 0; this->ExtraGenerator = 0; - this->CurrentLocalGenerator = 0; + this->CurrentMakefile = 0; this->TryCompileOuterMakefile = 0; - - this->WindowsShell = false; - this->WindowsVSIDE = false; - this->WatcomWMake = false; - this->MinGWMake = false; - this->NMake = false; - this->MSYSShell = false; } cmGlobalGenerator::~cmGlobalGenerator() @@ -93,18 +87,16 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p, { return true; } - else - { - std::ostringstream e; - e << - "Generator\n" - " " << this->GetName() << "\n" - "does not support platform specification, but platform\n" - " " << p << "\n" - "was specified."; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); - return false; - } + + std::ostringstream e; + e << + "Generator\n" + " " << this->GetName() << "\n" + "does not support platform specification, but platform\n" + " " << p << "\n" + "was specified."; + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; } bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, @@ -114,18 +106,15 @@ bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, { return true; } - else - { - std::ostringstream e; - e << - "Generator\n" - " " << this->GetName() << "\n" - "does not support toolset specification, but toolset\n" - " " << ts << "\n" - "was specified."; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); - return false; - } + std::ostringstream e; + e << + "Generator\n" + " " << this->GetName() << "\n" + "does not support toolset specification, but toolset\n" + " " << ts << "\n" + "was specified."; + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; } std::string cmGlobalGenerator::SelectMakeProgram( @@ -1099,7 +1088,7 @@ void cmGlobalGenerator::Configure() this->ClearGeneratorMembers(); // start with this directory - cmLocalGenerator *lg = this->CreateLocalGenerator(); + cmLocalGenerator *lg = this->MakeLocalGenerator(); this->LocalGenerators.push_back(lg); // set the Start directories @@ -1112,7 +1101,7 @@ void cmGlobalGenerator::Configure() this->CMakeInstance->GetHomeOutputDirectory()); // now do it - lg->Configure(); + lg->GetMakefile()->Configure(); // update the cache entry for the number of local generators, this is used // for progress @@ -1229,6 +1218,7 @@ void cmGlobalGenerator::Generate() this->CreateDefaultGlobalTargets(&globalTargets); for (i = 0; i < this->LocalGenerators.size(); ++i) { + this->LocalGenerators[i]->ComputeObjectMaxPath(); cmMakefile* mf = this->LocalGenerators[i]->GetMakefile(); cmTargets* targets = &(mf->GetTargets()); cmTargets::iterator tit; @@ -1286,8 +1276,7 @@ void cmGlobalGenerator::Generate() // Generate project files for (i = 0; i < this->LocalGenerators.size(); ++i) { - this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem(); - this->SetCurrentLocalGenerator(this->LocalGenerators[i]); + this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile()); this->LocalGenerators[i]->Generate(); if(!this->LocalGenerators[i]->GetMakefile()->IsOn( "CMAKE_SKIP_INSTALL_RULES")) @@ -1299,7 +1288,7 @@ void cmGlobalGenerator::Generate() (static_cast<float>(i)+1.0f)/ static_cast<float>(this->LocalGenerators.size())); } - this->SetCurrentLocalGenerator(0); + this->SetCurrentMakefile(0); if(!this->GenerateCPackPropertiesFile()) { @@ -1373,10 +1362,18 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens) { cmTargets& targets = this->LocalGenerators[i]->GetMakefile()->GetTargets(); + std::vector<std::string> targetNames; + targetNames.reserve(targets.size()); for(cmTargets::iterator ti = targets.begin(); ti != targets.end(); ++ti) { - cmTarget& target = ti->second; + targetNames.push_back(ti->second.GetName()); + } + for(std::vector<std::string>::iterator ti = targetNames.begin(); + ti != targetNames.end(); ++ti) + { + cmTarget& target = *this->LocalGenerators[i] + ->GetMakefile()->FindTarget(*ti, true); if(target.GetType() == cmTarget::EXECUTABLE || target.GetType() == cmTarget::STATIC_LIBRARY || target.GetType() == cmTarget::SHARED_LIBRARY || @@ -1882,9 +1879,22 @@ void cmGlobalGenerator::EnableInstallTarget() } cmLocalGenerator * -cmGlobalGenerator::CreateLocalGenerator(cmLocalGenerator *parent) +cmGlobalGenerator::MakeLocalGenerator(cmState::Snapshot snapshot, + cmLocalGenerator *parent) { - return new cmLocalGenerator(this, parent); + if (!snapshot.IsValid()) + { + snapshot = this->CMakeInstance->GetCurrentSnapshot(); + } + + return this->CreateLocalGenerator(parent, snapshot); +} + +cmLocalGenerator* +cmGlobalGenerator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) +{ + return new cmLocalGenerator(this, parent, snapshot); } void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen, @@ -2127,17 +2137,10 @@ inline std::string removeQuotes(const std::string& s) return s; } -void cmGlobalGenerator::SetCMakeInstance(cmake* cm) -{ - // Store a pointer to the cmake object instance. - this->CMakeInstance = cm; -} - void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) { cmMakefile* mf = this->LocalGenerators[0]->GetMakefile(); const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir(); - const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND"); // CPack std::string workingDir = mf->GetCurrentBinaryDirectory(); @@ -2252,7 +2255,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) } else { - singleLine.push_back(cmakeCommand); + singleLine.push_back(cmSystemTools::GetCMakeCommand()); singleLine.push_back("-E"); singleLine.push_back("echo"); singleLine.push_back("No interactive CMake dialog available."); @@ -2273,7 +2276,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) cpackCommandLines.end()); singleLine.erase(singleLine.begin(), singleLine.end()); depends.erase(depends.begin(), depends.end()); - singleLine.push_back(cmakeCommand); + singleLine.push_back(cmSystemTools::GetCMakeCommand()); singleLine.push_back("-H$(CMAKE_SOURCE_DIR)"); singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); cpackCommandLines.push_back(singleLine); @@ -2315,7 +2318,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) ostr.str().c_str(), &cpackCommandLines, depends, 0, /*uses_terminal*/false); } - std::string cmd = cmakeCommand; + std::string cmd = cmSystemTools::GetCMakeCommand(); cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); singleLine.erase(singleLine.begin(), singleLine.end()); @@ -2435,7 +2438,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( { // Package cmTarget target; - target.GetProperties().SetCMakeInstance(this->CMakeInstance); target.SetType(cmTarget::GLOBAL_TARGET, name); target.SetProperty("EXCLUDE_FROM_ALL","TRUE"); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 3b2a41f..f02df90 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -21,10 +21,15 @@ #include "cmExportSetMap.h" // For cmExportSetMap #include "cmGeneratorTarget.h" #include "cmGeneratorExpression.h" +#include "cmState.h" #if defined(CMAKE_BUILD_WITH_CMAKE) # include "cmFileLockPool.h" -# include <cmsys/hash_map.hxx> +# ifdef CMake_HAVE_CXX11_UNORDERED_MAP +# include <unordered_map> +# else +# include <cmsys/hash_map.hxx> +# endif #endif class cmake; @@ -49,11 +54,12 @@ class cmGlobalGenerator { public: ///! Free any memory allocated with the GlobalGenerator - cmGlobalGenerator(); + cmGlobalGenerator(cmake* cm); virtual ~cmGlobalGenerator(); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + cmLocalGenerator* MakeLocalGenerator( + cmState::Snapshot snapshot = cmState::Snapshot(), + cmLocalGenerator* parent = 0); ///! Get the name for this generator virtual std::string GetName() const { return "Generic"; } @@ -118,7 +124,7 @@ public: * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ - virtual int TryCompile(const std::string& srcdir, const std::string& bindir, + int TryCompile(const std::string& srcdir, const std::string& bindir, const std::string& projectName, const std::string& targetName, bool fast, std::string& output, cmMakefile* mf); @@ -155,9 +161,6 @@ public: const std::string& native, bool ignoreErrors); - ///! Set the CMake instance - void SetCMakeInstance(cmake *cm); - ///! Get the CMake instance cmake *GetCMakeInstance() const { return this->CMakeInstance; } @@ -165,11 +168,13 @@ public: const std::vector<cmLocalGenerator *>& GetLocalGenerators() const { return this->LocalGenerators;} - cmLocalGenerator* GetCurrentLocalGenerator() - {return this->CurrentLocalGenerator;} + cmMakefile* GetCurrentMakefile() const + { + return this->CurrentMakefile; + } - void SetCurrentLocalGenerator(cmLocalGenerator* lg) - {this->CurrentLocalGenerator = lg;} + void SetCurrentMakefile(cmMakefile* mf) + {this->CurrentMakefile = mf;} void AddLocalGenerator(cmLocalGenerator *lg); @@ -307,8 +312,6 @@ public: { return this->BinaryDirectories.insert(dir).second; } - /** Supported systems creates a GUID for the given name */ - virtual void CreateGUID(const std::string&) {} /** Return true if the generated build tree may contain multiple builds. i.e. "Can I build Debug and Release in the same tree?" */ @@ -354,20 +357,14 @@ public: cmFileLockPool& GetFileLockPool() { return FileLockPool; } #endif - bool WindowsShell; - bool WindowsVSIDE; - bool WatcomWMake; - bool MinGWMake; - bool NMake; - bool MSYSShell; - + std::string MakeSilentFlag; protected: virtual void Generate(); typedef std::vector<cmLocalGenerator*> GeneratorVector; // for a project collect all its targets by following depend // information, and also collect all the targets - virtual void GetTargetSets(TargetDependSet& projectTargets, + void GetTargetSets(TargetDependSet& projectTargets, TargetDependSet& originalTargets, cmLocalGenerator* root, GeneratorVector const&); bool IsRootOnlyTarget(cmTarget* target) const; @@ -401,15 +398,11 @@ protected: std::vector<std::string> depends, const char* workingDir, bool uses_terminal); - bool NeedSymbolicMark; - bool UseLinkScript; - bool ForceUnixPaths; - bool ToolSupportsColor; std::string FindMakeProgramFile; std::string ConfiguredFilesPath; cmake *CMakeInstance; std::vector<cmLocalGenerator *> LocalGenerators; - cmLocalGenerator* CurrentLocalGenerator; + cmMakefile* CurrentMakefile; // map from project name to vector of local generators in that project std::map<std::string, std::vector<cmLocalGenerator*> > ProjectMap; std::map<cmLocalGenerator*, std::set<cmTarget const*> > @@ -417,7 +410,6 @@ protected: // Set of named installation components requested by the project. std::set<std::string> InstallComponents; - bool InstallTargetEnabled; // Sets of named target exports cmExportSetMap ExportSets; std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets; @@ -429,7 +421,11 @@ protected: // All targets in the entire project. #if defined(CMAKE_BUILD_WITH_CMAKE) +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP + typedef std::unordered_map<std::string, cmTarget*> TargetMap; +#else typedef cmsys::hash_map<std::string, cmTarget*> TargetMap; +#endif #else typedef std::map<std::string,cmTarget *> TargetMap; #endif @@ -438,12 +434,15 @@ protected: TargetMap ImportedTargets; std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles; - virtual const char* GetPredefinedTargetsFolder(); + const char* GetPredefinedTargetsFolder(); virtual bool UseFolderProperty(); private: + ///! Create a local generator appropriate to this Global Generator + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); + cmMakefile* TryCompileOuterMakefile; - float FirstTimeProgress; // If you add a new map here, make sure it is copied // in EnableLanguagesFromGenerator std::map<std::string, bool> IgnoreExtensions; @@ -516,6 +515,14 @@ private: // Pool of file locks cmFileLockPool FileLockPool; #endif + +protected: + float FirstTimeProgress; + bool NeedSymbolicMark; + bool UseLinkScript; + bool ForceUnixPaths; + bool ToolSupportsColor; + bool InstallTargetEnabled; }; #endif diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h index 3c2cd60..ebba599 100644 --- a/Source/cmGlobalGeneratorFactory.h +++ b/Source/cmGlobalGeneratorFactory.h @@ -15,6 +15,7 @@ #include "cmStandardIncludes.h" +class cmake; class cmGlobalGenerator; struct cmDocumentationEntry; @@ -30,7 +31,7 @@ public: /** Create a GlobalGenerator */ virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& n) const = 0; + const std::string& n, cmake* cm) const = 0; /** Get the documentation entry for this factory */ virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0; @@ -44,10 +45,10 @@ class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory { public: /** Create a GlobalGenerator */ - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const { + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { if (name != T::GetActualName()) return 0; - return new T; } + return new T(cm); } /** Get the documentation entry for this factory */ virtual void GetDocumentation(cmDocumentationEntry& entry) const { diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index d6bf75c..f764418 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -21,8 +21,8 @@ const char *cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj"; const char *cmGlobalGhsMultiGenerator::DEFAULT_MAKE_PROGRAM = "gbuild"; -cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator() - : OSDirRelative(false) +cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm) + : cmGlobalGenerator(cm), OSDirRelative(false) { this->GhsBuildCommandInitialized = false; } @@ -33,11 +33,10 @@ cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() } cmLocalGenerator * -cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { - cmLocalGenerator *lg = new cmLocalGhsMultiGenerator(this, parent); - this->SetCurrentLocalGenerator(lg); - return lg; + return new cmLocalGhsMultiGenerator(this, parent, snapshot); } void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry &entry) diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 6464f5c..f1a3ed7 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -24,14 +24,15 @@ public: /// The default name of GHS MULTI's build file. Typically: monolith.gpj. static const char *FILE_EXTENSION; - cmGlobalGhsMultiGenerator(); + cmGlobalGhsMultiGenerator(cmake* cm); ~cmGlobalGhsMultiGenerator(); static cmGlobalGeneratorFactory *NewFactory() { return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>(); } ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /// @return the name of this generator. static std::string GetActualName() { return "Green Hills MULTI"; } diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 25613eb..50e7053 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -13,14 +13,19 @@ #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" -cmGlobalJOMMakefileGenerator::cmGlobalJOMMakefileGenerator() +cmGlobalJOMMakefileGenerator::cmGlobalJOMMakefileGenerator(cmake* cm) + : cmGlobalUnixMakefileGenerator3(cm) { this->FindMakeProgramFile = "CMakeJOMFindMake.cmake"; this->ForceUnixPaths = false; this->ToolSupportsColor = true; this->UseLinkScript = false; - this->WindowsShell = true; - this->NMake = true; + cm->GetState()->SetWindowsShell(true); + cm->GetState()->SetNMake(true); + this->DefineWindowsNULL = true; + this->PassMakeflags = true; + this->UnixCD = false; + this->MakeSilentFlag = "/nologo"; } void cmGlobalJOMMakefileGenerator @@ -46,20 +51,6 @@ void cmGlobalJOMMakefileGenerator this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalJOMMakefileGenerator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalUnixMakefileGenerator3* lg - = new cmLocalUnixMakefileGenerator3(this, parent); - lg->SetDefineWindowsNULL(true); - lg->SetMakeSilentFlag("/nologo"); - lg->SetIgnoreLibPrefix(true); - lg->SetPassMakeflags(true); - lg->SetUnixCD(false); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalJOMMakefileGenerator ::GetDocumentation(cmDocumentationEntry& entry) diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index 4831309..2185b23 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -22,7 +22,7 @@ class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: - cmGlobalJOMMakefileGenerator(); + cmGlobalJOMMakefileGenerator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalJOMMakefileGenerator>(); } @@ -36,9 +36,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx index b6adcbb..a84923b 100644 --- a/Source/cmGlobalMSYSMakefileGenerator.cxx +++ b/Source/cmGlobalMSYSMakefileGenerator.cxx @@ -15,13 +15,14 @@ #include "cmake.h" #include <cmsys/FStream.hxx> -cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator() +cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator(cmake* cm) + : cmGlobalUnixMakefileGenerator3(cm) { this->FindMakeProgramFile = "CMakeMSYSFindMake.cmake"; this->ForceUnixPaths = true; this->ToolSupportsColor = true; this->UseLinkScript = false; - this->MSYSShell = true; + cm->GetState()->SetMSYSShell(true); } std::string @@ -93,18 +94,6 @@ void cmGlobalMSYSMakefileGenerator } } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalMSYSMakefileGenerator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalUnixMakefileGenerator3* lg = - new cmLocalUnixMakefileGenerator3(this, parent); - lg->SetIgnoreLibPrefix(true); - lg->SetPassMakeflags(false); - lg->SetUnixCD(true); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalMSYSMakefileGenerator ::GetDocumentation(cmDocumentationEntry& entry) diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h index 1795d86..2cefc97 100644 --- a/Source/cmGlobalMSYSMakefileGenerator.h +++ b/Source/cmGlobalMSYSMakefileGenerator.h @@ -22,7 +22,7 @@ class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: - cmGlobalMSYSMakefileGenerator(); + cmGlobalMSYSMakefileGenerator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalMSYSMakefileGenerator>(); } @@ -35,9 +35,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx index 5b92eeb..b6e52d7 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.cxx +++ b/Source/cmGlobalMinGWMakefileGenerator.cxx @@ -13,14 +13,15 @@ #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" -cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator() +cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator(cmake* cm) + : cmGlobalUnixMakefileGenerator3(cm) { this->FindMakeProgramFile = "CMakeMinGWFindMake.cmake"; this->ForceUnixPaths = true; this->ToolSupportsColor = true; this->UseLinkScript = true; - this->WindowsShell = true; - this->MinGWMake = true; + cm->GetState()->SetWindowsShell(true); + cm->GetState()->SetMinGWMake(true); } void cmGlobalMinGWMakefileGenerator @@ -58,18 +59,6 @@ void cmGlobalMinGWMakefileGenerator this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalMinGWMakefileGenerator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalUnixMakefileGenerator3* lg = - new cmLocalUnixMakefileGenerator3(this, parent); - lg->SetIgnoreLibPrefix(true); - lg->SetPassMakeflags(false); - lg->SetUnixCD(true); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalMinGWMakefileGenerator ::GetDocumentation(cmDocumentationEntry& entry) diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h index 93f67be..3b00126 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.h +++ b/Source/cmGlobalMinGWMakefileGenerator.h @@ -22,7 +22,7 @@ class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: - cmGlobalMinGWMakefileGenerator(); + cmGlobalMinGWMakefileGenerator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalMinGWMakefileGenerator>(); } @@ -34,9 +34,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index 98d7fb4..4219c34 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -13,14 +13,19 @@ #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" -cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator() +cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator(cmake* cm) + : cmGlobalUnixMakefileGenerator3(cm) { this->FindMakeProgramFile = "CMakeNMakeFindMake.cmake"; this->ForceUnixPaths = false; this->ToolSupportsColor = true; this->UseLinkScript = false; - this->WindowsShell = true; - this->NMake = true; + cm->GetState()->SetWindowsShell(true); + cm->GetState()->SetNMake(true); + this->DefineWindowsNULL = true; + this->PassMakeflags = true; + this->UnixCD = false; + this->MakeSilentFlag = "/nologo"; } void cmGlobalNMakeMakefileGenerator @@ -46,20 +51,6 @@ void cmGlobalNMakeMakefileGenerator this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalNMakeMakefileGenerator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalUnixMakefileGenerator3* lg = - new cmLocalUnixMakefileGenerator3(this, parent); - lg->SetDefineWindowsNULL(true); - lg->SetMakeSilentFlag("/nologo"); - lg->SetIgnoreLibPrefix(true); - lg->SetPassMakeflags(true); - lg->SetUnixCD(false); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalNMakeMakefileGenerator ::GetDocumentation(cmDocumentationEntry& entry) diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index cb898ba..dd72c49 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -22,7 +22,7 @@ class cmGlobalNMakeMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: - cmGlobalNMakeMakefileGenerator(); + cmGlobalNMakeMakefileGenerator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalNMakeMakefileGenerator>(); } @@ -34,9 +34,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 9a952a3..103d75a 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -21,6 +21,7 @@ #include <algorithm> #include <assert.h> +#include <ctype.h> const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja"; const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja"; @@ -57,6 +58,28 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os, os << "# " << replace.substr(lpos) << "\n\n"; } +std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name) +{ + // Ninja rule names must match "[a-zA-Z0-9_.-]+". Use ".xx" to encode + // "." and all invalid characters as hexadecimal. + std::string encoded; + for (std::string::const_iterator i = name.begin(); + i != name.end(); ++i) + { + if (isalnum(*i) || *i == '_' || *i == '-') + { + encoded += *i; + } + else + { + char buf[16]; + sprintf(buf, ".%02x", static_cast<unsigned int>(*i)); + encoded += buf; + } + } + return encoded; +} + static bool IsIdentChar(char c) { return @@ -120,7 +143,8 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables, const std::string& rspfile, - int cmdLineLimit) + int cmdLineLimit, + bool* usedResponseFile) { // Make sure there is a rule. if(rule.empty()) @@ -205,15 +229,20 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, std::string buildstr = build; std::string assignments = variable_assignments.str(); const std::string& args = arguments; + bool useResponseFile = false; if (cmdLineLimit > 0 && args.size() + buildstr.size() + assignments.size() > (size_t) cmdLineLimit) { - buildstr += "_RSP_FILE"; variable_assignments.str(std::string()); cmGlobalNinjaGenerator::WriteVariable(variable_assignments, "RSP_FILE", rspfile, "", 1); assignments += variable_assignments.str(); + useResponseFile = true; } + if (usedResponseFile) + { + *usedResponseFile = useResponseFile; + } os << buildstr << args << assignments; } @@ -300,12 +329,10 @@ void cmGlobalNinjaGenerator::AddMacOSXContentRule() { cmLocalGenerator *lg = this->LocalGenerators[0]; - cmMakefile* mfRoot = lg->GetMakefile(); std::ostringstream cmd; - cmd << lg->ConvertToOutputFormat( - mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), - cmLocalGenerator::SHELL) + cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(), + cmLocalGenerator::SHELL) << " -E copy $in $out"; this->AddRule("COPY_OSX_CONTENT", @@ -477,8 +504,8 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os, } -cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() - : cmGlobalGenerator() +cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm) + : cmGlobalGenerator(cm) , BuildFileStream(0) , RulesFileStream(0) , CompileCommandsStream(0) @@ -489,7 +516,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() , PolicyCMP0058(cmPolicies::WARN) { #ifdef _WIN32 - this->WindowsShell = true; + cm->GetState()->SetWindowsShell(true); #endif // // Ninja is not ported to non-Unix OS yet. // this->ForceUnixPaths = true; @@ -501,9 +528,10 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() // Virtual public methods. cmLocalGenerator* -cmGlobalNinjaGenerator::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalNinjaGenerator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { - return new cmLocalNinjaGenerator(this, parent); + return new cmLocalNinjaGenerator(this, parent, snapshot); } void cmGlobalNinjaGenerator @@ -1155,9 +1183,8 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmMakefile* mfRoot = lg->GetMakefile(); std::ostringstream cmd; - cmd << lg->ConvertToOutputFormat( - mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), - cmLocalGenerator::SHELL) + cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(), + cmLocalGenerator::SHELL) << " -H" << lg->ConvertToOutputFormat(mfRoot->GetHomeDirectory(), cmLocalGenerator::SHELL) diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 00dc237..ffd1cdc 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -61,6 +61,7 @@ public: /// Write a divider in the given output stream @a os. static void WriteDivider(std::ostream& os); + static std::string EncodeRuleName(std::string const& name); static std::string EncodeIdent(const std::string &ident, std::ostream &vars); static std::string EncodeLiteral(const std::string &lit); std::string EncodePath(const std::string &path); @@ -87,7 +88,8 @@ public: const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables, const std::string& rspfile = std::string(), - int cmdLineLimit = -1); + int cmdLineLimit = -1, + bool* usedResponseFile = 0); /** * Helper to write a build statement with the special 'phony' rule. @@ -158,8 +160,7 @@ public: bool IsGCCOnWindows() const { return UsingGCCOnWindows; } public: - /// Default constructor. - cmGlobalNinjaGenerator(); + cmGlobalNinjaGenerator(cmake* cm); /// Convenience method for creating an instance of this class. static cmGlobalGeneratorFactory* NewFactory() { @@ -169,7 +170,8 @@ public: virtual ~cmGlobalNinjaGenerator() { } /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator() - virtual cmLocalGenerator* CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator* CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /// Overloaded methods. @see cmGlobalGenerator::GetName(). virtual std::string GetName() const { diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index a4df493..4fe52dd 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -20,7 +20,8 @@ #include "cmGeneratorTarget.h" #include "cmAlgorithms.h" -cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() +cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm) + : cmGlobalGenerator(cm) { // This type of makefile always requires unix style paths this->ForceUnixPaths = true; @@ -33,6 +34,11 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() this->UseLinkScript = true; #endif this->CommandDatabase = NULL; + + this->IncludeDirective = "include"; + this->DefineWindowsNULL = false; + this->PassMakeflags = false; + this->UnixCD = true; } void cmGlobalUnixMakefileGenerator3 @@ -54,9 +60,10 @@ void cmGlobalUnixMakefileGenerator3 ///! Create a local generator appropriate to this Global Generator cmLocalGenerator * -cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { - return new cmLocalUnixMakefileGenerator3(this, parent); + return new cmLocalUnixMakefileGenerator3(this, parent, snapshot); } //---------------------------------------------------------------------------- @@ -580,7 +587,7 @@ void cmGlobalUnixMakefileGenerator3 else { lg = static_cast<cmLocalUnixMakefileGenerator3 *> - (this->CreateLocalGenerator()); + (this->MakeLocalGenerator()); // set the Start directories lg->GetMakefile()->SetCurrentSourceDirectory (this->CMakeInstance->GetHomeDirectory()); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 165a3c8..a639ff0 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -54,7 +54,7 @@ class cmLocalUnixMakefileGenerator3; class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator { public: - cmGlobalUnixMakefileGenerator3(); + cmGlobalUnixMakefileGenerator3(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalUnixMakefileGenerator3>(); } @@ -68,7 +68,8 @@ public: static void GetDocumentation(cmDocumentationEntry& entry); ///! Create a local generator appropriate to this Global Generator3 - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /** * Try to determine system information such as shared library @@ -132,6 +133,11 @@ public: virtual bool AllowDeleteOnError() const { return true; } virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; + + std::string IncludeDirective; + bool DefineWindowsNULL; + bool PassMakeflags; + bool UnixCD; protected: void WriteMainMakefile2(); void WriteMainCMakefile(); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 04bb6ce..4e8ada4 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -42,8 +42,8 @@ class cmGlobalVisualStudio10Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { std::string genName; const char* p = cmVS10GenName(name, genName); @@ -51,20 +51,17 @@ public: { return 0; } if(!*p) { - return new cmGlobalVisualStudio10Generator( - genName, ""); + return new cmGlobalVisualStudio10Generator(cm, genName, ""); } if(*p++ != ' ') { return 0; } if(strcmp(p, "Win64") == 0) { - return new cmGlobalVisualStudio10Generator( - genName, "x64"); + return new cmGlobalVisualStudio10Generator(cm, genName, "x64"); } if(strcmp(p, "IA64") == 0) { - return new cmGlobalVisualStudio10Generator( - genName, "Itanium"); + return new cmGlobalVisualStudio10Generator(cm, genName, "Itanium"); } return 0; } @@ -93,9 +90,9 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory() } //---------------------------------------------------------------------------- -cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( +cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(cmake* cm, const std::string& name, const std::string& platformName) - : cmGlobalVisualStudio8Generator(name, platformName) + : cmGlobalVisualStudio8Generator(cm, name, platformName) { std::string vc10Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( @@ -105,6 +102,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( this->SystemIsWindowsPhone = false; this->SystemIsWindowsStore = false; this->MSBuildCommandInitialized = false; + this->Version = VS10; } //---------------------------------------------------------------------------- @@ -309,10 +307,10 @@ void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout) ///! Create a local generator appropriate to this Global Generator cmLocalGenerator * -cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { - return new cmLocalVisualStudio10Generator( - cmLocalVisualStudioGenerator::VS10, this, parent); + return new cmLocalVisualStudio10Generator(this, parent, snapshot); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 8cb2588..74d5022 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -24,7 +24,7 @@ class cmGlobalVisualStudio10Generator : public cmGlobalVisualStudio8Generator { public: - cmGlobalVisualStudio10Generator(const std::string& name, + cmGlobalVisualStudio10Generator(cmake* cm, const std::string& name, const std::string& platformName); static cmGlobalGeneratorFactory* NewFactory(); @@ -46,7 +46,8 @@ public: ); ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /** * Try to determine system information such as shared library diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index 36ae0a4..419bf8a 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -37,8 +37,8 @@ class cmGlobalVisualStudio11Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { std::string genName; const char* p = cmVS11GenName(name, genName); @@ -46,20 +46,17 @@ public: { return 0; } if(!*p) { - return new cmGlobalVisualStudio11Generator( - genName, ""); + return new cmGlobalVisualStudio11Generator(cm, genName, ""); } if(*p++ != ' ') { return 0; } if(strcmp(p, "Win64") == 0) { - return new cmGlobalVisualStudio11Generator( - genName, "x64"); + return new cmGlobalVisualStudio11Generator(cm, genName, "x64"); } if(strcmp(p, "ARM") == 0) { - return new cmGlobalVisualStudio11Generator( - genName, "ARM"); + return new cmGlobalVisualStudio11Generator(cm, genName, "ARM"); } std::set<std::string> installedSDKs = @@ -71,7 +68,7 @@ public: } cmGlobalVisualStudio11Generator* ret = - new cmGlobalVisualStudio11Generator(name, p); + new cmGlobalVisualStudio11Generator(cm, name, p); ret->WindowsCEVersion = "8.00"; return ret; } @@ -108,15 +105,16 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory() } //---------------------------------------------------------------------------- -cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator( +cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(cmake* cm, const std::string& name, const std::string& platformName) - : cmGlobalVisualStudio10Generator(name, platformName) + : cmGlobalVisualStudio10Generator(cm, name, platformName) { std::string vc11Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;" "ProductDir", vc11Express, cmSystemTools::KeyWOW64_32); this->DefaultPlatformToolset = "v110"; + this->Version = VS11; } //---------------------------------------------------------------------------- @@ -237,14 +235,6 @@ void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout) } //---------------------------------------------------------------------------- -cmLocalGenerator * -cmGlobalVisualStudio11Generator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - return new cmLocalVisualStudio10Generator( - cmLocalVisualStudioGenerator::VS11, this, parent); -} - -//---------------------------------------------------------------------------- bool cmGlobalVisualStudio11Generator::UseFolderProperty() { // Intentionally skip over the parent class implementation and call the diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h index ae4b888..b50f4c9 100644 --- a/Source/cmGlobalVisualStudio11Generator.h +++ b/Source/cmGlobalVisualStudio11Generator.h @@ -20,7 +20,7 @@ class cmGlobalVisualStudio11Generator: public cmGlobalVisualStudio10Generator { public: - cmGlobalVisualStudio11Generator(const std::string& name, + cmGlobalVisualStudio11Generator(cmake* cm, const std::string& name, const std::string& platformName); static cmGlobalGeneratorFactory* NewFactory(); @@ -28,9 +28,6 @@ public: virtual void WriteSLNHeader(std::ostream& fout); - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - protected: virtual bool InitializeWindowsPhone(cmMakefile* mf); virtual bool InitializeWindowsStore(cmMakefile* mf); diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index 17b2fc7..efa1133 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -37,8 +37,8 @@ class cmGlobalVisualStudio12Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { std::string genName; const char* p = cmVS12GenName(name, genName); @@ -46,20 +46,17 @@ public: { return 0; } if(!*p) { - return new cmGlobalVisualStudio12Generator( - genName, ""); + return new cmGlobalVisualStudio12Generator(cm, genName, ""); } if(*p++ != ' ') { return 0; } if(strcmp(p, "Win64") == 0) { - return new cmGlobalVisualStudio12Generator( - genName, "x64"); + return new cmGlobalVisualStudio12Generator(cm, genName, "x64"); } if(strcmp(p, "ARM") == 0) { - return new cmGlobalVisualStudio12Generator( - genName, "ARM"); + return new cmGlobalVisualStudio12Generator(cm, genName, "ARM"); } return 0; } @@ -88,15 +85,16 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory() } //---------------------------------------------------------------------------- -cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator( +cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(cmake* cm, const std::string& name, const std::string& platformName) - : cmGlobalVisualStudio11Generator(name, platformName) + : cmGlobalVisualStudio11Generator(cm, name, platformName) { std::string vc12Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\12.0\\Setup\\VC;" "ProductDir", vc12Express, cmSystemTools::KeyWOW64_32); this->DefaultPlatformToolset = "v120"; + this->Version = VS12; } //---------------------------------------------------------------------------- @@ -217,14 +215,6 @@ void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout) } //---------------------------------------------------------------------------- -cmLocalGenerator * -cmGlobalVisualStudio12Generator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - return new cmLocalVisualStudio10Generator( - cmLocalVisualStudioGenerator::VS12, this, parent); -} - -//---------------------------------------------------------------------------- bool cmGlobalVisualStudio12Generator::IsWindowsDesktopToolsetInstalled() const { diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h index d304bc1..bce9e0c 100644 --- a/Source/cmGlobalVisualStudio12Generator.h +++ b/Source/cmGlobalVisualStudio12Generator.h @@ -20,7 +20,7 @@ class cmGlobalVisualStudio12Generator: public cmGlobalVisualStudio11Generator { public: - cmGlobalVisualStudio12Generator(const std::string& name, + cmGlobalVisualStudio12Generator(cmake* cm, const std::string& name, const std::string& platformName); static cmGlobalGeneratorFactory* NewFactory(); @@ -28,9 +28,6 @@ public: virtual void WriteSLNHeader(std::ostream& fout); - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - //in Visual Studio 2013 they detached the MSBuild tools version //from the .Net Framework version and instead made it have it's own //version number diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index 90fcc7e..2cf55d4 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -37,8 +37,8 @@ class cmGlobalVisualStudio14Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { std::string genName; const char* p = cmVS14GenName(name, genName); @@ -46,20 +46,17 @@ public: { return 0; } if(!*p) { - return new cmGlobalVisualStudio14Generator( - genName, ""); + return new cmGlobalVisualStudio14Generator(cm, genName, ""); } if(*p++ != ' ') { return 0; } if(strcmp(p, "Win64") == 0) { - return new cmGlobalVisualStudio14Generator( - genName, "x64"); + return new cmGlobalVisualStudio14Generator(cm, genName, "x64"); } if(strcmp(p, "ARM") == 0) { - return new cmGlobalVisualStudio14Generator( - genName, "ARM"); + return new cmGlobalVisualStudio14Generator(cm, genName, "ARM"); } return 0; } @@ -88,15 +85,16 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory() } //---------------------------------------------------------------------------- -cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator( +cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name, const std::string& platformName) - : cmGlobalVisualStudio12Generator(name, platformName) + : cmGlobalVisualStudio12Generator(cm, name, platformName) { std::string vc14Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\14.0\\Setup\\VC;" "ProductDir", vc14Express, cmSystemTools::KeyWOW64_32); this->DefaultPlatformToolset = "v140"; + this->Version = VS14; } //---------------------------------------------------------------------------- @@ -126,11 +124,3 @@ void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 14\n"; } } - -//---------------------------------------------------------------------------- -cmLocalGenerator * -cmGlobalVisualStudio14Generator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - return new cmLocalVisualStudio10Generator( - cmLocalVisualStudioGenerator::VS14, this, parent); -} diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h index 59f1e60..aa817be 100644 --- a/Source/cmGlobalVisualStudio14Generator.h +++ b/Source/cmGlobalVisualStudio14Generator.h @@ -20,7 +20,7 @@ class cmGlobalVisualStudio14Generator: public cmGlobalVisualStudio12Generator { public: - cmGlobalVisualStudio14Generator(const std::string& name, + cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name, const std::string& platformName); static cmGlobalGeneratorFactory* NewFactory(); @@ -28,9 +28,6 @@ public: virtual void WriteSLNHeader(std::ostream& fout); - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - virtual const char* GetToolsVersion() { return "14.0"; } protected: virtual const char* GetIDEVersion() { return "14.0"; } diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 570314e..632141a 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -31,9 +31,11 @@ std::string GetVS6TargetName(const std::string& targetName) return name; } -cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator() +cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator(cmake* cm) + : cmGlobalVisualStudioGenerator(cm) { this->MSDevCommandInitialized = false; + this->Version = VS6; } void cmGlobalVisualStudio6Generator @@ -171,9 +173,10 @@ cmGlobalVisualStudio6Generator::GenerateBuildCommand( ///! Create a local generator appropriate to this Global Generator cmLocalGenerator * -cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { - return new cmLocalVisualStudio6Generator(this, parent); + return new cmLocalVisualStudio6Generator(this, parent, snapshot); } diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h index d748a85..2460158 100644 --- a/Source/cmGlobalVisualStudio6Generator.h +++ b/Source/cmGlobalVisualStudio6Generator.h @@ -25,7 +25,7 @@ class cmTarget; class cmGlobalVisualStudio6Generator : public cmGlobalVisualStudioGenerator { public: - cmGlobalVisualStudio6Generator(); + cmGlobalVisualStudio6Generator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalVisualStudio6Generator>(); } @@ -39,7 +39,8 @@ public: static void GetDocumentation(cmDocumentationEntry& entry); ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /** * Try to determine system information such as shared library diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 308e858..1ab4c9c 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -16,23 +16,12 @@ #include "cmake.h" //---------------------------------------------------------------------------- -cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator( +cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(cmake* cm, const std::string& platformName) - : cmGlobalVisualStudio7Generator(platformName) + : cmGlobalVisualStudio7Generator(cm, platformName) { this->ProjectConfigurationSectionName = "ProjectConfiguration"; -} - -//---------------------------------------------------------------------------- -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalVisualStudio71Generator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS71, - this, parent); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS7()); - return lg; + this->Version = VS71; } //---------------------------------------------------------------------------- @@ -94,6 +83,9 @@ void cmGlobalVisualStudio71Generator cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { + std::vector<std::string> configs; + root->GetMakefile()->GetConfigurations(configs); + // Write out the header for a SLN file this->WriteSLNHeader(fout); @@ -115,11 +107,11 @@ void cmGlobalVisualStudio71Generator // Write out the configurations information for the solution fout << "Global\n"; // Write out the configurations for the solution - this->WriteSolutionConfigurations(fout); + this->WriteSolutionConfigurations(fout, configs); fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName << ") = postSolution\n"; // Write out the configurations for all the targets in the project - this->WriteTargetConfigurations(fout, orderedProjectTargets); + this->WriteTargetConfigurations(fout, configs, orderedProjectTargets); fout << "\tEndGlobalSection\n"; if (useFolderProperty) @@ -140,11 +132,12 @@ void cmGlobalVisualStudio71Generator //---------------------------------------------------------------------------- void cmGlobalVisualStudio71Generator -::WriteSolutionConfigurations(std::ostream& fout) +::WriteSolutionConfigurations(std::ostream& fout, + std::vector<std::string> const& configs) { fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n"; - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\t" << *i << " = " << *i << "\n"; } @@ -280,14 +273,15 @@ void cmGlobalVisualStudio71Generator void cmGlobalVisualStudio71Generator ::WriteProjectConfigurations( std::ostream& fout, const std::string& name, cmTarget::TargetType, + std::vector<std::string> const& configs, const std::set<std::string>& configsPartOfDefaultBuild, std::string const& platformMapping) { const std::string& platformName = !platformMapping.empty() ? platformMapping : this->GetPlatformName(); std::string guid = this->GetGUID(name); - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << *i << "|" << platformName << std::endl; diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index ad6c153..fbb9ecc 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -23,7 +23,8 @@ class cmGlobalVisualStudio71Generator : public cmGlobalVisualStudio7Generator { public: - cmGlobalVisualStudio71Generator(const std::string& platformName = ""); + cmGlobalVisualStudio71Generator(cmake* cm, + const std::string& platformName = ""); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalVisualStudio71Generator>(); } @@ -36,9 +37,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Where does this version of Visual Studio look for macros for the * current user? Returns the empty string if this version of Visual @@ -57,7 +55,8 @@ protected: virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); - virtual void WriteSolutionConfigurations(std::ostream& fout); + virtual void WriteSolutionConfigurations( + std::ostream& fout, std::vector<std::string> const& configs); virtual void WriteProject(std::ostream& fout, const std::string& name, const char* path, cmTarget const& t); @@ -66,6 +65,7 @@ protected: cmTarget const& t); virtual void WriteProjectConfigurations( std::ostream& fout, const std::string& name, cmTarget::TargetType type, + std::vector<std::string> const& configs, const std::set<std::string>& configsPartOfDefaultBuild, const std::string& platformMapping = ""); virtual void WriteExternalProject(std::ostream& fout, diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index a2faddd..f453da1 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -15,11 +15,39 @@ #include "cmGeneratedFileStream.h" #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" +#include "cmUuid.h" #include "cmake.h" #include <cmsys/Encoding.hxx> -cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator( +//---------------------------------------------------------------------------- +static cmVS7FlagTable cmVS7ExtraFlagTable[] = +{ + // Precompiled header and related options. Note that the + // UsePrecompiledHeader entries are marked as "Continue" so that the + // corresponding PrecompiledHeaderThrough entry can be found. + {"UsePrecompiledHeader", "YX", "Automatically Generate", "2", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "", + cmVS7FlagTable::UserValueRequired}, + {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "", + cmVS7FlagTable::UserValueRequired}, + {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "true", 0}, + + // Exception handling mode. If no entries match, it will be FALSE. + {"ExceptionHandling", "GX", "enable c++ exceptions", "true", 0}, + {"ExceptionHandling", "EHsc", "enable c++ exceptions", "true", 0}, + // The EHa option does not have an IDE setting. Let it go to false, + // and have EHa passed on the command line by leaving out the table + // entry. + + {0,0,0,0,0} +}; + +cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(cmake *cm, const std::string& platformName) + : cmGlobalVisualStudioGenerator(cm) { this->IntelProjectVersion = 0; this->DevEnvCommandInitialized = false; @@ -33,6 +61,8 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator( { this->DefaultPlatformName = platformName; } + this->ExtraFlagTable = cmVS7ExtraFlagTable; + this->Version = VS7; } cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator() @@ -94,7 +124,6 @@ void cmGlobalVisualStudio7Generator // Create list of configurations requested by user's cache, if any. this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); - this->GenerateConfigurations(mf); // if this environment variable is set, then copy it to // a static cache entry. It will be used by @@ -251,12 +280,11 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand( ///! Create a local generator appropriate to this Global Generator cmLocalGenerator * -cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS7, - this, parent); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS7()); + new cmLocalVisualStudio7Generator(this, parent, snapshot); return lg; } @@ -295,50 +323,6 @@ bool cmGlobalVisualStudio7Generator::SetGeneratorPlatform(std::string const& p, return this->cmGlobalVisualStudioGenerator::SetGeneratorPlatform(p, mf); } -void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf) -{ - // process the configurations - const char* ct - = this->CMakeInstance->GetCacheDefinition("CMAKE_CONFIGURATION_TYPES"); - if ( ct ) - { - std::vector<std::string> argsOut; - cmSystemTools::ExpandListArgument(ct, argsOut); - for(std::vector<std::string>::iterator i = argsOut.begin(); - i != argsOut.end(); ++i) - { - if(std::find(this->Configurations.begin(), - this->Configurations.end(), - *i) == this->Configurations.end()) - { - this->Configurations.push_back(*i); - } - } - } - // default to at least Debug and Release - if(this->Configurations.size() == 0) - { - this->Configurations.push_back("Debug"); - this->Configurations.push_back("Release"); - } - - // Reset the entry to have a semi-colon separated list. - std::string configs = this->Configurations[0]; - for(unsigned int i=1; i < this->Configurations.size(); ++i) - { - configs += ";"; - configs += this->Configurations[i]; - } - - mf->AddCacheDefinition( - "CMAKE_CONFIGURATION_TYPES", - configs.c_str(), - "Semicolon separated list of supported configuration types, " - "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, " - "anything else will be ignored.", - cmState::STRING); -} - void cmGlobalVisualStudio7Generator::Generate() { // first do the superclass method @@ -410,6 +394,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile() void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( std::ostream& fout, + std::vector<std::string> const& configs, OrderedTargetDependSet const& projectTargets) { // loop over again and write out configurations for each target @@ -425,23 +410,22 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( const char* expath = target->GetProperty("EXTERNAL_MSPROJECT"); if(expath) { - std::set<std::string> allConfigurations(this->Configurations.begin(), - this->Configurations.end()); + std::set<std::string> allConfigurations(configs.begin(), configs.end()); const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING"); this->WriteProjectConfigurations( fout, target->GetName().c_str(), target->GetType(), - allConfigurations, mapping ? mapping : ""); + configs, allConfigurations, mapping ? mapping : ""); } else { const std::set<std::string>& configsPartOfDefaultBuild = - this->IsPartOfDefaultBuild(projectTargets, target); + this->IsPartOfDefaultBuild(configs, projectTargets, target); const char *vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { this->WriteProjectConfigurations(fout, vcprojName, target->GetType(), - configsPartOfDefaultBuild); + configs, configsPartOfDefaultBuild); } } } @@ -530,8 +514,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( cumulativePath = cumulativePath + "/" + *iter; } - - this->CreateGUID(cumulativePath.c_str()); } if (!cumulativePath.empty()) @@ -576,6 +558,9 @@ void cmGlobalVisualStudio7Generator cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { + std::vector<std::string> configs; + root->GetMakefile()->GetConfigurations(configs); + // Write out the header for a SLN file this->WriteSLNHeader(fout); @@ -599,8 +584,8 @@ void cmGlobalVisualStudio7Generator << "\tGlobalSection(SolutionConfiguration) = preSolution\n"; int c = 0; - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\tConfigName." << c << " = " << *i << "\n"; c++; @@ -621,7 +606,7 @@ void cmGlobalVisualStudio7Generator // Write out the configurations for all the targets in the project fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n"; - this->WriteTargetConfigurations(fout, orderedProjectTargets); + this->WriteTargetConfigurations(fout, configs, orderedProjectTargets); fout << "\tEndGlobalSection\n"; // Write out global sections @@ -777,14 +762,15 @@ cmGlobalVisualStudio7Generator void cmGlobalVisualStudio7Generator ::WriteProjectConfigurations( std::ostream& fout, const std::string& name, cmTarget::TargetType, + std::vector<std::string> const& configs, const std::set<std::string>& configsPartOfDefaultBuild, const std::string& platformMapping) { const std::string& platformName = !platformMapping.empty() ? platformMapping : this->GetPlatformName(); std::string guid = this->GetGUID(name); - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << *i << "|" << platformName << "\n"; @@ -902,6 +888,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout) std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target) { + std::vector<std::string> configs; + target->GetMakefile()->GetConfigurations(configs); std::string pname = target->GetName(); pname += "_UTILITY"; std::string fname = target->GetMakefile()->GetCurrentBinaryDirectory(); @@ -910,7 +898,6 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target) fname += ".vcproj"; cmGeneratedFileStream fout(fname.c_str()); fout.SetCopyIfDifferent(true); - this->CreateGUID(pname.c_str()); std::string guid = this->GetGUID(pname.c_str()); fout << @@ -925,8 +912,8 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target) "\t<Platforms><Platform Name=\"Win32\"/></Platforms>\n" "\t<Configurations>\n" ; - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\t<Configuration\n" @@ -954,47 +941,30 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target) return pname; } -std::string cmGlobalVisualStudio7Generator::GetGUID(const std::string& name) +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name) { - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; - const char* storedGUID = - this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()); - if(storedGUID) + std::string const& guidStoreName = name + "_GUID_CMAKE"; + if (const char* storedGUID = + this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str())) { return std::string(storedGUID); } - cmSystemTools::Error("Unknown Target referenced : ", - name.c_str()); - return ""; -} + // Compute a GUID that is deterministic but unique to the build tree. + std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory(); + input += "|"; + input += name; + cmUuid uuidGenerator; -void cmGlobalVisualStudio7Generator::CreateGUID(const std::string& name) -{ - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; - if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str())) - { - return; - } - std::string ret; - UUID uid; - unsigned short *uidstr; - UuidCreate(&uid); - UuidToStringW(&uid,&uidstr); - ret = cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(uidstr)); - RpcStringFreeW(&uidstr); - ret = cmSystemTools::UpperCase(ret); - this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(), - ret.c_str(), "Stored GUID", - cmState::INTERNAL); -} + std::vector<unsigned char> uuidNamespace; + uuidGenerator.StringToBinary( + "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace); -std::vector<std::string> *cmGlobalVisualStudio7Generator::GetConfigurations() -{ - return &this->Configurations; -}; + std::string guid = uuidGenerator.FromMd5(uuidNamespace, input); + + return cmSystemTools::UpperCase(guid); +} //---------------------------------------------------------------------------- void cmGlobalVisualStudio7Generator @@ -1022,6 +992,7 @@ cmGlobalVisualStudio7Generator std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( + std::vector<std::string> const& configs, OrderedTargetDependSet const& projectTargets, cmTarget const* target) { std::set<std::string> activeConfigs; @@ -1034,8 +1005,8 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( if(target->GetName() == "INSTALL") { // inspect CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD properties - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { const char* propertyValue = target->GetMakefile() ->GetDefinition("CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD"); @@ -1054,12 +1025,13 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( { return activeConfigs; } + cmGeneratorTarget* gt = this->GetGeneratorTarget(target); // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { const char* propertyValue = - target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str()); + gt->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str()); if(cmSystemTools::IsOff(propertyValue)) { activeConfigs.insert(*i); @@ -1086,36 +1058,6 @@ cmGlobalVisualStudio7Generator return false; } -//---------------------------------------------------------------------------- -static cmVS7FlagTable cmVS7ExtraFlagTable[] = -{ - // Precompiled header and related options. Note that the - // UsePrecompiledHeader entries are marked as "Continue" so that the - // corresponding PrecompiledHeaderThrough entry can be found. - {"UsePrecompiledHeader", "YX", "Automatically Generate", "2", - cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, - {"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "", - cmVS7FlagTable::UserValueRequired}, - {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3", - cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, - {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "", - cmVS7FlagTable::UserValueRequired}, - {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "true", 0}, - - // Exception handling mode. If no entries match, it will be FALSE. - {"ExceptionHandling", "GX", "enable c++ exceptions", "true", 0}, - {"ExceptionHandling", "EHsc", "enable c++ exceptions", "true", 0}, - // The EHa option does not have an IDE setting. Let it go to false, - // and have EHa passed on the command line by leaving out the table - // entry. - - {0,0,0,0,0} -}; -cmIDEFlagTable const* cmGlobalVisualStudio7Generator::GetExtraFlagTableVS7() -{ - return cmVS7ExtraFlagTable; -} - std::string cmGlobalVisualStudio7Generator::Encoding() { std::ostringstream encoding; diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 92c5f1a..931ac9c 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -26,7 +26,8 @@ struct cmIDEFlagTable; class cmGlobalVisualStudio7Generator : public cmGlobalVisualStudioGenerator { public: - cmGlobalVisualStudio7Generator(const std::string& platformName = ""); + cmGlobalVisualStudio7Generator(cmake* cm, + const std::string& platformName = ""); ~cmGlobalVisualStudio7Generator(); static cmGlobalGeneratorFactory* NewFactory() { @@ -42,7 +43,8 @@ public: std::string const& GetPlatformName() const; ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual bool SetSystemName(std::string const& s, cmMakefile* mf); @@ -78,14 +80,8 @@ public: */ virtual void OutputSLNFile(); - /** - * Get the list of configurations - */ - std::vector<std::string> *GetConfigurations(); - - ///! Create a GUID or get an existing one. - void CreateGUID(const std::string& name); - std::string GetGUID(const std::string& name); + ///! Lookup a stored GUID or compute one deterministically. + std::string GetGUID(std::string const& name); /** Append the subdirectory for the given configuration. */ virtual void AppendDirectoryForConfig(const std::string& prefix, @@ -111,6 +107,8 @@ public: // Encoding for Visual Studio files virtual std::string Encoding(); + cmIDEFlagTable const* ExtraFlagTable; + protected: virtual void Generate(); virtual const char* GetIDEVersion() { return "7.0"; } @@ -120,7 +118,6 @@ protected: static const char* ExternalProjectType(const char* location); - static cmIDEFlagTable const* GetExtraFlagTableVS7(); virtual void OutputSLNFile(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root, @@ -133,6 +130,7 @@ protected: cmTarget const&t); virtual void WriteProjectConfigurations( std::ostream& fout, const std::string& name, cmTarget::TargetType type, + std::vector<std::string> const& configs, const std::set<std::string>& configsPartOfDefaultBuild, const std::string& platformMapping = ""); virtual void WriteSLNGlobalSections(std::ostream& fout, @@ -150,10 +148,9 @@ protected: OrderedTargetDependSet const& projectTargets); virtual void WriteTargetConfigurations( std::ostream& fout, + std::vector<std::string> const& configs, OrderedTargetDependSet const& projectTargets); - void GenerateConfigurations(cmMakefile* mf); - virtual void WriteExternalProject(std::ostream& fout, const std::string& name, const char* path, @@ -164,11 +161,11 @@ protected: std::string ConvertToSolutionPath(const char* path); std::set<std::string> - IsPartOfDefaultBuild(OrderedTargetDependSet const& projectTargets, + IsPartOfDefaultBuild(std::vector<std::string> const& configs, + OrderedTargetDependSet const& projectTargets, cmTarget const* target); bool IsDependedOn(OrderedTargetDependSet const& projectTargets, cmTarget const* target); - std::vector<std::string> Configurations; std::map<std::string, std::string> GUIDMap; virtual void WriteFolders(std::ostream& fout); diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index ff9ff10..b96a799 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -24,8 +24,8 @@ class cmGlobalVisualStudio8Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const { + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { if(strncmp(name.c_str(), vs8generatorName, sizeof(vs8generatorName) - 1) != 0) { @@ -35,8 +35,7 @@ public: const char* p = name.c_str() + sizeof(vs8generatorName) - 1; if(p[0] == '\0') { - return new cmGlobalVisualStudio8Generator( - name, ""); + return new cmGlobalVisualStudio8Generator(cm, name, ""); } if(p[0] != ' ') @@ -48,8 +47,7 @@ public: if(!strcmp(p, "Win64")) { - return new cmGlobalVisualStudio8Generator( - name, "x64"); + return new cmGlobalVisualStudio8Generator(cm, name, "x64"); } cmVisualStudioWCEPlatformParser parser(p); @@ -59,8 +57,8 @@ public: return 0; } - cmGlobalVisualStudio8Generator* ret = new cmGlobalVisualStudio8Generator( - name, p); + cmGlobalVisualStudio8Generator* ret = + new cmGlobalVisualStudio8Generator(cm, name, p); ret->WindowsCEVersion = parser.GetOSVersion(); return ret; } @@ -95,12 +93,14 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio8Generator::NewFactory() } //---------------------------------------------------------------------------- -cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator( +cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(cmake* cm, const std::string& name, const std::string& platformName) - : cmGlobalVisualStudio71Generator(platformName) + : cmGlobalVisualStudio71Generator(cm, platformName) { this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms"; this->Name = name; + this->ExtraFlagTable = this->GetExtraFlagTableVS8(); + this->Version = VS8; } //---------------------------------------------------------------------------- @@ -124,18 +124,6 @@ std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand() } //---------------------------------------------------------------------------- -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalVisualStudio8Generator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8, - this, parent); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - return lg; -} - -//---------------------------------------------------------------------------- void cmGlobalVisualStudio8Generator ::EnableLanguage(std::vector<std::string>const & lang, cmMakefile *mf, bool optional) @@ -197,7 +185,6 @@ void cmGlobalVisualStudio8Generator void cmGlobalVisualStudio8Generator::Configure() { this->cmGlobalVisualStudio7Generator::Configure(); - this->CreateGUID(CMAKE_CHECK_BUILD_SYSTEM_TARGET); } //---------------------------------------------------------------------------- @@ -262,7 +249,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() return false; } - std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND"); cmCustomCommandLines noCommandLines; cmTarget* tgt = mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false, @@ -320,18 +306,13 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Create a rule to re-run CMake. std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash(); stampName += "generate.stamp"; - const char* dsprule = mf->GetRequiredDefinition("CMAKE_COMMAND"); cmCustomCommandLine commandLine; - commandLine.push_back(dsprule); + commandLine.push_back(cmSystemTools::GetCMakeCommand()); std::string argH = "-H"; - argH += lg->Convert(mf->GetHomeDirectory(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED, true); + argH += mf->GetHomeDirectory(); commandLine.push_back(argH); std::string argB = "-B"; - argB += lg->Convert(mf->GetHomeOutputDirectory(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED, true); + argB += mf->GetHomeOutputDirectory(); commandLine.push_back(argB); commandLine.push_back("--check-stamp-list"); commandLine.push_back(stampList.c_str()); @@ -387,11 +368,12 @@ void cmGlobalVisualStudio8Generator::Generate() //---------------------------------------------------------------------------- void cmGlobalVisualStudio8Generator -::WriteSolutionConfigurations(std::ostream& fout) +::WriteSolutionConfigurations(std::ostream& fout, + std::vector<std::string> const& configs) { fout << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n"; - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\t" << *i << "|" << this->GetPlatformName() << " = " << *i << "|" << this->GetPlatformName() << "\n"; @@ -404,12 +386,13 @@ void cmGlobalVisualStudio8Generator ::WriteProjectConfigurations( std::ostream& fout, const std::string& name, cmTarget::TargetType type, + std::vector<std::string> const& configs, const std::set<std::string>& configsPartOfDefaultBuild, std::string const& platformMapping) { std::string guid = this->GetGUID(name); - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { fout << "\t\t{" << guid << "}." << *i << "|" << this->GetPlatformName() << ".ActiveCfg = " << *i << "|" diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index ee5ba9f..cc02b78 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -23,7 +23,7 @@ class cmGlobalVisualStudio8Generator : public cmGlobalVisualStudio71Generator { public: - cmGlobalVisualStudio8Generator(const std::string& name, + cmGlobalVisualStudio8Generator(cmake* cm, const std::string& name, const std::string& platformName); static cmGlobalGeneratorFactory* NewFactory(); @@ -33,9 +33,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); virtual void AddPlatformDefinitions(cmMakefile* mf); @@ -84,9 +81,11 @@ protected: static cmIDEFlagTable const* GetExtraFlagTableVS8(); virtual void WriteSLNHeader(std::ostream& fout); - virtual void WriteSolutionConfigurations(std::ostream& fout); + virtual void WriteSolutionConfigurations( + std::ostream& fout, std::vector<std::string> const& configs); virtual void WriteProjectConfigurations( std::ostream& fout, const std::string& name, cmTarget::TargetType type, + std::vector<std::string> const& configs, const std::set<std::string>& configsPartOfDefaultBuild, const std::string& platformMapping = ""); virtual bool ComputeTargetDepends(); diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index 8adde23..d98793a 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -22,8 +22,8 @@ class cmGlobalVisualStudio9Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const { + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const { if(strncmp(name.c_str(), vs9generatorName, sizeof(vs9generatorName) - 1) != 0) { @@ -33,8 +33,7 @@ public: const char* p = name.c_str() + sizeof(vs9generatorName) - 1; if(p[0] == '\0') { - return new cmGlobalVisualStudio9Generator( - name, ""); + return new cmGlobalVisualStudio9Generator(cm, name, ""); } if(p[0] != ' ') @@ -46,14 +45,12 @@ public: if(!strcmp(p, "IA64")) { - return new cmGlobalVisualStudio9Generator( - name, "Itanium"); + return new cmGlobalVisualStudio9Generator(cm, name, "Itanium"); } if(!strcmp(p, "Win64")) { - return new cmGlobalVisualStudio9Generator( - name, "x64"); + return new cmGlobalVisualStudio9Generator(cm, name, "x64"); } cmVisualStudioWCEPlatformParser parser(p); @@ -63,8 +60,8 @@ public: return 0; } - cmGlobalVisualStudio9Generator* ret = new cmGlobalVisualStudio9Generator( - name, p); + cmGlobalVisualStudio9Generator* ret = + new cmGlobalVisualStudio9Generator(cm, name, p); ret->WindowsCEVersion = parser.GetOSVersion(); return ret; } @@ -100,10 +97,11 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory() } //---------------------------------------------------------------------------- -cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator( +cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(cmake* cm, const std::string& name, const std::string& platformName) - : cmGlobalVisualStudio8Generator(name, platformName) + : cmGlobalVisualStudio8Generator(cm, name, platformName) { + this->Version = VS9; } //---------------------------------------------------------------------------- @@ -113,17 +111,6 @@ void cmGlobalVisualStudio9Generator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 2008\n"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalVisualStudio9Generator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalVisualStudio7Generator *lg - = new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9, - this, parent); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - return lg; -} - //---------------------------------------------------------------------------- std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory() { diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h index 97b7804..e25a4be 100644 --- a/Source/cmGlobalVisualStudio9Generator.h +++ b/Source/cmGlobalVisualStudio9Generator.h @@ -24,13 +24,10 @@ class cmGlobalVisualStudio9Generator : public cmGlobalVisualStudio8Generator { public: - cmGlobalVisualStudio9Generator(const std::string& name, + cmGlobalVisualStudio9Generator(cmake* cm, const std::string& name, const std::string& platformName); static cmGlobalGeneratorFactory* NewFactory(); - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index b74ba6f..585d19a 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -21,10 +21,11 @@ #include <cmsys/Encoding.hxx> //---------------------------------------------------------------------------- -cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator() +cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm) + : cmGlobalGenerator(cm) { - this->WindowsShell = true; - this->WindowsVSIDE = true; + cm->GetState()->SetWindowsShell(true); + cm->GetState()->SetWindowsVSIDE(true); } //---------------------------------------------------------------------------- @@ -33,6 +34,19 @@ cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator() } //---------------------------------------------------------------------------- +cmGlobalVisualStudioGenerator::VSVersion +cmGlobalVisualStudioGenerator::GetVersion() const +{ + return this->Version; +} + +//---------------------------------------------------------------------------- +void cmGlobalVisualStudioGenerator::SetVersion(VSVersion v) +{ + this->Version = v; +} + +//---------------------------------------------------------------------------- std::string cmGlobalVisualStudioGenerator::GetRegistryBase() { return cmGlobalVisualStudioGenerator::GetRegistryBase( diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index cb54132..69b4564 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -23,9 +23,27 @@ class cmGlobalVisualStudioGenerator : public cmGlobalGenerator { public: - cmGlobalVisualStudioGenerator(); + /** Known versions of Visual Studio. */ + enum VSVersion + { + VS6 = 60, + VS7 = 70, + VS71 = 71, + VS8 = 80, + VS9 = 90, + VS10 = 100, + VS11 = 110, + VS12 = 120, + /* VS13 = 130 was skipped */ + VS14 = 140 + }; + + cmGlobalVisualStudioGenerator(cmake* cm); virtual ~cmGlobalVisualStudioGenerator(); + VSVersion GetVersion() const; + void SetVersion(VSVersion v); + /** * Configure CMake's Visual Studio macros file into the user's Visual * Studio macros directory. @@ -107,6 +125,9 @@ protected: typedef std::map<cmTarget const*, std::string> UtilityDependsMap; UtilityDependsMap UtilityDepends; +protected: + VSVersion Version; + private: virtual std::string GetVSMakeProgram() = 0; void PrintCompilerAdvice(std::ostream&, std::string const&, diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 181178f..153773f 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -13,7 +13,8 @@ #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" -cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator() +cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm) + : cmGlobalUnixMakefileGenerator3(cm) { this->FindMakeProgramFile = "CMakeFindWMake.cmake"; #ifdef _WIN32 @@ -23,9 +24,13 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator() this->NeedSymbolicMark = true; this->EmptyRuleHackCommand = "@cd ."; #ifdef _WIN32 - this->WindowsShell = true; + cm->GetState()->SetWindowsShell(true); #endif - this->WatcomWMake = true; + cm->GetState()->SetWatcomWMake(true); + this->IncludeDirective = "!include"; + this->DefineWindowsNULL = true; + this->UnixCD = false; + this->MakeSilentFlag = "-h"; } void cmGlobalWatcomWMakeGenerator @@ -44,21 +49,6 @@ void cmGlobalWatcomWMakeGenerator this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator * -cmGlobalWatcomWMakeGenerator::CreateLocalGenerator(cmLocalGenerator* parent) -{ - cmLocalUnixMakefileGenerator3* lg - = new cmLocalUnixMakefileGenerator3(this, parent); - lg->SetDefineWindowsNULL(true); - lg->SetMakeSilentFlag("-h"); - lg->SetIgnoreLibPrefix(true); - lg->SetPassMakeflags(false); - lg->SetUnixCD(false); - lg->SetIncludeDirective("!include"); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalWatcomWMakeGenerator ::GetDocumentation(cmDocumentationEntry& entry) diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index 3af2f9d..4bfcf06 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -22,7 +22,7 @@ class cmGlobalWatcomWMakeGenerator : public cmGlobalUnixMakefileGenerator3 { public: - cmGlobalWatcomWMakeGenerator(); + cmGlobalWatcomWMakeGenerator(cmake* cm); static cmGlobalGeneratorFactory* NewFactory() { return new cmGlobalGeneratorSimpleFactory <cmGlobalWatcomWMakeGenerator>(); } @@ -34,9 +34,6 @@ public: /** Get the documentation entry for this generator. */ static void GetDocumentation(cmDocumentationEntry& entry); - ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); - /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4a7411c..1301e3e 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -117,8 +117,8 @@ public: class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& name) const; + virtual cmGlobalGenerator* + CreateGlobalGenerator(const std::string& name, cmake* cm) const; virtual void GetDocumentation(cmDocumentationEntry& entry) const { cmGlobalXCodeGenerator::GetDocumentation(entry); } @@ -128,7 +128,9 @@ public: }; //---------------------------------------------------------------------------- -cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version) +cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(cmake* cm, + std::string const& version) + : cmGlobalGenerator(cm) { this->VersionString = version; @@ -154,7 +156,7 @@ cmGlobalGeneratorFactory* cmGlobalXCodeGenerator::NewFactory() //---------------------------------------------------------------------------- cmGlobalGenerator* cmGlobalXCodeGenerator::Factory -::CreateGlobalGenerator(const std::string& name) const +::CreateGlobalGenerator(const std::string& name, cmake* cm) const { if (name != GetActualName()) return 0; @@ -187,7 +189,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory ("/Developer/Applications/Xcode.app/Contents/version.plist"); } cmsys::auto_ptr<cmGlobalXCodeGenerator> - gg(new cmGlobalXCodeGenerator(parser.Version)); + gg(new cmGlobalXCodeGenerator(cm, parser.Version)); if (gg->XcodeVersion == 20) { cmSystemTools::Message("Xcode 2.0 not really supported by cmake, " @@ -198,7 +200,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory #else std::cerr << "CMake should be built with cmake to use Xcode, " "default to Xcode 1.5\n"; - return new cmGlobalXCodeGenerator; + return new cmGlobalXCodeGenerator(cm); #endif } @@ -369,9 +371,10 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( //---------------------------------------------------------------------------- ///! Create a local generator appropriate to this Global Generator cmLocalGenerator * -cmGlobalXCodeGenerator::CreateLocalGenerator(cmLocalGenerator* parent) +cmGlobalXCodeGenerator::CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot) { - return new cmLocalXCodeGenerator(this, parent); + return new cmLocalXCodeGenerator(this, parent, snapshot); } //---------------------------------------------------------------------------- @@ -582,8 +585,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( { makefileStream << "\\\n" << this->ConvertToRelativeForMake(i->c_str()); } - std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND"); - makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str()) + makefileStream << "\n\t" << + this->ConvertToRelativeForMake(cmSystemTools::GetCMakeCommand().c_str()) << " -H" << this->ConvertToRelativeForMake( mf->GetHomeDirectory()) << " -B" << this->ConvertToRelativeForMake( @@ -1447,7 +1450,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, { cmCustomCommandLines cmd; cmd.resize(1); - cmd[0].push_back(this->CurrentMakefile->GetDefinition("CMAKE_COMMAND")); + cmd[0].push_back(cmSystemTools::GetCMakeCommand()); cmd[0].push_back("-E"); cmd[0].push_back("cmake_symlink_library"); std::string str_file = "$<TARGET_FILE:"; @@ -3801,33 +3804,13 @@ void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry) //---------------------------------------------------------------------------- std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p) { - if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") ) - { - return cmSystemTools::ConvertToOutputPath(p); - } - else - { - std::string ret = - this->CurrentLocalGenerator-> - ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p); - return cmSystemTools::ConvertToOutputPath(ret.c_str()); - } + return cmSystemTools::ConvertToOutputPath(p); } //---------------------------------------------------------------------------- std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p) { - if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") ) - { - return cmSystemTools::ConvertToOutputPath(p); - } - else - { - std::string ret = - this->CurrentLocalGenerator-> - ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p); - return cmSystemTools::ConvertToOutputPath(ret.c_str()); - } + return cmSystemTools::ConvertToOutputPath(p); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 6c911a4..c36e4af 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -29,7 +29,7 @@ class cmSourceGroup; class cmGlobalXCodeGenerator : public cmGlobalGenerator { public: - cmGlobalXCodeGenerator(std::string const& version); + cmGlobalXCodeGenerator(cmake* cm, std::string const& version); static cmGlobalGeneratorFactory* NewFactory(); ///! Get the name for the generator. @@ -41,7 +41,8 @@ public: static void GetDocumentation(cmDocumentationEntry& entry); ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent = 0); + virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent, + cmState::Snapshot snapshot); /** * Try to determine system information such as shared library diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 99542a9..fa29b4f 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -48,6 +48,7 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>& ,GraphName("GG") ,GraphHeader("node [\n fontsize = \"12\"\n];") ,GraphNodePrefix("node") +,LocalGenerators(localGenerators) ,GenerateForExecutables(true) ,GenerateForStaticLibs(true) ,GenerateForSharedLibs(true) @@ -55,7 +56,6 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>& ,GenerateForExternals(true) ,GeneratePerTarget(true) ,GenerateDependers(true) -,LocalGenerators(localGenerators) ,HaveTargetsAndLibs(false) { } @@ -65,9 +65,10 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, const char* fallbackSettingsFileName) { cmake cm; - cmGlobalGenerator ggi; - ggi.SetCMakeInstance(&cm); - cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator()); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cmGlobalGenerator ggi(&cm); + cmsys::auto_ptr<cmLocalGenerator> lg(ggi.MakeLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); const char* inFileName = settingsFileName; diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h index a7acd0e..64de684 100644 --- a/Source/cmGraphVizWriter.h +++ b/Source/cmGraphVizWriter.h @@ -69,14 +69,6 @@ protected: std::string GraphHeader; std::string GraphNodePrefix; - bool GenerateForExecutables; - bool GenerateForStaticLibs; - bool GenerateForSharedLibs; - bool GenerateForModuleLibs; - bool GenerateForExternals; - bool GeneratePerTarget; - bool GenerateDependers; - std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex; const std::vector<cmLocalGenerator*>& LocalGenerators; @@ -85,6 +77,13 @@ protected: // maps from the actual target names to node names in dot: std::map<std::string, std::string> TargetNamesNodes; + bool GenerateForExecutables; + bool GenerateForStaticLibs; + bool GenerateForSharedLibs; + bool GenerateForModuleLibs; + bool GenerateForExternals; + bool GeneratePerTarget; + bool GenerateDependers; bool HaveTargetsAndLibs; }; diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 3551f83..20448c1 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -27,7 +27,7 @@ static std::string cmIfCommandError( i != args.end(); ++i) { err += " "; - err += cmLocalGenerator::EscapeForCMake(i->GetValue()); + err += cmOutputConverter::EscapeForCMake(i->GetValue()); } err += "\n"; return err; @@ -92,10 +92,6 @@ IsFunctionBlocked(const cmListFileFunction& lff, } else { - // Place this call on the call stack. - cmMakefileCall stack_manager(&mf, this->Functions[c], status); - static_cast<void>(stack_manager); - // if trace is enabled, print the evaluated "elseif" statement if(mf.GetCMakeInstance()->GetTrace()) { @@ -119,7 +115,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, { std::string err = cmIfCommandError(expandedArguments); err += errorString; - mf.IssueMessage(messType, err); + cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]); + mf.GetCMakeInstance()->IssueMessage(messType, err, bt); if (messType == cmake::FATAL_ERROR) { cmSystemTools::SetFatalErrorOccured(); diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 28c27c2..ff2c6e5 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -28,9 +28,11 @@ cmInstallFilesGenerator bool optional): cmInstallGenerator(dest, configurations, component, message), Makefile(mf), - Files(files), Programs(programs), + Files(files), FilePermissions(file_permissions), - Rename(rename), Optional(optional) + Rename(rename), + Programs(programs), + Optional(optional) { // We need per-config actions if any files have generator expressions. for(std::vector<std::string>::const_iterator i = files.begin(); diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h index 0dbd712..bf482d6 100644 --- a/Source/cmInstallFilesGenerator.h +++ b/Source/cmInstallFilesGenerator.h @@ -43,9 +43,9 @@ protected: cmMakefile* Makefile; std::vector<std::string> Files; - bool Programs; std::string FilePermissions; std::string Rename; + bool Programs; bool Optional; }; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 082a78c..5115788 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -29,7 +29,9 @@ cmInstallTargetGenerator MessageLevel message, bool optional): cmInstallGenerator(dest, configurations, component, message), Target(&t), - ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) + FilePermissions(file_permissions), + ImportLibrary(implib), + Optional(optional) { this->ActionsPerConfig = true; this->NamelinkMode = NamelinkModeNone; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 075c8a4..db69220 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -14,7 +14,6 @@ #include "cmInstallGenerator.h" #include "cmTarget.h" -#include "cmGeneratorTarget.h" /** \class cmInstallTargetGenerator * \brief Generate target installation rules. @@ -100,11 +99,10 @@ protected: const std::string& toDestDirPath); cmTarget* Target; - bool ImportLibrary; std::string FilePermissions; - bool Optional; NamelinkModeType NamelinkMode; - cmGeneratorTarget* GeneratorTarget; + bool ImportLibrary; + bool Optional; }; #endif diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h new file mode 100644 index 0000000..d2339c4 --- /dev/null +++ b/Source/cmLinkedTree.h @@ -0,0 +1,164 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmLinkedTree_h +#define cmLinkedTree_h + +#include "cmStandardIncludes.h" + +#include <assert.h> + +/** + @brief A adaptor for traversing a tree structure in a vector + + This class is not intended to be wholly generic like a standard library + container adaptor. Mostly it exists to facilitate code sharing for the + needs of the cmState. For example, the Truncate() method is a specific + requirement of the cmState. + + An empty cmLinkedTree provides a Root() method, and an Extend() method, + each of which return iterators. A Tree can be built up by extending + from the root, and then extending from any other iterator. + + An iterator resulting from this tree construction can be + forward-only-iterated toward the root. Extending the tree never + invalidates existing iterators. + */ +template<typename T> +class cmLinkedTree +{ + typedef typename std::vector<T>::size_type PositionType; + typedef T* PointerType; + typedef T& ReferenceType; +public: + class iterator : public std::iterator<std::forward_iterator_tag, T> + { + friend class cmLinkedTree; + cmLinkedTree* Tree; + + // The Position is always 'one past the end'. + PositionType Position; + + iterator(cmLinkedTree* tree, PositionType pos) + : Tree(tree), Position(pos) + { + + } + + public: + iterator() + : Tree(0), Position(0) + { + + } + + void operator++() + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + this->Position = this->Tree->UpPositions[this->Position - 1]; + } + + PointerType operator->() const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + return this->Tree->GetPointer(this->Position - 1); + } + + PointerType operator->() + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + return this->Tree->GetPointer(this->Position - 1); + } + + bool operator==(iterator other) const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Tree == other.Tree); + return this->Position == other.Position; + } + + bool operator!=(iterator other) const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + return !(*this == other); + } + + bool IsValid() const + { + if (!this->Tree) + { + return false; + } + return this->Position <= this->Tree->Data.size(); + } + }; + + iterator Root() const + { + return iterator(const_cast<cmLinkedTree*>(this), 0); + } + + iterator Extend(iterator it) + { + return Extend_impl(it, T()); + } + + iterator Extend(iterator it, T t) + { + return Extend_impl(it, t); + } + + iterator Truncate() + { + assert(this->UpPositions.size() > 0); + this->UpPositions.erase(this->UpPositions.begin() + 1, + this->UpPositions.end()); + assert(this->Data.size() > 0); + this->Data.erase(this->Data.begin() + 1, this->Data.end()); + return iterator(this, 1); + } + +private: + T& GetReference(PositionType pos) + { + return this->Data[pos]; + } + + T* GetPointer(PositionType pos) + { + return &this->Data[pos]; + } + + iterator Extend_impl(iterator it, T t) + { + assert(this->UpPositions.size() == this->Data.size()); + assert(it.Position <= this->UpPositions.size()); + this->UpPositions.push_back(it.Position); + this->Data.push_back(t); + return iterator(this, this->UpPositions.size()); + } + + std::vector<T> Data; + std::vector<PositionType> UpPositions; +}; + +#endif diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index ddcea9b..ca58314 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -400,22 +400,42 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token, } } -//---------------------------------------------------------------------------- -void cmListFileBacktrace::MakeRelative() +void cmListFileBacktrace::Append(cmListFileContext const& context) +{ + this->push_back(context); +} + +void cmListFileBacktrace::PrintTitle(std::ostream& out) { - if (this->Relative) + if (this->empty()) { return; } - for (cmListFileBacktrace::iterator i = this->begin(); - i != this->end(); ++i) + + cmOutputConverter converter(this->Snapshot); + cmListFileContext lfc = this->front(); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); + out << (lfc.Line ? " at " : " in ") << lfc; +} + +void cmListFileBacktrace::PrintCallStack(std::ostream& out) +{ + if (size() <= 1) { - i->FilePath = this->LocalGenerator->Convert(i->FilePath, - cmLocalGenerator::HOME); + return; } - this->Relative = true; -} + cmOutputConverter converter(this->Snapshot); + const_iterator i = this->begin() + 1; + out << "Call Stack (most recent call first):\n"; + while(i != this->end()) + { + cmListFileContext lfc = *i; + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); + out << " " << lfc << "\n"; + ++i; + } +} //---------------------------------------------------------------------------- std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc) @@ -431,3 +451,22 @@ std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc) } return os; } + +bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs) +{ + if(lhs.Line != rhs.Line) + { + return lhs.Line < rhs.Line; + } + return lhs.FilePath < rhs.FilePath; +} + +bool operator==(const cmListFileContext& lhs, const cmListFileContext& rhs) +{ + return lhs.Line == rhs.Line && lhs.FilePath == rhs.FilePath; +} + +bool operator!=(const cmListFileContext& lhs, const cmListFileContext& rhs) +{ + return !(lhs == rhs); +} diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 544ff1b..4002d94 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -14,7 +14,7 @@ #include "cmStandardIncludes.h" -class cmLocalGenerator; +#include "cmState.h" /** \class cmListFileCache * \brief A class to cache list file contents. @@ -62,25 +62,29 @@ struct cmListFileContext }; std::ostream& operator<<(std::ostream&, cmListFileContext const&); +bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs); +bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs); +bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs); struct cmListFileFunction: public cmListFileContext { std::vector<cmListFileArgument> Arguments; }; -class cmListFileBacktrace: public std::vector<cmListFileContext> +class cmListFileBacktrace: private std::vector<cmListFileContext> { public: - cmListFileBacktrace(cmLocalGenerator* localGen) - : LocalGenerator(localGen) - , Relative(localGen ? false : true) + cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot()) + : Snapshot(snapshot) { } - void MakeRelative(); + void Append(cmListFileContext const& context); + + void PrintTitle(std::ostream& out); + void PrintCallStack(std::ostream& out); private: - cmLocalGenerator* LocalGenerator; - bool Relative; + cmState::Snapshot Snapshot; }; struct cmListFile diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 74362ae..5ed53d0 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -44,30 +44,21 @@ #endif cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, - cmLocalGenerator* parent) + cmLocalGenerator* parent, + cmState::Snapshot snapshot) + : cmOutputConverter(snapshot), StateSnapshot(snapshot) { + assert(snapshot.IsValid()); this->GlobalGenerator = gg; this->Parent = parent; if (parent) { parent->AddChild(this); - this->StateSnapshot = - this->GetState()->CreateSnapshot(parent->StateSnapshot); - } - else - { - this->StateSnapshot = - this->GetState()->CreateSnapshot(cmState::Snapshot(this->GetState())); } + this->Makefile = new cmMakefile(this); - this->LinkScriptShell = false; - this->IgnoreLibPrefix = false; - this->UseRelativePaths = false; - this->Configured = false; this->EmitUniversalBinaryFlags = true; - this->RelativePathsConfigured = false; - this->PathConversionsSetup = false; this->BackwardsCompatibility = 0; this->BackwardsCompatibilityFinal = false; } @@ -79,71 +70,7 @@ cmLocalGenerator::~cmLocalGenerator() bool cmLocalGenerator::IsRootMakefile() const { - return !this->GetParent(); -} - -//---------------------------------------------------------------------------- -class cmLocalGeneratorCurrent -{ - cmGlobalGenerator* GG; - cmLocalGenerator* LG; -public: - cmLocalGeneratorCurrent(cmLocalGenerator* lg) - { - this->GG = lg->GetGlobalGenerator(); - this->LG = this->GG->GetCurrentLocalGenerator(); - this->GG->SetCurrentLocalGenerator(lg); -#if defined(CMAKE_BUILD_WITH_CMAKE) - this->GG->GetFileLockPool().PushFileScope(); -#endif - } - ~cmLocalGeneratorCurrent() - { -#if defined(CMAKE_BUILD_WITH_CMAKE) - this->GG->GetFileLockPool().PopFileScope(); -#endif - this->GG->SetCurrentLocalGenerator(this->LG); - } -}; - -//---------------------------------------------------------------------------- -void cmLocalGenerator::Configure() -{ - // Manage the global generator's current local generator. - cmLocalGeneratorCurrent clg(this); - static_cast<void>(clg); - - // make sure the CMakeFiles dir is there - std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory(); - filesDir += cmake::GetCMakeFilesDirectory(); - cmSystemTools::MakeDirectory(filesDir.c_str()); - - // find & read the list file - this->ReadInputFile(); - - // at the end of the ReadListFile handle any old style subdirs - // first get all the subdirectories - std::vector<cmLocalGenerator *> subdirs = this->GetChildren(); - - // for each subdir recurse - std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - if (!(*sdi)->Configured) - { - this->Makefile->ConfigureSubDirectory(*sdi); - } - } - - this->Makefile->AddCMakeDependFilesFromUser(); - - // Check whether relative paths should be used for optionally - // relative paths. - this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS"); - - this->ComputeObjectMaxPath(); - - this->Configured = true; + return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid(); } //---------------------------------------------------------------------------- @@ -186,39 +113,6 @@ void cmLocalGenerator::ComputeObjectMaxPath() this->ObjectMaxPathViolations.clear(); } -//---------------------------------------------------------------------------- -void cmLocalGenerator::ReadInputFile() -{ - // Look for the CMakeLists.txt file. - std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory(); - currentStart += "/CMakeLists.txt"; - assert(cmSystemTools::FileExists(currentStart.c_str(), true)); - this->Makefile->ProcessBuildsystemFile(currentStart.c_str()); -} - -void cmLocalGenerator::SetupPathConversions() -{ - // Setup the current output directory components for use by - // Convert - std::string outdir; - outdir = - cmSystemTools::CollapseFullPath(this->GetState()->GetSourceDirectory()); - cmSystemTools::SplitPath(outdir, this->HomeDirectoryComponents); - outdir = cmSystemTools::CollapseFullPath( - this->StateSnapshot.GetCurrentSourceDirectory()); - cmSystemTools::SplitPath(outdir, this->StartDirectoryComponents); - - outdir = cmSystemTools::CollapseFullPath - (this->GetState()->GetBinaryDirectory()); - cmSystemTools::SplitPath(outdir, - this->HomeOutputDirectoryComponents); - - outdir = cmSystemTools::CollapseFullPath - (this->StateSnapshot.GetCurrentBinaryDirectory()); - cmSystemTools::SplitPath(outdir, - this->StartOutputDirectoryComponents); -} - void cmLocalGenerator::ConfigureFinalPass() { this->Makefile->ConfigureFinalPass(); @@ -390,12 +284,8 @@ void cmLocalGenerator::GenerateInstallRules() // Create the install script file. std::string file = this->StateSnapshot.GetCurrentBinaryDirectory(); std::string homedir = this->GetState()->GetBinaryDirectory(); - std::string currdir = this->StateSnapshot.GetCurrentBinaryDirectory(); - cmSystemTools::ConvertToUnixSlashes(file); - cmSystemTools::ConvertToUnixSlashes(homedir); - cmSystemTools::ConvertToUnixSlashes(currdir); int toplevel_install = 0; - if ( currdir == homedir ) + if (file == homedir) { toplevel_install = 1; } @@ -559,7 +449,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, objectDir = this->Convert(objectDir,START_OUTPUT,SHELL); std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL); std::string sourceFile = - this->Convert(source.GetFullPath(),START_OUTPUT,SHELL,true); + this->ConvertToOutputFormat(source.GetFullPath(), SHELL); std::string varString = "CMAKE_"; varString += lang; varString += "_COMPILE_OBJECT"; @@ -1031,12 +921,10 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, } if(variable == "CMAKE_COMMAND") { - const char* cmcommand = - this->GetMakefile()->GetDefinition("CMAKE_COMMAND"); - return this->Convert(cmcommand, FULL, SHELL); + return this->Convert(cmSystemTools::GetCMakeCommand(), FULL, SHELL); } - std::vector<std::string> enabledLanguages; - this->GlobalGenerator->GetEnabledLanguages(enabledLanguages); + std::vector<std::string> enabledLanguages = + this->GetState()->GetEnabledLanguages(); // loop over language specific replace variables int pos = 0; while(ruleReplaceVars[pos]) @@ -1208,56 +1096,6 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target, //---------------------------------------------------------------------------- std::string -cmLocalGenerator::ConvertToOutputForExistingCommon(const std::string& remote, - std::string const& result, - OutputFormat format) -{ - // If this is a windows shell, the result has a space, and the path - // already exists, we can use a short-path to reference it without a - // space. - if(this->GlobalGenerator->WindowsShell && result.find(' ') != result.npos && - cmSystemTools::FileExists(remote.c_str())) - { - std::string tmp; - if(cmSystemTools::GetShortPath(remote, tmp)) - { - return this->Convert(tmp, NONE, format, true); - } - } - - // Otherwise, leave it unchanged. - return result; -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOutputForExisting(const std::string& remote, - RelativeRoot local, - OutputFormat format) -{ - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); - - // Consider short-path. - return this->ConvertToOutputForExistingCommon(remote, result, format); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote, - const std::string& local, - OutputFormat format) -{ - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); - - // Consider short-path. - const char* remotePath = this->GetRelativeRootPath(remote); - return this->ConvertToOutputForExistingCommon(remotePath, result, format); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::ConvertToIncludeReference(std::string const& path, OutputFormat format, bool forceFullPaths) @@ -1355,8 +1193,7 @@ std::string cmLocalGenerator::GetIncludeFlags( { includeFlags << fwSearchFlag; } - includeFlags << this->Convert(frameworkDir, START_OUTPUT, - shellFormat, true) + includeFlags << this->ConvertToOutputFormat(frameworkDir, shellFormat) << " "; } continue; @@ -1878,7 +1715,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, fdi != fwDirs.end(); ++fdi) { frameworkPath += fwSearchFlag; - frameworkPath += this->Convert(*fdi, NONE, shellFormat, false); + frameworkPath += this->Convert(*fdi, NONE, shellFormat); frameworkPath += " "; } } @@ -1932,7 +1769,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, ri != runtimeDirs.end(); ++ri) { rpath += cli.GetRuntimeFlag(); - rpath += this->Convert(*ri, NONE, shellFormat, false); + rpath += this->Convert(*ri, NONE, shellFormat); rpath += " "; } fout << rpath; @@ -2288,7 +2125,8 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target, static void AddVisibilityCompileOption(std::string &flags, cmTarget const* target, cmLocalGenerator *lg, - const std::string& lang) + const std::string& lang, + std::string* warnCMP0063) { std::string l(lang); std::string compileOption = "CMAKE_" + l + "_COMPILE_OPTIONS_VISIBILITY"; @@ -2304,6 +2142,11 @@ static void AddVisibilityCompileOption(std::string &flags, { return; } + if (warnCMP0063) + { + *warnCMP0063 += " " + flagDefine + "\n"; + return; + } if (strcmp(prop, "hidden") != 0 && strcmp(prop, "default") != 0 && strcmp(prop, "protected") != 0 @@ -2321,7 +2164,8 @@ static void AddVisibilityCompileOption(std::string &flags, static void AddInlineVisibilityCompileOption(std::string &flags, cmTarget const* target, - cmLocalGenerator *lg) + cmLocalGenerator *lg, + std::string* warnCMP0063) { std::string compileOption = "CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN"; @@ -2336,6 +2180,11 @@ static void AddInlineVisibilityCompileOption(std::string &flags, { return; } + if (warnCMP0063) + { + *warnCMP0063 += " VISIBILITY_INLINES_HIDDEN\n"; + return; + } lg->AppendFlags(flags, opt); } @@ -2344,25 +2193,49 @@ void cmLocalGenerator ::AddVisibilityPresetFlags(std::string &flags, cmTarget const* target, const std::string& lang) { - int targetType = target->GetType(); - bool suitableTarget = ((targetType == cmTarget::SHARED_LIBRARY) - || (targetType == cmTarget::MODULE_LIBRARY) - || (target->IsExecutableWithExports())); - - if (!suitableTarget) + if (lang.empty()) { return; } - if (lang.empty()) + std::string warnCMP0063; + std::string *pWarnCMP0063 = 0; + if (target->GetType() != cmTarget::SHARED_LIBRARY && + target->GetType() != cmTarget::MODULE_LIBRARY && + !target->IsExecutableWithExports()) { - return; + switch (target->GetPolicyStatusCMP0063()) + { + case cmPolicies::OLD: + return; + case cmPolicies::WARN: + pWarnCMP0063 = &warnCMP0063; + break; + default: + break; + } } - AddVisibilityCompileOption(flags, target, this, lang); + + AddVisibilityCompileOption(flags, target, this, lang, pWarnCMP0063); if(lang == "CXX") { - AddInlineVisibilityCompileOption(flags, target, this); + AddInlineVisibilityCompileOption(flags, target, this, pWarnCMP0063); + } + + if (!warnCMP0063.empty() && + this->WarnCMP0063.insert(target).second) + { + std::ostringstream w; + w << + cmPolicies::GetPolicyWarning(cmPolicies::CMP0063) << "\n" + "Target \"" << target->GetName() << "\" of " + "type \"" << cmTarget::GetTargetTypeName(target->GetType()) << "\" " + "has the following visibility properties set for " << lang << ":\n" << + warnCMP0063 << + "For compatibility CMake is not honoring them for this target."; + target->GetMakefile()->GetCMakeInstance() + ->IssueMessage(cmake::AUTHOR_WARNING, w.str(), target->GetBacktrace()); } } @@ -2587,7 +2460,7 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines, { // Append the definition with proper escaping. std::string def = dflag; - if(this->GlobalGenerator->WatcomWMake) + if(this->GetState()->UseWatcomWMake()) { // The Watcom compiler does its own command line parsing instead // of using the windows shell rules. Definitions are one of @@ -2647,6 +2520,33 @@ void cmLocalGenerator::AppendFeatureOptions( } //---------------------------------------------------------------------------- +const char* cmLocalGenerator::GetFeature(const std::string& feature, + const std::string& config) +{ + // TODO: Define accumulation policy for features (prepend, append, replace). + // Currently we always replace. + if(!config.empty()) + { + std::string featureConfig = feature; + featureConfig += "_"; + featureConfig += cmSystemTools::UpperCase(config); + if(const char* value = this->Makefile->GetProperty(featureConfig)) + { + return value; + } + } + if(const char* value = this->Makefile->GetProperty(feature)) + { + return value; + } + if(cmLocalGenerator* parent = this->GetParent()) + { + return parent->GetFeature(feature, config); + } + return 0; +} + +//---------------------------------------------------------------------------- std::string cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg, const char* default_comment) @@ -2678,349 +2578,6 @@ cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg, } //---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOptionallyRelativeOutputPath( - const std::string& remote) -{ - return this->Convert(remote, START_OUTPUT, SHELL, true); -} - -//---------------------------------------------------------------------------- -const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot) -{ - switch (relroot) - { - case HOME: return this->GetState()->GetSourceDirectory(); - case START: return this->StateSnapshot.GetCurrentSourceDirectory(); - case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory(); - case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory(); - default: break; - } - return 0; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::Convert(const std::string& source, - RelativeRoot relative, - OutputFormat output, - bool optional) -{ - // Make sure the relative path conversion components are set. - if(!this->PathConversionsSetup) - { - this->SetupPathConversions(); - this->PathConversionsSetup = true; - } - - // Convert the path to a relative path. - std::string result = source; - - if (!optional || this->UseRelativePaths) - { - switch (relative) - { - case HOME: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath(this->HomeDirectoryComponents, - result); - break; - case START: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath(this->StartDirectoryComponents, - result); - break; - case HOME_OUTPUT: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = - this->ConvertToRelativePath(this->HomeOutputDirectoryComponents, - result); - break; - case START_OUTPUT: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = - this->ConvertToRelativePath(this->StartOutputDirectoryComponents, - result); - break; - case FULL: - result = cmSystemTools::CollapseFullPath(result); - break; - case NONE: - break; - } - } - return this->ConvertToOutputFormat(result, output); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source, - OutputFormat output) -{ - std::string result = source; - // Convert it to an output path. - if (output == MAKERULE) - { - result = cmSystemTools::ConvertToOutputPath(result.c_str()); - } - else if(output == SHELL || output == WATCOMQUOTE) - { - // For the MSYS shell convert drive letters to posix paths, so - // that c:/some/path becomes /c/some/path. This is needed to - // avoid problems with the shell path translation. - if(this->GlobalGenerator->MSYSShell && !this->LinkScriptShell) - { - if(result.size() > 2 && result[1] == ':') - { - result[1] = result[0]; - result[0] = '/'; - } - } - if(this->GlobalGenerator->WindowsShell) - { - std::replace(result.begin(), result.end(), '/', '\\'); - } - result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE); - } - else if(output == RESPONSE) - { - result = this->EscapeForShell(result, false, false, false); - } - return result; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::Convert(RelativeRoot remote, - const std::string& local, - OutputFormat output, - bool optional) -{ - const char* remotePath = this->GetRelativeRootPath(remote); - - // The relative root must have a path (i.e. not FULL or NONE) - assert(remotePath != 0); - - if(!local.empty() && (!optional || this->UseRelativePaths)) - { - std::vector<std::string> components; - cmSystemTools::SplitPath(local, components); - std::string result = this->ConvertToRelativePath(components, remotePath); - return this->ConvertToOutputFormat(result, output); - } - else - { - return this->ConvertToOutputFormat(remotePath, output); - } -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::FindRelativePathTopSource() -{ - cmState::Snapshot snapshot = this->StateSnapshot; - std::vector<cmState::Snapshot> snapshots; - snapshots.push_back(snapshot); - while (true) - { - snapshot = snapshot.GetParent(); - if (snapshot.IsValid()) - { - snapshots.push_back(snapshot); - } - else - { - break; - } - } - - std::string result = snapshots.front().GetCurrentSourceDirectory(); - - for (std::vector<cmState::Snapshot>::const_iterator it = - snapshots.begin() + 1; it != snapshots.end(); ++it) - { - std::string currentSource = it->GetCurrentSourceDirectory(); - if(cmSystemTools::IsSubDirectory(result, currentSource)) - { - result = currentSource; - } - } - - return result; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::FindRelativePathTopBinary() -{ - cmState::Snapshot snapshot = this->StateSnapshot; - std::vector<cmState::Snapshot> snapshots; - snapshots.push_back(snapshot); - while (true) - { - snapshot = snapshot.GetParent(); - if (snapshot.IsValid()) - { - snapshots.push_back(snapshot); - } - else - { - break; - } - } - - std::string result = snapshots.front().GetCurrentBinaryDirectory(); - - for (std::vector<cmState::Snapshot>::const_iterator it = - snapshots.begin() + 1; it != snapshots.end(); ++it) - { - std::string currentBinary = it->GetCurrentBinaryDirectory(); - if(cmSystemTools::IsSubDirectory(result, currentBinary)) - { - result = currentBinary; - } - } - - return result; -} - -//---------------------------------------------------------------------------- -void cmLocalGenerator::ConfigureRelativePaths() -{ - // Relative path conversion inside the source tree is not used to - // construct relative paths passed to build tools so it is safe to - // even when the source is a network path. - std::string source = this->FindRelativePathTopSource(); - this->RelativePathTopSource = source; - - // The current working directory on Windows cannot be a network - // path. Therefore relative paths cannot work when the binary tree - // is a network path. - std::string binary = this->FindRelativePathTopBinary(); - if(binary.size() < 2 || binary.substr(0, 2) != "//") - { - this->RelativePathTopBinary = binary; - } - else - { - this->RelativePathTopBinary = ""; - } -} - -//---------------------------------------------------------------------------- -static bool cmLocalGeneratorNotAbove(const char* a, const char* b) -{ - return (cmSystemTools::ComparePath(a, b) || - cmSystemTools::IsSubDirectory(a, b)); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, - const std::string& in_remote, - bool force) -{ - // The path should never be quoted. - assert(in_remote[0] != '\"'); - - // The local path should never have a trailing slash. - assert(!local.empty() && !(local[local.size()-1] == "")); - - // If the path is already relative then just return the path. - if(!cmSystemTools::FileIsFullPath(in_remote.c_str())) - { - return in_remote; - } - - // Make sure relative path conversion is configured. - if(!this->RelativePathsConfigured) - { - this->ConfigureRelativePaths(); - this->RelativePathsConfigured = true; - } - - if(!force) - { - // Skip conversion if the path and local are not both in the source - // or both in the binary tree. - std::string local_path = cmSystemTools::JoinPath(local); - if(!((cmLocalGeneratorNotAbove(local_path.c_str(), - this->RelativePathTopBinary.c_str()) && - cmLocalGeneratorNotAbove(in_remote.c_str(), - this->RelativePathTopBinary.c_str())) || - (cmLocalGeneratorNotAbove(local_path.c_str(), - this->RelativePathTopSource.c_str()) && - cmLocalGeneratorNotAbove(in_remote.c_str(), - this->RelativePathTopSource.c_str())))) - { - return in_remote; - } - } - - // Identify the longest shared path component between the remote - // path and the local path. - std::vector<std::string> remote; - cmSystemTools::SplitPath(in_remote, remote); - unsigned int common=0; - while(common < remote.size() && - common < local.size() && - cmSystemTools::ComparePath(remote[common], - local[common])) - { - ++common; - } - - // If no part of the path is in common then return the full path. - if(common == 0) - { - return in_remote; - } - - // If the entire path is in common then just return a ".". - if(common == remote.size() && - common == local.size()) - { - return "."; - } - - // If the entire path is in common except for a trailing slash then - // just return a "./". - if(common+1 == remote.size() && - remote[common].empty() && - common == local.size()) - { - return "./"; - } - - // Construct the relative path. - std::string relative; - - // First add enough ../ to get up to the level of the shared portion - // of the path. Leave off the trailing slash. Note that the last - // component of local will never be empty because local should never - // have a trailing slash. - for(unsigned int i=common; i < local.size(); ++i) - { - relative += ".."; - if(i < local.size()-1) - { - relative += "/"; - } - } - - // Now add the portion of the destination path that is not included - // in the shared portion of the path. Add a slash the first time - // only if there was already something in the path. If there was a - // trailing slash in the input then the last iteration of the loop - // will add a slash followed by an empty string which will preserve - // the trailing slash in the output. - - if(!relative.empty() && !remote.empty()) - { - relative += "/"; - } - relative += cmJoin(cmRange(remote).advance(common), "/"); - - // Finally return the path. - return relative; -} - -//---------------------------------------------------------------------------- class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator { public: @@ -3287,27 +2844,22 @@ void cmLocalGenerator::ComputeObjectFilenames( bool cmLocalGenerator::IsWindowsShell() const { - return this->GlobalGenerator->WindowsShell; + return this->GetState()->UseWindowsShell(); } bool cmLocalGenerator::IsWatcomWMake() const { - return this->GlobalGenerator->WatcomWMake; + return this->GetState()->UseWatcomWMake(); } bool cmLocalGenerator::IsMinGWMake() const { - return this->GlobalGenerator->MinGWMake; + return this->GetState()->UseMinGWMake(); } bool cmLocalGenerator::IsNMake() const { - return this->GlobalGenerator->NMake; -} - -void cmLocalGenerator::SetConfiguredCMP0014(bool configured) -{ - this->Configured = configured; + return this->GetState()->UseNMake(); } //---------------------------------------------------------------------------- @@ -3418,150 +2970,6 @@ cmLocalGenerator } //---------------------------------------------------------------------------- -static bool cmLocalGeneratorIsShellOperator(const std::string& str) -{ - static std::set<std::string> shellOperators; - if(shellOperators.empty()) - { - shellOperators.insert("<"); - shellOperators.insert(">"); - shellOperators.insert("<<"); - shellOperators.insert(">>"); - shellOperators.insert("|"); - shellOperators.insert("||"); - shellOperators.insert("&&"); - shellOperators.insert("&>"); - shellOperators.insert("1>"); - shellOperators.insert("2>"); - shellOperators.insert("2>&1"); - shellOperators.insert("1>&2"); - } - return shellOperators.count(str) > 0; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::EscapeForShell(const std::string& str, - bool makeVars, - bool forEcho, - bool useWatcomQuote) -{ - // Do not escape shell operators. - if(cmLocalGeneratorIsShellOperator(str)) - { - return str; - } - - // Compute the flags for the target shell environment. - int flags = 0; - if(this->GlobalGenerator->WindowsVSIDE) - { - flags |= cmsysSystem_Shell_Flag_VSIDE; - } - else if(!this->LinkScriptShell) - { - flags |= cmsysSystem_Shell_Flag_Make; - } - if(makeVars) - { - flags |= cmsysSystem_Shell_Flag_AllowMakeVariables; - } - if(forEcho) - { - flags |= cmsysSystem_Shell_Flag_EchoWindows; - } - if(useWatcomQuote) - { - flags |= cmsysSystem_Shell_Flag_WatcomQuote; - } - if(this->GlobalGenerator->WatcomWMake) - { - flags |= cmsysSystem_Shell_Flag_WatcomWMake; - } - if(this->GlobalGenerator->MinGWMake) - { - flags |= cmsysSystem_Shell_Flag_MinGWMake; - } - if(this->GlobalGenerator->NMake) - { - flags |= cmsysSystem_Shell_Flag_NMake; - } - - // Compute the buffer size needed. - int size = (this->GlobalGenerator->WindowsShell ? - cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) : - cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags)); - - // Compute the shell argument itself. - std::vector<char> arg(size); - if(this->GlobalGenerator->WindowsShell) - { - cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags); - } - else - { - cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags); - } - return std::string(&arg[0]); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::EscapeForCMake(const std::string& str) -{ - // Always double-quote the argument to take care of most escapes. - std::string result = "\""; - for(const char* c = str.c_str(); *c; ++c) - { - if(*c == '"') - { - // Escape the double quote to avoid ending the argument. - result += "\\\""; - } - else if(*c == '$') - { - // Escape the dollar to avoid expanding variables. - result += "\\$"; - } - else if(*c == '\\') - { - // Escape the backslash to avoid other escapes. - result += "\\\\"; - } - else - { - // Other characters will be parsed correctly. - result += *c; - } - } - result += "\""; - return result; -} - -//---------------------------------------------------------------------------- -cmLocalGenerator::FortranFormat -cmLocalGenerator::GetFortranFormat(const char* value) -{ - FortranFormat format = FortranFormatNone; - if(value && *value) - { - std::vector<std::string> fmt; - cmSystemTools::ExpandListArgument(value, fmt); - for(std::vector<std::string>::iterator fi = fmt.begin(); - fi != fmt.end(); ++fi) - { - if(*fi == "FIXED") - { - format = FortranFormatFixed; - } - if(*fi == "FREE") - { - format = FortranFormatFree; - } - } - } - return format; -} - -//---------------------------------------------------------------------------- std::string cmLocalGenerator::GetTargetDirectory(cmTarget const&) const { @@ -3591,7 +2999,7 @@ cmIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility() } } this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch); - this->BackwardsCompatibilityFinal = this->Configured; + this->BackwardsCompatibilityFinal = this->Makefile->IsConfigured(); } return this->BackwardsCompatibility; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index fa2f712..efdd487 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -14,6 +14,7 @@ #include "cmStandardIncludes.h" #include "cmState.h" +#include "cmOutputConverter.h" class cmMakefile; class cmGlobalGenerator; @@ -31,10 +32,11 @@ class cmCustomCommandGenerator; * platforms. This class should never be constructed directly. A * GlobalGenerator will create it and invoke the appropriate commands on it. */ -class cmLocalGenerator +class cmLocalGenerator : public cmOutputConverter { public: - cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent); + cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalGenerator(); /// @return whether we are processing the top CMakeLists.txt file. @@ -46,12 +48,6 @@ public: virtual void Generate() {} /** - * Process the CMakeLists files for this directory to fill in the - * Makefile ivar - */ - virtual void Configure(); - - /** * Calls TraceVSDependencies() on all targets of this generator. */ void TraceDependencies(); @@ -95,44 +91,6 @@ public: cmState* GetState() const; cmState::Snapshot GetStateSnapshot() const; - /** - * Convert something to something else. This is a centralized conversion - * routine used by the generators to handle relative paths and the like. - * The flags determine what is actually done. - * - * relative: treat the argument as a directory and convert it to make it - * relative or full or unchanged. If relative (HOME, START etc) then that - * specifies what it should be relative to. - * - * output: make the result suitable for output to a... - * - * optional: should any relative path operation be controlled by the rel - * path setting - */ - enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT }; - enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE }; - std::string ConvertToOutputFormat(const std::string& source, - OutputFormat output); - std::string Convert(const std::string& remote, RelativeRoot local, - OutputFormat output = UNCHANGED, - bool optional = false); - std::string Convert(RelativeRoot remote, const std::string& local, - OutputFormat output = UNCHANGED, - bool optional = false); - - /** - * Get path for the specified relative root. - */ - const char* GetRelativeRootPath(RelativeRoot relroot); - - /** - * Convert the given path to an output path that is optionally - * relative based on the cache option CMAKE_USE_RELATIVE_PATHS. The - * remote path must use forward slashes and not already be escaped - * or quoted. - */ - std::string ConvertToOptionallyRelativeOutputPath(const std::string& remote); - ///! set/get the parent generator cmLocalGenerator* GetParent() const {return this->Parent;} @@ -193,6 +151,9 @@ public: void AppendFeatureOptions(std::string& flags, const std::string& lang, const char* feature); + const char* GetFeature(const std::string& feature, + const std::string& config); + /** \brief Get absolute path to dependency \a name * * Translate a dependency as given in CMake code to the name to @@ -208,17 +169,6 @@ public: bool GetRealDependency(const std::string& name, const std::string& config, std::string& dep); - ///! for existing files convert to output path and short path if spaces - std::string ConvertToOutputForExisting(const std::string& remote, - RelativeRoot local = START_OUTPUT, - OutputFormat format = SHELL); - - /** For existing path identified by RelativeRoot convert to output - path and short path if spaces. */ - std::string ConvertToOutputForExisting(RelativeRoot remote, - const std::string& local = "", - OutputFormat format = SHELL); - virtual std::string ConvertToIncludeReference(std::string const& path, OutputFormat format = SHELL, bool forceFullPaths = false); @@ -290,40 +240,6 @@ public: const char* FilterPrefix; }; - /** Set whether to treat conversions to SHELL as a link script shell. */ - void SetLinkScriptShell(bool b) { this->LinkScriptShell = b; } - - /** Escape the given string to be used as a command line argument in - the native build system shell. Optionally allow the build - system to replace make variable references. Optionally adjust - escapes for the special case of passing to the native echo - command. */ - std::string EscapeForShell(const std::string& str, bool makeVars = false, - bool forEcho = false, - bool useWatcomQuote = false); - - /** Escape the given string as an argument in a CMake script. */ - static std::string EscapeForCMake(const std::string& str); - - enum FortranFormat - { - FortranFormatNone, - FortranFormatFixed, - FortranFormatFree - }; - FortranFormat GetFortranFormat(const char* value); - - /** - * Convert the given remote path to a relative path with respect to - * the given local path. The local path must be given in component - * form (see SystemTools::SplitPath) without a trailing slash. The - * remote path must use forward slashes and not already be escaped - * or quoted. - */ - std::string ConvertToRelativePath(const std::vector<std::string>& local, - const std::string& remote, - bool force=false); - /** * Get the relative path from the generator output directory to a * per-target support directory. @@ -391,11 +307,10 @@ public: bool IsMinGWMake() const; bool IsNMake() const; - void SetConfiguredCMP0014(bool configured); - + void ComputeObjectMaxPath(); protected: ///! put all the libraries for a target on into the given stream - virtual void OutputLinkLibraries(std::string& linkLibraries, + void OutputLinkLibraries(std::string& linkLibraries, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget &, @@ -438,12 +353,6 @@ protected: std::string& CreateSafeUniqueObjectFileName(const std::string& sin, std::string const& dir_max); - void ComputeObjectMaxPath(); - - void ConfigureRelativePaths(); - std::string FindRelativePathTopSource(); - std::string FindRelativePathTopBinary(); - void SetupPathConversions(); virtual std::string ConvertToLinkReference(std::string const& lib, OutputFormat format = SHELL); @@ -452,49 +361,26 @@ protected: definition. Issues a warning. */ virtual bool CheckDefinition(std::string const& define) const; - /** Read the input CMakeLists.txt file. */ - void ReadInputFile(); - cmMakefile *Makefile; cmState::Snapshot StateSnapshot; cmGlobalGenerator *GlobalGenerator; - std::vector<std::string> HomeDirectoryComponents; - std::vector<std::string> StartDirectoryComponents; - std::vector<std::string> HomeOutputDirectoryComponents; - std::vector<std::string> StartOutputDirectoryComponents; cmLocalGenerator* Parent; std::vector<cmLocalGenerator*> Children; std::map<std::string, std::string> UniqueObjectNamesMap; std::string::size_type ObjectPathMax; std::set<std::string> ObjectMaxPathViolations; - bool LinkScriptShell; - bool UseRelativePaths; - bool IgnoreLibPrefix; - bool Configured; + std::set<cmTarget const*> WarnCMP0063; + bool EmitUniversalBinaryFlags; // Hack for ExpandRuleVariable until object-oriented version is // committed. std::string TargetImplib; - // The top-most directories for relative path conversion. Both the - // source and destination location of a relative path conversion - // must be underneath one of these directories (both under source or - // both under binary) in order for the relative path to be evaluated - // safely by the build tools. - std::string RelativePathTopSource; - std::string RelativePathTopBinary; - bool RelativePathsConfigured; - bool PathConversionsSetup; - cmIML_INT_uint64_t BackwardsCompatibility; bool BackwardsCompatibilityFinal; private: - std::string ConvertToOutputForExistingCommon(const std::string& remote, - std::string const& result, - OutputFormat format); - void AddSharedFlags(std::string& flags, const std::string& lang, bool shared); bool GetShouldUseOldFlags(bool shared, const std::string &lang) const; diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx index ddef3f5..870b9b9 100644 --- a/Source/cmLocalGhsMultiGenerator.cxx +++ b/Source/cmLocalGhsMultiGenerator.cxx @@ -17,8 +17,9 @@ #include "cmGeneratedFileStream.h" cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, - cmLocalGenerator* parent) - : cmLocalGenerator(gg, parent) + cmLocalGenerator* parent, + cmState::Snapshot snapshot) + : cmLocalGenerator(gg, parent, snapshot) { } @@ -27,31 +28,16 @@ cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator() {} void cmLocalGhsMultiGenerator::Generate() { cmGeneratorTargetsType tgts = this->GetMakefile()->GetGeneratorTargets(); - if (!tgts.empty()) + + for (cmGeneratorTargetsType::iterator l = tgts.begin(); l != tgts.end(); + ++l) { - for (cmGeneratorTargetsType::iterator l = tgts.begin(); l != tgts.end(); - ++l) + if (l->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY + || l->second->Target->IsImported()) { - cmGhsMultiTargetGenerator tg(l->second->Target); - tg.Generate(); + continue; } + cmGhsMultiTargetGenerator tg(l->second->Target); + tg.Generate(); } } - -// Implemented in: -// cmLocalGenerator. -// Used in: -// Source/cmMakefile.cxx -// Source/cmGlobalGenerator.cxx -void cmLocalGhsMultiGenerator::Configure() -{ - // Compute the path to use when referencing the current output - // directory from the top output directory. - this->HomeRelativeOutputPath = - this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); - if (this->HomeRelativeOutputPath == ".") - { - this->HomeRelativeOutputPath = ""; - } - this->cmLocalGenerator::Configure(); -} diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h index ec25cba..f52ef39 100644 --- a/Source/cmLocalGhsMultiGenerator.h +++ b/Source/cmLocalGhsMultiGenerator.h @@ -25,32 +25,15 @@ class cmGeneratedFileStream; class cmLocalGhsMultiGenerator : public cmLocalGenerator { public: - cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent); + cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalGhsMultiGenerator(); - /// @returns the relative path between the HomeOutputDirectory and this - /// local generators StartOutputDirectory. - std::string GetHomeRelativeOutputPath() const - { - return this->HomeRelativeOutputPath; - } - /** * Generate the makefile for this directory. */ virtual void Generate(); - - /// Overloaded methods. @see cmLocalGenerator::Configure() - virtual void Configure(); - const char *GetBuildFileName() { return this->BuildFileName.c_str(); } - -protected: - virtual bool CustomCommandUseLocal() const { return true; } - -private: - std::string BuildFileName; - std::string HomeRelativeOutputPath; }; #endif diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index f1f1202..427ae10 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -23,8 +23,9 @@ #include <assert.h> cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg, - cmLocalGenerator* parent) - : cmLocalGenerator(gg, parent) + cmLocalGenerator* parent, + cmState::Snapshot snapshot) + : cmLocalGenerator(gg, parent, snapshot) , ConfigName("") , HomeRelativeOutputPath("") { @@ -40,6 +41,15 @@ cmLocalNinjaGenerator::~cmLocalNinjaGenerator() void cmLocalNinjaGenerator::Generate() { + // Compute the path to use when referencing the current output + // directory from the top output directory. + this->HomeRelativeOutputPath = + this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); + if(this->HomeRelativeOutputPath == ".") + { + this->HomeRelativeOutputPath = ""; + } + this->SetConfigName(); this->WriteProcessedMakefile(this->GetBuildFileStream()); @@ -90,25 +100,6 @@ void cmLocalNinjaGenerator::Generate() this->WriteCustomCommandBuildStatements(); } -// Implemented in: -// cmLocalUnixMakefileGenerator3. -// Used in: -// Source/cmMakefile.cxx -// Source/cmGlobalGenerator.cxx -void cmLocalNinjaGenerator::Configure() -{ - // Compute the path to use when referencing the current output - // directory from the top output directory. - this->HomeRelativeOutputPath = - this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); - if(this->HomeRelativeOutputPath == ".") - { - this->HomeRelativeOutputPath = ""; - } - this->cmLocalGenerator::Configure(); - -} - // TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it. std::string cmLocalNinjaGenerator ::GetTargetDirectory(cmTarget const& target) const @@ -305,8 +296,8 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Write statements declared in CMakeLists.txt:" << std::endl - << "# " << this->Makefile->GetCurrentListFile() << std::endl - ; + << "# " + << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE") << std::endl; if(this->IsRootMakefile()) os << "# Which is the root file." << std::endl; cmGlobalNinjaGenerator::WriteDivider(os); diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 3a6e030..ce966ff 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -31,28 +31,18 @@ class cmake; class cmLocalNinjaGenerator : public cmLocalGenerator { public: - /// Default constructor. - cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent); + cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, + cmState::Snapshot snapshot); - /// Destructor. virtual ~cmLocalNinjaGenerator(); - /// Overloaded methods. @see cmLocalGenerator::Generate() virtual void Generate(); - /// Overloaded methods. @see cmLocalGenerator::Configure() - virtual void Configure(); - - /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory() virtual std::string GetTargetDirectory(cmTarget const& target) const; const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; cmGlobalNinjaGenerator* GetGlobalNinjaGenerator(); - /** - * Shortcut to get the cmake instance throw the global generator. - * @return an instance of the cmake object. - */ const cmake* GetCMakeInstance() const; cmake* GetCMakeInstance(); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index f11c79e..f1fd806 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -80,15 +80,11 @@ static std::string cmSplitExtension(std::string const& in, std::string& base) //---------------------------------------------------------------------------- cmLocalUnixMakefileGenerator3:: -cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmLocalGenerator* parent) - : cmLocalGenerator(gg, parent) +cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmLocalGenerator* parent, + cmState::Snapshot snapshot) + : cmLocalGenerator(gg, parent, snapshot) { - this->IncludeDirective = "include"; this->MakefileVariableSize = 0; - this->IgnoreLibPrefix = false; - this->PassMakeflags = false; - this->DefineWindowsNULL = false; - this->UnixCD = true; this->ColorMakefile = false; this->SkipPreprocessedSourceRules = false; this->SkipAssemblySourceRules = false; @@ -102,7 +98,7 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() } //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::Configure() +void cmLocalUnixMakefileGenerator3::Generate() { // Compute the path to use when referencing the current output // directory from the top output directory. @@ -116,12 +112,7 @@ void cmLocalUnixMakefileGenerator3::Configure() { this->HomeRelativeOutputPath += "/"; } - this->cmLocalGenerator::Configure(); -} -//---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::Generate() -{ // Store the configuration name that will be generated. if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) { @@ -545,9 +536,11 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() // Setup relative path conversion tops. infoFileStream << "# Relative path conversion top directories.\n" - << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" << this->RelativePathTopSource + << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" + << this->StateSnapshot.GetRelativePathTopSource() << "\")\n" - << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \"" << this->RelativePathTopBinary + << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \"" + << this->StateSnapshot.GetRelativePathTopBinary() << "\")\n" << "\n"; @@ -720,7 +713,9 @@ cmLocalUnixMakefileGenerator3 makefileStream << "# Set environment variables for the build.\n" << "\n"; - if(this->DefineWindowsNULL) + cmGlobalUnixMakefileGenerator3* gg = + static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); + if(gg->DefineWindowsNULL) { makefileStream << "!IF \"$(OS)\" == \"Windows_NT\"\n" @@ -745,18 +740,16 @@ cmLocalUnixMakefileGenerator3 #endif } - std::string cmakecommand = - this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"); makefileStream << "# The CMake executable.\n" << "CMAKE_COMMAND = " - << this->ConvertShellCommand(cmakecommand, FULL) + << this->ConvertShellCommand(cmSystemTools::GetCMakeCommand(), FULL) << "\n" << "\n"; makefileStream << "# The command to remove a file.\n" << "RM = " - << this->ConvertShellCommand(cmakecommand, FULL) + << this->ConvertShellCommand(cmSystemTools::GetCMakeCommand(), FULL) << " -E remove -f\n" << "\n"; makefileStream @@ -1261,7 +1254,7 @@ cmLocalUnixMakefileGenerator3 f != files.end(); ++f) { std::string fc = this->Convert(*f,START_OUTPUT,UNCHANGED); - fout << " " << cmLocalGenerator::EscapeForCMake(fc) << "\n"; + fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n"; } fout << ")\n"; } @@ -1613,16 +1606,15 @@ cmLocalUnixMakefileGenerator3 } // Setup relative path top directories. - this->RelativePathsConfigured = true; if(const char* relativePathTopSource = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) { - this->RelativePathTopSource = relativePathTopSource; + this->StateSnapshot.SetRelativePathTopSource(relativePathTopSource); } if(const char* relativePathTopBinary = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) { - this->RelativePathTopBinary = relativePathTopBinary; + this->StateSnapshot.SetRelativePathTopBinary(relativePathTopBinary); } } else @@ -2060,7 +2052,7 @@ void cmLocalUnixMakefileGenerator3 di != defines.end(); ++di) { cmakefileStream - << " " << cmLocalGenerator::EscapeForCMake(*di) << "\n"; + << " " << cmOutputConverter::EscapeForCMake(*di) << "\n"; } cmakefileStream << " )\n"; @@ -2114,7 +2106,7 @@ void cmLocalUnixMakefileGenerator3 tri != transformRules.end(); ++tri) { cmakefileStream << " " - << cmLocalGenerator::EscapeForCMake(*tri) << "\n"; + << cmOutputConverter::EscapeForCMake(*tri) << "\n"; } cmakefileStream << " )\n"; @@ -2143,10 +2135,12 @@ cmLocalUnixMakefileGenerator3 cmd += this->Convert(makefile,NONE,SHELL); cmd += " "; + cmGlobalUnixMakefileGenerator3* gg = + static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); // Pass down verbosity level. - if(!this->GetMakeSilentFlag().empty()) + if(!gg->MakeSilentFlag.empty()) { - cmd += this->GetMakeSilentFlag(); + cmd += gg->MakeSilentFlag; cmd += " "; } @@ -2154,7 +2148,7 @@ cmLocalUnixMakefileGenerator3 // sub-invoked makes via an environment variable. However, some // makes do not support that, so you have to pass the flags // explicitly. - if(this->GetPassMakeflags()) + if(gg->PassMakeflags) { cmd += "-$(MAKEFLAGS) "; } @@ -2346,7 +2340,9 @@ void cmLocalUnixMakefileGenerator3 // support changing the drive letter with just "d:"). const char* cd_cmd = this->IsMinGWMake() ? "cd /d " : "cd "; - if(!this->UnixCD) + cmGlobalUnixMakefileGenerator3* gg = + static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); + if(!gg->UnixCD) { // On Windows we must perform each step separately and then change // back because the shell keeps the working directory between diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 7b436a5..dcb3016 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -35,16 +35,11 @@ class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator { public: cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, - cmLocalGenerator* parent); + cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalUnixMakefileGenerator3(); /** - * Process the CMakeLists files for this directory to fill in the - * Makefile ivar - */ - virtual void Configure(); - - /** * Generate the makefile for this directory. */ virtual void Generate(); @@ -67,52 +62,11 @@ public: void WriteMakeVariables(std::ostream& makefileStream); /** - * If true, then explicitly pass MAKEFLAGS on the make all target for makes - * that do not use environment variables. - * - */ - void SetPassMakeflags(bool s){this->PassMakeflags = s;} - bool GetPassMakeflags() { return this->PassMakeflags; } - - /** - * Set the flag used to keep the make program silent. - */ - void SetMakeSilentFlag(const std::string& s) { this->MakeSilentFlag = s; } - std::string &GetMakeSilentFlag() { return this->MakeSilentFlag; } - - /** - * If set to true, then NULL is set to nil for non Windows_NT. - * This uses make syntax used by nmake and borland. - * The default is false. - */ - void SetDefineWindowsNULL(bool v) {this->DefineWindowsNULL = v;} - - /** - * If set to true, cd dir && command is used to - * run commands in a different directory. - */ - void SetUnixCD(bool v) {this->UnixCD = v;} - - /** - * Set the string used to include one makefile into another default - * is include. - */ - void SetIncludeDirective(const std::string& s) - { this->IncludeDirective = s; } - const std::string& GetIncludeDirective() { return this->IncludeDirective; } - - /** * Set max makefile variable size, default is 0 which means unlimited. */ void SetMakefileVariableSize(int s) { this->MakefileVariableSize = s; } /** - * If ignore lib prefix is true, then do not strip lib from the name - * of a library. - */ - void SetIgnoreLibPrefix(bool s) { this->IgnoreLibPrefix = s; } - - /** * Set whether passing a make target on a command line requires an * extra level of escapes. */ @@ -300,31 +254,10 @@ private: ImplicitDependTargetMap ImplicitDepends; - //========================================================================== - // Configuration settings. - int MakefileVariableSize; - std::string IncludeDirective; - std::string MakeSilentFlag; std::string ConfigurationName; - bool DefineWindowsNULL; - bool UnixCD; - bool PassMakeflags; - bool MakeCommandEscapeTargetTwice; - bool BorlandMakeCurlyHack; - //========================================================================== std::string HomeRelativeOutputPath; - /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the - beginning of generation to avoid many duplicate lookups. */ - bool ColorMakefile; - - /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and - CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to - avoid many duplicate lookups. */ - bool SkipPreprocessedSourceRules; - bool SkipAssemblySourceRules; - struct LocalObjectEntry { cmTarget* Target; @@ -353,6 +286,13 @@ private: /* does the work for each target */ std::map<std::string, std::string> MakeVariableMap; std::map<std::string, std::string> ShortMakeVariableMap; + + int MakefileVariableSize; + bool MakeCommandEscapeTargetTwice; + bool BorlandMakeCurlyHack; + bool ColorMakefile; + bool SkipPreprocessedSourceRules; + bool SkipAssemblySourceRules; }; #endif diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index 06a3b6c..9ded83a 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -62,9 +62,10 @@ class cmVS10XMLParser : public cmXMLParser //---------------------------------------------------------------------------- cmLocalVisualStudio10Generator -::cmLocalVisualStudio10Generator(VSVersion v, cmGlobalGenerator* gg, - cmLocalGenerator* parent): - cmLocalVisualStudio7Generator(v, gg, parent) +::cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot): + cmLocalVisualStudio7Generator(gg, parent, snapshot) { } @@ -106,10 +107,9 @@ void cmLocalVisualStudio10Generator cmVS10XMLParser parser; parser.ParseFile(path); - // if we can not find a GUID then create one + // if we can not find a GUID then we will generate one later if(parser.GUID.empty()) { - this->GlobalGenerator->CreateGUID(name); return; } diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h index 987e08b..c588aaf 100644 --- a/Source/cmLocalVisualStudio10Generator.h +++ b/Source/cmLocalVisualStudio10Generator.h @@ -25,8 +25,9 @@ class cmLocalVisualStudio10Generator : public cmLocalVisualStudio7Generator { public: ///! Set cache only and recurse to false by default. - cmLocalVisualStudio10Generator(VSVersion v, cmGlobalGenerator* gg, - cmLocalGenerator* parent); + cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalVisualStudio10Generator(); diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 42da639..a26a1dd 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -25,8 +25,9 @@ cmLocalVisualStudio6Generator ::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, - cmLocalGenerator* parent): - cmLocalVisualStudioGenerator(VS6, gg, parent) + cmLocalGenerator* parent, + cmState::Snapshot snapshot): + cmLocalVisualStudioGenerator(gg, parent, snapshot) { } @@ -221,10 +222,8 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt) { std::string dspname = GetVS6TargetName(tgt.GetName()); dspname += ".dsp.cmake"; - const char* dsprule = - this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"); cmCustomCommandLine commandLine; - commandLine.push_back(dsprule); + commandLine.push_back(cmSystemTools::GetCMakeCommand()); std::string makefileIn = this->Makefile->GetCurrentSourceDirectory(); makefileIn += "/"; makefileIn += "CMakeLists.txt"; @@ -236,13 +235,10 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt) comment += makefileIn; std::string args; args = "-H"; - args += this->Convert(this->Makefile->GetHomeDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeDirectory(); commandLine.push_back(args); args = "-B"; - args += - this->Convert(this->Makefile->GetHomeOutputDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeOutputDirectory(); commandLine.push_back(args); std::vector<std::string> const& listFiles = this->Makefile->GetListFiles(); @@ -499,7 +495,7 @@ void cmLocalVisualStudio6Generator // Tell MS-Dev what the source is. If the compiler knows how to // build it, then it will. fout << "SOURCE=" << - this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n"; + this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n"; if(!depends.empty()) { // Write out the dependencies for the rule. @@ -508,7 +504,7 @@ void cmLocalVisualStudio6Generator d != depends.end(); ++d) { fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(d->c_str()); + this->ConvertToOutputFormat(d->c_str(), SHELL); } fout << "\n"; } @@ -664,7 +660,7 @@ cmLocalVisualStudio6Generator if(this->GetRealDependency(d->c_str(), config.c_str(), dep)) { fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); + this->ConvertToOutputFormat(dep.c_str(), SHELL); } } fout << "\n"; @@ -690,7 +686,7 @@ cmLocalVisualStudio6Generator ++o) { // Write a rule for every output generated by this command. - fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str()) + fout << this->ConvertToOutputFormat(o->c_str(), SHELL) << " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t"; fout << script.c_str() << "\n\n"; } @@ -817,7 +813,7 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target, // Add a pre-link event to create the directory. cmCustomCommandLine command; - command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND")); + command.push_back(cmSystemTools::GetCMakeCommand()); command.push_back("-E"); command.push_back("make_directory"); command.push_back(outDir); @@ -907,7 +903,7 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target, for(i = includes.begin(); i != includes.end(); ++i) { std::string tmp = - this->ConvertToOptionallyRelativeOutputPath(i->c_str()); + this->ConvertToOutputFormat(i->c_str(), SHELL); if(useShortPath) { cmSystemTools::GetShortPath(tmp.c_str(), tmp); @@ -998,14 +994,14 @@ void cmLocalVisualStudio6Generator if(libPath.size()) { std::string lpath = - this->ConvertToOptionallyRelativeOutputPath(libPath.c_str()); + this->ConvertToOutputFormat(libPath.c_str(), SHELL); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = libPath + "$(INTDIR)"; lpathIntDir = - this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); + this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL); if(pathEmitted.insert(lpath).second) { libOptions += " /LIBPATH:"; @@ -1031,14 +1027,14 @@ void cmLocalVisualStudio6Generator if(exePath.size()) { std::string lpath = - this->ConvertToOptionallyRelativeOutputPath(exePath.c_str()); + this->ConvertToOutputFormat(exePath.c_str(), SHELL); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = exePath + "$(INTDIR)"; lpathIntDir = - this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); + this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL); if(pathEmitted.insert(lpath).second) { @@ -1072,14 +1068,14 @@ void cmLocalVisualStudio6Generator path += "/"; } std::string lpath = - this->ConvertToOptionallyRelativeOutputPath(path.c_str()); + this->ConvertToOutputFormat(path.c_str(), SHELL); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = path + "$(INTDIR)"; lpathIntDir = - this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); + this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL); if(pathEmitted.insert(lpath).second) { libOptions += " /LIBPATH:"; @@ -1143,9 +1139,9 @@ void cmLocalVisualStudio6Generator libDebug += ".lib"; } } - lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str()); + lib = this->ConvertToOutputFormat(lib.c_str(), SHELL); libDebug = - this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str()); + this->ConvertToOutputFormat(libDebug.c_str(), SHELL); if (j->second == cmTarget::GENERAL) { @@ -1368,21 +1364,21 @@ void cmLocalVisualStudio6Generator { #ifdef CM_USE_OLD_VS6 outputDirOld = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (target.GetDirectory().c_str())); + removeQuotes(this->ConvertToOutputFormat + (target.GetDirectory().c_str(), SHELL)); #endif outputDirDebug = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("Debug").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("Debug").c_str(), SHELL)); outputDirRelease = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("Release").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("Release").c_str(), SHELL)); outputDirMinSizeRel = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("MinSizeRel").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("MinSizeRel").c_str(), SHELL)); outputDirRelWithDebInfo = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("RelWithDebInfo").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("RelWithDebInfo").c_str(), SHELL)); } else if(target.GetType() == cmTarget::OBJECT_LIBRARY) { @@ -1450,15 +1446,13 @@ void cmLocalVisualStudio6Generator targetImplibFlagMinSizeRel = "/implib:"; targetImplibFlagRelWithDebInfo = "/implib:"; targetImplibFlagDebug += - this->ConvertToOptionallyRelativeOutputPath(fullPathImpDebug.c_str()); + this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL); targetImplibFlagRelease += - this->ConvertToOptionallyRelativeOutputPath(fullPathImpRelease.c_str()); + this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL); targetImplibFlagMinSizeRel += - this->ConvertToOptionallyRelativeOutputPath( - fullPathImpMinSizeRel.c_str()); + this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL); targetImplibFlagRelWithDebInfo += - this->ConvertToOptionallyRelativeOutputPath( - fullPathImpRelWithDebInfo.c_str()); + this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL); } #ifdef CM_USE_OLD_VS6 @@ -1670,12 +1664,12 @@ void cmLocalVisualStudio6Generator // to convert to output path for unix to win32 conversion cmSystemTools::ReplaceString (line, "LIBRARY_OUTPUT_PATH", - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (libPath.c_str())).c_str()); + removeQuotes(this->ConvertToOutputFormat + (libPath.c_str(), SHELL)).c_str()); cmSystemTools::ReplaceString (line, "EXECUTABLE_OUTPUT_PATH", - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (exePath.c_str())).c_str()); + removeQuotes(this->ConvertToOutputFormat + (exePath.c_str(), SHELL)).c_str()); #endif if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY) @@ -1885,9 +1879,9 @@ void cmLocalVisualStudio6Generator } dir += "$(IntDir)"; options += "# ADD LINK32 /LIBPATH:"; - options += this->ConvertToOptionallyRelativeOutputPath(dir.c_str()); + options += this->ConvertToOutputFormat(dir.c_str(), SHELL); options += " /LIBPATH:"; - options += this->ConvertToOptionallyRelativeOutputPath(d->c_str()); + options += this->ConvertToOutputFormat(d->c_str(), SHELL); options += "\n"; } } @@ -1898,7 +1892,7 @@ void cmLocalVisualStudio6Generator if(l->IsPath) { options += - this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str()); + this->ConvertToOutputFormat(l->Value.c_str(), SHELL); } else if (!l->Target || l->Target->GetType() != cmTarget::INTERFACE_LIBRARY) @@ -1934,7 +1928,7 @@ void cmLocalVisualStudio6Generator options += "# ADD "; options += tool; options += "32 "; - options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str()); + options += this->ConvertToOutputFormat(oi->c_str(), SHELL); options += "\n"; } } diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h index a6e0b3d..8f4d521 100644 --- a/Source/cmLocalVisualStudio6Generator.h +++ b/Source/cmLocalVisualStudio6Generator.h @@ -30,7 +30,8 @@ class cmLocalVisualStudio6Generator : public cmLocalVisualStudioGenerator public: ///! Set cache only and recurse to false by default. cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, - cmLocalGenerator* parent); + cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalVisualStudio6Generator(); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 63c18a7..dc3a16d 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -55,11 +55,11 @@ static void cmConvertToWindowsSlash(std::string& s) //---------------------------------------------------------------------------- cmLocalVisualStudio7Generator -::cmLocalVisualStudio7Generator(VSVersion v, cmGlobalGenerator* gg, - cmLocalGenerator* parent): - cmLocalVisualStudioGenerator(v, gg, parent) +::cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot): + cmLocalVisualStudioGenerator(gg, parent, snapshot) { - this->ExtraFlagTable = 0; this->Internal = new cmLocalVisualStudio7GeneratorInternals(this); } @@ -82,8 +82,6 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() // Now create GUIDs for targets cmTargets &tgts = this->Makefile->GetTargets(); - cmGlobalVisualStudio7Generator* gg = - static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY) @@ -96,10 +94,6 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() this->ReadAndStoreExternalGUID( l->second.GetName().c_str(), path); } - else - { - gg->CreateGUID(l->first.c_str()); - } } @@ -241,18 +235,17 @@ void cmLocalVisualStudio7Generator::WriteStampFiles() void cmLocalVisualStudio7Generator ::CreateSingleVCProj(const std::string& lname, cmTarget &target) { - this->FortranProject = - static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator) - ->TargetIsFortranOnly(target); - this->WindowsCEProject = - static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator) - ->TargetsWindowsCE(); + cmGlobalVisualStudioGenerator* gg + = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator); + this->FortranProject = gg->TargetIsFortranOnly(target); + this->WindowsCEProject = gg->TargetsWindowsCE(); // Intel Fortran for VS10 uses VS9 format ".vfproj" files. - VSVersion realVersion = this->Version; - if(this->FortranProject && this->Version >= VS10) + cmGlobalVisualStudioGenerator::VSVersion realVersion = gg->GetVersion(); + if(this->FortranProject + && gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS10) { - this->Version = VS9; + gg->SetVersion(cmGlobalVisualStudioGenerator::VS9); } // add to the list of projects @@ -282,7 +275,7 @@ void cmLocalVisualStudio7Generator this->GlobalGenerator->FileReplacedDuringGenerate(fname); } - this->Version = realVersion; + gg->SetVersion(realVersion); } //---------------------------------------------------------------------------- @@ -292,10 +285,8 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() stampName += "/"; stampName += cmake::GetCMakeFilesDirectoryPostSlash(); stampName += "generate.stamp"; - const char* dsprule = - this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"); cmCustomCommandLine commandLine; - commandLine.push_back(dsprule); + commandLine.push_back(cmSystemTools::GetCMakeCommand()); std::string makefileIn = this->Makefile->GetCurrentSourceDirectory(); makefileIn += "/"; makefileIn += "CMakeLists.txt"; @@ -308,13 +299,10 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() comment += makefileIn; std::string args; args = "-H"; - args += this->Convert(this->Makefile->GetHomeDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeDirectory(); commandLine.push_back(args); args = "-B"; - args += - this->Convert(this->Makefile->GetHomeOutputDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeOutputDirectory(); commandLine.push_back(args); commandLine.push_back("--check-stamp-file"); std::string stampFilename = this->Convert(stampName.c_str(), FULL, @@ -343,17 +331,14 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() } } -void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout, - const std::string& libName, - cmTarget &target) +void cmLocalVisualStudio7Generator::WriteConfigurations( + std::ostream& fout, std::vector<std::string> const& configs, + const std::string& libName, cmTarget &target + ) { - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); - fout << "\t<Configurations>\n"; - for( std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for (std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { this->WriteConfiguration(fout, i->c_str(), libName, target); } @@ -773,7 +758,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, } Options targetOptions(this, t, table, - this->ExtraFlagTable); + gg->ExtraFlagTable); targetOptions.FixExceptionHandlingDefault(); std::string asmLocation = configName + "/"; targetOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str()); @@ -995,7 +980,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // end of <Tool Name=VCMIDLTool // Check if we need the FAT32 workaround. - if(targetBuilds && this->Version >= VS8) + if(targetBuilds && this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8) { // Check the filesystem type where the target will be written. if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str())) @@ -1093,7 +1078,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, if(!this->ModuleDefinitionFile.empty()) { std::string defFile = - this->ConvertToOptionallyRelativeOutputPath(this->ModuleDefinitionFile); + this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL); linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str()); } switch(target.GetType()) @@ -1130,7 +1115,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t<Tool\n" << "\t\t\t\tName=\"" << tool << "\"\n"; - if(this->GetVersion() < VS8 || this->FortranProject) + if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 + || this->FortranProject) { std::ostringstream libdeps; this->Internal->OutputObjects(libdeps, &target); @@ -1190,7 +1176,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, // libraries which may be set by the user to something bad. fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) " << this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); - if(this->GetVersion() < VS8 || this->FortranProject) + if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 + || this->FortranProject) { this->Internal->OutputObjects(fout, &target, " "); } @@ -1218,7 +1205,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } if(this->WindowsCEProject) { - if(this->GetVersion() < VS9) + if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS9) { fout << "\t\t\t\tSubSystem=\"9\"\n"; } @@ -1288,7 +1275,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, // libraries which may be set by the user to something bad. fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) " << this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); - if(this->GetVersion() < VS8 || this->FortranProject) + if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 + || this->FortranProject) { this->Internal->OutputObjects(fout, &target, " "); } @@ -1316,7 +1304,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } if ( this->WindowsCEProject ) { - if(this->GetVersion() < VS9) + if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS9) { fout << "\t\t\t\tSubSystem=\"9\"\n"; } @@ -1469,10 +1457,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, const std::string& libName, cmTarget &target) { - // get the configurations - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); + std::vector<std::string> configs; + this->Makefile->GetConfigurations(configs); // We may be modifying the source groups temporarily, so make a copy. std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); @@ -1505,7 +1491,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, // open the project this->WriteProjectStart(fout, libName, target, sourceGroups); // write the configuration information - this->WriteConfigurations(fout, libName, target); + this->WriteConfigurations(fout, configs, libName, target); fout << "\t<Files>\n"; @@ -1517,7 +1503,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, this->WriteGroup(&sg, target, fout, libName, configs); } - if(this->GetVersion() >= VS8 && !this->FortranProject) + if(this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8 + && !this->FortranProject) { // VS >= 8 support per-config source locations so we // list object library content as external objects. @@ -1561,7 +1548,7 @@ public: cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg, cmTarget& target, cmSourceFile const& sf, - std::vector<std::string>* configs); + std::vector<std::string> const& configs); std::map<std::string, cmLVS7GFileConfig> FileConfigMap; }; @@ -1569,7 +1556,7 @@ cmLocalVisualStudio7GeneratorFCInfo ::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg, cmTarget& target, cmSourceFile const& sf, - std::vector<std::string>* configs) + std::vector<std::string> const& configs) { cmGeneratorTarget* gt = lg->GetGlobalGenerator()->GetGeneratorTarget(&target); @@ -1580,8 +1567,8 @@ cmLocalVisualStudio7GeneratorFCInfo } // Compute per-source, per-config information. - for(std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { std::string configUpper = cmSystemTools::UpperCase(*i); cmLVS7GFileConfig fc; @@ -1691,13 +1678,13 @@ std::string cmLocalVisualStudio7Generator ::ComputeLongestObjectDirectory(cmTarget& target) const { - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); + std::vector<std::string> configs; + target.GetMakefile()->GetConfigurations(configs); + // Compute the maximum length configuration name. std::string config_max; - for(std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::iterator i = configs.begin(); + i != configs.end(); ++i) { if(i->size() > config_max.size()) { @@ -1721,7 +1708,7 @@ cmLocalVisualStudio7Generator bool cmLocalVisualStudio7Generator ::WriteGroup(const cmSourceGroup *sg, cmTarget& target, std::ostream &fout, const std::string& libName, - std::vector<std::string> *configs) + std::vector<std::string> const& configs) { cmGlobalVisualStudio7Generator* gg = static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); @@ -1771,7 +1758,8 @@ bool cmLocalVisualStudio7Generator fout << "\t\t\t\tRelativePath=\"" << d << "\">\n"; if(cmCustomCommand const* command = (*sf)->GetCustomCommand()) { - this->WriteCustomRule(fout, source.c_str(), *command, fcinfo); + this->WriteCustomRule(fout, configs, source.c_str(), + *command, fcinfo); } else if(!fcinfo.FileConfigMap.empty()) { @@ -1842,7 +1830,7 @@ bool cmLocalVisualStudio7Generator table = cmLocalVisualStudio7GeneratorFortranFlagTable; } Options fileOptions(this, tool, table, - this->ExtraFlagTable); + gg->ExtraFlagTable); fileOptions.Parse(fc.CompileFlags.c_str()); fileOptions.AddDefines(fc.CompileDefs.c_str()); fileOptions.AddDefines(fc.CompileDefsConfig.c_str()); @@ -1887,6 +1875,7 @@ bool cmLocalVisualStudio7Generator void cmLocalVisualStudio7Generator:: WriteCustomRule(std::ostream& fout, + std::vector<std::string> const& configs, const char* source, const cmCustomCommand& command, FCInfo& fcinfo) @@ -1895,10 +1884,6 @@ WriteCustomRule(std::ostream& fout, static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); // Write the rule for each configuration. - std::vector<std::string>::iterator i; - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); const char* compileTool = "VCCLCompilerTool"; if(this->FortranProject) { @@ -1909,7 +1894,8 @@ WriteCustomRule(std::ostream& fout, { customTool = "VFCustomBuildTool"; } - for(i = configs->begin(); i != configs->end(); ++i) + for (std::vector<std::string>::const_iterator i = configs.begin(); + i != configs.end(); ++i) { cmCustomCommandGenerator ccg(command, *i, this->Makefile); cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i]; @@ -2149,13 +2135,13 @@ cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout, << gg->Encoding() << "\"?>\n" << "<VisualStudioProject\n" << "\tProjectType=\"Visual C++\"\n"; - if(this->Version == VS71) + if(gg->GetVersion() == cmGlobalVisualStudioGenerator::VS71) { fout << "\tVersion=\"7.10\"\n"; } else { - fout << "\tVersion=\"" << (this->Version/10) << ".00\"\n"; + fout << "\tVersion=\"" << (gg->GetVersion()/10) << ".00\"\n"; } const char* projLabel = target.GetProperty("PROJECT_LABEL"); if(!projLabel) @@ -2168,7 +2154,7 @@ cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout, keyword = "Win32Proj"; } fout << "\tName=\"" << projLabel << "\"\n"; - if(this->Version >= VS8) + if(gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS8) { fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n"; } @@ -2239,7 +2225,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s) std::string cmLocalVisualStudio7Generator ::ConvertToXMLOutputPath(const char* path) { - std::string ret = this->ConvertToOptionallyRelativeOutputPath(path); + std::string ret = this->ConvertToOutputFormat(path, SHELL); cmSystemTools::ReplaceString(ret, "&", "&"); cmSystemTools::ReplaceString(ret, "\"", """); cmSystemTools::ReplaceString(ret, "<", "<"); @@ -2250,7 +2236,7 @@ std::string cmLocalVisualStudio7Generator std::string cmLocalVisualStudio7Generator ::ConvertToXMLOutputPathSingle(const char* path) { - std::string ret = this->ConvertToOptionallyRelativeOutputPath(path); + std::string ret = this->ConvertToOutputFormat(path, SHELL); cmSystemTools::ReplaceString(ret, "\"", ""); cmSystemTools::ReplaceString(ret, "&", "&"); cmSystemTools::ReplaceString(ret, "<", "<"); @@ -2317,12 +2303,9 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( { cmVS7XMLParser parser; parser.ParseFile(path); - // if we can not find a GUID then create one + // if we can not find a GUID then we will generate one later if(parser.GUID.size() == 0) { - cmGlobalVisualStudio7Generator* gg = - static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); - gg->CreateGUID(name); return; } std::string guidStoreName = name; diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 1891369..43f3af9 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -35,8 +35,9 @@ class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator { public: ///! Set cache only and recurse to false by default. - cmLocalVisualStudio7Generator(VSVersion v, cmGlobalGenerator* gg, - cmLocalGenerator* parent); + cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalVisualStudio7Generator(); @@ -54,8 +55,6 @@ public: */ void SetBuildType(BuildType,const std::string& name); - void SetExtraFlagTable(cmVS7FlagTable const* table) - { this->ExtraFlagTable = table; } virtual std::string GetTargetDirectory(cmTarget const&) const; cmSourceFile* CreateVCProjBuildRule(); void WriteStampFiles(); @@ -79,6 +78,7 @@ private: void WriteVCProjFile(std::ostream& fout, const std::string& libName, cmTarget &tgt); void WriteConfigurations(std::ostream& fout, + std::vector<std::string> const& configs, const std::string& libName, cmTarget &tgt); void WriteConfiguration(std::ostream& fout, const std::string& configName, @@ -103,6 +103,7 @@ private: void WriteVCProjEndGroup(std::ostream& fout); void WriteCustomRule(std::ostream& fout, + std::vector<std::string> const& configs, const char* source, const cmCustomCommand& command, FCInfo& fcinfo); @@ -111,7 +112,7 @@ private: bool WriteGroup(const cmSourceGroup *sg, cmTarget& target, std::ostream &fout, const std::string& libName, - std::vector<std::string> *configs); + std::vector<std::string> const& configs); friend class cmLocalVisualStudio7GeneratorFCInfo; friend class cmLocalVisualStudio7GeneratorInternals; @@ -119,7 +120,6 @@ private: class EventWriter; friend class EventWriter; - cmVS7FlagTable const* ExtraFlagTable; std::string ModuleDefinitionFile; bool FortranProject; bool WindowsCEProject; diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 4a596d5..ca72939 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -19,11 +19,11 @@ //---------------------------------------------------------------------------- cmLocalVisualStudioGenerator -::cmLocalVisualStudioGenerator(VSVersion v, cmGlobalGenerator* gg, - cmLocalGenerator* parent) - : cmLocalGenerator(gg, parent) +::cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot) + : cmLocalGenerator(gg, parent, snapshot) { - this->Version = v; } //---------------------------------------------------------------------------- @@ -32,6 +32,15 @@ cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator() } //---------------------------------------------------------------------------- +cmGlobalVisualStudioGenerator::VSVersion +cmLocalVisualStudioGenerator::GetVersion() const +{ + cmGlobalVisualStudioGenerator* gg = + static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator); + return gg->GetVersion(); +} + +//---------------------------------------------------------------------------- void cmLocalVisualStudioGenerator::ComputeObjectFilenames( std::map<cmSourceFile const*, std::string>& mapping, cmGeneratorTarget const* gt) @@ -91,7 +100,7 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, // Add a pre-build event to create the directory. cmCustomCommandLine command; - command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND")); + command.push_back(cmSystemTools::GetCMakeCommand()); command.push_back("-E"); command.push_back("make_directory"); command.push_back(impDir); diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index 1152e82..d414651 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h @@ -13,6 +13,7 @@ #define cmLocalVisualStudioGenerator_h #include "cmLocalGenerator.h" +#include "cmGlobalVisualStudioGenerator.h" #include <cmsys/auto_ptr.hxx> @@ -30,23 +31,9 @@ class cmCustomCommandGenerator; class cmLocalVisualStudioGenerator : public cmLocalGenerator { public: - /** Known versions of Visual Studio. */ - enum VSVersion - { - VS6 = 60, - VS7 = 70, - VS71 = 71, - VS8 = 80, - VS9 = 90, - VS10 = 100, - VS11 = 110, - VS12 = 120, - /* VS13 = 130 was skipped */ - VS14 = 140 - }; - - cmLocalVisualStudioGenerator(VSVersion v, cmGlobalGenerator* gg, - cmLocalGenerator* parent); + cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalVisualStudioGenerator(); /** Construct a script from the given list of command lines. */ @@ -57,8 +44,7 @@ public: sequence of custom commands. */ const char* GetReportErrorLabel() const; - /** Version of Visual Studio. */ - VSVersion GetVersion() const { return this->Version; } + cmGlobalVisualStudioGenerator::VSVersion GetVersion() const; virtual std::string ComputeLongestObjectDirectory(cmTarget&) const = 0; @@ -76,8 +62,6 @@ protected: cmsys::auto_ptr<cmCustomCommand> MaybeCreateImplibDir(cmTarget& target, const std::string& config, bool isFortran); - - VSVersion Version; }; #endif diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index a957c27..804dd7d 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -16,8 +16,9 @@ //---------------------------------------------------------------------------- cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg, - cmLocalGenerator* parent) - : cmLocalGenerator(gg, parent) + cmLocalGenerator* parent, + cmState::Snapshot snapshot) + : cmLocalGenerator(gg, parent, snapshot) { // the global generator does this, so do not // put these flags into the language flags diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h index 54bc6df..26fff9c 100644 --- a/Source/cmLocalXCodeGenerator.h +++ b/Source/cmLocalXCodeGenerator.h @@ -24,7 +24,8 @@ class cmLocalXCodeGenerator : public cmLocalGenerator { public: ///! Set cache only and recurse to false by default. - cmLocalXCodeGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent); + cmLocalXCodeGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, + cmState::Snapshot snapshot); virtual ~cmLocalXCodeGenerator(); virtual std::string GetTargetDirectory(cmTarget const& target) const; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 7ac4432..028ab62 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -96,12 +96,8 @@ bool cmMacroHelperCommand::InvokeInitialPass return false; } - // Enforce matching logical blocks inside the macro. - cmMakefile::LexicalPushPop lexScope(this->Makefile); - - // Push a weak policy scope which restores the policies recorded at - // macro creation. - cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies); + cmMakefile::MacroPushPop macroScope(this->Makefile, + this->Policies); // set the value of argc std::ostringstream argcDefStream; @@ -191,8 +187,7 @@ bool cmMacroHelperCommand::InvokeInitialPass { // The error message should have already included the call stack // so we do not need to report an error here. - lexScope.Quiet(); - polScope.Quiet(); + macroScope.Quiet(); inStatus.SetNestedError(true); return false; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 7b8d3af..a8b163a 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -38,7 +38,6 @@ #include <cmsys/FStream.hxx> #include <cmsys/auto_ptr.hxx> -#include <stack> #include <list> #include <ctype.h> // for isspace #include <assert.h> @@ -47,8 +46,6 @@ class cmMakefile::Internals { public: std::list<cmDefinitions> VarStack; - std::stack<std::set<std::string> > VarInitStack; - std::stack<std::set<std::string> > VarUsageStack; bool IsSourceFileTryCompile; void PushDefinitions() @@ -69,6 +66,12 @@ public: this->VarStack.rend()); } + bool IsInitialized(std::string const& name) + { + return cmDefinitions::HasKey(name, this->VarStack.rbegin(), + this->VarStack.rend()); + } + void SetDefinition(std::string const& name, std::string const& value) { this->VarStack.back().Set(name, value.c_str()); @@ -76,34 +79,18 @@ public: void RemoveDefinition(std::string const& name) { - if (this->VarStack.size() > 1) - { - // In lower scopes we store keys, defined or not. - this->VarStack.back().Set(name, 0); - } - else - { - this->VarStack.back().Erase(name); - } + this->VarStack.back().Set(name, 0); } - std::vector<std::string> LocalKeys() const + std::vector<std::string> UnusedKeys() const { - return this->VarStack.back().LocalKeys(); + return this->VarStack.back().UnusedKeys(); } std::vector<std::string> ClosureKeys() const { - std::vector<std::string> closureKeys; - std::set<std::string> bound; - for (std::list<cmDefinitions>::const_reverse_iterator it = - this->VarStack.rbegin(); it != this->VarStack.rend(); ++it) - { - std::vector<std::string> const& localKeys = it->ClosureKeys(bound); - closureKeys.insert(closureKeys.end(), - localKeys.begin(), localKeys.end()); - } - return closureKeys; + return cmDefinitions::ClosureKeys(this->VarStack.rbegin(), + this->VarStack.rend()); } void PopDefinitions() @@ -113,35 +100,32 @@ public: bool RaiseScope(std::string const& var, const char* varDef, cmMakefile* mf) { - assert(this->VarStack.size() > 0); - std::list<cmDefinitions>::reverse_iterator it = this->VarStack.rbegin(); + assert(it != this->VarStack.rend()); ++it; if(it == this->VarStack.rend()) { - if(cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent()) + cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent(); + if(!plg) { - // Update the definition in the parent directory top scope. This - // directory's scope was initialized by the closure of the parent - // scope, so we do not need to localize the definition first. - cmMakefile* parent = plg->GetMakefile(); - if (varDef) - { - parent->AddDefinition(var, varDef); - } - else - { - parent->RemoveDefinition(var); - } - return true; + return false; + } + // Update the definition in the parent directory top scope. This + // directory's scope was initialized by the closure of the parent + // scope, so we do not need to localize the definition first. + cmMakefile* parent = plg->GetMakefile(); + if (varDef) + { + parent->AddDefinition(var, varDef); } else { - return false; + parent->RemoveDefinition(var); } + return true; } // First localize the definition in the current scope. - this->GetDefinition(var); + cmDefinitions::Raise(var, this->VarStack.rbegin(), this->VarStack.rend()); // Now update the definition in the parent scope. it->Set(var, varDef); @@ -156,15 +140,13 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) StateSnapshot(localGenerator->GetStateSnapshot()) { this->Internal->PushDefinitions(); - this->Internal->VarInitStack.push(std::set<std::string>()); - this->Internal->VarUsageStack.push(std::set<std::string>()); this->Internal->IsSourceFileTryCompile = false; // Initialize these first since AddDefaultDefinitions calls AddDefinition - this->WarnUnused = false; - this->CheckSystemVars = false; + this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused(); + this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); - this->GeneratingBuildSystem = false; + this->Configured = false; this->SuppressWatches = false; // Setup the default include file regular expression (match everything). @@ -231,25 +213,15 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); #endif - this->Properties.SetCMakeInstance(this->GetCMakeInstance()); - this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused(); - this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); - { const char* dir = this->GetCMakeInstance()->GetHomeDirectory(); this->AddDefinition("CMAKE_SOURCE_DIR", dir); - if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") ) - { - this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", dir); - } + this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", dir); } { const char* dir = this->GetCMakeInstance()->GetHomeOutputDirectory(); this->AddDefinition("CMAKE_BINARY_DIR", dir); - if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") ) - { - this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", dir); - } + this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", dir); } } @@ -270,114 +242,69 @@ cmMakefile::~cmMakefile() } } -void cmMakefile::PrintStringVector(const char* s, - const std::vector<std::string>& v) const -{ - std::cout << s << ": ( \n" << cmWrap('"', v, '"', " ") << ")\n"; -} - -void cmMakefile -::PrintStringVector(const char* s, - const std::vector<std::pair<std::string, bool> >& v) const -{ - std::cout << s << ": ( \n"; - for(std::vector<std::pair<std::string, bool> >::const_iterator i - = v.begin(); i != v.end(); ++i) - { - std::cout << i->first << " " << i->second; - } - std::cout << " )\n"; -} - - -// call print on all the classes in the makefile -void cmMakefile::Print() const -{ - // print the class lists - std::cout << "classes:\n"; - - std::cout << " this->Targets: "; - for (cmTargets::iterator l = this->Targets.begin(); - l != this->Targets.end(); l++) - { - std::cout << l->first << std::endl; - } - - std::cout << " this->StartOutputDirectory; " << - this->GetCurrentBinaryDirectory() << std::endl; - std::cout << " this->HomeOutputDirectory; " << - this->GetHomeOutputDirectory() << std::endl; - std::cout << " this->cmStartDirectory; " << - this->GetCurrentSourceDirectory() << std::endl; - std::cout << " this->cmHomeDirectory; " << - this->GetHomeDirectory() << std::endl; - std::cout << " this->ProjectName; " - << this->ProjectName << std::endl; - this->PrintStringVector("this->LinkDirectories", this->LinkDirectories); -#if defined(CMAKE_BUILD_WITH_CMAKE) - for( std::vector<cmSourceGroup>::const_iterator i = - this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i) - { - std::cout << "Source Group: " << i->GetName() << std::endl; - } -#endif -} - //---------------------------------------------------------------------------- void cmMakefile::IssueMessage(cmake::MessageType t, std::string const& text) const { // Collect context information. - cmLocalGenerator* localGen = this->GetLocalGenerator(); - if(this->CallStack.empty() && this->GetCMakeInstance()->GetIsInTryCompile()) - { - localGen = 0; - } - cmListFileBacktrace backtrace(localGen); if(!this->CallStack.empty()) { if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR)) { this->CallStack.back().Status->SetNestedError(true); } - backtrace = this->GetBacktrace(); + this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace()); } else { cmListFileContext lfc; - if(this->ListFileStack.empty()) - { - // We are not processing the project. Add the directory-level context. - lfc.FilePath = this->GetCurrentSourceDirectory(); - lfc.FilePath += "/CMakeLists.txt"; - } - else + // We are not currently executing a command. Add whatever context + // information we have. + lfc.FilePath = this->ListFileStack.back(); + + if(!this->GetCMakeInstance()->GetIsInTryCompile()) { - // We are processing the project but are not currently executing a - // command. Add whatever context information we have. - lfc.FilePath = this->ListFileStack.back(); + lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath, + cmLocalGenerator::HOME); } lfc.Line = 0; - backtrace.push_back(lfc); + this->GetCMakeInstance()->IssueMessage(t, text, lfc); } - - // Issue the message. - this->GetCMakeInstance()->IssueMessage(t, text, backtrace); } //---------------------------------------------------------------------------- cmListFileBacktrace cmMakefile::GetBacktrace() const { - cmListFileBacktrace backtrace(this->GetLocalGenerator()); + cmListFileBacktrace backtrace(this->StateSnapshot); for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin(); i != this->CallStack.rend(); ++i) { - backtrace.push_back(*i->Context); + backtrace.Append(*i->Context); } return backtrace; } //---------------------------------------------------------------------------- +cmListFileBacktrace +cmMakefile::GetBacktrace(cmListFileContext const& lfc) const +{ + cmListFileBacktrace backtrace(this->StateSnapshot); + backtrace.Append(lfc); + for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin(); + i != this->CallStack.rend(); ++i) + { + backtrace.Append(*i->Context); + } + return backtrace; +} + +//---------------------------------------------------------------------------- +cmListFileContext cmMakefile::GetExecutionContext() const +{ + return *this->CallStack.back().Context; +} + +//---------------------------------------------------------------------------- void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const { std::ostringstream msg; @@ -603,25 +530,29 @@ void cmMakefile::IncludeScope::EnforceCMP0011() bool cmMakefile::ProcessBuildsystemFile(const char* listfile) { this->AddDefinition("CMAKE_PARENT_LIST_FILE", listfile); - this->cmCurrentListFile = listfile; std::string curSrc = this->GetCurrentSourceDirectory(); - return this->ReadListFile(listfile, true, - curSrc == this->GetHomeDirectory()); + bool result = this->ReadListFile(listfile, true, + curSrc == this->GetHomeDirectory()); + this->EnforceDirectoryLevelRules(); + return result; } bool cmMakefile::ReadDependentFile(const char* listfile, bool noPolicyScope) { - this->AddDefinition("CMAKE_PARENT_LIST_FILE", this->GetCurrentListFile()); - this->cmCurrentListFile = - cmSystemTools::CollapseFullPath(listfile, - this->GetCurrentSourceDirectory()); - return this->ReadListFile(this->cmCurrentListFile.c_str(), - noPolicyScope); + this->AddDefinition("CMAKE_PARENT_LIST_FILE", + this->GetDefinition("CMAKE_CURRENT_LIST_FILE")); + bool result = this->ReadListFile(listfile, noPolicyScope, false); + this->ListFileStack.pop_back(); + return result; +} + +bool cmMakefile::ReadListFile(const char* listfile) +{ + bool result = this->ReadListFile(listfile, true, false); + this->ListFileStack.pop_back(); + return result; } -//---------------------------------------------------------------------------- -// Parse the given CMakeLists.txt file executing all commands -// bool cmMakefile::ReadListFile(const char* listfile, bool noPolicyScope, bool requireProjectCommand) @@ -656,11 +587,8 @@ bool cmMakefile::ReadListFile(const char* listfile, this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); - this->ListFileStack.pop_back(); - if (res) { - // Check for unused variables this->CheckForUnusedVariables(); } @@ -705,13 +633,6 @@ bool cmMakefile::ReadListFileInternal(const char* filenametoread, } } - // If this is the directory-level CMakeLists.txt file then perform - // some extra checks. - if(this->ListFileStack.size() == 1) - { - this->EnforceDirectoryLevelRules(); - } - return true; } @@ -1562,10 +1483,8 @@ void cmMakefile::AddLinkDirectory(const std::string& dir) } } -void cmMakefile::InitializeFromParent() +void cmMakefile::InitializeFromParent(cmMakefile* parent) { - cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile(); - // Initialize definitions with the closure of the parent scope. this->Internal->InitializeDefinitions(parent); @@ -1639,10 +1558,118 @@ void cmMakefile::InitializeFromParent() this->ImportedTargets = parent->ImportedTargets; } -void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) +void cmMakefile::PushFunctionScope(const cmPolicies::PolicyMap& pm) { - lg2->GetMakefile()->InitializeFromParent(); - std::string currentStart = lg2->GetMakefile()->GetCurrentSourceDirectory(); + this->Internal->PushDefinitions(); + + this->PushLoopBlockBarrier(); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope(); +#endif + + this->PushFunctionBlockerBarrier(); + + this->PushPolicy(true, pm); + this->PushPolicyBarrier(); +} + +void cmMakefile::PopFunctionScope(bool reportError) +{ + this->PopPolicyBarrier(reportError); + this->PopPolicy(); + + this->PopFunctionBlockerBarrier(reportError); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope(); +#endif + + this->PopLoopBlockBarrier(); + + this->CheckForUnusedVariables(); + + this->Internal->PopDefinitions(); +} + +void cmMakefile::PushMacroScope(const cmPolicies::PolicyMap& pm) +{ + this->PushFunctionBlockerBarrier(); + + this->PushPolicy(true, pm); + this->PushPolicyBarrier(); +} + +void cmMakefile::PopMacroScope(bool reportError) +{ + this->PopPolicyBarrier(reportError); + this->PopPolicy(); + + this->PopFunctionBlockerBarrier(reportError); +} + +//---------------------------------------------------------------------------- +class cmMakefileCurrent +{ + cmGlobalGenerator* GG; + cmMakefile* MF; + cmState::Snapshot Snapshot; +public: + cmMakefileCurrent(cmMakefile* mf) + { + this->GG = mf->GetGlobalGenerator(); + this->MF = this->GG->GetCurrentMakefile(); + this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot(); + this->GG->GetCMakeInstance()->SetCurrentSnapshot( + this->GG->GetCMakeInstance()->GetCurrentSnapshot()); + this->GG->SetCurrentMakefile(mf); +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PushFileScope(); +#endif + } + ~cmMakefileCurrent() + { +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PopFileScope(); +#endif + this->GG->SetCurrentMakefile(this->MF); + this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); + } +}; + +//---------------------------------------------------------------------------- +void cmMakefile::Configure() +{ + cmMakefileCurrent cmf(this); + + // make sure the CMakeFiles dir is there + std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory(); + filesDir += cmake::GetCMakeFilesDirectory(); + cmSystemTools::MakeDirectory(filesDir.c_str()); + + std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory(); + currentStart += "/CMakeLists.txt"; + assert(cmSystemTools::FileExists(currentStart.c_str(), true)); + this->ProcessBuildsystemFile(currentStart.c_str()); + + // at the end handle any old style subdirs + std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories; + + // for each subdir recurse + std::vector<cmMakefile*>::iterator sdi = subdirs.begin(); + for (; sdi != subdirs.end(); ++sdi) + { + this->ConfigureSubDirectory(*sdi); + } + + this->AddCMakeDependFilesFromUser(); + this->SetConfigured(); +} + +void cmMakefile::ConfigureSubDirectory(cmMakefile *mf) +{ + mf->InitializeFromParent(this); + std::string currentStart = mf->GetCurrentSourceDirectory(); if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg=" Entering "; @@ -1680,11 +1707,12 @@ void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) // NEW behavior prints the error. this->IssueMessage(cmake::FATAL_ERROR, e.str()); } - lg2->SetConfiguredCMP0014(true); + mf->SetConfigured(); return; } // finally configure the subdir - lg2->Configure(); + mf->Configure(); + if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg=" Returning to "; @@ -1704,22 +1732,31 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, return; } + cmState::Snapshot newSnapshot = this->GetState() + ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot); + // create a new local generator and set its parent cmLocalGenerator *lg2 = this->GetGlobalGenerator() - ->CreateLocalGenerator(this->LocalGenerator); + ->MakeLocalGenerator(newSnapshot, this->LocalGenerator); this->GetGlobalGenerator()->AddLocalGenerator(lg2); + cmMakefile* subMf = lg2->GetMakefile(); + // set the subdirs start dirs - lg2->GetMakefile()->SetCurrentSourceDirectory(srcPath); - lg2->GetMakefile()->SetCurrentBinaryDirectory(binPath); + subMf->SetCurrentSourceDirectory(srcPath); + subMf->SetCurrentBinaryDirectory(binPath); if(excludeFromAll) { - lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } if (immediate) { - this->ConfigureSubDirectory(lg2); + this->ConfigureSubDirectory(subMf); + } + else + { + this->UnConfiguredDirectories.push_back(subMf); } } @@ -1795,14 +1832,11 @@ void cmMakefile::AddDefinition(const std::string& name, const char* value) return; } - this->Internal->SetDefinition(name, value); - if (!this->Internal->VarUsageStack.empty() && - this->VariableInitialized(name)) + if (this->VariableInitialized(name)) { - this->CheckForUnused("changing definition", name); - this->Internal->VarUsageStack.top().erase(name); + this->LogUnused("changing definition", name); } - this->Internal->VarInitStack.top().insert(name); + this->Internal->SetDefinition(name, value); #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* vv = this->GetVariableWatch(); @@ -1871,14 +1905,11 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, void cmMakefile::AddDefinition(const std::string& name, bool value) { - this->Internal->SetDefinition(name, value ? "ON" : "OFF"); - if (!this->Internal->VarUsageStack.empty() && - this->VariableInitialized(name)) + if (this->VariableInitialized(name)) { - this->CheckForUnused("changing definition", name); - this->Internal->VarUsageStack.top().erase(name); + this->LogUnused("changing definition", name); } - this->Internal->VarInitStack.top().insert(name); + this->Internal->SetDefinition(name, value ? "ON" : "OFF"); #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* vv = this->GetVariableWatch(); if ( vv ) @@ -1895,61 +1926,46 @@ void cmMakefile::CheckForUnusedVariables() const { return; } - const std::vector<std::string>& locals = this->Internal->LocalKeys(); - std::vector<std::string>::const_iterator it = locals.begin(); - for (; it != locals.end(); ++it) + const std::vector<std::string>& unused = this->Internal->UnusedKeys(); + std::vector<std::string>::const_iterator it = unused.begin(); + for (; it != unused.end(); ++it) { - this->CheckForUnused("out of scope", *it); + this->LogUnused("out of scope", *it); } } void cmMakefile::MarkVariableAsUsed(const std::string& var) { - this->Internal->VarUsageStack.top().insert(var); + this->Internal->GetDefinition(var); } bool cmMakefile::VariableInitialized(const std::string& var) const { - if(this->Internal->VarInitStack.top().find(var) != - this->Internal->VarInitStack.top().end()) - { - return true; - } - return false; -} - -bool cmMakefile::VariableUsed(const std::string& var) const -{ - if(this->Internal->VarUsageStack.top().find(var) != - this->Internal->VarUsageStack.top().end()) - { - return true; - } - return false; + return this->Internal->IsInitialized(var); } -void cmMakefile::CheckForUnused(const char* reason, +void cmMakefile::LogUnused(const char* reason, const std::string& name) const { - if (this->WarnUnused && !this->VariableUsed(name)) + if (this->WarnUnused) { std::string path; - cmListFileBacktrace bt(this->GetLocalGenerator()); + cmListFileContext lfc; if (!this->CallStack.empty()) { - const cmListFileContext* file = this->CallStack.back().Context; - bt.push_back(*file); - path = file->FilePath.c_str(); + lfc = this->GetExecutionContext(); + path = lfc.FilePath; } else { path = this->GetCurrentSourceDirectory(); path += "/CMakeLists.txt"; - cmListFileContext lfc; lfc.FilePath = path; lfc.Line = 0; - bt.push_back(lfc); } + lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath, + cmLocalGenerator::HOME); + if (this->CheckSystemVars || cmSystemTools::IsSubDirectory(path, this->GetHomeDirectory()) || @@ -1962,21 +1978,18 @@ void cmMakefile::CheckForUnused(const char* reason, msg << "unused variable (" << reason << ") \'" << name << "\'"; this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, msg.str(), - bt); + lfc); } } } void cmMakefile::RemoveDefinition(const std::string& name) { - this->Internal->RemoveDefinition(name); - if (!this->Internal->VarUsageStack.empty() && - this->VariableInitialized(name)) + if (this->VariableInitialized(name)) { - this->CheckForUnused("unsetting", name); - this->Internal->VarUsageStack.top().erase(name); + this->LogUnused("unsetting", name); } - this->Internal->VarInitStack.top().insert(name); + this->Internal->RemoveDefinition(name); #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* vv = this->GetVariableWatch(); if ( vv ) @@ -2223,25 +2236,10 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name, return; } // build the whole source group path - const char* fullname = sg->GetFullName(); - cmGlobalGenerator* gg = this->GetGlobalGenerator(); - if(strlen(fullname)) - { - std::string guidName = "SG_Filter_"; - guidName += fullname; - gg->CreateGUID(guidName); - } for(++i; i<=lastElement; ++i) { sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName())); sg = sg->LookupChild(name[i].c_str()); - fullname = sg->GetFullName(); - if(strlen(fullname)) - { - std::string guidName = "SG_Filter_"; - guidName += fullname; - gg->CreateGUID(guidName); - } } sg->SetGroupRegex(regex); @@ -2443,7 +2441,6 @@ const char* cmMakefile::GetRequiredDefinition(const std::string& name) const bool cmMakefile::IsDefinitionSet(const std::string& name) const { const char* def = this->Internal->GetDefinition(name); - this->Internal->VarUsageStack.top().insert(name); if(!def) { def = this->GetState()->GetInitializedCacheValue(name); @@ -2464,10 +2461,6 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const const char* cmMakefile::GetDefinition(const std::string& name) const { - if (this->WarnUnused) - { - this->Internal->VarUsageStack.top().insert(name); - } const char* def = this->Internal->GetDefinition(name); if(!def) { @@ -2502,18 +2495,11 @@ const char* cmMakefile::GetSafeDefinition(const std::string& def) const return ret; } -std::vector<std::string> cmMakefile -::GetDefinitions(int cacheonly /* = 0 */) const +std::vector<std::string> cmMakefile::GetDefinitions() const { - std::vector<std::string> res; - if ( !cacheonly ) - { - res = this->Internal->ClosureKeys(); - } - std::vector<std::string> cacheKeys = - this->GetState()->GetCacheEntryKeys(); + std::vector<std::string> res = this->Internal->ClosureKeys(); + std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys(); res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); - std::sort(res.begin(), res.end()); return res; } @@ -2874,14 +2860,13 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( this->GetHomeOutputDirectory())) { std::ostringstream msg; - cmListFileBacktrace bt(this->GetLocalGenerator()); cmListFileContext lfc; - lfc.FilePath = filename; + lfc.FilePath = this->LocalGenerator + ->Convert(filename, cmLocalGenerator::HOME); lfc.Line = line; - bt.push_back(lfc); msg << "uninitialized variable \'" << lookup << "\'"; this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, - msg.str(), bt); + msg.str(), lfc); } } } @@ -3276,6 +3261,7 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) this->FunctionBlockerBarriers.back(); while(this->FunctionBlockers.size() > barrier) { + cmMakefile::LoopBlockPop loopBlockPop(this); cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back()); this->FunctionBlockers.pop_back(); if(reportError) @@ -3410,7 +3396,7 @@ void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb) if(!this->CallStack.empty()) { // Record the context in which the blocker is created. - fb->SetStartingContext(*(this->CallStack.back().Context)); + fb->SetStartingContext(this->GetExecutionContext()); } this->FunctionBlockers.push_back(fb); @@ -3576,7 +3562,6 @@ int cmMakefile::TryCompile(const std::string& srcdir, // 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"); cmake cm; cm.SetIsInTryCompile(true); cmGlobalGenerator *gg = cm.CreateGlobalGenerator @@ -4095,7 +4080,7 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value) } } - this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY); + this->Properties.SetProperty(prop, value); } void cmMakefile::AppendProperty(const std::string& prop, @@ -4135,23 +4120,26 @@ void cmMakefile::AppendProperty(const std::string& prop, return; } - this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString); + this->Properties.AppendProperty(prop, value, asString); } const char *cmMakefile::GetProperty(const std::string& prop) const { - return this->GetProperty(prop, cmProperty::DIRECTORY); + const bool chain = this->GetState()-> + IsPropertyChained(prop, cmProperty::DIRECTORY); + return this->GetProperty(prop, chain); } const char *cmMakefile::GetProperty(const std::string& prop, - cmProperty::ScopeType scope) const + bool chain) const { // watch for specific properties static std::string output; output = ""; if (prop == "PARENT_DIRECTORY") { - cmState::Snapshot parent = this->StateSnapshot.GetParent(); + cmState::Snapshot parent = + this->StateSnapshot.GetBuildsystemDirectoryParent(); if(parent.IsValid()) { return parent.GetCurrentSourceDirectory(); @@ -4168,14 +4156,14 @@ const char *cmMakefile::GetProperty(const std::string& prop, output = cmJoin(this->ListFileStack, ";"); return output.c_str(); } - else if (prop == "VARIABLES" || prop == "CACHE_VARIABLES") + else if ( prop == "CACHE_VARIABLES" ) { - int cacheonly = 0; - if ( prop == "CACHE_VARIABLES" ) - { - cacheonly = 1; - } - output = cmJoin(this->GetDefinitions(cacheonly), ";"); + output = cmJoin(this->GetState()->GetCacheEntryKeys(), ";"); + return output.c_str(); + } + else if (prop == "VARIABLES") + { + output = cmJoin(this->GetDefinitions(), ";"); return output.c_str(); } else if (prop == "MACROS") @@ -4247,15 +4235,13 @@ const char *cmMakefile::GetProperty(const std::string& prop, return output.c_str(); } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, scope, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal && chain) { if(this->LocalGenerator->GetParent()) { return this->LocalGenerator->GetParent()->GetMakefile()-> - GetProperty(prop, scope); + GetProperty(prop, chain); } return this->GetState()->GetGlobalProperty(prop); } @@ -4268,33 +4254,6 @@ bool cmMakefile::GetPropertyAsBool(const std::string& prop) const return cmSystemTools::IsOn(this->GetProperty(prop)); } -//---------------------------------------------------------------------------- -const char* cmMakefile::GetFeature(const std::string& feature, - const std::string& config) -{ - // TODO: Define accumulation policy for features (prepend, append, replace). - // Currently we always replace. - if(!config.empty()) - { - std::string featureConfig = feature; - featureConfig += "_"; - featureConfig += cmSystemTools::UpperCase(config); - if(const char* value = this->GetProperty(featureConfig)) - { - return value; - } - } - if(const char* value = this->GetProperty(feature)) - { - return value; - } - if(cmLocalGenerator* parent = this->LocalGenerator->GetParent()) - { - return parent->GetMakefile()->GetFeature(feature, config); - } - return 0; -} - cmTarget* cmMakefile::FindTarget(const std::string& name, bool excludeAliases) const { @@ -4365,13 +4324,13 @@ void cmMakefile::AddCMakeDependFilesFromUser() } } -std::string cmMakefile::GetListFileStack() const +std::string cmMakefile::FormatListFileStack() const { std::ostringstream tmp; size_t depth = this->ListFileStack.size(); if (depth > 0) { - std::deque<std::string>::const_iterator it = this->ListFileStack.end(); + std::vector<std::string>::const_iterator it = this->ListFileStack.end(); do { if (depth != this->ListFileStack.size()) @@ -4394,10 +4353,6 @@ std::string cmMakefile::GetListFileStack() const void cmMakefile::PushScope() { this->Internal->PushDefinitions(); - const std::set<std::string>& init = this->Internal->VarInitStack.top(); - const std::set<std::string>& usage = this->Internal->VarUsageStack.top(); - this->Internal->VarInitStack.push(init); - this->Internal->VarUsageStack.push(usage); this->PushLoopBlockBarrier(); @@ -4414,31 +4369,9 @@ void cmMakefile::PopScope() this->PopLoopBlockBarrier(); - std::set<std::string> init = this->Internal->VarInitStack.top(); - std::set<std::string> usage = this->Internal->VarUsageStack.top(); - const std::vector<std::string>& locals = this->Internal->LocalKeys(); - // Remove initialization and usage information for variables in the local - // scope. - std::vector<std::string>::const_iterator it = locals.begin(); - for (; it != locals.end(); ++it) - { - init.erase(*it); - if (!this->VariableUsed(*it)) - { - this->CheckForUnused("out of scope", *it); - } - else - { - usage.erase(*it); - } - } + this->CheckForUnusedVariables(); this->Internal->PopDefinitions(); - this->Internal->VarInitStack.pop(); - this->Internal->VarUsageStack.pop(); - // Push initialization and usage up to the parent scope. - this->Internal->VarInitStack.top().insert(init.begin(), init.end()); - this->Internal->VarUsageStack.top().insert(usage.begin(), usage.end()); } void cmMakefile::RaiseScope(const std::string& var, const char *varDef) @@ -4736,6 +4669,11 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re) this->MarkVariableAsUsed(nMatchesVariable); } +cmState::Snapshot cmMakefile::GetStateSnapshot() const +{ + return this->StateSnapshot; +} + //---------------------------------------------------------------------------- cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const @@ -4935,20 +4873,9 @@ bool cmMakefile::SetPolicyVersion(const char *version) } //---------------------------------------------------------------------------- -bool cmMakefile::HasCMP0054AlreadyBeenReported( - cmListFileContext context) const +bool cmMakefile::HasCMP0054AlreadyBeenReported() const { - cmCMP0054Id id(context); - - bool alreadyReported = - this->CMP0054ReportedIds.find(id) != this->CMP0054ReportedIds.end(); - - if(!alreadyReported) - { - this->CMP0054ReportedIds.insert(id); - } - - return alreadyReported; + return !this->CMP0054ReportedIds.insert(this->GetExecutionContext()).second; } //---------------------------------------------------------------------------- @@ -5508,3 +5435,41 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const } return true; } + + +cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf, + cmPolicies::PolicyMap const& pm) + : Makefile(mf), ReportError(true) +{ + this->Makefile->PushFunctionScope(pm); +} + +cmMakefile::FunctionPushPop::~FunctionPushPop() +{ + this->Makefile->PopFunctionScope(this->ReportError); +} + + +cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf, + const cmPolicies::PolicyMap& pm) + : Makefile(mf), ReportError(true) +{ + this->Makefile->PushMacroScope(pm); +} + +cmMakefile::MacroPushPop::~MacroPushPop() +{ + this->Makefile->PopMacroScope(this->ReportError); +} + +cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmListFileContext& lfc, + cmExecutionStatus& status): Makefile(mf) +{ + cmMakefile::CallStackEntry entry = {&lfc, &status}; + this->Makefile->CallStack.push_back(entry); +} + +cmMakefileCall::~cmMakefileCall() +{ + this->Makefile->CallStack.pop_back(); +} diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index e0eef6f..6f6ed27 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -14,7 +14,6 @@ #include "cmExecutionStatus.h" #include "cmListFileCache.h" -#include "cmPolicies.h" #include "cmPropertyMap.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -31,11 +30,14 @@ #include <cmsys/auto_ptr.hxx> #include <cmsys/RegularExpression.hxx> #if defined(CMAKE_BUILD_WITH_CMAKE) -# include <cmsys/hash_map.hxx> +# ifdef CMake_HAVE_CXX11_UNORDERED_MAP +# include <unordered_map> +# else +# include <cmsys/hash_map.hxx> +# endif #endif #include <stack> -#include <deque> class cmFunctionBlocker; class cmCommand; @@ -62,14 +64,10 @@ class cmMakefile class Internals; cmsys::auto_ptr<Internals> Internal; public: - /* Check for unused variables in this scope */ - void CheckForUnusedVariables() const; /* Mark a variable as used */ void MarkVariableAsUsed(const std::string& var); /* return true if a variable has been initialized */ bool VariableInitialized(const std::string& ) const; - /* return true if a variable has been used */ - bool VariableUsed(const std::string& ) const; /** * Construct an empty makefile. @@ -81,12 +79,7 @@ public: */ ~cmMakefile(); - /** - * Read and parse a CMakeLists.txt file. - */ - bool ReadListFile(const char* listfile, - bool noPolicyScope = true, - bool requireProjectCommand = false); + bool ReadListFile(const char* listfile); bool ReadDependentFile(const char* listfile, bool noPolicyScope = true); @@ -159,11 +152,6 @@ public: */ void FinalPass(); - /** - * Print the object state to std::cout. - */ - void Print() const; - /** Add a custom command to the build. */ void AddCustomCommandToTarget(const std::string& target, const std::vector<std::string>& byproducts, @@ -281,10 +269,12 @@ public: bool excludeFromAll, bool immediate); + void Configure(); + /** * Configure a subdirectory */ - void ConfigureSubDirectory(cmLocalGenerator *); + void ConfigureSubDirectory(cmMakefile* mf); /** * Add an include directory to the build. @@ -383,37 +373,10 @@ public: friend class PolicyPushPop; /** - * Get the Policies Instance - */ - cmPolicies *GetPolicies() const; - - struct cmCMP0054Id - { - cmCMP0054Id(cmListFileContext const& context): - Context(context) - { - - } - - bool operator< (cmCMP0054Id const& id) const - { - if(this->Context.FilePath != id.Context.FilePath) - return this->Context.FilePath < id.Context.FilePath; - - return this->Context.Line < id.Context.Line; - } - - cmListFileContext Context; - }; - - mutable std::set<cmCMP0054Id> CMP0054ReportedIds; - - /** * Determine if the given context, name pair has already been reported * in context of CMP0054. */ - bool HasCMP0054AlreadyBeenReported( - cmListFileContext context) const; + bool HasCMP0054AlreadyBeenReported() const; bool IgnoreErrorsCMP0061() const; @@ -435,14 +398,6 @@ public: void SetCurrentBinaryDirectory(const std::string& dir); const char* GetCurrentBinaryDirectory() const; - /* Get the current CMakeLists.txt file that is being processed. This - * is just used in order to be able to 'branch' from one file to a second - * transparently */ - const char* GetCurrentListFile() const - { - return this->cmCurrentListFile.c_str(); - } - //@} /** @@ -554,7 +509,7 @@ public: * cacheonly is specified and is greater than 0, then only cache * variables will be listed. */ - std::vector<std::string> GetDefinitions(int cacheonly=0) const; + std::vector<std::string> GetDefinitions() const; /** * Test a boolean variable to see if it is true or false. @@ -605,12 +560,14 @@ public: { this->ListFiles.push_back(file);} void AddCMakeDependFilesFromUser(); - std::string GetListFileStack() const; + std::string FormatListFileStack() const; /** * Get the current context backtrace. */ cmListFileBacktrace GetBacktrace() const; + cmListFileBacktrace GetBacktrace(cmListFileContext const& lfc) const; + cmListFileContext GetExecutionContext() const; /** * Get the vector of files created by this makefile @@ -758,18 +715,14 @@ public: void AppendProperty(const std::string& prop, const char *value, bool asString=false); const char *GetProperty(const std::string& prop) const; - const char *GetProperty(const std::string& prop, - cmProperty::ScopeType scope) const; + const char *GetProperty(const std::string& prop, bool chain) const; bool GetPropertyAsBool(const std::string& prop) const; - const char* GetFeature(const std::string& feature, - const std::string& config); - // Get the properties cmPropertyMap &GetProperties() { return this->Properties; } ///! Initialize a makefile from its parent - void InitializeFromParent(); + void InitializeFromParent(cmMakefile* parent); void AddInstallGenerator(cmInstallGenerator* g) { if(g) this->InstallGenerators.push_back(g); } @@ -781,7 +734,36 @@ public: const std::vector<cmTestGenerator*>& GetTestGenerators() const { return this->TestGenerators; } - // push and pop variable scopes + class FunctionPushPop + { + public: + FunctionPushPop(cmMakefile* mf, + cmPolicies::PolicyMap const& pm); + ~FunctionPushPop(); + + void Quiet() { this->ReportError = false; } + private: + cmMakefile* Makefile; + bool ReportError; + }; + + class MacroPushPop + { + public: + MacroPushPop(cmMakefile* mf, + cmPolicies::PolicyMap const& pm); + ~MacroPushPop(); + + void Quiet() { this->ReportError = false; } + private: + cmMakefile* Makefile; + bool ReportError; + }; + + void PushFunctionScope(cmPolicies::PolicyMap const& pm); + void PopFunctionScope(bool reportError); + void PushMacroScope(cmPolicies::PolicyMap const& pm); + void PopMacroScope(bool reportError); void PushScope(); void PopScope(); void RaiseScope(const std::string& var, const char *value); @@ -819,8 +801,8 @@ public: return this->CompileDefinitionsEntries; } - bool IsGeneratingBuildSystem() const { return this->GeneratingBuildSystem; } - void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; } + bool IsConfigured() const { return this->Configured; } + void SetConfigured(){ this->Configured = true; } void AddQtUiFileWithOptions(cmSourceFile *sf); std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const; @@ -854,21 +836,27 @@ public: void ClearMatches(); void StoreMatches(cmsys::RegularExpression& re); + cmState::Snapshot GetStateSnapshot() const; + protected: // add link libraries and directories to the target void AddGlobalLinkInformation(const std::string& name, cmTarget& target); // Check for a an unused variable - void CheckForUnused(const char* reason, const std::string& name) const; + void LogUnused(const char* reason, const std::string& name) const; - std::string cmCurrentListFile; + mutable std::set<cmListFileContext> CMP0054ReportedIds; std::string ProjectName; // project name // libraries, classes, and executables mutable cmTargets Targets; #if defined(CMAKE_BUILD_WITH_CMAKE) +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP + typedef std::unordered_map<std::string, cmTarget*> TargetMap; +#else typedef cmsys::hash_map<std::string, cmTarget*> TargetMap; +#endif #else typedef std::map<std::string, cmTarget*> TargetMap; #endif @@ -924,6 +912,10 @@ private: cmState::Snapshot StateSnapshot; + bool ReadListFile(const char* listfile, + bool noPolicyScope, + bool requireProjectCommand); + bool ReadListFileInternal(const char* filenametoread, bool noPolicyScope, bool requireProjectCommand); @@ -935,10 +927,6 @@ private: friend class cmMakeDepend; // make depend needs direct access // to the Sources array - void PrintStringVector(const char* s, const - std::vector<std::pair<std::string, bool> >& v) const; - void PrintStringVector(const char* s, - const std::vector<std::string>& v) const; void AddDefaultDefinitions(); typedef std::vector<cmFunctionBlocker*> FunctionBlockersType; @@ -956,14 +944,12 @@ private: mutable cmsys::RegularExpression cmAtVarRegex; mutable cmsys::RegularExpression cmNamedCurly; - cmPropertyMap Properties; + std::vector<cmMakefile*> UnConfiguredDirectories; - // Unused variable flags - bool WarnUnused; - bool CheckSystemVars; + cmPropertyMap Properties; // stack of list files being read - std::deque<std::string> ListFileStack; + std::vector<std::string> ListFileStack; // stack of commands being invoked. struct CallStackEntry @@ -971,7 +957,7 @@ private: cmListFileContext const* Context; cmExecutionStatus* Status; }; - typedef std::deque<CallStackEntry> CallStackType; + typedef std::vector<CallStackEntry> CallStackType; CallStackType CallStack; friend class cmMakefileCall; @@ -1003,8 +989,6 @@ private: cmPolicies::PolicyStatus GetPolicyStatusInternal(cmPolicies::PolicyID id) const; - bool CheckCMP0000; - // Enforce rules about CMakeLists.txt files. void EnforceDirectoryLevelRules() const; @@ -1030,7 +1014,6 @@ private: long line, bool removeEmpty, bool replaceAt) const; - bool GeneratingBuildSystem; /** * Old version of GetSourceFileWithOutput(const std::string&) kept for * backward-compatibility. It implements a linear search and support @@ -1041,7 +1024,11 @@ private: // A map for fast output to input look up. #if defined(CMAKE_BUILD_WITH_CMAKE) +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP + typedef std::unordered_map<std::string, cmSourceFile*> OutputToSourceMap; +#else typedef cmsys::hash_map<std::string, cmSourceFile*> OutputToSourceMap; +#endif #else typedef std::map<std::string, cmSourceFile*> OutputToSourceMap; #endif @@ -1070,6 +1057,13 @@ private: bool HaveCxxStandardAvailable(cmTarget const* target, const std::string& feature) const; + void CheckForUnusedVariables() const; + + // Unused variable flags + bool WarnUnused; + bool CheckSystemVars; + bool CheckCMP0000; + bool Configured; mutable bool SuppressWatches; }; @@ -1080,15 +1074,8 @@ class cmMakefileCall public: cmMakefileCall(cmMakefile* mf, cmListFileContext const& lfc, - cmExecutionStatus& status): Makefile(mf) - { - cmMakefile::CallStackEntry entry = {&lfc, &status}; - this->Makefile->CallStack.push_back(entry); - } - ~cmMakefileCall() - { - this->Makefile->CallStack.pop_back(); - } + cmExecutionStatus& status); + ~cmMakefileCall(); private: cmMakefile* Makefile; }; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index c001622..450f573 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -626,7 +626,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules install_name_dir = this->LocalGenerator->Convert(install_name_dir, cmLocalGenerator::NONE, - cmLocalGenerator::SHELL, false); + cmLocalGenerator::SHELL); vars.TargetInstallNameDir = install_name_dir.c_str(); } } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 2ee23d1..923aa7b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -226,7 +226,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() dependFileNameFull += "/depend.make"; *this->BuildFileStream << "# Include any dependencies generated for this target.\n" - << this->LocalGenerator->IncludeDirective << " " << root + << this->GlobalGenerator->IncludeDirective << " " << root << this->Convert(dependFileNameFull, cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKERULE) @@ -237,7 +237,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() // Include the progress variables for the target. *this->BuildFileStream << "# Include the progress variables for this target.\n" - << this->LocalGenerator->IncludeDirective << " " << root + << this->GlobalGenerator->IncludeDirective << " " << root << this->Convert(this->ProgressFileNameFull, cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKERULE) @@ -270,7 +270,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() // Include the flags for the target. *this->BuildFileStream << "# Include the compile flags for this target's objects.\n" - << this->LocalGenerator->IncludeDirective << " " << root + << this->GlobalGenerator->IncludeDirective << " " << root << this->Convert(this->FlagFileNameFull, cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKERULE) @@ -614,13 +614,7 @@ cmMakefileTargetGenerator } // Get the output paths for source and object files. - std::string sourceFile = source.GetFullPath(); - if(this->LocalGenerator->UseRelativePaths) - { - sourceFile = this->Convert(sourceFile, - cmLocalGenerator::START_OUTPUT); - } - sourceFile = this->Convert(sourceFile, + std::string sourceFile = this->Convert(source.GetFullPath(), cmLocalGenerator::NONE, cmLocalGenerator::SHELL); @@ -761,6 +755,20 @@ cmMakefileTargetGenerator source.GetFullPath(), workingDirectory, compileCommand); } + // Maybe insert an include-what-you-use runner. + if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) + { + std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE"; + const char *iwyu = this->Target->GetProperty(iwyu_prop); + if (iwyu && *iwyu) + { + std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_iwyu --iwyu="; + run_iwyu += this->LocalGenerator->EscapeForShell(iwyu); + run_iwyu += " -- "; + compileCommands.front().insert(0, run_iwyu); + } + } + // Expand placeholders in the commands. for(std::vector<std::string>::iterator i = compileCommands.begin(); i != compileCommands.end(); ++i) @@ -1118,8 +1126,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() pi != this->MultipleOutputPairs.end(); ++pi) { *this->InfoFileStream - << " " << cmLocalGenerator::EscapeForCMake(pi->first) - << " " << cmLocalGenerator::EscapeForCMake(pi->second) + << " " << cmOutputConverter::EscapeForCMake(pi->first) + << " " << cmOutputConverter::EscapeForCMake(pi->second) << "\n"; } *this->InfoFileStream << " )\n\n"; @@ -1581,9 +1589,8 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l) if(emitted.insert(*i).second) { flags += fwSearchFlag; - flags += this->Convert(*i, - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL, true); + flags += this->LocalGenerator + ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL); flags += " "; } } @@ -2079,13 +2086,13 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) //---------------------------------------------------------------------------- const char* cmMakefileTargetGenerator::GetFeature(const std::string& feature) { - return this->Target->GetFeature(feature, this->ConfigName); + return this->GeneratorTarget->GetFeature(feature, this->ConfigName); } //---------------------------------------------------------------------------- bool cmMakefileTargetGenerator::GetFeatureAsBool(const std::string& feature) { - return this->Target->GetFeatureAsBool(feature, this->ConfigName); + return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 58044e8..2e1b052 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -273,10 +273,9 @@ protected: std::string Convert(const std::string& source, cmLocalGenerator::RelativeRoot relative, cmLocalGenerator::OutputFormat output = - cmLocalGenerator::UNCHANGED, - bool optional = false) + cmLocalGenerator::UNCHANGED) { - return this->LocalGenerator->Convert(source, relative, output, optional); + return this->LocalGenerator->Convert(source, relative, output); } }; diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 617214f..25d929c 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -51,7 +51,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles() // Include the progress variables for the target. *this->BuildFileStream << "# Include the progress variables for this target.\n" - << this->LocalGenerator->IncludeDirective << " " << root + << this->GlobalGenerator->IncludeDirective << " " << root << this->Convert(this->ProgressFileNameFull, cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKERULE) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 771ecc4..bbf03ff 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -94,8 +94,6 @@ void cmNinjaNormalTargetGenerator::Generate() } else { - this->WriteLinkRule(false); // write rule without rspfile support - this->WriteLinkRule(true); // write rule with rspfile support this->WriteLinkStatement(); } } @@ -160,7 +158,9 @@ cmNinjaNormalTargetGenerator return this->TargetLinkLanguage + "_" + cmTarget::GetTargetTypeName(this->GetTarget()->GetType()) - + "_LINKER"; + + "_LINKER__" + + cmGlobalNinjaGenerator::EncodeRuleName(this->GetTarget()->GetName()) + ; } void @@ -169,8 +169,6 @@ cmNinjaNormalTargetGenerator { cmTarget::TargetType targetType = this->GetTarget()->GetType(); std::string ruleName = this->LanguageLinkerRule(); - if (useResponseFile) - ruleName += "_RSP_FILE"; // Select whether to use a response file for objects. std::string rspfile; @@ -284,8 +282,7 @@ cmNinjaNormalTargetGenerator !this->GetTarget()->IsFrameworkOnApple()) { std::string cmakeCommand = this->GetLocalGenerator()->ConvertToOutputFormat( - this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"), - cmLocalGenerator::SHELL); + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); if (targetType == cmTarget::EXECUTABLE) this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_EXECUTABLE", cmakeCommand + @@ -339,8 +336,7 @@ cmNinjaNormalTargetGenerator { std::string cmakeCommand = this->GetLocalGenerator()->ConvertToOutputFormat( - mf->GetRequiredDefinition("CMAKE_COMMAND"), - cmLocalGenerator::SHELL); + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); linkCmds.push_back(cmakeCommand + " -E remove $TARGET_FILE"); } // TODO: Use ARCHIVE_APPEND for archives over a certain size. @@ -529,8 +525,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() { vars["INSTALLNAME_DIR"] = localGen.Convert(install_dir, cmLocalGenerator::NONE, - cmLocalGenerator::SHELL, - false); + cmLocalGenerator::SHELL); } } } @@ -661,6 +656,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } // Write the build statement for this target. + bool usedResponseFile = false; globalGen.WriteBuild(this->GetBuildFileStream(), comment.str(), this->LanguageLinkerRule(), @@ -670,7 +666,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() orderOnlyDeps, vars, rspfile, - commandLineLengthLimit); + commandLineLengthLimit, + &usedResponseFile); + this->WriteLinkRule(usedResponseFile); if (targetOutput != targetOutputReal && !target.IsFrameworkOnApple()) { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 128a35b..b2aef68 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -97,16 +97,24 @@ std::string const& cmNinjaTargetGenerator::GetConfigName() const return this->LocalGenerator->GetConfigName(); } +std::string cmNinjaTargetGenerator::LanguageCompilerRule( + const std::string& lang) const +{ + return lang + "_COMPILER__" + + cmGlobalNinjaGenerator::EncodeRuleName(this->Target->GetName()); +} + // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. const char* cmNinjaTargetGenerator::GetFeature(const std::string& feature) { - return this->Target->GetFeature(feature, this->GetConfigName()); + return this->GeneratorTarget->GetFeature(feature, this->GetConfigName()); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. bool cmNinjaTargetGenerator::GetFeatureAsBool(const std::string& feature) { - return this->Target->GetFeatureAsBool(feature, this->GetConfigName()); + return this->GeneratorTarget->GetFeatureAsBool(feature, + this->GetConfigName()); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. @@ -451,6 +459,23 @@ cmNinjaTargetGenerator std::vector<std::string> compileCmds; cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + // Maybe insert an include-what-you-use runner. + if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) + { + std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE"; + const char *iwyu = this->Target->GetProperty(iwyu_prop); + if (iwyu && *iwyu) + { + std::string run_iwyu = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); + run_iwyu += " -E __run_iwyu --iwyu="; + run_iwyu += this->GetLocalGenerator()->EscapeForShell(iwyu); + run_iwyu += " -- "; + compileCmds.front().insert(0, run_iwyu); + } + } + if (!compileCmds.empty()) { compileCmds.front().insert(0, cldeps); diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 5733fde..4e7d8b3 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -67,8 +67,7 @@ protected: std::string const& GetConfigName() const; - std::string LanguageCompilerRule(const std::string& lang) const - { return lang + "_COMPILER"; } + std::string LanguageCompilerRule(const std::string& lang) const; const char* GetFeature(const std::string& feature); bool GetFeatureAsBool(const std::string& feature); diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 07c85dd..cb5a51f 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -44,8 +44,6 @@ private: cmTarget const* Target; std::string Purpose; - bool Computed; - std::vector<std::string> OrderedDirectories; std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries; @@ -68,8 +66,9 @@ private: void OrderDirectories(); void VisitDirectory(unsigned int i); void DiagnoseCycle(); - bool CycleDiagnosed; int WalkId; + bool CycleDiagnosed; + bool Computed; // Adjacency-list representation of runtime path ordering graph. // This maps from directory to those that must come *before* it. diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx new file mode 100644 index 0000000..db73a34 --- /dev/null +++ b/Source/cmOutputConverter.cxx @@ -0,0 +1,447 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmOutputConverter.h" + +#include "cmAlgorithms.h" +#include "cmake.h" + +#include <cmsys/System.h> + +#include <assert.h> + +cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot) + : StateSnapshot(snapshot), LinkScriptShell(false) +{ +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToOutputForExistingCommon(const std::string& remote, + std::string const& result, + OutputFormat format) +{ + // If this is a windows shell, the result has a space, and the path + // already exists, we can use a short-path to reference it without a + // space. + if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos && + cmSystemTools::FileExists(remote.c_str())) + { + std::string tmp; + if(cmSystemTools::GetShortPath(remote, tmp)) + { + return this->ConvertToOutputFormat(tmp, format); + } + } + + // Otherwise, leave it unchanged. + return result; +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToOutputForExisting(const std::string& remote, + RelativeRoot local, + OutputFormat format) +{ + static_cast<void>(local); + + // Perform standard conversion. + std::string result = this->ConvertToOutputFormat(remote, format); + + // Consider short-path. + return this->ConvertToOutputForExistingCommon(remote, result, format); +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToOutputForExisting(RelativeRoot remote, + const std::string& local, + OutputFormat format) +{ + // Perform standard conversion. + std::string result = this->Convert(remote, local, format, true); + + // Consider short-path. + const char* remotePath = this->GetRelativeRootPath(remote); + return this->ConvertToOutputForExistingCommon(remotePath, result, format); +} + +//---------------------------------------------------------------------------- +const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) +{ + switch (relroot) + { + case HOME: return this->GetState()->GetSourceDirectory(); + case START: return this->StateSnapshot.GetCurrentSourceDirectory(); + case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory(); + case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory(); + default: break; + } + return 0; +} + +std::string cmOutputConverter::Convert(const std::string& source, + RelativeRoot relative, + OutputFormat output) +{ + // Convert the path to a relative path. + std::string result = source; + + switch (relative) + { + case HOME: + result = this->ConvertToRelativePath( + this->GetState()->GetSourceDirectoryComponents(), result); + break; + case START: + result = this->ConvertToRelativePath( + this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result); + break; + case HOME_OUTPUT: + result = this->ConvertToRelativePath( + this->GetState()->GetBinaryDirectoryComponents(), result); + break; + case START_OUTPUT: + result = this->ConvertToRelativePath( + this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result); + break; + case FULL: + result = cmSystemTools::CollapseFullPath(result); + break; + case NONE: + break; + } + return this->ConvertToOutputFormat(result, output); +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source, + OutputFormat output) +{ + std::string result = source; + // Convert it to an output path. + if (output == MAKERULE) + { + result = cmSystemTools::ConvertToOutputPath(result.c_str()); + } + else if(output == SHELL || output == WATCOMQUOTE) + { + // For the MSYS shell convert drive letters to posix paths, so + // that c:/some/path becomes /c/some/path. This is needed to + // avoid problems with the shell path translation. + if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell) + { + if(result.size() > 2 && result[1] == ':') + { + result[1] = result[0]; + result[0] = '/'; + } + } + if(this->GetState()->UseWindowsShell()) + { + std::replace(result.begin(), result.end(), '/', '\\'); + } + result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE); + } + else if(output == RESPONSE) + { + result = this->EscapeForShell(result, false, false, false); + } + return result; +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::Convert(RelativeRoot remote, + const std::string& local, + OutputFormat output, + bool optional) +{ + const char* remotePath = this->GetRelativeRootPath(remote); + + // The relative root must have a path (i.e. not FULL or NONE) + assert(remotePath != 0); + + if(!local.empty() && !optional) + { + std::vector<std::string> components; + cmSystemTools::SplitPath(local, components); + std::string result = this->ConvertToRelativePath(components, remotePath); + return this->ConvertToOutputFormat(result, output); + } + + return this->ConvertToOutputFormat(remotePath, output); +} + +//---------------------------------------------------------------------------- +static bool cmOutputConverterNotAbove(const char* a, const char* b) +{ + return (cmSystemTools::ComparePath(a, b) || + cmSystemTools::IsSubDirectory(a, b)); +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToRelativePath(const std::vector<std::string>& local, + const std::string& in_remote, + bool force) +{ + // The path should never be quoted. + assert(in_remote[0] != '\"'); + + // The local path should never have a trailing slash. + assert(!local.empty() && !(local[local.size()-1] == "")); + + // If the path is already relative then just return the path. + if(!cmSystemTools::FileIsFullPath(in_remote.c_str())) + { + return in_remote; + } + + if(!force) + { + // Skip conversion if the path and local are not both in the source + // or both in the binary tree. + std::string local_path = cmSystemTools::JoinPath(local); + if(!((cmOutputConverterNotAbove(local_path.c_str(), + this->StateSnapshot.GetRelativePathTopBinary()) && + cmOutputConverterNotAbove(in_remote.c_str(), + this->StateSnapshot.GetRelativePathTopBinary())) || + (cmOutputConverterNotAbove(local_path.c_str(), + this->StateSnapshot.GetRelativePathTopSource()) && + cmOutputConverterNotAbove(in_remote.c_str(), + this->StateSnapshot.GetRelativePathTopSource())))) + { + return in_remote; + } + } + + // Identify the longest shared path component between the remote + // path and the local path. + std::vector<std::string> remote; + cmSystemTools::SplitPath(in_remote, remote); + unsigned int common=0; + while(common < remote.size() && + common < local.size() && + cmSystemTools::ComparePath(remote[common], + local[common])) + { + ++common; + } + + // If no part of the path is in common then return the full path. + if(common == 0) + { + return in_remote; + } + + // If the entire path is in common then just return a ".". + if(common == remote.size() && + common == local.size()) + { + return "."; + } + + // If the entire path is in common except for a trailing slash then + // just return a "./". + if(common+1 == remote.size() && + remote[common].empty() && + common == local.size()) + { + return "./"; + } + + // Construct the relative path. + std::string relative; + + // First add enough ../ to get up to the level of the shared portion + // of the path. Leave off the trailing slash. Note that the last + // component of local will never be empty because local should never + // have a trailing slash. + for(unsigned int i=common; i < local.size(); ++i) + { + relative += ".."; + if(i < local.size()-1) + { + relative += "/"; + } + } + + // Now add the portion of the destination path that is not included + // in the shared portion of the path. Add a slash the first time + // only if there was already something in the path. If there was a + // trailing slash in the input then the last iteration of the loop + // will add a slash followed by an empty string which will preserve + // the trailing slash in the output. + + if(!relative.empty() && !remote.empty()) + { + relative += "/"; + } + relative += cmJoin(cmRange(remote).advance(common), "/"); + + // Finally return the path. + return relative; +} + +//---------------------------------------------------------------------------- +static bool cmOutputConverterIsShellOperator(const std::string& str) +{ + static std::set<std::string> shellOperators; + if(shellOperators.empty()) + { + shellOperators.insert("<"); + shellOperators.insert(">"); + shellOperators.insert("<<"); + shellOperators.insert(">>"); + shellOperators.insert("|"); + shellOperators.insert("||"); + shellOperators.insert("&&"); + shellOperators.insert("&>"); + shellOperators.insert("1>"); + shellOperators.insert("2>"); + shellOperators.insert("2>&1"); + shellOperators.insert("1>&2"); + } + return shellOperators.count(str) > 0; +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::EscapeForShell(const std::string& str, + bool makeVars, + bool forEcho, + bool useWatcomQuote) +{ + // Do not escape shell operators. + if(cmOutputConverterIsShellOperator(str)) + { + return str; + } + + // Compute the flags for the target shell environment. + int flags = 0; + if(this->GetState()->UseWindowsVSIDE()) + { + flags |= cmsysSystem_Shell_Flag_VSIDE; + } + else if(!this->LinkScriptShell) + { + flags |= cmsysSystem_Shell_Flag_Make; + } + if(makeVars) + { + flags |= cmsysSystem_Shell_Flag_AllowMakeVariables; + } + if(forEcho) + { + flags |= cmsysSystem_Shell_Flag_EchoWindows; + } + if(useWatcomQuote) + { + flags |= cmsysSystem_Shell_Flag_WatcomQuote; + } + if(this->GetState()->UseWatcomWMake()) + { + flags |= cmsysSystem_Shell_Flag_WatcomWMake; + } + if(this->GetState()->UseMinGWMake()) + { + flags |= cmsysSystem_Shell_Flag_MinGWMake; + } + if(this->GetState()->UseNMake()) + { + flags |= cmsysSystem_Shell_Flag_NMake; + } + + // Compute the buffer size needed. + int size = (this->GetState()->UseWindowsShell() ? + cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) : + cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags)); + + // Compute the shell argument itself. + std::vector<char> arg(size); + if(this->GetState()->UseWindowsShell()) + { + cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags); + } + else + { + cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags); + } + return std::string(&arg[0]); +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::EscapeForCMake(const std::string& str) +{ + // Always double-quote the argument to take care of most escapes. + std::string result = "\""; + for(const char* c = str.c_str(); *c; ++c) + { + if(*c == '"') + { + // Escape the double quote to avoid ending the argument. + result += "\\\""; + } + else if(*c == '$') + { + // Escape the dollar to avoid expanding variables. + result += "\\$"; + } + else if(*c == '\\') + { + // Escape the backslash to avoid other escapes. + result += "\\\\"; + } + else + { + // Other characters will be parsed correctly. + result += *c; + } + } + result += "\""; + return result; +} + +//---------------------------------------------------------------------------- +cmOutputConverter::FortranFormat +cmOutputConverter::GetFortranFormat(const char* value) +{ + FortranFormat format = FortranFormatNone; + if(value && *value) + { + std::vector<std::string> fmt; + cmSystemTools::ExpandListArgument(value, fmt); + for(std::vector<std::string>::iterator fi = fmt.begin(); + fi != fmt.end(); ++fi) + { + if(*fi == "FIXED") + { + format = FortranFormatFixed; + } + if(*fi == "FREE") + { + format = FortranFormatFree; + } + } + } + return format; +} + +void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell) +{ + this->LinkScriptShell = linkScriptShell; +} + +cmState* cmOutputConverter::GetState() const +{ + return this->StateSnapshot.GetState(); +} diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h new file mode 100644 index 0000000..1d3f8c7 --- /dev/null +++ b/Source/cmOutputConverter.h @@ -0,0 +1,106 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmOutputConverter_h +#define cmOutputConverter_h + +#include "cmStandardIncludes.h" + +#include "cmGlobalGenerator.h" +#include "cmState.h" + +class cmOutputConverter +{ +public: + cmOutputConverter(cmState::Snapshot snapshot); + + /** + * Convert something to something else. This is a centralized conversion + * routine used by the generators to handle relative paths and the like. + * The flags determine what is actually done. + * + * relative: treat the argument as a directory and convert it to make it + * relative or full or unchanged. If relative (HOME, START etc) then that + * specifies what it should be relative to. + * + * output: make the result suitable for output to a... + * + * optional: should any relative path operation be controlled by the rel + * path setting + */ + enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT }; + enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE }; + std::string ConvertToOutputFormat(const std::string& source, + OutputFormat output); + std::string Convert(const std::string& remote, RelativeRoot local, + OutputFormat output = UNCHANGED); + std::string Convert(RelativeRoot remote, const std::string& local, + OutputFormat output = UNCHANGED, + bool optional = false); + + /** + * Get path for the specified relative root. + */ + const char* GetRelativeRootPath(RelativeRoot relroot); + + ///! for existing files convert to output path and short path if spaces + std::string ConvertToOutputForExisting(const std::string& remote, + RelativeRoot local = START_OUTPUT, + OutputFormat format = SHELL); + + /** For existing path identified by RelativeRoot convert to output + path and short path if spaces. */ + std::string ConvertToOutputForExisting(RelativeRoot remote, + const std::string& local = "", + OutputFormat format = SHELL); + + void SetLinkScriptShell(bool linkScriptShell); + + std::string EscapeForShell(const std::string& str, + bool makeVars = false, + bool forEcho = false, + bool useWatcomQuote = false); + + static std::string EscapeForCMake(const std::string& str); + + enum FortranFormat + { + FortranFormatNone, + FortranFormatFixed, + FortranFormatFree + }; + static FortranFormat GetFortranFormat(const char* value); + + /** + * Convert the given remote path to a relative path with respect to + * the given local path. The local path must be given in component + * form (see SystemTools::SplitPath) without a trailing slash. The + * remote path must use forward slashes and not already be escaped + * or quoted. + */ + std::string ConvertToRelativePath(const std::vector<std::string>& local, + const std::string& in_remote, + bool force = false); + +private: + cmState* GetState() const; + + std::string ConvertToOutputForExistingCommon(const std::string& remote, + std::string const& result, + OutputFormat format); + +private: + cmState::Snapshot StateSnapshot; + + bool LinkScriptShell; +}; + +#endif diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index f8d61db..5026893 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -343,29 +343,24 @@ cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id) return e.str(); } -cmPolicies::PolicyMap::PolicyMap() -{ - this->UNDEFINED.set(); -} - cmPolicies::PolicyStatus cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const { PolicyStatus status = cmPolicies::WARN; - if (this->OLD[id]) + if (this->Status[(POLICY_STATUS_COUNT * id) + OLD]) { status = cmPolicies::OLD; } - else if (this->NEW[id]) + else if (this->Status[(POLICY_STATUS_COUNT * id) + NEW]) { status = cmPolicies::NEW; } - else if (this->REQUIRED_ALWAYS[id]) + else if (this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_ALWAYS]) { status = cmPolicies::REQUIRED_ALWAYS; } - else if (this->REQUIRED_IF_USED[id]) + else if (this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_IF_USED]) { status = cmPolicies::REQUIRED_IF_USED; } @@ -375,19 +370,25 @@ cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const void cmPolicies::PolicyMap::Set(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status) { - this->UNDEFINED.reset(id); - this->OLD[id] = (status == cmPolicies::OLD); - this->NEW[id] = (status == cmPolicies::NEW); - this->REQUIRED_ALWAYS[id] = (status == cmPolicies::REQUIRED_ALWAYS); - this->REQUIRED_IF_USED[id] = (status == cmPolicies::REQUIRED_IF_USED); + this->Status[(POLICY_STATUS_COUNT * id) + OLD] = (status == OLD); + this->Status[(POLICY_STATUS_COUNT * id) + WARN] = (status == WARN); + this->Status[(POLICY_STATUS_COUNT * id) + NEW] = (status == NEW); + this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_ALWAYS] = + (status == REQUIRED_ALWAYS); + this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_IF_USED] = + (status == REQUIRED_IF_USED); } bool cmPolicies::PolicyMap::IsDefined(cmPolicies::PolicyID id) const { - return !this->UNDEFINED[id]; + return this->Status[(POLICY_STATUS_COUNT * id) + OLD] + || this->Status[(POLICY_STATUS_COUNT * id) + WARN] + || this->Status[(POLICY_STATUS_COUNT * id) + NEW] + || this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_ALWAYS] + || this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_IF_USED]; } bool cmPolicies::PolicyMap::IsEmpty() const { - return !this->UNDEFINED.none(); + return this->Status.none(); } diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index eb56494..8a3c27d 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -214,6 +214,9 @@ class cmPolicy; 3, 3, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0062, \ "Disallow install() of export() result.", \ + 3, 3, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0063, \ + "Honor visibility properties for all target types.", \ 3, 3, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) @@ -241,6 +244,7 @@ public: REQUIRED_IF_USED, REQUIRED_ALWAYS ///< Issue an error unless user sets policy status to NEW. }; +#define POLICY_STATUS_COUNT 5 /// Policy identifiers enum PolicyID @@ -278,18 +282,13 @@ public: /** Represent a set of policy values. */ struct PolicyMap { - PolicyMap(); PolicyStatus Get(PolicyID id) const; void Set(PolicyID id, PolicyStatus status); bool IsDefined(PolicyID id) const; bool IsEmpty() const; private: - std::bitset<cmPolicies::CMPCOUNT> UNDEFINED; - std::bitset<cmPolicies::CMPCOUNT> OLD; - std::bitset<cmPolicies::CMPCOUNT> NEW; - std::bitset<cmPolicies::CMPCOUNT> REQUIRED_IF_USED; - std::bitset<cmPolicies::CMPCOUNT> REQUIRED_ALWAYS; + std::bitset<cmPolicies::CMPCOUNT * POLICY_STATUS_COUNT> Status; }; }; diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx index d2f7bf3..15d9ed0 100644 --- a/Source/cmProcessTools.cxx +++ b/Source/cmProcessTools.cxx @@ -44,7 +44,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, //---------------------------------------------------------------------------- cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR): - Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0') + Log(0), Prefix(0), Separator(sep), LineEnd('\0'), IgnoreCR(ignoreCR) { } diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h index 439726d..23833ca 100644 --- a/Source/cmProcessTools.h +++ b/Source/cmProcessTools.h @@ -51,12 +51,12 @@ public: /** Configure logging of lines as they are extracted. */ void SetLog(std::ostream* log, const char* prefix); protected: - char Separator; - bool IgnoreCR; std::ostream* Log; const char* Prefix; - char LineEnd; std::string Line; + char Separator; + char LineEnd; + bool IgnoreCR; virtual bool ProcessChunk(const char* data, int length); /** Implement in a subclass to process one line of input. It diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx index 40976db..ef57068 100644 --- a/Source/cmProperty.cxx +++ b/Source/cmProperty.cxx @@ -12,17 +12,14 @@ #include "cmProperty.h" #include "cmSystemTools.h" -void cmProperty::Set(const std::string& name, const char *value) +void cmProperty::Set(const char *value) { - this->Name = name; this->Value = value; this->ValueHasBeenSet = true; } -void cmProperty::Append(const std::string& name, const char *value, - bool asString) +void cmProperty::Append(const char *value, bool asString) { - this->Name = name; if(!this->Value.empty() && *value && !asString) { this->Value += ";"; diff --git a/Source/cmProperty.h b/Source/cmProperty.h index 659c4c3..e026372 100644 --- a/Source/cmProperty.h +++ b/Source/cmProperty.h @@ -21,11 +21,10 @@ public: TEST, VARIABLE, CACHED_VARIABLE, INSTALL }; // set this property - void Set(const std::string& name, const char *value); + void Set(const char *value); // append to this property - void Append(const std::string& name, const char *value, - bool asString = false); + void Append(const char *value, bool asString = false); // get the value const char *GetValue() const; @@ -34,7 +33,6 @@ public: cmProperty() { this->ValueHasBeenSet = false; } protected: - std::string Name; std::string Value; bool ValueHasBeenSet; }; diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx index 3875318..776fad1 100644 --- a/Source/cmPropertyDefinitionMap.cxx +++ b/Source/cmPropertyDefinitionMap.cxx @@ -29,9 +29,9 @@ void cmPropertyDefinitionMap } } -bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) +bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const { - cmPropertyDefinitionMap::iterator it = this->find(name); + cmPropertyDefinitionMap::const_iterator it = this->find(name); if (it == this->end()) { return false; @@ -40,9 +40,9 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) return true; } -bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) +bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const { - cmPropertyDefinitionMap::iterator it = this->find(name); + cmPropertyDefinitionMap::const_iterator it = this->find(name); if (it == this->end()) { return false; diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h index 00c7328..f95c721 100644 --- a/Source/cmPropertyDefinitionMap.h +++ b/Source/cmPropertyDefinitionMap.h @@ -27,10 +27,10 @@ public: bool chain); // has a named property been defined - bool IsPropertyDefined(const std::string& name); + bool IsPropertyDefined(const std::string& name) const; // is a named property set to chain - bool IsPropertyChained(const std::string& name); + bool IsPropertyChained(const std::string& name) const; }; #endif diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index 070f6f1..ef09dbc 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -14,6 +14,8 @@ #include "cmake.h" #include "cmState.h" +#include <assert.h> + cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name) { cmPropertyMap::iterator it = this->find(name); @@ -29,54 +31,39 @@ cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name) return prop; } -void cmPropertyMap::SetProperty(const std::string& name, const char *value, - cmProperty::ScopeType scope) +void cmPropertyMap::SetProperty(const std::string& name, const char *value) { if(!value) { this->erase(name); return; } - (void)scope; cmProperty *prop = this->GetOrCreateProperty(name); - prop->Set(name,value); + prop->Set(value); } void cmPropertyMap::AppendProperty(const std::string& name, const char* value, - cmProperty::ScopeType scope, bool asString) + bool asString) { // Skip if nothing to append. if(!value || !*value) { return; } - (void)scope; cmProperty *prop = this->GetOrCreateProperty(name); - prop->Append(name,value,asString); + prop->Append(value,asString); } const char *cmPropertyMap -::GetPropertyValue(const std::string& name, - cmProperty::ScopeType scope, - bool &chain) const +::GetPropertyValue(const std::string& name) const { - chain = false; - if (name.empty()) - { - return 0; - } + assert(!name.empty()); cmPropertyMap::const_iterator it = this->find(name); if (it == this->end()) { - // should we chain up? - if (this->CMakeInstance) - { - chain = this->CMakeInstance->GetState()-> - IsPropertyChained(name,scope); - } return 0; } return it->second.GetValue(); diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h index 02d4235..a9062db 100644 --- a/Source/cmPropertyMap.h +++ b/Source/cmPropertyMap.h @@ -14,29 +14,17 @@ #include "cmProperty.h" -class cmake; - class cmPropertyMap : public std::map<std::string,cmProperty> { public: cmProperty *GetOrCreateProperty(const std::string& name); - void SetProperty(const std::string& name, const char *value, - cmProperty::ScopeType scope); + void SetProperty(const std::string& name, const char *value); void AppendProperty(const std::string& name, const char* value, - cmProperty::ScopeType scope, bool asString=false); - - const char *GetPropertyValue(const std::string& name, - cmProperty::ScopeType scope, - bool &chain) const; - - void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; } - - cmPropertyMap() { this->CMakeInstance = 0;} + bool asString=false); -private: - cmake *CMakeInstance; + const char *GetPropertyValue(const std::string& name) const; }; #endif diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 457de11..ef32c75 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -20,7 +20,7 @@ #include "cmAlgorithms.h" #if defined(_WIN32) && !defined(__CYGWIN__) -# include "cmLocalVisualStudioGenerator.h" +# include "cmGlobalVisualStudioGenerator.h" #endif #include <sys/stat.h> @@ -320,7 +320,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) std::string targetDir = getAutogenTargetDir(target); cmCustomCommandLine currentLine; - currentLine.push_back(makefile->GetSafeDefinition("CMAKE_COMMAND")); + currentLine.push_back(cmSystemTools::GetCMakeCommand()); currentLine.push_back("-E"); currentLine.push_back("cmake_autogen"); currentLine.push_back(targetDir); @@ -372,13 +372,13 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) cmGlobalGenerator* gg = localGen->GetGlobalGenerator(); if(gg->GetName().find("Visual Studio") != std::string::npos) { - cmLocalVisualStudioGenerator* vslg = - static_cast<cmLocalVisualStudioGenerator*>(localGen); + cmGlobalVisualStudioGenerator* vsgg = + static_cast<cmGlobalVisualStudioGenerator*>(gg); // Under VS >= 7 use a PRE_BUILD event instead of a separate target to // reduce the number of targets loaded into the IDE. // This also works around a VS 11 bug that may skip updating the target: // https://connect.microsoft.com/VisualStudio/feedback/details/769495 - usePRE_BUILD = vslg->GetVersion() >= cmLocalVisualStudioGenerator::VS7; + usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7; if(usePRE_BUILD) { for (std::vector<std::string>::iterator it = depends.begin(); @@ -550,9 +550,9 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) std::string autogenTargetName = getAutogenTargetName(target); makefile->AddDefinition("_moc_target_name", - cmLocalGenerator::EscapeForCMake(autogenTargetName).c_str()); + cmOutputConverter::EscapeForCMake(autogenTargetName).c_str()); makefile->AddDefinition("_origin_target_name", - cmLocalGenerator::EscapeForCMake(target->GetName()).c_str()); + cmOutputConverter::EscapeForCMake(target->GetName()).c_str()); std::string targetDir = getAutogenTargetDir(target); @@ -582,7 +582,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) this->SetupSourceFiles(target); } makefile->AddDefinition("_cpp_files", - cmLocalGenerator::EscapeForCMake(this->Sources).c_str()); + cmOutputConverter::EscapeForCMake(this->Sources).c_str()); if (target->GetPropertyAsBool("AUTOMOC")) { this->SetupAutoMocTarget(target, autogenTargetName, @@ -764,11 +764,11 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); std::string _moc_options = (tmp!=0 ? tmp : ""); makefile->AddDefinition("_moc_options", - cmLocalGenerator::EscapeForCMake(_moc_options).c_str()); + cmOutputConverter::EscapeForCMake(_moc_options).c_str()); makefile->AddDefinition("_skip_moc", - cmLocalGenerator::EscapeForCMake(this->SkipMoc).c_str()); + cmOutputConverter::EscapeForCMake(this->SkipMoc).c_str()); makefile->AddDefinition("_moc_headers", - cmLocalGenerator::EscapeForCMake(this->Headers).c_str()); + cmOutputConverter::EscapeForCMake(this->Headers).c_str()); bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE"); makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); @@ -780,9 +780,9 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, _moc_incs, _moc_compile_defs); makefile->AddDefinition("_moc_incs", - cmLocalGenerator::EscapeForCMake(_moc_incs).c_str()); + cmOutputConverter::EscapeForCMake(_moc_incs).c_str()); makefile->AddDefinition("_moc_compile_defs", - cmLocalGenerator::EscapeForCMake(_moc_compile_defs).c_str()); + cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str()); for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) @@ -795,7 +795,7 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, if (config_moc_incs != _moc_incs) { configIncludes[*li] = - cmLocalGenerator::EscapeForCMake(config_moc_incs); + cmOutputConverter::EscapeForCMake(config_moc_incs); if(_moc_incs.empty()) { _moc_incs = config_moc_incs; @@ -804,7 +804,7 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, if (config_moc_compile_defs != _moc_compile_defs) { configDefines[*li] = - cmLocalGenerator::EscapeForCMake(config_moc_compile_defs); + cmOutputConverter::EscapeForCMake(config_moc_compile_defs); if(_moc_compile_defs.empty()) { _moc_compile_defs = config_moc_compile_defs; @@ -906,7 +906,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, skipped.insert(skipVec.begin(), skipVec.end()); makefile->AddDefinition("_skip_uic", - cmLocalGenerator::EscapeForCMake(this->SkipUic).c_str()); + cmOutputConverter::EscapeForCMake(this->SkipUic).c_str()); std::vector<cmSourceFile*> uiFilesWithOptions = makefile->GetQtUiFilesWithOptions(); @@ -920,7 +920,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, if (!_uic_opts.empty()) { - _uic_opts = cmLocalGenerator::EscapeForCMake(_uic_opts); + _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts); makefile->AddDefinition("_uic_target_options", _uic_opts.c_str()); } for (std::vector<std::string>::const_iterator li = configs.begin(); @@ -931,7 +931,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, if (config_uic_opts != _uic_opts) { configUicOptions[*li] = - cmLocalGenerator::EscapeForCMake(config_uic_opts); + cmOutputConverter::EscapeForCMake(config_uic_opts); if(_uic_opts.empty()) { _uic_opts = config_uic_opts; @@ -966,9 +966,9 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, } makefile->AddDefinition("_qt_uic_options_files", - cmLocalGenerator::EscapeForCMake(uiFileFiles).c_str()); + cmOutputConverter::EscapeForCMake(uiFileFiles).c_str()); makefile->AddDefinition("_qt_uic_options_options", - cmLocalGenerator::EscapeForCMake(uiFileOptions).c_str()); + cmOutputConverter::EscapeForCMake(uiFileOptions).c_str()); std::string targetName = target->GetName(); if (strcmp(qtVersion, "5") == 0) @@ -1141,15 +1141,15 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target) } } makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(), - cmLocalGenerator::EscapeForCMake(qrcInputs).c_str()); + cmOutputConverter::EscapeForCMake(qrcInputs).c_str()); makefile->AddDefinition("_rcc_files", - cmLocalGenerator::EscapeForCMake(_rcc_files).c_str()); + cmOutputConverter::EscapeForCMake(_rcc_files).c_str()); makefile->AddDefinition("_qt_rcc_options_files", - cmLocalGenerator::EscapeForCMake(rccFileFiles).c_str()); + cmOutputConverter::EscapeForCMake(rccFileFiles).c_str()); makefile->AddDefinition("_qt_rcc_options_options", - cmLocalGenerator::EscapeForCMake(rccFileOptions).c_str()); + cmOutputConverter::EscapeForCMake(rccFileOptions).c_str()); makefile->AddDefinition("_qt_rcc_executable", this->GetRccExecutable(target).c_str()); @@ -1203,23 +1203,6 @@ std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target) return std::string(); } -static cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, - const std::string& targetDirectory) -{ - cmGlobalGenerator* gg = new cmGlobalGenerator(); - gg->SetCMakeInstance(cm); - - cm->SetHomeOutputDirectory(targetDirectory); - cm->SetHomeDirectory(targetDirectory); - - cmLocalGenerator* lg = gg->CreateLocalGenerator(); - lg->GetMakefile()->SetCurrentBinaryDirectory(targetDirectory); - lg->GetMakefile()->SetCurrentSourceDirectory(targetDirectory); - gg->SetCurrentLocalGenerator(lg); - - return gg; -} - bool cmQtAutoGenerators::Run(const std::string& targetDirectory, const std::string& config) { @@ -1227,25 +1210,26 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory, cmake cm; cm.SetHomeOutputDirectory(targetDirectory); cm.SetHomeDirectory(targetDirectory); - cmGlobalGenerator* gg = CreateGlobalGenerator(&cm, targetDirectory); - cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile(); + cmGlobalGenerator gg(&cm); + + cmLocalGenerator* lg = gg.MakeLocalGenerator(); + lg->GetMakefile()->SetCurrentBinaryDirectory(targetDirectory); + lg->GetMakefile()->SetCurrentSourceDirectory(targetDirectory); + gg.SetCurrentMakefile(lg->GetMakefile()); - this->ReadAutogenInfoFile(makefile, targetDirectory, config); - this->ReadOldMocDefinitionsFile(makefile, targetDirectory); + this->ReadAutogenInfoFile(lg->GetMakefile(), targetDirectory, config); + this->ReadOldMocDefinitionsFile(lg->GetMakefile(), targetDirectory); this->Init(); if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - success = this->RunAutogen(makefile); + success = this->RunAutogen(lg->GetMakefile()); } this->WriteOldMocDefinitionsFile(targetDirectory); - delete gg->GetCurrentLocalGenerator(); - delete gg; - gg = NULL; - makefile = NULL; + delete lg; return success; } @@ -1450,7 +1434,7 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile( outfile.open(filename.c_str(), std::ios::trunc); outfile << "set(AM_OLD_COMPILE_SETTINGS " - << cmLocalGenerator::EscapeForCMake( + << cmOutputConverter::EscapeForCMake( this->CurrentCompileSettingsStr) << ")\n"; outfile.close(); diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index f74e3c5..4c0fcbc 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -105,7 +105,6 @@ private: std::string SkipMoc; std::string SkipUic; std::string Headers; - bool IncludeProjectDirsBefore; std::string Srcdir; std::string Builddir; std::string MocExecutable; @@ -131,6 +130,7 @@ private: std::map<std::string, std::string> RccOptions; std::map<std::string, std::vector<std::string> > RccInputs; + bool IncludeProjectDirsBefore; bool Verbose; bool ColorOutput; bool RunMocFailed; @@ -138,7 +138,6 @@ private: bool RunRccFailed; bool GenerateAll; bool RelaxedMode; - }; #endif diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index e9cfacc..53dc5a8 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -85,8 +85,10 @@ bool cmSetTestsPropertiesCommand unsigned int k; for (k = 0; k < propertyPairs.size(); k = k + 2) { - test->SetProperty(propertyPairs[k], - propertyPairs[k+1].c_str()); + if (!propertyPairs[k].empty()) + { + test->SetProperty(propertyPairs[k], propertyPairs[k+1].c_str()); + } } } else diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 724ab39..86f0a7a 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -22,7 +22,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name): Location(mf, name) { this->CustomCommand = 0; - this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); this->FindFullPathFailed = false; this->IsUiFile = (".ui" == cmSystemTools::GetFilenameLastExtension(this->Location.GetName())); @@ -299,7 +298,7 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc) //---------------------------------------------------------------------------- void cmSourceFile::SetProperty(const std::string& prop, const char* value) { - this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE); + this->Properties.SetProperty(prop, value); if (this->IsUiFile) { @@ -315,8 +314,7 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value) void cmSourceFile::AppendProperty(const std::string& prop, const char* value, bool asString) { - this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE, - asString); + this->Properties.AppendProperty(prop, value, asString); } //---------------------------------------------------------------------------- @@ -362,13 +360,16 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const } } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal) { cmMakefile const* mf = this->Location.GetMakefile(); - return mf->GetProperty(prop,cmProperty::SOURCE_FILE); + const bool chain = mf->GetState()-> + IsPropertyChained(prop, cmProperty::SOURCE_FILE); + if (chain) + { + return mf->GetProperty(prop, chain); + } } return retVal; diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index f898260..1433b54 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -107,8 +107,9 @@ private: std::string Extension; std::string Language; std::string FullPath; - bool FindFullPathFailed; std::string ObjectLibrary; + std::vector<std::string> Depends; + bool FindFullPathFailed; bool IsUiFile; bool FindFullPath(std::string* error); @@ -116,7 +117,6 @@ private: void CheckExtension(); void CheckLanguage(std::string const& ext); - std::vector<std::string> Depends; static const std::string propLANGUAGE; }; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 82a2939..a13c13f 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -18,11 +18,40 @@ #include <assert.h> +struct cmState::SnapshotDataType +{ + cmState::PositionType DirectoryParent; + cmState::SnapshotType SnapshotType; + cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator + BuildSystemDirectory; +}; + +struct cmState::BuildsystemDirectoryStateType +{ + std::string Location; + std::string OutputLocation; + + std::vector<std::string> CurrentSourceDirectoryComponents; + std::vector<std::string> CurrentBinaryDirectoryComponents; + // The top-most directories for relative path conversion. Both the + // source and destination location of a relative path conversion + // must be underneath one of these directories (both under source or + // both under binary) in order for the relative path to be evaluated + // safely by the build tools. + std::string RelativePathTopSource; + std::string RelativePathTopBinary; +}; + cmState::cmState(cmake* cm) : CMakeInstance(cm), - IsInTryCompile(false) + IsInTryCompile(false), + WindowsShell(false), + WindowsVSIDE(false), + WatcomWMake(false), + MinGWMake(false), + NMake(false), + MSYSShell(false) { - this->Initialize(); } cmState::~cmState() @@ -190,15 +219,14 @@ void cmState::RemoveCacheEntryProperty(std::string const& key, ->GetCacheIterator(key.c_str()).SetProperty(propertyName, (void*)0); } -void cmState::Initialize() +void cmState::Reset() { this->GlobalProperties.clear(); this->PropertyDefinitions.clear(); - this->Locations.clear(); - this->OutputLocations.clear(); - this->ParentPositions.clear(); - this->CreateSnapshot(Snapshot()); + this->BuildsystemDirectory.Truncate(); + this->SnapshotData.Truncate(); + this->DefineProperty ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "", true); @@ -231,27 +259,41 @@ void cmState::DefineProperty(const std::string& name, chained); } -cmPropertyDefinition *cmState +cmPropertyDefinition const* cmState ::GetPropertyDefinition(const std::string& name, - cmProperty::ScopeType scope) + cmProperty::ScopeType scope) const { if (this->IsPropertyDefined(name,scope)) { - return &(this->PropertyDefinitions[scope][name]); + cmPropertyDefinitionMap const& defs = + this->PropertyDefinitions.find(scope)->second; + return &defs.find(name)->second; } return 0; } bool cmState::IsPropertyDefined(const std::string& name, - cmProperty::ScopeType scope) + cmProperty::ScopeType scope) const { - return this->PropertyDefinitions[scope].IsPropertyDefined(name); + std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it + = this->PropertyDefinitions.find(scope); + if (it == this->PropertyDefinitions.end()) + { + return false; + } + return it->second.IsPropertyDefined(name); } bool cmState::IsPropertyChained(const std::string& name, - cmProperty::ScopeType scope) + cmProperty::ScopeType scope) const { - return this->PropertyDefinitions[scope].IsPropertyChained(name); + std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it + = this->PropertyDefinitions.find(scope); + if (it == this->PropertyDefinitions.end()) + { + return false; + } + return it->second.IsPropertyChained(name); } void cmState::SetLanguageEnabled(std::string const& l) @@ -399,14 +441,13 @@ void cmState::RemoveUserDefinedCommands() void cmState::SetGlobalProperty(const std::string& prop, const char* value) { - this->GlobalProperties.SetProperty(prop, value, cmProperty::GLOBAL); + this->GlobalProperties.SetProperty(prop, value); } void cmState::AppendGlobalProperty(const std::string& prop, const char* value, bool asString) { - this->GlobalProperties.AppendProperty(prop, value, - cmProperty::GLOBAL, asString); + this->GlobalProperties.AppendProperty(prop, value, asString); } const char *cmState::GetGlobalProperty(const std::string& prop) @@ -444,9 +485,7 @@ const char *cmState::GetGlobalProperty(const std::string& prop) return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1; } #undef STRING_LIST_ELEMENT - bool dummy = false; - return this->GlobalProperties.GetPropertyValue(prop, cmProperty::GLOBAL, - dummy); + return this->GlobalProperties.GetPropertyValue(prop); } bool cmState::GetGlobalPropertyAsBool(const std::string& prop) @@ -458,6 +497,10 @@ void cmState::SetSourceDirectory(std::string const& sourceDirectory) { this->SourceDirectory = sourceDirectory; cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory); + + cmSystemTools::SplitPath( + cmSystemTools::CollapseFullPath(this->SourceDirectory), + this->SourceDirectoryComponents); } const char* cmState::GetSourceDirectory() const @@ -465,10 +508,79 @@ const char* cmState::GetSourceDirectory() const return this->SourceDirectory.c_str(); } +std::vector<std::string> const& cmState::GetSourceDirectoryComponents() const +{ + return this->SourceDirectoryComponents; +} + void cmState::SetBinaryDirectory(std::string const& binaryDirectory) { this->BinaryDirectory = binaryDirectory; cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory); + + cmSystemTools::SplitPath( + cmSystemTools::CollapseFullPath(this->BinaryDirectory), + this->BinaryDirectoryComponents); +} + +void cmState::SetWindowsShell(bool windowsShell) +{ + this->WindowsShell = windowsShell; +} + +bool cmState::UseWindowsShell() const +{ + return this->WindowsShell; +} + +void cmState::SetWindowsVSIDE(bool windowsVSIDE) +{ + this->WindowsVSIDE = windowsVSIDE; +} + +bool cmState::UseWindowsVSIDE() const +{ + return this->WindowsVSIDE; +} + +void cmState::SetWatcomWMake(bool watcomWMake) +{ + this->WatcomWMake = watcomWMake; +} + +bool cmState::UseWatcomWMake() const +{ + return this->WatcomWMake; +} + +void cmState::SetMinGWMake(bool minGWMake) +{ + this->MinGWMake = minGWMake; +} + +bool cmState::UseMinGWMake() const +{ + return this->MinGWMake; +} + +void cmState::SetNMake(bool nMake) +{ + this->NMake = nMake; +} + +bool cmState::UseNMake() const +{ + return this->NMake; +} + +void cmState::SetMSYSShell(bool mSYSShell) +{ + this->MSYSShell = mSYSShell; +} + +bool cmState::UseMSYSShell() const +{ + return this->MSYSShell; } const char* cmState::GetBinaryDirectory() const @@ -476,12 +588,111 @@ const char* cmState::GetBinaryDirectory() const return this->BinaryDirectory.c_str(); } -cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot) +std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const { - PositionType pos = this->ParentPositions.size(); - this->ParentPositions.push_back(originSnapshot.Position); - this->Locations.resize(this->Locations.size() + 1); - this->OutputLocations.resize(this->OutputLocations.size() + 1); + return this->BinaryDirectoryComponents; +} + +void cmState::Snapshot::ComputeRelativePathTopSource() +{ + // Relative path conversion inside the source tree is not used to + // construct relative paths passed to build tools so it is safe to use + // even when the source is a network path. + + cmState::Snapshot snapshot = *this; + std::vector<cmState::Snapshot> snapshots; + snapshots.push_back(snapshot); + while (true) + { + snapshot = snapshot.GetBuildsystemDirectoryParent(); + if (snapshot.IsValid()) + { + snapshots.push_back(snapshot); + } + else + { + break; + } + } + + std::string result = snapshots.front().GetCurrentSourceDirectory(); + + for (std::vector<cmState::Snapshot>::const_iterator it = + snapshots.begin() + 1; it != snapshots.end(); ++it) + { + std::string currentSource = it->GetCurrentSourceDirectory(); + if(cmSystemTools::IsSubDirectory(result, currentSource)) + { + result = currentSource; + } + } + this->Position->BuildSystemDirectory->RelativePathTopSource = result; +} + +void cmState::Snapshot::ComputeRelativePathTopBinary() +{ + cmState::Snapshot snapshot = *this; + std::vector<cmState::Snapshot> snapshots; + snapshots.push_back(snapshot); + while (true) + { + snapshot = snapshot.GetBuildsystemDirectoryParent(); + if (snapshot.IsValid()) + { + snapshots.push_back(snapshot); + } + else + { + break; + } + } + + std::string result = + snapshots.front().GetCurrentBinaryDirectory(); + + for (std::vector<cmState::Snapshot>::const_iterator it = + snapshots.begin() + 1; it != snapshots.end(); ++it) + { + std::string currentBinary = it->GetCurrentBinaryDirectory(); + if(cmSystemTools::IsSubDirectory(result, currentBinary)) + { + result = currentBinary; + } + } + + // The current working directory on Windows cannot be a network + // path. Therefore relative paths cannot work when the binary tree + // is a network path. + if(result.size() < 2 || result.substr(0, 2) != "//") + { + this->Position->BuildSystemDirectory->RelativePathTopBinary = result; + } + else + { + this->Position->BuildSystemDirectory->RelativePathTopBinary = ""; + } +} + +cmState::Snapshot cmState::CreateBaseSnapshot() +{ + PositionType pos = this->SnapshotData.Extend(this->SnapshotData.Root()); + pos->DirectoryParent = this->SnapshotData.Root(); + pos->SnapshotType = BuildsystemDirectoryType; + pos->BuildSystemDirectory = + this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root()); + return cmState::Snapshot(this, pos); +} + +cmState::Snapshot +cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot) +{ + assert(originSnapshot.IsValid()); + PositionType pos = this->SnapshotData.Extend(originSnapshot.Position); + pos->DirectoryParent = originSnapshot.Position; + pos->SnapshotType = BuildsystemDirectoryType; + pos->BuildSystemDirectory = + this->BuildsystemDirectory.Extend( + originSnapshot.Position->BuildSystemDirectory); return cmState::Snapshot(this, pos); } @@ -494,52 +705,99 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position) const char* cmState::Snapshot::GetCurrentSourceDirectory() const { - return this->State->Locations[this->Position].c_str(); + return this->Position->BuildSystemDirectory->Location.c_str(); } void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir) { - assert(this->State->Locations.size() > this->Position); - this->State->Locations[this->Position] = dir; - cmSystemTools::ConvertToUnixSlashes( - this->State->Locations[this->Position]); - this->State->Locations[this->Position] = - cmSystemTools::CollapseFullPath(this->State->Locations[this->Position]); + assert(this->State); + std::string& loc = this->Position->BuildSystemDirectory->Location; + loc = dir; + cmSystemTools::ConvertToUnixSlashes(loc); + loc = cmSystemTools::CollapseFullPath(loc); + + cmSystemTools::SplitPath( + loc, + this->Position->BuildSystemDirectory->CurrentSourceDirectoryComponents); + this->ComputeRelativePathTopSource(); } const char* cmState::Snapshot::GetCurrentBinaryDirectory() const { - return this->State->OutputLocations[this->Position].c_str(); + return this->Position->BuildSystemDirectory->OutputLocation.c_str(); } void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir) { - assert(this->State->OutputLocations.size() > this->Position); - this->State->OutputLocations[this->Position] = dir; - cmSystemTools::ConvertToUnixSlashes( - this->State->OutputLocations[this->Position]); - this->State->OutputLocations[this->Position] = - cmSystemTools::CollapseFullPath( - this->State->OutputLocations[this->Position]); + std::string& loc = this->Position->BuildSystemDirectory->OutputLocation; + loc = dir; + cmSystemTools::ConvertToUnixSlashes(loc); + loc = cmSystemTools::CollapseFullPath(loc); + + cmSystemTools::SplitPath( + loc, + this->Position->BuildSystemDirectory->CurrentBinaryDirectoryComponents); + this->ComputeRelativePathTopBinary(); +} + +std::vector<std::string> const& +cmState::Snapshot::GetCurrentSourceDirectoryComponents() +{ + return this->Position->BuildSystemDirectory + ->CurrentSourceDirectoryComponents; +} + +std::vector<std::string> const& +cmState::Snapshot::GetCurrentBinaryDirectoryComponents() +{ + return this->Position->BuildSystemDirectory + ->CurrentBinaryDirectoryComponents; +} + +const char* cmState::Snapshot::GetRelativePathTopSource() const +{ + return this->Position->BuildSystemDirectory->RelativePathTopSource.c_str(); +} + +const char* cmState::Snapshot::GetRelativePathTopBinary() const +{ + return this->Position->BuildSystemDirectory->RelativePathTopBinary.c_str(); +} + +void cmState::Snapshot::SetRelativePathTopSource(const char* dir) +{ + this->Position->BuildSystemDirectory->RelativePathTopSource = dir; +} + +void cmState::Snapshot::SetRelativePathTopBinary(const char* dir) +{ + this->Position->BuildSystemDirectory->RelativePathTopBinary = dir; } bool cmState::Snapshot::IsValid() const { - return this->State ? true : false; + return this->State && this->Position.IsValid() + ? this->Position != this->State->SnapshotData.Root() + : false; } -cmState::Snapshot cmState::Snapshot::GetParent() const +cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const { Snapshot snapshot; - if (!this->State) + if (!this->State || this->Position == this->State->SnapshotData.Root()) { return snapshot; } - PositionType parentPos = this->State->ParentPositions[this->Position]; - if (parentPos > 0) + PositionType parentPos = this->Position->DirectoryParent; + if (parentPos != this->State->SnapshotData.Root()) { snapshot = Snapshot(this->State, parentPos); } return snapshot; } + +cmState* cmState::Snapshot::GetState() const +{ + return this->State; +} diff --git a/Source/cmState.h b/Source/cmState.h index ed58c64..353a6c6 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -15,29 +15,50 @@ #include "cmStandardIncludes.h" #include "cmPropertyDefinitionMap.h" #include "cmPropertyMap.h" +#include "cmLinkedTree.h" class cmake; class cmCommand; class cmState { - typedef std::vector<std::string>::size_type PositionType; + struct SnapshotDataType; + typedef cmLinkedTree<SnapshotDataType>::iterator PositionType; friend class Snapshot; public: cmState(cmake* cm); ~cmState(); + enum SnapshotType + { + BuildsystemDirectoryType + }; + class Snapshot { public: - Snapshot(cmState* state = 0, PositionType position = 0); + Snapshot(cmState* state = 0, PositionType position = PositionType()); const char* GetCurrentSourceDirectory() const; void SetCurrentSourceDirectory(std::string const& dir); const char* GetCurrentBinaryDirectory() const; void SetCurrentBinaryDirectory(std::string const& dir); + std::vector<std::string> const& GetCurrentSourceDirectoryComponents(); + std::vector<std::string> const& GetCurrentBinaryDirectoryComponents(); + + const char* GetRelativePathTopSource() const; + const char* GetRelativePathTopBinary() const; + void SetRelativePathTopSource(const char* dir); + void SetRelativePathTopBinary(const char* dir); + bool IsValid() const; - Snapshot GetParent() const; + Snapshot GetBuildsystemDirectoryParent() const; + + cmState* GetState() const; + + private: + void ComputeRelativePathTopSource(); + void ComputeRelativePathTopBinary(); private: friend class cmState; @@ -45,7 +66,8 @@ public: cmState::PositionType Position; }; - Snapshot CreateSnapshot(Snapshot originSnapshot); + Snapshot CreateBaseSnapshot(); + Snapshot CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot); enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC, UNINITIALIZED }; @@ -81,7 +103,7 @@ public: void RemoveCacheEntryProperty(std::string const& key, std::string const& propertyName); - void Initialize(); + void Reset(); // Define a property void DefineProperty(const std::string& name, cmProperty::ScopeType scope, const char *ShortDescription, @@ -89,12 +111,14 @@ public: bool chain = false); // get property definition - cmPropertyDefinition *GetPropertyDefinition - (const std::string& name, cmProperty::ScopeType scope); + cmPropertyDefinition const* GetPropertyDefinition + (const std::string& name, cmProperty::ScopeType scope) const; // Is a property defined? - bool IsPropertyDefined(const std::string& name, cmProperty::ScopeType scope); - bool IsPropertyChained(const std::string& name, cmProperty::ScopeType scope); + bool IsPropertyDefined(const std::string& name, + cmProperty::ScopeType scope) const; + bool IsPropertyChained(const std::string& name, + cmProperty::ScopeType scope) const; void SetLanguageEnabled(std::string const& l); bool GetLanguageEnabled(std::string const& l) const; @@ -123,18 +147,45 @@ public: const char* GetBinaryDirectory() const; void SetBinaryDirectory(std::string const& binaryDirectory); + std::vector<std::string> const& GetSourceDirectoryComponents() const; + std::vector<std::string> const& GetBinaryDirectoryComponents() const; + + void SetWindowsShell(bool windowsShell); + bool UseWindowsShell() const; + void SetWindowsVSIDE(bool windowsVSIDE); + bool UseWindowsVSIDE() const; + void SetWatcomWMake(bool watcomWMake); + bool UseWatcomWMake() const; + void SetMinGWMake(bool minGWMake); + bool UseMinGWMake() const; + void SetNMake(bool nMake); + bool UseNMake() const; + void SetMSYSShell(bool mSYSShell); + bool UseMSYSShell() const; + private: std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions; std::vector<std::string> EnabledLanguages; std::map<std::string, cmCommand*> Commands; cmPropertyMap GlobalProperties; cmake* CMakeInstance; - std::vector<std::string> Locations; - std::vector<std::string> OutputLocations; - std::vector<PositionType> ParentPositions; + + struct BuildsystemDirectoryStateType; + cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory; + + cmLinkedTree<SnapshotDataType> SnapshotData; + + std::vector<std::string> SourceDirectoryComponents; + std::vector<std::string> BinaryDirectoryComponents; std::string SourceDirectory; std::string BinaryDirectory; bool IsInTryCompile; + bool WindowsShell; + bool WindowsVSIDE; + bool WatcomWMake; + bool MinGWMake; + bool NMake; + bool MSYSShell; }; #endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 8a8c163..398d5c9 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -13,7 +13,7 @@ #include "cmake.h" #include "cmMakefile.h" #include "cmSourceFile.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmGlobalGenerator.h" #include "cmComputeLinkInformation.h" #include "cmListFileCache.h" @@ -94,13 +94,13 @@ class cmTargetInternals { public: cmTargetInternals() - : Backtrace(NULL) + : Backtrace() { this->PolicyWarnedCMP0022 = false; this->UtilityItemsDone = false; } cmTargetInternals(cmTargetInternals const&) - : Backtrace(NULL) + : Backtrace() { this->PolicyWarnedCMP0022 = false; this->UtilityItemsDone = false; @@ -239,13 +239,6 @@ cmTargetInternals::~cmTargetInternals() //---------------------------------------------------------------------------- cmTarget::cmTarget() { -#define INITIALIZE_TARGET_POLICY_MEMBER(POLICY) \ - this->PolicyStatus ## POLICY = cmPolicies::WARN; - - CM_FOR_EACH_TARGET_POLICY(INITIALIZE_TARGET_POLICY_MEMBER) - -#undef INITIALIZE_TARGET_POLICY_MEMBER - this->Makefile = 0; #if defined(_WIN32) && !defined(__CYGWIN__) this->LinkLibrariesForVS6Analyzed = false; @@ -286,9 +279,6 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Set our makefile. this->Makefile = mf; - // set the cmake instance of the properties - this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); - // Check whether this is a DLL platform. this->DLLPlatform = (this->Makefile->IsOn("WIN32") || this->Makefile->IsOn("CYGWIN") || @@ -333,9 +323,11 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("MACOSX_BUNDLE", 0); this->SetPropertyDefault("MACOSX_RPATH", 0); this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); + this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0); this->SetPropertyDefault("C_STANDARD", 0); this->SetPropertyDefault("C_STANDARD_REQUIRED", 0); this->SetPropertyDefault("C_EXTENSIONS", 0); + this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0); this->SetPropertyDefault("CXX_STANDARD", 0); this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0); this->SetPropertyDefault("CXX_EXTENSIONS", 0); @@ -441,20 +433,14 @@ void cmTarget::SetMakefile(cmMakefile* mf) } // Record current policies for later use. -#define CAPTURE_TARGET_POLICY(POLICY) \ - this->PolicyStatus ## POLICY = \ - this->Makefile->GetPolicyStatus(cmPolicies::POLICY); - - CM_FOR_EACH_TARGET_POLICY(CAPTURE_TARGET_POLICY) - -#undef CAPTURE_TARGET_POLICY + this->Makefile->RecordPolicies(this->PolicyMap); if (this->TargetTypeValue == INTERFACE_LIBRARY) { // This policy is checked in a few conditions. The properties relevant // to the policy are always ignored for INTERFACE_LIBRARY targets, // so ensure that the conditions don't lead to nonsense. - this->PolicyStatusCMP0022 = cmPolicies::NEW; + this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW); } if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) @@ -762,7 +748,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files, "SOURCES") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugSourcesDone = true; } @@ -1239,8 +1225,11 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature) ret = false; } } - cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - this->TLLCommands.push_back(std::make_pair(signature, lfbt)); + cmListFileContext lfc = this->Makefile->GetExecutionContext(); + if (this->TLLCommands.empty() || this->TLLCommands.back().second != lfc) + { + this->TLLCommands.push_back(std::make_pair(signature, lfc)); + } return ret; } @@ -1248,39 +1237,19 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature) void cmTarget::GetTllSignatureTraces(std::ostringstream &s, TLLSignature sig) const { - std::vector<cmListFileBacktrace> sigs; - typedef std::vector<std::pair<TLLSignature, cmListFileBacktrace> > Container; + const char *sigString = (sig == cmTarget::KeywordTLLSignature ? "keyword" + : "plain"); + s << "The uses of the " << sigString << " signature are here:\n"; + typedef std::vector<std::pair<TLLSignature, cmListFileContext> > Container; + cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot()); for(Container::const_iterator it = this->TLLCommands.begin(); it != this->TLLCommands.end(); ++it) { if (it->first == sig) { - sigs.push_back(it->second); - } - } - if (!sigs.empty()) - { - const char *sigString - = (sig == cmTarget::KeywordTLLSignature ? "keyword" - : "plain"); - s << "The uses of the " << sigString << " signature are here:\n"; - UNORDERED_SET<std::string> emitted; - for(std::vector<cmListFileBacktrace>::iterator it = sigs.begin(); - it != sigs.end(); ++it) - { - it->MakeRelative(); - cmListFileBacktrace::const_iterator i = it->begin(); - if(i != it->end()) - { - cmListFileContext const& lfc = *i; - std::ostringstream line; - line << " * " << (lfc.Line? "": " in ") << lfc << std::endl; - if (emitted.insert(line.str()).second) - { - s << line.str(); - } - ++i; - } + cmListFileContext lfc = it->second; + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); + s << " * " << lfc << std::endl; } } } @@ -1787,7 +1756,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) } else { - this->Properties.SetProperty(prop, value, cmProperty::TARGET); + this->Properties.SetProperty(prop, value); this->MaybeInvalidatePropertyCache(prop); } } @@ -1872,7 +1841,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, } else { - this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); + this->Properties.AppendProperty(prop, value, asString); this->MaybeInvalidatePropertyCache(prop); } } @@ -2121,7 +2090,7 @@ cmTarget::GetIncludeDirectories(const std::string& config, "INCLUDE_DIRECTORIES") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugIncludesDone = true; } @@ -2292,7 +2261,7 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, "COMPILE_OPTIONS") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompileOptionsDone = true; } @@ -2363,7 +2332,7 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, "COMPILE_DEFINITIONS") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompileDefinitionsDone = true; } @@ -2464,7 +2433,7 @@ void cmTarget::GetCompileFeatures(std::vector<std::string> &result, "COMPILE_FEATURES") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompileFeaturesDone = true; } @@ -2829,34 +2798,6 @@ void cmTarget::GetTargetVersion(bool soversion, } //---------------------------------------------------------------------------- -const char* cmTarget::GetFeature(const std::string& feature, - const std::string& config) const -{ - if(!config.empty()) - { - std::string featureConfig = feature; - featureConfig += "_"; - featureConfig += cmSystemTools::UpperCase(config); - if(const char* value = this->GetProperty(featureConfig)) - { - return value; - } - } - if(const char* value = this->GetProperty(feature)) - { - return value; - } - return this->Makefile->GetFeature(feature, config); -} - -//---------------------------------------------------------------------------- -bool cmTarget::GetFeatureAsBool(const std::string& feature, - const std::string& config) const -{ - return cmSystemTools::IsOn(this->GetFeature(feature, config)); -} - -//---------------------------------------------------------------------------- bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const { if (this->IsImported()) @@ -2953,8 +2894,7 @@ const char *cmTarget::GetProperty(const std::string& prop, // cannot take into account the per-configuration name of the // target because the configuration type may not be known at // CMake time. - this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(), - cmProperty::TARGET); + this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild()); } // Support "LOCATION_<CONFIG>". @@ -2965,9 +2905,7 @@ const char *cmTarget::GetProperty(const std::string& prop, return 0; } const char* configName = prop.c_str() + 9; - this->Properties.SetProperty(prop, - this->GetLocation(configName), - cmProperty::TARGET); + this->Properties.SetProperty(prop, this->GetLocation(configName)); } // Support "<CONFIG>_LOCATION". else if(cmHasLiteralSuffix(prop, "_LOCATION")) @@ -2979,9 +2917,7 @@ const char *cmTarget::GetProperty(const std::string& prop, { return 0; } - this->Properties.SetProperty(prop, - this->GetLocation(configName), - cmProperty::TARGET); + this->Properties.SetProperty(prop, this->GetLocation(configName)); } } } @@ -3183,17 +3119,19 @@ const char *cmTarget::GetProperty(const std::string& prop, } } } - this->Properties.SetProperty("SOURCES", ss.str().c_str(), - cmProperty::TARGET); + this->Properties.SetProperty("SOURCES", ss.str().c_str()); } } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal) { - return this->Makefile->GetProperty(prop, cmProperty::TARGET); + const bool chain = this->GetMakefile()->GetState()-> + IsPropertyChained(prop, cmProperty::TARGET); + if (chain) + { + return this->Makefile->GetProperty(prop, chain); + } } return retVal; } @@ -4872,7 +4810,7 @@ cmTarget::ReportPropertyOrigin(const std::string &p, p) != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompatiblePropertiesDone[p] = true; } @@ -5946,8 +5884,8 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( // libraries and executables that export symbols. const char* explicitLibraries = 0; std::string linkIfaceProp; - if(thisTarget->PolicyStatusCMP0022 != cmPolicies::OLD && - thisTarget->PolicyStatusCMP0022 != cmPolicies::WARN) + if(thisTarget->GetPolicyStatusCMP0022() != cmPolicies::OLD && + thisTarget->GetPolicyStatusCMP0022() != cmPolicies::WARN) { // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; @@ -5973,7 +5911,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( } if(explicitLibraries && - thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && + thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN && !this->PolicyWarnedCMP0022) { // Compare the explicitly set old link interface properties to the @@ -6017,8 +5955,8 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( iface.Libraries, iface.HadHeadSensitiveCondition); } - else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN - || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) + else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN + || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD) // If CMP0022 is NEW then the plain tll signature sets the // INTERFACE_LINK_LIBRARIES, so if we get here then the project // cleared the property explicitly and we should not fall back @@ -6029,7 +5967,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); iface.Libraries.insert(iface.Libraries.end(), impl->Libraries.begin(), impl->Libraries.end()); - if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && + if(thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN && !this->PolicyWarnedCMP0022 && !usage_requirements_only) { // Compare the link implementation fallback link interface to the @@ -6121,8 +6059,8 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, } } } - else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN - || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) + else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN + || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD) { // The link implementation is the default link interface. cmTarget::LinkImplementationLibraries const* @@ -6442,7 +6380,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const if(lib != item) { cmake* cm = this->Makefile->GetCMakeInstance(); - switch(this->PolicyStatusCMP0004) + switch(this->GetPolicyStatusCMP0004()) { case cmPolicies::WARN: { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a032414..6916bd3 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -19,7 +19,11 @@ #include <cmsys/auto_ptr.hxx> #if defined(CMAKE_BUILD_WITH_CMAKE) -#include <cmsys/hash_map.hxx> +# ifdef CMake_HAVE_CXX11_UNORDERED_MAP +# include <unordered_map> +# else +# include <cmsys/hash_map.hxx> +# endif #endif #define CM_FOR_EACH_TARGET_POLICY(F) \ @@ -35,7 +39,8 @@ F(CMP0042) \ F(CMP0046) \ F(CMP0052) \ - F(CMP0060) + F(CMP0060) \ + F(CMP0063) class cmake; class cmMakefile; @@ -61,7 +66,7 @@ public: class cmLinkImplItem: public cmLinkItem { public: - cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {} + cmLinkImplItem(): cmLinkItem(), Backtrace(), FromGenex(false) {} cmLinkImplItem(std::string const& n, cmTarget const* t, cmListFileBacktrace const& bt, @@ -139,7 +144,7 @@ public: #define DECLARE_TARGET_POLICY(POLICY) \ cmPolicies::PolicyStatus GetPolicyStatus ## POLICY () const \ - { return this->PolicyStatus ## POLICY; } + { return this->PolicyMap.Get(cmPolicies::POLICY); } CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY) @@ -255,11 +260,6 @@ public: bool GetPropertyAsBool(const std::string& prop) const; void CheckProperty(const std::string& prop, cmMakefile* context) const; - const char* GetFeature(const std::string& feature, - const std::string& config) const; - bool GetFeatureAsBool(const std::string& feature, - const std::string& config) const; - bool IsImported() const {return this->IsImportedTarget;} void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const; @@ -637,12 +637,6 @@ public: private: bool HandleLocationPropertyPolicy(cmMakefile* context) const; - // The set of include directories that are marked as system include - // directories. - std::set<std::string> SystemIncludeDirectories; - - std::vector<std::pair<TLLSignature, cmListFileBacktrace> > TLLCommands; - #if defined(_WIN32) && !defined(__CYGWIN__) /** * A list of direct dependencies. Use in conjunction with DependencyMap. @@ -737,40 +731,48 @@ private: void GetSourceFiles(std::vector<std::string> &files, const std::string& config) const; private: + mutable cmPropertyMap Properties; + std::set<std::string> SystemIncludeDirectories; + std::set<std::string> LinkDirectoriesEmmitted; + std::set<std::string> Utilities; + mutable std::set<std::string> LinkImplicitNullProperties; + std::map<std::string, cmListFileBacktrace> UtilityBacktraces; + mutable std::map<std::string, bool> DebugCompatiblePropertiesDone; + mutable std::map<std::string, std::string> MaxLanguageStandards; + cmPolicies::PolicyMap PolicyMap; std::string Name; + std::string InstallPath; + std::string RuntimeInstallPath; + mutable std::string ExportMacro; + std::vector<std::string> LinkDirectories; std::vector<cmCustomCommand> PreBuildCommands; std::vector<cmCustomCommand> PreLinkCommands; std::vector<cmCustomCommand> PostBuildCommands; - TargetType TargetTypeValue; + std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands; LinkLibraryVectorType PrevLinkedLibraries; + LinkLibraryVectorType OriginalLinkLibraries; #if defined(_WIN32) && !defined(__CYGWIN__) LinkLibraryVectorType LinkLibrariesForVS6; - bool LinkLibrariesForVS6Analyzed; #endif - std::vector<std::string> LinkDirectories; - std::set<std::string> LinkDirectoriesEmmitted; + cmMakefile* Makefile; + cmTargetInternalPointer Internal; + TargetType TargetTypeValue; bool HaveInstallRule; - std::string InstallPath; - std::string RuntimeInstallPath; - mutable std::string ExportMacro; - std::set<std::string> Utilities; - std::map<std::string, cmListFileBacktrace> UtilityBacktraces; bool RecordDependencies; - mutable cmPropertyMap Properties; - LinkLibraryVectorType OriginalLinkLibraries; bool DLLPlatform; bool IsAndroid; bool IsApple; bool IsImportedTarget; + bool BuildInterfaceIncludesAppended; mutable bool DebugIncludesDone; - mutable std::map<std::string, bool> DebugCompatiblePropertiesDone; mutable bool DebugCompileOptionsDone; mutable bool DebugCompileDefinitionsDone; mutable bool DebugSourcesDone; mutable bool DebugCompileFeaturesDone; - mutable std::set<std::string> LinkImplicitNullProperties; - mutable std::map<std::string, std::string> MaxLanguageStandards; - bool BuildInterfaceIncludesAppended; + mutable bool LinkImplementationLanguageIsContextDependent; +#if defined(_WIN32) && !defined(__CYGWIN__) + bool LinkLibrariesForVS6Analyzed; +#endif // Cache target output paths for each configuration. struct OutputInfo; @@ -820,23 +822,10 @@ private: void ProcessSourceExpression(std::string const& expr); - // The cmMakefile instance that owns this target. This should - // always be set. - cmMakefile* Makefile; - - // Policy status recorded when target was created. -#define TARGET_POLICY_MEMBER(POLICY) \ - cmPolicies::PolicyStatus PolicyStatus ## POLICY; - - CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_MEMBER) - -#undef TARGET_POLICY_MEMBER - // Internal representation details. friend class cmTargetInternals; friend class cmGeneratorTarget; friend class cmTargetTraceDependencies; - cmTargetInternalPointer Internal; void ComputeVersionedName(std::string& vName, std::string const& prefix, @@ -844,12 +833,14 @@ private: std::string const& suffix, std::string const& name, const char* version) const; - - mutable bool LinkImplementationLanguageIsContextDependent; }; #ifdef CMAKE_BUILD_WITH_CMAKE -typedef cmsys::hash_map<std::string,cmTarget> cmTargets; +#ifdef CMake_HAVE_CXX11_UNORDERED_MAP +typedef std::unordered_map<std::string, cmTarget> cmTargets; +#else +typedef cmsys::hash_map<std::string, cmTarget> cmTargets; +#endif #else typedef std::map<std::string,cmTarget> cmTargets; #endif diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index ff5d411..6fcd0dc 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -21,7 +21,6 @@ cmTest::cmTest(cmMakefile* mf) { this->Makefile = mf; this->OldStyle = true; - this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); } //---------------------------------------------------------------------------- @@ -50,12 +49,15 @@ void cmTest::SetCommand(std::vector<std::string> const& command) //---------------------------------------------------------------------------- const char *cmTest::GetProperty(const std::string& prop) const { - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal) { - return this->Makefile->GetProperty(prop,cmProperty::TEST); + const bool chain = this->Makefile->GetState()-> + IsPropertyChained(prop, cmProperty::TEST); + if (chain) + { + return this->Makefile->GetProperty(prop, chain); + } } return retVal; } @@ -69,12 +71,12 @@ bool cmTest::GetPropertyAsBool(const std::string& prop) const //---------------------------------------------------------------------------- void cmTest::SetProperty(const std::string& prop, const char* value) { - this->Properties.SetProperty(prop, value, cmProperty::TEST); + this->Properties.SetProperty(prop, value); } //---------------------------------------------------------------------------- void cmTest::AppendProperty(const std::string& prop, const char* value, bool asString) { - this->Properties.AppendProperty(prop, value, cmProperty::TEST, asString); + this->Properties.AppendProperty(prop, value, asString); } diff --git a/Source/cmTest.h b/Source/cmTest.h index c6e7e42..ca88afe 100644 --- a/Source/cmTest.h +++ b/Source/cmTest.h @@ -40,11 +40,6 @@ public: return this->Command; } - /** - * Print the structure to std::cout. - */ - void Print() const; - ///! Set/Get a property of this source file void SetProperty(const std::string& prop, const char *value); void AppendProperty(const std::string& prop, diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 7e11d8c..546ad71 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -12,7 +12,7 @@ #include "cmTestGenerator.h" #include "cmGeneratorExpression.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -97,13 +97,13 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs); std::string emulatorExe(emulatorWithArgs[0]); cmSystemTools::ConvertToUnixSlashes(emulatorExe); - os << cmLocalGenerator::EscapeForCMake(emulatorExe) << " "; + os << cmOutputConverter::EscapeForCMake(emulatorExe) << " "; for(std::vector<std::string>::const_iterator ei = emulatorWithArgs.begin()+1; ei != emulatorWithArgs.end(); ++ei) { - os << cmLocalGenerator::EscapeForCMake(*ei) << " "; + os << cmOutputConverter::EscapeForCMake(*ei) << " "; } } } @@ -115,11 +115,11 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, } // Generate the command line with full escapes. - os << cmLocalGenerator::EscapeForCMake(exe); + os << cmOutputConverter::EscapeForCMake(exe); for(std::vector<std::string>::const_iterator ci = command.begin()+1; ci != command.end(); ++ci) { - os << " " << cmLocalGenerator::EscapeForCMake( + os << " " << cmOutputConverter::EscapeForCMake( ge.Parse(*ci)->Evaluate(mf, config)); } @@ -136,7 +136,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, i != pm.end(); ++i) { os << " " << i->first - << " " << cmLocalGenerator::EscapeForCMake( + << " " << cmOutputConverter::EscapeForCMake( ge.Parse(i->second.GetValue())->Evaluate(mf, config)); } os << ")" << std::endl; @@ -206,7 +206,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, i != pm.end(); ++i) { fout << " " << i->first - << " " << cmLocalGenerator::EscapeForCMake(i->second.GetValue()); + << " " << cmOutputConverter::EscapeForCMake(i->second.GetValue()); } fout << ")" << std::endl; } diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 3cd92cb..b9ffe5e 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -375,7 +375,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, comment += "Run arguments : "; comment += runArgs; comment += "\n"; - comment += " Called from: " + this->Makefile->GetListFileStack(); + comment += " Called from: " + this->Makefile->FormatListFileStack(); cmsys::SystemTools::ReplaceString(comment, "\n", "\n# "); file << comment << "\n\n"; diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 9473008..09cef5e 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -68,11 +68,8 @@ static void cmVariableWatchCommandVariableAccessed( cmExecutionStatus status; if(!makefile->ExecuteCommand(newLFF,status)) { - arg.FilePath = "Unknown"; - arg.Line = 0; std::ostringstream error; - error << "Error in cmake code at\n" - << arg.FilePath << ":" << arg.Line << ":\n" + error << "Error in cmake code at\nUnknown:0:\n" << "A command failed during the invocation of callback \"" << data->Command << "\"."; cmSystemTools::Error(error.str().c_str()); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 131a134..9b78df3 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -47,13 +47,13 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetClFlagTable() const { if(this->MSTools) { - cmLocalVisualStudioGenerator::VSVersion + cmGlobalVisualStudioGenerator::VSVersion v = this->LocalGenerator->GetVersion(); - if(v >= cmLocalVisualStudioGenerator::VS14) + if(v >= cmGlobalVisualStudioGenerator::VS14) { return cmVS14CLFlagTable; } - else if(v >= cmLocalVisualStudioGenerator::VS12) + else if(v >= cmGlobalVisualStudioGenerator::VS12) { return cmVS12CLFlagTable; } - else if(v == cmLocalVisualStudioGenerator::VS11) + else if(v == cmGlobalVisualStudioGenerator::VS11) { return cmVS11CLFlagTable; } else { return cmVS10CLFlagTable; } @@ -65,13 +65,13 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetRcFlagTable() const { if(this->MSTools) { - cmLocalVisualStudioGenerator::VSVersion + cmGlobalVisualStudioGenerator::VSVersion v = this->LocalGenerator->GetVersion(); - if(v >= cmLocalVisualStudioGenerator::VS14) + if(v >= cmGlobalVisualStudioGenerator::VS14) { return cmVS14RCFlagTable; } - else if(v >= cmLocalVisualStudioGenerator::VS12) + else if(v >= cmGlobalVisualStudioGenerator::VS12) { return cmVS12RCFlagTable; } - else if(v == cmLocalVisualStudioGenerator::VS11) + else if(v == cmGlobalVisualStudioGenerator::VS11) { return cmVS11RCFlagTable; } else { return cmVS10RCFlagTable; } @@ -83,13 +83,13 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLibFlagTable() const { if(this->MSTools) { - cmLocalVisualStudioGenerator::VSVersion + cmGlobalVisualStudioGenerator::VSVersion v = this->LocalGenerator->GetVersion(); - if(v >= cmLocalVisualStudioGenerator::VS14) + if(v >= cmGlobalVisualStudioGenerator::VS14) { return cmVS14LibFlagTable; } - else if(v >= cmLocalVisualStudioGenerator::VS12) + else if(v >= cmGlobalVisualStudioGenerator::VS12) { return cmVS12LibFlagTable; } - else if(v == cmLocalVisualStudioGenerator::VS11) + else if(v == cmGlobalVisualStudioGenerator::VS11) { return cmVS11LibFlagTable; } else { return cmVS10LibFlagTable; } @@ -101,13 +101,13 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLinkFlagTable() const { if(this->MSTools) { - cmLocalVisualStudioGenerator::VSVersion + cmGlobalVisualStudioGenerator::VSVersion v = this->LocalGenerator->GetVersion(); - if(v >= cmLocalVisualStudioGenerator::VS14) + if(v >= cmGlobalVisualStudioGenerator::VS14) { return cmVS14LinkFlagTable; } - else if(v >= cmLocalVisualStudioGenerator::VS12) + else if(v >= cmGlobalVisualStudioGenerator::VS12) { return cmVS12LinkFlagTable; } - else if(v == cmLocalVisualStudioGenerator::VS11) + else if(v == cmGlobalVisualStudioGenerator::VS11) { return cmVS11LinkFlagTable; } else { return cmVS10LinkFlagTable; } @@ -119,13 +119,13 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetMasmFlagTable() const { if(this->MSTools) { - cmLocalVisualStudioGenerator::VSVersion + cmGlobalVisualStudioGenerator::VSVersion v = this->LocalGenerator->GetVersion(); - if(v >= cmLocalVisualStudioGenerator::VS14) + if(v >= cmGlobalVisualStudioGenerator::VS14) { return cmVS14MASMFlagTable; } - else if(v >= cmLocalVisualStudioGenerator::VS12) + else if(v >= cmGlobalVisualStudioGenerator::VS12) { return cmVS12MASMFlagTable; } - else if(v == cmLocalVisualStudioGenerator::VS11) + else if(v == cmGlobalVisualStudioGenerator::VS11) { return cmVS11MASMFlagTable; } else { return cmVS10MASMFlagTable; } @@ -173,11 +173,11 @@ cmVisualStudio10TargetGenerator(cmTarget* target, this->Target = target; this->GeneratorTarget = gg->GetGeneratorTarget(target); this->Makefile = target->GetMakefile(); + this->Makefile->GetConfigurations(this->Configurations); this->LocalGenerator = (cmLocalVisualStudio7Generator*) this->Makefile->GetLocalGenerator(); this->Name = this->Target->GetName(); - this->GlobalGenerator->CreateGUID(this->Name.c_str()); this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str()); this->Platform = gg->GetPlatformName(); this->NsightTegra = gg->IsNsightTegra(); @@ -525,10 +525,9 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; - std::vector<std::string> const * configs = - this->GlobalGenerator->GetConfigurations(); - for(std::vector<std::string>::const_iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); if(this->Target->GetProperty("VS_GLOBAL_ROOTNAMESPACE")) @@ -629,11 +628,9 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences() void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() { this->WriteString("<ItemGroup Label=\"ProjectConfigurations\">\n", 1); - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); - for(std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { this->WriteString("<ProjectConfiguration Include=\"", 2); (*this->BuildFileStream ) << *i << "|" << this->Platform << "\">\n"; @@ -649,11 +646,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() { - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); - for(std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { this->WritePlatformConfigTag("PropertyGroup", i->c_str(), @@ -864,14 +859,12 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source, } } cmLocalVisualStudio7Generator* lg = this->LocalGenerator; - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); this->WriteSource("CustomBuild", source, ">\n"); - for(std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { cmCustomCommandGenerator ccg(command, *i, this->Makefile); std::string comment = lg->ConstructComment(ccg); @@ -911,7 +904,8 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source, sep = ";"; } (*this->BuildFileStream ) << "</Outputs>\n"; - if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10) + if(this->LocalGenerator->GetVersion() + > cmGlobalVisualStudioGenerator::VS10) { // VS >= 11 let us turn off linking of custom command outputs. this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3); @@ -928,10 +922,7 @@ cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path, return forceRelative ? cmSystemTools::RelativePath( this->Makefile->GetCurrentBinaryDirectory(), path.c_str()) - : this->LocalGenerator->Convert(path.c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED, - /* optional = */ true); + : path.c_str(); } void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s) @@ -1089,7 +1080,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() (*this->BuildFileStream) << name << "\">\n"; std::string guidName = "SG_Filter_"; guidName += name; - this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); @@ -1104,7 +1094,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() { this->WriteString("<Filter Include=\"Object Libraries\">\n", 2); std::string guidName = "SG_Filter_Object Libraries"; - this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); @@ -1117,7 +1106,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() { this->WriteString("<Filter Include=\"Resource Files\">\n", 2); std::string guidName = "SG_Filter_Resource Files"; - this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); @@ -1339,8 +1327,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) if(!deployContent.empty()) { - std::vector<std::string> const* configs = - this->GlobalGenerator->GetConfigurations(); cmGeneratorExpression ge; cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(deployContent); @@ -1352,13 +1338,14 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) << "\\%(FileName)%(Extension)"; this->WriteString("</Link>\n", 0); } - for(size_t i = 0; i != configs->size(); ++i) + for(size_t i = 0; i != this->Configurations.size(); ++i) { - if(0 == strcmp(cge->Evaluate(this->Makefile, (*configs)[i]), "1")) + if(0 == strcmp(cge->Evaluate(this->Makefile, + this->Configurations[i]), "1")) { this->WriteString("<DeploymentContent Condition=\"" "'$(Configuration)|$(Platform)'=='", 3); - (*this->BuildFileStream) << (*configs)[i] << "|" + (*this->BuildFileStream) << this->Configurations[i] << "|" << this->Platform << "'\">true"; this->WriteString("</DeploymentContent>\n", 0); } @@ -1366,7 +1353,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) { this->WriteString("<ExcludedFromBuild Condition=\"" "'$(Configuration)|$(Platform)'=='", 3); - (*this->BuildFileStream) << (*configs)[i] << "|" + (*this->BuildFileStream) << this->Configurations[i] << "|" << this->Platform << "'\">true"; this->WriteString("</ExcludedFromBuild>\n", 0); } @@ -1416,7 +1403,7 @@ void cmVisualStudio10TargetGenerator::WriteSource( // conversion uses full paths when possible to allow deeper trees. bool forceRelative = false; std::string sourceFile = this->ConvertPath(sf->GetFullPath(), false); - if(this->LocalGenerator->GetVersion() == cmLocalVisualStudioGenerator::VS10 + if(this->LocalGenerator->GetVersion() == cmGlobalVisualStudioGenerator::VS10 && cmSystemTools::FileIsFullPath(sourceFile.c_str())) { // Normal path conversion resulted in a full path. VS 10 (but not 11) @@ -1544,7 +1531,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources() ++si; } } - if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10) + if(this->LocalGenerator->GetVersion() > cmGlobalVisualStudioGenerator::VS10) { // For VS >= 11 we use LinkObjects to avoid linking custom command // outputs. Use Object for all external objects, generated or not. @@ -1654,11 +1641,9 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( (*this->BuildFileStream ) << "$(IntDir)/" << objectName << "</ObjectFileName>\n"; } - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); - for( std::vector<std::string>::iterator config = configs->begin(); - config != configs->end(); ++config) + for(std::vector<std::string>::const_iterator + config = this->Configurations.begin(); + config != this->Configurations.end(); ++config) { std::string configUpper = cmSystemTools::UpperCase(*config); std::string configDefines = defines; @@ -1736,11 +1721,9 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() this->WriteString("<PropertyGroup>\n", 2); this->WriteString("<_ProjectFileVersion>10.0.20506.1" "</_ProjectFileVersion>\n", 3); - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); - for(std::vector<std::string>::iterator config = configs->begin(); - config != configs->end(); ++config) + for(std::vector<std::string>::const_iterator + config = this->Configurations.begin(); + config != this->Configurations.end(); ++config) { if(ttype >= cmTarget::UTILITY) { @@ -1854,10 +1837,9 @@ OutputLinkIncremental(std::string const& configName) //---------------------------------------------------------------------------- bool cmVisualStudio10TargetGenerator::ComputeClOptions() { - std::vector<std::string> const* configs = - this->GlobalGenerator->GetConfigurations(); - for(std::vector<std::string>::const_iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { if(!this->ComputeClOptions(*i)) { @@ -2025,10 +2007,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( //---------------------------------------------------------------------------- bool cmVisualStudio10TargetGenerator::ComputeRcOptions() { - std::vector<std::string> const* configs = - this->GlobalGenerator->GetConfigurations(); - for(std::vector<std::string>::const_iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { if(!this->ComputeRcOptions(*i)) { @@ -2091,10 +2072,9 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions() { return true; } - std::vector<std::string> const* configs = - this->GlobalGenerator->GetConfigurations(); - for(std::vector<std::string>::const_iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { if(!this->ComputeMasmOptions(*i)) { @@ -2238,10 +2218,9 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions() this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - std::vector<std::string> const* configs = - this->GlobalGenerator->GetConfigurations(); - for(std::vector<std::string>::const_iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { if(!this->ComputeLinkOptions(*i)) { @@ -2590,11 +2569,9 @@ WriteMidlOptions(std::string const& /*config*/, void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() { - std::vector<std::string> *configs = - static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); - for(std::vector<std::string>::iterator i = configs->begin(); - i != configs->end(); ++i) + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) { std::vector<std::string> includes; this->LocalGenerator->GetIncludeDirectories(includes, diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index a2776de..451f8b2 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -137,6 +137,7 @@ private: OptionsMap MasmOptions; OptionsMap LinkOptions; std::string PathToVcxproj; + std::vector<std::string> Configurations; cmTarget* Target; cmGeneratorTarget* GeneratorTarget; cmMakefile* Makefile; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 00386f6..6512fc2 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -96,14 +96,14 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault() // remove the flag we need to override the IDE default of on. switch (this->Version) { - case cmLocalVisualStudioGenerator::VS7: - case cmLocalVisualStudioGenerator::VS71: + case cmGlobalVisualStudioGenerator::VS7: + case cmGlobalVisualStudioGenerator::VS71: this->FlagMap["ExceptionHandling"] = "FALSE"; break; - case cmLocalVisualStudioGenerator::VS10: - case cmLocalVisualStudioGenerator::VS11: - case cmLocalVisualStudioGenerator::VS12: - case cmLocalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VS14: // by default VS puts <ExceptionHandling></ExceptionHandling> empty // for a project, to make our projects look the same put a new line // and space over for the closing </ExceptionHandling> as the default @@ -132,7 +132,7 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose) this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end()) { this->FlagMap["SuppressStartupBanner"] = - this->Version < cmLocalVisualStudioGenerator::VS10 ? "FALSE" : ""; + this->Version < cmGlobalVisualStudioGenerator::VS10 ? "FALSE" : ""; } } @@ -270,7 +270,7 @@ cmVisualStudioGeneratorOptions { return; } - if(this->Version >= cmLocalVisualStudioGenerator::VS10) + if(this->Version >= cmGlobalVisualStudioGenerator::VS10) { // if there are configuration specific flags, then // use the configuration specific tag for PreprocessorDefinitions @@ -298,7 +298,7 @@ cmVisualStudioGeneratorOptions { // Escape the definition for the compiler. std::string define; - if(this->Version < cmLocalVisualStudioGenerator::VS10) + if(this->Version < cmGlobalVisualStudioGenerator::VS10) { define = this->LocalGenerator->EscapeForShell(di->c_str(), true); @@ -308,7 +308,7 @@ cmVisualStudioGeneratorOptions define = *di; } // Escape this flag for the IDE. - if(this->Version >= cmLocalVisualStudioGenerator::VS10) + if(this->Version >= cmGlobalVisualStudioGenerator::VS10) { define = cmVisualStudio10GeneratorOptionsEscapeForXML(define); @@ -325,7 +325,7 @@ cmVisualStudioGeneratorOptions fout << sep << define; sep = ";"; } - if(this->Version >= cmLocalVisualStudioGenerator::VS10) + if(this->Version >= cmGlobalVisualStudioGenerator::VS10) { fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix; } @@ -340,7 +340,7 @@ void cmVisualStudioGeneratorOptions ::OutputFlagMap(std::ostream& fout, const char* indent) { - if(this->Version >= cmLocalVisualStudioGenerator::VS10) + if(this->Version >= cmGlobalVisualStudioGenerator::VS10) { for(std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin(); m != this->FlagMap.end(); ++m) @@ -395,7 +395,7 @@ cmVisualStudioGeneratorOptions { if(!this->FlagString.empty()) { - if(this->Version >= cmLocalVisualStudioGenerator::VS10) + if(this->Version >= cmGlobalVisualStudioGenerator::VS10) { fout << prefix; if(this->Configuration.size()) diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index 5490a43..0179134 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -73,7 +73,7 @@ public: void SetConfiguration(const char* config); private: cmLocalVisualStudioGenerator* LocalGenerator; - cmLocalVisualStudioGenerator::VSVersion Version; + cmGlobalVisualStudioGenerator::VSVersion Version; std::string Configuration; Tool CurrentTool; diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx new file mode 100644 index 0000000..f9b3b49 --- /dev/null +++ b/Source/cmXMLWriter.cxx @@ -0,0 +1,134 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Daniel Pfeifer <daniel@pfeifer-mail.de> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmXMLWriter.h" +#include "cmXMLSafe.h" + +#include <cassert> +#include <fstream> + +cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level) +: Output(output) +, Level(level) +, ElementOpen(false) +, BreakAttrib(false) +, IsContent(false) +{ +} + +cmXMLWriter::~cmXMLWriter() +{ + assert(this->Elements.empty()); +} + +void cmXMLWriter::StartDocument(const char* encoding) +{ + this->Output << "<?xml version=\"1.0\" encoding=\"" << encoding << "\"?>"; +} + +void cmXMLWriter::EndDocument() +{ + assert(this->Elements.empty()); + this->Output << '\n'; +} + +void cmXMLWriter::StartElement(std::string const& name) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << '<' << name; + this->Elements.push(name); + this->ElementOpen = true; + this->BreakAttrib = false; +} + +void cmXMLWriter::EndElement() +{ + assert(!this->Elements.empty()); + if (this->ElementOpen) + { + this->Output << "/>"; + } + else + { + this->ConditionalLineBreak(!this->IsContent, this->Elements.size() - 1); + this->IsContent = false; + this->Output << "</" << this->Elements.top() << '>'; + } + this->Elements.pop(); + this->ElementOpen = false; +} + +void cmXMLWriter::BreakAttributes() +{ + this->BreakAttrib = true; +} + +void cmXMLWriter::Comment(const char* comment) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << "<!-- " << comment << " -->"; +} + +void cmXMLWriter::CData(std::string const& data) +{ + this->PreContent(); + this->Output << "<![CDATA[" << data << "]]>"; +} + +void cmXMLWriter::ProcessingInstruction(const char* target, const char* data) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << "<?" << target << ' ' << data << "?>"; +} + +void cmXMLWriter::FragmentFile(const char* fname) +{ + this->CloseStartElement(); + std::ifstream fin(fname, std::ios::in | std::ios::binary); + this->Output << fin.rdbuf(); +} + +void cmXMLWriter::ConditionalLineBreak(bool condition, std::size_t indent) +{ + if (condition) + { + this->Output << '\n' << std::string(indent + this->Level, '\t'); + } +} + +void cmXMLWriter::PreAttribute() +{ + assert(this->ElementOpen); + this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size()); + if (!this->BreakAttrib) + { + this->Output << ' '; + } +} + +void cmXMLWriter::PreContent() +{ + this->CloseStartElement(); + this->IsContent = true; +} + +void cmXMLWriter::CloseStartElement() +{ + if (this->ElementOpen) + { + this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size()); + this->Output << '>'; + this->ElementOpen = false; + } +} diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h new file mode 100644 index 0000000..c38c0de --- /dev/null +++ b/Source/cmXMLWriter.h @@ -0,0 +1,120 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Daniel Pfeifer <daniel@pfeifer-mail.de> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmXMLWiter_h +#define cmXMLWiter_h + +#include "cmStandardIncludes.h" +#include "cmXMLSafe.h" + +#include <ostream> +#include <stack> +#include <string> +#include <vector> + +class cmXMLWriter +{ +public: + cmXMLWriter(std::ostream& output, std::size_t level = 0); + ~cmXMLWriter(); + + void StartDocument(const char* encoding = "UTF-8"); + void EndDocument(); + + void StartElement(std::string const& name); + void EndElement(); + + void BreakAttributes(); + + template <typename T> + void Attribute(const char* name, T const& value) + { + this->PreAttribute(); + this->Output << name << "=\"" << SafeAttribute(value) << '"'; + } + + template <typename T> + void Element(std::string const& name, T const& value) + { + this->StartElement(name); + this->Content(value); + this->EndElement(); + } + + template <typename T> + void Content(T const& content) + { + this->PreContent(); + this->Output << SafeContent(content); + } + + void Comment(const char* comment); + + void CData(std::string const& data); + + void ProcessingInstruction(const char* target, const char* data); + + void FragmentFile(const char* fname); + +private: + cmXMLWriter(const cmXMLWriter&); + cmXMLWriter& operator=(const cmXMLWriter&); + + void ConditionalLineBreak(bool condition, std::size_t indent); + + void PreAttribute(); + void PreContent(); + + void CloseStartElement(); + +private: + static cmXMLSafe SafeAttribute(const char* value) + { + return cmXMLSafe(value); + } + + static cmXMLSafe SafeAttribute(std::string const& value) + { + return cmXMLSafe(value); + } + + template <typename T> + static T SafeAttribute(T value) + { + return value; + } + + static cmXMLSafe SafeContent(const char* value) + { + return cmXMLSafe(value).Quotes(false); + } + + static cmXMLSafe SafeContent(std::string const& value) + { + return cmXMLSafe(value).Quotes(false); + } + + template <typename T> + static T SafeContent(T value) + { + return value; + } + +private: + std::ostream& Output; + std::stack<std::string, std::vector<std::string> > Elements; + std::size_t Level; + bool ElementOpen; + bool BreakAttrib; + bool IsContent; +}; + +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 5c5c428..eeb6575 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -88,8 +88,6 @@ # include "cmGlobalKdevelopGenerator.h" #endif -#include "cmExtraQbsGenerator.h" - #ifdef CMAKE_USE_ECLIPSE # include "cmExtraEclipseCDT4Generator.h" #endif @@ -136,6 +134,7 @@ cmake::cmake() this->Policies = new cmPolicies(); this->State = new cmState(this); + this->CurrentSnapshot = this->State->CreateBaseSnapshot(); #ifdef __APPLE__ struct rlimit rlp; @@ -187,7 +186,7 @@ cmake::~cmake() void cmake::CleanupCommandsAndMacros() { - this->State->Initialize(); + this->State->Reset(); this->State->RemoveUserDefinedCommands(); } @@ -364,8 +363,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args, // if a generator was not specified use a generic one if (!gg) { - gg = new cmGlobalGenerator; - gg->SetCMakeInstance(this); + gg = new cmGlobalGenerator(this); created = true; } @@ -376,7 +374,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args, std::string homeOutputDir = this->GetHomeOutputDirectory(); this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); - cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator()); + cmsys::auto_ptr<cmLocalGenerator> lg(gg->MakeLocalGenerator()); lg->GetMakefile()->SetCurrentBinaryDirectory (cmSystemTools::GetCurrentWorkingDirectory()); lg->GetMakefile()->SetCurrentSourceDirectory @@ -413,12 +411,11 @@ bool cmake::FindPackage(const std::vector<std::string>& args) (cmSystemTools::GetCurrentWorkingDirectory()); // if a generator was not yet created, temporarily create one - cmGlobalGenerator *gg = new cmGlobalGenerator; - gg->SetCMakeInstance(this); + cmGlobalGenerator *gg = new cmGlobalGenerator(this); this->SetGlobalGenerator(gg); // read in the list file to fill the cache - cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator()); + cmsys::auto_ptr<cmLocalGenerator> lg(gg->MakeLocalGenerator()); cmMakefile* mf = lg->GetMakefile(); mf->SetCurrentBinaryDirectory (cmSystemTools::GetCurrentWorkingDirectory()); @@ -456,8 +453,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args) std::vector<std::string> includeDirs; cmSystemTools::ExpandListArgument(includes, includeDirs); - std::string includeFlags = lg->GetIncludeFlags(includeDirs, 0, - language, false); + std::string includeFlags = lg->GetIncludeFlags(includeDirs, 0, language); std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS"); printf("%s %s\n", includeFlags.c_str(), definitions.c_str()); @@ -903,8 +899,6 @@ void cmake::AddDefaultExtraGenerators() &cmExtraSublimeTextGenerator::New); this->AddExtraGenerator(cmExtraKateGenerator::GetActualName(), &cmExtraKateGenerator::New); - this->AddExtraGenerator(cmExtraQbsGenerator::GetActualName(), - &cmExtraQbsGenerator::New); #ifdef CMAKE_USE_ECLIPSE this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(), @@ -956,7 +950,7 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname) for (RegisteredGeneratorsVector::const_iterator i = this->Generators.begin(); i != this->Generators.end(); ++i) { - generator = (*i)->CreateGlobalGenerator(name); + generator = (*i)->CreateGlobalGenerator(name, this); if (generator) { break; @@ -965,7 +959,6 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname) if (generator) { - generator->SetCMakeInstance(this); generator->SetExternalMakefileProjectGenerator(extraGenerator); } else @@ -1050,8 +1043,6 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator *gg) { this->CCEnvironment = ""; } - // set the cmake instance just to be sure - gg->SetCMakeInstance(this); } int cmake::DoPreConfigureChecks() @@ -1304,12 +1295,12 @@ int cmake::ActualConfigure() = this->CreateGlobalGenerator(installedCompiler.c_str()); if(!gen) { - gen = new cmGlobalNMakeMakefileGenerator; + gen = new cmGlobalNMakeMakefileGenerator(this); } this->SetGlobalGenerator(gen); std::cout << "-- Building for: " << gen->GetName() << "\n"; #else - this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3); + this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this)); #endif } if(!this->GlobalGenerator) @@ -1446,20 +1437,6 @@ int cmake::ActualConfigure() cmState::PATH); } } - if(!this->State - ->GetInitializedCacheValue("CMAKE_USE_RELATIVE_PATHS")) - { - this->State->AddCacheEntry - ("CMAKE_USE_RELATIVE_PATHS", "OFF", - "If true, cmake will use relative paths in makefiles and projects.", - cmState::BOOL); - if (!this->State->GetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS", - "ADVANCED")) - { - this->State->SetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS", - "ADVANCED", "1"); - } - } if(cmSystemTools::GetFatalErrorOccured()) { @@ -1625,11 +1602,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) std::string message = "Build files have been written to: "; message += this->GetHomeOutputDirectory(); this->UpdateProgress(message.c_str(), -1); - if(ret) - { - return ret; - } - return ret; } @@ -1925,9 +1897,10 @@ int cmake::CheckBuildSystem() // Read the rerun check file and use it to decide whether to do the // global generate. cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cmGlobalGenerator gg(&cm); + cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator()); cmMakefile* mf = lg->GetMakefile(); if(!mf->ReadListFile(this->CheckBuildSystemArgument.c_str()) || cmSystemTools::GetErrorOccuredFlag()) @@ -1957,7 +1930,7 @@ int cmake::CheckBuildSystem() ggd(this->CreateGlobalGenerator(genName)); if(ggd.get()) { - cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); + cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->MakeLocalGenerator()); lgd->ClearDependencies(mf, verbose); } } @@ -2435,24 +2408,15 @@ static bool cmakeCheckStampList(const char* stampList) return true; } -//---------------------------------------------------------------------------- -void cmake::IssueMessage(cmake::MessageType t, std::string const& text, - cmListFileBacktrace const& bt) +bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg) { - cmListFileBacktrace backtrace = bt; - backtrace.MakeRelative(); - - std::ostringstream msg; - bool isError = false; // Construct the message header. if(t == cmake::FATAL_ERROR) { - isError = true; msg << "CMake Error"; } else if(t == cmake::INTERNAL_ERROR) { - isError = true; msg << "CMake Internal Error (please report a bug)"; } else if(t == cmake::LOG) @@ -2462,7 +2426,6 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, else if(t == cmake::DEPRECATION_ERROR) { msg << "CMake Deprecation Error"; - isError = true; } else if (t == cmake::DEPRECATION_WARNING) { @@ -2478,40 +2441,24 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, "CMAKE_SUPPRESS_DEVELOPER_WARNINGS"); if(suppress && cmSystemTools::IsOn(suppress)) { - return; + return false; } msg << " (dev)"; } } + return true; +} - // Add the immediate context. - cmListFileBacktrace::const_iterator i = backtrace.begin(); - if(i != backtrace.end()) - { - cmListFileContext const& lfc = *i; - msg << (lfc.Line? " at ": " in ") << lfc; - ++i; - } - - // Add the message text. - { - msg << ":\n"; - cmDocumentationFormatter formatter; - formatter.SetIndent(" "); - formatter.PrintFormatted(msg, text.c_str()); - } +void printMessageText(std::ostream& msg, std::string const& text) +{ + msg << ":\n"; + cmDocumentationFormatter formatter; + formatter.SetIndent(" "); + formatter.PrintFormatted(msg, text.c_str()); +} - // Add the rest of the context. - if(i != backtrace.end()) - { - msg << "Call Stack (most recent call first):\n"; - while(i != backtrace.end()) - { - cmListFileContext const& lfc = *i; - msg << " " << lfc << "\n"; - ++i; - } - } +void displayMessage(cmake::MessageType t, std::ostringstream& msg) +{ // Add a note about warning suppression. if(t == cmake::AUTHOR_WARNING) @@ -2540,7 +2487,9 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, #endif // Output the message. - if(isError) + if(t == cmake::FATAL_ERROR + || t == cmake::INTERNAL_ERROR + || t == cmake::DEPRECATION_ERROR) { cmSystemTools::SetErrorOccured(); cmSystemTools::Message(msg.str().c_str(), "Error"); @@ -2552,6 +2501,47 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, } //---------------------------------------------------------------------------- +void cmake::IssueMessage(cmake::MessageType t, std::string const& text, + cmListFileBacktrace const& bt) +{ + cmListFileBacktrace backtrace = bt; + + std::ostringstream msg; + if (!this->PrintMessagePreamble(t, msg)) + { + return; + } + + // Add the immediate context. + backtrace.PrintTitle(msg); + + printMessageText(msg, text); + + // Add the rest of the context. + backtrace.PrintCallStack(msg); + + displayMessage(t, msg); +} + +//---------------------------------------------------------------------------- +void cmake::IssueMessage(cmake::MessageType t, std::string const& text, + cmListFileContext const& lfc) +{ + std::ostringstream msg; + if (!this->PrintMessagePreamble(t, msg)) + { + return; + } + + // Add the immediate context. + msg << (lfc.Line ? " at " : " in ") << lfc; + + printMessageText(msg, text); + + displayMessage(t, msg); +} + +//---------------------------------------------------------------------------- std::vector<std::string> cmake::GetDebugConfigs() { std::vector<std::string> configs; @@ -2580,6 +2570,9 @@ int cmake::Build(const std::string& dir, const std::vector<std::string>& nativeOptions, bool clean) { + + this->SetHomeDirectory(""); + this->SetHomeOutputDirectory(""); if(!cmSystemTools::FileIsDirectory(dir)) { std::cerr << "Error: " << dir << " is not a directory\n"; diff --git a/Source/cmake.h b/Source/cmake.h index 0d1977e..f0f9411 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -30,7 +30,6 @@ class cmDocumentationSection; class cmPolicies; class cmTarget; class cmGeneratedFileStream; -class cmState; /** \brief Represents a cmake invocation. * @@ -223,9 +222,6 @@ class cmake ///! this is called by generators to update the progress void UpdateProgress(const char *msg, float prog); - ///! get the cmake policies instance - cmPolicies *GetPolicies() {return this->Policies;} - ///! Get the variable watch object cmVariableWatch* GetVariableWatch() { return this->VariableWatch; } @@ -302,7 +298,10 @@ class cmake /** Display a message to the user. */ void IssueMessage(cmake::MessageType t, std::string const& text, - cmListFileBacktrace const& backtrace = cmListFileBacktrace(NULL)); + cmListFileBacktrace const& backtrace = cmListFileBacktrace()); + void IssueMessage(cmake::MessageType t, std::string const& text, + cmListFileContext const& lfc); + ///! run the --build option int Build(const std::string& dir, const std::string& target, @@ -314,6 +313,10 @@ class cmake void WatchUnusedCli(const std::string& var); cmState* GetState() const { return this->State; } + void SetCurrentSnapshot(cmState::Snapshot snapshot) + { this->CurrentSnapshot = snapshot; } + cmState::Snapshot GetCurrentSnapshot() const + { return this->CurrentSnapshot; } protected: void RunCheckForUnusedVariables(); @@ -394,16 +397,19 @@ private: InstalledFilesMap InstalledFiles; cmState* State; + cmState::Snapshot CurrentSnapshot; void UpdateConversionPathTable(); // Print a list of valid generators to stderr. void PrintGeneratorList(); + + bool PrintMessagePreamble(cmake::MessageType t, std::ostream& msg); }; #define CMAKE_STANDARD_OPTIONS_TABLE \ {"-C <initial-cache>", "Pre-load a script to populate the cache."}, \ - {"-D <var>:<type>=<value>", "Create a cmake cache entry."}, \ + {"-D <var>[:<type>]=<value>", "Create a cmake cache entry."}, \ {"-U <globbing_expr>", "Remove matching entries from CMake cache."}, \ {"-G <generator-name>", "Specify a build system generator."},\ {"-T <toolset-name>", "Specify toolset name if supported by generator."}, \ diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index d82087f..cc30732 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -113,12 +113,7 @@ static cmMakefile* cmakemainGetMakefile(void *clientdata) cmGlobalGenerator* gg=cm->GetGlobalGenerator(); if (gg) { - cmLocalGenerator* lg=gg->GetCurrentLocalGenerator(); - if (lg) - { - cmMakefile* mf = lg->GetMakefile(); - return mf; - } + return gg->GetCurrentMakefile(); } } return 0; @@ -130,7 +125,7 @@ static std::string cmakemainGetStack(void *clientdata) cmMakefile* mf=cmakemainGetMakefile(clientdata); if (mf) { - msg = mf->GetListFileStack(); + msg = mf->FormatListFileStack(); if (!msg.empty()) { msg = "\n Called from: " + msg; @@ -214,6 +209,8 @@ int do_cmake(int ac, char const* const* av) { // Construct and print requested documentation. cmake hcm; + hcm.SetHomeDirectory(""); + hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); // the command line args are processed here so that you can do @@ -317,10 +314,14 @@ int do_cmake(int ac, char const* const* av) if (sysinfo) { cmake cm; + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); int ret = cm.GetSystemInformation(args); return ret; } cmake cm; + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); cmSystemTools::SetMessageCallback(cmakemainMessageCallback, (void *)&cm); cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm); cm.SetWorkingMode(workingMode); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 12bb8ee..3ea2186 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -211,6 +211,88 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) return 0; } + // run include what you use command and then run the compile + // command. This is an internal undocumented option and should + // only be used by CMake itself when running iwyu. + else if (args[1] == "__run_iwyu") + { + if (args.size() < 3) + { + std::cerr << "__run_iwyu Usage: -E __run_iwyu [--iwyu=/path/iwyu]" + " -- compile command\n"; + return 1; + } + bool doing_options = true; + std::vector<std::string> orig_cmd; + std::string iwyu; + for (std::string::size_type cc = 2; cc < args.size(); cc ++) + { + std::string const& arg = args[cc]; + if (arg == "--") + { + doing_options = false; + } + else if (doing_options && cmHasLiteralPrefix(arg, "--iwyu=")) + { + iwyu = arg.substr(7); + } + else if (doing_options) + { + std::cerr << "__run_iwyu given unknown argument: " << arg << "\n"; + return 1; + } + else + { + orig_cmd.push_back(arg); + } + } + if (iwyu.empty()) + { + std::cerr << "__run_iwyu missing --iwyu=\n"; + return 1; + } + if (orig_cmd.empty()) + { + std::cerr << "__run_iwyu missing compile command after --\n"; + return 1; + } + + // Construct the iwyu command line by taking what was given + // and adding all the arguments we give to the compiler. + std::vector<std::string> iwyu_cmd; + cmSystemTools::ExpandListArgument(iwyu, iwyu_cmd, true); + iwyu_cmd.insert(iwyu_cmd.end(), orig_cmd.begin()+1, orig_cmd.end()); + + // Run the iwyu command line. Capture its stderr and hide its stdout. + int ret = 0; + std::string stdErr; + if(!cmSystemTools::RunSingleCommand(iwyu_cmd, 0, &stdErr, &ret, + 0, cmSystemTools::OUTPUT_NONE)) + { + std::cerr << "Error running '" << iwyu_cmd[0] << "': " + << stdErr << "\n"; + return 1; + } + + // Warn if iwyu reported anything. + if(stdErr.find("should remove these lines:") != stdErr.npos + || stdErr.find("should add these lines:") != stdErr.npos) + { + std::cerr << "Warning: include-what-you-use reported diagnostics:\n" + << stdErr << "\n"; + } + + // Now run the real compiler command and return its result value. + if(!cmSystemTools::RunSingleCommand(orig_cmd, 0, &stdErr, &ret, 0, + cmSystemTools::OUTPUT_PASSTHROUGH)) + { + std::cerr << "Error running '" << orig_cmd[0] << "': " + << stdErr << "\n"; + return 1; + } + return ret; + } + // Echo string else if (args[1] == "echo" ) { @@ -646,7 +728,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen)) { cm.SetGlobalGenerator(ggd); - cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); + cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->MakeLocalGenerator()); lgd->GetMakefile()->SetCurrentSourceDirectory(startDir); lgd->GetMakefile()->SetCurrentBinaryDirectory(startOutDir); diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 0fc47b7..e784759 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -160,6 +160,8 @@ int main (int argc, char const* const* argv) if(doc.CheckOptions(argc, argv)) { cmake hcm; + hcm.SetHomeDirectory(""); + hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); // Construct and print requested documentation. diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 8069ee2..7eb678b 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -88,6 +88,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR) IF(POLICY CMP0025) CMAKE_POLICY(SET CMP0025 NEW) ENDIF() +IF(POLICY CMP0056) + CMAKE_POLICY(SET CMP0056 NEW) +ENDIF() #----------------------------------------------------------------------------- # If a namespace is not specified, use "kwsys" and enable testing. @@ -783,6 +786,15 @@ IF(KWSYS_USE_SystemInformation) SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1) ENDIF() + + IF(UNIX AND NOT CYGWIN) + KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG + "Checking whether CXX compiler has getloadavg" DIRECT) + IF(KWSYS_CXX_HAS_GETLOADAVG) + SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY + COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1) + ENDIF() + ENDIF() ENDIF() #----------------------------------------------------------------------------- diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index b0434f4..6e81b0b 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -81,6 +81,11 @@ typedef int siginfo_t; # include <errno.h> // extern int errno; #endif +#if defined (__CYGWIN__) && !defined(_WIN32) +# include <windows.h> +# undef _WIN32 +#endif + #ifdef __FreeBSD__ # include <sys/sysctl.h> # include <fenv.h> @@ -366,6 +371,8 @@ public: const char *procLimitEnvVarName); LongLong GetProcMemoryUsed(); + double GetLoadAverage(); + // enable/disable stack trace signal handler. static void SetStackTraceOnError(int enable); @@ -820,6 +827,11 @@ SystemInformation::LongLong SystemInformation::GetProcMemoryUsed() return this->Implementation->GetProcMemoryUsed(); } +double SystemInformation::GetLoadAverage() +{ + return this->Implementation->GetLoadAverage(); +} + SystemInformation::LongLong SystemInformation::GetProcessId() { return this->Implementation->GetProcessId(); @@ -1490,6 +1502,60 @@ void SymbolProperties::Initialize(void *address) } #endif // don't define this class if we're not using it +// -------------------------------------------------------------------------- +#if defined(_WIN32) || defined(__CYGWIN__) +# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes +#endif +#if defined(_MSC_VER) && _MSC_VER < 1310 +# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes +#endif +#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) +double calculateCPULoad(unsigned __int64 idleTicks, + unsigned __int64 totalTicks) +{ + static double previousLoad = -0.0; + static unsigned __int64 previousIdleTicks = 0; + static unsigned __int64 previousTotalTicks = 0; + + unsigned __int64 const idleTicksSinceLastTime = + idleTicks - previousIdleTicks; + unsigned __int64 const totalTicksSinceLastTime = + totalTicks - previousTotalTicks; + + double load; + if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0) + { + // No new information. Use previous result. + load = previousLoad; + } + else + { + // Calculate load since last time. + load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime; + + // Smooth if possible. + if (previousLoad > 0) + { + load = 0.25 * load + 0.75 * previousLoad; + } + } + + previousLoad = load; + previousIdleTicks = idleTicks; + previousTotalTicks = totalTicks; + + return load; +} + +unsigned __int64 fileTimeToUInt64(FILETIME const& ft) +{ + LARGE_INTEGER out; + out.HighPart = ft.dwHighDateTime; + out.LowPart = ft.dwLowDateTime; + return out.QuadPart; +} +#endif + } // anonymous namespace @@ -3612,6 +3678,38 @@ SystemInformationImplementation::GetProcMemoryUsed() #endif } +double SystemInformationImplementation::GetLoadAverage() +{ +#if defined(KWSYS_CXX_HAS_GETLOADAVG) + double loadavg[3] = { 0.0, 0.0, 0.0 }; + if (getloadavg(loadavg, 3) > 0) + { + return loadavg[0]; + } + return -0.0; +#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) + // Old windows.h headers do not provide GetSystemTimes. + typedef BOOL (WINAPI *GetSystemTimesType)(LPFILETIME, LPFILETIME, + LPFILETIME); + static GetSystemTimesType pGetSystemTimes = + (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"), + "GetSystemTimes"); + FILETIME idleTime, kernelTime, userTime; + if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime)) + { + unsigned __int64 const idleTicks = + fileTimeToUInt64(idleTime); + unsigned __int64 const totalTicks = + fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime); + return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU(); + } + return -0.0; +#else + // Not implemented on this platform. + return -0.0; +#endif +} + /** Get the process id of the running process. */ diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index a9fd05d..4acdc4f 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -130,6 +130,10 @@ public: // Get system RAM used by this process id in units of KiB. LongLong GetProcMemoryUsed(); + // Return the load average of the machine or -0.0 if it cannot + // be determined. + double GetLoadAverage(); + // enable/disable stack trace signal handler. In order to // produce an informative stack trace the application should // be dynamically linked and compiled with debug symbols. diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 6c4a7a6..c834e34 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -2674,27 +2674,43 @@ kwsys_stl::string SystemTools::GetLastSystemError() bool SystemTools::RemoveFile(const kwsys_stl::string& source) { #ifdef _WIN32 + kwsys_stl::wstring const& ws = + SystemTools::ConvertToWindowsExtendedPath(source); + if (DeleteFileW(ws.c_str())) + { + return true; + } + DWORD err = GetLastError(); + if (err == ERROR_FILE_NOT_FOUND || + err == ERROR_PATH_NOT_FOUND) + { + return true; + } + if (err != ERROR_ACCESS_DENIED) + { + return false; + } + /* The file may be read-only. Try adding write permission. */ mode_t mode; - if ( !SystemTools::GetPermissions(source, mode) ) + if (!SystemTools::GetPermissions(source, mode) || + !SystemTools::SetPermissions(source, S_IWRITE)) { + SetLastError(err); return false; } - /* Win32 unlink is stupid --- it fails if the file is read-only */ - SystemTools::SetPermissions(source, S_IWRITE); -#endif -#ifdef _WIN32 - bool res = - _wunlink(SystemTools::ConvertToWindowsExtendedPath(source).c_str()) == 0; -#else - bool res = unlink(source.c_str()) != 0 ? false : true; -#endif -#ifdef _WIN32 - if ( !res ) + if (DeleteFileW(ws.c_str()) || + GetLastError() == ERROR_FILE_NOT_FOUND || + GetLastError() == ERROR_PATH_NOT_FOUND) { - SystemTools::SetPermissions(source, mode); + return true; } + /* Try to restore the original permissions. */ + SystemTools::SetPermissions(source, mode); + SetLastError(err); + return false; +#else + return unlink(source.c_str()) == 0 || errno == ENOENT; #endif - return res; } bool SystemTools::RemoveADirectory(const kwsys_stl::string& source) diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx index 82620da..1596fe4 100644 --- a/Source/kwsys/kwsysPlatformTestsCXX.cxx +++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx @@ -452,6 +452,19 @@ int main() } #endif +#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG +// Match feature definitions from SystemInformation.cxx +#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif +#include <stdlib.h> +int main() +{ + double loadavg[3] = { 0.0, 0.0, 0.0 }; + return getloadavg(loadavg, 3); +} +#endif + #ifdef TEST_KWSYS_CXX_HAS_RLIMIT64 # if defined(KWSYS_HAS_LFS) # define _LARGEFILE_SOURCE diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx index 53d51ac..fc8ea55 100644 --- a/Source/kwsys/testSystemInformation.cxx +++ b/Source/kwsys/testSystemInformation.cxx @@ -87,6 +87,7 @@ int testSystemInformation(int, char*[]) printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB"); printMethod3(info, GetHostMemoryUsed(), "KiB"); printMethod3(info, GetProcMemoryUsed(), "KiB"); + printMethod(info, GetLoadAverage); for (long int i = 0; i <= 31; i++) { diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index 42b6249..15d8eab 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -156,6 +156,24 @@ static bool CheckFileOperations() res = false; } + kwsys_stl::string const testFileMissing(testNewDir + "/testMissingFile.txt"); + if (!kwsys::SystemTools::RemoveFile(testFileMissing)) + { + std::string const& msg = kwsys::SystemTools::GetLastSystemError(); + kwsys_ios::cerr << + "RemoveFile(\"" << testFileMissing << "\") failed: " << msg << "\n"; + res = false; + } + + kwsys_stl::string const testFileMissingDir(testNewDir + "/missing/file.txt"); + if (!kwsys::SystemTools::RemoveFile(testFileMissingDir)) + { + std::string const& msg = kwsys::SystemTools::GetLastSystemError(); + kwsys_ios::cerr << + "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg << "\n"; + res = false; + } + kwsys::SystemTools::Touch(testNewFile.c_str(), true); if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) { |