// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml;
namespace UnrealBuildTool
{
///
/// Stores project-specific IOS settings. Instances of this object are cached by IOSPlatform.
///
class IOSProjectSettings
{
///
/// The cached project file location
///
public readonly FileReference ProjectFile;
///
/// Whether to generate a dSYM file or not.
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMFile")]
public readonly bool bGeneratedSYMFile = true;
///
/// Whether to generate a dSYM bundle or not.
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMBundle")]
public readonly bool bGeneratedSYMBundle = false;
///
/// The minimum supported version
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion")]
private readonly string MinimumIOSVersion = null;
///
/// Whether to support iPhone
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone")]
private readonly bool bSupportsIPhone = true;
///
/// Whether to support iPad
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad")]
private readonly bool bSupportsIPad = true;
///
/// Whether to target ArmV7
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7")]
private readonly bool bDevForArmV7 = false;
///
/// Whether to target Arm64
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64")]
private readonly bool bDevForArm64 = false;
///
/// Whether to target ArmV7S
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S")]
private readonly bool bDevForArmV7S = false;
///
/// Whether to target ArmV7 for shipping configurations
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7")]
private readonly bool bShipForArmV7 = false;
///
/// Whether to target Arm64 for shipping configurations
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64")]
private readonly bool bShipForArm64 = false;
///
/// Whether to target ArmV7S for shipping configurations
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S")]
private readonly bool bShipForArmV7S = false;
///
/// additional linker flags for shipping
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalShippingLinkerFlags")]
public readonly string AdditionalShippingLinkerFlags = "";
///
/// additional linker flags for non-shipping
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalLinkerFlags")]
public readonly string AdditionalLinkerFlags = "";
///
/// mobile provision to use for code signing
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MobileProvision")]
public readonly string MobileProvision = "";
///
/// signing certificate to use for code signing
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SigningCertificate")]
public readonly string SigningCertificate = "";
///
/// true if bit code should be embedded
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForBitcode")]
public readonly bool bShipForBitcode = false;
///
/// true if notifications are enabled
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport")]
public readonly bool bNotificationsEnabled = false;
///
/// The bundle identifier
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier")]
public readonly string BundleIdentifier = "";
///
/// true if using Xcode managed provisioning, else false
///
[ConfigFile(ConfigHierarchyType.Engine, "/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bAutomaticSigning")]
public readonly bool bAutomaticSigning = false;
///
/// Returns a list of all the non-shipping architectures which are supported
///
public IEnumerable NonShippingArchitectures
{
get
{
if(bDevForArmV7 || (!bDevForArm64 && !bDevForArmV7S))
{
yield return "armv7";
}
if(bDevForArm64)
{
yield return "arm64";
}
if(bDevForArmV7S)
{
yield return "armv7s";
}
}
}
///
/// Returns a list of all the shipping architectures which are supported
///
public IEnumerable ShippingArchitectures
{
get
{
if(bShipForArmV7 || (!bShipForArm64 && !bShipForArmV7S))
{
yield return "armv7";
}
if(bShipForArm64 || (!bShipForArmV7 && !bShipForArmV7S))
{
yield return "arm64";
}
if(bShipForArmV7S)
{
yield return "armv7s";
}
}
}
///
/// Which version of the iOS to allow at run time
///
public virtual string RuntimeVersion
{
get
{
switch (MinimumIOSVersion)
{
case "IOS_9":
return "9.0";
case "IOS_10":
return "10.0";
default:
return "8.0";
}
}
}
///
/// which devices the game is allowed to run on
///
public virtual string RuntimeDevices
{
get
{
if (bSupportsIPad && !bSupportsIPhone)
{
return "2";
}
else if (!bSupportsIPad && bSupportsIPhone)
{
return "1";
}
else
{
return "1,2";
}
}
}
///
/// Constructor
///
/// The project file to read settings for
public IOSProjectSettings(FileReference ProjectFile)
: this(ProjectFile, UnrealTargetPlatform.IOS)
{
}
///
/// Protected constructor. Used by TVOSProjectSettings.
///
/// The project file to read settings for
/// The platform to read settings for
protected IOSProjectSettings(FileReference ProjectFile, UnrealTargetPlatform Platform)
{
this.ProjectFile = ProjectFile;
ConfigCache.ReadSettings(DirectoryReference.FromFile(ProjectFile), Platform, this);
BundleIdentifier = BundleIdentifier.Replace("[PROJECT_NAME]", ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game")).Replace("_", "");
}
}
///
/// IOS provisioning data
///
class IOSProvisioningData
{
public string SigningCertificate;
public string MobileProvision;
public string MobileProvisionUUID;
public string TeamUUID;
public bool bHaveCertificate = false;
public IOSProvisioningData(IOSProjectSettings ProjectSettings, bool bForDistribution)
: this(ProjectSettings, false, bForDistribution)
{
}
protected IOSProvisioningData(IOSProjectSettings ProjectSettings, bool bIsTVOS, bool bForDistribtion)
{
SigningCertificate = ProjectSettings.SigningCertificate;
MobileProvision = ProjectSettings.MobileProvision;
FileReference ProjectFile = ProjectSettings.ProjectFile;
if (!string.IsNullOrEmpty(SigningCertificate))
{
// verify the certificate
Process IPPProcess = new Process();
if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
{
string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bForDistribtion ? " -distribution" : "");
IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh";
IPPProcess.StartInfo.Arguments = IPPCmd;
IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
}
else
{
string IPPCmd = "certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bForDistribtion ? " -distribution" : "");
IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe";
IPPProcess.StartInfo.Arguments = IPPCmd;
IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
}
Utils.RunLocalProcess(IPPProcess);
}
else
{
SigningCertificate = bForDistribtion ? "iPhone Distribution" : "iPhone Developer";
bHaveCertificate = true;
}
if (string.IsNullOrEmpty(MobileProvision) // no provision specified
|| !File.Exists((BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + MobileProvision) // file doesn't exist
|| !bHaveCertificate) // certificate doesn't exist
{
SigningCertificate = "";
MobileProvision = "";
Log.TraceLog("Provision not specified or not found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", searching for compatible match...");
Process IPPProcess = new Process();
if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
{
string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : "");
IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh";
IPPProcess.StartInfo.Arguments = IPPCmd;
IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
}
else
{
string IPPCmd = "signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : "");
IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe";
IPPProcess.StartInfo.Arguments = IPPCmd;
IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler);
}
Utils.RunLocalProcess(IPPProcess);
Log.TraceLog("Provision found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", Provision: " + MobileProvision + " Certificate: " + SigningCertificate);
}
// add to the dictionary
SigningCertificate = SigningCertificate.Replace("\"", "");
// read the provision to get the UUID
string filename = (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + MobileProvision;
if (File.Exists(filename))
{
byte[] AllBytes = File.ReadAllBytes(filename);
uint StartIndex = (uint)AllBytes.Length;
uint EndIndex = (uint)AllBytes.Length;
for (uint i = 0; i + 4 < AllBytes.Length; i++)
{
if (AllBytes[i] == '<' && AllBytes[i+1] == '?' && AllBytes[i+ 2] == 'x' && AllBytes[i+ 3] == 'm' && AllBytes[i+ 4] == 'l')
{
StartIndex = i;
break;
}
}
if (StartIndex < AllBytes.Length)
{
for (uint i = StartIndex; i + 7 < AllBytes.Length; i++)
{
if(AllBytes[i] == '<' && AllBytes[i + 1] == '/' && AllBytes[i + 2] == 'p' && AllBytes[i + 3] == 'l' && AllBytes[i + 4] == 'i' && AllBytes[i + 5] == 's' && AllBytes[i + 6] == 't' && AllBytes[i + 7] == '>')
{
EndIndex = i+7;
break;
}
}
}
if (StartIndex < AllBytes.Length && EndIndex < AllBytes.Length)
{
byte[] TextBytes = new byte[EndIndex - StartIndex];
Buffer.BlockCopy(AllBytes, (int)StartIndex, TextBytes, 0, (int)(EndIndex - StartIndex));
string AllText = Encoding.UTF8.GetString(TextBytes);
int idx = AllText.IndexOf("UUID");
if (idx > 0)
{
idx = AllText.IndexOf("", idx);
if (idx > 0)
{
idx += "".Length;
MobileProvisionUUID = AllText.Substring(idx, AllText.IndexOf("", idx) - idx);
}
}
idx = AllText.IndexOf("com.apple.developer.team-identifier");
if (idx > 0)
{
idx = AllText.IndexOf("", idx);
if (idx > 0)
{
idx += "".Length;
TeamUUID = AllText.Substring(idx, AllText.IndexOf("", idx) - idx);
}
}
}
if (string.IsNullOrEmpty(MobileProvisionUUID) || string.IsNullOrEmpty(TeamUUID))
{
MobileProvision = null;
SigningCertificate = null;
Log.TraceLog("Failed to parse the mobile provisioning profile.");
}
}
else
{
Log.TraceLog("No matching provision file was discovered. Please ensure you have a compatible provision installed.");
}
}
void IPPDataReceivedHandler(Object Sender, DataReceivedEventArgs Line)
{
if ((Line != null) && (Line.Data != null))
{
if (!string.IsNullOrEmpty(SigningCertificate))
{
if (Line.Data.Contains("CERTIFICATE-") && Line.Data.Contains(SigningCertificate))
{
bHaveCertificate = true;
}
}
else
{
int cindex = Line.Data.IndexOf("CERTIFICATE-");
int pindex = Line.Data.IndexOf("PROVISION-");
if (cindex > -1 && pindex > -1)
{
cindex += "CERTIFICATE-".Length;
SigningCertificate = Line.Data.Substring(cindex, pindex - cindex - 1);
pindex += "PROVISION-".Length;
MobileProvision = Line.Data.Substring(pindex);
}
}
}
}
}
class IOSPlatform : UEBuildPlatform
{
IOSPlatformSDK SDK;
List CachedProjectSettings = new List();
Dictionary ProvisionCache = new Dictionary();
// by default, use an empty architecture (which is really just a modifer to the platform for some paths/names)
public static string IOSArchitecture = "";
public IOSPlatform(IOSPlatformSDK InSDK)
: this(InSDK, UnrealTargetPlatform.IOS, CppPlatform.IOS)
{
}
protected IOSPlatform(IOSPlatformSDK InSDK, UnrealTargetPlatform TargetPlatform, CppPlatform CPPPlatform)
: base(TargetPlatform, CPPPlatform)
{
SDK = InSDK;
}
// The current architecture - affects everything about how UBT operates on IOS
public override string GetDefaultArchitecture(FileReference ProjectFile)
{
return IOSArchitecture;
}
public override void ResetTarget(TargetRules Target)
{
// we currently don't have any simulator libs for PhysX
if (Target.Architecture == "-simulator")
{
Target.bCompilePhysX = false;
}
Target.bBuildEditor = false;
Target.bBuildDeveloperTools = false;
Target.bCompileAPEX = false;
Target.bRuntimePhysicsCooking = false;
Target.bCompileSimplygon = false;
Target.bCompileSimplygonSSF = false;
Target.bBuildDeveloperTools = false;
}
public override void ValidateTarget(TargetRules Target)
{
Target.bUsePCHFiles = false;
Target.bDeployAfterCompile = true;
// we assume now we are building with IOS8 or later
if (Target.bCompileAgainstEngine)
{
Target.GlobalDefinitions.Add("HAS_METAL=1");
Target.ExtraModuleNames.Add("MetalRHI");
}
else
{
Target.GlobalDefinitions.Add("HAS_METAL=0");
}
Target.bCheckSystemHeadersForModification = false;
}
public override SDKStatus HasRequiredSDKsInstalled()
{
return SDK.HasRequiredSDKsInstalled();
}
///
/// Get the extension to use for the given binary type
///
/// The binary type being built
/// string The binary extenstion (ie 'exe' or 'dll')
public override string GetBinaryExtension(UEBuildBinaryType InBinaryType)
{
switch (InBinaryType)
{
case UEBuildBinaryType.DynamicLinkLibrary:
return ".dylib";
case UEBuildBinaryType.Executable:
return "";
case UEBuildBinaryType.StaticLibrary:
return ".a";
case UEBuildBinaryType.Object:
return ".o";
case UEBuildBinaryType.PrecompiledHeader:
return ".gch";
}
return base.GetBinaryExtension(InBinaryType);
}
public IOSProjectSettings ReadProjectSettings(FileReference ProjectFile)
{
IOSProjectSettings ProjectSettings = CachedProjectSettings.FirstOrDefault(x => x.ProjectFile == ProjectFile);
if(ProjectSettings == null)
{
ProjectSettings = CreateProjectSettings(ProjectFile);
CachedProjectSettings.Add(ProjectSettings);
}
return ProjectSettings;
}
protected virtual IOSProjectSettings CreateProjectSettings(FileReference ProjectFile)
{
return new IOSProjectSettings(ProjectFile);
}
public IOSProvisioningData ReadProvisioningData(IOSProjectSettings ProjectSettings, bool bForDistribution = false)
{
string ProvisionKey = ProjectSettings.BundleIdentifier + " " + bForDistribution.ToString();
IOSProvisioningData ProvisioningData;
if(!ProvisionCache.TryGetValue(ProvisionKey, out ProvisioningData))
{
ProvisioningData = CreateProvisioningData(ProjectSettings, bForDistribution);
ProvisionCache.Add(ProvisionKey, ProvisioningData);
}
return ProvisioningData;
}
protected virtual IOSProvisioningData CreateProvisioningData(IOSProjectSettings ProjectSettings, bool bForDistribution)
{
return new IOSProvisioningData(ProjectSettings, bForDistribution);
}
public override string GetDebugInfoExtension(ReadOnlyTargetRules InTarget, UEBuildBinaryType InBinaryType)
{
IOSProjectSettings ProjectSettings = ReadProjectSettings(InTarget.ProjectFile);
if(ProjectSettings.bGeneratedSYMFile)
{
return ".dSYM";
}
if(ProjectSettings.bGeneratedSYMBundle)
{
return ".dSYM.zip";
}
return "";
}
public override bool CanUseXGE()
{
return false;
}
public override bool CanUseDistcc()
{
return true;
}
public override void PreBuildSync()
{
IOSToolChain.PreBuildSync();
}
public override void PostBuildSync(UEBuildTarget Target)
{
IOSToolChain.PostBuildSync(Target);
}
public override void PostCodeGeneration(UHTManifest Manifest)
{
IOSToolChain.PostCodeGeneration(Manifest);
}
///
/// Check for the default configuration
/// return true if the project uses the default build config
///
public override bool HasDefaultBuildConfig(UnrealTargetPlatform Platform, DirectoryReference ProjectDirectoryName)
{
string[] BoolKeys = new string[] {
"bDevForArmV7", "bDevForArm64", "bDevForArmV7S", "bShipForArmV7",
"bShipForArm64", "bShipForArmV7S", "bShipForBitcode", "bGeneratedSYMFile",
"bGeneratedSYMBundle", "bEnableRemoteNotificationsSupport", "bEnableCloudKitSupport"
};
string[] StringKeys = new string[] {
"MinimumiOSVersion",
"AdditionalLinkerFlags",
"AdditionalShippingLinkerFlags"
};
// look up iOS specific settings
if (!DoProjectSettingsMatchDefault(Platform, ProjectDirectoryName, "/Script/IOSRuntimeSettings.IOSRuntimeSettings",
BoolKeys, null, StringKeys))
{
return false;
}
// check the base settings
return base.HasDefaultBuildConfig(Platform, ProjectDirectoryName);
}
///
/// Whether the editor should be built for this platform or not
///
/// The UnrealTargetPlatform being built
/// The UnrealTargetConfiguration being built
/// bool true if the editor should be built, false if not
public override bool ShouldNotBuildEditor(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration)
{
return true;
}
public override bool BuildRequiresCookedData(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration)
{
return true; // for iOS can only run cooked. this is mostly for testing console code paths.
}
public override bool ShouldCompileMonolithicBinary(UnrealTargetPlatform InPlatform)
{
// This platform currently always compiles monolithic
return true;
}
public override bool UseAbsolutePathsInUnityFiles()
{
return false;
}
///
/// Modify the rules for a newly created module, where the target is a different host platform.
/// This is not required - but allows for hiding details of a particular platform.
///
/// The name of the module
/// The module rules
/// The target being build
public override void ModifyModuleRulesForOtherPlatform(string ModuleName, ModuleRules Rules, ReadOnlyTargetRules Target)
{
if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Mac))
{
bool bBuildShaderFormats = Target.bForceBuildShaderFormats;
if (!Target.bBuildRequiresCookedData)
{
if (ModuleName == "Engine")
{
if (Target.bBuildDeveloperTools)
{
Rules.PlatformSpecificDynamicallyLoadedModuleNames.Add("IOSTargetPlatform");
Rules.PlatformSpecificDynamicallyLoadedModuleNames.Add("TVOSTargetPlatform");
}
}
else if (ModuleName == "TargetPlatform")
{
bBuildShaderFormats = true;
Rules.DynamicallyLoadedModuleNames.Add("TextureFormatPVR");
Rules.DynamicallyLoadedModuleNames.Add("TextureFormatASTC");
if (Target.bBuildDeveloperTools && Target.bCompileAgainstEngine)
{
Rules.PlatformSpecificDynamicallyLoadedModuleNames.Add("AudioFormatADPCM");
}
}
}
// allow standalone tools to use targetplatform modules, without needing Engine
if (ModuleName == "TargetPlatform")
{
if (Target.bForceBuildTargetPlatforms)
{
Rules.PlatformSpecificDynamicallyLoadedModuleNames.Add("IOSTargetPlatform");
Rules.PlatformSpecificDynamicallyLoadedModuleNames.Add("TVOSTargetPlatform");
}
if (bBuildShaderFormats)
{
Rules.PlatformSpecificDynamicallyLoadedModuleNames.Add("MetalShaderFormat");
}
}
}
}
///
/// Converts the passed in path from UBT host to compiler native format.
///
/// The path to convert
/// The path in native format for the toolchain
public override string ConvertPath(string OriginalPath)
{
return IOSToolChain.ConvertPath(OriginalPath);
}
///
/// Whether this platform should create debug information or not
///
/// The target being built
/// bool true if debug info should be generated, false if not
public override bool ShouldCreateDebugInfo(ReadOnlyTargetRules Target)
{
return true;
}
///
/// Setup the target environment for building
///
/// Settings for the target being compiled
/// The compile environment for this target
/// The link environment for this target
public override void SetUpEnvironment(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment)
{
CompileEnvironment.Definitions.Add("PLATFORM_IOS=1");
CompileEnvironment.Definitions.Add("PLATFORM_APPLE=1");
CompileEnvironment.Definitions.Add("WITH_TTS=0");
CompileEnvironment.Definitions.Add("WITH_SPEECH_RECOGNITION=0");
CompileEnvironment.Definitions.Add("WITH_DATABASE_SUPPORT=0");
CompileEnvironment.Definitions.Add("WITH_EDITOR=0");
CompileEnvironment.Definitions.Add("USE_NULL_RHI=0");
CompileEnvironment.Definitions.Add("REQUIRES_ALIGNED_INT_ACCESS");
IOSProjectSettings ProjectSettings = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.IOS)).ReadProjectSettings(Target.ProjectFile);
if (ProjectSettings.bNotificationsEnabled)
{
CompileEnvironment.Definitions.Add("NOTIFICATIONS_ENABLED=1");
}
else
{
CompileEnvironment.Definitions.Add("NOTIFICATIONS_ENABLED=0");
}
if (Target.Architecture == "-simulator")
{
CompileEnvironment.Definitions.Add("WITH_SIMULATOR=1");
}
else
{
CompileEnvironment.Definitions.Add("WITH_SIMULATOR=0");
}
LinkEnvironment.AdditionalFrameworks.Add(new UEBuildFramework("GameKit"));
LinkEnvironment.AdditionalFrameworks.Add(new UEBuildFramework("StoreKit"));
}
///
/// Modify the rules for a newly created module, in a target that's being built for this platform.
/// This is not required - but allows for hiding details of a particular platform.
///
/// The name of the module
/// The module rules
/// The target being build
public override void ModifyModuleRulesForActivePlatform(string ModuleName, ModuleRules Rules, ReadOnlyTargetRules Target)
{
}
///
/// Creates a toolchain instance for the given platform.
///
/// The platform to create a toolchain for
/// The target being built
/// New toolchain instance.
public override UEToolChain CreateToolChain(CppPlatform CppPlatform, ReadOnlyTargetRules Target)
{
IOSProjectSettings ProjectSettings = ReadProjectSettings(Target.ProjectFile);
return new IOSToolChain(Target.ProjectFile, ProjectSettings);
}
///
/// Deploys the given target
///
/// Information about the target being deployed
public override void Deploy(UEBuildDeployTarget Target)
{
new UEDeployIOS().PrepTargetForDeployment(Target);
}
}
class IOSPlatformSDK : UEBuildPlatformSDK
{
protected override SDKStatus HasRequiredManualSDKInternal()
{
if (!Utils.IsRunningOnMono)
{
// check to see if iTunes is installed
string dllPath = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Apple Inc.\\Apple Mobile Device Support\\Shared", "iTunesMobileDeviceDLL", null) as string;
if (String.IsNullOrEmpty(dllPath) || !File.Exists(dllPath))
{
dllPath = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Apple Inc.\\Apple Mobile Device Support\\Shared", "MobileDeviceDLL", null) as string;
if (String.IsNullOrEmpty(dllPath) || !File.Exists(dllPath))
{
return SDKStatus.Invalid;
}
}
}
return SDKStatus.Valid;
}
}
class IOSPlatformFactory : UEBuildPlatformFactory
{
protected override UnrealTargetPlatform TargetPlatform
{
get { return UnrealTargetPlatform.IOS; }
}
///
/// Register the platform with the UEBuildPlatform class
///
protected override void RegisterBuildPlatforms(SDKOutputLevel OutputLevel)
{
IOSPlatformSDK SDK = new IOSPlatformSDK();
SDK.ManageAndValidateSDK(OutputLevel);
// Register this build platform for IOS
Log.TraceVerbose(" Registering for {0}", UnrealTargetPlatform.IOS.ToString());
UEBuildPlatform.RegisterBuildPlatform(new IOSPlatform(SDK));
UEBuildPlatform.RegisterPlatformWithGroup(UnrealTargetPlatform.IOS, UnrealPlatformGroup.Unix);
UEBuildPlatform.RegisterPlatformWithGroup(UnrealTargetPlatform.IOS, UnrealPlatformGroup.Apple);
UEBuildPlatform.RegisterPlatformWithGroup(UnrealTargetPlatform.IOS, UnrealPlatformGroup.IOS);
if (IOSPlatform.IOSArchitecture == "-simulator")
{
UEBuildPlatform.RegisterPlatformWithGroup(UnrealTargetPlatform.IOS, UnrealPlatformGroup.Simulator);
}
else
{
UEBuildPlatform.RegisterPlatformWithGroup(UnrealTargetPlatform.IOS, UnrealPlatformGroup.Device);
}
}
}
}