diff options
author | Neko-san | 2022-06-30 13:25:36 -0500 |
---|---|---|
committer | Neko-san | 2022-06-30 13:25:36 -0500 |
commit | d6a99cd3ced52428c0bc3ac2020927801a5e67d3 (patch) | |
tree | c2a62e31be55f218648f9a68dd164cd1d99573e5 | |
download | aur-d6a99cd3ced52428c0bc3ac2020927801a5e67d3.tar.gz |
Initilize repository for the Unreal Engine 4 AUR
-rw-r--r-- | .SRCINFO | 35 | ||||
-rw-r--r-- | PKGBUILD | 154 | ||||
-rw-r--r-- | ccache_executor.patch | 586 | ||||
-rw-r--r-- | clang_path_fix.patch | 15 | ||||
-rw-r--r-- | com.unrealengine.UE4Editor.desktop | 11 |
5 files changed, 801 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..40d89fe228d3 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,35 @@ +pkgbase = unreal-engine-4 + pkgdesc = A 3D game engine by Epic Games which can be used non-commercially for free. + pkgver = 4.27 + pkgrel = 1 + url = https://www.unrealengine.com/ + arch = x86_64 + arch = x86_64_v2 + arch = x86_64_v3 + arch = x86_64_v4 + license = custom:UnrealEngine + makedepends = git + makedepends = openssh + depends = icu63 + depends = sdl2 + depends = python + depends = lld + depends = clang + depends = xdg-user-dirs + depends = dos2unix + optdepends = qt5-base: qmake build system for projects + optdepends = cmake: build system for projects + optdepends = qtcreator: IDE for projects + optdepends = codelite: IDE for projects + optdepends = kdevelop: IDE for projects + optdepends = clion: IDE for projects + options = !strip + options = staticlibs + source = com.unrealengine.UE4Editor.desktop + source = clang_path_fix.patch + source = ccache_executor.patch + sha256sums = 15e9f9d8dc8bd8513f6a5eca990e2aab21fd38724ad57d213b06a6610a951d58 + sha256sums = 960c5a100e0c3732f3c73fb645d3989d39acf4576d74615bbef38ebeee008b90 + sha256sums = 33982486f7fafac35a33dfa37c85cfba8543aa78b5fe13c395d9cccf691ef4b3 + +pkgname = unreal-engine-4 diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..ec1f36619885 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,154 @@ +# Maintainer: Neko-san <aur at mycat dot anonaddy dot me> + +# The source is about 200 MiB, with an extra ~11 GiB of dependencies downloaded in Setup.sh, and may take several hours to compile. +# If you want to turn on additional patches there are switches below. +pkgname=unreal-engine-4 +pkgver=4.27 +pkgrel=0 +pkgdesc='A 3D game engine by Epic Games which can be used non-commercially for free.' +arch=('x86_64' 'x86_64_v2' 'x86_64_v3' 'x86_64_v4') +url=https://www.unrealengine.com/ +makedepends=('git' 'openssh') +depends=('icu63' 'sdl2' 'python' 'lld' 'clang' 'xdg-user-dirs' 'dos2unix') +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') +license=('custom:UnrealEngine') +source=('com.unrealengine.UE4Editor.desktop' + 'clang_path_fix.patch' + 'ccache_executor.patch') +sha256sums=('15e9f9d8dc8bd8513f6a5eca990e2aab21fd38724ad57d213b06a6610a951d58' + '960c5a100e0c3732f3c73fb645d3989d39acf4576d74615bbef38ebeee008b90' + '33982486f7fafac35a33dfa37c85cfba8543aa78b5fe13c395d9cccf691ef4b3') +# Not sure if compiling Unreal with LTO is legal? Lot's of different proprietary software goes into Unreal +options=('!strip' 'staticlibs') # Package is 3 Gib smaller with "strip" but it takes a long time and generates many warnings + +_install_dir="opt/${pkgname}" # Default engine installation directory. Can be useful if you do not have a lot of space in /opt directory. +_ccache_support=false # Patches for ccache. More optimizations might be needed? +_WithDDC=false # Change this to true if you have a modern system and don't mind the extra packaging time (and size) to avoid compiling shaders on UE startup later; set to false by default for those with less robust systems + +## Courtesy of the original author of this patch from https://aur.archlinux.org/packages/unreal-engine +## This patch is a bit more complex, so I'll try to maintain it, but don't be surprised if updates for this patch is not speedy +if [[ ${_ccache_support} == true ]] +then + depends+=(ccache) +fi + +## Use this if you prefer opendoas; the benefit here is that doas won't time out on you if you wait too long to authenticate after compilation +if [ -f /usr/bin/doas ] && [ -f /etc/doas.conf ]; then + PACMAN_AUTH=(doas) +fi + +## This is for detecting your CPU architecture automatically; set to false if you want to enforce your own makepkg.conf file + +## Note: the resulting package will still be named containing "x86_64" unless the build was done with an "official" Arch distro for that architecture (like Arch ARM - [I don't advise using Arch ARM though]) +## or if you manage to trick your Arch installation to accept other architecture extensions by fiddling with the $CARCH variable and /etc/pacman.conf - this method has flaws, namely due to a bug: +## it doesn't work with "makechrootpkg" - though, this PKGBUILD doesn't work in with this method anyway because of Github SSH Agent nonsense + +arch_auto=true + +if [[ ${arch_auto} == true ]] +then + ## Architecture checks and compile flag adjustments - shellcheck throws a fit about the build function but it looks fine to me; checks for the highest available x64 support level and falls back to "native" if either not available + if test "$(/lib/ld-linux-x86-64.so.2 --help | grep -w '^ x86-64-v4' | cut -d ',' -f 1)" == ' x86-64-v4 (supported'; then + export CFLAGS="${CFLAGS} -march=x86-64-v4 -mtune=x86-64-v4 -O3 -pipe" + export CXXFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS" + export LDFLAGS="-Wl,-O3,--sort-common,--as-needed,-z,relro,-z,now" + elif test "$(/lib/ld-linux-x86-64.so.2 --help | grep -w '^ x86-64-v3' | cut -d ',' -f 1)" == ' x86-64-v3 (supported'; then + export CFLAGS="${CFLAGS} -march=x86-64-v3 -mtune=x86-64-v3 -O3 -pipe" + export CXXFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS" + export LDFLAGS="-Wl,-O3,--sort-common,--as-needed,-z,relro,-z,now" + elif test "$(/lib/ld-linux-x86-64.so.2 --help | grep -w '^ x86-64-v2' | cut -d ',' -f 1)" == ' x86-64-v2 (supported'; then + export CFLAGS="${CFLAGS} -march=x86-64-v2 -mtune=x86-64-v2 -O3 -pipe" + export CXXFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS" + export LDFLAGS="-Wl,-O3,--sort-common,--as-needed,-z,relro,-z,now" + elif test "$(/lib/ld-linux-x86-64.so.2 --help | grep -w '^ x86_64 (AT_PLATFORM; supported' | cut -d ',' -f 1)" == ' x86_64 (AT_PLATFORM; supported'; then + export CFLAGS="${CFLAGS} -march=x86-64 -mtune=x86-64 -O3 -pipe" + export CXXFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS" + export LDFLAGS="-Wl,-O3,--sort-common,--as-needed,-z,relro,-z,now" + else + export CFLAGS="${CFLAGS} -march=native -mtune=native -O3 -pipe" + export CXXFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS" + export LDFLAGS="-Wl,-O3,--sort-common,--as-needed,-z,relro,-z,now" + fi +fi + +prepare() { + # Check access to the repository + if ! git ls-remote git@github.com:EpicGames/UnrealEngine &>/dev/null + then + error 'You must register at unrealengine.com and link your github account to access this private repo. See the wiki for more info: https://wiki.archlinux.org/index.php/Unreal_Engine_4' + exit 1 + fi + + # Download Unreal Engine source or update if the folder exists + if [[ ! -d ${pkgname} ]] + then + git clone --depth=1 --branch=${pkgver}-release git@github.com:EpicGames/UnrealEngine ${pkgname} + cd ${pkgname} + else + cd ${pkgname} + rm -f .git/index.lock + git fetch --depth=1 origin tag ${pkgver}-release + git reset --hard ${pkgver}-release + fi + + # Apply custom patches + patch -p1 -i "${srcdir}/clang_path_fix.patch" # Replace Windows specific search with the correct path (used for -mode=GenerateClangDatabase in UBT) + if [[ ${_ccache_support} == true ]] + then + patch -p1 -i "${srcdir}/ccache_executor.patch" + fi + + # Qt Creator source code access + if [[ ! -d Engine/Plugins/Developer/QtCreatorSourceCodeAccess ]] + then + git -C Engine/Plugins/Developer clone --depth=1 git@github.com:fire/QtCreatorSourceCodeAccess + fi + + # For some reason, despite this file explicitly asking not to be removed, it was removed from the UE5 source; it has to be re-added or the build will fail - this is the UE4 package, but this will remain in place in-case this occurs for UE4 branches + if [[ ! -f ${pkgname}/Engine/Source/ThirdParty/Linux/HaveLinuxDependencies ]] + then + mkdir -p ${pkgname}/Engine/Source/ThirdParty/Linux/ + touch ${pkgname}/Engine/Source/ThirdParty/Linux/HaveLinuxDependencies + sed -i "1c\This file must have no extension so that GitDeps considers it a binary dependency - it will only be pulled by the Setup script if Linux is enabled. Please do not remove this file." ${pkgname}/Engine/Source/ThirdParty/Linux/HaveLinuxDependencies + fi + + ./Setup.sh +} + +build() { + cd ${pkgname} + if [[ ${_WithDDC} == true ]]; then + Engine/Build/BatchFiles/RunUAT.sh BuildGraph -target="Make Installed Build Linux" -script=Engine/Build/InstalledEngineBuild.xml -set:WithDDC=true -set:HostPlatformOnly=false -set:WithLinux=true -set:WithWin64=true -set:WithWin32=false -set:WithMac=false -set:WithAndroid=false -set:WithIOS=false -set:WithTVOS=false -set:WithLumin=false -set:WithHTML5=false + else + Engine/Build/BatchFiles/RunUAT.sh BuildGraph -target="Make Installed Build Linux" -script=Engine/Build/InstalledEngineBuild.xml -set:WithDDC=false -set:HostPlatformOnly=false -set:WithLinux=true -set:WithWin64=true -set:WithWin32=false -set:WithMac=false -set:WithAndroid=false -set:WithIOS=false -set:WithTVOS=false -set:WithLumin=false -set:WithHTML5=false + fi +} + +package() { + # Desktop entry + if [[ "${_install_dir}" != "opt/${pkgname}" ]] # Set new path if dir changed + then + sed -i "5c\Path=/${_install_dir}/Engine/Binaries/Linux/" com.unrealengine.UE4Editor.desktop + sed -i "6c\Exec=/${_install_dir}/Engine/Binaries/Linux/UE4Editor %F" com.unrealengine.UE4Editor.desktop + fi + install -Dm775 com.unrealengine.UE4Editor.desktop "$pkgdir/usr/share/applications/com.unrealengine.UE4Editor.desktop" + + cd ${pkgname} + + # Icon for Desktop entry + install -Dm770 Engine/Source/Programs/UnrealVS/Resources/Preview.png "${pkgdir}/usr/share/pixmaps/ue4editor.png" + + # License + install -Dm770 LICENSE.md "${pkgdir}/usr/share/licenses/UnrealEngine/LICENSE.md" + + # Engine + ## Set to all permissions to prevent the engine from breaking itself; more elegant solutions might exist - suggest them if they can be automated here + ## Also, correct me if I package this improperly; I added Win64 support for the build in hopes of supporting cross-compilation + install -dm777 "${pkgdir}/${_install_dir}/Engine" + mv LocalBuilds/Engine/Linux/* "${pkgdir}/${_install_dir}" +} diff --git a/ccache_executor.patch b/ccache_executor.patch new file mode 100644 index 000000000000..d652a9546683 --- /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/clang_path_fix.patch b/clang_path_fix.patch new file mode 100644 index 000000000000..5e45cefcbf55 --- /dev/null +++ b/clang_path_fix.patch @@ -0,0 +1,15 @@ +diff --git a/Engine/Source/Programs/UnrealBuildTool/Modes/GenerateClangDatabase.cs b/Engine/Source/Programs/UnrealBuildTool/Modes/GenerateClangDatabase.cs +index 66044e95b..5c62d17dd 100644 +--- a/Engine/Source/Programs/UnrealBuildTool/Modes/GenerateClangDatabase.cs ++++ b/Engine/Source/Programs/UnrealBuildTool/Modes/GenerateClangDatabase.cs +@@ -63,8 +63,8 @@ namespace UnrealBuildTool + UEBuildTarget Target = UEBuildTarget.Create(TargetDescriptor, BuildConfiguration.bSkipRulesCompile, BuildConfiguration.bUsePrecompiled); + + // Find the location of the compiler +- VCEnvironment Environment = VCEnvironment.Create(WindowsCompiler.Clang, Target.Platform, Target.Rules.WindowsPlatform.Architecture, null, Target.Rules.WindowsPlatform.WindowsSdkVersion, null); +- FileReference ClangPath = FileReference.Combine(Environment.CompilerDir, "bin", "clang++.exe"); ++ //VCEnvironment Environment = VCEnvironment.Create(WindowsCompiler.Clang, Target.Platform, Target.Rules.WindowsPlatform.Architecture, null, Target.Rules.WindowsPlatform.WindowsSdkVersion, null); ++ FileReference ClangPath = new FileReference("/usr/bin/clang++"); + + // Convince each module to output its generated code include path + foreach (UEBuildBinary Binary in Target.Binaries) diff --git a/com.unrealengine.UE4Editor.desktop b/com.unrealengine.UE4Editor.desktop new file mode 100644 index 000000000000..d86cd555754d --- /dev/null +++ b/com.unrealengine.UE4Editor.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Name=Unreal Engine 4 Editor +Comment=Create next-generation video games +Path=/opt/unreal-engine/Engine/Binaries/Linux/ +Exec=/opt/unreal-engine/Engine/Binaries/Linux/UE4Editor %F +MimeType=text/x-uproject +Icon=ue4editor +Terminal=false +Categories=Development; + |