You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
========================== MAJOR FEATURES + CHANGES ========================== Change 2835191 on 2016/01/19 by Nick.Whiting Invert the y-axis on the SteamVR controllers to match the convention of the engine and the rest of the gamepads #jira UE-22705 Change 2835686 on 2016/01/20 by Gareth.Martin Fixed landscape material instances not being updated if holes are painted on a landscape that doesn't have the landscape visibility mask node in the material and then the visibility mask node is added to the material later. #jira UE-18187 Change 2835767 on 2016/01/20 by Richard.Hinckley #jira UE-25499 Added a cursor to TopDown template (C++ version) to match the BP version. Change 2835772 on 2016/01/20 by Richard.Hinckley #jira UE-25499 Adding the material asset for the C++ TopDown template's cursor. Change 2835811 on 2016/01/20 by Taizyd.Korambayil #jira UE-25699 Added Validity Checks in BP logic, unchecked CDO for Pixel Ship, to Fix Log Warnings #jira UE-25704 Adjusted Matinee to happen at Box Location #jira UE-25688 Adjusted Player Starts #jira UE-25693 Adjusted Player Starts Change 2835863 on 2016/01/20 by Gareth.Martin Fixed crash in the landscape ramp and mirror tools if the streaming level containing the landscape is hidden (or possibly if the landscape actor is deleted) #jira UE-24883 Change 2835889 on 2016/01/20 by Taizyd.Korambayil #jira UE-25698 Enabled V-sync, also fixed up player Respawn Issue Change 2835995 on 2016/01/20 by Jamie.Dale The output log now hard-wraps lines to prevent long lines causing performance issues #jira UE-24187 Change 2836052 on 2016/01/20 by Taizyd.Korambayil #jira UE-25675 Added Blocking Volume to prevent Player from Falling off map #jira UE-25676 Added Blocking Volumes so that the Player doesn't get stucl at awkward corners under the Bridge Change 2836137 on 2016/01/20 by Chad.Taylor Vehicle and VehicleAdv template content fixes for new VR camera #jira UE-25507 Change 2836166 on 2016/01/20 by Gareth.Martin Fixed hiding a streaming level containing a landscape causing the landscape editor to switch to the "New Landscape" tool instead of exiting #jira UE-25093 Change 2836174 on 2016/01/20 by Chad.Taylor IHeadMountedDisplay crash fix associated with accessing a dangling pointer. #jira UE-25272 Change 2836179 on 2016/01/20 by Jamie.Dale Optimized FShapedGlyphSequence reverse look-up There's now a reverse look-up map of cluster indices to their glyph data in order to avoid brute force looping #jira UE-24187 Change 2836286 on 2016/01/20 by Chris.Babcock Update Qualcomm TextureConverter for OSX #jira UE-22092 #ue4 #android Change 2836328 on 2016/01/20 by Nick.Darnell Fixing a problem with widget components crashing on destruction with the render commands to pre/post render for window render commands needing access to the policy, but it potentially being deleted. Inserting a NoOp command that keeps the shared ptr alive through the RHI render process. #jira UE-25752 Change 2836342 on 2016/01/20 by Nick.Darnell Depending on shutdown order, the Slate Renderer may go away, and then render data handles may not be collected correctly because they are trying to reference a pointer that's no longer valid and cause a crash on exit. The correct approach would be to have render handles actually have a pointer back to who owns them, in this case the RHI Resource Manager, which is still alive and well at this point in the pipeline. Then if the resource manager is collected, it forces all handles to get cleaned up correctly, or if the handles are collected first, they can be sure they've got a valid pointer back to the resource manager. #jira UE-25753 Change 2836358 on 2016/01/20 by Taizyd.Korambayil #jira UE-25710 Replaced Deprecated Nodes Change 2836510 on 2016/01/20 by Taizyd.Korambayil #jira UE-25718 Adjsuted BP to make pointer decal rotate in the direction of surface Change 2836564 on 2016/01/20 by Taizyd.Korambayil #jira UE-25716 Added bool to store last Moved Direction Change 2836697 on 2016/01/20 by Taizyd.Korambayil #jira UE-25740 Removed unused VR Nodes to remove Log errors on Mac Change 2836725 on 2016/01/20 by Peter.Sauerbrei workaround for thread race when trying to release the TargetDeviceService endpoint after an unclaim message is sent #jira UE-25123 Change 2836782 on 2016/01/20 by Jamie.Dale Added FTextLayout::AddLines This is similar to AddLine, however it allows you to add multiple lines in a single call, thus avoiding the re-justification cost associated with each call to AddLine. AddLine has also been changed to take the same structure type as AddLines (which takes an array of these structures), and the existing version of AddLine has been deprecated. #jira UE-24187 Change 2836801 on 2016/01/20 by Jeff.Campeau [CL 2857187 by Matthew Griffin in Main branch]
431 lines
17 KiB
C#
431 lines
17 KiB
C#
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.IO;
|
|
using AutomationTool;
|
|
using UnrealBuildTool;
|
|
|
|
public class MacPlatform : Platform
|
|
{
|
|
public MacPlatform()
|
|
: base(UnrealTargetPlatform.Mac)
|
|
{
|
|
}
|
|
|
|
public override string GetCookPlatform(bool bDedicatedServer, bool bIsClientOnly, string CookFlavor)
|
|
{
|
|
const string NoEditorCookPlatform = "MacNoEditor";
|
|
const string ServerCookPlatform = "MacServer";
|
|
const string ClientCookPlatform = "MacClient";
|
|
|
|
if (bDedicatedServer)
|
|
{
|
|
return ServerCookPlatform;
|
|
}
|
|
else if (bIsClientOnly)
|
|
{
|
|
return ClientCookPlatform;
|
|
}
|
|
else
|
|
{
|
|
return NoEditorCookPlatform;
|
|
}
|
|
}
|
|
|
|
public override string GetEditorCookPlatform()
|
|
{
|
|
return "Mac";
|
|
}
|
|
|
|
private void StageAppBundle(DeploymentContext SC, StagedFileType InStageFileType, string InPath, string NewName)
|
|
{
|
|
if (InStageFileType != StagedFileType.DebugNonUFS)
|
|
{
|
|
// Files with DebugFileExtensions should always be DebugNonUFS
|
|
List<string> DebugExtentionWildCards = new List<string>();
|
|
foreach(string DebugExtention in GetDebugFileExtentions())
|
|
{
|
|
string ExtensionWildcard = "*" + DebugExtention;
|
|
DebugExtentionWildCards.Add(ExtensionWildcard);
|
|
SC.StageFiles(StagedFileType.DebugNonUFS, InPath, ExtensionWildcard, true, null, NewName, true, true, null);
|
|
}
|
|
|
|
// Also stage the non-debug files, excluding the debug ones staged above
|
|
SC.StageFiles(InStageFileType, InPath, "*", true, DebugExtentionWildCards.ToArray(), NewName, false, true, null);
|
|
}
|
|
else
|
|
{
|
|
// We are already DebugNonUFS, no need to do any special-casing
|
|
SC.StageFiles(InStageFileType, InPath, "*", true, null, NewName, false, true, null);
|
|
}
|
|
}
|
|
|
|
public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
|
|
{
|
|
// the first app is the "main" one, the rest are marked as debug files for exclusion from chunking/distribution
|
|
StagedFileType WorkingFileType = StagedFileType.NonUFS;
|
|
|
|
List<string> Exes = GetExecutableNames(SC);
|
|
foreach (var Exe in Exes)
|
|
{
|
|
string AppBundlePath = "";
|
|
if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir)))
|
|
{
|
|
AppBundlePath = CombinePaths(SC.ShortProjectName, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app");
|
|
StageAppBundle(SC, WorkingFileType, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"), AppBundlePath);
|
|
}
|
|
else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)))
|
|
{
|
|
AppBundlePath = CombinePaths("Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app");
|
|
|
|
string AbsoluteBundlePath = CombinePaths (SC.LocalRoot, AppBundlePath);
|
|
// ensure the ue4game binary exists, if applicable
|
|
if (!SC.IsCodeBasedProject && !Directory.Exists(AbsoluteBundlePath) && !SC.bIsCombiningMultiplePlatforms)
|
|
{
|
|
LogError("Failed to find app bundle " + AbsoluteBundlePath);
|
|
throw new AutomationException(ExitCode.Error_MissingExecutable, "Could not find app bundle {0}. You may need to build the UE4 project with your target configuration and platform.", AbsoluteBundlePath);
|
|
}
|
|
|
|
StageAppBundle(SC, WorkingFileType, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"), AppBundlePath);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(AppBundlePath))
|
|
{
|
|
SC.StageFiles(WorkingFileType, CombinePaths(SC.ProjectRoot, "Build/Mac"), "Application.icns", false, null, CombinePaths(AppBundlePath, "Contents/Resources"), true);
|
|
|
|
if (Params.bUsesSteam)
|
|
{
|
|
SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Source/ThirdParty/Steamworks/Steamv132/sdk/redistributable_bin/osx32"), "libsteam_api.dylib", false, null, CombinePaths(AppBundlePath, "Contents/MacOS"), true);
|
|
}
|
|
}
|
|
|
|
// the first app is the "main" one, the rest are marked as debug files for exclusion from chunking/distribution
|
|
WorkingFileType = StagedFileType.DebugNonUFS;
|
|
}
|
|
|
|
if (SC.bStageCrashReporter)
|
|
{
|
|
string CrashReportClientPath = CombinePaths("Engine/Binaries", SC.PlatformDir, "CrashReportClient.app");
|
|
StageAppBundle(SC, StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, "CrashReportClient.app"), CrashReportClientPath);
|
|
}
|
|
|
|
// Copy the splash screen, Mac specific
|
|
SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true);
|
|
|
|
// CEF3 files
|
|
if(Params.bUsesCEF3)
|
|
{
|
|
SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/CEF3/Mac/"), "*", true, null, null, true);
|
|
string UnrealCEFSubProcessPath = CombinePaths("Engine/Binaries", SC.PlatformDir, "UnrealCEFSubProcess.app");
|
|
StageAppBundle(SC, StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, "UnrealCEFSubProcess.app"), UnrealCEFSubProcessPath);
|
|
}
|
|
|
|
// Stage the bootstrap executable
|
|
if(!Params.NoBootstrapExe)
|
|
{
|
|
foreach(StageTarget Target in SC.StageTargets)
|
|
{
|
|
BuildProduct Executable = Target.Receipt.BuildProducts.FirstOrDefault(x => x.Type == BuildProductType.Executable);
|
|
if(Executable != null)
|
|
{
|
|
// only create bootstraps for executables
|
|
if (SC.NonUFSStagingFiles.ContainsKey(Executable.Path) && Executable.Path.Replace("\\", "/").Contains("/" + TargetPlatformType.ToString() + "/"))
|
|
{
|
|
string BootstrapArguments = "";
|
|
if (!SC.IsCodeBasedProject && !ShouldStageCommandLine(Params, SC))
|
|
{
|
|
BootstrapArguments = String.Format("../../../{0}/{0}.uproject", SC.ShortProjectName);
|
|
}
|
|
|
|
string BootstrapExeName;
|
|
if(SC.StageTargetConfigurations.Count > 1)
|
|
{
|
|
BootstrapExeName = Path.GetFileName(Executable.Path) + ".app";
|
|
}
|
|
else if(Params.IsCodeBasedProject)
|
|
{
|
|
BootstrapExeName = Target.Receipt.TargetName + ".app";
|
|
}
|
|
else
|
|
{
|
|
BootstrapExeName = SC.ShortProjectName + ".app";
|
|
}
|
|
|
|
string AppPath = Executable.Path.Substring(0, Executable.Path.LastIndexOf(".app/") + 4);
|
|
object Dest = SC.NonUFSStagingFiles[Executable.Path];
|
|
foreach (var DestPath in SC.NonUFSStagingFiles[Executable.Path])
|
|
{
|
|
string AppRelativePath = DestPath.Substring(0, DestPath.LastIndexOf(".app/") + 4);
|
|
StageBootstrapExecutable(SC, BootstrapExeName, AppPath, AppRelativePath, BootstrapArguments);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy the ShaderCache files, if they exist
|
|
SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Content"), "ShaderCache.ushadercache", false, null, null, true);
|
|
SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Content"), "ShaderCodeCache.ushadercode", false, null, null, true);
|
|
}
|
|
|
|
string GetValueFromInfoPlist(string InfoPlist, string Key, string DefaultValue = "")
|
|
{
|
|
string Value = DefaultValue;
|
|
string KeyString = "<key>" + Key + "</key>";
|
|
int KeyIndex = InfoPlist.IndexOf(KeyString);
|
|
if (KeyIndex > 0)
|
|
{
|
|
int ValueStartIndex = InfoPlist.IndexOf("<string>", KeyIndex + KeyString.Length) + "<string>".Length;
|
|
int ValueEndIndex = InfoPlist.IndexOf("</string>", ValueStartIndex);
|
|
if (ValueStartIndex > 0 && ValueEndIndex > ValueStartIndex)
|
|
{
|
|
Value = InfoPlist.Substring(ValueStartIndex, ValueEndIndex - ValueStartIndex);
|
|
}
|
|
}
|
|
return Value;
|
|
}
|
|
|
|
void StageBootstrapExecutable(DeploymentContext SC, string ExeName, string TargetFile, string StagedRelativeTargetPath, string StagedArguments)
|
|
{
|
|
string InputApp = CombinePaths(SC.LocalRoot, "Engine", "Binaries", SC.PlatformDir, "BootstrapPackagedGame.app");
|
|
if (InternalUtils.SafeDirectoryExists(InputApp))
|
|
{
|
|
// Create the new bootstrap program
|
|
string IntermediateDir = CombinePaths(SC.ProjectRoot, "Intermediate", "Staging");
|
|
InternalUtils.SafeCreateDirectory(IntermediateDir);
|
|
|
|
string IntermediateApp = CombinePaths(IntermediateDir, ExeName);
|
|
if (Directory.Exists(IntermediateApp))
|
|
{
|
|
Directory.Delete(IntermediateApp, true);
|
|
}
|
|
CloneDirectory(InputApp, IntermediateApp);
|
|
|
|
// Rename the executable
|
|
string GameName = Path.GetFileNameWithoutExtension(ExeName);
|
|
File.Move(CombinePaths(IntermediateApp, "Contents", "MacOS", "BootstrapPackagedGame"), CombinePaths(IntermediateApp, "Contents", "MacOS", GameName));
|
|
|
|
// Copy the icon
|
|
string SrcInfoPlistPath = CombinePaths(TargetFile, "Contents", "Info.plist");
|
|
string SrcInfoPlist = File.ReadAllText(SrcInfoPlistPath);
|
|
|
|
string IconName = GetValueFromInfoPlist(SrcInfoPlist, "CFBundleIconFile");
|
|
if (!string.IsNullOrEmpty(IconName))
|
|
{
|
|
string IconPath = CombinePaths(TargetFile, "Contents", "Resources", IconName + ".icns");
|
|
InternalUtils.SafeCreateDirectory(CombinePaths(IntermediateApp, "Contents", "Resources"));
|
|
File.Copy(IconPath, CombinePaths(IntermediateApp, "Contents", "Resources", IconName + ".icns"));
|
|
}
|
|
|
|
// Update Info.plist contents
|
|
string DestInfoPlistPath = CombinePaths(IntermediateApp, "Contents", "Info.plist");
|
|
string DestInfoPlist = File.ReadAllText(DestInfoPlistPath);
|
|
|
|
string AppIdentifier = GetValueFromInfoPlist(SrcInfoPlist, "CFBundleIdentifier");
|
|
if (AppIdentifier == "com.epicgames.UE4Game")
|
|
{
|
|
AppIdentifier = "";
|
|
}
|
|
|
|
string Copyright = GetValueFromInfoPlist(SrcInfoPlist, "NSHumanReadableCopyright");
|
|
string BundleVersion = GetValueFromInfoPlist(SrcInfoPlist, "CFBundleVersion", "1");
|
|
string ShortVersion = GetValueFromInfoPlist(SrcInfoPlist, "CFBundleShortVersionString", "1.0");
|
|
|
|
DestInfoPlist = DestInfoPlist.Replace("com.epicgames.BootstrapPackagedGame", string.IsNullOrEmpty(AppIdentifier) ? "com.epicgames." + GameName + "_bootstrap" : AppIdentifier + "_bootstrap");
|
|
DestInfoPlist = DestInfoPlist.Replace("BootstrapPackagedGame", GameName);
|
|
DestInfoPlist = DestInfoPlist.Replace("__UE4_ICON_FILE__", IconName);
|
|
DestInfoPlist = DestInfoPlist.Replace("__UE4_APP_TO_LAUNCH__", StagedRelativeTargetPath);
|
|
DestInfoPlist = DestInfoPlist.Replace("__UE4_COMMANDLINE__", StagedArguments);
|
|
DestInfoPlist = DestInfoPlist.Replace("__UE4_COPYRIGHT__", Copyright);
|
|
DestInfoPlist = DestInfoPlist.Replace("__UE4_BUNDLE_VERSION__", BundleVersion);
|
|
DestInfoPlist = DestInfoPlist.Replace("__UE4_SHORT_VERSION__", ShortVersion);
|
|
|
|
File.WriteAllText(DestInfoPlistPath, DestInfoPlist);
|
|
|
|
StageAppBundle(SC, StagedFileType.NonUFS, IntermediateApp, ExeName);
|
|
}
|
|
}
|
|
|
|
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL)
|
|
{
|
|
// package up the program, potentially with an installer for Mac
|
|
PrintRunTime();
|
|
}
|
|
|
|
public override void ProcessArchivedProject(ProjectParams Params, DeploymentContext SC)
|
|
{
|
|
if (Params.CreateAppBundle)
|
|
{
|
|
string ExeName = SC.StageExecutables[0];
|
|
string BundlePath = CombinePaths(SC.ArchiveDirectory, SC.ShortProjectName + ".app");
|
|
|
|
if (SC.bIsCombiningMultiplePlatforms)
|
|
{
|
|
// when combining multiple platforms, don't merge the content into the .app, use the one in the Binaries directory
|
|
BundlePath = CombinePaths(SC.ArchiveDirectory, SC.ShortProjectName, "Binaries", "Mac", ExeName + ".app");
|
|
if (!Directory.Exists(BundlePath))
|
|
{
|
|
// if the .app wasn't there, just skip out (we don't require executables when combining)
|
|
return;
|
|
}
|
|
}
|
|
|
|
string TargetPath = CombinePaths(BundlePath, "Contents", "UE4");
|
|
if (!SC.bIsCombiningMultiplePlatforms)
|
|
{
|
|
if (Directory.Exists(BundlePath))
|
|
{
|
|
Directory.Delete(BundlePath, true);
|
|
}
|
|
|
|
string SourceBundlePath = CombinePaths(SC.ArchiveDirectory, SC.ShortProjectName, "Binaries", "Mac", ExeName + ".app");
|
|
if (!Directory.Exists(SourceBundlePath))
|
|
{
|
|
SourceBundlePath = CombinePaths(SC.ArchiveDirectory, "Engine", "Binaries", "Mac", ExeName + ".app");
|
|
}
|
|
Directory.Move(SourceBundlePath, BundlePath);
|
|
|
|
if (DirectoryExists(TargetPath))
|
|
{
|
|
Directory.Delete(TargetPath, true);
|
|
}
|
|
|
|
// First, move all files and folders inside he app bundle
|
|
string[] StagedFiles = Directory.GetFiles(SC.ArchiveDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
foreach (string FilePath in StagedFiles)
|
|
{
|
|
string TargetFilePath = CombinePaths(TargetPath, Path.GetFileName(FilePath));
|
|
Directory.CreateDirectory(Path.GetDirectoryName(TargetFilePath));
|
|
File.Move(FilePath, TargetFilePath);
|
|
}
|
|
|
|
string[] StagedDirectories = Directory.GetDirectories(SC.ArchiveDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
foreach (string DirPath in StagedDirectories)
|
|
{
|
|
string DirName = Path.GetFileName(DirPath);
|
|
if (!DirName.EndsWith(".app"))
|
|
{
|
|
string TargetDirPath = CombinePaths(TargetPath, DirName);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(TargetDirPath));
|
|
Directory.Move(DirPath, TargetDirPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update executable name, icon and entry in Info.plist
|
|
string UE4GamePath = CombinePaths(BundlePath, "Contents", "MacOS", ExeName);
|
|
if (ExeName != SC.ShortProjectName && File.Exists(UE4GamePath))
|
|
{
|
|
string GameExePath = CombinePaths(BundlePath, "Contents", "MacOS", SC.ShortProjectName);
|
|
File.Delete(GameExePath);
|
|
File.Move(UE4GamePath, GameExePath);
|
|
|
|
string DefaultIconPath = CombinePaths(BundlePath, "Contents", "Resources", "UE4Game.icns");
|
|
string CustomIconSrcPath = CombinePaths(BundlePath, "Contents", "Resources", "Application.icns");
|
|
string CustomIconDestPath = CombinePaths(BundlePath, "Contents", "Resources", SC.ShortProjectName + ".icns");
|
|
if (File.Exists(CustomIconSrcPath))
|
|
{
|
|
File.Delete(DefaultIconPath);
|
|
File.Move(CustomIconSrcPath, CustomIconDestPath);
|
|
}
|
|
else if (File.Exists(DefaultIconPath))
|
|
{
|
|
File.Move(DefaultIconPath, CustomIconDestPath);
|
|
}
|
|
|
|
string InfoPlistPath = CombinePaths(BundlePath, "Contents", "Info.plist");
|
|
string InfoPlistContents = File.ReadAllText(InfoPlistPath);
|
|
InfoPlistContents = InfoPlistContents.Replace(ExeName, SC.ShortProjectName);
|
|
InfoPlistContents = InfoPlistContents.Replace("<string>UE4Game</string>", "<string>" + SC.ShortProjectName + "</string>");
|
|
File.Delete(InfoPlistPath);
|
|
File.WriteAllText(InfoPlistPath, InfoPlistContents);
|
|
}
|
|
|
|
if (!SC.bIsCombiningMultiplePlatforms)
|
|
{
|
|
// creating these directories when the content isn't moved into the application causes it
|
|
// to fail to load, and isn't needed
|
|
Directory.CreateDirectory(CombinePaths(TargetPath, "Engine", "Binaries", "Mac"));
|
|
Directory.CreateDirectory(CombinePaths(TargetPath, SC.ShortProjectName, "Binaries", "Mac"));
|
|
}
|
|
}
|
|
}
|
|
|
|
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
|
|
{
|
|
if (!File.Exists(ClientApp))
|
|
{
|
|
if (Directory.Exists(ClientApp + ".app"))
|
|
{
|
|
ClientApp += ".app/Contents/MacOS/" + Path.GetFileName(ClientApp);
|
|
}
|
|
else
|
|
{
|
|
Int32 BaseDirLen = Params.BaseStageDirectory.Length;
|
|
string StageSubDir = ClientApp.Substring(BaseDirLen, ClientApp.IndexOf("/", BaseDirLen + 1) - BaseDirLen);
|
|
ClientApp = CombinePaths(Params.BaseStageDirectory, StageSubDir, Params.ShortProjectName + ".app/Contents/MacOS/" + Params.ShortProjectName);
|
|
}
|
|
}
|
|
|
|
PushDir(Path.GetDirectoryName(ClientApp));
|
|
// Always start client process and don't wait for exit.
|
|
ProcessResult ClientProcess = Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit);
|
|
PopDir();
|
|
|
|
return ClientProcess;
|
|
}
|
|
|
|
public override bool IsSupported { get { return true; } }
|
|
|
|
public override bool ShouldUseManifestForUBTBuilds(string AddArgs)
|
|
{
|
|
// don't use the manifest to set up build products if we are compiling Mac under Windows and we aren't going to copy anything back to the PC
|
|
bool bIsBuildingRemotely = UnrealBuildTool.BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac;
|
|
bool bUseManifest = !bIsBuildingRemotely || AddArgs.IndexOf("-CopyAppBundleBackToDevice", StringComparison.InvariantCultureIgnoreCase) > 0;
|
|
return bUseManifest;
|
|
}
|
|
public override List<string> GetDebugFileExtentions()
|
|
{
|
|
return new List<string> { ".dSYM" };
|
|
}
|
|
public override bool CanHostPlatform(UnrealTargetPlatform Platform)
|
|
{
|
|
if (Platform == UnrealTargetPlatform.IOS || Platform == UnrealTargetPlatform.Mac || Platform == UnrealTargetPlatform.TVOS)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override bool ShouldStageCommandLine(ProjectParams Params, DeploymentContext SC)
|
|
{
|
|
return false; // !String.IsNullOrEmpty(Params.StageCommandline) || !String.IsNullOrEmpty(Params.RunCommandline) || (!Params.IsCodeBasedProject && Params.NoBootstrapExe);
|
|
}
|
|
|
|
public override bool SignExecutables(DeploymentContext SC, ProjectParams Params)
|
|
{
|
|
if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
|
|
{
|
|
// Sign everything we built
|
|
List<string> FilesToSign = GetExecutableNames(SC);
|
|
foreach (var Exe in FilesToSign)
|
|
{
|
|
string AppBundlePath = "";
|
|
if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir)))
|
|
{
|
|
AppBundlePath = CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app");
|
|
}
|
|
else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)))
|
|
{
|
|
AppBundlePath = CombinePaths("Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app");
|
|
}
|
|
CodeSign.SignMacFileOrFolder(AppBundlePath);
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
}
|