diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/CTest/cmCTestMultiProcessHandler.cxx | 7 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.cxx | 36 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.h | 11 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.cxx | 61 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.h | 15 | ||||
-rw-r--r-- | Source/CTest/cmProcess.cxx | 23 | ||||
-rw-r--r-- | Source/CTest/cmProcess.h | 18 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 4 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 15 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioVersionedGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 11 |
14 files changed, 169 insertions, 40 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 2584a62..e2f28c1 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 26) -set(CMake_VERSION_PATCH 20230601) +set(CMake_VERSION_PATCH 20230605) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 44eccb2..7d22a87 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -634,8 +634,9 @@ void cmCTestMultiProcessHandler::FinishTestProcess( int test = runner->GetIndex(); auto* properties = runner->GetTestProperties(); - bool testResult = runner->EndTest(this->Completed, this->Total, started); - if (runner->TimedOutForStopTime()) { + cmCTestRunTest::EndTestResult testResult = + runner->EndTest(this->Completed, this->Total, started); + if (testResult.StopTimePassed) { this->SetStopTimePassed(); } if (started) { @@ -646,7 +647,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess( } } - if (testResult) { + if (testResult.Passed) { this->Passed->push_back(properties->Name); } else if (!properties->Disabled) { this->Failed->push_back(properties->Name); diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index cd2b230..9b62183 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -95,16 +95,15 @@ void cmCTestRunTest::CheckOutput(std::string const& line) } } -bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) +cmCTestRunTest::EndTestResult cmCTestRunTest::EndTest(size_t completed, + size_t total, + bool started) { this->WriteLogOutputTop(completed, total); std::string reason; bool passed = true; cmProcess::State res = started ? this->TestProcess->GetProcessStatus() : cmProcess::State::Error; - if (res != cmProcess::State::Expired) { - this->TimeoutIsForStopTime = false; - } std::int64_t retVal = this->TestProcess->GetExitValue(); bool forceFail = false; bool forceSkip = false; @@ -182,6 +181,11 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } } else if (res == cmProcess::State::Expired) { outputStream << "***Timeout "; + if (this->TestProperties->TimeoutSignal && + this->TestProcess->GetTerminationStyle() == + cmProcess::Termination::Custom) { + outputStream << "(" << this->TestProperties->TimeoutSignal->Name << ") "; + } this->TestResult.Status = cmCTestTestHandler::TIMEOUT; outputTestErrorsToConsole = this->CTest->GetOutputTestOutputOnTestFailure(); @@ -344,8 +348,15 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) if (!this->NeedsToRepeat()) { this->TestHandler->TestResults.push_back(this->TestResult); } + cmCTestRunTest::EndTestResult testResult; + testResult.Passed = passed || skipped; + if (res == cmProcess::State::Expired && + this->TestProcess->GetTimeoutReason() == + cmProcess::TimeoutReason::StopTime) { + testResult.StopTimePassed = true; + } this->TestProcess.reset(); - return passed || skipped; + return testResult; } bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner, @@ -534,6 +545,19 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) this->TestResult.Name = this->TestProperties->Name; this->TestResult.Path = this->TestProperties->Directory; + // Reject invalid test properties. + if (this->TestProperties->Error) { + std::string const& msg = *this->TestProperties->Error; + *this->TestHandler->LogFile << msg << std::endl; + cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl); + this->TestResult.CompletionStatus = "Invalid Test Properties"; + this->TestResult.Status = cmCTestTestHandler::NOT_RUN; + this->TestResult.Output = msg; + this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); + return false; + } + // Return immediately if test is disabled if (this->TestProperties->Disabled) { this->TestResult.CompletionStatus = "Disabled"; @@ -772,8 +796,8 @@ bool cmCTestRunTest::ForkProcess() timeRemaining = cmDuration::zero(); } if (!timeout || timeRemaining < *timeout) { - this->TimeoutIsForStopTime = true; timeout = timeRemaining; + this->TestProcess->SetTimeoutReason(cmProcess::TimeoutReason::StopTime); } if (timeout) { diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 6a507f4..fed7296 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -71,10 +71,16 @@ public: std::string const& output, std::string const& detail); + struct EndTestResult + { + bool Passed = false; + bool StopTimePassed = false; + }; + // launch the test process, return whether it started correctly bool StartTest(size_t completed, size_t total); // capture and report the test results - bool EndTest(size_t completed, size_t total, bool started); + EndTestResult EndTest(size_t completed, size_t total, bool started); // Called by ctest -N to log the command string void ComputeArguments(); @@ -90,8 +96,6 @@ public: void FinalizeTest(bool started = true); - bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; } - void SetUseAllocatedResources(bool use) { this->UseAllocatedResources = use; @@ -120,7 +124,6 @@ private: 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 cmCTestTestHandler* TestHandler; cmCTest* CTest; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 7764f2b..6b02a5e 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -17,6 +17,10 @@ #include <sstream> #include <utility> +#ifndef _WIN32 +# include <csignal> +#endif + #include <cm/memory> #include <cm/string_view> #include <cmext/algorithm> @@ -2171,6 +2175,16 @@ void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length, } } +void cmCTestTestHandler::cmCTestTestProperties::AppendError( + cm::string_view err) +{ + if (this->Error) { + *this->Error = cmStrCat(*this->Error, '\n', err); + } else { + this->Error = err; + } +} + bool cmCTestTestHandler::SetTestsProperties( const std::vector<std::string>& args) { @@ -2247,6 +2261,53 @@ bool cmCTestTestHandler::SetTestsProperties( rt.FixturesRequired.insert(lval.begin(), lval.end()); } else if (key == "TIMEOUT"_s) { rt.Timeout = cmDuration(atof(val.c_str())); + } else if (key == "TIMEOUT_SIGNAL_NAME"_s) { +#ifdef _WIN32 + rt.AppendError("TIMEOUT_SIGNAL_NAME is not supported on Windows."); +#else + std::string const& signalName = val; + Signal s; + if (signalName == "SIGINT"_s) { + s.Number = SIGINT; + } else if (signalName == "SIGQUIT"_s) { + s.Number = SIGQUIT; + } else if (signalName == "SIGTERM"_s) { + s.Number = SIGTERM; + } else if (signalName == "SIGUSR1"_s) { + s.Number = SIGUSR1; + } else if (signalName == "SIGUSR2"_s) { + s.Number = SIGUSR2; + } + if (s.Number) { + s.Name = signalName; + rt.TimeoutSignal = std::move(s); + } else { + rt.AppendError(cmStrCat("TIMEOUT_SIGNAL_NAME \"", signalName, + "\" not supported on this platform.")); + } +#endif + } else if (key == "TIMEOUT_SIGNAL_GRACE_PERIOD"_s) { +#ifdef _WIN32 + rt.AppendError( + "TIMEOUT_SIGNAL_GRACE_PERIOD is not supported on Windows."); +#else + std::string const& gracePeriod = val; + static cmDuration minGracePeriod{ 0 }; + static cmDuration maxGracePeriod{ 60 }; + cmDuration gp = cmDuration(atof(gracePeriod.c_str())); + if (gp <= minGracePeriod) { + rt.AppendError(cmStrCat("TIMEOUT_SIGNAL_GRACE_PERIOD \"", + gracePeriod, "\" is not greater than \"", + minGracePeriod.count(), "\" seconds.")); + } else if (gp > maxGracePeriod) { + rt.AppendError(cmStrCat("TIMEOUT_SIGNAL_GRACE_PERIOD \"", + gracePeriod, + "\" is not less than the maximum of \"", + maxGracePeriod.count(), "\" seconds.")); + } else { + rt.TimeoutGracePeriod = gp; + } +#endif } else if (key == "COST"_s) { rt.Cost = static_cast<float>(atof(val.c_str())); } else if (key == "REQUIRED_FILES"_s) { diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index b7c0faf..315a5b7 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -15,6 +15,7 @@ #include <vector> #include <cm/optional> +#include <cm/string_view> #include "cmsys/RegularExpression.hxx" @@ -119,12 +120,16 @@ public: bool operator!=(const cmCTestTestResourceRequirement& other) const; }; - // NOTE: This struct is Saved/Restored - // in cmCTestTestHandler, if you add to this class - // then you must add the new members to that code or - // ctest -j N will break for that feature + struct Signal + { + int Number = 0; + std::string Name; + }; + struct cmCTestTestProperties { + void AppendError(cm::string_view err); + cm::optional<std::string> Error; std::string Name; std::string Directory; std::vector<std::string> Args; @@ -148,6 +153,8 @@ public: int PreviousRuns = 0; bool RunSerial = false; cm::optional<cmDuration> Timeout; + cm::optional<Signal> TimeoutSignal; + cm::optional<cmDuration> TimeoutGracePeriod; cmDuration AlternateTimeout; int Index = 0; // Requested number of process slots diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 780d626..269b92c 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -13,6 +13,7 @@ #include "cmCTest.h" #include "cmCTestRunTest.h" +#include "cmCTestTestHandler.h" #include "cmGetPipes.h" #include "cmStringAlgorithms.h" #if defined(_WIN32) @@ -274,7 +275,29 @@ void cmProcess::OnTimeoutCB(uv_timer_t* timer) void cmProcess::OnTimeout() { + bool const wasExecuting = this->ProcessState == cmProcess::State::Executing; this->ProcessState = cmProcess::State::Expired; + + // If the test process is still executing normally, and we timed out because + // the test timeout was reached, send the custom timeout signal, if any. + if (wasExecuting && this->TimeoutReason_ == TimeoutReason::Normal) { + cmCTestTestHandler::cmCTestTestProperties* p = + this->Runner->GetTestProperties(); + if (p->TimeoutSignal) { + this->TerminationStyle = Termination::Custom; + uv_process_kill(this->Process, p->TimeoutSignal->Number); + if (p->TimeoutGracePeriod) { + this->Timeout = *p->TimeoutGracePeriod; + } else { + static const cmDuration defaultGracePeriod{ 1.0 }; + this->Timeout = defaultGracePeriod; + } + this->StartTimer(); + return; + } + } + + this->TerminationStyle = Termination::Forced; bool const was_still_reading = !this->ReadHandleClosed; if (!this->ReadHandleClosed) { this->ReadHandleClosed = true; diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index 1578687..dc755eb 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -41,6 +41,14 @@ public: // Return true if the process starts bool StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity); + enum class TimeoutReason + { + Normal, + StopTime, + }; + void SetTimeoutReason(TimeoutReason r) { this->TimeoutReason_ = r; } + TimeoutReason GetTimeoutReason() const { return this->TimeoutReason_; } + enum class State { Starting, @@ -77,8 +85,17 @@ public: return std::move(this->Runner); } + enum class Termination + { + Normal, + Custom, + Forced, + }; + Termination GetTerminationStyle() const { return this->TerminationStyle; } + private: cm::optional<cmDuration> Timeout; + TimeoutReason TimeoutReason_ = TimeoutReason::Normal; std::chrono::steady_clock::time_point StartTime; cmDuration TotalTime; bool ReadHandleClosed = false; @@ -128,4 +145,5 @@ private: std::vector<const char*> ProcessArgs; int Id; int64_t ExitValue; + Termination TerminationStyle = Termination::Normal; }; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 5c2e238..3cefeda 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -28,6 +28,7 @@ #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" #include "cmEvaluatedTargetProperty.h" +#include "cmExperimental.h" #include "cmFileSet.h" #include "cmFileTimes.h" #include "cmGeneratedFileStream.h" @@ -8907,7 +8908,8 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport( // Else, an empty CMAKE_CXX_STANDARD_DEFAULT means CMake does not detect and // set a default standard level for this compiler, so assume all standards // are available. - if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) { + if (!cmExperimental::HasSupportEnabled( + *this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi)) { return Cxx20SupportLevel::MissingExperimentalFlag; } return Cxx20SupportLevel::Supported; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 07c8f17..5175aae 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1465,19 +1465,6 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const return false; } -void cmGlobalGenerator::CxxModuleSupportCheck() const -{ - bool const diagnose = !this->DiagnosedCxxModuleSupport && - !this->CMakeInstance->GetIsInTryCompile(); - if (diagnose) { - this->DiagnosedCxxModuleSupport = true; - this->GetCMakeInstance()->IssueMessage( - MessageType::AUTHOR_WARNING, - "C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP " - "is experimental. It is meant only for compiler developers to try."); - } -} - void cmGlobalGenerator::ComputeBuildFileGenerators() { for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { @@ -1641,8 +1628,6 @@ void cmGlobalGenerator::Generate() // it builds by default. this->InitializeProgressMarks(); - this->DiagnosedCxxModuleSupport = false; - this->ProcessEvaluationFiles(); this->CMakeInstance->UpdateProgress("Generating", 0.1f); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 01afabd..9aefaff 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -661,8 +661,6 @@ protected: virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const; - void CxxModuleSupportCheck() const; - bool AddHeaderSetVerification(); bool AddAutomaticSources(); @@ -775,8 +773,6 @@ private: std::map<std::string, StripCommandStyle> StripCommandStyleMap; #endif - mutable bool DiagnosedCxxModuleSupport = false; - // Deferral id generation. size_t NextDeferId = 0; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 9380d7d..e20f157 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -874,7 +874,6 @@ bool cmGlobalNinjaGenerator::CheckLanguages( bool cmGlobalNinjaGenerator::CheckCxxModuleSupport() { - this->CxxModuleSupportCheck(); if (this->NinjaSupportsDyndepsCxx) { return true; } diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h index 558ea7c..8712459 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.h +++ b/Source/cmGlobalVisualStudioVersionedGenerator.h @@ -50,7 +50,6 @@ public: bool CheckCxxModuleSupport() override { - this->CxxModuleSupportCheck(); return this->SupportsCxxModuleDyndep(); } bool SupportsCxxModuleDyndep() const override diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 63b2043..7ad4023 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1201,6 +1201,17 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) { cmSystemTools::ConvertToUnixSlashes(impDirVec[i]); } + + // The CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES are computed using + // try_compile in CMAKE_DETERMINE_COMPILER_ABI, but the implicit include + // directories are not known during that try_compile. This can be a + // problem when the HIP runtime include path is /usr/include because the + // runtime include path is always added to the userDirs and the compiler + // includes standard library headers via "__clang_hip_runtime_wrapper.h". + if (lang == "HIP" && impDirVec.size() == impDirVecOldSize && + !cm::contains(impDirVec, "/usr/include")) { + implicitExclude.emplace("/usr/include"); + } } // The Platform/UnixPaths module used to hard-code /usr/include for C, CXX, |