Browse Source

Windows build error handling improvements, better build clean logic

JoshEngebretson 10 years ago
parent
commit
f61c359318

+ 63 - 0
Source/ToolCore/Build/BuildBase.cpp

@@ -40,6 +40,69 @@ BuildBase::~BuildBase()
     }
 }
 
+#ifdef ATOMIC_PLATFORM_WINDOWS
+
+bool BuildBase::BuildClean(const String& path)
+{
+    if (buildFailed_)
+    {
+        LOGERRORF("BuildBase::BuildClean - Attempt to clean directory of failed build, %s", path.CString());
+        return false;
+    }
+
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+
+    if (!fileSystem->DirExists(path))
+        return true;
+
+    // On Windows, do a little dance with the folder to avoid issues
+    // with deleting folder and immediately recreating it
+
+    String pathName, fileName, ext;
+    SplitPath(path, pathName, fileName, ext);
+    pathName = AddTrailingSlash(pathName);    
+
+    unsigned i = 0;
+    while (true) 
+    {
+        String newPath = ToString("%s%s_Temp_%u", pathName.CString(), fileName.CString(), i++);
+        if (!fileSystem->DirExists(newPath))
+        {
+            if (!MoveFileExW(GetWideNativePath(path).CString(), GetWideNativePath(newPath).CString(), MOVEFILE_WRITE_THROUGH))
+            {
+                FailBuild(ToString("BuildBase::BuildClean: Unable to move directory %s -> ", path.CString(), newPath.CString()));
+                return false;
+            }
+
+            // Remove the moved directory
+            return BuildRemoveDirectory(newPath);
+
+        }
+        else
+        {
+            LOGWARNINGF("BuildBase::BuildClean - temp build folder exists, removing: %s", newPath.CString());
+            fileSystem->RemoveDir(newPath, true);
+        }
+
+        if (i == 255)
+        {
+            FailBuild(ToString("BuildBase::BuildClean: Unable to move directory ( i == 255) %s -> ", path.CString(), newPath.CString()));
+            return false;
+        }
+    }
+
+    return false;
+}
+
+#else
+
+bool BuildBase::BuildClean(const String& path)
+{
+    return BuildRemoveDirectory(path);
+}
+
+#endif
+
 bool BuildBase::BuildCreateDirectory(const String& path)
 {
     if (buildFailed_)

+ 6 - 4
Source/ToolCore/Build/BuildBase.h

@@ -43,17 +43,19 @@ public:
     void BuildWarn(const String& warning, bool sendEvent = true);
     void BuildError(const String& error, bool sendEvent = true);
 
+    /// Fail the current build
+    void FailBuild(const String& message);
+
     /// Converts subprocess output event to a buildoutput event
     void HandleSubprocessOutputEvent(StringHash eventType, VariantMap& eventData);
 
 protected:
 
+    bool BuildClean(const String& path);
     bool BuildRemoveDirectory(const String& path);
     bool BuildCreateDirectory(const String& path);
     bool BuildCopyFile(const String& srcFileName, const String& destFileName);
 
-    /// Fail the current build
-    void FailBuild(const String& message);
 
     void GenerateResourcePackage(const String& resourcePackagePath);
 
@@ -65,12 +67,12 @@ protected:
     PODVector<BuildResourceEntry*> resourceEntries_;
 
     bool containsMDL_;
+    bool buildFailed_;
 
 private:
 
     PlatformID platformID_;
-
-    bool buildFailed_;
+    
     Vector<String> buildLog_;
     Vector<String> buildWarnings_;
     Vector<String> buildErrors_;

+ 19 - 18
Source/ToolCore/Build/BuildWindows.cpp

@@ -76,6 +76,8 @@ void BuildWindows::BuildAtomicNET()
     if (!results.Size())
         return;
 
+    BuildLog("Building AtomicNET");
+
     fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources/AtomicNET");
     fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources/AtomicNET/Atomic");
     fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources/AtomicNET/Atomic/Assemblies");
@@ -124,42 +126,41 @@ void BuildWindows::Build(const String& buildPath)
 
     buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder();
 
-    VariantMap buildOutput;
-    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Starting Windows Deployment</color>\n\n";
-    SendEvent(E_BUILDOUTPUT, buildOutput);
+    BuildLog("Starting Windows Deployment");
 
     Initialize();
 
+    if (!BuildClean(buildPath_))
+        return;
+
     BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
 
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
 
-    if (fileSystem->DirExists(buildPath_))
-        fileSystem->RemoveDir(buildPath_, true);
-
     String rootSourceDir = tenv->GetRootSourceDir();
     String playerBinary = tenv->GetPlayerBinary();
     String d3d9dll = GetPath(playerBinary) + "/D3DCompiler_47.dll";
 
-    fileSystem->CreateDir(buildPath_);
-    fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources");
+    if (!BuildCreateDirectory(buildPath_))
+        return;
+
+    if (!BuildCreateDirectory(buildPath_ + "/AtomicPlayer_Resources"))
+        return;
 
     String resourcePackagePath = buildPath_ + "/AtomicPlayer_Resources/AtomicResources" + PAK_EXTENSION;
     GenerateResourcePackage(resourcePackagePath);
+    if (buildFailed_)
+        return;
+   
+    if (!BuildCopyFile(playerBinary, buildPath_ + "/AtomicPlayer.exe"))
+        return;
 
-    fileSystem->Copy(playerBinary, buildPath_ + "/AtomicPlayer.exe");
-    fileSystem->Copy(d3d9dll, buildPath_ + "/D3DCompiler_47.dll");
-
-    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Building AtomicNET</color>\n\n";
-    SendEvent(E_BUILDOUTPUT, buildOutput);
+    if (!BuildCopyFile(d3d9dll, buildPath_ + "/D3DCompiler_47.dll"))
+        return;
 
     BuildAtomicNET();
 
-    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Building AtomicNET Complete</color>\n\n";
-    SendEvent(E_BUILDOUTPUT, buildOutput);
-
-    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Windows Deployment Complete</color>\n\n";
-    SendEvent(E_BUILDOUTPUT, buildOutput);
+    BuildLog("Windows Deployment Complete");
 
     buildSystem->BuildComplete(PLATFORMID_WINDOWS, buildPath_);
 

+ 5 - 5
Source/ToolCore/Build/ResourcePackager.cpp

@@ -60,7 +60,7 @@ bool ResourcePackager::WritePackageFile(const String& destFilePath)
     SharedPtr<File> dest(new File(context_, destFilePath, FILE_WRITE));
     if (!dest->IsOpen())
     {
-        buildBase_->BuildError("Could not open output file " + destFilePath);
+        buildBase_->FailBuild("Could not open output file " + destFilePath);
         return false;
     }
 
@@ -90,7 +90,7 @@ bool ResourcePackager::WritePackageFile(const String& destFilePath)
         File srcFile(context_, entry->absolutePath_);
         if (!srcFile.IsOpen())
         {
-            buildBase_->BuildError("Could not open input file " + entry->absolutePath_);
+            buildBase_->FailBuild("Could not open input file " + entry->absolutePath_);
             return false;
         }
 
@@ -100,7 +100,7 @@ bool ResourcePackager::WritePackageFile(const String& destFilePath)
 
         if (srcFile.Read(&buffer[0], dataSize) != dataSize)
         {
-            buildBase_->BuildError("Could not read input file " + entry->absolutePath_);
+            buildBase_->FailBuild("Could not read input file " + entry->absolutePath_);
             return false;
         }
 
@@ -137,7 +137,7 @@ bool ResourcePackager::WritePackageFile(const String& destFilePath)
             unsigned packedSize = LZ4_compressHC((const char*)&buffer[pos], (char*)compressBuffer.Get(), unpackedSize);
             if (!packedSize)
             {
-                buildBase_->BuildError("LZ4 compression failed for file " + entry->absolutePath_ + " at offset " + pos);
+                buildBase_->FailBuild("LZ4 compression failed for file " + entry->absolutePath_ + " at offset " + pos);
                 return false;
             }
 
@@ -197,7 +197,7 @@ void ResourcePackager::GeneratePackage(const String& destFilePath)
 
         if (!file.Open(entry->absolutePath_))
         {
-            buildBase_->BuildError(Atomic::ToString("Could not open resource file %s", entry->absolutePath_.CString()));
+            buildBase_->FailBuild(Atomic::ToString("Could not open resource file %s", entry->absolutePath_.CString()));
             return;
         }