You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
RootDirectory, EngineDirectory, UnrealBuildToolPath are now found in BuildUtilities' UnrealBuild namesapce. The way these are computed has changed. Previously, it was assumed that the application is UnrealBuildTool, and paths were constructed relative to that assembly. Now, the assumption is that the process is located under a "Engine/Build/DotNET" sub-path and paths are constructed relative to that. #jira none [CL 16607440 by jonathan adamczewski in ue5-main branch]
302 lines
9.0 KiB
C#
302 lines
9.0 KiB
C#
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Diagnostics;
|
|
using System.Text;
|
|
using EpicGames.Core;
|
|
using System.Text.RegularExpressions;
|
|
using UnrealBuildBase;
|
|
|
|
#nullable disable
|
|
|
|
namespace UnrealBuildTool
|
|
{
|
|
abstract class AppleToolChainSettings
|
|
{
|
|
/// <summary>
|
|
/// Which developer directory to root from? If this is "xcode-select", UBT will query for the currently selected Xcode
|
|
/// </summary>
|
|
public string XcodeDeveloperDir = "xcode-select";
|
|
|
|
public AppleToolChainSettings(bool bVerbose)
|
|
{
|
|
SelectXcode(ref XcodeDeveloperDir, bVerbose);
|
|
}
|
|
|
|
private static void SelectXcode(ref string DeveloperDir, bool bVerbose)
|
|
{
|
|
string Reason = "hardcoded";
|
|
|
|
if (DeveloperDir == "xcode-select")
|
|
{
|
|
Reason = "xcode-select";
|
|
|
|
// on the Mac, run xcode-select directly
|
|
DeveloperDir = Utils.RunLocalProcessAndReturnStdOut("xcode-select", "--print-path");
|
|
|
|
// make sure we get a full path
|
|
if (Directory.Exists(DeveloperDir) == false)
|
|
{
|
|
throw new BuildException("Selected Xcode ('{0}') doesn't exist, cannot continue.", DeveloperDir);
|
|
}
|
|
|
|
if (DeveloperDir.EndsWith("/") == false)
|
|
{
|
|
// we expect this to end with a slash
|
|
DeveloperDir += "/";
|
|
}
|
|
}
|
|
|
|
if (bVerbose && !DeveloperDir.StartsWith("/Applications/Xcode.app"))
|
|
{
|
|
Log.TraceInformationOnce("Compiling with non-standard Xcode ({0}): {1}", Reason, DeveloperDir);
|
|
}
|
|
|
|
// Installed engine requires Xcode 11
|
|
if (UnrealBuildTool.IsEngineInstalled())
|
|
{
|
|
string XcodeBuilderVersionOutput = Utils.RunLocalProcessAndReturnStdOut("xcodebuild", "-version");
|
|
if (XcodeBuilderVersionOutput.Length > 10)
|
|
{
|
|
string[] Version = XcodeBuilderVersionOutput.Substring(6, 4).Split('.');
|
|
if (Version.Length == 2)
|
|
{
|
|
if (int.Parse(Version[0]) < 11)
|
|
{
|
|
throw new BuildException("Building for macOS, iOS and tvOS requires Xcode 11 or newer, Xcode " + Version[0] + "." + Version[1] + " detected");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log.TraceWarning("Failed to query Xcode version");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log.TraceWarning("Failed to query Xcode version");
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void SelectSDK(string BaseSDKDir, string OSPrefix, ref string PlatformSDKVersion, bool bVerbose)
|
|
{
|
|
if (PlatformSDKVersion == "latest")
|
|
{
|
|
PlatformSDKVersion = "";
|
|
try
|
|
{
|
|
// on the Mac, we can just get the directory name
|
|
string[] SubDirs = System.IO.Directory.GetDirectories(BaseSDKDir);
|
|
|
|
// loop over the subdirs and parse out the version
|
|
int MaxSDKVersionMajor = 0;
|
|
int MaxSDKVersionMinor = 0;
|
|
string MaxSDKVersionString = null;
|
|
foreach (string SubDir in SubDirs)
|
|
{
|
|
string SubDirName = Path.GetFileNameWithoutExtension(SubDir);
|
|
if (SubDirName.StartsWith(OSPrefix))
|
|
{
|
|
// get the SDK version from the directory name
|
|
string SDKString = SubDirName.Replace(OSPrefix, "");
|
|
int Major = 0;
|
|
int Minor = 0;
|
|
|
|
// parse it into whole and fractional parts (since 10.10 > 10.9 in versions, but not in math)
|
|
try
|
|
{
|
|
string[] Tokens = SDKString.Split(".".ToCharArray());
|
|
if (Tokens.Length == 2)
|
|
{
|
|
Major = int.Parse(Tokens[0]);
|
|
Minor = int.Parse(Tokens[1]);
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// weirdly formatted SDKs
|
|
continue;
|
|
}
|
|
|
|
// update largest SDK version number
|
|
if (Major > MaxSDKVersionMajor || (Major == MaxSDKVersionMajor && Minor > MaxSDKVersionMinor))
|
|
{
|
|
MaxSDKVersionString = SDKString;
|
|
MaxSDKVersionMajor = Major;
|
|
MaxSDKVersionMinor = Minor;
|
|
}
|
|
}
|
|
}
|
|
|
|
// use the largest version
|
|
if (MaxSDKVersionString != null)
|
|
{
|
|
PlatformSDKVersion = MaxSDKVersionString;
|
|
}
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
// on any exception, just use the backup version
|
|
Log.TraceInformation("Triggered an exception while looking for SDK directory in Xcode.app");
|
|
Log.TraceInformation("{0}", Ex.ToString());
|
|
}
|
|
}
|
|
|
|
// make sure we have a valid SDK directory
|
|
if (!RuntimePlatform.IsWindows && !Directory.Exists(Path.Combine(BaseSDKDir, OSPrefix + PlatformSDKVersion + ".sdk")))
|
|
{
|
|
throw new BuildException("Invalid SDK {0}{1}.sdk, not found in {2}", OSPrefix, PlatformSDKVersion, BaseSDKDir);
|
|
}
|
|
|
|
if (bVerbose && !ProjectFileGenerator.bGenerateProjectFiles)
|
|
{
|
|
Log.TraceInformation("Compiling with {0} SDK {1}", OSPrefix, PlatformSDKVersion);
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class AppleToolChain : ISPCToolChain
|
|
{
|
|
protected FileReference ProjectFile;
|
|
|
|
public AppleToolChain(FileReference InProjectFile)
|
|
{
|
|
ProjectFile = InProjectFile;
|
|
}
|
|
|
|
protected DirectoryReference GetMacDevSrcRoot()
|
|
{
|
|
return UnrealBuildTool.EngineSourceDirectory;
|
|
}
|
|
|
|
protected void StripSymbolsWithXcode(FileReference SourceFile, FileReference TargetFile, string ToolchainDir)
|
|
{
|
|
if (SourceFile != TargetFile)
|
|
{
|
|
// Strip command only works in place so we need to copy original if target is different
|
|
File.Copy(SourceFile.FullName, TargetFile.FullName, true);
|
|
}
|
|
|
|
ProcessStartInfo StartInfo = new ProcessStartInfo();
|
|
StartInfo.FileName = Path.Combine(ToolchainDir, "strip");
|
|
StartInfo.Arguments = String.Format("\"{0}\" -S", TargetFile.FullName);
|
|
StartInfo.UseShellExecute = false;
|
|
StartInfo.CreateNoWindow = true;
|
|
Utils.RunLocalProcessAndLogOutput(StartInfo);
|
|
}
|
|
|
|
static Version ClangVersion = null;
|
|
static string FullClangVersion = null;
|
|
|
|
protected Version GetClangVersion()
|
|
{
|
|
if (ClangVersion == null)
|
|
{
|
|
FileReference ClangLocation = new FileReference("/usr/bin/clang");
|
|
ClangVersion = RunToolAndCaptureVersion(ClangLocation, "--version");
|
|
}
|
|
return ClangVersion;
|
|
}
|
|
|
|
protected string GetFullClangVersion()
|
|
{
|
|
if (FullClangVersion == null)
|
|
{
|
|
// get the first line that has the full clang and build number
|
|
FileReference ClangLocation = new FileReference("/usr/bin/clang");
|
|
FullClangVersion = RunToolAndCaptureOutput(ClangLocation, "--version", "(.*)");
|
|
}
|
|
|
|
return FullClangVersion;
|
|
}
|
|
|
|
protected static string GetCppStandardCompileArgument(CppStandardVersion Version)
|
|
{
|
|
switch (Version)
|
|
{
|
|
case CppStandardVersion.Cpp14:
|
|
return " -std=c++14";
|
|
case CppStandardVersion.Cpp17:
|
|
return " -std=c++17";
|
|
case CppStandardVersion.Latest:
|
|
case CppStandardVersion.Cpp20:
|
|
return " -std=c++20";
|
|
default:
|
|
throw new BuildException($"Unsupported C++ standard type set: {Version}");
|
|
}
|
|
}
|
|
|
|
protected string GetDsymutilPath(out string ExtraOptions, bool bIsForLTOBuild=false)
|
|
{
|
|
FileReference DsymutilLocation = new FileReference("/usr/bin/dsymutil");
|
|
|
|
// dsymutil before 10.0.1 has a bug that causes issues, it's fixed in autosdks but not everyone has those set up so for the timebeing we have
|
|
// a version in P4 - first determine if we need it
|
|
string DsymutilVersionString = Utils.RunLocalProcessAndReturnStdOut(DsymutilLocation.FullName, "-version");
|
|
|
|
bool bUseInstalledDsymutil = true;
|
|
int Major = 0, Minor = 0, Patch = 0;
|
|
|
|
// tease out the version number
|
|
string[] Tokens = DsymutilVersionString.Split(" ".ToCharArray());
|
|
|
|
// sanity check
|
|
if (Tokens.Length < 4 || Tokens[3].Contains(".") == false)
|
|
{
|
|
Log.TraceInformationOnce("Unable to parse dsymutil version out of: {0}", DsymutilVersionString);
|
|
}
|
|
else
|
|
{
|
|
string[] Versions = Tokens[3].Split(".".ToCharArray());
|
|
if (Versions.Length < 3)
|
|
{
|
|
Log.TraceInformationOnce("Unable to parse version token: {0}", Tokens[3]);
|
|
}
|
|
else
|
|
{
|
|
if (!int.TryParse(Versions[0], out Major) || !int.TryParse(Versions[1], out Minor) || !int.TryParse(Versions[2], out Patch))
|
|
{
|
|
Log.TraceInformationOnce("Unable to parse version tokens: {0}", Tokens[3]);
|
|
}
|
|
else
|
|
{
|
|
if (Major < 12)
|
|
{
|
|
Log.TraceInformationOnce("dsymutil version is {0}.{1}.{2}. Using bundled version.", Major, Minor, Patch);
|
|
bUseInstalledDsymutil = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// if the installed one is too old, use a fixed up one if it can
|
|
if (bUseInstalledDsymutil == false)
|
|
{
|
|
FileReference PatchedDsymutilLocation = FileReference.Combine(UnrealBuild.EngineDirectory, "Restricted/NotForLicensees/Binaries/Mac/LLVM/bin/dsymutil");
|
|
|
|
if (File.Exists(PatchedDsymutilLocation.FullName))
|
|
{
|
|
DsymutilLocation = PatchedDsymutilLocation;
|
|
}
|
|
|
|
DirectoryReference AutoSdkDir;
|
|
if (UEBuildPlatformSDK.TryGetHostPlatformAutoSDKDir(out AutoSdkDir))
|
|
{
|
|
FileReference AutoSdkDsymutilLocation = FileReference.Combine(AutoSdkDir, "Mac", "LLVM", "bin", "dsymutil");
|
|
if (FileReference.Exists(AutoSdkDsymutilLocation))
|
|
{
|
|
DsymutilLocation = AutoSdkDsymutilLocation;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 10.0.1 has an issue with LTO builds where we need to limit the number of threads
|
|
ExtraOptions = (bIsForLTOBuild && Major == 10 && Minor == 0 && Patch == 1) ? "-j 1" : "";
|
|
return DsymutilLocation.FullName;
|
|
}
|
|
};
|
|
}
|