diff options
Diffstat (limited to 'Source')
85 files changed, 1615 insertions, 813 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 49cbda7..dc73cec 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -366,6 +366,7 @@ SET(CTEST_SRCS cmCTest.cxx CTest/cmCTestConfigureHandler.cxx CTest/cmCTestCoverageCommand.cxx CTest/cmCTestCoverageHandler.cxx + CTest/cmParsePHPCoverage.cxx CTest/cmCTestEmptyBinaryDirectoryCommand.cxx CTest/cmCTestGenericHandler.cxx CTest/cmCTestHandlerCommand.cxx @@ -502,4 +503,3 @@ IF(APPLE) ENDIF(APPLE) INSTALL_FILES(${CMAKE_DATA_DIR}/include cmCPluginAPI.h) - diff --git a/Source/CMakeVersionSource.cmake b/Source/CMakeVersionSource.cmake new file mode 100644 index 0000000..05e265c --- /dev/null +++ b/Source/CMakeVersionSource.cmake @@ -0,0 +1,37 @@ +# Try to identify the current development source version. +set(CMake_VERSION_SOURCE "") +if(EXISTS ${CMake_SOURCE_DIR}/.git/HEAD) + find_program(GIT_EXECUTABLE NAMES git git.cmd) + mark_as_advanced(GIT_EXECUTABLE) + if(GIT_EXECUTABLE) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD + OUTPUT_VARIABLE head + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMake_SOURCE_DIR} + ) + if(head) + set(CMake_VERSION_SOURCE "g${head}") + execute_process( + COMMAND ${GIT_EXECUTABLE} update-index -q --refresh + WORKING_DIRECTORY ${CMake_SOURCE_DIR} + ) + execute_process( + COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- + OUTPUT_VARIABLE dirty + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMake_SOURCE_DIR} + ) + if(dirty) + set(CMake_VERSION_SOURCE "${CMake_VERSION_SOURCE}-dirty") + endif() + endif() + endif() +elseif(EXISTS ${CMake_SOURCE_DIR}/CVS/Repository) + file(READ ${CMake_SOURCE_DIR}/CVS/Repository repo) + set(branch "") + if("${repo}" MATCHES "\\.git/") + string(REGEX REPLACE ".*\\.git/([^\r\n]*).*" "-\\1" branch "${repo}") + endif() + set(CMake_VERSION_SOURCE "cvs${branch}") +endif() diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 6224b40..4a4b428 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -789,7 +789,7 @@ int cmCPackGenerator::DoPackage() cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove toplevel directory: " << toplevelDirectory << std::endl); - if ( !cmSystemTools::RemoveADirectory(toplevelDirectory) ) + if ( !cmSystemTools::RepeatedRemoveDirectory(toplevelDirectory) ) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem removing toplevel directory: " @@ -1084,7 +1084,7 @@ int cmCPackGenerator::CleanTemporaryDirectory() cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Clean temporary : " << tempInstallDirectory << std::endl); - if(!cmsys::SystemTools::RemoveADirectory(tempInstallDirectory)) + if(!cmSystemTools::RepeatedRemoveDirectory(tempInstallDirectory)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem removing temporary directory: " << diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index 55b8d5b..36302df 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -292,7 +292,7 @@ private: if(this->EmailRegex.find(this->Rev.Author)) { this->Rev.Author = this->EmailRegex.match(1); - //email = email_regex.match(2); + this->Rev.EMail = this->EmailRegex.match(2); } } else if(strcmp(name, "timestamp") == 0 && !this->CData.empty()) diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index a125459..bc02fbc 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -551,6 +551,7 @@ class cmCTestBuildHandler::FragmentCompare { public: FragmentCompare(cmFileTimeComparison* ftc): FTC(ftc) {} + FragmentCompare(): FTC(0) {} bool operator()(std::string const& l, std::string const& r) { // Order files by modification time. Use lexicographic order diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 1076886..3235bfd 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -10,6 +10,7 @@ See the License for more information. ============================================================================*/ #include "cmCTestCoverageHandler.h" +#include "cmParsePHPCoverage.h" #include "cmCTest.h" #include "cmake.h" #include "cmMakefile.h" @@ -126,20 +127,6 @@ private: //---------------------------------------------------------------------- -//********************************************************************** -class cmCTestCoverageHandlerContainer -{ -public: - int Error; - std::string SourceDir; - std::string BinaryDir; - typedef std::vector<int> SingleFileCoverageVector; - typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap; - TotalCoverageMap TotalCoverage; - std::ostream* OFS; -}; -//********************************************************************** -//---------------------------------------------------------------------- //---------------------------------------------------------------------- cmCTestCoverageHandler::cmCTestCoverageHandler() @@ -380,7 +367,6 @@ int cmCTestCoverageHandler::ProcessHandler() cmsys::RegularExpression(rexIt->c_str())); } - if(this->HandleBullseyeCoverage(&cont)) { return cont.Error; @@ -396,8 +382,14 @@ int cmCTestCoverageHandler::ProcessHandler() { return error; } + file_count += this->HandlePHPCoverage(&cont); + if ( file_count < 0 ) + { + return error; + } error = cont.Error; + std::set<std::string> uncovered = this->FindUncoveredFiles(&cont); if ( file_count == 0 ) { @@ -524,7 +516,7 @@ int cmCTestCoverageHandler::ProcessHandler() { cmOStringStream ostr; ostr << "Problem reading source file: " << fullFileName.c_str() - << " line:" << cc; + << " line:" << cc << " out total: " << fcov.size()-1; errorsWhileAccumulating.push_back(ostr.str()); error ++; break; @@ -577,13 +569,58 @@ int cmCTestCoverageHandler::ProcessHandler() this->WriteXMLLabels(covSumFile, shortFileName); covSumFile << "\t</File>" << std::endl; } + + //Handle all the files in the extra coverage globs that have no cov data + for(std::set<std::string>::iterator i = uncovered.begin(); + i != uncovered.end(); ++i) + { + 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; + + std::ifstream ifs(fullPath.c_str()); + if (!ifs) + { + cmOStringStream ostr; + ostr << "Cannot open source file: " << fullPath.c_str(); + errorsWhileAccumulating.push_back(ostr.str()); + error ++; + continue; + } + int untested = 0; + std::string line; + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Actually perfoming coverage for: " << i->c_str() << std::endl); + while (cmSystemTools::GetLineFromStream(ifs, line)) + { + covLogFile << "\t\t<Line Number=\"" << untested << "\" Count=\"0\">" + << cmXMLSafe(line) << "</Line>" << std::endl; + untested ++; + } + covLogFile << "\t\t</Report>\n\t</File>" << std::endl; + + 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; + } + this->EndCoverageLogFile(covLogFile, logFileCount); if ( errorsWhileAccumulating.size() > 0 ) { cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl); cmCTestLog(this->CTest, ERROR_MESSAGE, - "Error(s) while acumulating results:" << std::endl); + "Error(s) while accumulating results:" << std::endl); std::vector<std::string>::iterator erIt; for ( erIt = errorsWhileAccumulating.begin(); erIt != errorsWhileAccumulating.end(); @@ -654,6 +691,8 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf) " Add coverage exclude regular expressions." << std::endl); this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE", this->CustomCoverageExclude); + this->CTest->PopulateCustomVector(mf, "CTEST_EXTRA_COVERAGE_GLOB", + this->ExtraCoverageGlobs); std::vector<cmStdString>::iterator it; for ( it = this->CustomCoverageExclude.begin(); it != this->CustomCoverageExclude.end(); @@ -662,6 +701,12 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf) cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: " << it->c_str() << std::endl); } + for ( it = this->ExtraCoverageGlobs.begin(); + it != this->ExtraCoverageGlobs.end(); ++it) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage glob: " + << it->c_str() << std::endl); + } } //---------------------------------------------------------------------- @@ -695,6 +740,18 @@ bool IsFileInDir(const std::string &infile, const std::string &indir) } //---------------------------------------------------------------------- +int cmCTestCoverageHandler::HandlePHPCoverage( + cmCTestCoverageHandlerContainer* cont) +{ + cmParsePHPCoverage cov(*cont, this->CTest); + std::string coverageDir = this->CTest->GetBinaryDir() + "/xdebugCoverage"; + if(cmSystemTools::FileIsDirectory(coverageDir.c_str())) + { + cov.ReadPHPCoverageDirectory(coverageDir.c_str()); + } + return static_cast<int>(cont->TotalCoverage.size()); +} +//---------------------------------------------------------------------- int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestCoverageHandlerContainer* cont) { @@ -1703,6 +1760,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( << "</ElapsedMinutes>" << "</Coverage>" << std::endl; this->CTest->EndXML(covSumFile); + // Now create the coverage information for each file return this->RunBullseyeCoverageBranch(cont, coveredFileNames, @@ -1961,3 +2019,39 @@ bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source) } return true; } + +//---------------------------------------------------------------------- +std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles( + cmCTestCoverageHandlerContainer* cont) +{ + std::set<std::string> extraMatches; + + for(std::vector<cmStdString>::iterator i = this->ExtraCoverageGlobs.begin(); + i != this->ExtraCoverageGlobs.end(); ++i) + { + cmsys::Glob gl; + gl.RecurseOn(); + gl.RecurseThroughSymlinksOff(); + std::string glob = cont->SourceDir + "/" + *i; + gl.FindFiles(glob); + std::vector<std::string> files = gl.GetFiles(); + for(std::vector<std::string>::iterator f = files.begin(); + f != files.end(); ++f) + { + extraMatches.insert(this->CTest->GetShortPathToFile( + f->c_str())); + } + } + + if(extraMatches.size()) + { + for(cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator i = + cont->TotalCoverage.begin(); i != cont->TotalCoverage.end(); ++i) + { + std::string shortPath = this->CTest->GetShortPathToFile( + i->first.c_str()); + extraMatches.erase(shortPath); + } + } + return extraMatches; +} diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index b3e4db6..d3e8503 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -20,8 +20,17 @@ #include <cmsys/RegularExpression.hxx> class cmGeneratedFileStream; -class cmCTestCoverageHandlerContainer; - +class cmCTestCoverageHandlerContainer +{ +public: + int Error; + std::string SourceDir; + std::string BinaryDir; + typedef std::vector<int> SingleFileCoverageVector; + typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap; + TotalCoverageMap TotalCoverage; + std::ostream* OFS; +}; /** \class cmCTestCoverageHandler * \brief A class that handles coverage computaiton for ctest * @@ -59,6 +68,9 @@ private: int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont); void FindGCovFiles(std::vector<std::string>& files); + //! Handle coverage using xdebug php coverage + int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont); + //! Handle coverage using Bullseye int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont); int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont); @@ -66,6 +78,7 @@ private: std::set<cmStdString>& coveredFileNames, std::vector<std::string>& files, std::vector<std::string>& filesFullPath); + int RunBullseyeCommand( cmCTestCoverageHandlerContainer* cont, const char* cmd, @@ -91,52 +104,12 @@ private: std::string FindFile(cmCTestCoverageHandlerContainer* cont, std::string fileName); - struct cmCTestCoverage - { - cmCTestCoverage() - { - this->AbsolutePath = ""; - this->FullPath = ""; - this->Covered = false; - this->Tested = 0; - this->UnTested = 0; - this->Lines.clear(); - this->Show = false; - } - cmCTestCoverage(const cmCTestCoverage& rhs) : - AbsolutePath(rhs.AbsolutePath), - FullPath(rhs.FullPath), - Covered(rhs.Covered), - Tested(rhs.Tested), - UnTested(rhs.UnTested), - Lines(rhs.Lines), - Show(rhs.Show) - { - } - cmCTestCoverage& operator=(const cmCTestCoverage& rhs) - { - this->AbsolutePath = rhs.AbsolutePath; - this->FullPath = rhs.FullPath; - this->Covered = rhs.Covered; - this->Tested = rhs.Tested; - this->UnTested = rhs.UnTested; - this->Lines = rhs.Lines; - this->Show = rhs.Show; - return *this; - } - std::string AbsolutePath; - std::string FullPath; - bool Covered; - int Tested; - int UnTested; - std::vector<int> Lines; - bool Show; - }; - + std::set<std::string> FindUncoveredFiles( + cmCTestCoverageHandlerContainer* cont); std::vector<cmStdString> CustomCoverageExclude; std::vector<cmsys::RegularExpression> CustomCoverageExcludeRegex; + std::vector<cmStdString> ExtraCoverageGlobs; - typedef std::map<std::string, cmCTestCoverage> CoverageMap; // Map from source file to label ids. class LabelSet: public std::set<int> {}; diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 6d5bf65..f5ba361 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -87,9 +87,11 @@ void cmCTestGIT::NoteNewRevision() //---------------------------------------------------------------------------- bool cmCTestGIT::UpdateImpl() { + const char* git = this->CommandLineTool.c_str(); + // Use "git pull" to update the working tree. std::vector<char const*> git_pull; - git_pull.push_back(this->CommandLineTool.c_str()); + git_pull.push_back(git); git_pull.push_back("pull"); // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY) @@ -112,7 +114,14 @@ bool cmCTestGIT::UpdateImpl() OutputLogger out(this->Log, "pull-out> "); OutputLogger err(this->Log, "pull-err> "); - return this->RunUpdateCommand(&git_pull[0], &out, &err); + if(this->RunUpdateCommand(&git_pull[0], &out, &err)) + { + char const* git_submodule[] = {git, "submodule", "update", 0}; + OutputLogger out2(this->Log, "submodule-out> "); + OutputLogger err2(this->Log, "submodule-err> "); + return this->RunChild(git_submodule, &out2, &err2); + } + return false; } //---------------------------------------------------------------------------- @@ -338,6 +347,7 @@ private: Person author; this->ParsePerson(this->Line.c_str()+7, author); this->Rev.Author = author.Name; + this->Rev.EMail = author.EMail; // Convert the time to a human-readable format that is also easy // to machine-parse: "CCYY-MM-DD hh:mm:ss". diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h index 2561ed4..0b6ad2e 100644 --- a/Source/CTest/cmCTestGIT.h +++ b/Source/CTest/cmCTestGIT.h @@ -35,6 +35,7 @@ private: void LoadRevisions(); void LoadModifications(); +public: // needed by older Sun compilers // Parsing helper classes. class OneLineParser; class DiffParser; diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx index b263677..86a7617 100644 --- a/Source/CTest/cmCTestHG.cxx +++ b/Source/CTest/cmCTestHG.cxx @@ -220,7 +220,7 @@ private: } else if ( strcmp(name, "email") == 0 && !this->CData.empty()) { - // this->Rev.Email.assign(&this->CData[0], this->CData.size()); + this->Rev.EMail.assign(&this->CData[0], this->CData.size()); } else if(strcmp(name, "date") == 0 && !this->CData.empty()) { diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index c1ca9ea..8a69780 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -453,15 +453,24 @@ void cmCTestMultiProcessHandler::CreateTestCostList() for(TestMap::iterator i = this->Tests.begin(); i != this->Tests.end(); ++i) { - std::string name = this->Properties[i->first]->Name; - if(std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(), - name) != this->LastTestsFailed.end()) + //We only want to schedule them by cost in a parallel situation + if(this->ParallelLevel > 1) { - this->TestCosts[FLT_MAX].insert(i->first); + std::string name = this->Properties[i->first]->Name; + if(std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(), + name) != this->LastTestsFailed.end()) + { + this->TestCosts[FLT_MAX].insert(i->first); + } + else + { + this->TestCosts[this->Properties[i->first]->Cost].insert(i->first); + } } - else + else //we ignore their cost { - this->TestCosts[this->Properties[i->first]->Cost].insert(i->first); + this->TestCosts[this->Tests.size() + - this->Properties[i->first]->Index].insert(i->first); } } } diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 659cb73..4c9675b 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -14,6 +14,7 @@ #include "cmCTestMemCheckHandler.h" #include "cmCTest.h" #include "cmSystemTools.h" +#include "cm_curl.h" #include <cm_zlib.h> #include <cmsys/Base64.h> @@ -22,7 +23,6 @@ cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler) { this->CTest = handler->CTest; this->TestHandler = handler; - this->ModifyEnv = false; this->TestProcess = 0; this->TestResult.ExecutionTime =0; this->TestResult.ReturnValue = 0; @@ -138,11 +138,6 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) this->CompressOutput(); } - //restore the old environment - if (this->ModifyEnv) - { - cmSystemTools::RestoreEnv(this->OrigEnv); - } this->WriteLogOutputTop(completed, total); std::string reason; bool passed = true; @@ -441,7 +436,7 @@ bool cmCTestRunTest::StartTest(size_t total) } this->StartTime = this->CTest->CurrentTime(); - return this->CreateProcess(this->TestProperties->Timeout, + return this->ForkProcess(this->ResolveTimeout(), &this->TestProperties->Environment); } @@ -518,7 +513,71 @@ void cmCTestRunTest::DartProcessing() } //---------------------------------------------------------------------- -bool cmCTestRunTest::CreateProcess(double testTimeOut, +double cmCTestRunTest::ResolveTimeout() +{ + double timeout = this->TestProperties->Timeout; + + if(this->CTest->GetStopTime() == "") + { + return timeout; + } + struct tm* lctime; + time_t current_time = time(0); + lctime = gmtime(¤t_time); + int gm_hour = lctime->tm_hour; + time_t gm_time = mktime(lctime); + lctime = localtime(¤t_time); + int local_hour = lctime->tm_hour; + + int tzone_offset = local_hour - gm_hour; + if(gm_time > current_time && gm_hour < local_hour) + { + // this means gm_time is on the next day + tzone_offset -= 24; + } + else if(gm_time < current_time && gm_hour > local_hour) + { + // this means gm_time is on the previous day + tzone_offset += 24; + } + + tzone_offset *= 100; + char buf[1024]; + // add todays year day and month to the time in str because + // curl_getdate no longer assumes the day is today + sprintf(buf, "%d%02d%02d %s %+05i", + lctime->tm_year + 1900, + lctime->tm_mon + 1, + lctime->tm_mday, + this->CTest->GetStopTime().c_str(), + tzone_offset); + + time_t stop_time = curl_getdate(buf, ¤t_time); + if(stop_time == -1) + { + return timeout; + } + + //the stop time refers to the next day + if(this->CTest->NextDayStopTime) + { + stop_time += 24*60*60; + } + int stop_timeout = (stop_time - current_time) % (24*60*60); + this->CTest->LastStopTimeout = stop_timeout; + + if(stop_timeout <= 0 || stop_timeout > this->CTest->LastStopTimeout) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "The stop time has been passed. " + "Exiting ctest." << std::endl); + exit(-1); + } + return timeout == 0 ? stop_timeout : + (timeout < stop_timeout ? timeout : stop_timeout); +} + +//---------------------------------------------------------------------- +bool cmCTestRunTest::ForkProcess(double testTimeOut, std::vector<std::string>* environment) { this->TestProcess = new cmProcess; @@ -528,9 +587,6 @@ bool cmCTestRunTest::CreateProcess(double testTimeOut, this->TestProcess->SetCommand(this->ActualCommand.c_str()); this->TestProcess->SetCommandArguments(this->Arguments); - std::vector<std::string> origEnv; - this->ModifyEnv = (environment && environment->size()>0); - // determine how much time we have double timeout = this->CTest->GetRemainingTimeAllowed() - 120; if (this->CTest->GetTimeOut() > 0 && this->CTest->GetTimeOut() < timeout) @@ -553,9 +609,13 @@ bool cmCTestRunTest::CreateProcess(double testTimeOut, this->TestProcess->SetTimeout(timeout); - if (this->ModifyEnv) +#ifdef CMAKE_BUILD_WITH_CMAKE + cmSystemTools::SaveRestoreEnvironment sre; +#endif + + if (environment && environment->size()>0) { - this->OrigEnv = cmSystemTools::AppendEnv(environment); + cmSystemTools::AppendEnv(environment); } return this->TestProcess->StartProcess(); diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 1e4c1cc..d7d3a2f 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -59,7 +59,9 @@ public: private: void DartProcessing(); void ExeNotFound(std::string exe); - bool CreateProcess(double testTimeOut, + // Figures out a final timeout which is min(STOP_TIME, NOW+TIMEOUT) + double ResolveTimeout(); + bool ForkProcess(double testTimeOut, std::vector<std::string>* environment); void WriteLogOutputTop(size_t completed, size_t total); //Run post processing of the process output for MemCheck @@ -75,14 +77,9 @@ private: //if this option is set to false.) //bool OptimizeForCTest; - //flag for whether the env was modified for this run - bool ModifyEnv; - bool UsePrefixCommand; std::string PrefixCommand; - //stores the original environment if we are modifying it - std::vector<std::string> OrigEnv; std::string ProcessOutput; std::string CompressedOutput; double CompressionRatio; diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index b0adf22..5aee035 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -25,6 +25,7 @@ cmCTestTestCommand::cmCTestTestCommand() this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL"; this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL"; this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM"; + this->Arguments[ctt_STOP_TIME] = "STOP_TIME"; this->Arguments[ctt_LAST] = 0; this->Last = ctt_LAST; } @@ -98,6 +99,10 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() handler->SetOption("ScheduleRandom", this->Values[ctt_SCHEDULE_RANDOM]); } + if(this->Values[ctt_STOP_TIME]) + { + this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]); + } return handler; } diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index 12314df..c6fd631 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -62,7 +62,8 @@ public: " [EXCLUDE_LABEL exclude regex] \n" " [INCLUDE_LABEL label regex] \n" " [PARALLEL_LEVEL level] \n" - " [SCHEDULE_RANDOM on]) \n" + " [SCHEDULE_RANDOM on] \n" + " [STOP_TIME time of day]) \n" "Tests the given build directory and stores results in Test.xml. The " "second argument is a variable that will hold value. Optionally, " "you can specify the starting test number START, the ending test number " @@ -73,7 +74,8 @@ public: "property LABEL. PARALLEL_LEVEL should be set to a positive number " "representing the number of tests to be run in parallel. " "SCHEDULE_RANDOM will launch tests in a random order, and is " - "typically used to detect implicit test dependencies." + "typically used to detect implicit test dependencies. STOP_TIME is the " + "time of day at which the tests should all stop running." "\n" CTEST_COMMAND_APPEND_OPTION_DOCS; } @@ -96,6 +98,7 @@ protected: ctt_INCLUDE_LABEL, ctt_PARALLEL_LEVEL, ctt_SCHEDULE_RANDOM, + ctt_STOP_TIME, ctt_LAST }; }; diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index f87b37c..9eae3f3 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -306,6 +306,7 @@ int cmCTestUpdateHandler::ProcessHandler() } if(!updated) { + os << "Update command failed:\n" << vc->GetUpdateCommandLine(); cmCTestLog(this->CTest, ERROR_MESSAGE, " Update command failed: " << vc->GetUpdateCommandLine() << "\n"); } diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index 35f567a..f9ad79a 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -227,6 +227,7 @@ void cmCTestVC::WriteXMLEntry(std::ostream& xml, << "\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<Log>" << cmXMLSafe(rev.Log) << "</Log>\n" << "\t\t\t<Revision>" << cmXMLSafe(rev.Rev) << "</Revision>\n" << "\t\t\t<PriorRevision>" << cmXMLSafe(prior) << "</PriorRevision>\n" diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h index e6ea76d..d36bc8f 100644 --- a/Source/CTest/cmCTestVC.h +++ b/Source/CTest/cmCTestVC.h @@ -73,6 +73,7 @@ protected: std::string Rev; std::string Date; std::string Author; + std::string EMail; std::string Log; }; diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx new file mode 100644 index 0000000..32c1ec1 --- /dev/null +++ b/Source/CTest/cmParsePHPCoverage.cxx @@ -0,0 +1,252 @@ +#include "cmStandardIncludes.h" +#include "cmSystemTools.h" +#include "cmParsePHPCoverage.h" +#include <cmsys/Directory.hxx> + +/* + To setup coverage for php. + + - edit php.ini to add auto prepend and append php files from phpunit + auto_prepend_file = + auto_append_file = + - run the tests + - run this program on all the files in c:/tmp + +*/ + +cmParsePHPCoverage::cmParsePHPCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest) + :Coverage(cont), CTest(ctest) +{ +} + +bool cmParsePHPCoverage::ReadUntil(std::ifstream& in, char until) +{ + char c = 0; + while(in.get(c) && c != until) + { + } + if(c != until) + { + return false; + } + return true; +} +bool cmParsePHPCoverage::ReadCoverageArray(std::ifstream& in, + cmStdString const& fileName) +{ + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& coverageVector + = this->Coverage.TotalCoverage[fileName]; + + char c; + char buf[4]; + in.read(buf, 3); + buf[3] = 0; + if(strcmp(buf, ";a:") != 0) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read start of coverage array, found : " + << buf << "\n"); + return false; + } + int size = 0; + if(!this->ReadInt(in, size)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read size "); + return false; + } + if(!in.get(c) && c == '{') + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read open {\n"); + return false; + } + for(int i =0; i < size; i++) + { + this->ReadUntil(in, ':'); + int line = 0; + this->ReadInt(in, line); + // ok xdebug may have a bug here + // it seems to be 1 based but often times + // seems to have a 0'th line. + line--; + if(line < 0) + { + line = 0; + } + this->ReadUntil(in, ':'); + int value = 0; + this->ReadInt(in, value); + // make sure the vector is the right size and is + // initialized with -1 for each line + while(coverageVector.size() <= static_cast<size_t>(line) ) + { + coverageVector.push_back(-1); + } + // if value is less than 0, set it to zero + // TODO figure out the difference between + // -1 and -2 in xdebug coverage?? For now + // assume less than 0 is just not covered + // CDash expects -1 for non executable code (like comments) + // and 0 for uncovered code, and a positive value + // for number of times a line was executed + if(value < 0) + { + value = 0; + } + // if unset then set it to value + if(coverageVector[line] == -1) + { + coverageVector[line] = value; + } + // otherwise increment by value + else + { + coverageVector[line] += value; + } + } + return true; +} + +bool cmParsePHPCoverage::ReadInt(std::ifstream& in, int& v) +{ + std::string s; + char c = 0; + while(in.get(c) && c != ':' && c != ';') + { + s += c; + } + v = atoi(s.c_str()); + return true; +} + +bool cmParsePHPCoverage::ReadArraySize(std::ifstream& in, int& size) +{ + char c = 0; + in.get(c); + if(c != 'a') + { + return false; + } + if(in.get(c) && c == ':') + { + if(this->ReadInt(in, size)) + { + return true; + } + } + return false; +} + +bool cmParsePHPCoverage::ReadFileInformation(std::ifstream& in) +{ + char buf[4]; + in.read(buf, 2); + buf[2] = 0; + if(strcmp(buf, "s:") != 0) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read start of file info found: [" << buf << "]\n"); + return false; + } + char c; + int size = 0; + if(this->ReadInt(in, size)) + { + size++; // add one for null termination + char* s = new char[size+1]; + // read open quote + if(in.get(c) && c != '"') + { + return false; + } + // read the string data + in.read(s, size-1); + s[size-1] = 0; + cmStdString fileName = s; + delete [] s; + // read close quote + if(in.get(c) && c != '"') + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read close quote\n" + << "read [" << c << "]\n"); + return false; + } + if(!this->ReadCoverageArray(in, fileName) ) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read coverage array for file: " + << fileName << "\n"); + return false; + } + return true; + } + return false; +} + + +bool cmParsePHPCoverage::ReadPHPData(const char* file) +{ + std::ifstream in(file); + if(!in) + { + return false; + } + int size = 0; + this->ReadArraySize(in, size); + char c = 0; + in.get(c); + if(c != '{') + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read open array\n"); + return false; + } + for(int i =0; i < size; i++) + { + if(!this->ReadFileInformation(in)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Failed to read file #" << i << "\n"); + return false; + } + in.get(c); + if(c != '}') + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "failed to read close array\n"); + return false; + } + } + return true; +} + +bool cmParsePHPCoverage::ReadPHPCoverageDirectory(const char* d) +{ + cmsys::Directory dir; + if(!dir.Load(d)) + { + return false; + } + size_t numf; + unsigned int i; + numf = dir.GetNumberOfFiles(); + for (i = 0; i < numf; i++) + { + std::string file = dir.GetFile(i); + if(file != "." && file != ".." + && !cmSystemTools::FileIsDirectory(file.c_str())) + { + std::string path = d; + path += "/"; + path += file; + if(!this->ReadPHPData(path.c_str())) + { + return false; + } + } + } + return true; +} diff --git a/Source/CTest/cmParsePHPCoverage.h b/Source/CTest/cmParsePHPCoverage.h new file mode 100644 index 0000000..ce5741d --- /dev/null +++ b/Source/CTest/cmParsePHPCoverage.h @@ -0,0 +1,48 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + 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 cmParsePHPCoverage_h +#define cmParsePHPCoverage_h + +#include "cmStandardIncludes.h" +#include "cmCTestCoverageHandler.h" + +/** \class cmParsePHPCoverage + * \brief Parse xdebug PHP coverage information + * + * This class is used to parse php coverage information produced + * by xdebug. The data is stored as a php dump of the array + * return by xdebug coverage. It is an array of arrays. + */ +class cmParsePHPCoverage +{ +public: + cmParsePHPCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest); + bool ReadPHPCoverageDirectory(const char* dir); + void PrintCoverage(); +private: + bool ReadPHPData(const char* file); + bool ReadArraySize(std::ifstream& in, int& size); + bool ReadFileInformation(std::ifstream& in); + bool ReadInt(std::ifstream& in, int& v); + bool ReadCoverageArray(std::ifstream& in, cmStdString const&); + bool ReadUntil(std::ifstream& in, char until); + typedef std::map<int, int> FileLineCoverage; + std::map<cmStdString, FileLineCoverage> FileToCoverage; + std::map<int, int> FileCoverage; + cmCTestCoverageHandlerContainer& Coverage; + cmCTest* CTest; +}; + + +#endif diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index e613a78..28f4697 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -11,7 +11,6 @@ ============================================================================*/ #include "QCMake.h" // include to disable MS warnings #include <QApplication> -#include <QFileInfo> #include <QDir> #include <QTranslator> #include <QLocale> @@ -21,6 +20,7 @@ #include "cmake.h" #include "cmVersion.h" #include <cmsys/CommandLineArguments.hxx> +#include <cmsys/SystemTools.hxx> //---------------------------------------------------------------------------- static const char * cmDocumentationName[][3] = @@ -164,16 +164,19 @@ int main(int argc, char** argv) QStringList args = app.arguments(); if(args.count() == 2) { - QFileInfo buildFileInfo(args[1], "CMakeCache.txt"); - QFileInfo srcFileInfo(args[1], "CMakeLists.txt"); - if(buildFileInfo.exists()) + cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toAscii().data()); + cmsys_stl::string buildFilePath = + cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str()); + cmsys_stl::string srcFilePath = + cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str()); + if(cmSystemTools::FileExists(buildFilePath.c_str())) { - dialog.setBinaryDirectory(buildFileInfo.absolutePath()); + dialog.setBinaryDirectory(filePath.c_str()); } - else if(srcFileInfo.exists()) + else if(cmSystemTools::FileExists(srcFilePath.c_str())) { - dialog.setSourceDirectory(srcFileInfo.absolutePath()); - dialog.setBinaryDirectory(QDir::currentPath()); + dialog.setSourceDirectory(filePath.c_str()); + dialog.setBinaryDirectory(cmSystemTools::CollapseFullPath(".").c_str()); } } } diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index eb82f2a..74a3d35 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -81,11 +81,8 @@ CMakeSetupDialog::CMakeSetupDialog() this->Splitter->restoreState(p); bool groupView = settings.value("GroupView", false).toBool(); - if(groupView) - { - this->setViewType(2); - this->ViewType->setCurrentIndex(2); - } + this->setGroupedView(groupView); + this->groupedCheck->setCheckState(groupView ? Qt::Checked : Qt::Unchecked); QMenu* FileMenu = this->menuBar()->addMenu(tr("&File")); this->ReloadCacheAction = FileMenu->addAction(tr("&Reload Cache")); @@ -217,8 +214,10 @@ void CMakeSetupDialog::initialize() SIGNAL(outputMessage(QString)), this, SLOT(message(QString))); - QObject::connect(this->ViewType, SIGNAL(currentIndexChanged(int)), - this, SLOT(setViewType(int))); + QObject::connect(this->groupedCheck, SIGNAL(toggled(bool)), + this, SLOT(setGroupedView(bool))); + QObject::connect(this->advancedCheck, SIGNAL(toggled(bool)), + this, SLOT(setAdvancedView(bool))); QObject::connect(this->Search, SIGNAL(textChanged(QString)), this, SLOT(setSearchFilter(QString))); @@ -950,33 +949,22 @@ void CMakeSetupDialog::setDebugOutput(bool flag) "setDebugOutput", Qt::QueuedConnection, Q_ARG(bool, flag)); } -void CMakeSetupDialog::setViewType(int v) +void CMakeSetupDialog::setGroupedView(bool v) { - if(v == 0) // simple view - { - this->CacheValues->cacheModel()->setViewType(QCMakeCacheModel::FlatView); - this->CacheValues->setRootIsDecorated(false); - this->CacheValues->setShowAdvanced(false); - } - else if(v == 1) // advanced view - { - this->CacheValues->cacheModel()->setViewType(QCMakeCacheModel::FlatView); - this->CacheValues->setRootIsDecorated(false); - this->CacheValues->setShowAdvanced(true); - } - else if(v == 2) // grouped view - { - this->CacheValues->cacheModel()->setViewType(QCMakeCacheModel::GroupView); - this->CacheValues->setRootIsDecorated(true); - this->CacheValues->setShowAdvanced(true); - } + this->CacheValues->cacheModel()->setViewType(v ? QCMakeCacheModel::GroupView : QCMakeCacheModel::FlatView); + this->CacheValues->setRootIsDecorated(v); QSettings settings; settings.beginGroup("Settings/StartPath"); - settings.setValue("GroupView", v == 2); + settings.setValue("GroupView", v); } +void CMakeSetupDialog::setAdvancedView(bool v) +{ + this->CacheValues->setShowAdvanced(v); +} + void CMakeSetupDialog::showUserChanges() { QSet<QCMakeProperty> changes = diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index de7922a..0e3caec 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -70,7 +70,8 @@ protected slots: void addCacheEntry(); void startSearch(); void setDebugOutput(bool); - void setViewType(int); + void setAdvancedView(bool); + void setGroupedView(bool); void showUserChanges(); void setSearchFilter(const QString& str); diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui index ae0dca2..dc8ee3f 100644 --- a/Source/QtDialog/CMakeSetupDialog.ui +++ b/Source/QtDialog/CMakeSetupDialog.ui @@ -1,7 +1,8 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>CMakeSetupDialog</class> - <widget class="QWidget" name="CMakeSetupDialog" > - <property name="geometry" > + <widget class="QWidget" name="CMakeSetupDialog"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> @@ -9,115 +10,111 @@ <height>582</height> </rect> </property> - <layout class="QGridLayout" > - <property name="margin" > + <layout class="QGridLayout"> + <property name="margin"> <number>9</number> </property> - <property name="spacing" > + <property name="spacing"> <number>6</number> </property> - <item row="0" column="0" > - <layout class="QGridLayout" > - <property name="margin" > + <item row="0" column="0"> + <layout class="QGridLayout"> + <property name="margin"> <number>0</number> </property> - <property name="spacing" > + <property name="spacing"> <number>6</number> </property> - <item row="0" column="0" > - <widget class="QLabel" name="label" > - <property name="text" > + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> <string>Where is the source code:</string> </property> </widget> </item> - <item row="0" column="1" > - <widget class="QLineEdit" name="SourceDirectory" /> + <item row="0" column="1"> + <widget class="QLineEdit" name="SourceDirectory"/> </item> - <item row="0" column="2" > - <widget class="QPushButton" name="BrowseSourceDirectoryButton" > - <property name="text" > + <item row="0" column="2"> + <widget class="QPushButton" name="BrowseSourceDirectoryButton"> + <property name="text"> <string>Browse &Source...</string> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QLabel" name="label_2" > - <property name="text" > + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> <string>Where to build the binaries:</string> </property> </widget> </item> - <item row="1" column="1" > - <widget class="QComboBox" name="BinaryDirectory" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Ignored" > + <item row="1" column="1"> + <widget class="QComboBox" name="BinaryDirectory"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="editable" > + <property name="editable"> <bool>true</bool> </property> </widget> </item> - <item row="1" column="2" > - <widget class="QPushButton" name="BrowseBinaryDirectoryButton" > - <property name="text" > + <item row="1" column="2"> + <widget class="QPushButton" name="BrowseBinaryDirectoryButton"> + <property name="text"> <string>Browse &Build...</string> </property> </widget> </item> </layout> </item> - <item row="1" column="0" > - <widget class="QSplitter" name="Splitter" > - <property name="orientation" > + <item row="1" column="0"> + <widget class="QSplitter" name="Splitter"> + <property name="orientation"> <enum>Qt::Vertical</enum> </property> - <widget class="QFrame" name="frame" > - <property name="frameShape" > + <widget class="QFrame" name="frame"> + <property name="frameShape"> <enum>QFrame::NoFrame</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Raised</enum> </property> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > + <layout class="QVBoxLayout"> + <property name="spacing"> <number>6</number> </property> + <property name="margin"> + <number>0</number> + </property> <item> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > + <layout class="QHBoxLayout"> + <property name="spacing"> <number>6</number> </property> + <property name="margin"> + <number>0</number> + </property> <item> - <widget class="QLabel" name="label_4" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>0</vsizetype> + <widget class="QLabel" name="label_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="text" > + <property name="text"> <string>Search:</string> </property> </widget> </item> <item> - <widget class="QLineEdit" name="Search" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>0</vsizetype> + <widget class="QLineEdit" name="Search"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -125,33 +122,14 @@ </widget> </item> <item> - <widget class="QComboBox" name="ViewType" > - <item> - <property name="text" > - <string>Simple View</string> - </property> - </item> - <item> - <property name="text" > - <string>Advanced View</string> - </property> - </item> - <item> - <property name="text" > - <string>Grouped View</string> - </property> - </item> - </widget> - </item> - <item> <spacer> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeType" > + <property name="sizeType"> <enum>QSizePolicy::Minimum</enum> </property> - <property name="sizeHint" > + <property name="sizeHint" stdset="0"> <size> <width>40</width> <height>23</height> @@ -160,33 +138,49 @@ </spacer> </item> <item> - <widget class="QToolButton" name="AddEntry" > - <property name="toolTip" > + <widget class="QCheckBox" name="groupedCheck"> + <property name="text"> + <string>Grouped</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="advancedCheck"> + <property name="text"> + <string>Advanced</string> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="AddEntry"> + <property name="toolTip"> <string>Add New Entry</string> </property> - <property name="text" > + <property name="text"> <string>&Add Entry</string> </property> - <property name="icon" > - <iconset resource="CMakeSetup.qrc" >:/Icons/Plus16.png</iconset> + <property name="icon"> + <iconset resource="CMakeSetup.qrc"> + <normaloff>:/Icons/Plus16.png</normaloff>:/Icons/Plus16.png</iconset> </property> - <property name="toolButtonStyle" > + <property name="toolButtonStyle"> <enum>Qt::ToolButtonTextBesideIcon</enum> </property> </widget> </item> <item> - <widget class="QToolButton" name="RemoveEntry" > - <property name="toolTip" > + <widget class="QToolButton" name="RemoveEntry"> + <property name="toolTip"> <string>Remove Selected Entries</string> </property> - <property name="text" > + <property name="text"> <string>&Remove Entry</string> </property> - <property name="icon" > - <iconset resource="CMakeSetup.qrc" >:/Icons/Delete16.png</iconset> + <property name="icon"> + <iconset resource="CMakeSetup.qrc"> + <normaloff>:/Icons/Delete16.png</normaloff>:/Icons/Delete16.png</iconset> </property> - <property name="toolButtonStyle" > + <property name="toolButtonStyle"> <enum>Qt::ToolButtonTextBesideIcon</enum> </property> </widget> @@ -194,69 +188,69 @@ </layout> </item> <item> - <widget class="QCMakeCacheView" name="CacheValues" > - <property name="alternatingRowColors" > + <widget class="QCMakeCacheView" name="CacheValues"> + <property name="alternatingRowColors"> <bool>true</bool> </property> - <property name="selectionMode" > + <property name="selectionMode"> <enum>QAbstractItemView::ExtendedSelection</enum> </property> - <property name="selectionBehavior" > + <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> </widget> </item> <item> - <widget class="QLabel" name="label_3" > - <property name="text" > + <widget class="QLabel" name="label_3"> + <property name="text"> <string>Press Configure to update and display new values in red, then press Generate to generate selected build files.</string> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignCenter</set> </property> - <property name="wordWrap" > + <property name="wordWrap"> <bool>true</bool> </property> </widget> </item> <item> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > + <layout class="QHBoxLayout"> + <property name="spacing"> <number>6</number> </property> + <property name="margin"> + <number>0</number> + </property> <item> - <widget class="QPushButton" name="ConfigureButton" > - <property name="text" > + <widget class="QPushButton" name="ConfigureButton"> + <property name="text"> <string>&Configure</string> </property> </widget> </item> <item> - <widget class="QPushButton" name="GenerateButton" > - <property name="text" > + <widget class="QPushButton" name="GenerateButton"> + <property name="text"> <string>&Generate</string> </property> </widget> </item> <item> - <widget class="QLabel" name="Generator" > - <property name="text" > + <widget class="QLabel" name="Generator"> + <property name="text"> <string>Current Generator:</string> </property> </widget> </item> <item> <spacer> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeType" > + <property name="sizeType"> <enum>QSizePolicy::Expanding</enum> </property> - <property name="sizeHint" > + <property name="sizeHint" stdset="0"> <size> <width>121</width> <height>27</height> @@ -265,23 +259,23 @@ </spacer> </item> <item> - <widget class="QProgressBar" name="ProgressBar" > - <property name="minimum" > + <widget class="QProgressBar" name="ProgressBar"> + <property name="minimum"> <number>0</number> </property> - <property name="maximum" > + <property name="maximum"> <number>100</number> </property> - <property name="value" > + <property name="value"> <number>0</number> </property> - <property name="textVisible" > + <property name="textVisible"> <bool>false</bool> </property> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="textDirection" > + <property name="textDirection"> <enum>QProgressBar::BottomToTop</enum> </property> </widget> @@ -290,11 +284,11 @@ </item> </layout> </widget> - <widget class="QTextEdit" name="Output" > - <property name="lineWrapMode" > + <widget class="QTextEdit" name="Output"> + <property name="lineWrapMode"> <enum>QTextEdit::NoWrap</enum> </property> - <property name="readOnly" > + <property name="readOnly"> <bool>true</bool> </property> </widget> @@ -310,7 +304,7 @@ </customwidget> </customwidgets> <resources> - <include location="CMakeSetup.qrc" /> + <include location="CMakeSetup.qrc"/> </resources> <connections/> </ui> diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index b7e939e..126934c 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -66,14 +66,17 @@ bool cmCMakeMinimumRequired int current_major = cmVersion::GetMajorVersion(); int current_minor = cmVersion::GetMinorVersion(); int current_patch = cmVersion::GetPatchVersion(); + int current_tweak = cmVersion::GetTweakVersion(); - // Parse the required version number. If no patch-level is given - // use zero. + // Parse at least two components of the version number. + // Use zero for those not specified. int required_major = 0; int required_minor = 0; int required_patch = 0; - if(sscanf(version_string.c_str(), "%d.%d.%d", - &required_major, &required_minor, &required_patch) < 2) + int required_tweak = 0; + if(sscanf(version_string.c_str(), "%u.%u.%u.%u", + &required_major, &required_minor, + &required_patch, &required_tweak) < 2) { cmOStringStream e; e << "could not parse VERSION \"" << version_string.c_str() << "\"."; @@ -87,13 +90,17 @@ bool cmCMakeMinimumRequired current_minor < required_minor) || (current_major == required_major && current_minor == required_minor && - current_patch < required_patch)) + current_patch < required_patch) || + (current_major == required_major && + current_minor == required_minor && + current_patch == required_patch && + current_tweak < required_tweak)) { // The current version is too low. cmOStringStream e; e << "CMake " << version_string.c_str() << " or higher is required. You are running version " - << current_major << "." << current_minor << "." << current_patch; + << cmVersion::GetCMakeVersion(); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return true; diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h index 05c2505..9bf7ef8 100644 --- a/Source/cmCMakeMinimumRequired.h +++ b/Source/cmCMakeMinimumRequired.h @@ -61,13 +61,13 @@ public: virtual const char* GetFullDocumentation() { return - " cmake_minimum_required(VERSION major[.minor[.patch]]\n" + " cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]]\n" " [FATAL_ERROR])\n" "If the current version of CMake is lower than that required " "it will stop processing the project and report an error. " "When a version higher than 2.4 is specified the command implicitly " "invokes\n" - " cmake_policy(VERSION major[.minor[.patch]])\n" + " cmake_policy(VERSION major[.minor[.patch[.tweak]]])\n" "which sets the cmake policy version level to the version specified. " "When version 2.4 or lower is given the command implicitly invokes\n" " cmake_policy(VERSION 2.4)\n" diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h index ffd0f44..b326865 100644 --- a/Source/cmCMakePolicyCommand.h +++ b/Source/cmCMakePolicyCommand.h @@ -80,7 +80,7 @@ public: "behavior. " "While setting policies individually is supported, we encourage " "projects to set policies based on CMake versions.\n" - " cmake_policy(VERSION major.minor[.patch])\n" + " cmake_policy(VERSION major.minor[.patch[.tweak]])\n" "Specify that the current CMake list file is written for the " "given version of CMake. " "All policies introduced in the specified version or earlier " diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e417e1b..bd69d6c 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -311,9 +311,12 @@ cmCTest::cmCTest() this->InteractiveDebugMode = true; this->TimeOut = 0; this->GlobalTimeout = 0; + this->LastStopTimeout = 24 * 60 * 60; this->CompressXMLFiles = false; this->CTestConfigFile = ""; this->ScheduleType = ""; + this->StopTime = ""; + this->NextDayStopTime = false; this->OutputLogFile = 0; this->OutputLogFileLastTag = -1; this->SuppressUpdatingCTestConfiguration = false; @@ -1881,6 +1884,12 @@ void cmCTest::HandleCommandLineArguments(size_t &i, double timeout = (double)atof(args[i].c_str()); this->GlobalTimeout = timeout; } + + if(this->CheckArgument(arg, "--stop-time") && i < args.size() - 1) + { + i++; + this->SetStopTime(args[i]); + } if(this->CheckArgument(arg, "-C", "--build-config") && i < args.size() - 1) @@ -2335,6 +2344,13 @@ void cmCTest::SetNotesFiles(const char* notes) } //---------------------------------------------------------------------- +void cmCTest::SetStopTime(std::string time) +{ + this->StopTime = time; + this->DetermineNextDayStop(); +} + +//---------------------------------------------------------------------- int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf) { bool found = false; @@ -2536,6 +2552,46 @@ void cmCTest::EmptyCTestConfiguration() } //---------------------------------------------------------------------- +void cmCTest::DetermineNextDayStop() +{ + struct tm* lctime; + time_t current_time = time(0); + lctime = gmtime(¤t_time); + int gm_hour = lctime->tm_hour; + time_t gm_time = mktime(lctime); + lctime = localtime(¤t_time); + int local_hour = lctime->tm_hour; + + int tzone_offset = local_hour - gm_hour; + if(gm_time > current_time && gm_hour < local_hour) + { + // this means gm_time is on the next day + tzone_offset -= 24; + } + else if(gm_time < current_time && gm_hour > local_hour) + { + // this means gm_time is on the previous day + tzone_offset += 24; + } + + tzone_offset *= 100; + char buf[1024]; + sprintf(buf, "%d%02d%02d %s %+05i", + lctime->tm_year + 1900, + lctime->tm_mon + 1, + lctime->tm_mday, + this->StopTime.c_str(), + tzone_offset); + + time_t stop_time = curl_getdate(buf, ¤t_time); + + if(stop_time < current_time) + { + this->NextDayStopTime = true; + } +} + +//---------------------------------------------------------------------- void cmCTest::SetCTestConfiguration(const char *name, const char* value) { cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:" diff --git a/Source/cmCTest.h b/Source/cmCTest.h index adf359c..3d7d117 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -214,6 +214,9 @@ public: std::string GetCDashVersion(); + std::string GetStopTime() { return this->StopTime; } + void SetStopTime(std::string time); + //Used for parallel ctest job scheduling std::string GetScheduleType() { return this->ScheduleType; } void SetScheduleType(std::string type) { this->ScheduleType = type; } @@ -403,6 +406,8 @@ public: private: std::string ConfigType; std::string ScheduleType; + std::string StopTime; + bool NextDayStopTime; bool Verbose; bool ExtraVerbose; bool ProduceXML; @@ -420,6 +425,8 @@ private: int GenerateNotesFile(const char* files); + void DetermineNextDayStop(); + // these are helper classes typedef std::map<cmStdString,cmCTestGenericHandler*> t_TestingHandlers; t_TestingHandlers TestingHandlers; @@ -450,6 +457,8 @@ private: double GlobalTimeout; + int LastStopTimeout; + int MaxTestNameWidth; int ParallelLevel; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 69a4d22..1cabed2 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -376,6 +376,8 @@ cmComputeLinkInformation { this->OrderDependentRPath ->SetImplicitDirectories(this->ImplicitLinkDirs); + this->OrderDependentRPath + ->AddLanguageDirectories(this->RuntimeLinkDirs); } // Decide whether to enable compatible library search path mode. @@ -1324,13 +1326,12 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item) //---------------------------------------------------------------------------- void cmComputeLinkInformation::AddDirectoryItem(std::string const& item) { -#ifdef __APPLE__ - if(cmSystemTools::IsPathToFramework(item.c_str())) + if(this->Makefile->IsOn("APPLE") + && cmSystemTools::IsPathToFramework(item.c_str())) { this->AddFrameworkItem(item); } else -#endif { this->DropDirectoryItem(item); } @@ -1642,6 +1643,14 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() this->ImplicitLinkLibs.insert(item); } } + + // Get platform specific rpath link directories + if(const char *rpathDirs = + (this->Makefile->GetDefinition + ("CMAKE_PLATFORM_RUNTIME_PATH"))) + { + cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs); + } } //---------------------------------------------------------------------------- diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index ad2026b..bbeed68 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -163,6 +163,9 @@ private: std::set<cmStdString> ImplicitLinkDirs; std::set<cmStdString> ImplicitLinkLibs; + // Additional paths configured by the runtime linker + std::vector<std::string> RuntimeLinkDirs; + // Linker search path compatibility mode. std::set<cmStdString> OldLinkDirMask; std::vector<std::string> OldLinkDirItems; diff --git a/Source/cmData.h b/Source/cmData.h deleted file mode 100644 index 3ae32f5..0000000 --- a/Source/cmData.h +++ /dev/null @@ -1,38 +0,0 @@ -/*============================================================================ - 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 cmData_h -#define cmData_h - -#include "cmStandardIncludes.h" - -/** \class cmData - * \brief Hold extra data on a cmMakefile instance for a command. - * - * When CMake commands need to store extra information in a cmMakefile - * instance, but the information is not needed by the makefile generators, - * it can be held in a subclass of cmData. The cmMakefile class has a map - * from std::string to cmData*. On its destruction, it destroys all the - * extra data through the virtual destructor of cmData. - */ -class cmData -{ -public: - cmData(const char* name): Name(name) {} - virtual ~cmData() {} - - const std::string& GetName() const - { return this->Name; } -protected: - std::string Name; -}; - -#endif diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 6957334..c7848b7 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -251,12 +251,22 @@ void cmDocumentVariables::DefineVariables(cmake* cm) " executable being run.",false, "Variables that Provide Information"); cm->DefineProperty + ("CMAKE_TWEAK_VERSION", cmProperty::VARIABLE, + "The tweak version of cmake (i.e. the 1 in X.X.X.1).", + "This specifies the tweak version of the CMake executable being run. " + "Releases use tweak < 20000000 and development versions use the date " + "format CCYYMMDD for the tweak level." + ,false, "Variables that Provide Information"); + cm->DefineProperty ("CMAKE_VERSION", cmProperty::VARIABLE, - "The full version of cmake in major.minor.patch format.", + "The full version of cmake in major.minor.patch[.tweak[-id]] format.", "This specifies the full version of the CMake executable being run. " "This variable is defined by versions 2.6.3 and higher. " - "See variables CMAKE_MAJOR_VERSION, CMAKE_MINOR_VERSION, and " - "CMAKE_PATCH_VERSION for individual version components.", false, + "See variables CMAKE_MAJOR_VERSION, CMAKE_MINOR_VERSION, " + "CMAKE_PATCH_VERSION, and CMAKE_TWEAK_VERSION " + "for individual version components. " + "The [-id] component appears in non-release versions " + "and may be arbitrary text.", false, "Variables that Provide Information"); cm->DefineProperty @@ -598,7 +608,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "will check each of the contained directories for the existence of the " "library which is currently searched. By default it contains the " "standard directories for the current system. It is NOT intended to be " - "modified by the project, use CMAKE_SYSTEM_LIBRARY_PATH for this. See " + "modified by the project, use CMAKE_LIBRARY_PATH for this. See " "also CMAKE_SYSTEM_PREFIX_PATH.", false, "Variables That Change Behavior"); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index fc2fb14..bfe11c1 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -606,20 +606,22 @@ bool cmDocumentation::CreateSingleModule(const char* fname, } else { - if(text.length() < 2 && brief.length() == 1) - { - return false; - } - char* pname = strcpy(new char[strlen(moduleName)+1], moduleName); - char* ptext = strcpy(new char[text.length()+1], text.c_str()); - this->ModuleStrings.push_back(pname); - this->ModuleStrings.push_back(ptext); - char* pbrief = strcpy(new char[brief.length()+1], brief.c_str()); - this->ModuleStrings.push_back(pbrief); - moduleSection.Append(pname, pbrief, ptext); - return true; + break; } } + + if(text.length() < 2 && brief.length() == 1) + { + return false; + } + + char* pname = strcpy(new char[strlen(moduleName)+1], moduleName); + char* ptext = strcpy(new char[text.length()+1], text.c_str()); + this->ModuleStrings.push_back(pname); + this->ModuleStrings.push_back(ptext); + char* pbrief = strcpy(new char[brief.length()+1], brief.c_str()); + this->ModuleStrings.push_back(pbrief); + moduleSection.Append(pname, pbrief, ptext); return true; } @@ -1177,11 +1179,18 @@ bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os) this->CurrentArgument.c_str(), *this->AllSections["Modules"])) { - this->PrintDocumentationCommand - (os, this->AllSections["Modules"]->GetEntries()[0]); - os << "\n Defined in: "; - os << moduleName << "\n"; - return true; + if(this->AllSections["Modules"]->GetEntries().size()) + { + this->PrintDocumentationCommand + (os, this->AllSections["Modules"]->GetEntries()[0]); + os << "\n Defined in: "; + os << moduleName << "\n"; + return true; + } + else + { + return false; + } } } diff --git a/Source/cmDocumentationFormatterText.cxx b/Source/cmDocumentationFormatterText.cxx index 078b890..0b04b73 100644 --- a/Source/cmDocumentationFormatterText.cxx +++ b/Source/cmDocumentationFormatterText.cxx @@ -96,7 +96,7 @@ void cmDocumentationFormatterText::PrintColumn(std::ostream& os, { // Print text arranged in an indented column of fixed witdh. const char* l = text; - int column = 0; + long column = 0; bool newSentence = false; bool firstLine = true; int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent)); diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 763fdd8..147f6ac 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -687,7 +687,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag) // The value has been read successfully. Report it. se.Position = static_cast<unsigned long>(strtab.sh_offset + first); se.Size = last - first; - se.IndexInSection = di - this->DynamicSectionEntries.begin(); + se.IndexInSection = static_cast<int>(di - this->DynamicSectionEntries.begin()); return &se; } } diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 5cbef8c..4cb2b48 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -630,8 +630,8 @@ std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf) std::string hostSystemName = mf->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME"); std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME"); - std::string compilerId = mf->GetRequiredDefinition(compilerIdVar.c_str()); - std::string compiler = "gcc"; + std::string compilerId = mf->GetSafeDefinition(compilerIdVar.c_str()); + std::string compiler = "gcc"; // default to gcc if (compilerId == "MSVC") { compiler = "msvc8"; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index fe914fd..204d5d7 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -292,7 +292,6 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() AddEnvVar(fout, "INCLUDE", mf); AddEnvVar(fout, "LIB", mf); AddEnvVar(fout, "LIBPATH", mf); - AddEnvVar(fout, "INCLUDE", mf); } else if (compilerId == "Intel") { diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index c2e90b6..133c1a1 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -183,24 +183,18 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, std::string dir = cmSystemTools::GetFilenamePath(fileName); cmSystemTools::MakeDirectory(dir.c_str()); - mode_t mode = -#if defined( _MSC_VER ) || defined( __MINGW32__ ) - S_IREAD | S_IWRITE -#elif defined( __BORLANDC__ ) - S_IRUSR | S_IWUSR -#else - 0666 -#endif - ; + mode_t mode = 0; // Set permissions to writable if ( cmSystemTools::GetPermissions(fileName.c_str(), mode) ) { cmSystemTools::SetPermissions(fileName.c_str(), #if defined( _MSC_VER ) || defined( __MINGW32__ ) - S_IREAD | S_IWRITE + mode | S_IWRITE +#elif defined( __BORLANDC__ ) + mode | S_IWUSR #else - 0666 + mode | S_IWUSR | S_IWGRP #endif ); } @@ -217,7 +211,10 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, } file << message; file.close(); - cmSystemTools::SetPermissions(fileName.c_str(), mode); + if(mode) + { + cmSystemTools::SetPermissions(fileName.c_str(), mode); + } return true; } @@ -529,13 +526,6 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) return false; } - // At least one compiler (Portland Group Fortran) produces binaries - // with some extra characters in strings. - char extra[256]; // = {}; // some compilers do not like this - memset(extra, 0, sizeof(extra)); - extra[0x0c] = 1; // FF (form feed) - extra[0x14] = 1; // DC4 (device control 4) - // Parse strings out of the file. int output_size = 0; std::vector<std::string> strings; @@ -545,28 +535,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) (limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) && (c = fin.get(), fin)) { - if(c == '\0') - { - // A terminating null character has been found. Check if the - // current string matches the requirements. Since it was - // terminated by a null character, we require that the length be - // at least one no matter what the user specified. - if(s.length() >= minlen && s.length() >= 1 && - (!have_regex || regex.find(s.c_str()))) - { - output_size += static_cast<int>(s.size()) + 1; - if(limit_output >= 0 && output_size >= limit_output) - { - s = ""; - break; - } - strings.push_back(s); - } - - // Reset the string to empty. - s = ""; - } - else if(c == '\n' && !newline_consume) + if(c == '\n' && !newline_consume) { // The current line has been terminated. Check if the current // string matches the requirements. The length may now be as @@ -590,7 +559,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) { // Ignore CR character to make output always have UNIX newlines. } - else if((c >= 0x20 && c < 0x7F) || c == '\t' || extra[c] || + else if((c >= 0x20 && c < 0x7F) || c == '\t' || (c == '\n' && newline_consume)) { // This is an ASCII character that may be part of a string. @@ -600,7 +569,23 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) } else { - // This is a non-string character. Reset the string to emtpy. + // TODO: Support ENCODING option. See issue #10519. + // A non-string character has been found. Check if the current + // string matches the requirements. We require that the length + // be at least one no matter what the user specified. + if(s.length() >= minlen && s.length() >= 1 && + (!have_regex || regex.find(s.c_str()))) + { + output_size += static_cast<int>(s.size()) + 1; + if(limit_output >= 0 && output_size >= limit_output) + { + s = ""; + break; + } + strings.push_back(s); + } + + // Reset the string to empty. s = ""; } @@ -1519,7 +1504,7 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile, this->ReportCopy(toFile, TypeFile, copy); // Copy the file. - if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true, false)) + if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true)) { cmOStringStream e; e << this->Name << " cannot copy file \"" << fromFile @@ -1531,6 +1516,13 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile, // Set the file modification time of the destination file. if(copy && !this->Always) { + // Add write permission so we can set the file time. + // Permissions are set unconditionally below anyway. + mode_t perm = 0; + if(cmSystemTools::GetPermissions(toFile, perm)) + { + cmSystemTools::SetPermissions(toFile, perm | mode_owner_write); + } if (!cmSystemTools::CopyFileTime(fromFile, toFile)) { cmOStringStream e; @@ -2455,7 +2447,8 @@ namespace{ fout->write(chPtr, realsize); return realsize; } - + + static size_t cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr, size_t size, void *data) @@ -2468,6 +2461,72 @@ namespace{ } + class cURLProgressHelper + { + public: + cURLProgressHelper(cmFileCommand *fc) + { + this->CurrentPercentage = -1; + this->FileCommand = fc; + } + + bool UpdatePercentage(double value, double total, std::string &status) + { + int OldPercentage = this->CurrentPercentage; + + if (0.0 == total) + { + this->CurrentPercentage = 100; + } + else + { + this->CurrentPercentage = static_cast<int>(value/total*100.0 + 0.5); + } + + bool updated = (OldPercentage != this->CurrentPercentage); + + if (updated) + { + cmOStringStream oss; + oss << "[download " << this->CurrentPercentage << "% complete]"; + status = oss.str(); + } + + return updated; + } + + cmFileCommand *GetFileCommand() + { + return this->FileCommand; + } + + private: + int CurrentPercentage; + cmFileCommand *FileCommand; + }; + + + static int + cmFileCommandCurlProgressCallback(void *clientp, + double dltotal, double dlnow, + double ultotal, double ulnow) + { + cURLProgressHelper *helper = + reinterpret_cast<cURLProgressHelper *>(clientp); + + static_cast<void>(ultotal); + static_cast<void>(ulnow); + + std::string status; + if (helper->UpdatePercentage(dlnow, dltotal, status)) + { + cmFileCommand *fc = helper->GetFileCommand(); + cmMakefile *mf = fc->GetMakefile(); + mf->DisplayStatus(status.c_str(), -1); + } + + return 0; + } } #endif @@ -2481,8 +2540,8 @@ namespace { cURLEasyGuard(CURL * easy) : Easy(easy) {} - - ~cURLEasyGuard(void) + + ~cURLEasyGuard(void) { if (this->Easy) { @@ -2503,6 +2562,7 @@ namespace { } #endif + bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) @@ -2520,9 +2580,13 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> ++i; std::string file = *i; ++i; + long timeout = 0; std::string verboseLog; std::string statusVar; + std::string expectedMD5sum; + bool showProgress = false; + while(i != args.end()) { if(*i == "TIMEOUT") @@ -2561,9 +2625,65 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> } statusVar = *i; } + else if(*i == "EXPECTED_MD5") + { + ++i; + if( i == args.end()) + { + this->SetError("FILE(DOWNLOAD url file EXPECTED_MD5 sum) missing " + "sum value for EXPECTED_MD5."); + return false; + } + expectedMD5sum = cmSystemTools::LowerCase(*i); + } + else if(*i == "SHOW_PROGRESS") + { + showProgress = true; + } ++i; } + // If file exists already, and caller specified an expected md5 sum, + // and the existing file already has the expected md5 sum, then simply + // return. + // + if(cmSystemTools::FileExists(file.c_str()) && + !expectedMD5sum.empty()) + { + char computedMD5[32]; + + if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5)) + { + this->SetError("FILE(DOWNLOAD ) error; cannot compute MD5 sum on " + "pre-existing file"); + return false; + } + + std::string actualMD5sum = cmSystemTools::LowerCase( + std::string(computedMD5, 32)); + + if (expectedMD5sum == actualMD5sum) + { + this->Makefile->DisplayStatus( + "FILE(DOWNLOAD ) returning early: file already exists with " + "expected MD5 sum", -1); + + if(statusVar.size()) + { + cmOStringStream result; + result << (int)0 << ";\"" + "returning early: file already exists with expected MD5 sum\""; + this->Makefile->AddDefinition(statusVar.c_str(), + result.str().c_str()); + } + + return true; + } + } + + // Make sure parent directory exists so we can write to the file + // as we receive downloaded bits from curl... + // std::string dir = cmSystemTools::GetFilenamePath(file.c_str()); if(!cmSystemTools::FileExists(dir.c_str()) && !cmSystemTools::MakeDirectory(dir.c_str())) @@ -2582,6 +2702,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> "file for write."); return false; } + ::CURL *curl; ::curl_global_init(CURL_GLOBAL_DEFAULT); curl = ::curl_easy_init(); @@ -2597,28 +2718,31 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); if (res != CURLE_OK) { - std::string errstring = "FILE(DOWNLOAD ) error; cannot set url: "; - errstring += ::curl_easy_strerror(res); + std::string errstring = "FILE(DOWNLOAD ) error; cannot set url: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, - cmFileCommandWriteMemoryCallback); + cmFileCommandWriteMemoryCallback); if (res != CURLE_OK) - { - std::string errstring = - "FILE(DOWNLOAD ) error; cannot set write function: "; - errstring += ::curl_easy_strerror(res); + { + std::string errstring = + "FILE(DOWNLOAD ) error; cannot set write function: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, - cmFileCommandCurlDebugCallback); + cmFileCommandCurlDebugCallback); if (res != CURLE_OK) { - std::string errstring = - "FILE(DOWNLOAD ) error; cannot set debug function: "; - errstring += ::curl_easy_strerror(res); + std::string errstring = + "FILE(DOWNLOAD ) error; cannot set debug function: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } @@ -2630,14 +2754,25 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> { std::string errstring = "FILE(DOWNLOAD ) error; cannot set write data: "; errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug); if (res != CURLE_OK) { - std::string errstring = "FILE(DOWNLOAD ) error; cannot set write data: "; + std::string errstring = "FILE(DOWNLOAD ) error; cannot set debug data: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); + return false; + } + + res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + if (res != CURLE_OK) + { + std::string errstring = "FILE(DOWNLOAD ) error; cannot set follow-redirect option: "; errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } @@ -2649,24 +2784,70 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> { std::string errstring = "FILE(DOWNLOAD ) error; cannot set verbose: "; errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } } + if(timeout > 0) { res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout ); if (res != CURLE_OK) { - std::string errstring = "FILE(DOWNLOAD ) error; cannot set verbose: "; + std::string errstring = "FILE(DOWNLOAD ) error; cannot set timeout: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); + return false; + } + } + + // Need the progress helper's scope to last through the duration of + // the curl_easy_perform call... so this object is declared at function + // scope intentionally, rather than inside the "if(showProgress)" + // block... + // + cURLProgressHelper helper(this); + + if(showProgress) + { + res = ::curl_easy_setopt(curl, + CURLOPT_NOPROGRESS, 0); + if (res != CURLE_OK) + { + std::string errstring = "FILE(DOWNLOAD ) error; cannot set noprogress value: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); + return false; + } + + res = ::curl_easy_setopt(curl, + CURLOPT_PROGRESSFUNCTION, cmFileCommandCurlProgressCallback); + if (res != CURLE_OK) + { + std::string errstring = "FILE(DOWNLOAD ) error; cannot set progress function: "; + errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); + return false; + } + + res = ::curl_easy_setopt(curl, + CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper)); + if (res != CURLE_OK) + { + std::string errstring = "FILE(DOWNLOAD ) error; cannot set progress data: "; errstring += ::curl_easy_strerror(res); + this->SetError(errstring.c_str()); return false; } } + res = ::curl_easy_perform(curl); + /* always cleanup */ g_curl.release(); ::curl_easy_cleanup(curl); + if(statusVar.size()) { cmOStringStream result; @@ -2674,7 +2855,44 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> this->Makefile->AddDefinition(statusVar.c_str(), result.str().c_str()); } + ::curl_global_cleanup(); + + // Explicitly flush/close so we can measure the md5 accurately. + // + fout.flush(); + fout.close(); + + // Verify MD5 sum if requested: + // + if (!expectedMD5sum.empty()) + { + char computedMD5[32]; + + if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5)) + { + this->SetError("FILE(DOWNLOAD ) error; cannot compute MD5 sum on " + "downloaded file"); + return false; + } + + std::string actualMD5sum = cmSystemTools::LowerCase( + std::string(computedMD5, 32)); + + if (expectedMD5sum != actualMD5sum) + { + cmOStringStream oss; + oss << "FILE(DOWNLOAD ) error; expected and actual MD5 sums differ" + << std::endl + << " for file: [" << file << "]" << std::endl + << " expected MD5 sum: [" << expectedMD5sum << "]" << std::endl + << " actual MD5 sum: [" << actualMD5sum << "]" << std::endl + ; + this->SetError(oss.str().c_str()); + return false; + } + } + if(chunkDebug.size()) { chunkDebug.push_back(0); @@ -2692,6 +2910,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> this->Makefile->AddDefinition(verboseLog.c_str(), &*chunkDebug.begin()); } + return true; #else this->SetError("FILE(DOWNLOAD ) " diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index c6da301..e771092 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -80,7 +80,8 @@ public: " file(RELATIVE_PATH variable directory file)\n" " file(TO_CMAKE_PATH path result)\n" " file(TO_NATIVE_PATH path result)\n" - " file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log])\n" + " file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log]\n" + " [EXPECTED_MD5 sum] [SHOW_PROGRESS])\n" "WRITE will write a message into a file called 'filename'. It " "overwrites the file if it already exists, and creates the file " "if it does not exist.\n" @@ -152,7 +153,12 @@ public: "and the second element is a string value for the error. A 0 " "numeric error means no error in the operation. " "If TIMEOUT time is specified, the operation will " - "timeout after time seconds, time should be specified as an integer." + "timeout after time seconds, time should be specified as an integer. " + "If EXPECTED_MD5 sum is specified, the operation will verify that the " + "downloaded file's actual md5 sum matches the expected value. If it " + "does not match, the operation fails with an error. " + "If SHOW_PROGRESS is specified, progress information will be printed " + "as status messages until the operation is complete." "\n" "The file() command also provides COPY and INSTALL signatures:\n" " file(<COPY|INSTALL> files... DESTINATION <dir>\n" diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index f4c0064..f352172 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -423,3 +423,17 @@ void cmFindCommon::AddTrailingSlashes(std::vector<std::string>& paths) } } } + +//---------------------------------------------------------------------------- +void cmFindCommon::SetMakefile(cmMakefile* makefile) +{ + cmCommand::SetMakefile(makefile); + + // If we are building for Apple (OSX or also iphone), make sure + // that frameworks and bundles are searched first. + if(this->Makefile->IsOn("APPLE")) + { + this->SearchFrameworkFirst = true; + this->SearchAppBundleFirst = true; + } +} diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index 08d2158..2ffbd00 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -61,6 +61,8 @@ protected: PathType pathType); void AddPathInternal(std::string const& in_path, PathType pathType); + void SetMakefile(cmMakefile* makefile); + bool NoDefaultPath; bool NoCMakePath; bool NoCMakeEnvironmentPath; diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h index c85b296..aff4d7e 100644 --- a/Source/cmGetFilenameComponentCommand.h +++ b/Source/cmGetFilenameComponentCommand.h @@ -62,10 +62,10 @@ public: virtual const char* GetFullDocumentation() { return - " get_filename_component(VarName FileName\n" + " get_filename_component(<VAR> FileName\n" " PATH|ABSOLUTE|NAME|EXT|NAME_WE|REALPATH\n" " [CACHE])\n" - "Set VarName to be the path (PATH), file name (NAME), file " + "Set <VAR> to be the path (PATH), file name (NAME), file " "extension (EXT), file name without extension (NAME_WE) of FileName, " "the full path (ABSOLUTE), or the full path with all symlinks " "resolved (REALPATH). " @@ -73,14 +73,14 @@ public: "trailing slashes. The longest file extension is always considered. " "If the optional CACHE argument is specified, the result variable is " "added to the cache.\n" - " get_filename_component(VarName FileName\n" - " PROGRAM [PROGRAM_ARGS ArgVar]\n" + " get_filename_component(<VAR> FileName\n" + " PROGRAM [PROGRAM_ARGS <ARG_VAR>]\n" " [CACHE])\n" "The program in FileName will be found in the system search path or " "left as a full path. If PROGRAM_ARGS is present with PROGRAM, then " "any command-line arguments present in the FileName string are split " - "from the program name and stored in ArgVar. This is used to separate " - "a program name from its arguments in a command line string."; + "from the program name and stored in <ARG_VAR>. This is used to " + "separate a program name from its arguments in a command line string."; } cmTypeMacro(cmGetFilenameComponentCommand, cmCommand); diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index d608aac..1191575 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -37,6 +37,7 @@ cmLocalGenerator *cmGlobalVisualStudio71Generator::CreateLocalGenerator() void cmGlobalVisualStudio71Generator::AddPlatformDefinitions(cmMakefile* mf) { this->cmGlobalVisualStudio7Generator::AddPlatformDefinitions(mf); + mf->RemoveDefinition("MSVC70"); mf->AddDefinition("MSVC71", "1"); } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 0d6e389..537a88f 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1514,8 +1514,13 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, extraLinkOptions = this->CurrentMakefile-> GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS"); } - - const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); + + const char* linkFlagsProp = "LINK_FLAGS"; + if(target.GetType() == cmTarget::STATIC_LIBRARY) + { + linkFlagsProp = "STATIC_LIBRARY_FLAGS"; + } + const char* targetLinkFlags = target.GetProperty(linkFlagsProp); if(targetLinkFlags) { extraLinkOptions += " "; @@ -1523,7 +1528,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, } if(configName && *configName) { - std::string linkFlagsVar = "LINK_FLAGS_"; + std::string linkFlagsVar = linkFlagsProp; + linkFlagsVar += "_"; linkFlagsVar += cmSystemTools::UpperCase(configName); if(const char* linkFlags = target.GetProperty(linkFlagsVar.c_str())) { diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h index d14d564..5269041 100644 --- a/Source/cmIncludeExternalMSProjectCommand.h +++ b/Source/cmIncludeExternalMSProjectCommand.h @@ -62,9 +62,8 @@ public: " dep1 dep2 ...)\n" "Includes an external Microsoft project in the generated workspace " "file. Currently does nothing on UNIX. This will create a " - "target named INCLUDE_EXTERNAL_MSPROJECT_[projectname]. This can " - "be used in the add_dependencies command to make things depend " - "on the external project."; + "target named [projectname]. This can be used in the add_dependencies " + "command to make things depend on the external project."; } cmTypeMacro(cmIncludeExternalMSProjectCommand, cmCommand); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4156f32..13d875f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -712,9 +712,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) std::string langFlags; this->AddLanguageFlags(langFlags, llang, 0); -#ifdef __APPLE__ this->AddArchitectureFlags(langFlags, &target, llang, 0); -#endif /* __APPLE__ */ vars.LanguageCompileFlags = langFlags.c_str(); cmCustomCommandLines commandLines; @@ -1272,8 +1270,8 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang) #endif for(i = includes.begin(); i != includes.end(); ++i) { -#ifdef __APPLE__ - if(cmSystemTools::IsPathToFramework(i->c_str())) + if(this->Makefile->IsOn("APPLE") + && cmSystemTools::IsPathToFramework(i->c_str())) { std::string frameworkDir = *i; frameworkDir += "/../"; @@ -1288,7 +1286,7 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang) } continue; } -#endif + std::string include = *i; if(!flagUsed || repeatFlag) { @@ -1766,12 +1764,17 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, //---------------------------------------------------------------------------- -#ifdef __APPLE__ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, cmTarget* target, const char *lang, const char* config) { + // Only add Mac OS X specific flags on Darwin platforms (OSX and iphone): + if(!this->Makefile->IsOn("APPLE")) + { + return; + } + if(this->EmitUniversalBinaryFlags) { std::vector<std::string> archs; @@ -1828,7 +1831,6 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, } } } -#endif /* __APPLE__ */ //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 489b613..43bf1e7 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -133,10 +133,8 @@ public: std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; }; -#ifdef __APPLE__ void AddArchitectureFlags(std::string& flags, cmTarget* target, const char *lang, const char* config); -#endif /* __APPLE__ */ void AddLanguageFlags(std::string& flags, const char* lang, const char* config); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index fce5a9c..004d19a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -973,6 +973,24 @@ cmLocalUnixMakefileGenerator3 this->ConfigurationName.c_str()); if (cmd.size()) { + // Use "call " before any invocations of .bat or .cmd files + // invoked as custom commands in the WindowsShell. + // + bool useCall = false; + + if (this->WindowsShell) + { + std::string suffix; + if (cmd.size() > 4) + { + suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size()-4)); + if (suffix == ".bat" || suffix == ".cmd") + { + useCall = true; + } + } + } + cmSystemTools::ReplaceString(cmd, "/./", "/"); // Convert the command to a relative path only if the current // working directory will be the start-output directory. @@ -1044,6 +1062,10 @@ cmLocalUnixMakefileGenerator3 } } } + if (useCall && launcher.empty()) + { + cmd = "call " + cmd; + } commands1.push_back(cmd); } } diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 2cf840d..539816d 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1142,6 +1142,10 @@ void cmLocalVisualStudio6Generator // Get extra linker options for this target type. std::string extraLinkOptions; + std::string extraLinkOptionsDebug; + std::string extraLinkOptionsRelease; + std::string extraLinkOptionsMinSizeRel; + std::string extraLinkOptionsRelWithDebInfo; if(target.GetType() == cmTarget::EXECUTABLE) { extraLinkOptions = @@ -1165,6 +1169,33 @@ void cmLocalVisualStudio6Generator extraLinkOptions += targetLinkFlags; } + if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_DEBUG")) + { + extraLinkOptionsDebug += " "; + extraLinkOptionsDebug += targetLinkFlags; + } + + if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_RELEASE")) + { + extraLinkOptionsRelease += " "; + extraLinkOptionsRelease += targetLinkFlags; + } + + if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_MINSIZEREL")) + { + extraLinkOptionsMinSizeRel += " "; + extraLinkOptionsMinSizeRel += targetLinkFlags; + } + + if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_RELWITHDEBINFO")) + { + extraLinkOptionsRelWithDebInfo += " "; + extraLinkOptionsRelWithDebInfo += targetLinkFlags; + } + + + + // Get standard libraries for this language. if(targetBuilds) { @@ -1259,13 +1290,21 @@ void cmLocalVisualStudio6Generator target.GetType() == cmTarget::SHARED_LIBRARY || target.GetType() == cmTarget::MODULE_LIBRARY) { - this->ComputeLinkOptions(target, "Debug", extraLinkOptions, + extraLinkOptionsDebug = + extraLinkOptions + " " + extraLinkOptionsDebug; + extraLinkOptionsRelease = + extraLinkOptions + " " + extraLinkOptionsRelease; + extraLinkOptionsMinSizeRel = + extraLinkOptions + " " + extraLinkOptionsMinSizeRel; + extraLinkOptionsRelWithDebInfo = + extraLinkOptions + " " + extraLinkOptionsRelWithDebInfo; + this->ComputeLinkOptions(target, "Debug", extraLinkOptionsDebug, optionsDebug); - this->ComputeLinkOptions(target, "Release", extraLinkOptions, + this->ComputeLinkOptions(target, "Release", extraLinkOptionsRelease, optionsRelease); - this->ComputeLinkOptions(target, "MinSizeRel", extraLinkOptions, + this->ComputeLinkOptions(target, "MinSizeRel", extraLinkOptionsMinSizeRel, optionsMinSizeRel); - this->ComputeLinkOptions(target, "RelWithDebInfo", extraLinkOptions, + this->ComputeLinkOptions(target, "RelWithDebInfo", extraLinkOptionsRelWithDebInfo, optionsRelWithDebInfo); } @@ -1342,11 +1381,43 @@ void cmLocalVisualStudio6Generator cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str()); } std::string staticLibOptions; + std::string staticLibOptionsDebug; + std::string staticLibOptionsRelease; + std::string staticLibOptionsMinSizeRel; + std::string staticLibOptionsRelWithDebInfo; if(target.GetType() == cmTarget::STATIC_LIBRARY ) { if(const char* libflags = target.GetProperty("STATIC_LIBRARY_FLAGS")) { staticLibOptions = libflags; + staticLibOptionsDebug = libflags; + staticLibOptionsRelease = libflags; + staticLibOptionsMinSizeRel = libflags; + staticLibOptionsRelWithDebInfo = libflags; + } + if(const char* libflagsDebug = + target.GetProperty("STATIC_LIBRARY_FLAGS_DEBUG")) + { + staticLibOptionsDebug += " "; + staticLibOptionsDebug = libflagsDebug; + } + if(const char* libflagsRelease = + target.GetProperty("STATIC_LIBRARY_FLAGS_RELEASE")) + { + staticLibOptionsRelease += " "; + staticLibOptionsRelease = libflagsRelease; + } + if(const char* libflagsMinSizeRel = + target.GetProperty("STATIC_LIBRARY_FLAGS_MINSIZEREL")) + { + staticLibOptionsMinSizeRel += " "; + staticLibOptionsMinSizeRel = libflagsMinSizeRel; + } + if(const char* libflagsRelWithDebInfo = + target.GetProperty("STATIC_LIBRARY_FLAGS_RELWITHDEBINFO")) + { + staticLibOptionsRelWithDebInfo += " "; + staticLibOptionsRelWithDebInfo = libflagsRelWithDebInfo; } } @@ -1378,6 +1449,14 @@ void cmLocalVisualStudio6Generator mfcFlag); if(target.GetType() == cmTarget::STATIC_LIBRARY ) { + cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG", + staticLibOptionsDebug.c_str()); + cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELEASE", + staticLibOptionsRelease.c_str()); + cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_MINSIZEREL", + staticLibOptionsMinSizeRel.c_str()); + cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELWITHDEBINFO", + staticLibOptionsRelWithDebInfo.c_str()); cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS", staticLibOptions.c_str()); } @@ -1420,7 +1499,7 @@ void cmLocalVisualStudio6Generator outputNameDebug.c_str()); cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELEASE", outputNameRelease.c_str()); - cmSystemTools::ReplaceString(line, "OUTPUT_NAME_MINSIZEREL", + cmSystemTools::ReplaceString(line, "OUTPUT_NAME_MINSIZEREL", outputNameMinSizeRel.c_str()); cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELWITHDEBINFO", outputNameRelWithDebInfo.c_str()); @@ -1431,7 +1510,7 @@ void cmLocalVisualStudio6Generator optionsDebug.c_str()); cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELEASE", optionsRelease.c_str()); - cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_MINSIZEREL", + cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_MINSIZEREL", optionsMinSizeRel.c_str()); cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELWITHDEBINFO", optionsRelWithDebInfo.c_str()); @@ -1519,41 +1598,18 @@ void cmLocalVisualStudio6Generator std::string flagVar = baseFlagVar + "_RELEASE"; flagsRelease = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" "; - if(const char* targetLinkFlags = - target.GetProperty("LINK_FLAGS_RELEASE")) - { - flagsRelease += targetLinkFlags; - flagsRelease += " "; - } + flagVar = baseFlagVar + "_MINSIZEREL"; flagsMinSize = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsMinSize += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" "; - if(const char* targetLinkFlags = - target.GetProperty("LINK_FLAGS_MINSIZEREL")) - { - flagsMinSize += targetLinkFlags; - flagsMinSize += " "; - } - + flagVar = baseFlagVar + "_DEBUG"; flagsDebug = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" "; - if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_DEBUG")) - { - flagsDebug += targetLinkFlags; - flagsDebug += " "; - } flagVar = baseFlagVar + "_RELWITHDEBINFO"; flagsDebugRel = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsDebugRel += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; - if(const char* targetLinkFlags = - target.GetProperty("LINK_FLAGS_RELWITHDEBINFO")) - { - flagsDebugRel += targetLinkFlags; - flagsDebugRel += " "; - } - } // if unicode is not found, then add -D_MBCS @@ -1619,7 +1675,7 @@ void cmLocalVisualStudio6Generator // There are not separate CXX and C template files, so we use the same // variable names. The previous code sets up flags* variables to contain // the correct C or CXX flags - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", flagsMinSize.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", flagsDebug.c_str()); @@ -1629,7 +1685,7 @@ void cmLocalVisualStudio6Generator flagsRelease.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZE", + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL", minsizeDefines.c_str()); cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG", debugDefines.c_str()); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 1af0d1d..136c177 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -236,7 +236,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() { std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash(); stampName += "generate.stamp"; - const char* dsprule = + const char* dsprule = this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"); cmCustomCommandLine commandLine; commandLine.push_back(dsprule); @@ -261,7 +261,9 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() START_OUTPUT, UNCHANGED, true); commandLine.push_back(args); commandLine.push_back("--check-stamp-file"); - commandLine.push_back(stampName.c_str()); + std::string stampFilename = this->Convert(stampName.c_str(), FULL, + SHELL); + commandLine.push_back(stampFilename.c_str()); std::vector<std::string> const& listFiles = this->Makefile->GetListFiles(); @@ -913,7 +915,20 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } fout << "\t\t\t<Tool\n" << "\t\t\t\tName=\"" << tool << "\"\n"; - if(const char* libflags = target.GetProperty("STATIC_LIBRARY_FLAGS")) + + std::string libflags; + if(const char* flags = target.GetProperty("STATIC_LIBRARY_FLAGS")) + { + libflags += flags; + } + std::string libFlagsConfig = "STATIC_LIBRARY_FLAGS_"; + libFlagsConfig += configTypeUpper; + if(const char* flagsConfig = target.GetProperty(libFlagsConfig.c_str())) + { + libflags += " "; + libflags += flagsConfig; + } + if(!libflags.empty()) { fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n"; } @@ -978,7 +993,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, temp = target.GetDirectory(configName); temp += "/"; temp += targetNamePDB; - fout << "\t\t\t\tProgramDataBaseFile=\"" << + fout << "\t\t\t\tProgramDatabaseFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; if(isDebug) { @@ -1053,7 +1068,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( target.GetDirectory(configName).c_str()); - fout << "\t\t\t\tProgramDataBaseFile=\"" + fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; if(isDebug) diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 83d8dec..ed0b07f 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -169,7 +169,7 @@ cmLocalVisualStudioGenerator script += newline; newline = newline_text; script += "cd "; - script += this->Convert(workingDirectory, START_OUTPUT, SHELL); + script += this->Convert(workingDirectory, FULL, SHELL); // Change the working drive. if(workingDirectory[0] && workingDirectory[1] == ':') @@ -230,7 +230,15 @@ cmLocalVisualStudioGenerator escapeAllowMakeVars); } } + + // After each custom command, check for an error result. + // If there was an error, jump to the VCReportError label, + // skipping the run of any subsequent commands in this + // sequence. + // + script += newline_text; + script += "if errorlevel 1 goto VCReportError"; } + return script; } - diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index d09188a..8eece6b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -124,7 +124,6 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->LocalGenerator = mf.LocalGenerator; this->FunctionBlockers = mf.FunctionBlockers; - this->DataMap = mf.DataMap; this->MacrosMap = mf.MacrosMap; this->SubDirectoryOrder = mf.SubDirectoryOrder; this->Properties = mf.Properties; @@ -200,14 +199,6 @@ cmMakefile::~cmMakefile() { delete this->UsedCommands[i]; } - for(DataMapType::const_iterator d = this->DataMap.begin(); - d != this->DataMap.end(); ++d) - { - if(d->second) - { - delete d->second; - } - } std::vector<cmFunctionBlocker*>::iterator pos; for (pos = this->FunctionBlockers.begin(); pos != this->FunctionBlockers.end(); ++pos) @@ -2368,11 +2359,9 @@ void cmMakefile::AddDefaultDefinitions() this->AddDefinition("CMAKE_MAJOR_VERSION", temp); sprintf(temp, "%d", cmVersion::GetPatchVersion()); this->AddDefinition("CMAKE_PATCH_VERSION", temp); - sprintf(temp, "%u.%u.%u", - cmVersion::GetMajorVersion(), - cmVersion::GetMinorVersion(), - cmVersion::GetPatchVersion()); - this->AddDefinition("CMAKE_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetTweakVersion()); + this->AddDefinition("CMAKE_TWEAK_VERSION", temp); + this->AddDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion()); this->AddDefinition("CMAKE_FILES_DIRECTORY", cmake::GetCMakeFilesDirectory()); @@ -2593,54 +2582,6 @@ void cmMakefile::SetHomeOutputDirectory(const char* lib) } } - -/** - * Register the given cmData instance with its own name. - */ -void cmMakefile::RegisterData(cmData* data) -{ - std::string name = data->GetName(); - DataMapType::const_iterator d = this->DataMap.find(name); - if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data)) - { - delete d->second; - } - this->DataMap[name] = data; -} - - -/** - * Register the given cmData instance with the given name. This can be used - * to register a NULL pointer. - */ -void cmMakefile::RegisterData(const char* name, cmData* data) -{ - DataMapType::const_iterator d = this->DataMap.find(name); - if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data)) - { - delete d->second; - } - this->DataMap[name] = data; -} - - -/** - * Lookup a cmData instance previously registered with the given name. If - * the instance cannot be found, return NULL. - */ -cmData* cmMakefile::LookupData(const char* name) const -{ - DataMapType::const_iterator d = this->DataMap.find(name); - if(d != this->DataMap.end()) - { - return d->second; - } - else - { - return 0; - } -} - //---------------------------------------------------------------------------- cmSourceFile* cmMakefile::GetSource(const char* sourceName) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 63f81b8..4fae7ee 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -13,7 +13,6 @@ #define cmMakefile_h #include "cmCacheManager.h" -#include "cmData.h" #include "cmExecutionStatus.h" #include "cmListFileCache.h" #include "cmPolicies.h" @@ -692,10 +691,6 @@ public: std::vector<cmSourceGroup> &groups); #endif - void RegisterData(cmData*); - void RegisterData(const char*, cmData*); - cmData* LookupData(const char*) const; - /** * Execute a single CMake command. Returns true if the command * succeeded or false if it failed. @@ -916,9 +911,6 @@ private: void PushFunctionBlockerBarrier(); void PopFunctionBlockerBarrier(bool reportError = true); - typedef std::map<cmStdString, cmData*> DataMapType; - DataMapType DataMap; - typedef std::map<cmStdString, cmStdString> StringStringMap; StringStringMap MacrosMap; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index e7c4a7d..93c981a 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -229,10 +229,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Add language feature flags. this->AddFeatureFlags(flags, linkLanguage); -#ifdef __APPLE__ this->LocalGenerator->AddArchitectureFlags(flags, this->Target, linkLanguage, this->ConfigName); -#endif /* __APPLE__ */ // Add target-specific linker flags. this->LocalGenerator->AppendFlags diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index f351174..dff91fe 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -122,6 +122,10 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() std::string extraFlags; this->LocalGenerator->AppendFlags (extraFlags,this->Target->GetProperty("STATIC_LIBRARY_FLAGS")); + std::string staticLibraryFlagsConfig = "STATIC_LIBRARY_FLAGS_"; + staticLibraryFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); + this->LocalGenerator->AppendFlags + (extraFlags, this->Target->GetProperty(staticLibraryFlagsConfig.c_str())); this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), false); } @@ -682,10 +686,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string langFlags; this->AddFeatureFlags(langFlags, linkLanguage); -#ifdef __APPLE__ this->LocalGenerator->AddArchitectureFlags(langFlags, this->Target, linkLanguage, this->ConfigName); -#endif /* __APPLE__ */ // remove any language flags that might not work with the // particular os diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index eae7101..4c4dbc1 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -294,10 +294,8 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() // Add language feature flags. this->AddFeatureFlags(flags, lang); -#ifdef __APPLE__ this->LocalGenerator->AddArchitectureFlags(flags, this->Target, lang, this->ConfigName); -#endif /* __APPLE__ */ // Fortran-specific flags computed for this target. if(*l == "Fortran") @@ -1439,11 +1437,15 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output, //---------------------------------------------------------------------------- std::string cmMakefileTargetGenerator::GetFrameworkFlags() { -#ifndef __APPLE__ - return std::string(); -#else - std::set<cmStdString> emitted; + if(!this->Makefile->IsOn("APPLE")) + { + return std::string(); + } + + std::set<cmStdString> emitted; +#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */ emitted.insert("/System/Library/Frameworks"); +#endif std::vector<std::string> includes; this->LocalGenerator->GetIncludeDirectories(includes); std::vector<std::string>::iterator i; @@ -1475,7 +1477,6 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() } } return flags; -#endif } //---------------------------------------------------------------------------- diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 2d41d40..69d3e51 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -3,6 +3,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmVersion.h" +#include "cmVersionMacros.h" #include <map> #include <set> #include <queue> @@ -22,6 +23,7 @@ public: unsigned int majorVersionIntroduced, unsigned int minorVersionIntroduced, unsigned int patchVersionIntroduced, + unsigned int tweakVersionIntroduced, cmPolicies::PolicyStatus status) { if (!idString || !shortDescription || ! longDescription) @@ -37,21 +39,26 @@ public: this->MajorVersionIntroduced = majorVersionIntroduced; this->MinorVersionIntroduced = minorVersionIntroduced; this->PatchVersionIntroduced = patchVersionIntroduced; + this->TweakVersionIntroduced = tweakVersionIntroduced; this->Status = status; } std::string GetVersionString() { - cmOStringStream error; - error << this->MajorVersionIntroduced << "." << - this->MinorVersionIntroduced << "." << - this->PatchVersionIntroduced; - return error.str(); + cmOStringStream v; + v << this->MajorVersionIntroduced << "." << this->MinorVersionIntroduced; + v << "." << this->PatchVersionIntroduced; + if(this->TweakVersionIntroduced > 0) + { + v << "." << this->TweakVersionIntroduced; + } + return v.str(); } bool IsPolicyNewerThan(unsigned int majorV, unsigned int minorV, - unsigned int patchV) + unsigned int patchV, + unsigned int tweakV) { if (majorV < this->MajorVersionIntroduced) { @@ -69,7 +76,15 @@ public: { return false; } - return (patchV < this->PatchVersionIntroduced); + if (patchV < this->PatchVersionIntroduced) + { + return true; + } + if (patchV > this->PatchVersionIntroduced) + { + return false; + } + return (tweakV < this->TweakVersionIntroduced); } cmPolicies::PolicyID ID; @@ -79,6 +94,7 @@ public: unsigned int MajorVersionIntroduced; unsigned int MinorVersionIntroduced; unsigned int PatchVersionIntroduced; + unsigned int TweakVersionIntroduced; cmPolicies::PolicyStatus Status; }; @@ -110,7 +126,7 @@ cmPolicies::cmPolicies() "The NEW behavior is to issue an error instead of a warning. " "An included file may set CMP0000 explicitly to affect how this " "policy is enforced for the main CMakeLists.txt file.", - 2,6,0, cmPolicies::WARN + 2,6,0,0, cmPolicies::WARN ); this->DefinePolicy( @@ -126,7 +142,7 @@ cmPolicies::cmPolicies() "and the cmake_policy command. " "However, CMake must still check CMAKE_BACKWARDS_COMPATIBILITY for " "projects written for CMake 2.4 and below.", - 2,6,0, cmPolicies::WARN + 2,6,0,0, cmPolicies::WARN ); this->DefinePolicy( @@ -148,7 +164,7 @@ cmPolicies::cmPolicies() "Custom targets must simply have globally unique names (unless one " "uses the global property ALLOW_DUPLICATE_CUSTOM_TARGETS with a " "Makefiles generator).", - 2,6,0, cmPolicies::WARN + 2,6,0,0, cmPolicies::WARN ); this->DefinePolicy( @@ -213,7 +229,7 @@ cmPolicies::cmPolicies() "Note that the warning for this policy will be issued for at most " "one target. This avoids flooding users with messages for every " "target when setting the policy once will probably fix all targets.", - 2,6,0, cmPolicies::WARN); + 2,6,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0004, "CMP0004", @@ -229,7 +245,7 @@ cmPolicies::cmPolicies() "The setting for this policy used when checking the library names is " "that in effect when the target is created by an add_executable or " "add_library command.", - 2,6,0, cmPolicies::WARN); + 2,6,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0005, "CMP0005", @@ -250,7 +266,7 @@ cmPolicies::cmPolicies() "for all native build tools automatically. " "See documentation of the COMPILE_DEFINITIONS target property for " "limitations of the escaping implementation.", - 2,6,0, cmPolicies::WARN); + 2,6,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0006, "CMP0006", @@ -268,7 +284,7 @@ cmPolicies::cmPolicies() "DESTINATION if a BUNDLE DESTINATION is not given. " "The NEW behavior for this policy is to produce an error if a bundle " "target is installed without a BUNDLE DESTINATION.", - 2,6,0, cmPolicies::WARN); + 2,6,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0007, "CMP0007", @@ -280,7 +296,7 @@ cmPolicies::cmPolicies() "The OLD behavior for this policy is to ignore empty list elements. " "The NEW behavior for this policy is to correctly count empty " "elements in a list. ", - 2,6,0, cmPolicies::WARN); + 2,6,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0008, "CMP0008", @@ -306,7 +322,7 @@ cmPolicies::cmPolicies() "path and ask the linker to search for it. " "The NEW behavior for this policy is to trust the given path and " "pass it directly to the native build tool unchanged.", - 2,6,1, cmPolicies::WARN); + 2,6,1,0, cmPolicies::WARN); this->DefinePolicy( CMP0009, "CMP0009", @@ -322,7 +338,7 @@ cmPolicies::cmPolicies() "The NEW behavior for this policy is not to follow the symlinks " "by default, but only if FOLLOW_SYMLINKS is given as an additional " "argument to the FILE command.", - 2,6,2, cmPolicies::WARN); + 2,6,2,0, cmPolicies::WARN); this->DefinePolicy( CMP0010, "CMP0010", @@ -334,7 +350,7 @@ cmPolicies::cmPolicies() "The OLD behavior for this policy is to warn about the error, leave " "the string untouched, and continue. " "The NEW behavior for this policy is to report an error.", - 2,6,3, cmPolicies::WARN); + 2,6,3,0, cmPolicies::WARN); this->DefinePolicy( CMP0011, "CMP0011", @@ -354,7 +370,7 @@ cmPolicies::cmPolicies() "include() and find_package() commands. " "The NEW behavior for this policy is to allow the commands to do their " "default cmake_policy PUSH and POP.", - 2,6,3, cmPolicies::WARN); + 2,6,3,0, cmPolicies::WARN); this->DefinePolicy( CMP0012, "CMP0012", @@ -376,7 +392,7 @@ cmPolicies::cmPolicies() "named like numbers and boolean constants. " "The NEW behavior for this policy is to recognize numbers and " "boolean constants without dereferencing variables with such names.", - 2,8,0, cmPolicies::WARN); + 2,8,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0013, "CMP0013", @@ -393,7 +409,7 @@ cmPolicies::cmPolicies() "directories. " "The NEW behavior for this policy is to disallow duplicate binary " "directories with an error.", - 2,8,0, cmPolicies::WARN); + 2,8,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0014, "CMP0014", @@ -405,7 +421,7 @@ cmPolicies::cmPolicies() "the case is an error. " "The OLD behavior for this policy is to silently ignore the problem. " "The NEW behavior for this policy is to report an error.", - 2,8,0, cmPolicies::WARN); + 2,8,0,0, cmPolicies::WARN); this->DefinePolicy( CMP0015, "CMP0015", @@ -420,7 +436,7 @@ cmPolicies::cmPolicies() "The NEW behavior for this policy is to convert relative paths to " "absolute paths by appending the relative path to " "CMAKE_CURRENT_SOURCE_DIR.", - 2,8,1, cmPolicies::WARN); + 2,8,1,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() @@ -441,6 +457,7 @@ void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD, unsigned int majorVersionIntroduced, unsigned int minorVersionIntroduced, unsigned int patchVersionIntroduced, + unsigned int tweakVersionIntroduced, cmPolicies::PolicyStatus status) { // a policy must be unique and can only be defined once @@ -457,6 +474,7 @@ void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD, majorVersionIntroduced, minorVersionIntroduced, patchVersionIntroduced, + tweakVersionIntroduced, status); this->PolicyStringMap[idString] = iD; } @@ -475,14 +493,15 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, unsigned int majorVer = 2; unsigned int minorVer = 0; unsigned int patchVer = 0; + unsigned int tweakVer = 0; // parse the string - if(sscanf(ver.c_str(), "%u.%u.%u", - &majorVer, &minorVer, &patchVer) < 2) + if(sscanf(ver.c_str(), "%u.%u.%u.%u", + &majorVer, &minorVer, &patchVer, &tweakVer) < 2) { cmOStringStream e; e << "Invalid policy version value \"" << ver << "\". " - << "A numeric major.minor[.patch] must be given."; + << "A numeric major.minor[.patch[.tweak]] must be given."; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -510,7 +529,11 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, minorVer > cmVersion::GetMinorVersion()) || (majorVer == cmVersion::GetMajorVersion() && minorVer == cmVersion::GetMinorVersion() && - patchVer > cmVersion::GetPatchVersion())) + patchVer > cmVersion::GetPatchVersion()) || + (majorVer == cmVersion::GetMajorVersion() && + minorVer == cmVersion::GetMinorVersion() && + patchVer == cmVersion::GetPatchVersion() && + tweakVer > cmVersion::GetTweakVersion())) { cmOStringStream e; e << "An attempt was made to set the policy version of CMake to \"" @@ -528,7 +551,7 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, = this->Policies.begin(); for (;i != this->Policies.end(); ++i) { - if (i->second->IsPolicyNewerThan(majorVer,minorVer,patchVer)) + if (i->second->IsPolicyNewerThan(majorVer,minorVer,patchVer,tweakVer)) { if(i->second->Status == cmPolicies::REQUIRED_ALWAYS) { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index aaa3ac0..23064dc 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -72,6 +72,7 @@ public: unsigned int majorVersionIntroduced, unsigned int minorVersionIntroduced, unsigned int patchVersionIntroduced, + unsigned int tweakVersionIntroduced, cmPolicies::PolicyStatus status); ///! Set a policy level for this listfile diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 3704d6a..bc52d7f 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -404,7 +404,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "The VS6 IDE does not support definition values with spaces " "(but NMake does). Xcode does not support per-configuration " "definitions on source files.\n" - "Dislaimer: Most native build tools have poor support for escaping " + "Disclaimer: Most native build tools have poor support for escaping " "certain values. CMake has work-arounds for many cases but some " "values may just not be possible to pass correctly. If a value " "does not seem to be escaped correctly, do not attempt to " @@ -433,7 +433,7 @@ void cmSourceFile::DefineProperties(cmake *cm) ("GENERATED", cmProperty::SOURCE_FILE, "Is this source file generated as part of the build process.", "If a source file is generated by the build process CMake will " - "handle it differently in temrs of dependency checking etc. " + "handle it differently in terms of dependency checking etc. " "Otherwise having a non-existent source file could create problems."); cm->DefineProperty @@ -487,7 +487,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "For frameworks the content folder is " "\"<name>.framework/Versions/<version>\". " "See the PUBLIC_HEADER, PRIVATE_HEADER, and RESOURCE target " - "properties for specifying files meant for Headers, PrivateHeadres, " + "properties for specifying files meant for Headers, PrivateHeaders, " "or Resources directories."); cm->DefineProperty diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 5db0200..9b9cb3b 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -45,6 +45,7 @@ // This is a hack to prevent warnings about these functions being // declared but not referenced. #if defined(__sgi) && !defined(__GNUC__) +# pragma set woff 3970 /* conversion from pointer to same-sized */ # include <sys/termios.h> class cmStandardIncludesHack { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index d176987..5f7cfa3 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2048,12 +2048,13 @@ bool extract_tar(const char* outFileName, bool verbose, if (verbose && extract) { cmSystemTools::Stdout("x "); + cmSystemTools::Stdout(archive_entry_pathname(entry)); } if(verbose && !extract) { list_item_verbose(stdout, entry); } - else + else if(!extract) { cmSystemTools::Stdout(archive_entry_pathname(entry)); } @@ -2937,3 +2938,18 @@ bool cmSystemTools::CheckRPath(std::string const& file, return false; #endif } + +//---------------------------------------------------------------------------- +bool cmSystemTools::RepeatedRemoveDirectory(const char* dir) +{ + // Windows sometimes locks files temporarily so try a few times. + for(int i = 0; i < 10; ++i) + { + if(cmSystemTools::RemoveADirectory(dir)) + { + return true; + } + cmSystemTools::Delay(100); + } + return false; +} diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index ed924dd..da5da31 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -436,6 +436,9 @@ public: static bool CheckRPath(std::string const& file, std::string const& newRPath); + /** Remove a directory; repeat a few times in case of locked files. */ + static bool RepeatedRemoveDirectory(const char* dir); + private: static bool s_ForceUnixPaths; static bool s_RunCommandHideConsole; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0436bd0..45ba358 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -202,7 +202,7 @@ void cmTarget::DefineProperties(cmake *cm) cm->DefineProperty ("HAS_CXX", cmProperty::TARGET, - "Link the target using the C++ linker tool (obselete).", + "Link the target using the C++ linker tool (obsolete).", "This is equivalent to setting the LINKER_LANGUAGE property to CXX. " "See that property's documentation for details."); @@ -708,6 +708,11 @@ void cmTarget::DefineProperties(cmake *cm) "Extra flags to use when linking a static library."); cm->DefineProperty + ("STATIC_LIBRARY_FLAGS_<CONFIG>", cmProperty::TARGET, + "Per-configuration flags for creating a static library.", + "This is the configuration-specific version of STATIC_LIBRARY_FLAGS."); + + cm->DefineProperty ("SUFFIX", cmProperty::TARGET, "What comes after the library name.", "A target property that can be set to override the suffix " diff --git a/Source/cmVersion.cxx b/Source/cmVersion.cxx index bde5f98..047d24d 100644 --- a/Source/cmVersion.cxx +++ b/Source/cmVersion.cxx @@ -16,8 +16,9 @@ unsigned int cmVersion::GetMajorVersion() { return CMake_VERSION_MAJOR; } unsigned int cmVersion::GetMinorVersion() { return CMake_VERSION_MINOR; } unsigned int cmVersion::GetPatchVersion() { return CMake_VERSION_PATCH; } +unsigned int cmVersion::GetTweakVersion() { return CMake_VERSION_TWEAK; } const char* cmVersion::GetCMakeVersion() { - return CMake_VERSION_FULL CMake_VERSION_RC_SUFFIX; + return CMake_VERSION; } diff --git a/Source/cmVersion.h b/Source/cmVersion.h index f267ab6..e313524 100644 --- a/Source/cmVersion.h +++ b/Source/cmVersion.h @@ -28,6 +28,7 @@ public: static unsigned int GetMajorVersion(); static unsigned int GetMinorVersion(); static unsigned int GetPatchVersion(); + static unsigned int GetTweakVersion(); static const char* GetCMakeVersion(); }; diff --git a/Source/cmVersionConfig.h.in b/Source/cmVersionConfig.h.in index ee6eca7..76bc8fe 100644 --- a/Source/cmVersionConfig.h.in +++ b/Source/cmVersionConfig.h.in @@ -12,4 +12,5 @@ #define CMake_VERSION_MAJOR @CMake_VERSION_MAJOR@ #define CMake_VERSION_MINOR @CMake_VERSION_MINOR@ #define CMake_VERSION_PATCH @CMake_VERSION_PATCH@ -#cmakedefine CMake_VERSION_RC @CMake_VERSION_RC@ +#define CMake_VERSION_TWEAK @CMake_VERSION_TWEAK@ +#define CMake_VERSION "@CMake_VERSION@" diff --git a/Source/cmVersionMacros.h b/Source/cmVersionMacros.h index 412db6d..67f58ca 100644 --- a/Source/cmVersionMacros.h +++ b/Source/cmVersionMacros.h @@ -14,22 +14,9 @@ #include "cmVersionConfig.h" -#define CMAKE_TO_STRING(x) CMAKE_TO_STRING0(x) -#define CMAKE_TO_STRING0(x) #x - -#define CMake_VERSION \ - CMAKE_TO_STRING(CMake_VERSION_MAJOR) "." \ - CMAKE_TO_STRING(CMake_VERSION_MINOR) - -#define CMake_VERSION_FULL \ - CMAKE_TO_STRING(CMake_VERSION_MAJOR) "." \ - CMAKE_TO_STRING(CMake_VERSION_MINOR) "." \ - CMAKE_TO_STRING(CMake_VERSION_PATCH) - -#if !(CMake_VERSION_MINOR & 1) && defined(CMake_VERSION_RC) -# define CMake_VERSION_RC_SUFFIX "-rc" CMAKE_TO_STRING(CMake_VERSION_RC) -#else -# define CMake_VERSION_RC_SUFFIX "" +#define CMake_VERSION_TWEAK_IS_RELEASE(tweak) ((tweak) < 20000000) +#if CMake_VERSION_TWEAK_IS_RELEASE(CMake_VERSION_TWEAK) +# define CMake_VERSION_IS_RELEASE 1 #endif #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 4a8e161..53d6594 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -441,6 +441,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() path += this->Name; path += ".vcxproj.filters"; cmGeneratedFileStream fout(path.c_str()); + fout.SetCopyIfDifferent(true); char magic[] = {0xEF,0xBB, 0xBF}; fout.write(magic, 3); cmGeneratedFileStream* save = this->BuildFileStream; @@ -484,9 +485,14 @@ void cmVisualStudio10TargetGenerator::WriteGroups() this->WriteString("</Project>\n", 0); // restore stream pointer this->BuildFileStream = save; + + if (fout.Close()) + { + this->GlobalGenerator->FileReplacedDuringGenerate(path); + } } -void +void cmVisualStudio10TargetGenerator:: WriteGroupSources(const char* name, std::vector<cmSourceFile*> const& sources, @@ -854,6 +860,13 @@ OutputLinkIncremental(std::string const& configName) flags += " "; flags += targetLinkFlags; } + std::string flagsProp = "LINK_FLAGS_"; + flagsProp += CONFIG; + if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str())) + { + flags += " "; + flags += flagsConfig; + } if(flags.find("INCREMENTAL:NO") != flags.npos) { incremental = "false"; @@ -1010,22 +1023,27 @@ WriteRCOptions(std::string const& , } -void cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& - ) +void +cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config) { if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) { return; } - if(const char* libflags = this->Target - ->GetProperty("STATIC_LIBRARY_FLAGS")) + const char* libflags = this->Target->GetProperty("STATIC_LIBRARY_FLAGS"); + std::string flagsConfigVar = "STATIC_LIBRARY_FLAGS_"; + flagsConfigVar += cmSystemTools::UpperCase(config); + const char* libflagsConfig = + this->Target->GetProperty(flagsConfigVar.c_str()); + if(libflags || libflagsConfig) { this->WriteString("<Lib>\n", 2); cmVisualStudioGeneratorOptions libOptions(this->LocalGenerator, 10, cmVisualStudioGeneratorOptions::Linker, cmVS10LibFlagTable, 0, this); - libOptions.Parse(libflags); + libOptions.Parse(libflags?libflags:""); + libOptions.Parse(libflagsConfig?libflagsConfig:""); libOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); libOptions.OutputFlagMap(*this->BuildFileStream, " "); this->WriteString("</Lib>\n", 2); @@ -1093,6 +1111,13 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& flags += " "; flags += targetLinkFlags; } + std::string flagsProp = "LINK_FLAGS_"; + flagsProp += CONFIG; + if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str())) + { + flags += " "; + flags += flagsConfig; + } cmVisualStudioGeneratorOptions linkOptions(this->LocalGenerator, 10, cmVisualStudioGeneratorOptions::Linker, diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx index c8b4ae4..d9bd26c 100644 --- a/Source/cmWin32ProcessExecution.cxx +++ b/Source/cmWin32ProcessExecution.cxx @@ -22,7 +22,8 @@ #if defined(__BORLANDC__) # define STRICMP stricmp # define TO_INTPTR(x) ((long)(x)) -#else // Visual studio +#endif // Borland +#if defined(_MSC_VER) // Visual studio # if ( _MSC_VER >= 1300 ) # include <stddef.h> # define TO_INTPTR(x) ((intptr_t)(x)) @@ -30,7 +31,12 @@ # define TO_INTPTR(x) ((long)(x)) # endif // Visual studio .NET # define STRICMP _stricmp -#endif // Borland +#endif // Visual Studio +#if defined(__MINGW32__) +# include <stdint.h> +# define TO_INTPTR(x) ((intptr_t)(x)) +# define STRICMP _stricmp +#endif // MinGW #define POPEN_1 1 #define POPEN_2 2 diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index f46b87f..b2acb2b 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -54,24 +54,18 @@ bool cmWriteFileCommand std::string dir = cmSystemTools::GetFilenamePath(fileName); cmSystemTools::MakeDirectory(dir.c_str()); - mode_t mode = -#if defined( _MSC_VER ) || defined( __MINGW32__ ) - S_IREAD | S_IWRITE -#elif defined( __BORLANDC__ ) - S_IRUSR | S_IWUSR -#else - 0666 -#endif - ; + mode_t mode = 0; // Set permissions to writable if ( cmSystemTools::GetPermissions(fileName.c_str(), mode) ) { cmSystemTools::SetPermissions(fileName.c_str(), #if defined( _MSC_VER ) || defined( __MINGW32__ ) - S_IREAD | S_IWRITE + mode | S_IWRITE +#elif defined( __BORLANDC__ ) + mode | S_IWUSR #else - 0666 + mode | S_IWUSR | S_IWGRP #endif ); } @@ -89,7 +83,10 @@ bool cmWriteFileCommand } file << message << std::endl; file.close(); - cmSystemTools::SetPermissions(fileName.c_str(), mode); + if(mode) + { + cmSystemTools::SetPermissions(fileName.c_str(), mode); + } return true; } diff --git a/Source/ctest.cxx b/Source/ctest.cxx index c9b875d..24921c4 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -218,6 +218,10 @@ static const char * cmDocumentationOptions[][3] = {"--timeout <seconds>", "Set a global timeout on all tests.", "This option will set a global timeout on all tests that do not already " "have a timeout set on them."}, + {"--stop-time <time>", "Set a time at which all tests should stop running.", + "Set a real time of day at which all tests should timeout. Example: " + "7:00:00 -0400. Any time format understood by the curl date parser is " + "accepted. Local time is assumed if no timezone is specified."}, {"--http1.0", "Submit using HTTP 1.0.", "This option will force CTest to use HTTP 1.0 to submit files to the " "dashboard, instead of HTTP 1.1."}, diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 62042e8..f440ff9 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -309,6 +309,14 @@ IF(NOT KWSYS_IN_SOURCE_BUILD) ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPY_ONLY IMMEDIATE) ENDIF(NOT KWSYS_IN_SOURCE_BUILD) +# Select plugin module file name convention. +IF(NOT KWSYS_DynamicLoader_PREFIX) + SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX}) +ENDIF() +IF(NOT KWSYS_DynamicLoader_SUFFIX) + SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX}) +ENDIF() + #----------------------------------------------------------------------------- # We require ANSI support from the C compiler. Add any needed flags. IF(CMAKE_ANSI_CFLAGS) diff --git a/Source/kwsys/Configure.h.in b/Source/kwsys/Configure.h.in index 97b2c5d..15986cf 100644 --- a/Source/kwsys/Configure.h.in +++ b/Source/kwsys/Configure.h.in @@ -28,6 +28,10 @@ # if defined(__INTEL_COMPILER) # pragma warning (disable: 1572) /* floating-point equality test */ # endif +# if defined(__sgi) && !defined(__GNUC__) +# pragma set woff 3970 /* pointer to int conversion */ +# pragma set woff 3968 /* 64 bit conversion */ +# endif #endif /* Whether kwsys namespace is "kwsys". */ diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx index a337031..c4ee095 100644 --- a/Source/kwsys/DynamicLoader.cxx +++ b/Source/kwsys/DynamicLoader.cxx @@ -69,19 +69,6 @@ DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sy return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); } -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibPrefix() -{ - return "lib"; -} - -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibExtension() -{ - return ".sl"; -} - -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { // TODO: Need implementation with errno/strerror @@ -176,21 +163,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( } //---------------------------------------------------------------------------- -const char* DynamicLoader::LibPrefix() -{ - return "lib"; -} - -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibExtension() -{ - // NSCreateObjectFileImageFromFile fail when dealing with dylib image - // it returns NSObjectFileImageInappropriateFile - //return ".dylib"; - return ".so"; -} - -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return 0; @@ -285,22 +257,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( } //---------------------------------------------------------------------------- -const char* DynamicLoader::LibPrefix() -{ -#ifdef __MINGW32__ - return "lib"; -#else - return ""; -#endif -} - -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibExtension() -{ - return ".dll"; -} - -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { LPVOID lpMsgBuf=NULL; @@ -418,18 +374,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( } //---------------------------------------------------------------------------- -const char* DynamicLoader::LibPrefix() -{ - return "lib"; -} - -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibExtension() -{ - return ".so"; -} - -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { const char *retval = strerror(last_dynamic_err); @@ -444,7 +388,7 @@ const char* DynamicLoader::LastError() // 5. Implementation for systems without dynamic libs // __gnu_blrts__ is IBM BlueGene/L // __LIBCATAMOUNT__ is defined on Catamount on Cray compute nodes -#if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__) +#if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__) || defined(__CRAYXT_COMPUTE_LINUX_TARGET) #include <string.h> // for strerror() #define DYNAMICLOADER_DEFINED 1 @@ -476,18 +420,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( } //---------------------------------------------------------------------------- -const char* DynamicLoader::LibPrefix() - { - return "lib"; - } - -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibExtension() - { - return ".a"; - } - -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return "General error"; @@ -540,22 +472,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( } //---------------------------------------------------------------------------- -const char* DynamicLoader::LibPrefix() -{ - return "lib"; -} - -//---------------------------------------------------------------------------- -const char* DynamicLoader::LibExtension() -{ -#ifdef __CYGWIN__ - return ".dll"; -#else - return ".so"; -#endif -} - -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return dlerror(); diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in index 325e956..64468ec 100644 --- a/Source/kwsys/DynamicLoader.hxx.in +++ b/Source/kwsys/DynamicLoader.hxx.in @@ -86,11 +86,11 @@ public: /** Find the address of the symbol in the given library. */ static SymbolPointer GetSymbolAddress(LibraryHandle, const char*); - /** Return the library prefix for the given architecture */ - static const char* LibPrefix(); + /** Return the default module prefix for the current platform. */ + static const char* LibPrefix() { return "@KWSYS_DynamicLoader_PREFIX@"; } - /** Return the library extension for the given architecture. */ - static const char* LibExtension(); + /** Return the default module suffix for the current platform. */ + static const char* LibExtension() { return "@KWSYS_DynamicLoader_SUFFIX@"; } /** Return the last error produced from a calls made on this class. */ static const char* LastError(); diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index 373e906..9c66a44 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -720,6 +720,14 @@ void kwsysProcess_Execute(kwsysProcess* cp) return; } + /* Make sure we have something to run. */ + if(cp->NumberOfCommands < 1) + { + strcpy(cp->ErrorMessage, "No command"); + cp->State = kwsysProcess_State_Error; + return; + } + /* Initialize the control structure for a new process. */ if(!kwsysProcessInitialize(cp)) { @@ -2373,9 +2381,13 @@ static pid_t kwsysProcessFork(kwsysProcess* cp, Here we define the command to call on each platform and the corresponding parsing format string. The parsing format should have two integers to store: the pid and then the ppid. */ -#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) \ + || defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__) # define KWSYSPE_PS_COMMAND "ps axo pid,ppid" # define KWSYSPE_PS_FORMAT "%d %d\n" +#elif defined(__sun) && (defined(__SVR4) || defined(__svr4__)) /* Solaris */ +# define KWSYSPE_PS_COMMAND "ps -e -o pid,ppid" +# define KWSYSPE_PS_FORMAT "%d %d\n" #elif defined(__hpux) || defined(__sun__) || defined(__sgi) || defined(_AIX) \ || defined(__sparc) # define KWSYSPE_PS_COMMAND "ps -ef" diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index c5ea6db..5aa4d8b 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -987,6 +987,14 @@ void kwsysProcess_Execute(kwsysProcess* cp) return; } + /* Make sure we have something to run. */ + if(cp->NumberOfCommands < 1) + { + strcpy(cp->ErrorMessage, "No command"); + cp->State = kwsysProcess_State_Error; + return; + } + /* Initialize the control structure for a new process. */ if(!kwsysProcessInitialize(cp)) { diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in index da62d84..8521099 100644 --- a/Source/kwsys/SharedForward.h.in +++ b/Source/kwsys/SharedForward.h.in @@ -201,6 +201,12 @@ static const char kwsys_shared_forward_path_slash[2] = {KWSYS_SHARED_FORWARD_PAT # define KWSYS_SHARED_FORWARD_LDD_N 1 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" +/* OpenBSD */ +#elif defined(__OpenBSD__) +# define KWSYS_SHARED_FORWARD_LDD "ldd" +# define KWSYS_SHARED_FORWARD_LDD_N 1 +# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" + /* OSX */ #elif defined(__APPLE__) # define KWSYS_SHARED_FORWARD_LDD "otool", "-L" diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 7041d38..936c1f7 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -2395,11 +2395,13 @@ int SystemInformationImplementation::QueryMemory() #elif _WIN32 #if _MSC_VER < 1300 MEMORYSTATUS ms; + unsigned long tv, tp, av, ap; ms.dwLength = sizeof(ms); GlobalMemoryStatus(&ms); -#define MEM_VAL(value) dw##value + #define MEM_VAL(value) dw##value #else MEMORYSTATUSEX ms; + DWORDLONG tv, tp, av, ap; ms.dwLength = sizeof(ms); if (0 == GlobalMemoryStatusEx(&ms)) { @@ -2407,10 +2409,10 @@ int SystemInformationImplementation::QueryMemory() } #define MEM_VAL(value) ull##value #endif - unsigned long tv = ms.MEM_VAL(TotalVirtual); - unsigned long tp = ms.MEM_VAL(TotalPhys); - unsigned long av = ms.MEM_VAL(AvailVirtual); - unsigned long ap = ms.MEM_VAL(AvailPhys); + tv = ms.MEM_VAL(TotalVirtual); + tp = ms.MEM_VAL(TotalPhys); + av = ms.MEM_VAL(AvailVirtual); + ap = ms.MEM_VAL(AvailPhys); this->TotalVirtualMemory = tv>>10>>10; this->TotalPhysicalMemory = tp>>10>>10; this->AvailableVirtualMemory = av>>10>>10; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 1c00621..3153235 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -9,6 +9,13 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ + +#ifdef __osf__ +# define _OSF_SOURCE +# define _POSIX_C_SOURCE 199506L +# define _XOPEN_SOURCE_EXTENDED +#endif + #include "kwsysPrivate.h" #include KWSYS_HEADER(RegularExpression.hxx) #include KWSYS_HEADER(SystemTools.hxx) @@ -1715,8 +1722,7 @@ kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path) } bool SystemTools::CopyFileIfDifferent(const char* source, - const char* destination, - bool copyPermissions) + const char* destination) { // special check for a destination that is a directory // FilesDiffer does not handle file to directory compare @@ -1729,8 +1735,7 @@ bool SystemTools::CopyFileIfDifferent(const char* source, new_destination += SystemTools::GetFilenameName(source_name); if(SystemTools::FilesDiffer(source, new_destination.c_str())) { - return SystemTools::CopyFileAlways(source, destination, - copyPermissions); + return SystemTools::CopyFileAlways(source, destination); } else { @@ -1743,7 +1748,7 @@ bool SystemTools::CopyFileIfDifferent(const char* source, // are different if(SystemTools::FilesDiffer(source, destination)) { - return SystemTools::CopyFileAlways(source, destination, copyPermissions); + return SystemTools::CopyFileAlways(source, destination); } // at this point the files must be the same so return true return true; @@ -1829,8 +1834,7 @@ bool SystemTools::FilesDiffer(const char* source, /** * Copy a file named by "source" to the file named by "destination". */ -bool SystemTools::CopyFileAlways(const char* source, const char* destination, - bool copyPermissions) +bool SystemTools::CopyFileAlways(const char* source, const char* destination) { // If files are the same do not copy if ( SystemTools::SameFile(source, destination) ) @@ -1917,23 +1921,11 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination, fin.close(); fout.close(); - // More checks. - struct stat statSource, statDestination; - statSource.st_size = 12345; - statDestination.st_size = 12345; - if(stat(source, &statSource) != 0) - { - return false; - } - else if(stat(destination, &statDestination) != 0) + if(!fout) { return false; } - else if(statSource.st_size != statDestination.st_size) - { - return false; - } - if ( copyPermissions && perms ) + if ( perms ) { if ( !SystemTools::SetPermissions(destination, perm) ) { @@ -1945,15 +1937,15 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination, //---------------------------------------------------------------------------- bool SystemTools::CopyAFile(const char* source, const char* destination, - bool always, bool copyPermissions) + bool always) { if(always) { - return SystemTools::CopyFileAlways(source, destination, copyPermissions); + return SystemTools::CopyFileAlways(source, destination); } else { - return SystemTools::CopyFileIfDifferent(source, destination, copyPermissions); + return SystemTools::CopyFileIfDifferent(source, destination); } } @@ -1962,7 +1954,7 @@ bool SystemTools::CopyAFile(const char* source, const char* destination, * "destination". */ bool SystemTools::CopyADirectory(const char* source, const char* destination, - bool always, bool copyPermissions) + bool always) { Directory dir; dir.Load(source); @@ -1986,16 +1978,14 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination, fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum)); if (!SystemTools::CopyADirectory(fullPath.c_str(), fullDestPath.c_str(), - always, - copyPermissions)) + always)) { return false; } } else { - if(!SystemTools::CopyAFile(fullPath.c_str(), destination, always, - copyPermissions)) + if(!SystemTools::CopyAFile(fullPath.c_str(), destination, always)) { return false; } @@ -3065,38 +3055,35 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot return relativePath; } -// OK, some fun stuff to get the actual case of a given path. -// Basically, you just need to call ShortPath, then GetLongPathName, -// However, GetLongPathName is not implemented on windows NT and 95, -// so we have to simulate it on those versions #ifdef _WIN32 -int OldWindowsGetLongPath(kwsys_stl::string const& shortPath, - kwsys_stl::string& longPath ) +static int GetCasePathName(const kwsys_stl::string & pathIn, + kwsys_stl::string & casePath) { - kwsys_stl::string::size_type iFound = shortPath.rfind('/'); - if (iFound > 1 && iFound != shortPath.npos) + kwsys_stl::string::size_type iFound = pathIn.rfind('/'); + if (iFound > 1 && iFound != pathIn.npos) { // recurse to peel off components // - if (OldWindowsGetLongPath(shortPath.substr(0, iFound), longPath) > 0) + if (GetCasePathName(pathIn.substr(0, iFound), casePath) > 0) { - longPath += '/'; - if (shortPath[1] != '/') + casePath += '/'; + if (pathIn[1] != '/') { WIN32_FIND_DATA findData; // append the long component name to the path // - if (INVALID_HANDLE_VALUE != ::FindFirstFile - (shortPath.c_str(), &findData)) + HANDLE hFind = ::FindFirstFile(pathIn.c_str(), &findData); + if (INVALID_HANDLE_VALUE != hFind) { - longPath += findData.cFileName; + casePath += findData.cFileName; + ::FindClose(hFind); } else { // if FindFirstFile fails, return the error code // - longPath = ""; + casePath = ""; return 0; } } @@ -3104,37 +3091,9 @@ int OldWindowsGetLongPath(kwsys_stl::string const& shortPath, } else { - longPath = shortPath; - } - return (int)longPath.size(); -} - - -int PortableGetLongPathName(const char* pathIn, - kwsys_stl::string & longPath) -{ - HMODULE lh = LoadLibrary("Kernel32.dll"); - if(lh) - { - FARPROC proc = GetProcAddress(lh, "GetLongPathNameA"); - if(proc) - { - typedef DWORD (WINAPI * GetLongFunctionPtr) (LPCSTR,LPSTR,DWORD); - GetLongFunctionPtr func = (GetLongFunctionPtr)proc; - char buffer[MAX_PATH+1]; - int len = (*func)(pathIn, buffer, MAX_PATH+1); - if(len == 0 || len > MAX_PATH+1) - { - FreeLibrary(lh); - return 0; - } - longPath = buffer; - FreeLibrary(lh); - return len; - } - FreeLibrary(lh); + casePath = pathIn; } - return OldWindowsGetLongPath(pathIn, longPath); + return (int)casePath.size(); } #endif @@ -3153,29 +3112,19 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p) { return i->second; } - kwsys_stl::string shortPath; - if(!SystemTools::GetShortPath(p, shortPath)) - { - return p; - } - kwsys_stl::string longPath; - int len = PortableGetLongPathName(shortPath.c_str(), longPath); + kwsys_stl::string casePath; + int len = GetCasePathName(p, casePath); if(len == 0 || len > MAX_PATH+1) { return p; } - // Use original path if conversion back to a long path failed. - if(longPath == shortPath) - { - longPath = p; - } // make sure drive letter is always upper case - if(longPath.size() > 1 && longPath[1] == ':') + if(casePath.size() > 1 && casePath[1] == ':') { - longPath[0] = toupper(longPath[0]); + casePath[0] = toupper(casePath[0]); } - (*SystemTools::LongPathMap)[p] = longPath; - return longPath; + (*SystemTools::LongPathMap)[p] = casePath; + return casePath; #endif } diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index fd35742..ec70320 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -500,14 +500,10 @@ public: /** * Copy the source file to the destination file only - * if the two files differ. If the "copyPermissions" - * argument is true, the permissions of the copy are - * set to be the same as the permissions of the - * original. + * if the two files differ. */ static bool CopyFileIfDifferent(const char* source, - const char* destination, - bool copyPermissions = true); + const char* destination); /** * Compare the contents of two files. Return true if different @@ -520,22 +516,17 @@ public: static bool SameFile(const char* file1, const char* file2); /** - * Copy a file. If the "copyPermissions" argument is true, the - * permissions of the copy are set to be the same as the permissions - * of the original. + * Copy a file. */ - static bool CopyFileAlways(const char* source, const char* destination, - bool copyPermissions = true); + static bool CopyFileAlways(const char* source, const char* destination); /** * Copy a file. If the "always" argument is true the file is always * copied. If it is false, the file is copied only if it is new or - * has changed. If the "copyPermissions" argument is true, the - * permissions of the copy are set to be the same as the permissions - * of the original. + * has changed. */ static bool CopyAFile(const char* source, const char* destination, - bool always = true, bool copyPermissions = true); + bool always = true); /** * Copy content directory to another directory with all files and @@ -544,7 +535,7 @@ public: * are new are copied. */ static bool CopyADirectory(const char* source, const char* destination, - bool always = true, bool copyPermissions = true); + bool always = true); /** * Remove a file diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in index b36c975..db52fc8 100644 --- a/Source/kwsys/hashtable.hxx.in +++ b/Source/kwsys/hashtable.hxx.in @@ -38,6 +38,7 @@ # pragma warn -8027 /* 'for' not inlined. */ # pragma warn -8026 /* 'exception' not inlined. */ #endif + #ifndef @KWSYS_NAMESPACE@_hashtable_hxx #define @KWSYS_NAMESPACE@_hashtable_hxx @@ -57,6 +58,9 @@ # pragma warning (disable:4786) # pragma warning (disable:4512) /* no assignment operator for class */ #endif +#if defined(__sgi) && !defined(__GNUC__) +# pragma set woff 3970 /* pointer to int conversion */ 3321 3968 +#endif #if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE # define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator< T > @@ -388,6 +392,10 @@ struct _Hashtable_const_iterator { // Note: assumes long is at least 32 bits. enum { _stl_num_primes = 31 }; +// create a function with a static local to that function that returns +// the static +inline const unsigned long* get_stl_prime_list() { + static const unsigned long _stl_prime_list[_stl_num_primes] = { 5ul, 11ul, 23ul, @@ -399,10 +407,12 @@ static const unsigned long _stl_prime_list[_stl_num_primes] = 1610612741ul, 3221225473ul, 4294967291ul }; +return &_stl_prime_list[0]; } + inline size_t _stl_next_prime(size_t __n) { - const unsigned long* __first = _stl_prime_list; - const unsigned long* __last = _stl_prime_list + (int)_stl_num_primes; + const unsigned long* __first = get_stl_prime_list(); + const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes; const unsigned long* pos = @KWSYS_NAMESPACE@_stl::lower_bound(__first, __last, __n); return pos == __last ? *(__last - 1) : *pos; } @@ -587,7 +597,7 @@ public: size_type bucket_count() const { return _M_buckets.size(); } size_type max_bucket_count() const - { return _stl_prime_list[(int)_stl_num_primes - 1]; } + { return get_stl_prime_list()[(int)_stl_num_primes - 1]; } size_type elems_in_bucket(size_type __bucket) const { diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index 6926d2c..2ce7080 100644 --- a/Source/kwsys/kwsysDateStamp.cmake +++ b/Source/kwsys/kwsysDateStamp.cmake @@ -15,7 +15,7 @@ SET(KWSYS_DATE_STAMP_YEAR 2010) # KWSys version date month component. Format is MM. -SET(KWSYS_DATE_STAMP_MONTH 03) +SET(KWSYS_DATE_STAMP_MONTH 06) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 11) +SET(KWSYS_DATE_STAMP_DAY 15) diff --git a/Source/kwsys/testAutoPtr.cxx b/Source/kwsys/testAutoPtr.cxx index 747d869..ed75ff4 100644 --- a/Source/kwsys/testAutoPtr.cxx +++ b/Source/kwsys/testAutoPtr.cxx @@ -25,7 +25,7 @@ #define ASSERT(x,y) if (!(x)) { printf("FAIL: " y "\n"); status = 1; } -static int instances = 0; +int instances = 0; // don't declare as static struct A { |