diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/CTest/cmCTestMultiProcessHandler.cxx | 4 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.cxx | 148 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.h | 17 | ||||
-rw-r--r-- | Source/CTest/cmCTestSubmitHandler.cxx | 48 | ||||
-rw-r--r-- | Source/cmCTest.cxx | 80 | ||||
-rw-r--r-- | Source/cmCTest.h | 9 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 56 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 30 | ||||
-rw-r--r-- | Source/ctest.cxx | 1 |
10 files changed, 295 insertions, 100 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 408cc7d..cc4f51a 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 12) -set(CMake_VERSION_PATCH 20181001) +set(CMake_VERSION_PATCH 20181002) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 3e0c1ac..f026001 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -178,7 +178,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) this->Properties[test]->Directory + " : " + std::strerror(workdir.GetLastResult())); } else { - if (testRun->StartTest(this->Total)) { + if (testRun->StartTest(this->Completed, this->Total)) { return true; } } @@ -440,7 +440,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner, this->SetStopTimePassed(); } if (started) { - if (!this->StopTimePassed && runner->StartAgain()) { + if (!this->StopTimePassed && runner->StartAgain(this->Completed)) { this->Completed--; // remove the completed test because run again return; } diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 23d4616..7f081ef 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -181,6 +181,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } } } + std::ostringstream outputStream; if (res == cmProcess::State::Exited) { bool success = !forceFail && (retVal == 0 || @@ -196,36 +197,36 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } else if ((success && !this->TestProperties->WillFail) || (!success && this->TestProperties->WillFail)) { this->TestResult.Status = cmCTestTestHandler::COMPLETED; - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Passed "); + outputStream << " Passed "; } else { this->TestResult.Status = cmCTestTestHandler::FAILED; - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Failed " << reason); + outputStream << "***Failed " << reason; outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; } } else if (res == cmProcess::State::Expired) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Timeout "); + outputStream << "***Timeout "; this->TestResult.Status = cmCTestTestHandler::TIMEOUT; outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; } else if (res == cmProcess::State::Exception) { outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Exception: "); + outputStream << "***Exception: "; this->TestResult.ExceptionStatus = this->TestProcess->GetExitExceptionString(); switch (this->TestProcess->GetExitException()) { case cmProcess::Exception::Fault: - cmCTestLog(this->CTest, HANDLER_OUTPUT, "SegFault"); + outputStream << "SegFault"; this->TestResult.Status = cmCTestTestHandler::SEGFAULT; break; case cmProcess::Exception::Illegal: - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Illegal"); + outputStream << "Illegal"; this->TestResult.Status = cmCTestTestHandler::ILLEGAL; break; case cmProcess::Exception::Interrupt: - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Interrupt"); + outputStream << "Interrupt"; this->TestResult.Status = cmCTestTestHandler::INTERRUPT; break; case cmProcess::Exception::Numerical: - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Numerical"); + outputStream << "Numerical"; this->TestResult.Status = cmCTestTestHandler::NUMERICAL; break; default: @@ -234,16 +235,41 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) this->TestResult.Status = cmCTestTestHandler::OTHER_FAULT; } } else if ("Disabled" == this->TestResult.CompletionStatus) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Not Run (Disabled) "); + outputStream << "***Not Run (Disabled) "; } else // cmProcess::State::Error { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Not Run "); + outputStream << "***Not Run "; } passed = this->TestResult.Status == cmCTestTestHandler::COMPLETED; char buf[1024]; sprintf(buf, "%6.2f sec", this->TestProcess->GetTotalTime().count()); - cmCTestLog(this->CTest, HANDLER_OUTPUT, buf << "\n"); + outputStream << buf << "\n"; + + if (this->CTest->GetTestProgressOutput()) { + if (!passed) { + // If the test did not pass, reprint test name and error + std::string output = GetTestPrefix(completed, total); + std::string testName = this->TestProperties->Name; + const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth(); + testName.resize(maxTestNameWidth + 4, '.'); + + output += testName; + output += outputStream.str(); + outputStream.str(""); + outputStream.clear(); + outputStream << output; + cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, "\n"); // flush + } + if (completed == total) { + std::string testName = + GetTestPrefix(completed, total) + this->TestProperties->Name + "\n"; + cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName); + } + } + if (!this->CTest->GetTestProgressOutput() || !passed) { + cmCTestLog(this->CTest, HANDLER_OUTPUT, outputStream.str()); + } if (outputTestErrorsToConsole) { cmCTestLog(this->CTest, HANDLER_OUTPUT, this->ProcessOutput << std::endl); @@ -331,7 +357,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) return passed || skipped; } -bool cmCTestRunTest::StartAgain() +bool cmCTestRunTest::StartAgain(size_t completed) { if (!this->RunAgain) { return false; @@ -346,7 +372,7 @@ bool cmCTestRunTest::StartAgain() return true; } - this->StartTest(this->TotalNumberOfTests); + this->StartTest(completed, this->TotalNumberOfTests); return true; } @@ -398,12 +424,14 @@ void cmCTestRunTest::StartFailure(std::string const& output) { // Still need to log the Start message so the test summary records our // attempt to start this test - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(2 * getNumWidth(this->TotalNumberOfTests) + 8) - << "Start " - << std::setw(getNumWidth(this->TestHandler->GetMaxIndex())) - << this->TestProperties->Index << ": " - << this->TestProperties->Name << std::endl); + if (!this->CTest->GetTestProgressOutput()) { + cmCTestLog(this->CTest, HANDLER_OUTPUT, + std::setw(2 * getNumWidth(this->TotalNumberOfTests) + 8) + << "Start " + << std::setw(getNumWidth(this->TestHandler->GetMaxIndex())) + << this->TestProperties->Index << ": " + << this->TestProperties->Name << std::endl); + } this->ProcessOutput.clear(); if (!output.empty()) { @@ -425,16 +453,44 @@ void cmCTestRunTest::StartFailure(std::string const& output) this->TestProcess = cm::make_unique<cmProcess>(*this); } +std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const +{ + std::ostringstream outputStream; + outputStream << std::setw(getNumWidth(total)) << completed << "/"; + outputStream << std::setw(getNumWidth(total)) << total << " "; + + if (this->TestHandler->MemCheck) { + outputStream << "MemCheck"; + } else { + outputStream << "Test"; + } + + std::ostringstream indexStr; + indexStr << " #" << this->Index << ":"; + outputStream << std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) + << indexStr.str(); + outputStream << " "; + + return outputStream.str(); +} + // Starts the execution of a test. Returns once it has started -bool cmCTestRunTest::StartTest(size_t total) +bool cmCTestRunTest::StartTest(size_t completed, size_t total) { this->TotalNumberOfTests = total; // save for rerun case - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(2 * getNumWidth(total) + 8) - << "Start " - << std::setw(getNumWidth(this->TestHandler->GetMaxIndex())) - << this->TestProperties->Index << ": " - << this->TestProperties->Name << std::endl); + if (!this->CTest->GetTestProgressOutput()) { + cmCTestLog(this->CTest, HANDLER_OUTPUT, + std::setw(2 * getNumWidth(total) + 8) + << "Start " + << std::setw(getNumWidth(this->TestHandler->GetMaxIndex())) + << this->TestProperties->Index << ": " + << this->TestProperties->Name << std::endl); + } else { + std::string testName = + GetTestPrefix(completed, total) + this->TestProperties->Name + "\n"; + cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName); + } + this->ProcessOutput.clear(); // Return immediately if test is disabled @@ -689,44 +745,41 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout, void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) { - // if this is the last or only run of this test - // then print out completed / total + std::ostringstream outputStream; + + // If this is the last or only run of this test, or progress output is + // requested, then print out completed / total. // Only issue is if a test fails and we are running until fail // then it will never print out the completed / total, same would // got for run until pass. Trick is when this is called we don't // yet know if we are passing or failing. - if (this->NumberOfRunsLeft == 1) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(getNumWidth(total)) << completed << "/"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(getNumWidth(total)) << total << " "); + if (this->NumberOfRunsLeft == 1 || this->CTest->GetTestProgressOutput()) { + outputStream << std::setw(getNumWidth(total)) << completed << "/"; + outputStream << std::setw(getNumWidth(total)) << total << " "; } // if this is one of several runs of a test just print blank space // to keep things neat else { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(getNumWidth(total)) << " " - << " "); - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(getNumWidth(total)) << " " - << " "); + outputStream << std::setw(getNumWidth(total)) << " "; + outputStream << std::setw(getNumWidth(total)) << " "; } if (this->TestHandler->MemCheck) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "MemCheck"); + outputStream << "MemCheck"; } else { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Test"); + outputStream << "Test"; } std::ostringstream indexStr; indexStr << " #" << this->Index << ":"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) - << indexStr.str()); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + outputStream << std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) + << indexStr.str(); + outputStream << " "; + const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth(); std::string outname = this->TestProperties->Name + " "; outname.resize(maxTestNameWidth + 4, '.'); + outputStream << outname; *this->TestHandler->LogFile << this->TestProperties->Index << "/" << this->TestHandler->TotalNumberOfTests @@ -754,7 +807,10 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) *this->TestHandler->LogFile << this->ProcessOutput << "<end of output>" << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, outname.c_str()); + if (!this->CTest->GetTestProgressOutput()) { + cmCTestLog(this->CTest, HANDLER_OUTPUT, outputStream.str()); + } + cmCTestLog(this->CTest, DEBUG, "Testing " << this->TestProperties->Name << " ... "); } diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 7e80157..48a5064 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cmath> #include <set> #include <stddef.h> #include <string> @@ -64,7 +65,7 @@ public: void CompressOutput(); // launch the test process, return whether it started correctly - bool StartTest(size_t total); + bool StartTest(size_t completed, size_t total); // capture and report the test results bool EndTest(size_t completed, size_t total, bool started); // Called by ctest -N to log the command string @@ -72,7 +73,7 @@ public: void ComputeWeightedCost(); - bool StartAgain(); + bool StartAgain(size_t completed); void StartFailure(std::string const& output); @@ -93,6 +94,9 @@ private: // Run post processing of the process output for MemCheck void MemCheckPostProcess(); + // Returns "completed/total Test #Index: " + std::string GetTestPrefix(size_t completed, size_t total) const; + cmCTestTestHandler::cmCTestTestProperties* TestProperties; bool TimeoutIsForStopTime = false; // Pointer back to the "parent"; the handler that invoked this test run @@ -118,14 +122,7 @@ private: inline int getNumWidth(size_t n) { - int numWidth = 1; - if (n >= 10) { - numWidth = 2; - } - if (n >= 100) { - numWidth = 3; - } - return numWidth; + return static_cast<int>(std::log10(n)) + 1; } #endif diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index c7f3f39..ecf309a 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -392,8 +392,12 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); std::string local_file = file; + bool initialize_cdash_buildid = false; if (!cmSystemTools::FileExists(local_file)) { local_file = localprefix + "/" + file; + // If this file exists within the local Testing directory we assume + // that it will be associated with the current build in CDash. + initialize_cdash_buildid = true; } std::string remote_file = remoteprefix + cmSystemTools::GetFilenameName(file); @@ -425,26 +429,30 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ((url.find('?') == std::string::npos) ? '?' : '&') + "FileName=" + ofile; - cmCTestCurl ctest_curl(this->CTest); - upload_as += "&build="; - upload_as += - ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")); - upload_as += "&site="; - upload_as += - ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")); - upload_as += "&stamp="; - upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); - upload_as += "-"; - upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script")); - cmake* cm = ch->GetCMake(); - if (cm) { - const char* subproject = - cm->GetState()->GetGlobalProperty("SubProject"); - if (subproject) { - upload_as += "&subproject="; - upload_as += ctest_curl.Escape(subproject); + if (initialize_cdash_buildid) { + // Provide extra arguments to CDash so that it can initialize and + // return a buildid. + cmCTestCurl ctest_curl(this->CTest); + upload_as += "&build="; + upload_as += + ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")); + upload_as += "&site="; + upload_as += + ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")); + upload_as += "&stamp="; + upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); + upload_as += "-"; + upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); + cmCTestScriptHandler* ch = static_cast<cmCTestScriptHandler*>( + this->CTest->GetHandler("script")); + cmake* cm = ch->GetCMake(); + if (cm) { + const char* subproject = + cm->GetState()->GetGlobalProperty("SubProject"); + if (subproject) { + upload_as += "&subproject="; + upload_as += ctest_curl.Escape(subproject); + } } } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 6639787..908eea1 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -24,6 +24,11 @@ #include <time.h> #include <utility> #include <vector> +#if defined(_WIN32) +# include <windows.h> // IWYU pragma: keep +#else +# include <unistd.h> // IWYU pragma: keep +#endif #include "cmAlgorithms.h" #include "cmCTestBuildAndTestHandler.h" @@ -263,6 +268,8 @@ cmCTest::cmCTest() this->Failover = false; this->ForceNewCTestProcess = false; this->TomorrowTag = false; + this->TestProgressOutput = false; + this->FlushTestProgressLine = false; this->Verbose = false; this->Debug = false; @@ -290,10 +297,16 @@ cmCTest::cmCTest() this->OutputTestOutputOnTestFailure = false; this->RepeatTests = 1; // default to run each test once this->RepeatUntilFail = false; - std::string outOnFail; - if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", outOnFail)) { - this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(outOnFail); + + std::string envValue; + if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) { + this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(envValue); + } + envValue.clear(); + if (cmSystemTools::GetEnv("CTEST_PROGRESS_OUTPUT", envValue)) { + this->TestProgressOutput = !cmSystemTools::IsOff(envValue); } + this->InitStreams(); this->Parts[PartStart].SetName("Start"); @@ -1875,6 +1888,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, if (this->CheckArgument(arg, "-Q", "--quiet")) { this->Quiet = true; } + if (this->CheckArgument(arg, "--progress")) { + this->TestProgressOutput = true; + } if (this->CheckArgument(arg, "-V", "--verbose")) { this->Verbose = true; } @@ -2038,6 +2054,23 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, return true; } +bool cmCTest::ProgressOutputSupportedByConsole() const +{ +#if defined(_WIN32) + // On Windows we need a console buffer. + void* console = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; + return GetConsoleScreenBufferInfo(console, &csbi); +#else + // On UNIX we need a non-dumb tty. + std::string term_env_variable; + if (cmSystemTools::GetEnv("TERM", term_env_variable)) { + return isatty(1) && term_env_variable != "dumb"; + } +#endif + return false; +} + // handle the -S -SR and -SP arguments void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, bool& SRArgumentSpecified) @@ -2192,6 +2225,18 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) } } + // TestProgressOutput only supported if console supports it and not logging + // to a file + this->TestProgressOutput = this->TestProgressOutput && + !this->OutputLogFile && this->ProgressOutputSupportedByConsole(); +#ifdef _WIN32 + if (this->TestProgressOutput) { + // Disable output line buffering so we can print content without + // a newline. + std::setvbuf(stdout, nullptr, _IONBF, 0); + } +#endif + // now what should cmake do? if --build-and-test was specified then // we run the build and test handler and return if (cmakeAndTest) { @@ -2761,6 +2806,7 @@ static const char* cmCTestStringLogType[] = { "DEBUG", "OUTPUT", "HANDLER_OUTPUT", "HANDLER_PROGRESS_OUTPUT", + "HANDLER_TEST_PROGRESS_OUTPUT", "HANDLER_VERBOSE_OUTPUT", "WARNING", "ERROR_MESSAGE", @@ -2821,6 +2867,34 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, if (!this->Quiet) { std::ostream& out = *this->StreamOut; std::ostream& err = *this->StreamErr; + + if (logType == HANDLER_TEST_PROGRESS_OUTPUT) { + if (this->TestProgressOutput) { + cmCTestLogOutputFileLine(out); + if (this->FlushTestProgressLine) { + printf("\r"); + this->FlushTestProgressLine = false; + out.flush(); + } + + std::string msg_str{ msg }; + auto const lineBreakIt = msg_str.find('\n'); + if (lineBreakIt != std::string::npos) { + this->FlushTestProgressLine = true; + msg_str.erase(std::remove(msg_str.begin(), msg_str.end(), '\n'), + msg_str.end()); + } + + out << msg_str; +#ifndef _WIN32 + printf("\x1B[K"); // move caret to end +#endif + out.flush(); + return; + } + logType = HANDLER_OUTPUT; + } + switch (logType) { case DEBUG: if (this->Debug) { diff --git a/Source/cmCTest.h b/Source/cmCTest.h index c6ece98..345b538 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -390,6 +390,7 @@ public: OUTPUT, HANDLER_OUTPUT, HANDLER_PROGRESS_OUTPUT, + HANDLER_TEST_PROGRESS_OUTPUT, HANDLER_VERBOSE_OUTPUT, WARNING, ERROR_MESSAGE, @@ -429,6 +430,8 @@ public: void SetFailover(bool failover) { this->Failover = failover; } bool GetFailover() { return this->Failover; } + bool GetTestProgressOutput() const { return this->TestProgressOutput; } + bool GetVerbose() { return this->Verbose; } bool GetExtraVerbose() { return this->ExtraVerbose; } @@ -467,6 +470,7 @@ private: std::string ConfigType; std::string ScheduleType; std::chrono::system_clock::time_point StopTime; + bool TestProgressOutput; bool Verbose; bool ExtraVerbose; bool ProduceXML; @@ -476,6 +480,8 @@ private: bool PrintLabels; bool Failover; + bool FlushTestProgressLine; + bool ForceNewCTestProcess; bool RunConfigurationScript; @@ -561,6 +567,9 @@ private: bool HandleCommandLineArguments(size_t& i, std::vector<std::string>& args, std::string& errormsg); + /** returns true iff the console supports progress output */ + bool ProgressOutputSupportedByConsole() const; + /** handle the -S -SP and -SR arguments */ void HandleScriptArguments(size_t& i, std::vector<std::string>& args, bool& SRArgumentSpecified); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 54af2f4..1f76703 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1275,6 +1275,33 @@ protected: this->DirPermissions |= mode_world_read; this->DirPermissions |= mode_world_execute; } + + bool GetDefaultDirectoryPermissions(mode_t** mode) + { + // check if default dir creation permissions were set + const char* default_dir_install_permissions = + this->Makefile->GetDefinition( + "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (default_dir_install_permissions && *default_dir_install_permissions) { + std::vector<std::string> items; + cmSystemTools::ExpandListArgument(default_dir_install_permissions, + items); + for (const auto& arg : items) { + if (!this->CheckPermissions(arg, **mode)) { + std::ostringstream e; + e << this->FileCommand->GetError() + << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS " + "variable."; + this->FileCommand->SetError(e.str()); + return false; + } + } + } else { + *mode = nullptr; + } + + return true; + } }; bool cmFileCopier::Parse(std::vector<std::string> const& args) @@ -1668,8 +1695,15 @@ bool cmFileCopier::InstallDirectory(const char* source, this->ReportCopy(destination, TypeDir, !cmSystemTools::FileIsDirectory(destination)); + // check if default dir creation permissions were set + mode_t default_dir_mode_v = 0; + mode_t* default_dir_mode = &default_dir_mode_v; + if (!this->GetDefaultDirectoryPermissions(&default_dir_mode)) { + return false; + } + // Make sure the destination directory exists. - if (!cmSystemTools::MakeDirectory(destination)) { + if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) { std::ostringstream e; e << this->Name << " cannot make directory \"" << destination << "\": " << cmSystemTools::GetLastSystemError(); @@ -2073,23 +2107,9 @@ bool cmFileInstaller::HandleInstallDestination() // check if default dir creation permissions were set mode_t default_dir_mode_v = 0; - mode_t* default_dir_mode = nullptr; - const char* default_dir_install_permissions = this->Makefile->GetDefinition( - "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); - if (default_dir_install_permissions && *default_dir_install_permissions) { - std::vector<std::string> items; - cmSystemTools::ExpandListArgument(default_dir_install_permissions, items); - for (const auto& arg : items) { - if (!this->CheckPermissions(arg, default_dir_mode_v)) { - std::ostringstream e; - e << this->FileCommand->GetError() - << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable."; - this->FileCommand->SetError(e.str()); - return false; - } - } - - default_dir_mode = &default_dir_mode_v; + mode_t* default_dir_mode = &default_dir_mode_v; + if (!this->GetDefaultDirectoryPermissions(&default_dir_mode)) { + return false; } if (this->InstallType != cmInstallType_DIRECTORY) { diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index c8dc392..f423560 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -181,6 +181,36 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, output)); } + const std::vector<std::string>& byproducts = ccg.GetByproducts(); + for (std::string const& byproduct : byproducts) { + this->CleanFiles.push_back( + this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, + byproduct)); + } + } + } + + // Add byproducts from build events to the clean rules + if (clean) { + std::vector<cmCustomCommand> buildEventCommands = + this->GeneratorTarget->GetPreBuildCommands(); + + buildEventCommands.insert( + buildEventCommands.end(), + this->GeneratorTarget->GetPreLinkCommands().begin(), + this->GeneratorTarget->GetPreLinkCommands().end()); + buildEventCommands.insert( + buildEventCommands.end(), + this->GeneratorTarget->GetPostBuildCommands().begin(), + this->GeneratorTarget->GetPostBuildCommands().end()); + + for (const auto& be : buildEventCommands) { + const std::vector<std::string>& byproducts = be.GetByproducts(); + for (std::string const& byproduct : byproducts) { + this->CleanFiles.push_back( + this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, + byproduct)); + } } } std::vector<cmSourceFile const*> headerSources; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index b338dea..ca8a776 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -27,6 +27,7 @@ static const char* cmDocumentationUsage[][2] = { { nullptr, static const char* cmDocumentationOptions[][2] = { { "-C <cfg>, --build-config <cfg>", "Choose configuration to test." }, + { "--progress", "Enable short progress output from tests." }, { "-V,--verbose", "Enable verbose output from tests." }, { "-VV,--extra-verbose", "Enable more verbose output from tests." }, { "--debug", "Displaying more verbose internals of CTest." }, |