Просмотр исходного кода

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.
Nils Gladitz 12 лет назад
Родитель
Сommit
35fbc10079
2 измененных файлов с 63 добавлено и 3 удалено
  1. 60 3
      Source/CTest/cmCTestScriptHandler.cxx
  2. 3 0
      Source/CTest/cmCTestScriptHandler.h

+ 60 - 3
Source/CTest/cmCTestScriptHandler.cxx

@@ -22,6 +22,7 @@
 
 //#include <cmsys/RegularExpression.hxx>
 #include <cmsys/Process.h>
+#include <cmsys/Directory.hxx>
 
 // 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());
 }
 
 //-------------------------------------------------------------------------

+ 3 - 0
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<cmStdString> ConfigurationScripts;
   std::vector<bool> ScriptProcessScope;