diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx index 2c92d77bb1..5ae89a1c80 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx @@ -2,22 +2,98 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestEmptyBinaryDirectoryCommand.h" -#include "cmCTestScriptHandler.h" +#include "cmsys/Directory.hxx" + #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" +#include "cmSystemTools.h" -bool cmCTestEmptyBinaryDirectoryCommand::InitialPass( - std::vector const& args, cmExecutionStatus& status) +namespace { + +// Try to remove the binary directory once +cmsys::Status TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath) +{ + cmsys::Directory directory; + directory.Load(directoryPath); + + // Make sure that CMakeCache.txt is deleted last. + for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) { + std::string path = directory.GetFile(i); + + if (path == "." || path == ".." || path == "CMakeCache.txt") { + continue; + } + + std::string fullPath = cmStrCat(directoryPath, "/", path); + + bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) && + !cmSystemTools::FileIsSymlink(fullPath); + + cmsys::Status status; + if (isDirectory) { + status = cmSystemTools::RemoveADirectory(fullPath); + } else { + status = cmSystemTools::RemoveFile(fullPath); + } + if (!status) { + return status; + } + } + + return cmSystemTools::RemoveADirectory(directoryPath); +} + +/* + * Empty Binary Directory + */ +bool EmptyBinaryDirectory(const std::string& sname, std::string& err) +{ + // try to avoid deleting root + if (sname.size() < 2) { + err = "path too short"; + return false; + } + + // consider non existing target directory a success + if (!cmSystemTools::FileExists(sname)) { + return true; + } + + // try to avoid deleting directories that we shouldn't + std::string check = cmStrCat(sname, "/CMakeCache.txt"); + + if (!cmSystemTools::FileExists(check)) { + err = "path does not contain an existing CMakeCache.txt file"; + return false; + } + + cmsys::Status status; + for (int i = 0; i < 5; ++i) { + status = TryToRemoveBinaryDirectoryOnce(sname); + if (status) { + return true; + } + cmSystemTools::Delay(100); + } + + err = status.GetString(); + return false; +} + +} // namespace + +bool cmCTestEmptyBinaryDirectoryCommand(std::vector const& args, + cmExecutionStatus& status) { if (args.size() != 1) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string err; - if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0], err)) { + if (!EmptyBinaryDirectory(args[0], err)) { status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, cmStrCat("Did not remove the binary directory:\n ", args[0], diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h index 3ad75ed99e..d19ae98705 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h @@ -5,41 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep #include -#include #include -#include - -#include "cmCTestCommand.h" -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmCTestEmptyBinaryDirectory - * \brief Run a ctest script - * - * cmLibrarysCommand defines a list of executable (i.e., test) - * programs to create. - */ -class cmCTestEmptyBinaryDirectoryCommand : public cmCTestCommand -{ -public: - cmCTestEmptyBinaryDirectoryCommand() {} - - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr Clone() override - { - auto ni = cm::make_unique(); - ni->CTest = this->CTest; - return std::unique_ptr(std::move(ni)); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector const& args, - cmExecutionStatus& status) override; -}; +bool cmCTestEmptyBinaryDirectoryCommand(std::vector const& args, + cmExecutionStatus& status); diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 94de6306da..f933b6a785 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -12,8 +12,6 @@ #include -#include "cmsys/Directory.hxx" - #include "cmCTest.h" #include "cmCTestBuildCommand.h" #include "cmCTestCommand.h" @@ -36,7 +34,6 @@ #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" -#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUVHandlePtr.h" #include "cmUVProcessChain.h" @@ -228,8 +225,8 @@ void cmCTestScriptHandler::CreateCMake() cm::make_unique()); this->AddCTestCommand("ctest_coverage", cm::make_unique()); - this->AddCTestCommand("ctest_empty_binary_directory", - cm::make_unique()); + state->AddBuiltinCommand("ctest_empty_binary_directory", + cmCTestEmptyBinaryDirectoryCommand); this->AddCTestCommand("ctest_memcheck", cm::make_unique()); this->AddCTestCommand("ctest_read_custom_files", @@ -376,73 +373,6 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf, return true; } -bool cmCTestScriptHandler::EmptyBinaryDirectory(const std::string& sname, - std::string& err) -{ - // try to avoid deleting root - if (sname.size() < 2) { - err = "path too short"; - return false; - } - - // consider non existing target directory a success - if (!cmSystemTools::FileExists(sname)) { - return true; - } - - // try to avoid deleting directories that we shouldn't - std::string check = cmStrCat(sname, "/CMakeCache.txt"); - - if (!cmSystemTools::FileExists(check)) { - err = "path does not contain an existing CMakeCache.txt file"; - return false; - } - - cmsys::Status status; - for (int i = 0; i < 5; ++i) { - status = TryToRemoveBinaryDirectoryOnce(sname); - if (status) { - return true; - } - cmSystemTools::Delay(100); - } - - err = status.GetString(); - return false; -} - -cmsys::Status cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce( - const std::string& directoryPath) -{ - cmsys::Directory directory; - directory.Load(directoryPath); - - for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) { - std::string path = directory.GetFile(i); - - if (path == "." || path == ".." || path == "CMakeCache.txt") { - continue; - } - - std::string fullPath = cmStrCat(directoryPath, "/", path); - - bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) && - !cmSystemTools::FileIsSymlink(fullPath); - - cmsys::Status status; - if (isDirectory) { - status = cmSystemTools::RemoveADirectory(fullPath); - } else { - status = cmSystemTools::RemoveFile(fullPath); - } - if (!status) { - return status; - } - } - - return cmSystemTools::RemoveADirectory(directoryPath); -} - cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed() { if (!this->Makefile) { diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index 8fb325a0a2..18fc2c43b5 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h @@ -9,8 +9,6 @@ #include #include -#include "cmsys/Status.hxx" - #include "cmCTestGenericHandler.h" #include "cmDuration.h" @@ -45,11 +43,6 @@ public: const std::string& script, bool InProcess, int* returnValue); - /* - * Empty Binary Directory - */ - static bool EmptyBinaryDirectory(const std::string& dir, std::string& err); - /* * Some elapsed time handling functions */ @@ -83,10 +76,6 @@ private: void AddCTestCommand(std::string const& name, std::unique_ptr command); - // Try to remove the binary directory once - static cmsys::Status TryToRemoveBinaryDirectoryOnce( - const std::string& directoryPath); - std::vector ConfigurationScripts; std::vector ScriptProcessScope;