summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO16
-rw-r--r--BuildConfiguration.xml7
-rw-r--r--PKGBUILD56
-rw-r--r--ccache.patch92
-rw-r--r--ccache_executor.patch586
-rw-r--r--processor_multiplier.patch13
-rw-r--r--use-arch-mono.patch10
7 files changed, 653 insertions, 127 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 284719e18e0..6887d6d7eef 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,11 +1,12 @@
pkgbase = unreal-engine
pkgdesc = A 3D game engine by Epic Games which can be used non-commercially for free.
- pkgver = 4.26.1
- pkgrel = 5
+ pkgver = 4.26.2
+ pkgrel = 2
url = https://www.unrealengine.com/
arch = x86_64
license = custom:UnrealEngine
makedepends = mono
+ makedepends = mono-msbuild
makedepends = dos2unix
makedepends = git
makedepends = openssh
@@ -20,20 +21,23 @@ pkgbase = unreal-engine
optdepends = codelite: IDE for projects
optdepends = kdevelop: IDE for projects
optdepends = clion: IDE for projects
+ optdepends = ccache: cache compilations
options = !strip
options = staticlibs
source = com.unrealengine.UE4Editor.desktop
- source = use-arch-mono.patch
source = clang_11.patch
source = PackageWithSystemCompiler.patch
- source = ccache.patch
+ source = ccache_executor.patch
source = compile_and_regenerate.patch
+ source = processor_multiplier.patch
+ source = BuildConfiguration.xml
sha256sums = 15e9f9d8dc8bd8513f6a5eca990e2aab21fd38724ad57d213b06a6610a951d58
- sha256sums = e891f07bf7294cd5fde8eb6de92e6d47ed004847ea8afd7c944e9b9b2bacaff4
sha256sums = 8042bed3405298b5a4357068dd6b22a5a8a0f19def64b4f61ed0362fb46cb00d
sha256sums = 9e403b939a0601c6271da17af9497742cacd74e3cde41562c9f288dfbdcbdbfe
- sha256sums = a0a0d3f065e27f4d31e21e5f9d15cb4d8f59c50245a45469878fc1fe8bdc78e6
+ sha256sums = 33982486f7fafac35a33dfa37c85cfba8543aa78b5fe13c395d9cccf691ef4b3
sha256sums = 7e53beb5818ceadb765689ad8e1baf55ce1d6afe8a9d6884b6f2bd121083c3f7
+ sha256sums = a129607acc1ea6a48ee5af073da6bd9318176d07e91e743ce93662065f7288dd
+ sha256sums = 7cfc5ef5f7842d5e0a574938226e54361529b2fb5c68606c0e099352a513f84c
pkgname = unreal-engine
diff --git a/BuildConfiguration.xml b/BuildConfiguration.xml
new file mode 100644
index 00000000000..53e8ac44592
--- /dev/null
+++ b/BuildConfiguration.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
+ <LocalExecutor>
+ <ProcessorCountMultiplier>1.2</ProcessorCountMultiplier>
+ <MaxProcessorCount>30</MaxProcessorCount>
+ </LocalExecutor>
+</Configuration>
diff --git a/PKGBUILD b/PKGBUILD
index 5b89df56b09..a7e223fe296 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -4,32 +4,35 @@
# The source is about 200 MiB, with an extra ~11 GiB of dependencies downloaded in Setup.sh, and may take several hours to compile.
pkgname=unreal-engine
-pkgver=4.26.1
-pkgrel=5
+pkgver=4.26.2
+pkgrel=2
pkgdesc='A 3D game engine by Epic Games which can be used non-commercially for free.'
arch=(x86_64)
url=https://www.unrealengine.com/
-makedepends=(mono dos2unix git openssh)
+makedepends=(mono mono-msbuild dos2unix git openssh)
depends=(icu sdl2 python lld xdg-user-dirs)
optdepends=('qt5-base: qmake build system for projects'
'cmake: build system for projects'
'qtcreator: IDE for projects'
'codelite: IDE for projects'
'kdevelop: IDE for projects'
- 'clion: IDE for projects')
+ 'clion: IDE for projects'
+ 'ccache: cache compilations')
license=(custom:UnrealEngine)
source=(com.unrealengine.UE4Editor.desktop
- use-arch-mono.patch
clang_11.patch
PackageWithSystemCompiler.patch
- ccache.patch
- compile_and_regenerate.patch)
+ ccache_executor.patch
+ compile_and_regenerate.patch
+ processor_multiplier.patch
+ BuildConfiguration.xml)
sha256sums=('15e9f9d8dc8bd8513f6a5eca990e2aab21fd38724ad57d213b06a6610a951d58'
- 'e891f07bf7294cd5fde8eb6de92e6d47ed004847ea8afd7c944e9b9b2bacaff4'
'8042bed3405298b5a4357068dd6b22a5a8a0f19def64b4f61ed0362fb46cb00d'
'9e403b939a0601c6271da17af9497742cacd74e3cde41562c9f288dfbdcbdbfe'
- 'a0a0d3f065e27f4d31e21e5f9d15cb4d8f59c50245a45469878fc1fe8bdc78e6'
- '7e53beb5818ceadb765689ad8e1baf55ce1d6afe8a9d6884b6f2bd121083c3f7')
+ '33982486f7fafac35a33dfa37c85cfba8543aa78b5fe13c395d9cccf691ef4b3'
+ '7e53beb5818ceadb765689ad8e1baf55ce1d6afe8a9d6884b6f2bd121083c3f7'
+ 'a129607acc1ea6a48ee5af073da6bd9318176d07e91e743ce93662065f7288dd'
+ '7cfc5ef5f7842d5e0a574938226e54361529b2fb5c68606c0e099352a513f84c')
options=(!strip staticlibs) # Package is 3 Gib smaller with "strip" but it takes a long time and generates many warnings
# Set options to anything that is not null to enable them.
@@ -37,6 +40,11 @@ _system_compiler= # for the system compiler you'll need to set LINUX_MULTIARCH_
# as an environment to /usr/sbin compile projects after building.
# The system compiler should work for everything in engine now.
_ccache_support= # Patches for ccache. More optimizations might be needed.
+_system_mono= # Uses System mono for unreal.
+ # must set UE_USE_SYSTEM_MONO
+ # in your environment for it to
+ # work after install
+_processor_multiplier= # Allows multiplier on processor count. Allowing the Maximum threads your cpu can handle
prepare() {
# Check access to the repository
@@ -58,7 +66,10 @@ prepare() {
git reset --hard $pkgver-release
fi
- patch Engine/Build/BatchFiles/Linux/SetupMono.sh $srcdir/use-arch-mono.patch # Use system mono
+ if [ -n "$_system_mono" ]
+ then
+ export UE_USE_SYSTEM_MONO=1
+ fi
generateProjectArgs="-makefile"
if [ -n "$_system_compiler" ]
then
@@ -70,7 +81,13 @@ prepare() {
fi
if [ -n "$_ccache_support" ]
then
- patch -p1 -i "$srcdir/ccache.patch"
+ patch -p1 -i "$srcdir/ccache_executor.patch"
+ fi
+ if [ -n "$_processor_multiplier" ]
+ then
+ patch -p1 -i "$srcdir/processor_multiplier.patch"
+ mkdir -p "$srcdir/$pkgname/Engine/Saved/UnrealBuildTool"
+ mv "$srcdir/BuildConfiguration.xml" "$_"
fi
# Qt Creator source code access
@@ -112,18 +129,18 @@ package() {
sed -i "5c\Path=/$dir/Engine/Binaries/Linux/" com.unrealengine.UE4Editor.desktop
sed -i "6c\Exec=/$dir/Engine/Binaries/Linux/UE4Editor %F" com.unrealengine.UE4Editor.desktop
fi
- install -Dm777 com.unrealengine.UE4Editor.desktop $pkgdir/usr/share/applications/com.unrealengine.UE4Editor.desktop
+ install -Dm770 com.unrealengine.UE4Editor.desktop $pkgdir/usr/share/applications/com.unrealengine.UE4Editor.desktop
cd $pkgname
# Icon for Desktop entry
- install -Dm777 Engine/Source/Programs/UnrealVS/Resources/Preview.png $pkgdir/usr/share/pixmaps/ue4editor.png
+ install -Dm770 Engine/Source/Programs/UnrealVS/Resources/Preview.png $pkgdir/usr/share/pixmaps/ue4editor.png
# License
- install -Dm777 LICENSE.md $pkgdir/usr/share/licenses/UnrealEngine/LICENSE.md
+ install -Dm770 LICENSE.md $pkgdir/usr/share/licenses/UnrealEngine/LICENSE.md
# Engine
- install -dm777 "$pkgdir/$dir/Engine"
+ install -dm770 "$pkgdir/$dir/Engine"
mv Engine/Binaries "$pkgdir/$dir/Engine/Binaries"
mv Engine/Build "$pkgdir/$dir/Engine/Build"
mv Engine/Config "$pkgdir/$dir/Engine/Config"
@@ -134,6 +151,7 @@ package() {
mv Engine/Programs "$pkgdir/$dir/Engine/Programs"
mv Engine/Shaders "$pkgdir/$dir/Engine/Shaders"
mv Engine/Source "$pkgdir/$dir/Engine/Source"
+ mv Engine/Saved "$pkgdir/$dir/Engine/Saved"
# Required folders
# install -d "$pkgdir/$dir/Engine/DerivedDataCache"
@@ -144,7 +162,7 @@ package() {
mv Templates "$pkgdir/$dir/Templates"
# Build scripts, used by some plugins (CLion)
- install -Dm777 GenerateProjectFiles.sh "$pkgdir/$dir/GenerateProjectFiles.sh"
- install -Dm777 Setup.sh "$pkgdir/$dir/Setup.sh"
- install -Dm777 .ue4dependencies "$pkgdir/$dir/.ue4dependencies"
+ install -Dm770 GenerateProjectFiles.sh "$pkgdir/$dir/GenerateProjectFiles.sh"
+ install -Dm770 Setup.sh "$pkgdir/$dir/Setup.sh"
+ install -Dm770 .ue4dependencies "$pkgdir/$dir/.ue4dependencies"
}
diff --git a/ccache.patch b/ccache.patch
deleted file mode 100644
index e43080e42ba..00000000000
--- a/ccache.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 739747f0b50796af2642afe51afe6d1c2a456673 Mon Sep 17 00:00:00 2001
-From: Zerophase <mikelojkovic@gmail.com>
-Date: Mon, 4 May 2020 06:53:57 -0500
-Subject: [PATCH] ccache support
-
----
- .../Platform/Linux/LinuxToolChain.cs | 41 +++++++++++++++----
- 1 file changed, 33 insertions(+), 8 deletions(-)
-
-diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Linux/LinuxToolChain.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Linux/LinuxToolChain.cs
-index 1f856d789be..687ce99d66f 100644
---- a/Engine/Source/Programs/UnrealBuildTool/Platform/Linux/LinuxToolChain.cs
-+++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Linux/LinuxToolChain.cs
-@@ -115,6 +115,7 @@ namespace UnrealBuildTool
- // use native linux toolchain
- ClangPath = LinuxCommon.WhichClang();
- GCCPath = LinuxCommon.WhichGcc();
-+ CCachePath = LinuxCommon.Which("ccache");
- ArPath = LinuxCommon.Which("ar");
- LlvmArPath = LinuxCommon.Which("llvm-ar");
- RanlibPath = LinuxCommon.Which("ranlib");
-@@ -152,12 +153,13 @@ namespace UnrealBuildTool
-
- // set up the path to our toolchain
- GCCPath = "";
-- ClangPath = Path.Combine(BaseLinuxPath, @"bin", "clang++" + GetHostPlatformBinarySuffix());
-- ArPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}-{1}", Architecture, "ar" + GetHostPlatformBinarySuffix())));
-- LlvmArPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}", "llvm-ar" + GetHostPlatformBinarySuffix())));
-- RanlibPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}-{1}", Architecture, "ranlib" + GetHostPlatformBinarySuffix())));
-- ObjcopyPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}", "llvm-objcopy" + GetHostPlatformBinarySuffix())));
-- StripPath = ObjcopyPath;
-+ CCachePath = "/usr/bin/ccache";
-+ ClangPath = Path.Combine(BaseLinuxPath, @"bin", "clang++" + GetHostPlatformBinarySuffix());
-+ ArPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}-{1}", Architecture, "ar" + GetHostPlatformBinarySuffix())));
-+ LlvmArPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}", "llvm-ar" + GetHostPlatformBinarySuffix())));
-+ RanlibPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}-{1}", Architecture, "ranlib" + GetHostPlatformBinarySuffix())));
-+ StripPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}-{1}", Architecture, "strip" + GetHostPlatformBinarySuffix())));
-+ ObjcopyPath = Path.Combine(Path.Combine(BaseLinuxPath, String.Format("bin/{0}-{1}", Architecture, "objcopy" + GetHostPlatformBinarySuffix())));
-
- // When cross-compiling on Windows, use old FixDeps. It is slow, but it does not have timing issues
- bUseFixdeps = (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64 || BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win32);
-@@ -1142,6 +1144,7 @@ namespace UnrealBuildTool
- protected string BaseLinuxPath;
- protected string ClangPath;
- protected string GCCPath;
-+ protected string CCachePath;
- protected string ArPath;
- protected string LlvmArPath;
- protected string RanlibPath;
-@@ -1228,6 +1231,7 @@ namespace UnrealBuildTool
- String.IsNullOrEmpty(ClangPath) ? "gcc" : "clang",
- String.IsNullOrEmpty(ClangPath) ? GCCPath : ClangPath,
- CompilerVersionString, CompilerVersionMajor, CompilerVersionMinor, CompilerVersionPatch);
-+ Log.TraceInformation("{0}", String.IsNullOrEmpty(CCachePath) ? "" : "Using CCache");
-
- if (UsingClang())
- {
-@@ -1472,8 +1476,29 @@ namespace UnrealBuildTool
-
- FileReference CompilerResponseFileName = CompileAction.ProducedItems[0].Location + ".rsp";
- FileItem CompilerResponseFileItem = Graph.CreateIntermediateTextFile(CompilerResponseFileName, AllArguments);
--
-- CompileAction.CommandArguments = string.Format(" @\"{0}\"", CompilerResponseFileName);
-+ if (!String.IsNullOrEmpty(CCachePath))
-+ {
-+ // Sloppiness Settings to try
-+ // pch_defines,time_macros,file_stat_matches, file_stat_matches_ctime,include_file_ctime,include_file_mtime
-+ CompileAction.CommandPath = new FileReference(CCachePath);
-+ Environment.SetEnvironmentVariable("CCACHE_SLOPPINESS", "pch_defines,modules,locale,time_macros");
-+ if (UsingClang())
-+ {
-+ string PreprocesspCH = " -fpch-preprocess ";
-+ string SkipPCHValidation = " -Xclang -fno-validate-pch";
-+ CompileAction.CommandArguments += ClangPath + PreprocesspCH + SkipPCHValidation;
-+ }
-+ else
-+ {
-+ CompileAction.CommandArguments += GCCPath;
-+ }
-+ }
-+ else
-+ {
-+ CompileAction.CommandPath = new FileReference(ClangPath);
-+ }
-+
-+ CompileAction.CommandArguments += string.Format(" @\"{0}\"", CompilerResponseFileName);
- CompileAction.PrerequisiteItems.Add(CompilerResponseFileItem);
- CompileAction.CommandDescription = "Compile";
- CompileAction.CommandVersion = CompilerVersionString;
---
-2.31.0
-
diff --git a/ccache_executor.patch b/ccache_executor.patch
new file mode 100644
index 00000000000..d652a954668
--- /dev/null
+++ b/ccache_executor.patch
@@ -0,0 +1,586 @@
+diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/BuildConfiguration.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/BuildConfiguration.cs
+index 0957ae99925..a20a95da3aa 100644
+--- a/Engine/Source/Programs/UnrealBuildTool/Configuration/BuildConfiguration.cs
++++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/BuildConfiguration.cs
+@@ -61,6 +61,9 @@ namespace UnrealBuildTool
+ [CommandLine("-NoFASTBuild", Value = "false")]
+ public bool bAllowFASTBuild = true;
+
++ [XmlConfigFile] [CommandLine("-Noccache", Value = "false")]
++ public bool bAllowCCache = true;
++
+ /// <summary>
+ /// Whether SN-DBS may be used.
+ /// </summary>
+diff --git a/Engine/Source/Programs/UnrealBuildTool/Executors/Experimental/CCache.cs b/Engine/Source/Programs/UnrealBuildTool/Executors/Experimental/CCache.cs
+new file mode 100644
+index 00000000000..4f00dc80bbf
+--- /dev/null
++++ b/Engine/Source/Programs/UnrealBuildTool/Executors/Experimental/CCache.cs
+@@ -0,0 +1,74 @@
++using System.Collections.Generic;
++using System.Diagnostics;
++using Tools.DotNETCommon;
++
++namespace UnrealBuildTool
++{
++ class CCache : LocalExecutor
++ {
++ private readonly string ClangPath;
++ private readonly string CCachePath;
++
++ private string ClangCommand;
++ private string CompileCommand;
++
++ public CCache()
++ :base(0)
++ {
++ ClangPath = LinuxCommon.WhichClang();
++ CCachePath = LinuxCommon.Which("ccache");
++ }
++
++ public override string Name => "ccache";
++ public static bool IsAvailable()
++ {
++ if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux)
++ {
++ if (!string.IsNullOrEmpty(LinuxCommon.Which("ccache")))
++ return true;
++ }
++
++ return false;
++ }
++ public override bool ExecuteActions(List<Action> Actions, bool bLogDetailedActionStats)
++ {
++ Log.TraceInformation("Using CCache");
++ ClangCommand = ClangPath + " -fpch-preprocess -Xclang -fno-validate-pch ";
++
++ return base.ExecuteActions(Actions, bLogDetailedActionStats);
++ }
++
++ protected override void Run(Action Action)
++ {
++ switch (Action.ActionType)
++ {
++ case ActionType.Compile:
++ if (Action.StatusDescription.EndsWith(".ispc"))
++ CompileCommand = Action.CommandPath.ToString() + " " + Action.CommandArguments;
++ else
++ CompileCommand = ClangCommand + Action.CommandArguments;
++ ProcessStartInfo CcacheStartInfo = new ProcessStartInfo(CCachePath, CompileCommand);
++ CcacheStartInfo.UseShellExecute = false;
++ CcacheStartInfo.WorkingDirectory = Action.WorkingDirectory.FullName;
++ CcacheStartInfo.RedirectStandardError = true;
++ CcacheStartInfo.RedirectStandardOutput = true;
++
++ // Sloppiness Settings to try
++ // pch_defines,time_macros,file_stat_matches, file_stat_matches_ctime,include_file_ctime,include_file_mtime
++ CcacheStartInfo.EnvironmentVariables.Add("CCache_SLOPPINESS",
++ "pch_defines,modules,locale,time_macros");
++ base.Run(CcacheStartInfo, Action);
++ break;
++ case ActionType.Link:
++ case ActionType.WriteMetadata:
++ case ActionType.BuildProject:
++ base.Run(Action);
++ break;
++ default:
++ Log.TraceInformation("Action types not handled: {0}",
++ Action.ActionType.ToString());
++ break;
++ }
++ }
++ }
++}
+\ No newline at end of file
+diff --git a/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs b/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs
+index 8f4f153bd75..0636a29be10 100644
+--- a/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs
++++ b/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs
+@@ -63,6 +63,12 @@ namespace UnrealBuildTool
+ }
+
+
++ protected void ThreadFunc(ProcessStartInfo ActionStartInfo)
++ {
++ Action.StartTime = DateTimeOffset.Now;
++ ActionProgress(ActionStartInfo);
++ RunActionProcess(ActionStartInfo);
++ }
+ /// <summary>
+ /// The actual function to run in a thread. This is potentially long and blocking
+ /// </summary>
+@@ -81,9 +87,15 @@ namespace UnrealBuildTool
+ ActionStartInfo.RedirectStandardOutput = false;
+ ActionStartInfo.RedirectStandardError = false;
+
++ ActionProgress(ActionStartInfo);
++ RunActionProcess(ActionStartInfo);
++ // Try to launch the action's process, and produce a friendly error message if it fails.
++ }
++
++ private void ActionProgress(ProcessStartInfo ActionStartInfo)
++ {
+ // Log command-line used to execute task if debug info printing is enabled.
+ Log.TraceVerbose("Executing: {0} {1}", ActionStartInfo.FileName, ActionStartInfo.Arguments);
+-
+ // Log summary if wanted.
+ if (Action.bShouldOutputStatusDescription)
+ {
+@@ -97,68 +109,14 @@ namespace UnrealBuildTool
+ Log.TraceInformation("[{0}/{1}] {2} {3}", JobNumber, TotalJobs, CommandDescription, Action.StatusDescription);
+ }
+ }
+-
+- // Try to launch the action's process, and produce a friendly error message if it fails.
+- Process ActionProcess = null;
++ }
++
++ private void RunActionProcess(ProcessStartInfo ActionStartInfo)
++ {
++ Process ActionProcess = LaunchActionProcess(ActionStartInfo);
+ try
+ {
+- try
+- {
+- ActionProcess = new Process();
+- ActionProcess.StartInfo = ActionStartInfo;
+- ActionStartInfo.RedirectStandardOutput = true;
+- ActionStartInfo.RedirectStandardError = true;
+- ActionProcess.OutputDataReceived += new DataReceivedEventHandler(ActionDebugOutput);
+- ActionProcess.ErrorDataReceived += new DataReceivedEventHandler(ActionDebugOutput);
+- ActionProcess.Start();
+-
+- ActionProcess.BeginOutputReadLine();
+- ActionProcess.BeginErrorReadLine();
+- }
+- catch (Exception ex)
+- {
+- Log.TraceError("Failed to start local process for action: {0} {1}", Action.CommandPath, Action.CommandArguments);
+- Log.WriteException(ex, null);
+- ExitCode = 1;
+- bComplete = true;
+- return;
+- }
+-
+- // wait for process to start
+- // NOTE: this may or may not be necessary; seems to depend on whether the system UBT is running on start the process in a timely manner.
+- int checkIterations = 0;
+- bool haveConfiguredProcess = false;
+- do
+- {
+- if (ActionProcess.HasExited)
+- {
+- if (haveConfiguredProcess == false)
+- Debug.WriteLine("Process for action exited before able to configure!");
+- break;
+- }
+-
+- if (!haveConfiguredProcess)
+- {
+- try
+- {
+- ActionProcess.PriorityClass = ProcessPriorityClass.BelowNormal;
+- haveConfiguredProcess = true;
+- }
+- catch (Exception)
+- {
+- }
+- break;
+- }
+-
+- Thread.Sleep(10);
+-
+- checkIterations++;
+- } while (checkIterations < 100);
+- if (checkIterations == 100)
+- {
+- throw new BuildException("Failed to configure local process for action: {0} {1}", Action.CommandPath, Action.CommandArguments);
+- }
+-
++ //CheckIterations(ActionProcess); Might be needed for Local Executor. Doesn't seem to do anything
+ // block until it's complete
+ // @todo iosmerge: UBT had started looking at: if (Utils.IsValidProcess(Process))
+ // do we need to check that in the thread model?
+@@ -181,8 +139,79 @@ namespace UnrealBuildTool
+
+ // we are done!!
+ bComplete = true;
++
+ }
+
++ private void CheckIterations(Process ActionProcess)
++ {
++ // wait for process to start
++ // NOTE: this may or may not be necessary; seems to depend on whether the system UBT is running on start the process in a timely manner.
++ int checkIterations = 0;
++ bool haveConfiguredProcess = false;
++ do
++ {
++ if (ActionProcess.HasExited)
++ {
++ if (haveConfiguredProcess == false)
++ Debug.WriteLine("Process for action exited before able to configure!");
++ break;
++ }
++
++ if (!haveConfiguredProcess)
++ {
++ try
++ {
++ ActionProcess.PriorityClass = ProcessPriorityClass.BelowNormal;
++ haveConfiguredProcess = true;
++ }
++ catch (Exception)
++ {
++ }
++ break;
++ }
++
++ Thread.Sleep(10);
++
++ checkIterations++;
++ } while (checkIterations < 100);
++ if (checkIterations == 100)
++ {
++ throw new BuildException("Failed to configure local process for action: {0} {1}", Action.CommandPath, Action.CommandArguments);
++ }
++ }
++
++ private Process LaunchActionProcess(ProcessStartInfo ActionStartInfo)
++ {
++ Process ActionProcess = null;
++ try
++ {
++ ActionProcess = new Process();
++ ActionProcess.StartInfo = ActionStartInfo;
++ ActionStartInfo.RedirectStandardOutput = true;
++ ActionStartInfo.RedirectStandardError = true;
++ ActionProcess.OutputDataReceived += new DataReceivedEventHandler(ActionDebugOutput);
++ ActionProcess.ErrorDataReceived += new DataReceivedEventHandler(ActionDebugOutput);
++ ActionProcess.Start();
++
++ ActionProcess.BeginOutputReadLine();
++ ActionProcess.BeginErrorReadLine();
++ return ActionProcess;
++ }
++ catch (Exception ex)
++ {
++ Log.TraceError("Failed to start local process for action: {0} {1}", Action.CommandPath, Action.CommandArguments);
++ Log.WriteException(ex, null);
++ ExitCode = 1;
++ bComplete = true;
++ return ActionProcess;
++ }
++ }
++
++ public void Run(ProcessStartInfo ActionStartInfo)
++ {
++ Thread T = new Thread(() => ThreadFunc(ActionStartInfo));
++ T.Start();
++ }
+ /// <summary>
+ /// Starts a thread and runs the action in that thread
+ /// </summary>
+@@ -214,6 +243,10 @@ namespace UnrealBuildTool
+ /// </summary>
+ int NumParallelProcesses;
+
++ private int JobNumber;
++ private int TotalJobs;
++ private int ProgressValue;
++
+ /// <summary>
+ /// Constructor
+ /// </summary>
+@@ -304,43 +337,16 @@ namespace UnrealBuildTool
+ Log.TraceInformation("Performing {0} actions ({1} in parallel)", Actions.Count, NumParallelProcesses);
+
+ Dictionary<Action, ActionThread> ActionThreadDictionary = new Dictionary<Action, ActionThread>();
+- int JobNumber = 1;
++ JobNumber = 1;
++ TotalJobs = Actions.Count;
++ ProgressValue = 0;
+ using (ProgressWriter ProgressWriter = new ProgressWriter("Compiling C++ source code...", false))
+ {
+- int ProgressValue = 0;
+ while (true)
+ {
+- // Count the number of pending and still executing actions.
+- int NumUnexecutedActions = 0;
+ int NumExecutingActions = 0;
+- foreach (Action Action in Actions)
+- {
+- ActionThread ActionThread = null;
+- bool bFoundActionProcess = ActionThreadDictionary.TryGetValue(Action, out ActionThread);
+- if (bFoundActionProcess == false)
+- {
+- NumUnexecutedActions++;
+- }
+- else if (ActionThread != null)
+- {
+- if (ActionThread.bComplete == false)
+- {
+- NumUnexecutedActions++;
+- NumExecutingActions++;
+- }
+- }
+- }
+-
+- // Update the current progress
+- int NewProgressValue = Actions.Count + 1 - NumUnexecutedActions;
+- if (ProgressValue != NewProgressValue)
+- {
+- ProgressWriter.Write(ProgressValue, Actions.Count + 1);
+- ProgressValue = NewProgressValue;
+- }
+-
+ // If there aren't any pending actions left, we're done executing.
+- if (NumUnexecutedActions == 0)
++ if (ExecuteActionCount(Actions, ProgressWriter, ref NumExecutingActions))
+ {
+ break;
+ }
+@@ -350,65 +356,14 @@ namespace UnrealBuildTool
+ foreach (Action Action in Actions)
+ {
+ ActionThread ActionProcess = null;
+- bool bFoundActionProcess = ActionThreadDictionary.TryGetValue(Action, out ActionProcess);
+- if (bFoundActionProcess == false)
++ if (!FoundActionProcess(Action))
+ {
+ if (NumExecutingActions < Math.Max(1, NumParallelProcesses))
+ {
+- // Determine whether there are any prerequisites of the action that are outdated.
+- bool bHasOutdatedPrerequisites = false;
+- bool bHasFailedPrerequisites = false;
+- foreach (Action PrerequisiteAction in Action.PrerequisiteActions)
+- {
+- if (Actions.Contains(PrerequisiteAction))
+- {
+- ActionThread PrerequisiteProcess = null;
+- bool bFoundPrerequisiteProcess = ActionThreadDictionary.TryGetValue(PrerequisiteAction, out PrerequisiteProcess);
+- if (bFoundPrerequisiteProcess == true)
+- {
+- if (PrerequisiteProcess == null)
+- {
+- bHasFailedPrerequisites = true;
+- }
+- else if (PrerequisiteProcess.bComplete == false)
+- {
+- bHasOutdatedPrerequisites = true;
+- }
+- else if (PrerequisiteProcess.ExitCode != 0)
+- {
+- bHasFailedPrerequisites = true;
+- }
+- }
+- else
+- {
+- bHasOutdatedPrerequisites = true;
+- }
+- }
+- }
+-
+- // If there are any failed prerequisites of this action, don't execute it.
+- if (bHasFailedPrerequisites)
+- {
+- // Add a null entry in the dictionary for this action.
+- ActionThreadDictionary.Add(Action, null);
+- }
+ // If there aren't any outdated prerequisites of this action, execute it.
+- else if (!bHasOutdatedPrerequisites)
++ if (!ExecutePrerequisiteActions(Actions, Action))
+ {
+- ActionThread ActionThread = new ActionThread(Action, JobNumber, Actions.Count);
+- JobNumber++;
+-
+- try
+- {
+- ActionThread.Run();
+- }
+- catch (Exception ex)
+- {
+- throw new BuildException(ex, "Failed to start thread for action: {0} {1}\r\n{2}", Action.CommandPath, Action.CommandArguments, ex.ToString());
+- }
+-
+- ActionThreadDictionary.Add(Action, ActionThread);
+-
++ Run(Action);
+ NumExecutingActions++;
+ }
+ }
+@@ -512,5 +467,119 @@ namespace UnrealBuildTool
+
+ return bSuccess;
+ }
++
++ private ActionThread CreateActionThread(Action Action)
++ {
++ return new ActionThread(Action, JobNumber++, TotalJobs);
++ }
++ protected virtual void Run(ProcessStartInfo ProcessStartInfo, Action Action)
++ {
++ ActionThread ActionThread = CreateActionThread(Action);
++ try
++ {
++ ActionThread.Run(ProcessStartInfo);
++ }
++ catch (Exception ex)
++ {
++ throw new BuildException(ex, "Failed to start thread for action: {0} {1}\r\n{2}", Action.CommandPath, Action.CommandArguments, ex.ToString());
++ }
++ ActionThreadDictionary.Add(Action, ActionThread);
++ }
++ protected virtual void Run(Action Action)
++ {
++ ActionThread ActionThread = CreateActionThread(Action);
++ try
++ {
++ ActionThread.Run();
++ }
++ catch (Exception ex)
++ {
++ throw new BuildException(ex, "Failed to start thread for action: {0} {1}\r\n{2}", Action.CommandPath, Action.CommandArguments, ex.ToString());
++ }
++ ActionThreadDictionary.Add(Action, ActionThread);
++ }
++
++ private Dictionary<Action, ActionThread> ActionThreadDictionary = new Dictionary<Action, ActionThread>();
++ private bool FoundActionProcess(Action Action)
++ {
++ ActionThread ActionProcess = null;
++ return ActionThreadDictionary.TryGetValue(Action, out ActionProcess);
++ }
++
++ private bool ExecutePrerequisiteActions(List<Action> Actions, Action Action)
++ {
++ bool bHasOutdatedPrerequisites = false;
++ bool bHasFailedPrerequisites = false;
++ foreach (Action PrerequisiteAction in Action.PrerequisiteActions)
++ {
++ if (Actions.Contains(PrerequisiteAction))
++ {
++ ActionThread PrerequisiteProcess = null;
++ bool bFoundPrerequisiteProcess =
++ ActionThreadDictionary.TryGetValue(PrerequisiteAction,
++ out PrerequisiteProcess);
++ if (bFoundPrerequisiteProcess == true)
++ {
++ if (PrerequisiteProcess == null)
++ {
++ bHasFailedPrerequisites = true;
++ }
++ else if (PrerequisiteProcess.bComplete == false)
++ {
++ bHasOutdatedPrerequisites = true;
++ }
++ else if (PrerequisiteProcess.ExitCode != 0)
++ {
++ bHasFailedPrerequisites = true;
++ }
++ }
++ else
++ {
++ bHasOutdatedPrerequisites = true;
++ }
++ }
++ }
++
++
++ if (bHasFailedPrerequisites)
++ {
++ // Add a null entry in the dictionary for this action.
++ ActionThreadDictionary.Add(Action, null);
++ }
++
++ return bHasOutdatedPrerequisites;
++ }
++
++ private bool ExecuteActionCount(List<Action> Actions, ProgressWriter ProgressWriter, ref int NumExecutingActions)
++ {
++ int NumUnexecutedActions = 0;
++ foreach (Action Action in Actions)
++ {
++ ActionThread ActionThread = null;
++ bool bFoundActionProcess = ActionThreadDictionary.TryGetValue(Action, out ActionThread);
++ if (bFoundActionProcess == false)
++ {
++ NumUnexecutedActions++;
++ }
++ else if (ActionThread != null)
++ {
++ if (ActionThread.bComplete == false)
++ {
++ NumUnexecutedActions++;
++ NumExecutingActions++;
++ }
++ }
++ }
++
++ int NewProgressValue = TotalJobs + 1 - NumUnexecutedActions;
++ if (ProgressValue != NewProgressValue)
++ {
++ ProgressWriter.Write(ProgressValue, TotalJobs + 1);
++ ProgressValue = NewProgressValue;
++ }
++
++ // If there aren't any pending actions left, we're done executing.
++ return NumUnexecutedActions == 0;
++ }
+ };
+ }
+diff --git a/Engine/Source/Programs/UnrealBuildTool/System/ActionGraph.cs b/Engine/Source/Programs/UnrealBuildTool/System/ActionGraph.cs
+index a1cdcdad1ed..27725550c87 100644
+--- a/Engine/Source/Programs/UnrealBuildTool/System/ActionGraph.cs
++++ b/Engine/Source/Programs/UnrealBuildTool/System/ActionGraph.cs
+@@ -184,6 +184,10 @@ namespace UnrealBuildTool
+ {
+ Executor = new FASTBuild();
+ }
++ else if (BuildConfiguration.bAllowCCache && CCache.IsAvailable())
++ {
++ Executor = new CCache();
++ }
+ else if (BuildConfiguration.bAllowDistcc)
+ {
+ Executor = new Distcc();
+diff --git a/Engine/Source/Programs/UnrealBuildTool/ToolChain/UEToolChain.cs b/Engine/Source/Programs/UnrealBuildTool/ToolChain/UEToolChain.cs
+index 7f1baf9a147..fc7c9ae84cc 100644
+--- a/Engine/Source/Programs/UnrealBuildTool/ToolChain/UEToolChain.cs
++++ b/Engine/Source/Programs/UnrealBuildTool/ToolChain/UEToolChain.cs
+@@ -420,12 +420,10 @@ namespace UnrealBuildTool
+ }
+ }
+
+- // Build target triplet
+ Arguments.Add(String.Format("--target-os={0}", GetISPCOSTarget(CompileEnvironment.Platform)));
+ Arguments.Add(String.Format("--arch={0}", GetISPCArchTarget(CompileEnvironment.Platform, null)));
+ Arguments.Add(String.Format("--target={0}", TargetString));
+-
+- // PIC is needed for modular builds except on Windows
++
+ if ((CompileEnvironment.bIsBuildingDLL ||
+ CompileEnvironment.bIsBuildingLibrary) &&
+ !UEBuildPlatform.IsPlatformInGroup(CompileEnvironment.Platform, UnrealPlatformGroup.Windows))
+@@ -433,6 +431,8 @@ namespace UnrealBuildTool
+ Arguments.Add("--pic");
+ }
+
++ // PIC is needed for modular builds except on Windows
++
+ // Include paths. Don't use AddIncludePath() here, since it uses the full path and exceeds the max command line length.
+ // Because ISPC response files don't support white space in arguments, paths with white space need to be passed to the command line directly.
+ foreach (DirectoryReference IncludePath in CompileEnvironment.UserIncludePaths)
+diff --git a/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj b/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj
+index 2736ef225e2..453153cc0cc 100644
+--- a/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj
++++ b/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj
+@@ -142,6 +142,7 @@
+ </Choose>
+ <ItemGroup>
+ <Compile Include="Configuration\ModuleRulesContext.cs" />
++ <Compile Include="Executors\Experimental\CCache.cs" />
+ <Compile Include="Executors\HybridExecutor.cs" />
+ <Compile Include="Modes\BuildMode.cs" />
+ <Compile Include="Modes\CleanMode.cs" />
diff --git a/processor_multiplier.patch b/processor_multiplier.patch
new file mode 100644
index 00000000000..4620a612b02
--- /dev/null
+++ b/processor_multiplier.patch
@@ -0,0 +1,13 @@
+diff --git a/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs b/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs
+index 47cd98680ba..1072d5bc3e6 100644
+--- a/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs
++++ b/Engine/Source/Programs/UnrealBuildTool/Executors/LocalExecutor.cs
+@@ -305,7 +305,7 @@ namespace UnrealBuildTool
+ // No hyper-threading. Only kicking off a task per CPU to keep machine responsive.
+ else
+ {
+- MaxActionsToExecuteInParallel = NumPhysicalCores;
++ MaxActionsToExecuteInParallel = (int) (NumPhysicalCores * ProcessorCountMultiplier);
+ }
+
+ #if !NET_CORE
diff --git a/use-arch-mono.patch b/use-arch-mono.patch
deleted file mode 100644
index a85cab55672..00000000000
--- a/use-arch-mono.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- SetupMono.sh 2020-05-04 02:07:37.213825041 -0500
-+++ SetupMono_new.sh 2020-05-05 12:31:03.403575161 -0500
-@@ -11,6 +11,7 @@
- bash FixDependencyFiles.sh
- IS_MONO_INSTALLED=0
- IS_MS_BUILD_AVAILABLE=0
-+UE_USE_SYSTEM_MONO=1
- MONO_VERSION_PATH=$(command -v mono) || true
-
- if [ "$UE_USE_SYSTEM_MONO" == "1" ] && [ ! $MONO_VERSION_PATH == "" ] && [ -f $MONO_VERSION_PATH ]; then