From 8d4743b9e98268e693007b3af01b63c8f0b4334a Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Tue, 28 Jan 2025 13:10:53 +0100 Subject: cmCTestBuildHandler: Store path of temporary log file --- Source/CTest/cmCTestBuildHandler.cxx | 5 +++-- Source/CTest/cmCTestBuildHandler.h | 1 + Source/CTest/cmCTestGenericHandler.cxx | 4 +--- Source/CTest/cmCTestGenericHandler.h | 6 ------ Source/cmCTest.cxx | 1 - Source/cmGeneratedFileStream.h | 5 +++++ 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index a830bef..af54e56 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -302,6 +302,8 @@ int cmCTestBuildHandler::ProcessHandler() "Cannot create build log file" << std::endl); } + this->LogFileName = ofs.GetTempName(); + // Create lists of regular expression strings for errors, error exceptions, // warnings and warning exceptions. std::vector::size_type cc; @@ -884,8 +886,7 @@ bool cmCTestBuildHandler::RunMakeCommand(std::string const& command, // Use temporary BuildLog file to populate this error for // CDash. ofs.flush(); - reporter.LogOut = this->LogFileNames["Build"]; - reporter.LogOut += ".tmp"; + reporter.LogOut = this->LogFileName; reporter.WriteXML(); } } else { diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h index 00ed8c2..9d9b847 100644 --- a/Source/CTest/cmCTestBuildHandler.h +++ b/Source/CTest/cmCTestBuildHandler.h @@ -145,6 +145,7 @@ private: bool UseCTestLaunch = false; std::string CTestLaunchDir; + std::string LogFileName; class LaunchHelper; friend class LaunchHelper; diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 625333f..1e3d20d 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -3,9 +3,9 @@ #include "cmCTestGenericHandler.h" #include +#include #include "cmCTest.h" -#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmCTestGenericHandler::cmCTestGenericHandler(cmCTest* ctest) @@ -72,8 +72,6 @@ bool cmCTestGenericHandler::StartLogFile(char const* name, ostr << "_" << this->CTest->GetCurrentTag(); } ostr << ".log"; - this->LogFileNames[name] = - cmStrCat(this->CTest->GetBinaryDir(), "/Testing/Temporary/", ostr.str()); if (!this->CTest->OpenOutputFile("Temporary", ostr.str(), xofs)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create log file: " << ostr.str() << std::endl); diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index 02fce78..4fc9adb 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h @@ -4,9 +4,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include -#include - #include "cmCTest.h" #include "cmSystemTools.h" @@ -52,8 +49,6 @@ public: cmCTestGenericHandler(cmCTest* ctest); virtual ~cmCTestGenericHandler(); - using t_StringToString = std::map; - void SetSubmitIndex(int idx) { this->SubmitIndex = idx; } int GetSubmitIndex() { return this->SubmitIndex; } @@ -75,7 +70,6 @@ protected: unsigned long TestLoad = 0; cmSystemTools::OutputOption HandlerVerbose = cmSystemTools::OUTPUT_NONE; cmCTest* CTest; - t_StringToString LogFileNames; cmake* CMake = nullptr; int SubmitIndex = 0; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 603b1f4..af53085 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -665,7 +665,6 @@ bool cmCTest::OpenOutputFile(std::string const& path, std::string const& name, } } std::string filename = testingDir + "/" + name; - stream.SetTempExt("tmp"); stream.Open(filename); if (!stream) { cmCTestLog(this, ERROR_MESSAGE, diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h index b440fa9..c832bc3 100644 --- a/Source/cmGeneratedFileStream.h +++ b/Source/cmGeneratedFileStream.h @@ -148,6 +148,11 @@ public: void SetTempExt(std::string const& ext); /** + * Get the name of the temporary file. + */ + std::string const& GetTempName() const { return this->TempName; } + + /** * Write a specific string using an alternate encoding. * Afterward, the original encoding is restored. */ -- cgit v0.12 From 509b2cca66a7fe48097dee62026aa9994ec367cf Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Tue, 28 Jan 2025 13:04:00 +0100 Subject: cmCTest: Extract utility functions from cmCTestGenericHandler --- Source/CTest/cmCTestGenericHandler.cxx | 59 +---------------------------- Source/cmCTest.cxx | 69 +++++++++++++++++++++++++++++++--- Source/cmCTest.h | 6 ++- 3 files changed, 71 insertions(+), 63 deletions(-) diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 1e3d20d..eea2da3 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -2,17 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestGenericHandler.h" -#include -#include - #include "cmCTest.h" -#include "cmSystemTools.h" cmCTestGenericHandler::cmCTestGenericHandler(cmCTest* ctest) : CTest(ctest) { this->SetVerbose(ctest->GetExtraVerbose()); - this->SetSubmitIndex(ctest->GetSubmitIndex()); } cmCTestGenericHandler::~cmCTestGenericHandler() = default; @@ -21,61 +16,11 @@ bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part, char const* name, cmGeneratedFileStream& xofs) { - if (!name) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot create resulting XML file without providing the name" - << std::endl); - return false; - } - std::ostringstream ostr; - ostr << name; - if (this->SubmitIndex > 0) { - ostr << "_" << this->SubmitIndex; - } - ostr << ".xml"; - if (this->CTest->GetCurrentTag().empty()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Current Tag empty, this may mean NightlyStartTime / " - "CTEST_NIGHTLY_START_TIME was not set correctly. Or " - "maybe you forgot to call ctest_start() before calling " - "ctest_configure()." - << std::endl); - cmSystemTools::SetFatalErrorOccurred(); - return false; - } - if (!this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(), ostr.str(), - xofs, true)) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot create resulting XML file: " << ostr.str() - << std::endl); - return false; - } - this->CTest->AddSubmitFile(part, ostr.str()); - return true; + return this->CTest->StartResultingXML(part, name, this->SubmitIndex, xofs); } bool cmCTestGenericHandler::StartLogFile(char const* name, cmGeneratedFileStream& xofs) { - if (!name) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot create log file without providing the name" - << std::endl); - return false; - } - std::ostringstream ostr; - ostr << "Last" << name; - if (this->SubmitIndex > 0) { - ostr << "_" << this->SubmitIndex; - } - if (!this->CTest->GetCurrentTag().empty()) { - ostr << "_" << this->CTest->GetCurrentTag(); - } - ostr << ".log"; - if (!this->CTest->OpenOutputFile("Temporary", ostr.str(), xofs)) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot create log file: " << ostr.str() << std::endl); - return false; - } - return true; + return this->CTest->StartLogFile(name, this->SubmitIndex, xofs); } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index af53085..5a7c309 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -3102,11 +3102,6 @@ bool cmCTest::GetExtraVerbose() const return this->Impl->ExtraVerbose; } -int cmCTest::GetSubmitIndex() const -{ - return this->Impl->SubmitIndex; -} - bool cmCTest::GetInteractiveDebugMode() const { return this->Impl->InteractiveDebugMode; @@ -3611,3 +3606,67 @@ bool cmCTest::CompressString(std::string& str) return true; } + +bool cmCTest::StartResultingXML(Part part, char const* name, int submitIndex, + cmGeneratedFileStream& xofs) +{ + if (!name) { + cmCTestLog( + this, ERROR_MESSAGE, + "Cannot create resulting XML file without providing the name\n"); + return false; + } + if (submitIndex == 0) { + submitIndex = this->Impl->SubmitIndex; + } + std::ostringstream ostr; + ostr << name; + if (submitIndex > 0) { + ostr << "_" << submitIndex; + } + ostr << ".xml"; + if (this->Impl->CurrentTag.empty()) { + cmCTestLog(this, ERROR_MESSAGE, + "Current Tag empty, this may mean NightlyStartTime / " + "CTEST_NIGHTLY_START_TIME was not set correctly. Or " + "maybe you forgot to call ctest_start() before calling " + "ctest_configure().\n"); + cmSystemTools::SetFatalErrorOccurred(); + return false; + } + if (!this->OpenOutputFile(this->Impl->CurrentTag, ostr.str(), xofs, true)) { + cmCTestLog(this, ERROR_MESSAGE, + "Cannot create resulting XML file: " << ostr.str() << '\n'); + return false; + } + this->AddSubmitFile(part, ostr.str()); + return true; +} + +bool cmCTest::StartLogFile(char const* name, int submitIndex, + cmGeneratedFileStream& xofs) +{ + if (!name) { + cmCTestLog(this, ERROR_MESSAGE, + "Cannot create log file without providing the name\n"); + return false; + } + if (submitIndex == 0) { + submitIndex = this->Impl->SubmitIndex; + } + std::ostringstream ostr; + ostr << "Last" << name; + if (submitIndex > 0) { + ostr << "_" << submitIndex; + } + if (!this->Impl->CurrentTag.empty()) { + ostr << "_" << this->Impl->CurrentTag; + } + ostr << ".log"; + if (!this->OpenOutputFile("Temporary", ostr.str(), xofs)) { + cmCTestLog(this, ERROR_MESSAGE, + "Cannot create log file: " << ostr.str() << '\n'); + return false; + } + return true; +} diff --git a/Source/cmCTest.h b/Source/cmCTest.h index b308344..c6bfede 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -385,7 +385,11 @@ public: bool GetVerbose() const; bool GetExtraVerbose() const; - int GetSubmitIndex() const; + + bool StartResultingXML(Part part, char const* name, int submitIndex, + cmGeneratedFileStream& xofs); + bool StartLogFile(char const* name, int submitIndex, + cmGeneratedFileStream& xofs); void AddSiteProperties(cmXMLWriter& xml, cmake* cm); -- cgit v0.12 From fda055c2605420a2a23d1a2022a338a5d2de5861 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Tue, 28 Jan 2025 09:12:28 +0100 Subject: cmCTestConfigureHandler: Move class into cmCTestConfigureCommand.cxx Place declaration and definitions into places where following refactoring will cause minimal deltas. --- Source/CMakeLists.txt | 1 - Source/CTest/cmCTestConfigureCommand.cxx | 99 +++++++++++++++++++++++++++++- Source/CTest/cmCTestConfigureHandler.cxx | 101 ------------------------------- Source/CTest/cmCTestConfigureHandler.h | 26 -------- 4 files changed, 98 insertions(+), 129 deletions(-) delete mode 100644 Source/CTest/cmCTestConfigureHandler.cxx delete mode 100644 Source/CTest/cmCTestConfigureHandler.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 06eb9b4..745c38c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -1062,7 +1062,6 @@ add_library( CTest/cmCTestBuildHandler.cxx CTest/cmCTestCommand.cxx CTest/cmCTestConfigureCommand.cxx - CTest/cmCTestConfigureHandler.cxx CTest/cmCTestCoverageCommand.cxx CTest/cmCTestCoverageHandler.cxx CTest/cmCTestCurl.cxx diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 27f4074..87b7e29 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -2,8 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestConfigureCommand.h" +#include #include #include +#include #include #include @@ -12,17 +14,30 @@ #include "cmArgumentParser.h" #include "cmCTest.h" -#include "cmCTestConfigureHandler.h" #include "cmCTestGenericHandler.h" +#include "cmDuration.h" #include "cmExecutionStatus.h" +#include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmList.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmValue.h" +#include "cmXMLWriter.h" #include "cmake.h" +class cmCTestConfigureHandler : public cmCTestGenericHandler +{ +public: + cmCTestConfigureHandler(cmCTest* ctest) + : cmCTestGenericHandler(ctest) + { + } + + int ProcessHandler() override; +}; + std::unique_ptr cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, cmExecutionStatus& status) const @@ -157,6 +172,88 @@ cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, return std::unique_ptr(std::move(handler)); } +int cmCTestConfigureHandler::ProcessHandler() +{ + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "Configure project" << std::endl, this->Quiet); + std::string cCommand = + this->CTest->GetCTestConfiguration("ConfigureCommand"); + if (cCommand.empty()) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot find ConfigureCommand key in the DartConfiguration.tcl" + << std::endl); + return -1; + } + + std::string buildDirectory = + this->CTest->GetCTestConfiguration("BuildDirectory"); + if (buildDirectory.empty()) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot find BuildDirectory key in the DartConfiguration.tcl" + << std::endl); + return -1; + } + + auto elapsed_time_start = std::chrono::steady_clock::now(); + std::string output; + int retVal = 0; + bool res = false; + if (!this->CTest->GetShowOnly()) { + cmGeneratedFileStream os; + if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", os)) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot open configure file" << std::endl); + return 1; + } + std::string start_time = this->CTest->CurrentTime(); + auto start_time_time = std::chrono::system_clock::now(); + + cmGeneratedFileStream ofs; + this->StartLogFile("Configure", ofs); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Configure with command: " << cCommand << std::endl, + this->Quiet); + res = this->CTest->RunMakeCommand(cCommand, output, &retVal, + buildDirectory.c_str(), + cmDuration::zero(), ofs); + + if (ofs) { + ofs.close(); + } + + if (os) { + cmXMLWriter xml(os); + this->CTest->StartXML(xml, this->CMake, this->AppendXML); + this->CTest->GenerateSubprojectsOutput(xml); + xml.StartElement("Configure"); + xml.Element("StartDateTime", start_time); + xml.Element("StartConfigureTime", start_time_time); + xml.Element("ConfigureCommand", cCommand); + cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); + xml.Element("Log", output); + xml.Element("ConfigureStatus", retVal); + xml.Element("EndDateTime", this->CTest->CurrentTime()); + xml.Element("EndConfigureTime", std::chrono::system_clock::now()); + xml.Element("ElapsedMinutes", + std::chrono::duration_cast( + std::chrono::steady_clock::now() - elapsed_time_start) + .count()); + xml.EndElement(); // Configure + this->CTest->EndXML(xml); + } + } else { + cmCTestOptionalLog(this->CTest, DEBUG, + "Configure with command: " << cCommand << std::endl, + this->Quiet); + } + if (!res || retVal) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Error(s) when configuring the project" << std::endl); + return -1; + } + return 0; +} + bool cmCTestConfigureCommand::InitialPass(std::vector const& args, cmExecutionStatus& status) const { diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx deleted file mode 100644 index 35b6dce..0000000 --- a/Source/CTest/cmCTestConfigureHandler.cxx +++ /dev/null @@ -1,101 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCTestConfigureHandler.h" - -#include -#include -#include - -#include "cmCTest.h" -#include "cmDuration.h" -#include "cmGeneratedFileStream.h" -#include "cmXMLWriter.h" - -cmCTestConfigureHandler::cmCTestConfigureHandler(cmCTest* ctest) - : Superclass(ctest) -{ -} - -// clearly it would be nice if this were broken up into a few smaller -// functions and commented... -int cmCTestConfigureHandler::ProcessHandler() -{ - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - "Configure project" << std::endl, this->Quiet); - std::string cCommand = - this->CTest->GetCTestConfiguration("ConfigureCommand"); - if (cCommand.empty()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot find ConfigureCommand key in the DartConfiguration.tcl" - << std::endl); - return -1; - } - - std::string buildDirectory = - this->CTest->GetCTestConfiguration("BuildDirectory"); - if (buildDirectory.empty()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot find BuildDirectory key in the DartConfiguration.tcl" - << std::endl); - return -1; - } - - auto elapsed_time_start = std::chrono::steady_clock::now(); - std::string output; - int retVal = 0; - bool res = false; - if (!this->CTest->GetShowOnly()) { - cmGeneratedFileStream os; - if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", os)) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot open configure file" << std::endl); - return 1; - } - std::string start_time = this->CTest->CurrentTime(); - auto start_time_time = std::chrono::system_clock::now(); - - cmGeneratedFileStream ofs; - this->StartLogFile("Configure", ofs); - cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Configure with command: " << cCommand << std::endl, - this->Quiet); - res = this->CTest->RunMakeCommand(cCommand, output, &retVal, - buildDirectory.c_str(), - cmDuration::zero(), ofs); - - if (ofs) { - ofs.close(); - } - - if (os) { - cmXMLWriter xml(os); - this->CTest->StartXML(xml, this->CMake, this->AppendXML); - this->CTest->GenerateSubprojectsOutput(xml); - xml.StartElement("Configure"); - xml.Element("StartDateTime", start_time); - xml.Element("StartConfigureTime", start_time_time); - xml.Element("ConfigureCommand", cCommand); - cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); - xml.Element("Log", output); - xml.Element("ConfigureStatus", retVal); - xml.Element("EndDateTime", this->CTest->CurrentTime()); - xml.Element("EndConfigureTime", std::chrono::system_clock::now()); - xml.Element("ElapsedMinutes", - std::chrono::duration_cast( - std::chrono::steady_clock::now() - elapsed_time_start) - .count()); - xml.EndElement(); // Configure - this->CTest->EndXML(xml); - } - } else { - cmCTestOptionalLog(this->CTest, DEBUG, - "Configure with command: " << cCommand << std::endl, - this->Quiet); - } - if (!res || retVal) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Error(s) when configuring the project" << std::endl); - return -1; - } - return 0; -} diff --git a/Source/CTest/cmCTestConfigureHandler.h b/Source/CTest/cmCTestConfigureHandler.h deleted file mode 100644 index bcbead7..0000000 --- a/Source/CTest/cmCTestConfigureHandler.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#pragma once - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCTestGenericHandler.h" - -class cmCTest; - -/** \class cmCTestConfigureHandler - * \brief A class that handles ctest -S invocations - * - */ -class cmCTestConfigureHandler : public cmCTestGenericHandler -{ -public: - using Superclass = cmCTestGenericHandler; - - /* - * The main entry point for this class - */ - int ProcessHandler() override; - - cmCTestConfigureHandler(cmCTest* ctest); -}; -- cgit v0.12 From e52eada2c26bf8ff8046d778897fe78adf6073a9 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Tue, 28 Jan 2025 10:00:49 +0100 Subject: cmCTestConfigureCommand: Refactor command line construction --- Source/CTest/cmCTestConfigureCommand.cxx | 177 ++++++++++++++----------------- 1 file changed, 77 insertions(+), 100 deletions(-) diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 87b7e29..92123c8 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -3,7 +3,6 @@ #include "cmCTestConfigureCommand.h" #include -#include #include #include #include @@ -44,123 +43,101 @@ cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, { cmMakefile& mf = status.GetMakefile(); auto const& args = static_cast(arguments); - cmList options; - if (!args.Options.empty()) { - options.assign(args.Options); - } - - if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) { - status.SetError( - "Build directory not specified. Either use BUILD " - "argument to CTEST_CONFIGURE command or set CTEST_BINARY_DIRECTORY " - "variable"); + std::string const buildDirectory = !args.Build.empty() + ? args.Build + : mf.GetDefinition("CTEST_BINARY_DIRECTORY"); + if (buildDirectory.empty()) { + status.SetError("called with no build directory specified. " + "Either use the BUILD argument or set the " + "CTEST_BINARY_DIRECTORY variable."); return nullptr; } - cmValue ctestConfigureCommand = mf.GetDefinition("CTEST_CONFIGURE_COMMAND"); - - if (cmNonempty(ctestConfigureCommand)) { - this->CTest->SetCTestConfiguration("ConfigureCommand", - *ctestConfigureCommand, args.Quiet); - } else { - cmValue cmakeGeneratorName = mf.GetDefinition("CTEST_CMAKE_GENERATOR"); - if (cmNonempty(cmakeGeneratorName)) { - std::string const& source_dir = - this->CTest->GetCTestConfiguration("SourceDirectory"); - if (source_dir.empty()) { - status.SetError( - "Source directory not specified. Either use SOURCE " - "argument to CTEST_CONFIGURE command or set CTEST_SOURCE_DIRECTORY " - "variable"); - return nullptr; - } - - std::string const cmlName = mf.GetSafeDefinition("CMAKE_LIST_FILE_NAME"); - std::string const cmakelists_file = cmStrCat( - source_dir, "/", cmlName.empty() ? "CMakeLists.txt" : cmlName); - if (!cmSystemTools::FileExists(cmakelists_file)) { - std::ostringstream e; - e << "CMakeLists.txt file does not exist [" << cmakelists_file << "]"; - status.SetError(e.str()); - return nullptr; - } - - bool multiConfig = false; - bool cmakeBuildTypeInOptions = false; + std::string configureCommand = mf.GetDefinition("CTEST_CONFIGURE_COMMAND"); + if (configureCommand.empty()) { + cmValue cmakeGenerator = mf.GetDefinition("CTEST_CMAKE_GENERATOR"); + if (!cmNonempty(cmakeGenerator)) { + status.SetError( + "called with no configure command specified. " + "If this is a \"built with CMake\" project, set " + "CTEST_CMAKE_GENERATOR. If not, set CTEST_CONFIGURE_COMMAND."); + return nullptr; + } - auto gg = - mf.GetCMakeInstance()->CreateGlobalGenerator(*cmakeGeneratorName); - if (gg) { - multiConfig = gg->IsMultiConfig(); - gg.reset(); - } + std::string const sourceDirectory = !args.Source.empty() + ? args.Source + : mf.GetDefinition("CTEST_SOURCE_DIRECTORY"); + if (sourceDirectory.empty() || + !cmSystemTools::FileExists(sourceDirectory + "/CMakeLists.txt")) { + status.SetError("called with invalid source directory. " + "CTEST_SOURCE_DIRECTORY must be set to a directory " + "that contains CMakeLists.txt."); + return nullptr; + } - std::string cmakeConfigureCommand = - cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); + bool const multiConfig = [&]() -> bool { + cmake* cm = mf.GetCMakeInstance(); + auto gg = cm->CreateGlobalGenerator(cmakeGenerator); + return gg && gg->IsMultiConfig(); + }(); - for (std::string const& option : options) { - cmakeConfigureCommand += " \""; - cmakeConfigureCommand += option; - cmakeConfigureCommand += "\""; + bool const buildTypeInOptions = + args.Options.find("CMAKE_BUILD_TYPE=") != std::string::npos || + args.Options.find("CMAKE_BUILD_TYPE:STRING=") != std::string::npos; - if ((nullptr != strstr(option.c_str(), "CMAKE_BUILD_TYPE=")) || - (nullptr != strstr(option.c_str(), "CMAKE_BUILD_TYPE:STRING="))) { - cmakeBuildTypeInOptions = true; - } - } + configureCommand = cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); - if (!multiConfig && !cmakeBuildTypeInOptions && - !this->CTest->GetConfigType().empty()) { - cmakeConfigureCommand += " \"-DCMAKE_BUILD_TYPE:STRING="; - cmakeConfigureCommand += this->CTest->GetConfigType(); - cmakeConfigureCommand += "\""; - } + auto const options = cmList(args.Options); + for (std::string const& option : options) { + configureCommand += " \""; + configureCommand += option; + configureCommand += "\""; + } - if (mf.IsOn("CTEST_USE_LAUNCHERS")) { - cmakeConfigureCommand += " \"-DCTEST_USE_LAUNCHERS:BOOL=TRUE\""; - } + cmValue cmakeBuildType = mf.GetDefinition("CTEST_CONFIGURATION_TYPE"); + if (!multiConfig && !buildTypeInOptions && cmNonempty(cmakeBuildType)) { + configureCommand += " \"-DCMAKE_BUILD_TYPE:STRING="; + configureCommand += cmakeBuildType; + configureCommand += "\""; + } - cmakeConfigureCommand += " \"-G"; - cmakeConfigureCommand += *cmakeGeneratorName; - cmakeConfigureCommand += "\""; + if (mf.IsOn("CTEST_USE_LAUNCHERS")) { + configureCommand += " \"-DCTEST_USE_LAUNCHERS:BOOL=TRUE\""; + } - cmValue cmakeGeneratorPlatform = - mf.GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM"); - if (cmNonempty(cmakeGeneratorPlatform)) { - cmakeConfigureCommand += " \"-A"; - cmakeConfigureCommand += *cmakeGeneratorPlatform; - cmakeConfigureCommand += "\""; - } + configureCommand += " \"-G"; + configureCommand += cmakeGenerator; + configureCommand += "\""; - cmValue cmakeGeneratorToolset = - mf.GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET"); - if (cmNonempty(cmakeGeneratorToolset)) { - cmakeConfigureCommand += " \"-T"; - cmakeConfigureCommand += *cmakeGeneratorToolset; - cmakeConfigureCommand += "\""; - } + cmValue cmakeGeneratorPlatform = + mf.GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM"); + if (cmNonempty(cmakeGeneratorPlatform)) { + configureCommand += " \"-A"; + configureCommand += *cmakeGeneratorPlatform; + configureCommand += "\""; + } - cmakeConfigureCommand += " \"-S"; - cmakeConfigureCommand += source_dir; - cmakeConfigureCommand += "\""; + cmValue cmakeGeneratorToolset = + mf.GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET"); + if (cmNonempty(cmakeGeneratorToolset)) { + configureCommand += " \"-T"; + configureCommand += *cmakeGeneratorToolset; + configureCommand += "\""; + } - cmakeConfigureCommand += " \"-B"; - cmakeConfigureCommand += - this->CTest->GetCTestConfiguration("BuildDirectory"); - cmakeConfigureCommand += "\""; + configureCommand += " \"-S"; + configureCommand += sourceDirectory; + configureCommand += "\""; - this->CTest->SetCTestConfiguration("ConfigureCommand", - cmakeConfigureCommand, args.Quiet); - } else { - status.SetError( - "Configure command is not specified. If this is a " - "\"built with CMake\" project, set CTEST_CMAKE_GENERATOR. If not, " - "set CTEST_CONFIGURE_COMMAND."); - return nullptr; - } + configureCommand += " \"-B"; + configureCommand += buildDirectory; + configureCommand += "\""; } + this->CTest->SetCTestConfiguration("ConfigureCommand", configureCommand, + args.Quiet); + if (cmValue labelsForSubprojects = mf.GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { this->CTest->SetCTestConfiguration("LabelsForSubprojects", -- cgit v0.12 From c78d714eccc28cc5e6a07cc612519e46d01749c1 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Tue, 28 Jan 2025 10:53:47 +0100 Subject: cmCTestConfigureCommand: Refactor command execution --- Source/CTest/cmCTestConfigureCommand.cxx | 102 +++++++++++++++---------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 92123c8..a061ffd 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -153,9 +153,9 @@ int cmCTestConfigureHandler::ProcessHandler() { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Configure project" << std::endl, this->Quiet); - std::string cCommand = + std::string configureCommand = this->CTest->GetCTestConfiguration("ConfigureCommand"); - if (cCommand.empty()) { + if (configureCommand.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find ConfigureCommand key in the DartConfiguration.tcl" << std::endl); @@ -171,64 +171,64 @@ int cmCTestConfigureHandler::ProcessHandler() return -1; } - auto elapsed_time_start = std::chrono::steady_clock::now(); + if (this->CTest->GetShowOnly()) { + cmCTestOptionalLog(this->CTest, DEBUG, + "Configure with command: " << configureCommand << '\n', + this->Quiet); + return 0; + } + + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Configure with command: " << configureCommand << '\n', + this->Quiet); + + cmGeneratedFileStream logFile; + this->StartLogFile("Configure", logFile); + + auto const startTime = std::chrono::system_clock::now(); + auto const startDateTime = this->CTest->CurrentTime(); + std::string output; int retVal = 0; - bool res = false; - if (!this->CTest->GetShowOnly()) { - cmGeneratedFileStream os; - if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", os)) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot open configure file" << std::endl); - return 1; - } - std::string start_time = this->CTest->CurrentTime(); - auto start_time_time = std::chrono::system_clock::now(); + bool const res = this->CTest->RunMakeCommand(configureCommand, output, + &retVal, buildDirectory.c_str(), + cmDuration::zero(), logFile); - cmGeneratedFileStream ofs; - this->StartLogFile("Configure", ofs); - cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Configure with command: " << cCommand << std::endl, - this->Quiet); - res = this->CTest->RunMakeCommand(cCommand, output, &retVal, - buildDirectory.c_str(), - cmDuration::zero(), ofs); + auto const endTime = std::chrono::system_clock::now(); + auto const endDateTime = this->CTest->CurrentTime(); + auto const elapsedMinutes = + std::chrono::duration_cast(endTime - startTime); - if (ofs) { - ofs.close(); - } + cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); - if (os) { - cmXMLWriter xml(os); - this->CTest->StartXML(xml, this->CMake, this->AppendXML); - this->CTest->GenerateSubprojectsOutput(xml); - xml.StartElement("Configure"); - xml.Element("StartDateTime", start_time); - xml.Element("StartConfigureTime", start_time_time); - xml.Element("ConfigureCommand", cCommand); - cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); - xml.Element("Log", output); - xml.Element("ConfigureStatus", retVal); - xml.Element("EndDateTime", this->CTest->CurrentTime()); - xml.Element("EndConfigureTime", std::chrono::system_clock::now()); - xml.Element("ElapsedMinutes", - std::chrono::duration_cast( - std::chrono::steady_clock::now() - elapsed_time_start) - .count()); - xml.EndElement(); // Configure - this->CTest->EndXML(xml); - } - } else { - cmCTestOptionalLog(this->CTest, DEBUG, - "Configure with command: " << cCommand << std::endl, - this->Quiet); - } if (!res || retVal) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Error(s) when configuring the project" << std::endl); - return -1; } - return 0; + + cmGeneratedFileStream xmlFile; + if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", xmlFile)) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot open configure file" << std::endl); + return 1; + } + + cmXMLWriter xml(xmlFile); + this->CTest->StartXML(xml, this->CMake, this->AppendXML); + this->CTest->GenerateSubprojectsOutput(xml); + xml.StartElement("Configure"); + xml.Element("StartDateTime", startDateTime); + xml.Element("StartConfigureTime", startTime); + xml.Element("ConfigureCommand", configureCommand); + xml.Element("Log", output); + xml.Element("ConfigureStatus", retVal); + xml.Element("EndDateTime", endDateTime); + xml.Element("EndConfigureTime", endTime); + xml.Element("ElapsedMinutes", elapsedMinutes.count()); + xml.EndElement(); // Configure + this->CTest->EndXML(xml); + + return (!res || retVal) ? -1 : 0; } bool cmCTestConfigureCommand::InitialPass(std::vector const& args, -- cgit v0.12 From b0e92f4a70cbfd0c32a8db7f69fb2167fb174ca9 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Tue, 28 Jan 2025 11:18:27 +0100 Subject: cmCTestConfigureCommand: Remove handler usage --- Source/CTest/cmCTestConfigureCommand.cxx | 110 +++++++++++++------------------ Source/CTest/cmCTestConfigureCommand.h | 6 +- 2 files changed, 46 insertions(+), 70 deletions(-) diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index a061ffd..820eeae 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -3,9 +3,9 @@ #include "cmCTestConfigureCommand.h" #include +#include #include #include -#include #include #include @@ -13,7 +13,6 @@ #include "cmArgumentParser.h" #include "cmCTest.h" -#include "cmCTestGenericHandler.h" #include "cmDuration.h" #include "cmExecutionStatus.h" #include "cmGeneratedFileStream.h" @@ -26,23 +25,10 @@ #include "cmXMLWriter.h" #include "cmake.h" -class cmCTestConfigureHandler : public cmCTestGenericHandler -{ -public: - cmCTestConfigureHandler(cmCTest* ctest) - : cmCTestGenericHandler(ctest) - { - } - - int ProcessHandler() override; -}; - -std::unique_ptr -cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, - cmExecutionStatus& status) const +bool cmCTestConfigureCommand::ExecuteConfigure(ConfigureArguments const& args, + cmExecutionStatus& status) const { cmMakefile& mf = status.GetMakefile(); - auto const& args = static_cast(arguments); std::string const buildDirectory = !args.Build.empty() ? args.Build @@ -51,7 +37,7 @@ cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, status.SetError("called with no build directory specified. " "Either use the BUILD argument or set the " "CTEST_BINARY_DIRECTORY variable."); - return nullptr; + return false; } std::string configureCommand = mf.GetDefinition("CTEST_CONFIGURE_COMMAND"); @@ -62,7 +48,7 @@ cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, "called with no configure command specified. " "If this is a \"built with CMake\" project, set " "CTEST_CMAKE_GENERATOR. If not, set CTEST_CONFIGURE_COMMAND."); - return nullptr; + return false; } std::string const sourceDirectory = !args.Source.empty() @@ -73,7 +59,7 @@ cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, status.SetError("called with invalid source directory. " "CTEST_SOURCE_DIRECTORY must be set to a directory " "that contains CMakeLists.txt."); - return nullptr; + return false; } bool const multiConfig = [&]() -> bool { @@ -135,55 +121,33 @@ cmCTestConfigureCommand::InitializeHandler(HandlerArguments& arguments, configureCommand += "\""; } - this->CTest->SetCTestConfiguration("ConfigureCommand", configureCommand, - args.Quiet); - - if (cmValue labelsForSubprojects = - mf.GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { - this->CTest->SetCTestConfiguration("LabelsForSubprojects", - *labelsForSubprojects, args.Quiet); - } - - auto handler = cm::make_unique(this->CTest); - handler->SetQuiet(args.Quiet); - return std::unique_ptr(std::move(handler)); -} - -int cmCTestConfigureHandler::ProcessHandler() -{ - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - "Configure project" << std::endl, this->Quiet); - std::string configureCommand = - this->CTest->GetCTestConfiguration("ConfigureCommand"); - if (configureCommand.empty()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot find ConfigureCommand key in the DartConfiguration.tcl" - << std::endl); - return -1; - } - - std::string buildDirectory = - this->CTest->GetCTestConfiguration("BuildDirectory"); - if (buildDirectory.empty()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot find BuildDirectory key in the DartConfiguration.tcl" - << std::endl); - return -1; - } + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Configure project\n", + args.Quiet); if (this->CTest->GetShowOnly()) { cmCTestOptionalLog(this->CTest, DEBUG, "Configure with command: " << configureCommand << '\n', - this->Quiet); - return 0; + args.Quiet); + if (!args.ReturnValue.empty()) { + mf.AddDefinition(args.ReturnValue, "0"); + } + return true; + } + + if (!cmSystemTools::MakeDirectory(buildDirectory)) { + status.SetError(cmStrCat("cannot create directory ", buildDirectory)); + return false; } cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Configure with command: " << configureCommand << '\n', - this->Quiet); + args.Quiet); + + int const submitIndex = + args.SubmitIndex.empty() ? 0 : std::atoi(args.SubmitIndex.c_str()); cmGeneratedFileStream logFile; - this->StartLogFile("Configure", logFile); + this->CTest->StartLogFile("Configure", submitIndex, logFile); auto const startTime = std::chrono::system_clock::now(); auto const startDateTime = this->CTest->CurrentTime(); @@ -199,22 +163,36 @@ int cmCTestConfigureHandler::ProcessHandler() auto const elapsedMinutes = std::chrono::duration_cast(endTime - startTime); - cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, DEBUG, "End\n", args.Quiet); if (!res || retVal) { cmCTestLog(this->CTest, ERROR_MESSAGE, - "Error(s) when configuring the project" << std::endl); + "Error(s) when configuring the project\n"); + } + + if (!args.ReturnValue.empty()) { + mf.AddDefinition(args.ReturnValue, std::to_string(retVal)); + } + + if (cmValue value = mf.GetDefinition("CTEST_CHANGE_ID")) { + this->CTest->SetCTestConfiguration("ChangeId", *value, args.Quiet); + } + + if (cmValue value = mf.GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { + this->CTest->SetCTestConfiguration("LabelsForSubprojects", *value, + args.Quiet); } cmGeneratedFileStream xmlFile; - if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", xmlFile)) { + if (!this->CTest->StartResultingXML(cmCTest::PartConfigure, "Configure", + submitIndex, xmlFile)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open configure file" << std::endl); - return 1; + return false; } cmXMLWriter xml(xmlFile); - this->CTest->StartXML(xml, this->CMake, this->AppendXML); + this->CTest->StartXML(xml, mf.GetCMakeInstance(), args.Append); this->CTest->GenerateSubprojectsOutput(xml); xml.StartElement("Configure"); xml.Element("StartDateTime", startDateTime); @@ -228,7 +206,7 @@ int cmCTestConfigureHandler::ProcessHandler() xml.EndElement(); // Configure this->CTest->EndXML(xml); - return (!res || retVal) ? -1 : 0; + return res; } bool cmCTestConfigureCommand::InitialPass(std::vector const& args, @@ -240,6 +218,6 @@ bool cmCTestConfigureCommand::InitialPass(std::vector const& args, .Bind("OPTIONS"_s, &ConfigureArguments::Options); return this->Invoke(parser, args, status, [&](ConfigureArguments& a) { - return this->ExecuteHandlerCommand(a, status); + return this->ExecuteConfigure(a, status); }); } diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h index c2c6b3a..117d184 100644 --- a/Source/CTest/cmCTestConfigureCommand.h +++ b/Source/CTest/cmCTestConfigureCommand.h @@ -4,14 +4,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include #include #include #include "cmCTestHandlerCommand.h" class cmExecutionStatus; -class cmCTestGenericHandler; class cmCTestConfigureCommand : public cmCTestHandlerCommand { @@ -27,8 +25,8 @@ protected: private: std::string GetName() const override { return "ctest_configure"; } - std::unique_ptr InitializeHandler( - HandlerArguments& arguments, cmExecutionStatus& status) const override; + bool ExecuteConfigure(ConfigureArguments const& args, + cmExecutionStatus& status) const; bool InitialPass(std::vector const& args, cmExecutionStatus& status) const override; -- cgit v0.12