From 35fbc10079fcbce51f542347cf74c57e3164b85e Mon Sep 17 00:00:00 2001 From: Nils Gladitz Date: Fri, 1 Nov 2013 21:55:45 +0100 Subject: [PATCH] CTest: more aggressive implementation of ctest_empty_binary_directory() Make sure that CMakeCache.txt is the last file being removed since the binary directory may be left in a state that is no longer removable otherwise. Also retry removal a couple of times which makes this more robust on windows where file locks may temporarily prevent removal. --- Source/CTest/cmCTestScriptHandler.cxx | 63 +++++++++++++++++++++++++-- Source/CTest/cmCTestScriptHandler.h | 3 ++ 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 64bcd5968..7d33cf368 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -22,6 +22,7 @@ //#include #include +#include // used for sleep #ifdef _WIN32 @@ -1056,15 +1057,71 @@ bool cmCTestScriptHandler::EmptyBinaryDirectory(const char *sname) 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 = sname; check += "/CMakeCache.txt"; - if(cmSystemTools::FileExists(check.c_str()) && - !cmSystemTools::RemoveADirectory(sname)) + + if(!cmSystemTools::FileExists(check.c_str())) { return false; } - return true; + + for(int i = 0; i < 5; ++i) + { + if(TryToRemoveBinaryDirectoryOnce(sname)) + { + return true; + } + cmSystemTools::Delay(100); + } + + return false; +} + +//------------------------------------------------------------------------- +bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce( + const std::string& directoryPath) +{ + cmsys::Directory directory; + directory.Load(directoryPath.c_str()); + + 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 = directoryPath + std::string("/") + path; + + bool isDirectory = cmSystemTools::FileIsDirectory(fullPath.c_str()) && + !cmSystemTools::FileIsSymlink(fullPath.c_str()); + + if(isDirectory) + { + if(!cmSystemTools::RemoveADirectory(fullPath.c_str())) + { + return false; + } + } + else + { + if(!cmSystemTools::RemoveFile(fullPath.c_str())) + { + return false; + } + } + } + + return cmSystemTools::RemoveADirectory(directoryPath.c_str()); } //------------------------------------------------------------------------- diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index 80d5831e0..44e9dd0f5 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h @@ -135,6 +135,9 @@ private: // Add ctest command void AddCTestCommand(cmCTestCommand* command); + // Try to remove the binary directory once + static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath); + std::vector ConfigurationScripts; std::vector ScriptProcessScope;