diff options
Diffstat (limited to 'Source')
47 files changed, 477 insertions, 246 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index dc73cec..dbbb558 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -111,6 +111,7 @@ ENDIF(CMAKE_USE_ELF_PARSER) # Sources for CMakeLib # SET(SRCS + cmStandardIncludes.cxx cmBootstrapCommands.cxx cmCacheManager.cxx cmCacheManager.h diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 9c77cc1..cee24ef 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -135,7 +135,7 @@ int cmCPackDebGenerator::CompressFiles(const char* outFileName, // now add all directories which have to be compressed // collect all top level install dirs for that // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would give /usr and /opt - int topLevelLength = strlen(toplevel); + size_t topLevelLength = strlen(toplevel); std::set<std::string> installDirs; for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++ fileIt ) @@ -371,7 +371,7 @@ static const char * ar_rname(const char *path) typedef struct ar_hdr HDR; static char ar_hb[sizeof(HDR) + 1]; /* real header */ -static int ar_already_written; +static size_t ar_already_written; /* copy_ar -- * Copy size bytes from one file to another - taking care to handle the @@ -431,7 +431,7 @@ static int put_arobj(CF *cfp, struct stat *sb) /* If not truncating names and the name is too long or contains * a space, use extended format 1. */ - unsigned int lname = strlen(name); + size_t lname = strlen(name); uid_t uid = sb->st_uid; gid_t gid = sb->st_gid; if (uid > USHRT_MAX) { @@ -441,7 +441,7 @@ static int put_arobj(CF *cfp, struct stat *sb) gid = USHRT_MAX; } if (lname > sizeof(hdr->ar_name) || strchr(name, ' ')) - (void)sprintf(ar_hb, HDR1, AR_EFMT1, lname, + (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname, (long int)sb->st_mtime, uid, gid, sb->st_mode, (long long)sb->st_size + lname, ARFMAG); else { diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index ad77386..8329546 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -758,7 +758,7 @@ CreateComponentDescription(cmCPackComponent *component, } // Create the NSIS code to download this file on-the-fly. - unsigned totalSizeInKbytes = (totalSize + 512) / 1024; + unsigned long totalSizeInKbytes = (totalSize + 512) / 1024; if (totalSizeInKbytes == 0) { totalSizeInKbytes = 1; diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h index 228067e..9eb4907 100644 --- a/Source/CTest/cmCTestBuildCommand.h +++ b/Source/CTest/cmCTestBuildCommand.h @@ -60,10 +60,12 @@ public: virtual const char* GetFullDocumentation() { return - " ctest_build([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n" - " [NUMBER_ERRORS val] [NUMBER_WARNINGS val])\n" + " ctest_build([BUILD build_dir] [TARGET target] [RETURN_VALUE res]\n" + " [APPEND][NUMBER_ERRORS val] [NUMBER_WARNINGS val])\n" "Builds the given build directory and stores results in Build.xml. " - "If no BUILD is given, the CTEST_BINARY_DIRECTORY variable is used. " + "If no BUILD is given, the CTEST_BINARY_DIRECTORY variable is used.\n" + "The TARGET variable can be used to specify a build target. If none " + "is specified, the \"all\" target will be built.\n" "The RETURN_VALUE option specifies a variable in which to store the " "return value of the native build tool. " "The NUMBER_ERRORS and NUMBER_WARNINGS options specify variables in " diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index bc02fbc..3c5993d 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -65,7 +65,7 @@ static const char* cmCTestErrorMatches[] = { "^Unresolved:", "Undefined symbols:", "^Undefined[ \\t]+first referenced", - "^CMake Error:", + "^CMake Error.*:", ":[ \\t]cannot find", ":[ \\t]can't find", ": \\*\\*\\* No rule to make target \\`.*\\'. Stop", @@ -129,6 +129,7 @@ static const char* cmCTestWarningMatches[] = { "\\([0-9]*\\): remark #[0-9]*", "\".*\", line [0-9]+: remark\\([0-9]*\\):", "cc-[0-9]* CC: REMARK File = .*, Line = [0-9]*", + "^CMake Warning.*:", 0 }; @@ -174,8 +175,8 @@ cmCTestWarningErrorFileLine[] = { //---------------------------------------------------------------------- cmCTestBuildHandler::cmCTestBuildHandler() { - this->MaxPreContext = 6; - this->MaxPostContext = 6; + this->MaxPreContext = 10; + this->MaxPostContext = 10; this->MaxErrors = 50; this->MaxWarnings = 50; @@ -214,8 +215,8 @@ void cmCTestBuildHandler::Initialize() this->ErrorsAndWarnings.clear(); this->LastErrorOrWarning = this->ErrorsAndWarnings.end(); this->PostContextCount = 0; - this->MaxPreContext = 6; - this->MaxPostContext = 6; + this->MaxPreContext = 10; + this->MaxPostContext = 10; this->PreContext.clear(); this->TotalErrors = 0; @@ -249,6 +250,20 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile *mf) "CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS", this->MaxWarnings); + int n = -1; + this->CTest->PopulateCustomInteger(mf, "CTEST_CUSTOM_ERROR_PRE_CONTEXT", n); + if (n != -1) + { + this->MaxPreContext = static_cast<size_t>(n); + } + + n = -1; + this->CTest->PopulateCustomInteger(mf, "CTEST_CUSTOM_ERROR_POST_CONTEXT", n); + if (n != -1) + { + this->MaxPostContext = static_cast<size_t>(n); + } + // Record the user-specified custom warning rules. if(const char* customWarningMatchers = mf->GetDefinition("CTEST_CUSTOM_WARNING_MATCH")) @@ -959,7 +974,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingErrorQueue); cmCTestLog(this->CTest, OUTPUT, " Size of output: " - << int(this->BuildOutputLogSize / 1024.0) << "K" << std::endl); + << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl); // Properly handle output of the build command cmsysProcess_WaitForExit(cp, 0); @@ -1171,7 +1186,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, if ( tick % tick_line_len == 0 && tick > 0 ) { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Size: " - << int((this->BuildOutputLogSize / 1024.0) + 1) << "K" << std::endl + << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl << " "); } } diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 3235bfd..55a5225 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -2038,8 +2038,12 @@ std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles( for(std::vector<std::string>::iterator f = files.begin(); f != files.end(); ++f) { - extraMatches.insert(this->CTest->GetShortPathToFile( - f->c_str())); + if(this->ShouldIDoCoverage(f->c_str(), + cont->SourceDir.c_str(), cont->BinaryDir.c_str())) + { + extraMatches.insert(this->CTest->GetShortPathToFile( + f->c_str())); + } } } diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index f5ba361..a49c852 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -85,16 +85,14 @@ void cmCTestGIT::NoteNewRevision() } //---------------------------------------------------------------------------- -bool cmCTestGIT::UpdateImpl() +bool cmCTestGIT::UpdateByFetchAndReset() { 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(git); - git_pull.push_back("pull"); - - // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY) + // Use "git fetch" to get remote commits. + std::vector<char const*> git_fetch; + git_fetch.push_back(git); + git_fetch.push_back("fetch"); // Add user-specified update options. std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions"); @@ -106,22 +104,88 @@ bool cmCTestGIT::UpdateImpl() for(std::vector<cmStdString>::const_iterator ai = args.begin(); ai != args.end(); ++ai) { - git_pull.push_back(ai->c_str()); + git_fetch.push_back(ai->c_str()); } // Sentinel argument. - git_pull.push_back(0); + git_fetch.push_back(0); - OutputLogger out(this->Log, "pull-out> "); - OutputLogger err(this->Log, "pull-err> "); - if(this->RunUpdateCommand(&git_pull[0], &out, &err)) + // Fetch upstream refs. + OutputLogger fetch_out(this->Log, "fetch-out> "); + OutputLogger fetch_err(this->Log, "fetch-err> "); + if(!this->RunUpdateCommand(&git_fetch[0], &fetch_out, &fetch_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; } - return false; + + // Identify the merge head that would be used by "git pull". + std::string sha1; + { + std::string fetch_head = this->SourceDirectory + "/.git/FETCH_HEAD"; + std::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary); + std::string line; + while(sha1.empty() && cmSystemTools::GetLineFromStream(fin, line)) + { + if(line.find("\tnot-for-merge\t") == line.npos) + { + std::string::size_type pos = line.find('\t'); + if(pos != line.npos) + { + sha1 = line.substr(0, pos); + } + } + } + } + + // Reset the local branch to point at that tracked from upstream. + char const* git_reset[] = {git, "reset", "--hard", sha1.c_str(), 0}; + OutputLogger reset_out(this->Log, "reset-out> "); + OutputLogger reset_err(this->Log, "reset-err> "); + return this->RunChild(&git_reset[0], &reset_out, &reset_err); +} + +//---------------------------------------------------------------------------- +bool cmCTestGIT::UpdateByCustom(std::string const& custom) +{ + std::vector<std::string> git_custom_command; + cmSystemTools::ExpandListArgument(custom, git_custom_command, true); + std::vector<char const*> git_custom; + for(std::vector<std::string>::const_iterator + i = git_custom_command.begin(); i != git_custom_command.end(); ++i) + { + git_custom.push_back(i->c_str()); + } + git_custom.push_back(0); + + OutputLogger custom_out(this->Log, "custom-out> "); + OutputLogger custom_err(this->Log, "custom-err> "); + return this->RunUpdateCommand(&git_custom[0], &custom_out, &custom_err); +} + +//---------------------------------------------------------------------------- +bool cmCTestGIT::UpdateInternal() +{ + std::string custom = this->CTest->GetCTestConfiguration("GITUpdateCustom"); + if(!custom.empty()) + { + return this->UpdateByCustom(custom); + } + return this->UpdateByFetchAndReset(); +} + +//---------------------------------------------------------------------------- +bool cmCTestGIT::UpdateImpl() +{ + if(!this->UpdateInternal()) + { + return false; + } + + const char* git = this->CommandLineTool.c_str(); + char const* git_submodule[] = {git, "submodule", "update", 0}; + OutputLogger submodule_out(this->Log, "submodule-out> "); + OutputLogger submodule_err(this->Log, "submodule-err> "); + return this->RunChild(git_submodule, &submodule_out, &submodule_err); } //---------------------------------------------------------------------------- @@ -253,8 +317,12 @@ protected: \n Log message indented by (4) spaces\n (even blank lines have the spaces)\n + [[ \n [Diff format] + OR + \0 + ]] The header may have more fields. See 'git help diff-tree'. */ @@ -308,6 +376,11 @@ private: { if(this->Line.empty()) { + if(this->Section == SectionBody && this->LineEnd == '\0') + { + // Skip SectionDiff + this->NextSection(); + } this->NextSection(); } else diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h index 0b6ad2e..d8681fe 100644 --- a/Source/CTest/cmCTestGIT.h +++ b/Source/CTest/cmCTestGIT.h @@ -32,6 +32,10 @@ private: virtual void NoteNewRevision(); virtual bool UpdateImpl(); + bool UpdateByFetchAndReset(); + bool UpdateByCustom(std::string const& custom); + bool UpdateInternal(); + void LoadRevisions(); void LoadModifications(); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 8a69780..d50eaaa 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -18,11 +18,29 @@ #include <stack> #include <float.h> +class TestComparator +{ +public: + TestComparator(cmCTestMultiProcessHandler* handler) : Handler(handler) {} + ~TestComparator() {} + + // Sorts tests in descending order of cost + bool operator() (int index1, int index2) const + { + return Handler->Properties[index1]->Cost > + Handler->Properties[index2]->Cost; + } + +private: + cmCTestMultiProcessHandler* Handler; +}; + cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() { this->ParallelLevel = 1; this->Completed = 0; this->RunningCount = 0; + this->StopTimePassed = false; } cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler() @@ -69,6 +87,10 @@ void cmCTestMultiProcessHandler::RunTests() this->StartNextTests(); while(this->Tests.size() != 0) { + if(this->StopTimePassed) + { + return; + } this->CheckOutput(); this->StartNextTests(); } @@ -87,6 +109,7 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test) this->TestRunningMap[test] = true; // mark the test as running // now remove the test itself this->EraseTest(test); + this->RunningCount += GetProcessorsUsed(test); cmCTestRunTest* testRun = new cmCTestRunTest(this->TestHandler); testRun->SetIndex(test); @@ -102,6 +125,12 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test) { this->RunningTests.insert(testRun); } + else if(testRun->IsStopTimePassed()) + { + this->StopTimePassed = true; + delete testRun; + return; + } else { this->UnlockResources(test); @@ -142,15 +171,8 @@ void cmCTestMultiProcessHandler::UnlockResources(int index) void cmCTestMultiProcessHandler::EraseTest(int test) { this->Tests.erase(test); - for(TestCostMap::iterator i = this->TestCosts.begin(); - i != this->TestCosts.end(); ++i) - { - if(i->second.find(test) != i->second.end()) - { - i->second.erase(test); - return; - } - } + this->SortedTests.erase( + std::find(this->SortedTests.begin(), this->SortedTests.end(), test)); } //--------------------------------------------------------- @@ -232,38 +254,36 @@ void cmCTestMultiProcessHandler::StartNextTests() return; } - for(TestCostMap::reverse_iterator i = this->TestCosts.rbegin(); - i != this->TestCosts.rend(); ++i) + TestList copy = this->SortedTests; + for(TestList::iterator test = copy.begin(); test != copy.end(); ++test) { - TestSet tests = i->second; //copy the test set - for(TestSet::iterator test = tests.begin(); - test != tests.end(); ++test) + //in case this test has already been started due to dependency + if(this->TestRunningMap[*test] || this->TestFinishMap[*test]) { - //in case this test has already been started due to dependency - if(this->TestRunningMap[*test] || this->TestFinishMap[*test]) - { - continue; - } - size_t processors = GetProcessorsUsed(*test); - if(processors > numToStart) - { - return; - } - if(this->StartTest(*test)) - { - numToStart -= processors; - this->RunningCount += processors; - } - else - { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl - << "Test did not start waiting on depends to finish: " - << *test << "\n"); - } - if(numToStart == 0) + continue; + } + size_t processors = GetProcessorsUsed(*test); + if(processors > numToStart) + { + return; + } + if(this->StartTest(*test)) + { + if(this->StopTimePassed) { return; } + numToStart -= processors; + } + else + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl + << "Test did not start waiting on depends to finish: " + << *test << "\n"); + } + if(numToStart == 0) + { + return; } } } @@ -453,26 +473,22 @@ void cmCTestMultiProcessHandler::CreateTestCostList() for(TestMap::iterator i = this->Tests.begin(); i != this->Tests.end(); ++i) { - //We only want to schedule them by cost in a parallel situation - if(this->ParallelLevel > 1) - { - 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 //we ignore their cost + SortedTests.push_back(i->first); + + //If the test failed last time, it should be run first, so max the cost + if(std::find(this->LastTestsFailed.begin(), + this->LastTestsFailed.end(), + this->Properties[i->first]->Name) + != this->LastTestsFailed.end()) { - this->TestCosts[this->Tests.size() - - this->Properties[i->first]->Index].insert(i->first); + this->Properties[i->first]->Cost = FLT_MAX; } } + if(this->ParallelLevel > 1) + { + TestComparator comp(this); + std::sort(SortedTests.begin(), SortedTests.end(), comp); + } } //--------------------------------------------------------- @@ -595,7 +611,7 @@ int cmCTestMultiProcessHandler::FindMaxIndex() //Returns true if no cycles exist in the dependency graph bool cmCTestMultiProcessHandler::CheckCycles() { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Checking test dependency graph..." << std::endl); for(TestMap::iterator it = this->Tests.begin(); it != this->Tests.end(); ++it) @@ -603,34 +619,29 @@ bool cmCTestMultiProcessHandler::CheckCycles() //DFS from each element to itself std::stack<int> s; std::vector<int> visited; + s.push(it->first); - visited.push_back(it->first); while(!s.empty()) { int test = s.top(); s.pop(); - + for(TestSet::iterator d = this->Tests[test].begin(); d != this->Tests[test].end(); ++d) { - s.push(*d); - for(std::vector<int>::iterator v = visited.begin(); - v != visited.end(); ++v) + if(std::find(visited.begin(), visited.end(), *d) != visited.end()) { - if(*v == *d) - { - //cycle exists - cmCTestLog(this->CTest, ERROR_MESSAGE, "Error: a cycle exists in " - "the test dependency graph for the test \"" - << this->Properties[*d]->Name << "\"." << std::endl - << "Please fix the cycle and run ctest again." << std::endl); - return false; - } + //cycle exists + cmCTestLog(this->CTest, ERROR_MESSAGE, "Error: a cycle exists in " + "the test dependency graph for the test \"" + << this->Properties[it->first]->Name << "\"." << std::endl + << "Please fix the cycle and run ctest again." << std::endl); + return false; } - visited.push_back(*d); + s.push(*d); } - visited.pop_back(); + visited.push_back(test); } } return true; diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index d4f6c71..cc330f7 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -23,10 +23,11 @@ */ class cmCTestMultiProcessHandler { + friend class TestComparator; public: struct TestSet : public std::set<int> {}; struct TestMap : public std::map<int, TestSet> {}; - struct TestCostMap : public std::map<float, TestSet> {}; + struct TestList : public std::vector<int> {}; struct PropertiesMap : public std::map<int, cmCTestTestHandler::cmCTestTestProperties*> {}; @@ -88,12 +89,13 @@ protected: void UnlockResources(int index); // map from test number to set of depend tests TestMap Tests; - TestCostMap TestCosts; + TestList SortedTests; //Total number of tests we'll be running size_t Total; //Number of tests that are complete size_t Completed; size_t RunningCount; + bool StopTimePassed; //list of test properties (indices concurrent to the test map) PropertiesMap Properties; std::map<int, bool> TestRunningMap; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 4c9675b..ce44097 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -32,6 +32,7 @@ cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler) this->ProcessOutput = ""; this->CompressedOutput = ""; this->CompressionRatio = 2; + this->StopTimePassed = false; } cmCTestRunTest::~cmCTestRunTest() @@ -82,7 +83,8 @@ void cmCTestRunTest::CompressOutput() reinterpret_cast<unsigned char*>( const_cast<char*>(this->ProcessOutput.c_str())); //zlib makes the guarantee that this is the maximum output size - int outSize = static_cast<int>(this->ProcessOutput.size() * 1.001 + 13); + int outSize = static_cast<int>( + static_cast<double>(this->ProcessOutput.size()) * 1.001 + 13.0); unsigned char* out = new unsigned char[outSize]; strm.zalloc = Z_NULL; @@ -220,7 +222,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) { outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Exception: "); - switch ( retVal ) + switch(this->TestProcess->GetExitException()) { case cmsysProcess_Exception_Fault: cmCTestLog(this->CTest, HANDLER_OUTPUT, "SegFault"); @@ -341,13 +343,14 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) //---------------------------------------------------------------------- void cmCTestRunTest::ComputeWeightedCost() { - int prev = this->TestProperties->PreviousRuns; - float avgcost = this->TestProperties->Cost; + double prev = static_cast<double>(this->TestProperties->PreviousRuns); + double avgcost = static_cast<double>(this->TestProperties->Cost); double current = this->TestResult.ExecutionTime; if(this->TestResult.Status == cmCTestTestHandler::COMPLETED) { - this->TestProperties->Cost = ((prev * avgcost) + current) / (prev + 1); + this->TestProperties->Cost = + static_cast<float>(((prev * avgcost) + current) / (prev + 1.0)); this->TestProperties->PreviousRuns++; } } @@ -436,8 +439,13 @@ bool cmCTestRunTest::StartTest(size_t total) } this->StartTime = this->CTest->CurrentTime(); - return this->ForkProcess(this->ResolveTimeout(), - &this->TestProperties->Environment); + double timeout = this->ResolveTimeout(); + + if(this->StopTimePassed) + { + return false; + } + return this->ForkProcess(timeout, &this->TestProperties->Environment); } //---------------------------------------------------------------------- @@ -563,14 +571,15 @@ double cmCTestRunTest::ResolveTimeout() { stop_time += 24*60*60; } - int stop_timeout = (stop_time - current_time) % (24*60*60); + int stop_timeout = static_cast<int>(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); + "Stopping all tests." << std::endl); + this->StopTimePassed = true; + return 0; } return timeout == 0 ? stop_timeout : (timeout < stop_timeout ? timeout : stop_timeout); diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index d7d3a2f..e0cb888 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -39,6 +39,8 @@ public: std::string GetProcessOutput() { return this->ProcessOutput; } + bool IsStopTimePassed() { return this->StopTimePassed; } + cmCTestTestHandler::cmCTestTestResult GetTestResults() { return this->TestResult; } @@ -90,6 +92,7 @@ private: std::string TestCommand; std::string ActualCommand; std::vector<std::string> Arguments; + bool StopTimePassed; }; inline int getNumWidth(size_t n) diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index b9cee6c..a4a4863 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1036,9 +1036,9 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed, bool randomSchedule = this->CTest->GetScheduleType() == "Random"; if(randomSchedule) - { + { srand((unsigned)time(0)); - } + } for (ListOfTests::iterator it = this->TestList.begin(); it != this->TestList.end(); ++it) @@ -1048,7 +1048,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed, if(randomSchedule) { - p.Cost = rand(); + p.Cost = static_cast<float>(rand()); } if(p.Timeout == 0 && this->CTest->GetGlobalTimeout() != 0) @@ -1309,7 +1309,8 @@ std::string cmCTestTestHandler::EncodeFile(std::string file) cmSystemTools::RemoveFile(tarFile.c_str()); unsigned char *encoded_buffer - = new unsigned char [ static_cast<int>(len * 1.5 + 5) ]; + = new unsigned char [ static_cast<int>( + static_cast<double>(len) * 1.5 + 5.0) ]; unsigned long rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1); @@ -1881,7 +1882,8 @@ std::string cmCTestTestHandler::GenerateRegressionImages( unsigned char *file_buffer = new unsigned char [ len + 1 ]; ifs.read(reinterpret_cast<char*>(file_buffer), len); unsigned char *encoded_buffer - = new unsigned char [ static_cast<int>(len * 1.5 + 5) ]; + = new unsigned char [ static_cast<int>( + static_cast<double>(len) * 1.5 + 5.0) ]; unsigned long rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1); diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 571745d..8414349 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -52,6 +52,8 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS"); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, + "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM"); + this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "HGCommand", "CTEST_HG_COMMAND"); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS"); diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 9aa40d6..0ee631f 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -264,3 +264,9 @@ int cmProcess::ReportStatus() return result; } + + +int cmProcess::GetExitException() +{ + return cmsysProcess_GetExitException(this->Process); +} diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index 01dacf9..ff99ca2 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -43,7 +43,7 @@ public: void SetId(int id) { this->Id = id;} int GetExitValue() { return this->ExitValue;} double GetTotalTime() { return this->TotalTime;} - + int GetExitException(); /** * Read one line of output but block for no more than timeout. * Returns: diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx index c66147b..1c48d8c 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.cxx +++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx @@ -53,13 +53,13 @@ void cmCursesLongMessageForm::UpdateStatusBar() getmaxyx(stdscr, y, x); char bar[cmCursesMainForm::MAX_WIDTH]; - int size = strlen(this->Title.c_str()); + size_t size = strlen(this->Title.c_str()); if ( size >= cmCursesMainForm::MAX_WIDTH ) { size = cmCursesMainForm::MAX_WIDTH-1; } strncpy(bar, this->Title.c_str(), size); - for(int i=size-1; i<cmCursesMainForm::MAX_WIDTH; i++) bar[i] = ' '; + for(size_t i=size-1; i<cmCursesMainForm::MAX_WIDTH; i++) bar[i] = ' '; int width; if (x < cmCursesMainForm::MAX_WIDTH ) @@ -76,8 +76,8 @@ void cmCursesLongMessageForm::UpdateStatusBar() char version[cmCursesMainForm::MAX_WIDTH]; char vertmp[128]; sprintf(vertmp,"CMake Version %s", cmVersion::GetCMakeVersion()); - int sideSpace = (width-strlen(vertmp)); - for(int i=0; i<sideSpace; i++) { version[i] = ' '; } + size_t sideSpace = (width-strlen(vertmp)); + for(size_t i=0; i<sideSpace; i++) { version[i] = ' '; } sprintf(version+sideSpace, "%s", vertmp); version[width] = '\0'; diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index cd231ad..389ec7f 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -242,7 +242,7 @@ void cmCursesMainForm::RePost() // Assign the fields: 3 for each entry: label, new entry marker // ('*' or ' ') and entry widget this->Fields = new FIELD*[3*this->NumberOfVisibleEntries+1]; - int cc; + size_t cc; for ( cc = 0; cc < 3 * this->NumberOfVisibleEntries+1; cc ++ ) { this->Fields[cc] = 0; @@ -454,7 +454,7 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */) if (cw) { sprintf(firstLine, "Page %d of %d", cw->GetPage(), this->NumberOfPages); - curses_move(0,65-strlen(firstLine)-1); + curses_move(0,65-static_cast<unsigned int>(strlen(firstLine))-1); printw(firstLine); } // } @@ -526,10 +526,10 @@ void cmCursesMainForm::UpdateStatusBar(const char* message) // Join the key, help string and pad with spaces // (or truncate) as necessary char bar[cmCursesMainForm::MAX_WIDTH]; - int i, curFieldLen = strlen(curField); - int helpLen = strlen(help); + size_t i, curFieldLen = strlen(curField); + size_t helpLen = strlen(help); - int width; + size_t width; if (x < cmCursesMainForm::MAX_WIDTH ) { width = x; @@ -592,7 +592,7 @@ void cmCursesMainForm::UpdateStatusBar(const char* message) char version[cmCursesMainForm::MAX_WIDTH]; char vertmp[128]; sprintf(vertmp,"CMake Version %s", cmVersion::GetCMakeVersion()); - int sideSpace = (width-strlen(vertmp)); + size_t sideSpace = (width-strlen(vertmp)); for(i=0; i<sideSpace; i++) { version[i] = ' '; } sprintf(version+sideSpace, "%s", vertmp); version[width] = '\0'; @@ -795,8 +795,8 @@ void cmCursesMainForm::RemoveEntry(const char* value) // copy from the list box to the cache manager void cmCursesMainForm::FillCacheManagerFromUI() { - int size = this->Entries->size(); - for(int i=0; i < size; i++) + size_t size = this->Entries->size(); + for(size_t i=0; i < size; i++) { cmCacheManager::CacheIterator it = this->CMakeInstance->GetCacheManager()->GetCacheIterator( @@ -866,7 +866,7 @@ void cmCursesMainForm::HandleInput() std::string searchstr = "Search: " + this->SearchString; this->UpdateStatusBar( searchstr.c_str() ); this->PrintKeys(1); - curses_move(y-5,searchstr.size()); + curses_move(y-5,static_cast<unsigned int>(searchstr.size())); //curses_move(1,1); touchwin(stdscr); refresh(); @@ -961,7 +961,7 @@ void cmCursesMainForm::HandleInput() else if ( key == KEY_DOWN || key == ctrl('n') ) { FIELD* cur = current_field(this->Form); - int findex = field_index(cur); + size_t findex = field_index(cur); if ( findex == 3*this->NumberOfVisibleEntries-1 ) { continue; @@ -1108,7 +1108,7 @@ void cmCursesMainForm::HandleInput() { this->OkToGenerate = false; FIELD* cur = current_field(this->Form); - int findex = field_index(cur); + size_t findex = field_index(cur); // make the next or prev. current field after deletion // each entry consists of fields: label, isnew, value @@ -1199,7 +1199,7 @@ void cmCursesMainForm::JumpToCacheEntry(int idx, const char* astr) str = cmSystemTools::LowerCase(astr); } - if ( idx > this->NumberOfVisibleEntries ) + if ( size_t(idx) > this->NumberOfVisibleEntries ) { return; } @@ -1232,7 +1232,7 @@ void cmCursesMainForm::JumpToCacheEntry(int idx, const char* astr) } } } - if ( findex >= 3* this->NumberOfVisibleEntries-1 ) + if ( size_t(findex) >= 3* this->NumberOfVisibleEntries-1 ) { set_current_field(this->Form, this->Fields[2]); } diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h index 9751999..4084415 100644 --- a/Source/CursesDialog/cmCursesMainForm.h +++ b/Source/CursesDialog/cmCursesMainForm.h @@ -147,7 +147,7 @@ protected: // Where is cmake executable std::string WhereCMake; // Number of entries shown (depends on mode -normal or advanced-) - int NumberOfVisibleEntries; + size_t NumberOfVisibleEntries; bool AdvancedMode; // Did the iteration converge (no new entries) ? bool OkToGenerate; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index bd69d6c..4d56257 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1169,7 +1169,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output, if ( tick % tick_line_len == 0 && tick > 0 ) { cmCTestLog(this, HANDLER_OUTPUT, " Size: " - << int((output->size() / 1024.0) + 1) << "K" << std::endl + << int((double(output->size()) / 1024.0) + 1) << "K" << std::endl << " " << std::flush); } } @@ -1181,7 +1181,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output, } } cmCTestLog(this, OUTPUT, " Size of output: " - << int(output->size() / 1024.0) << "K" << std::endl); + << int(double(output->size()) / 1024.0) << "K" << std::endl); cmsysProcess_WaitForExit(cp, 0); diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index dab0c0d..b8a0c95 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -175,6 +175,23 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) { fprintf(fout, "SET(CMAKE_MODULE_PATH %s)\n", def); } + + const char* rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE"; + std::string rulesOverrideLang = + rulesOverrideBase + (lang ? std::string("_") + lang : std::string("")); + if(const char* rulesOverridePath = + this->Makefile->GetDefinition(rulesOverrideLang.c_str())) + { + fprintf(fout, "SET(%s \"%s\")\n", + rulesOverrideLang.c_str(), rulesOverridePath); + } + else if(const char* rulesOverridePath2 = + this->Makefile->GetDefinition(rulesOverrideBase)) + { + fprintf(fout, "SET(%s \"%s\")\n", + rulesOverrideBase, rulesOverridePath2); + } + if(lang) { fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE %s)\n", lang); diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index e77119f..2ed959f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1324,6 +1324,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_LINK_FLAGS", cmProperty::VARIABLE,0,0); + cm->DefineProperty("CMAKE_<LANG>_RESPONSE_FILE_LINK_FLAG", + cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES_INIT", @@ -1398,4 +1400,6 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS", cmProperty::VARIABLE,0,0); + cm->DefineProperty("CMAKE_MAKE_INCLUDE_FROM_ROOT", + cmProperty::VARIABLE,0,0); } diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 147f6ac..c198727 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -576,7 +576,7 @@ unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount() return i; } } - return this->DynamicSectionEntries.size(); + return static_cast<unsigned int>(this->DynamicSectionEntries.size()); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index b687fe1..4e8e7e6 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -750,8 +750,9 @@ cmGlobalUnixMakefileGenerator3 cmLocalGenerator::FULL, cmLocalGenerator::SHELL); progCmd << " "; - std::vector<int> &progFiles = this->ProgressMap[&t->second].Marks; - for (std::vector<int>::iterator i = progFiles.begin(); + std::vector<unsigned long>& progFiles = + this->ProgressMap[&t->second].Marks; + for (std::vector<unsigned long>::iterator i = progFiles.begin(); i != progFiles.end(); ++i) { progCmd << " " << *i; diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 401888f..f499536 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -177,7 +177,7 @@ protected: TargetProgress(): NumberOfActions(0) {} unsigned long NumberOfActions; std::string VariableFile; - std::vector<int> Marks; + std::vector<unsigned long> Marks; void WriteProgressVariables(unsigned long total, unsigned long& current); }; struct ProgressMapCompare { bool operator()(cmTarget*,cmTarget*) const; }; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index e423174..6e0f048 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -154,8 +154,6 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget() stampFile += "/"; stampFile += cmake::GetCMakeFilesDirectoryPostSlash(); stampFile += "generate.stamp"; - stampFile = generators[0]->Convert(stampFile.c_str(), - cmLocalGenerator::START_OUTPUT); fout << stampFile << "\n"; stamps.push_back(stampFile); } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index fd3508e..13d875f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2249,6 +2249,10 @@ std::string cmLocalGenerator::ConvertToOutputFormat(const char* source, } result = this->EscapeForShell(result.c_str(), true, false); } + else if(output == RESPONSE) + { + result = this->EscapeForShell(result.c_str(), false, false); + } return result; } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 4c2fc22..43bf1e7 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -102,7 +102,7 @@ public: * path setting */ enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT }; - enum OutputFormat { UNCHANGED, MAKEFILE, SHELL }; + enum OutputFormat { UNCHANGED, MAKEFILE, SHELL, RESPONSE }; std::string ConvertToOutputFormat(const char* source, OutputFormat output); std::string Convert(const char* remote, RelativeRoot local, OutputFormat output = UNCHANGED, diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 136c177..e411d3e 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -234,7 +234,9 @@ void cmLocalVisualStudio7Generator //---------------------------------------------------------------------------- cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() { - std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash(); + std::string stampName = this->Makefile->GetCurrentOutputDirectory(); + stampName += "/"; + stampName += cmake::GetCMakeFilesDirectoryPostSlash(); stampName += "generate.stamp"; const char* dsprule = this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"); @@ -270,9 +272,11 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() cmCustomCommandLines commandLines; commandLines.push_back(commandLine); const char* no_working_directory = 0; - this->Makefile->AddCustomCommandToOutput(stampName.c_str(), listFiles, - makefileIn.c_str(), commandLines, - comment.c_str(), + std::string fullpathStampName = this->Convert(stampName.c_str(), FULL, + UNCHANGED); + this->Makefile->AddCustomCommandToOutput(fullpathStampName.c_str(), + listFiles, makefileIn.c_str(), + commandLines, comment.c_str(), no_working_directory, true); if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) { diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index ac727ac..d5d6585 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -189,12 +189,15 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::WriteCommonCodeRules() { + const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")? + "$(CMAKE_BINARY_DIR)/" : ""); + // Include the dependencies for the target. std::string dependFileNameFull = this->TargetBuildDirectoryFull; dependFileNameFull += "/depend.make"; *this->BuildFileStream << "# Include any dependencies generated for this target.\n" - << this->LocalGenerator->IncludeDirective << " " + << this->LocalGenerator->IncludeDirective << " " << root << this->Convert(dependFileNameFull.c_str(), cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKEFILE) @@ -205,7 +208,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() // Include the progress variables for the target. *this->BuildFileStream << "# Include the progress variables for this target.\n" - << this->LocalGenerator->IncludeDirective << " " + << this->LocalGenerator->IncludeDirective << " " << root << this->Convert(this->ProgressFileNameFull.c_str(), cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKEFILE) @@ -238,7 +241,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() // Include the flags for the target. *this->BuildFileStream << "# Include the compile flags for this target's objects.\n" - << this->LocalGenerator->IncludeDirective << " " + << this->LocalGenerator->IncludeDirective << " " << root << this->Convert(this->FlagFileNameFull.c_str(), cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKEFILE) @@ -1327,7 +1330,7 @@ public: this->NextObject = this->LocalGenerator->Convert(obj.c_str(), cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL); + cmLocalGenerator::RESPONSE); // Roll over to next string if the limit will be exceeded. if(this->LengthLimit != std::string::npos && @@ -1621,6 +1624,17 @@ cmMakefileTargetGenerator std::vector<std::string> object_strings; this->WriteObjectsStrings(object_strings, responseFileLimit); + // Lookup the response file reference flag. + std::string responseFlagVar = "CMAKE_"; + responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName); + responseFlagVar += "_RESPONSE_FILE_LINK_FLAG"; + const char* responseFlag = + this->Makefile->GetDefinition(responseFlagVar.c_str()); + if(!responseFlag) + { + responseFlag = "@"; + } + // Write a response file for each string. const char* sep = ""; for(unsigned int i = 0; i < object_strings.size(); ++i) @@ -1638,7 +1652,7 @@ cmMakefileTargetGenerator sep = " "; // Reference the response file. - buildObjs += "@"; + buildObjs += responseFlag; buildObjs += this->Convert(objects_rsp.c_str(), cmLocalGenerator::NONE, cmLocalGenerator::SHELL); diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx index cacd766..d2f7bf3 100644 --- a/Source/cmProcessTools.cxx +++ b/Source/cmProcessTools.cxx @@ -44,7 +44,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, //---------------------------------------------------------------------------- cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR): - Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0) + Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0') { } @@ -61,8 +61,10 @@ bool cmProcessTools::LineParser::ProcessChunk(const char* first, int length) const char* last = first + length; for(const char* c = first; c != last; ++c) { - if(*c == this->Separator) + if(*c == this->Separator || *c == '\0') { + this->LineEnd = *c; + // Log this line. if(this->Log && this->Prefix) { diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h index 0b210af..439726d 100644 --- a/Source/cmProcessTools.h +++ b/Source/cmProcessTools.h @@ -55,6 +55,7 @@ public: bool IgnoreCR; std::ostream* Log; const char* Prefix; + char LineEnd; std::string Line; virtual bool ProcessChunk(const char* data, int length); diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h index 853e7ba..c477bb7 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -66,7 +66,9 @@ public: "directory (already processed by CMake) may be named by full or " "relative path.\n" "TARGET scope may name zero or more existing targets.\n" - "SOURCE scope may name zero or more source files.\n" + "SOURCE scope may name zero or more source files. " + "Note that source file properties are visible only to targets " + "added in the same directory (CMakeLists.txt).\n" "TEST scope may name zero or more existing tests.\n" "CACHE scope must name zero or more cache existing entries.\n" "The required PROPERTY option is immediately followed by the name " diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h index 7182152..392f168 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.h +++ b/Source/cmSetSourceFilesPropertiesCommand.h @@ -48,35 +48,15 @@ public: virtual const char* GetFullDocumentation() { return - " set_source_files_properties(file1 file2 ...\n" + " set_source_files_properties([file1 [file2 [...]]]\n" " PROPERTIES prop1 value1\n" - " prop2 value2 ...)\n" - "Set properties on a file. The syntax for the command is to list all " - "the files you want " - "to change, and then provide the values you want to set next. You " - "can make up your own properties as well. " - "The following are used by CMake. " - "The ABSTRACT flag (boolean) is used by some class wrapping " - "commands. " - "If WRAP_EXCLUDE (boolean) is true then many wrapping commands " - "will ignore this file. If GENERATED (boolean) is true then it " - "is not an error if this source file does not exist when it is " - "added to a target. Obviously, " - "it must be created (presumably by a custom command) before the " - "target is built. " - "If the HEADER_FILE_ONLY (boolean) property is true then the " - "file is not compiled. This is useful if you want to add extra " - "non build files to an IDE. " - "OBJECT_DEPENDS (string) adds dependencies to the object file. " - "COMPILE_FLAGS (string) is passed to the compiler as additional " - "command line arguments when the source file is compiled. " - "LANGUAGE (string) CXX|C will change the default compiler used " - "to compile the source file. The languages used need to be enabled " - "in the PROJECT command. " - "If SYMBOLIC (boolean) is set to true the build system will be " - "informed that the source file is not actually created on disk but " - "instead used as a symbolic name for a build rule."; - + " [prop2 value2 [...]])\n" + "Set properties associated with source files using a key/value " + "paired list. " + "See properties documentation for those known to CMake. " + "Unrecognized properties are ignored. " + "Source file properties are visible only to targets " + "added in the same directory (CMakeLists.txt)."; } cmTypeMacro(cmSetSourceFilesPropertiesCommand, cmCommand); diff --git a/Source/cmStandardIncludes.cxx b/Source/cmStandardIncludes.cxx new file mode 100644 index 0000000..a4bdb2e --- /dev/null +++ b/Source/cmStandardIncludes.cxx @@ -0,0 +1,16 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2010 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmStandardIncludes.h" +#if !defined(CMAKE_NO_ANSI_STRING_STREAM) +cmOStringStream::cmOStringStream() {} +cmOStringStream::~cmOStringStream() {} +#endif diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 9b9cb3b..e8decbb 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -241,7 +241,8 @@ typedef cmsys::String cmStdString; class cmOStringStream: public std::ostringstream { public: - cmOStringStream() {} + cmOStringStream(); + ~cmOStringStream(); private: cmOStringStream(const cmOStringStream&); void operator=(const cmOStringStream&); diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 3bd47a4..19f5c0f 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -739,7 +739,7 @@ bool cmStringCommand alphabet = cmStringCommandDefaultAlphabet; } - double sizeofAlphabet = alphabet.size(); + double sizeofAlphabet = static_cast<double>(alphabet.size()); if ( sizeofAlphabet < 1 ) { this->SetError("sub-command RANDOM invoked with bad alphabet."); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 5f7cfa3..0badbba 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1204,6 +1204,7 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) // Should be efficient enough on most system: const int bufferSize = 4096; char buffer[bufferSize]; + unsigned char const* buffer_uc = reinterpret_cast<unsigned char const*>(buffer); // This copy loop is very sensitive on certain platforms with // slightly broken stream libraries (like HPUX). Normally, it is // incorrect to not check the error condition on the fin.read() @@ -1212,10 +1213,9 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) while(fin) { fin.read(buffer, bufferSize); - if(fin.gcount()) + if(int gcount = static_cast<int>(fin.gcount())) { - cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(buffer), - fin.gcount()); + cmsysMD5_Append(md5, buffer_uc, gcount); } } cmsysMD5_FinalizeHex(md5, md5out); @@ -1989,9 +1989,9 @@ namespace{ # pragma warn -8066 /* unreachable code */ #endif -int copy_data(struct archive *ar, struct archive *aw) +long copy_data(struct archive *ar, struct archive *aw) { - int r; + long r; const void *buff; size_t size; off_t offset; @@ -2136,7 +2136,7 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, } else if(*outiter == '\n' || *outiter == '\0') { - int length = outiter-out.begin(); + std::vector<char>::size_type length = outiter-out.begin(); if(length > 1 && *(outiter-1) == '\r') { --length; @@ -2159,7 +2159,7 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, } else if(*erriter == '\n' || *erriter == '\0') { - int length = erriter-err.begin(); + std::vector<char>::size_type length = erriter-err.begin(); if(length > 1 && *(erriter-1) == '\r') { --length; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 53d6594..59e20d5 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -435,6 +435,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups() none.push_back(sf); } } + + this->AddMissingSourceGroups(groupsUsed, sourceGroups); + // Write out group file std::string path = this->Makefile->GetStartOutputDirectory(); path += "/"; @@ -492,6 +495,52 @@ void cmVisualStudio10TargetGenerator::WriteGroups() } } +// Add to groupsUsed empty source groups that have non-empty children. +void +cmVisualStudio10TargetGenerator::AddMissingSourceGroups( + std::set<cmSourceGroup*>& groupsUsed, + const std::vector<cmSourceGroup>& allGroups + ) +{ + for(std::vector<cmSourceGroup>::const_iterator current = allGroups.begin(); + current != allGroups.end(); ++current) + { + std::vector<cmSourceGroup> const& children = current->GetGroupChildren(); + if(children.empty()) + { + continue; // the group is really empty + } + + this->AddMissingSourceGroups(groupsUsed, children); + + cmSourceGroup* current_ptr = const_cast<cmSourceGroup*>(&(*current)); + if(groupsUsed.find(current_ptr) != groupsUsed.end()) + { + continue; // group has already been added to set + } + + // check if it least one of the group's descendants is not empty + // (at least one child must already have been added) + std::vector<cmSourceGroup>::const_iterator child_it = children.begin(); + while(child_it != children.end()) + { + cmSourceGroup* child_ptr = const_cast<cmSourceGroup*>(&(*child_it)); + if(groupsUsed.find(child_ptr) != groupsUsed.end()) + { + break; // found a child that was already added => add current group too + } + child_it++; + } + + if(child_it == children.end()) + { + continue; // no descendants have source files => ignore this group + } + + groupsUsed.insert(current_ptr); + } +} + void cmVisualStudio10TargetGenerator:: WriteGroupSources(const char* name, diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 989db71..64b2361 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -77,6 +77,10 @@ private: void WriteGroupSources(const char* name, std::vector<cmSourceFile*> const& sources, std::vector<cmSourceGroup>& ); + void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed, + const std::vector<cmSourceGroup>& allGroups); + + private: typedef cmVisualStudioGeneratorOptions Options; typedef std::map<cmStdString, Options*> OptionsMap; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 051cc1f..972af95 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -183,7 +183,7 @@ cmVisualStudioGeneratorOptions { fout << prefix << "PreprocessorDefinitions=\""; } - const char* comma = ""; + const char* sep = ""; for(std::vector<std::string>::const_iterator di = this->Defines.begin(); di != this->Defines.end(); ++di) { @@ -208,15 +208,8 @@ cmVisualStudioGeneratorOptions define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str()); } // Store the flag in the project file. - fout << comma << define; - if(this->Version == 10) - { - comma = ";"; - } - else - { - comma = ","; - } + fout << sep << define; + sep = ";"; } if(this->Version == 10) { diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c index 3d4ca16..c9bf259 100644 --- a/Source/cm_utf8.c +++ b/Source/cm_utf8.c @@ -50,7 +50,7 @@ const char* cm_utf8_decode_character(const char* first, const char* last, unsigned int* pc) { /* Count leading ones in the first byte. */ - unsigned char c = *first++; + unsigned char c = (unsigned char)*first++; unsigned char const ones = cm_utf8_ones[c]; switch(ones) { @@ -62,10 +62,10 @@ const char* cm_utf8_decode_character(const char* first, const char* last, /* Extract bits from this multi-byte character. */ { unsigned int uc = c & cm_utf8_mask[ones]; - unsigned char left; + int left; for(left = ones-1; left && first != last; --left) { - c = *first++; + c = (unsigned char)*first++; if(cm_utf8_ones[c] != 1) { return 0; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index f766d47..cb20069 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -162,16 +162,6 @@ cmake::cmake() } #endif - // If MAKEFLAGS are given in the environment, remove the environment - // variable. This will prevent try-compile from succeeding when it - // should fail (if "-i" is an option). We cannot simply test - // whether "-i" is given and remove it because some make programs - // encode the MAKEFLAGS variable in a strange way. - if(getenv("MAKEFLAGS")) - { - cmSystemTools::PutEnv("MAKEFLAGS="); - } - this->Verbose = false; this->InTryCompile = false; this->CacheManager = new cmCacheManager(this); @@ -2231,6 +2221,16 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) } } + // If MAKEFLAGS are given in the environment, remove the environment + // variable. This will prevent try-compile from succeeding when it + // should fail (if "-i" is an option). We cannot simply test + // whether "-i" is given and remove it because some make programs + // encode the MAKEFLAGS variable in a strange way. + if(getenv("MAKEFLAGS")) + { + cmSystemTools::PutEnv("MAKEFLAGS="); + } + this->PreLoadCMakeFiles(); std::string systemFile = this->GetHomeOutputDirectory(); @@ -3906,6 +3906,9 @@ static bool cmakeCheckStampFile(const char* stampName) // build system is really out of date. std::cout << "CMake is re-running because " << stampName << " is out-of-date.\n"; + std::cout << " the file '" << dep << "'\n"; + std::cout << " is newer than '" << stampDepends << "'\n"; + std::cout << " result='" << result << "'\n"; return false; } } diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index f440ff9..bcc7a96 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -141,12 +141,6 @@ IF(COMMAND SET_PROPERTY) "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>" ) ENDIF(COMMAND SET_PROPERTY) -# add option to disable memory cleanup at exit of putenv memory -IF(DEFINED KWSYS_DO_NOT_CLEAN_PUTENV) - SET(KWSYS_DO_NOT_CLEAN_PUTENV 1) -ELSE(DEFINED KWSYS_DO_NOT_CLEAN_PUTENV) - SET(KWSYS_DO_NOT_CLEAN_PUTENV 0) -ENDIF(DEFINED KWSYS_DO_NOT_CLEAN_PUTENV) # Select library components. IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) @@ -605,6 +599,23 @@ ELSE(KWSYS_BUILD_SHARED) ENDIF(KWSYS_BUILD_SHARED) #----------------------------------------------------------------------------- +# Configure some implementation details. + +KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T + "Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT) +KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T + "Checking whether C compiler has ssize_t in unistd.h" DIRECT) +SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES + COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}" + ) + +IF(KWSYS_DO_NOT_CLEAN_PUTENV) + # Disable cleanup of putenv memory for issues with GCOV. + SET_SOURCE_FILES_PROPERTIES(SystemTools.cxx PROPERTIES + COMPILE_FLAGS -DKWSYS_DO_NOT_CLEAN_PUTENV=1) +ENDIF(KWSYS_DO_NOT_CLEAN_PUTENV) + +#----------------------------------------------------------------------------- # Choose a directory for the generated headers. IF(NOT KWSYS_HEADER_ROOT) SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}") @@ -782,15 +793,6 @@ IF(KWSYS_USE_Process) ELSE(NOT UNIX) # Use the UNIX implementation. SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c) - - # Help ProcessUNIX.c compile properly on all platforms. - KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T - "Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT) - KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T - "Checking whether C compiler has ssize_t in unistd.h" DIRECT) - SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c PROPERTIES - COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}" - ) ENDIF(NOT UNIX) ENDIF(KWSYS_USE_Process) @@ -1095,6 +1097,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7}) ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n}) KWSYS_SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST}) + SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120) ENDFOREACH(n) # Some Apple compilers produce bad optimizations in this source. @@ -1122,5 +1125,11 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value") MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}") ENDIF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE) + + # Suppress known consistent failures on buggy systems. + IF(KWSYS_TEST_BOGUS_FAILURES) + SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON) + ENDIF() + ENDIF(BUILD_TESTING) ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in index 9310d94..716b84f 100644 --- a/Source/kwsys/Configure.hxx.in +++ b/Source/kwsys/Configure.hxx.in @@ -15,15 +15,6 @@ /* Include C configuration. */ #include <@KWSYS_NAMESPACE@/Configure.h> -/* Disable cleanup of putenv memory for issues with GCOV */ -#if @KWSYS_DO_NOT_CLEAN_PUTENV@ -#define KWSYS_DO_NOT_CLEAN_PUTENV -#else -#undef KWSYS_DO_NOT_CLEAN_PUTENV -#endif - - - /* Whether ANSI C++ stream headers are to be used. */ #define @KWSYS_NAMESPACE@_IOS_USE_ANSI @KWSYS_IOS_USE_ANSI@ diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index 77da3c2..40308e9 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 06) +SET(KWSYS_DATE_STAMP_MONTH 07) # KWSys version date day component. Format is DD. SET(KWSYS_DATE_STAMP_DAY 13) diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c index 0060c4d..877002a 100644 --- a/Source/kwsys/testProcess.c +++ b/Source/kwsys/testProcess.c @@ -94,7 +94,11 @@ int test4(int argc, const char* argv[]) fprintf(stderr, "Output before crash on stderr from crash test.\n"); fflush(stdout); fflush(stderr); +#if defined(__clang__) + *(int*)1 = 0; /* Clang warns about 0-ptr; undefined behavior. */ +#else *(int*)0 = 0; +#endif fprintf(stdout, "Output after crash on stdout from crash test.\n"); fprintf(stderr, "Output after crash on stderr from crash test.\n"); return 0; |