2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
using System ;
using System.Collections ;
using System.Collections.Generic ;
2014-04-28 19:56:45 -04:00
using System.Linq ;
2014-03-14 14:13:41 -04:00
using System.IO ;
using System.Diagnostics ;
using System.Security.AccessControl ;
using System.Xml ;
using System.Text ;
2014-04-23 19:28:13 -04:00
using Ionic.Zip ;
using Ionic.Zlib ;
2014-03-14 14:13:41 -04:00
namespace UnrealBuildTool
{
class IOSToolChain : RemoteToolChain
{
public override void RegisterToolChain ( )
{
RegisterRemoteToolChain ( UnrealTargetPlatform . Mac , CPPTargetPlatform . IOS ) ;
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* NOTE :
* Do NOT change the defaults to set your values , instead you should set the environment variables
* properly in your system , as other tools make use of them to work properly !
* The defaults are there simply for examples so you know what to put in your env vars . . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// If you are looking for where to change the remote compile server name, look in RemoteToolChain.cs
/** If this is set, then we don't do any post-compile steps except moving the executable into the proper spot on the Mac */
2014-06-06 07:43:02 -04:00
[XmlConfig]
2014-04-23 18:00:27 -04:00
public static bool bUseDangerouslyFastMode = false ;
2014-03-14 14:13:41 -04:00
/** Which version of the iOS SDK to target at build time */
2014-06-06 07:43:02 -04:00
[XmlConfig]
2014-04-23 18:00:27 -04:00
public static string IOSSDKVersion = "latest" ;
2014-06-17 18:27:26 -04:00
public static float IOSSDKVersionFloat = 0.0f ;
2014-03-14 14:13:41 -04:00
2014-10-24 15:31:48 -04:00
/** Which version of the iOS to allow at build time */
2014-06-06 07:43:02 -04:00
[XmlConfig]
2015-03-24 14:35:38 -04:00
public static string BuildIOSVersion = "7.0" ;
2014-10-24 15:31:48 -04:00
2014-03-14 14:13:41 -04:00
/** Which developer directory to root from */
2014-06-06 07:43:02 -04:00
[XmlConfig]
2014-04-23 18:00:27 -04:00
public static string XcodeDeveloperDir = "/Applications/Xcode.app/Contents/Developer/" ;
2014-03-14 14:13:41 -04:00
/** Location of the SDKs */
2014-04-23 18:00:27 -04:00
private static string BaseSDKDir ;
private static string BaseSDKDirSim ;
2014-03-14 14:13:41 -04:00
/** Which compiler frontend to use */
private static string IOSCompiler = "clang++" ;
/** Which linker frontend to use */
private static string IOSLinker = "clang++" ;
/** Which library archiver to use */
private static string IOSArchiver = "libtool" ;
2014-04-28 19:56:45 -04:00
public List < string > BuiltBinaries = new List < string > ( ) ;
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
/** Additional frameworks stored locally so we have access without LinkEnvironment */
public List < UEBuildFramework > RememberedAdditionalFrameworks = new List < UEBuildFramework > ( ) ;
2014-04-30 14:09:06 -04:00
2014-04-23 18:00:27 -04:00
/// <summary>
2014-06-05 12:12:32 -04:00
/// Function to call to after reset default data.
2014-04-23 18:00:27 -04:00
/// </summary>
2014-06-05 12:12:32 -04:00
public static void PostReset ( )
2014-04-23 18:00:27 -04:00
{
/** Location of the SDKs */
BaseSDKDir = XcodeDeveloperDir + "Platforms/iPhoneOS.platform/Developer/SDKs" ;
BaseSDKDirSim = XcodeDeveloperDir + "Platforms/iPhoneSimulator.platform/Developer/SDKs" ;
}
2014-03-14 14:13:41 -04:00
/** Hunt down the latest IOS sdk if desired */
public override void SetUpGlobalEnvironment ( )
{
base . SetUpGlobalEnvironment ( ) ;
if ( IOSSDKVersion = = "latest" )
{
try
{
string [ ] SubDirs = null ;
if ( Utils . IsRunningOnMono )
{
// on the Mac, we can just get the directory name
SubDirs = System . IO . Directory . GetDirectories ( BaseSDKDir ) ;
2015-01-20 11:50:47 -05:00
if ( ! ProjectFileGenerator . bGenerateProjectFiles )
{
Log . TraceInformation ( String . Format ( "Directories : {0} {1}" , SubDirs , SubDirs [ 0 ] ) ) ;
}
2014-03-14 14:13:41 -04:00
}
else
{
Hashtable Results = RPCUtilHelper . Command ( "/" , "ls" , BaseSDKDir , null ) ;
if ( Results ! = null )
{
string Result = ( string ) Results [ "CommandOutput" ] ;
SubDirs = Result . Split ( "\r\n" . ToCharArray ( ) , StringSplitOptions . RemoveEmptyEntries ) ;
}
}
// loop over the subdirs and parse out the version
float MaxSDKVersion = 0.0f ;
string MaxSDKVersionString = null ;
foreach ( string SubDir in SubDirs )
{
string SubDirName = Path . GetFileNameWithoutExtension ( SubDir ) ;
if ( SubDirName . StartsWith ( "iPhoneOS" ) )
{
// get the SDK version from the directory name
string SDKString = SubDirName . Replace ( "iPhoneOS" , "" ) ;
2014-05-06 14:14:12 -04:00
float SDKVersion = 0.0f ;
try
{
SDKVersion = float . Parse ( SDKString , System . Globalization . CultureInfo . InvariantCulture ) ;
}
catch ( Exception )
{
// weirdly formatted SDKs
continue ;
}
2014-03-14 14:13:41 -04:00
// update largest SDK version number
if ( SDKVersion > MaxSDKVersion )
{
MaxSDKVersion = SDKVersion ;
MaxSDKVersionString = SDKString ;
}
}
}
// convert back to a string with the exact format
if ( MaxSDKVersionString ! = null )
{
IOSSDKVersion = MaxSDKVersionString ;
}
}
2014-06-06 10:53:51 -04:00
catch ( Exception Ex )
2014-03-14 14:13:41 -04:00
{
// on any exception, just use the backup version
2014-06-17 18:27:26 -04:00
Log . TraceInformation ( "Triggered an exception while looking for SDK directory in Xcode.app" ) ;
2014-06-06 10:53:51 -04:00
Log . TraceInformation ( "{0}" , Ex . ToString ( ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-17 18:27:26 -04:00
if ( IOSSDKVersion = = "latest" )
2014-03-14 14:13:41 -04:00
{
2014-06-17 18:27:26 -04:00
throw new BuildException ( "Unable to determine SDK version from Xcode, we cannot continue" ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-06-17 18:27:26 -04:00
2014-06-24 11:41:30 -04:00
IOSSDKVersionFloat = float . Parse ( IOSSDKVersion , System . Globalization . CultureInfo . InvariantCulture ) ;
2014-06-17 18:27:26 -04:00
2015-01-20 11:50:47 -05:00
if ( ! ProjectFileGenerator . bGenerateProjectFiles )
2014-06-17 18:27:26 -04:00
{
2015-01-20 11:50:47 -05:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
{
Log . TraceInformation ( "Compiling with IOS SDK {0} on Mac {1}" , IOSSDKVersionFloat , RemoteServerName ) ;
}
else
{
Log . TraceInformation ( "Compiling with IOS SDK {0}" , IOSSDKVersionFloat ) ;
}
2014-06-17 18:27:26 -04:00
}
2014-03-14 14:13:41 -04:00
}
2015-04-03 10:25:57 -04:00
public override void AddFilesToReceipt ( BuildReceipt Receipt , UEBuildBinary Binary )
2014-04-23 18:33:14 -04:00
{
2015-03-21 19:32:59 -04:00
if ( BuildConfiguration . bCreateStubIPA & & Binary . Config . Type ! = UEBuildBinaryType . StaticLibrary )
2014-04-23 19:28:13 -04:00
{
string StubFile = Path . Combine ( Path . GetDirectoryName ( Binary . Config . OutputFilePath ) , Path . GetFileNameWithoutExtension ( Binary . Config . OutputFilePath ) + ".stub" ) ;
2015-04-03 10:25:57 -04:00
Receipt . AddBuildProduct ( StubFile , BuildProductType . Executable ) ;
2014-04-23 19:28:13 -04:00
}
2014-04-23 18:33:14 -04:00
}
2014-03-14 14:13:41 -04:00
static bool bHasPrinted = false ;
static string GetArchitectureArgument ( CPPTargetConfiguration Configuration , string UBTArchitecture )
{
2015-02-27 16:10:22 -05:00
IOSPlatform BuildPlat = UEBuildPlatform . GetBuildPlatform ( UnrealTargetPlatform . IOS ) as IOSPlatform ;
BuildPlat . SetUpProjectEnvironment ( UnrealTargetPlatform . IOS ) ;
2014-03-14 14:13:41 -04:00
// get the list of architectures to compile
string Archs =
UBTArchitecture = = "-simulator" ? "i386" :
2015-02-27 16:10:22 -05:00
( Configuration = = CPPTargetConfiguration . Shipping ) ? IOSPlatform . ShippingArchitectures : IOSPlatform . NonShippingArchitectures ;
2014-03-14 14:13:41 -04:00
if ( ! bHasPrinted )
{
bHasPrinted = true ;
Console . WriteLine ( "Compiling with these architectures: " + Archs ) ;
}
// parse the string
string [ ] Tokens = Archs . Split ( "," . ToCharArray ( ) ) ;
string Result = "" ;
foreach ( string Token in Tokens )
{
Result + = " -arch " + Token ;
}
return Result ;
}
2014-07-01 11:28:39 -04:00
string GetCompileArguments_Global ( CPPEnvironment CompileEnvironment )
2014-03-14 14:13:41 -04:00
{
2015-03-24 14:35:38 -04:00
IOSPlatform BuildPlat = UEBuildPlatform . GetBuildPlatform ( UnrealTargetPlatform . IOS ) as IOSPlatform ;
BuildPlat . SetUpProjectEnvironment ( UnrealTargetPlatform . IOS ) ;
2014-03-14 14:13:41 -04:00
string Result = "" ;
Result + = " -fmessage-length=0" ;
Result + = " -pipe" ;
Result + = " -fpascal-strings" ;
Result + = " -fno-exceptions" ;
Result + = " -fno-rtti" ;
Result + = " -fvisibility=hidden" ; // hides the linker warnings with PhysX
2014-06-17 18:27:26 -04:00
// if (CompileEnvironment.Config.TargetConfiguration == CPPTargetConfiguration.Shipping)
// {
// Result += " -flto";
// }
2014-03-14 14:13:41 -04:00
Result + = " -Wall -Werror" ;
Result + = " -Wno-unused-variable" ;
Result + = " -Wno-unused-value" ;
// this will hide the warnings about static functions in headers that aren't used in every single .cpp file
Result + = " -Wno-unused-function" ;
// this hides the "enumeration value 'XXXXX' not handled in switch [-Wswitch]" warnings - we should maybe remove this at some point and add UE_LOG(, Fatal, ) to default cases
Result + = " -Wno-switch" ;
// this hides the "warning : comparison of unsigned expression < 0 is always false" type warnings due to constant comparisons, which are possible with template arguments
Result + = " -Wno-tautological-compare" ;
//This will prevent the issue of warnings for unused private variables.
Result + = " -Wno-unused-private-field" ;
Result + = " -Wno-invalid-offsetof" ; // needed to suppress warnings about using offsetof on non-POD types.
Result + = " -c" ;
// What architecture(s) to build for
2014-06-09 11:12:01 -04:00
Result + = GetArchitectureArgument ( CompileEnvironment . Config . Target . Configuration , CompileEnvironment . Config . Target . Architecture ) ;
2014-03-14 14:13:41 -04:00
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Architecture = = "-simulator" )
2014-03-14 14:13:41 -04:00
{
Result + = " -isysroot " + BaseSDKDirSim + "/iPhoneSimulator" + IOSSDKVersion + ".sdk" ;
}
else
{
Result + = " -isysroot " + BaseSDKDir + "/iPhoneOS" + IOSSDKVersion + ".sdk" ;
}
2015-03-24 14:35:38 -04:00
Result + = " -miphoneos-version-min=" + BuildPlat . GetRunTimeVersion ( ) ;
2014-03-14 14:13:41 -04:00
// Optimize non- debug builds.
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Configuration ! = CPPTargetConfiguration . Debug )
2014-03-14 14:13:41 -04:00
{
2014-06-10 17:14:29 -04:00
if ( UEBuildConfiguration . bCompileForSize )
{
Result + = " -Oz" ;
}
else
{
Result + = " -O3" ;
}
2014-03-14 14:13:41 -04:00
}
else
{
Result + = " -O0" ;
}
// Create DWARF format debug info if wanted,
2015-03-20 15:10:21 -04:00
if ( CompileEnvironment . Config . bCreateDebugInfo )
2014-03-14 14:13:41 -04:00
{
Result + = " -gdwarf-2" ;
}
2014-07-01 11:28:39 -04:00
// Add additional frameworks so that their headers can be found
foreach ( UEBuildFramework Framework in CompileEnvironment . Config . AdditionalFrameworks )
{
if ( Framework . OwningModule ! = null & & Framework . FrameworkZipPath ! = null & & Framework . FrameworkZipPath ! = "" )
{
Result + = " -F \"" + GetRemoteIntermediateFrameworkZipPath ( Framework ) + "\"" ;
}
}
2014-03-14 14:13:41 -04:00
return Result ;
}
static string GetCompileArguments_CPP ( )
{
string Result = "" ;
Result + = " -x objective-c++" ;
Result + = " -fno-rtti" ;
Result + = " -fobjc-abi-version=2" ;
Result + = " -fobjc-legacy-dispatch" ;
2014-10-20 11:53:50 -04:00
Result + = " -std=c++11" ;
2015-02-27 16:10:22 -05:00
Result + = " -stdlib=libc++" ;
2014-03-14 14:13:41 -04:00
return Result ;
}
static string GetCompileArguments_MM ( )
{
string Result = "" ;
Result + = " -x objective-c++" ;
Result + = " -fobjc-abi-version=2" ;
Result + = " -fobjc-legacy-dispatch" ;
Result + = " -fno-rtti" ;
2014-10-20 11:53:50 -04:00
Result + = " -std=c++11" ;
2015-02-27 16:10:22 -05:00
Result + = " -stdlib=libc++" ;
2014-03-14 14:13:41 -04:00
return Result ;
}
static string GetCompileArguments_M ( )
{
string Result = "" ;
Result + = " -x objective-c" ;
Result + = " -fobjc-abi-version=2" ;
Result + = " -fobjc-legacy-dispatch" ;
2014-10-20 11:53:50 -04:00
Result + = " -std=c++11" ;
2015-02-27 16:10:22 -05:00
Result + = " -stdlib=libc++" ;
2014-03-14 14:13:41 -04:00
return Result ;
}
static string GetCompileArguments_C ( )
{
string Result = "" ;
Result + = " -x c" ;
return Result ;
}
static string GetCompileArguments_PCH ( )
{
string Result = "" ;
Result + = " -x objective-c++-header" ;
Result + = " -fno-rtti" ;
2014-10-20 11:53:50 -04:00
Result + = " -std=c++11" ;
2015-02-27 16:10:22 -05:00
Result + = " -stdlib=libc++" ;
2014-03-14 14:13:41 -04:00
return Result ;
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
string GetLocalFrameworkZipPath ( UEBuildFramework Framework )
{
2014-05-12 18:51:03 -04:00
if ( Framework . OwningModule = = null )
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
{
2014-05-12 18:51:03 -04:00
throw new BuildException ( "GetLocalFrameworkZipPath: No owning module for framework {0}" , Framework . FrameworkName ) ;
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
}
2014-05-12 18:51:03 -04:00
return Path . GetFullPath ( Framework . OwningModule . ModuleDirectory + "/" + Framework . FrameworkZipPath ) ;
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
}
string GetRemoteFrameworkZipPath ( UEBuildFramework Framework )
{
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
{
return ConvertPath ( GetLocalFrameworkZipPath ( Framework ) ) ;
}
return GetLocalFrameworkZipPath ( Framework ) ;
}
2014-05-12 18:51:03 -04:00
string GetRemoteIntermediateFrameworkZipPath ( UEBuildFramework Framework )
{
if ( Framework . OwningModule = = null )
{
throw new BuildException ( "GetRemoteIntermediateFrameworkZipPath: No owning module for framework {0}" , Framework . FrameworkName ) ;
}
string IntermediatePath = Framework . OwningModule . Target . ProjectDirectory + "/Intermediate/UnzippedFrameworks/" + Framework . OwningModule . Name ;
IntermediatePath = Path . GetFullPath ( ( IntermediatePath + Framework . FrameworkZipPath ) . Replace ( ".zip" , "" ) ) ;
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-05-12 18:51:03 -04:00
{
return ConvertPath ( IntermediatePath ) ;
}
return IntermediatePath ;
}
void CleanIntermediateDirectory ( string Path )
{
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-05-12 18:51:03 -04:00
{
// Delete the intermediate directory on the mac
2014-08-07 14:08:36 -04:00
RPCUtilHelper . Command ( "/" , String . Format ( "rm -rf \"{0}\"" , Path ) , "" , null ) ;
2014-05-12 18:51:03 -04:00
// Create a fresh intermediate after we delete it
2014-08-07 14:08:36 -04:00
RPCUtilHelper . Command ( "/" , String . Format ( "mkdir -p \"{0}\"" , Path ) , "" , null ) ;
2014-05-12 18:51:03 -04:00
}
else
{
// Delete the local dest directory if it exists
if ( Directory . Exists ( Path ) )
{
Directory . Delete ( Path , true ) ;
}
// Create the intermediate local directory
string ResultsText ;
2014-08-07 14:08:36 -04:00
RunExecutableAndWait ( "mkdir" , String . Format ( "-p \"{0}\"" , Path ) , out ResultsText ) ;
2014-05-12 18:51:03 -04:00
}
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
string GetLinkArguments_Global ( LinkEnvironment LinkEnvironment )
2014-03-14 14:13:41 -04:00
{
2015-03-24 14:35:38 -04:00
IOSPlatform BuildPlat = UEBuildPlatform . GetBuildPlatform ( UnrealTargetPlatform . IOS ) as IOSPlatform ;
BuildPlat . SetUpProjectEnvironment ( UnrealTargetPlatform . IOS ) ;
string Result = "" ;
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Architecture = = "-simulator" )
2014-03-14 14:13:41 -04:00
{
Result + = " -arch i386" ;
2014-04-23 18:00:27 -04:00
Result + = " -isysroot " + XcodeDeveloperDir + "Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" + IOSSDKVersion + ".sdk" ;
2014-03-14 14:13:41 -04:00
}
else
{
2014-06-09 11:12:01 -04:00
Result + = Result + = GetArchitectureArgument ( LinkEnvironment . Config . Target . Configuration , LinkEnvironment . Config . Target . Architecture ) ;
2014-04-23 18:00:27 -04:00
Result + = " -isysroot " + XcodeDeveloperDir + "Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" + IOSSDKVersion + ".sdk" ;
2014-03-14 14:13:41 -04:00
}
Result + = " -dead_strip" ;
2015-03-24 14:35:38 -04:00
Result + = " -miphoneos-version-min=" + BuildPlat . GetRunTimeVersion ( ) ;
2014-03-14 14:13:41 -04:00
Result + = " -Wl,-no_pie" ;
// Result += " -v";
// link in the frameworks
foreach ( string Framework in LinkEnvironment . Config . Frameworks )
{
Result + = " -framework " + Framework ;
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
foreach ( UEBuildFramework Framework in LinkEnvironment . Config . AdditionalFrameworks )
2014-03-14 14:13:41 -04:00
{
2014-05-12 18:51:03 -04:00
if ( Framework . OwningModule ! = null & & Framework . FrameworkZipPath ! = null & & Framework . FrameworkZipPath ! = "" )
2014-04-30 14:09:06 -04:00
{
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
// If this framework has a zip specified, we'll need to setup the path as well
2014-08-07 14:08:36 -04:00
Result + = " -F \"" + GetRemoteIntermediateFrameworkZipPath ( Framework ) + "\"" ;
2014-04-30 14:09:06 -04:00
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
Result + = " -framework " + Framework . FrameworkName ;
2014-03-14 14:13:41 -04:00
}
foreach ( string Framework in LinkEnvironment . Config . WeakFrameworks )
{
Result + = " -weak_framework " + Framework ;
}
return Result ;
}
static string GetArchiveArguments_Global ( LinkEnvironment LinkEnvironment )
{
string Result = "" ;
Result + = " -static" ;
return Result ;
}
2014-07-31 09:34:11 -04:00
public override CPPOutput CompileCPPFiles ( UEBuildTarget Target , CPPEnvironment CompileEnvironment , List < FileItem > SourceFiles , string ModuleName )
2014-03-14 14:13:41 -04:00
{
string Arguments = GetCompileArguments_Global ( CompileEnvironment ) ;
string PCHArguments = "" ;
if ( CompileEnvironment . Config . PrecompiledHeaderAction = = PrecompiledHeaderAction . Include )
{
// Add the precompiled header file's path to the include path so GCC can find it.
// This needs to be before the other include paths to ensure GCC uses it instead of the source header file.
2014-06-05 12:11:58 -04:00
var PrecompiledFileExtension = UEBuildPlatform . BuildPlatformDictionary [ UnrealTargetPlatform . IOS ] . GetBinaryExtension ( UEBuildBinaryType . PrecompiledHeader ) ;
PCHArguments + = string . Format ( " -include \"{0}\"" , ConvertPath ( CompileEnvironment . PrecompiledHeaderFile . AbsolutePath . Replace ( PrecompiledFileExtension , "" ) ) ) ;
2014-03-14 14:13:41 -04:00
}
// Add include paths to the argument list.
2014-10-27 13:09:47 -04:00
HashSet < string > AllIncludes = new HashSet < string > ( CompileEnvironment . Config . CPPIncludeInfo . IncludePaths ) ;
2014-09-11 03:21:51 -04:00
AllIncludes . UnionWith ( CompileEnvironment . Config . CPPIncludeInfo . SystemIncludePaths ) ;
2014-03-14 14:13:41 -04:00
foreach ( string IncludePath in AllIncludes )
{
Arguments + = string . Format ( " -I\"{0}\"" , ConvertPath ( Path . GetFullPath ( IncludePath ) ) ) ;
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-03-14 14:13:41 -04:00
{
// sync any third party headers we may need
if ( IncludePath . Contains ( "ThirdParty" ) )
{
string [ ] FileList = Directory . GetFiles ( IncludePath , "*.h" , SearchOption . AllDirectories ) ;
foreach ( string File in FileList )
{
FileItem ExternalDependency = FileItem . GetItemByPath ( File ) ;
LocalToRemoteFileItem ( ExternalDependency , true ) ;
}
FileList = Directory . GetFiles ( IncludePath , "*.cpp" , SearchOption . AllDirectories ) ;
foreach ( string File in FileList )
{
FileItem ExternalDependency = FileItem . GetItemByPath ( File ) ;
LocalToRemoteFileItem ( ExternalDependency , true ) ;
}
}
}
}
foreach ( string Definition in CompileEnvironment . Config . Definitions )
{
Arguments + = string . Format ( " -D\"{0}\"" , Definition ) ;
}
2014-07-31 09:34:11 -04:00
var BuildPlatform = UEBuildPlatform . GetBuildPlatformForCPPTargetPlatform ( CompileEnvironment . Config . Target . Platform ) ;
2014-03-14 14:13:41 -04:00
CPPOutput Result = new CPPOutput ( ) ;
// Create a compile action for each source file.
foreach ( FileItem SourceFile in SourceFiles )
{
Action CompileAction = new Action ( ActionType . Compile ) ;
string FileArguments = "" ;
string Extension = Path . GetExtension ( SourceFile . AbsolutePath ) . ToUpperInvariant ( ) ;
if ( CompileEnvironment . Config . PrecompiledHeaderAction = = PrecompiledHeaderAction . Create )
{
// Compile the file as a C++ PCH.
FileArguments + = GetCompileArguments_PCH ( ) ;
}
else if ( Extension = = ".C" )
{
// Compile the file as C code.
FileArguments + = GetCompileArguments_C ( ) ;
}
else if ( Extension = = ".CC" )
{
// Compile the file as C++ code.
FileArguments + = GetCompileArguments_CPP ( ) ;
}
else if ( Extension = = ".MM" )
{
// Compile the file as Objective-C++ code.
FileArguments + = GetCompileArguments_MM ( ) ;
}
else if ( Extension = = ".M" )
{
// Compile the file as Objective-C++ code.
FileArguments + = GetCompileArguments_M ( ) ;
}
else
{
// Compile the file as C++ code.
FileArguments + = GetCompileArguments_CPP ( ) ;
// only use PCH for .cpp files
FileArguments + = PCHArguments ;
}
// Add the C++ source file and its included files to the prerequisite item list.
Experimental UnrealBuildTool makefile support
UnrealBuildTool 'Makefiles' allow for very fast iterative builds.
- New BuildConfiguration.xml setting added: "bUseExperimentalFastBuildIteration" (disabled by default)
- Turning this on causes Unreal Build Tool to emit 'UBT Makefiles' for targets when they're built the first time.
- Subsequent builds will load these Makefiles and begin outdatedness checking and build invocation very quickly.
- The caveat is that if source files are added or removed to the project, UBT will need to gather information about those in order for your build to complete successfully.
- Currently, you must run the project file generator after adding/removing source files to tell UBT to re-gather this information.
- Events that can invalidate the 'UBT Makefile':
- Adding/removing .cpp files
- Adding/removing .h files with UObjects
- Adding new UObject types to a file that didn't previously have any
- Changing global build settings (most settings in this file qualify.)
- Changed code that affects how Unreal Header Tool works
- You can force regeneration of the 'UBT Makefile' by passing the '-Gather' argument, or simply regenerating project files
- New command-line parameters added:
- "-Gather": Tells UBT to always perform the gather step (slower but will catch project structural changes)
- "-NoGather": Disables the gather step, unless UBT detects that it must be done. This is the default when bUseExperimentalFastBuildIteration is enabled
- "-GatherOnly": Runs the gather step and saves a UBTMakefile, but doesn't build anything
- "-Assemble": Tells UBT to also assemble build products. This always defaults to enabled
- "-NoAssemble": Tells UBT to skip the assemble step, whether we gathered build products or not
- "-AssembleOnly": Tells UBT to only assemble build products and not to gather, unless UBT determines it must
Other changes:
- UBT now keeps track of which targets it was building in an intermediate file, to help it invalidate cached includes in subsequent runs when the targets are different
- C++ includes are now stored in a class separate from the C++ compile enviroment (for easier serialization)
- The method that UBT uses to find the CoreUObject module timestamp was rewritten
- Various '@todo ubtmake' comments added to tag possible remaining Makefile tasks
- The 'FileItem' class had some member variable comments and code cleaned up, while making it serializable
- Cleaned up the comments and member variables in the "Action" class, while making it serializable
- Some UBT classes are now "serializable". This is because we need to store the data in UBTMakefiles.
- Removed support for Actions to tinker with Stdout and Stderror (was not used for anything)
- Moved PrecompileHeaderEnvironment class to the UEBuildModule.cs source file
- Plugin intermediate include directories are now selected on demand rather than cached early
- Toolchain code for gathering prerequisite headers is now shared in a single function (AddPrerequisiteSourceFile)
- Removed Action.StatusDetailedDescription, was not used for anything
- Removed UEBuildConfiguration.bExcludePlugins, was not used for anything
- Removed ECompilationResult.FailedDueToHeaderChange, was not used for anything
[CL 2254472 by Mike Fricker in Main branch]
2014-08-13 08:17:43 -04:00
AddPrerequisiteSourceFile ( Target , BuildPlatform , CompileEnvironment , SourceFile , CompileAction . PrerequisiteItems ) ;
2014-03-14 14:13:41 -04:00
if ( CompileEnvironment . Config . PrecompiledHeaderAction = = PrecompiledHeaderAction . Create )
{
2014-06-05 12:11:58 -04:00
var PrecompiledFileExtension = UEBuildPlatform . BuildPlatformDictionary [ UnrealTargetPlatform . IOS ] . GetBinaryExtension ( UEBuildBinaryType . PrecompiledHeader ) ;
2014-03-14 14:13:41 -04:00
// Add the precompiled header file to the produced item list.
FileItem PrecompiledHeaderFile = FileItem . GetItemByPath (
Path . Combine (
CompileEnvironment . Config . OutputDirectory ,
2014-06-05 12:11:58 -04:00
Path . GetFileName ( SourceFile . AbsolutePath ) + PrecompiledFileExtension
2014-03-14 14:13:41 -04:00
)
) ;
FileItem RemotePrecompiledHeaderFile = LocalToRemoteFileItem ( PrecompiledHeaderFile , false ) ;
CompileAction . ProducedItems . Add ( RemotePrecompiledHeaderFile ) ;
Result . PrecompiledHeaderFile = RemotePrecompiledHeaderFile ;
// Add the parameters needed to compile the precompiled header file to the command-line.
FileArguments + = string . Format ( " -o \"{0}\"" , RemotePrecompiledHeaderFile . AbsolutePath , false ) ;
}
else
{
if ( CompileEnvironment . Config . PrecompiledHeaderAction = = PrecompiledHeaderAction . Include )
{
CompileAction . bIsUsingPCH = true ;
CompileAction . PrerequisiteItems . Add ( CompileEnvironment . PrecompiledHeaderFile ) ;
}
2014-06-05 12:11:58 -04:00
var ObjectFileExtension = UEBuildPlatform . BuildPlatformDictionary [ UnrealTargetPlatform . IOS ] . GetBinaryExtension ( UEBuildBinaryType . Object ) ;
2014-03-14 14:13:41 -04:00
// Add the object file to the produced item list.
FileItem ObjectFile = FileItem . GetItemByPath (
Path . Combine (
CompileEnvironment . Config . OutputDirectory ,
2014-06-05 12:11:58 -04:00
Path . GetFileName ( SourceFile . AbsolutePath ) + ObjectFileExtension
2014-03-14 14:13:41 -04:00
)
) ;
FileItem RemoteObjectFile = LocalToRemoteFileItem ( ObjectFile , false ) ;
CompileAction . ProducedItems . Add ( RemoteObjectFile ) ;
Result . ObjectFiles . Add ( RemoteObjectFile ) ;
FileArguments + = string . Format ( " -o \"{0}\"" , RemoteObjectFile . AbsolutePath , false ) ;
}
// Add the source file path to the command-line.
FileArguments + = string . Format ( " \"{0}\"" , ConvertPath ( SourceFile . AbsolutePath ) , false ) ;
2014-04-23 18:00:27 -04:00
string CompilerPath = XcodeDeveloperDir + "Toolchains/XcodeDefault.xctoolchain/usr/bin/" + IOSCompiler ;
2014-08-06 07:05:15 -04:00
if ( ! Utils . IsRunningOnMono & & BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-03-14 14:13:41 -04:00
{
CompileAction . ActionHandler = new Action . BlockingActionHandler ( RPCUtilHelper . RPCActionHandler ) ;
}
// RPC utility parameters are in terms of the Mac side
CompileAction . WorkingDirectory = GetMacDevSrcRoot ( ) ;
CompileAction . CommandPath = CompilerPath ;
CompileAction . CommandArguments = Arguments + FileArguments + CompileEnvironment . Config . AdditionalArguments ;
CompileAction . StatusDescription = string . Format ( "{0}" , Path . GetFileName ( SourceFile . AbsolutePath ) ) ;
CompileAction . bIsGCCCompiler = true ;
// We're already distributing the command by execution on Mac.
CompileAction . bCanExecuteRemotely = false ;
2014-07-23 18:42:01 -04:00
CompileAction . bShouldOutputStatusDescription = true ;
2014-03-14 14:13:41 -04:00
CompileAction . OutputEventHandler = new DataReceivedEventHandler ( RemoteOutputReceivedEventHandler ) ;
}
return Result ;
}
public override FileItem LinkFiles ( LinkEnvironment LinkEnvironment , bool bBuildImportLibraryOnly )
{
2014-04-23 18:00:27 -04:00
string LinkerPath = XcodeDeveloperDir + "Toolchains/XcodeDefault.xctoolchain/usr/bin/" +
2014-03-14 14:13:41 -04:00
( LinkEnvironment . Config . bIsBuildingLibrary ? IOSArchiver : IOSLinker ) ;
// Create an action that invokes the linker.
Action LinkAction = new Action ( ActionType . Link ) ;
2014-08-06 07:05:15 -04:00
if ( ! Utils . IsRunningOnMono & & BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-03-14 14:13:41 -04:00
{
LinkAction . ActionHandler = new Action . BlockingActionHandler ( RPCUtilHelper . RPCActionHandler ) ;
}
// RPC utility parameters are in terms of the Mac side
LinkAction . WorkingDirectory = GetMacDevSrcRoot ( ) ;
LinkAction . CommandPath = LinkerPath ;
// build this up over the rest of the function
LinkAction . CommandArguments = LinkEnvironment . Config . bIsBuildingLibrary ? GetArchiveArguments_Global ( LinkEnvironment ) : GetLinkArguments_Global ( LinkEnvironment ) ;
if ( ! LinkEnvironment . Config . bIsBuildingLibrary )
{
// Add the library paths to the argument list.
foreach ( string LibraryPath in LinkEnvironment . Config . LibraryPaths )
{
LinkAction . CommandArguments + = string . Format ( " -L\"{0}\"" , LibraryPath ) ;
}
// Add the additional libraries to the argument list.
foreach ( string AdditionalLibrary in LinkEnvironment . Config . AdditionalLibraries )
{
// for absolute library paths, convert to remote filename
if ( ! String . IsNullOrEmpty ( Path . GetDirectoryName ( AdditionalLibrary ) ) )
{
// add it to the prerequisites to make sure it's built first (this should be the case of non-system libraries)
FileItem LibFile = FileItem . GetItemByPath ( Path . GetFullPath ( AdditionalLibrary ) ) ;
FileItem RemoteLibFile = LocalToRemoteFileItem ( LibFile , false ) ;
LinkAction . PrerequisiteItems . Add ( RemoteLibFile ) ;
// and add to the commandline
2014-04-28 19:56:45 -04:00
LinkAction . CommandArguments + = string . Format ( " \"{0}\"" , ConvertPath ( Path . GetFullPath ( AdditionalLibrary ) ) ) ;
2014-03-14 14:13:41 -04:00
}
else
{
LinkAction . CommandArguments + = string . Format ( " -l\"{0}\"" , AdditionalLibrary ) ;
}
}
}
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-03-14 14:13:41 -04:00
{
// Add any additional files that we'll need in order to link the app
foreach ( string AdditionalShadowFile in LinkEnvironment . Config . AdditionalShadowFiles )
{
FileItem ShadowFile = FileItem . GetExistingItemByPath ( AdditionalShadowFile ) ;
if ( ShadowFile ! = null )
{
QueueFileForBatchUpload ( ShadowFile ) ;
LinkAction . PrerequisiteItems . Add ( ShadowFile ) ;
}
else
{
throw new BuildException ( "Couldn't find required additional file to shadow: {0}" , AdditionalShadowFile ) ;
}
}
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
// Handle additional framework assets that might need to be shadowed
foreach ( UEBuildFramework Framework in LinkEnvironment . Config . AdditionalFrameworks )
{
if ( Framework . OwningModule = = null | | Framework . FrameworkZipPath = = null | | Framework . FrameworkZipPath = = "" )
{
continue ; // Only care about frameworks that have a zip specified
}
// If we've already remembered this framework, skip
if ( RememberedAdditionalFrameworks . Contains ( Framework ) )
{
continue ;
}
// Remember any files we need to unzip
RememberedAdditionalFrameworks . Add ( Framework ) ;
// Copy them to remote mac if needed
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
{
FileItem ShadowFile = FileItem . GetExistingItemByPath ( GetLocalFrameworkZipPath ( Framework ) ) ;
if ( ShadowFile ! = null )
{
QueueFileForBatchUpload ( ShadowFile ) ;
LinkAction . PrerequisiteItems . Add ( ShadowFile ) ;
}
else
{
throw new BuildException ( "Couldn't find required additional file to shadow: {0}" , Framework . FrameworkZipPath ) ;
}
}
}
2014-03-14 14:13:41 -04:00
// Add the output file as a production of the link action.
FileItem OutputFile = FileItem . GetItemByPath ( Path . GetFullPath ( LinkEnvironment . Config . OutputFilePath ) ) ;
FileItem RemoteOutputFile = LocalToRemoteFileItem ( OutputFile , false ) ;
LinkAction . ProducedItems . Add ( RemoteOutputFile ) ;
// Add the input files to a response file, and pass the response file on the command-line.
List < string > InputFileNames = new List < string > ( ) ;
foreach ( FileItem InputFile in LinkEnvironment . InputFiles )
{
InputFileNames . Add ( string . Format ( "\"{0}\"" , InputFile . AbsolutePath ) ) ;
LinkAction . PrerequisiteItems . Add ( InputFile ) ;
}
// Write the list of input files to a response file, with a tempfilename, on remote machine
if ( LinkEnvironment . Config . bIsBuildingLibrary )
{
foreach ( string Filename in InputFileNames )
{
LinkAction . CommandArguments + = " " + Filename ;
}
// @todo rocket lib: the -filelist command should take a response file (see else condition), except that it just says it can't
// find the file that's in there. Rocket.lib may overflow the commandline by putting all files on the commandline, so this
// may be needed:
// LinkAction.CommandArguments += string.Format(" -filelist \"{0}\"", ConvertPath(ResponsePath));
}
else
{
2015-02-27 16:10:22 -05:00
bool bIsUE4Game = LinkEnvironment . Config . OutputFilePath . Contains ( "UE4Game" ) ;
string ResponsePath = Path . GetFullPath ( Path . Combine ( ( ! bIsUE4Game & & ! string . IsNullOrEmpty ( UnrealBuildTool . GetUProjectPath ( ) ) ) ? UnrealBuildTool . GetUProjectPath ( ) : BuildConfiguration . RelativeEnginePath , BuildConfiguration . PlatformIntermediateFolder , "LinkFileList_" + Path . GetFileNameWithoutExtension ( LinkEnvironment . Config . OutputFilePath ) + ".tmp" ) ) ;
2014-08-06 07:05:15 -04:00
if ( ! Utils . IsRunningOnMono & & BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-03-14 14:13:41 -04:00
{
ResponseFile . Create ( ResponsePath , InputFileNames ) ;
RPCUtilHelper . CopyFile ( ResponsePath , ConvertPath ( ResponsePath ) , true ) ;
}
else
{
ResponseFile . Create ( ConvertPath ( ResponsePath ) , InputFileNames ) ;
}
LinkAction . CommandArguments + = string . Format ( " @\"{0}\"" , ConvertPath ( ResponsePath ) ) ;
}
// Add the output file to the command-line.
LinkAction . CommandArguments + = string . Format ( " -o \"{0}\"" , RemoteOutputFile . AbsolutePath ) ;
// Add the additional arguments specified by the environment.
LinkAction . CommandArguments + = LinkEnvironment . Config . AdditionalArguments ;
// Only execute linking on the local PC.
LinkAction . bCanExecuteRemotely = false ;
LinkAction . StatusDescription = string . Format ( "{0}" , OutputFile . AbsolutePath ) ;
LinkAction . OutputEventHandler = new DataReceivedEventHandler ( RemoteOutputReceivedEventHandler ) ;
// For iPhone, generate the dSYM file if the config file is set to do so
2014-10-31 04:46:23 -04:00
if ( BuildConfiguration . bGeneratedSYMFile = = true & & Path . GetExtension ( OutputFile . AbsolutePath ) ! = ".a" )
2014-03-14 14:13:41 -04:00
{
Log . TraceInformation ( "Generating the dSYM file - this will add some time to your build..." ) ;
RemoteOutputFile = GenerateDebugInfo ( RemoteOutputFile ) ;
}
return RemoteOutputFile ;
}
/ * *
* Generates debug info for a given executable
*
* @param Executable FileItem describing the executable to generate debug info for
* /
static public FileItem GenerateDebugInfo ( FileItem Executable )
{
// Make a file item for the source and destination files
2015-02-27 16:10:22 -05:00
string FullDestPathRoot = Executable . AbsolutePath + ".dSYM" ;
2014-03-14 14:13:41 -04:00
string FullDestPath = FullDestPathRoot ;
2014-10-31 04:46:23 -04:00
FileItem DestFile ;
if ( ! Utils . IsRunningOnMono & & BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
{
DestFile = FileItem . GetRemoteItemByPath ( FullDestPath , UnrealTargetPlatform . IOS ) ;
}
else
{
DestFile = FileItem . GetItemByPath ( FullDestPath ) ;
}
2014-03-14 14:13:41 -04:00
// Make the compile action
Action GenDebugAction = new Action ( ActionType . GenerateDebugInfo ) ;
if ( ! Utils . IsRunningOnMono )
{
GenDebugAction . ActionHandler = new Action . BlockingActionHandler ( RPCUtilHelper . RPCActionHandler ) ;
}
2014-07-02 15:54:21 -04:00
IOSToolChain Toolchain = UEToolChain . GetPlatformToolChain ( CPPTargetPlatform . IOS ) as IOSToolChain ;
GenDebugAction . WorkingDirectory = Toolchain . GetMacDevSrcRoot ( ) ;
2014-03-14 14:13:41 -04:00
GenDebugAction . CommandPath = "sh" ;
// note that the source and dest are switched from a copy command
2014-10-31 04:46:23 -04:00
if ( ! Utils . IsRunningOnMono & & BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
{
2015-02-27 16:10:22 -05:00
GenDebugAction . CommandArguments = string . Format ( "-c '/usr/bin/dsymutil \"{0}\" -f -o \"{1}\"; cd \"{1}/..\"; zip -r -y -1 {2}.dSYM.zip {2}.dSYM'" ,
2014-10-31 04:46:23 -04:00
Executable . AbsolutePath ,
FullDestPathRoot ,
Path . GetFileName ( Executable . AbsolutePath ) ) ;
}
else
{
2015-02-27 16:10:22 -05:00
GenDebugAction . CommandArguments = string . Format ( "-c '/usr/bin/dsymutil \"{0}\" -f -o \"{1}\"'" ,
2014-10-31 04:46:23 -04:00
Executable . AbsolutePath ,
FullDestPathRoot ) ;
}
2014-03-14 14:13:41 -04:00
GenDebugAction . PrerequisiteItems . Add ( Executable ) ;
GenDebugAction . ProducedItems . Add ( DestFile ) ;
GenDebugAction . StatusDescription = GenDebugAction . CommandArguments ; // string.Format("Generating debug info for {0}", Path.GetFileName(Executable.AbsolutePath));
GenDebugAction . bCanExecuteRemotely = false ;
return DestFile ;
}
2014-04-23 19:28:13 -04:00
private void PackageStub ( string BinaryPath , string GameName , string ExeName )
{
// create the ipa
string IPAName = BinaryPath + "/" + ExeName + ".stub" ;
// delete the old one
if ( File . Exists ( IPAName ) )
{
File . Delete ( IPAName ) ;
}
// make the subdirectory if needed
string DestSubdir = Path . GetDirectoryName ( IPAName ) ;
if ( ! Directory . Exists ( DestSubdir ) )
{
Directory . CreateDirectory ( DestSubdir ) ;
}
// set up the directories
string ZipWorkingDir = String . Format ( "Payload/{0}.app/" , GameName ) ;
string ZipSourceDir = string . Format ( "{0}/Payload/{1}.app" , BinaryPath , GameName ) ;
// create the file
using ( ZipFile Zip = new ZipFile ( ) )
{
// add the entire directory
Zip . AddDirectory ( ZipSourceDir , ZipWorkingDir ) ;
// Update permissions to be UNIX-style
// Modify the file attributes of any added file to unix format
foreach ( ZipEntry E in Zip . Entries )
{
const byte FileAttributePlatform_NTFS = 0x0A ;
const byte FileAttributePlatform_UNIX = 0x03 ;
const byte FileAttributePlatform_FAT = 0x00 ;
const int UNIX_FILETYPE_NORMAL_FILE = 0x8000 ;
//const int UNIX_FILETYPE_SOCKET = 0xC000;
//const int UNIX_FILETYPE_SYMLINK = 0xA000;
//const int UNIX_FILETYPE_BLOCKSPECIAL = 0x6000;
const int UNIX_FILETYPE_DIRECTORY = 0x4000 ;
//const int UNIX_FILETYPE_CHARSPECIAL = 0x2000;
//const int UNIX_FILETYPE_FIFO = 0x1000;
const int UNIX_EXEC = 1 ;
const int UNIX_WRITE = 2 ;
const int UNIX_READ = 4 ;
int MyPermissions = UNIX_READ | UNIX_WRITE ;
int OtherPermissions = UNIX_READ ;
int PlatformEncodedBy = ( E . VersionMadeBy > > 8 ) & 0xFF ;
int LowerBits = 0 ;
// Try to preserve read-only if it was set
bool bIsDirectory = E . IsDirectory ;
// Check to see if this
bool bIsExecutable = false ;
if ( Path . GetFileNameWithoutExtension ( E . FileName ) . Equals ( GameName , StringComparison . InvariantCultureIgnoreCase ) )
{
bIsExecutable = true ;
}
if ( bIsExecutable )
{
// The executable will be encrypted in the final distribution IPA and will compress very poorly, so keeping it
// uncompressed gives a better indicator of IPA size for our distro builds
E . CompressionLevel = CompressionLevel . None ;
}
if ( ( PlatformEncodedBy = = FileAttributePlatform_NTFS ) | | ( PlatformEncodedBy = = FileAttributePlatform_FAT ) )
{
FileAttributes OldAttributes = E . Attributes ;
//LowerBits = ((int)E.Attributes) & 0xFFFF;
if ( ( OldAttributes & FileAttributes . Directory ) ! = 0 )
{
bIsDirectory = true ;
}
// Permissions
if ( ( OldAttributes & FileAttributes . ReadOnly ) ! = 0 )
{
MyPermissions & = ~ UNIX_WRITE ;
OtherPermissions & = ~ UNIX_WRITE ;
}
}
if ( bIsDirectory | | bIsExecutable )
{
MyPermissions | = UNIX_EXEC ;
OtherPermissions | = UNIX_EXEC ;
}
// Re-jigger the external file attributes to UNIX style if they're not already that way
if ( PlatformEncodedBy ! = FileAttributePlatform_UNIX )
{
int NewAttributes = bIsDirectory ? UNIX_FILETYPE_DIRECTORY : UNIX_FILETYPE_NORMAL_FILE ;
NewAttributes | = ( MyPermissions < < 6 ) ;
NewAttributes | = ( OtherPermissions < < 3 ) ;
NewAttributes | = ( OtherPermissions < < 0 ) ;
// Now modify the properties
E . AdjustExternalFileAttributes ( FileAttributePlatform_UNIX , ( NewAttributes < < 16 ) | LowerBits ) ;
}
}
// Save it out
Zip . Save ( IPAName ) ;
}
}
2014-04-28 19:56:45 -04:00
public override void PreBuildSync ( )
{
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
2014-04-28 19:56:45 -04:00
{
BuiltBinaries = new List < string > ( ) ;
}
base . PreBuildSync ( ) ;
2014-04-30 14:09:06 -04:00
// Unzip any third party frameworks that are stored as zips
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
foreach ( UEBuildFramework Framework in RememberedAdditionalFrameworks )
2014-04-30 14:09:06 -04:00
{
2014-05-12 18:51:03 -04:00
string ZipSrcPath = GetRemoteFrameworkZipPath ( Framework ) ;
string ZipDstPath = GetRemoteIntermediateFrameworkZipPath ( Framework ) ;
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
2014-05-12 18:51:03 -04:00
Log . TraceInformation ( "Unzipping: {0} -> {1}" , ZipSrcPath , ZipDstPath ) ;
2014-04-30 14:09:06 -04:00
2014-05-12 18:51:03 -04:00
CleanIntermediateDirectory ( ZipDstPath ) ;
// Assume that there is another directory inside the zip with the same name as the zip
ZipDstPath = ZipDstPath . Substring ( 0 , ZipDstPath . LastIndexOf ( '/' ) ) ;
2014-04-30 14:09:06 -04:00
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform = = UnrealTargetPlatform . Mac )
2014-04-30 14:09:06 -04:00
{
// If we're on the mac, just unzip using the shell
string ResultsText ;
2014-08-07 14:08:36 -04:00
RunExecutableAndWait ( "unzip" , String . Format ( "-o \"{0}\" -d \"{1}\"" , ZipSrcPath , ZipDstPath ) , out ResultsText ) ;
2014-04-30 14:09:06 -04:00
continue ;
}
2014-10-31 04:46:23 -04:00
else
2014-04-30 14:09:06 -04:00
{
2014-10-31 04:46:23 -04:00
// Use RPC utility if the zip is on remote mac
Hashtable Result = RPCUtilHelper . Command ( "/" , String . Format ( "unzip -o \"{0}\" -d \"{1}\"" , ZipSrcPath , ZipDstPath ) , "" , null ) ;
foreach ( DictionaryEntry Entry in Result )
{
Log . TraceInformation ( "{0}" , Entry . Value ) ;
}
2014-04-30 14:09:06 -04:00
}
}
2014-04-28 19:56:45 -04:00
}
2014-03-14 14:13:41 -04:00
public override void PostBuildSync ( UEBuildTarget Target )
{
base . PostBuildSync ( Target ) ;
2015-03-12 15:35:46 -04:00
string AppName = Target . TargetType = = TargetRules . TargetType . Game ? Target . TargetName : Target . AppName ;
2014-03-14 14:13:41 -04:00
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform = = UnrealTargetPlatform . Mac )
2014-03-14 14:13:41 -04:00
{
string RemoteShadowDirectoryMac = Path . GetDirectoryName ( Target . OutputPath ) ;
2014-12-17 10:25:23 -05:00
string FinalRemoteExecutablePath = String . Format ( "{0}/Payload/{1}.app/{1}" , RemoteShadowDirectoryMac , AppName ) ;
2014-04-02 18:09:23 -04:00
// strip the debug info from the executable if needed
2015-03-20 15:10:21 -04:00
if ( BuildConfiguration . bStripSymbolsOnIOS | | ( Target . Configuration = = UnrealTargetConfiguration . Shipping ) )
2014-04-02 18:09:23 -04:00
{
Process StripProcess = new Process ( ) ;
StripProcess . StartInfo . WorkingDirectory = RemoteShadowDirectoryMac ;
StripProcess . StartInfo . FileName = "/usr/bin/xcrun" ;
StripProcess . StartInfo . Arguments = "strip \"" + Target . OutputPath + "\"" ;
StripProcess . OutputDataReceived + = new DataReceivedEventHandler ( OutputReceivedDataEventHandler ) ;
StripProcess . ErrorDataReceived + = new DataReceivedEventHandler ( OutputReceivedDataEventHandler ) ;
OutputReceivedDataEventHandlerEncounteredError = false ;
OutputReceivedDataEventHandlerEncounteredErrorMessage = "" ;
Utils . RunLocalProcess ( StripProcess ) ;
if ( OutputReceivedDataEventHandlerEncounteredError )
{
throw new Exception ( OutputReceivedDataEventHandlerEncounteredErrorMessage ) ;
}
}
// copy the executable
2014-03-14 14:13:41 -04:00
if ( ! File . Exists ( FinalRemoteExecutablePath ) )
{
2014-12-17 10:25:23 -05:00
Directory . CreateDirectory ( String . Format ( "{0}/Payload/{1}.app" , RemoteShadowDirectoryMac , AppName ) ) ;
2014-03-14 14:13:41 -04:00
}
File . Copy ( Target . OutputPath , FinalRemoteExecutablePath , true ) ;
2014-04-23 19:28:13 -04:00
if ( BuildConfiguration . bCreateStubIPA )
{
2014-12-17 10:25:23 -05:00
string Project = Target . ProjectDirectory + "/" + AppName + ".uproject" ;
2014-04-23 19:28:13 -04:00
// generate the dummy project so signing works
2014-12-17 10:25:23 -05:00
if ( AppName = = "UE4Game" | | AppName = = "UE4Client" | | Utils . IsFileUnderDirectory ( Target . ProjectDirectory + "/" + AppName + ".uproject" , Path . GetFullPath ( "../.." ) ) )
2014-04-23 19:28:13 -04:00
{
2014-04-25 13:10:14 -04:00
UnrealBuildTool . GenerateProjectFiles ( new XcodeProjectFileGenerator ( ) , new string [ ] { "-platforms=IOS" , "-NoIntellIsense" , "-iosdeployonly" , "-ignorejunk" } ) ;
2014-04-23 19:28:13 -04:00
Project = Path . GetFullPath ( "../.." ) + "/UE4_IOS.xcodeproj" ;
}
else
{
2014-12-17 10:25:23 -05:00
Project = Target . ProjectDirectory + "/" + AppName + ".xcodeproj" ;
2014-04-23 19:28:13 -04:00
}
if ( Directory . Exists ( Project ) )
{
2014-04-27 21:21:43 -04:00
// ensure the plist, entitlements, and provision files are properly copied
2014-05-21 06:09:37 -04:00
var DeployHandler = UEBuildDeploy . GetBuildDeploy ( Target . Platform ) ;
2014-04-27 21:21:43 -04:00
if ( DeployHandler ! = null )
{
DeployHandler . PrepTargetForDeployment ( Target ) ;
}
2014-04-23 19:28:13 -04:00
// code sign the project
string CmdLine = XcodeDeveloperDir + "usr/bin/xcodebuild" +
" -project \"" + Project + "\"" +
" -configuration " + Target . Configuration +
2014-12-17 10:25:23 -05:00
" -scheme '" + AppName + " - iOS'" +
2014-04-23 19:28:13 -04:00
" -sdk iphoneos" +
" CODE_SIGN_IDENTITY=\"iPhone Developer\"" ;
2014-05-02 00:36:54 -04:00
Console . WriteLine ( "Code signing with command line: " + CmdLine ) ;
2014-04-23 19:28:13 -04:00
Process SignProcess = new Process ( ) ;
SignProcess . StartInfo . WorkingDirectory = RemoteShadowDirectoryMac ;
SignProcess . StartInfo . FileName = "/usr/bin/xcrun" ;
SignProcess . StartInfo . Arguments = CmdLine ;
SignProcess . OutputDataReceived + = new DataReceivedEventHandler ( OutputReceivedDataEventHandler ) ;
SignProcess . ErrorDataReceived + = new DataReceivedEventHandler ( OutputReceivedDataEventHandler ) ;
OutputReceivedDataEventHandlerEncounteredError = false ;
OutputReceivedDataEventHandlerEncounteredErrorMessage = "" ;
Utils . RunLocalProcess ( SignProcess ) ;
// delete the temp project
if ( Project . Contains ( "_IOS.xcodeproj" ) )
{
2014-05-02 09:43:59 -04:00
Directory . Delete ( Project , true ) ;
2014-04-23 19:28:13 -04:00
}
if ( OutputReceivedDataEventHandlerEncounteredError )
{
throw new Exception ( OutputReceivedDataEventHandlerEncounteredErrorMessage ) ;
}
// Package the stub
2014-12-17 10:25:23 -05:00
PackageStub ( RemoteShadowDirectoryMac , AppName , Path . GetFileNameWithoutExtension ( Target . OutputPath ) ) ;
2014-04-23 19:28:13 -04:00
}
}
2014-05-09 17:38:40 -04:00
{
// Copy bundled assets from additional frameworks to the intermediate assets directory (so they can get picked up during staging)
String LocalFrameworkAssets = Path . GetFullPath ( Target . ProjectDirectory + "/Intermediate/IOS/FrameworkAssets" ) ;
2014-05-12 18:51:03 -04:00
// Clean the local dest directory if it exists
CleanIntermediateDirectory ( LocalFrameworkAssets ) ;
2014-05-09 17:38:40 -04:00
foreach ( UEBuildFramework Framework in RememberedAdditionalFrameworks )
{
if ( Framework . OwningModule = = null | | Framework . CopyBundledAssets = = null | | Framework . CopyBundledAssets = = "" )
{
continue ; // Only care if we need to copy bundle assets
}
2014-05-12 18:51:03 -04:00
if ( Framework . OwningModule . Target ! = Target )
{
continue ; // This framework item doesn't belong to this target, skip it
}
2014-05-09 17:38:40 -04:00
string LocalZipPath = GetLocalFrameworkZipPath ( Framework ) ;
LocalZipPath = LocalZipPath . Replace ( ".zip" , "" ) ;
// For now, this is hard coded, but we need to loop over all modules, and copy bundled assets that need it
string LocalSource = LocalZipPath + "/" + Framework . CopyBundledAssets ;
string BundleName = Framework . CopyBundledAssets . Substring ( Framework . CopyBundledAssets . LastIndexOf ( '/' ) + 1 ) ;
string LocalDest = LocalFrameworkAssets + "/" + BundleName ;
Log . TraceInformation ( "Copying bundled asset... LocalSource: {0}, LocalDest: {1}" , LocalSource , LocalDest ) ;
2014-05-12 18:51:03 -04:00
string ResultsText ;
2014-12-10 11:57:17 -05:00
RunExecutableAndWait ( "cp" , String . Format ( "-R -L {0} {1}" , LocalSource . Replace ( " " , "\\ " ) , LocalDest . Replace ( " " , "\\ " ) ) , out ResultsText ) ;
2014-05-09 17:38:40 -04:00
}
}
2014-03-14 14:13:41 -04:00
}
else
{
2014-04-28 19:56:45 -04:00
// store off the binaries
foreach ( UEBuildBinary Binary in Target . AppBinaries )
{
BuiltBinaries . Add ( Path . GetFullPath ( Binary . ToString ( ) ) ) ;
}
2014-03-14 14:13:41 -04:00
// check to see if the DangerouslyFast mode is valid (in other words, a build has gone through since a Rebuild/Clean operation)
string DangerouslyFastValidFile = Path . Combine ( Target . GlobalLinkEnvironment . Config . IntermediateDirectory , "DangerouslyFastIsNotDangerous" ) ;
bool bUseDangerouslyFastModeWasRequested = bUseDangerouslyFastMode ;
if ( bUseDangerouslyFastMode )
{
if ( ! File . Exists ( DangerouslyFastValidFile ) )
{
Log . TraceInformation ( "Dangeroulsy Fast mode was requested, but a slow mode hasn't completed. Performing slow now..." ) ;
bUseDangerouslyFastMode = false ;
}
}
2014-12-10 16:13:56 -05:00
foreach ( string FilePath in BuiltBinaries )
{
string RemoteExecutablePath = ConvertPath ( FilePath ) ;
// when going super fast, just copy the executable to the final resting spot
if ( bUseDangerouslyFastMode )
2014-03-14 14:13:41 -04:00
{
2014-12-10 16:13:56 -05:00
Log . TraceInformation ( "==============================================================================" ) ;
Log . TraceInformation ( "USING DANGEROUSLY FAST MODE! IF YOU HAVE ANY PROBLEMS, TRY A REBUILD/CLEAN!!!!" ) ;
Log . TraceInformation ( "==============================================================================" ) ;
// copy the executable
string RemoteShadowDirectoryMac = ConvertPath ( Path . GetDirectoryName ( Target . OutputPath ) ) ;
2015-03-12 15:35:46 -04:00
string FinalRemoteExecutablePath = String . Format ( "{0}/Payload/{1}.app/{1}" , RemoteShadowDirectoryMac , Target . TargetName ) ;
2014-12-10 16:13:56 -05:00
RPCUtilHelper . Command ( "/" , String . Format ( "cp -f {0} {1}" , RemoteExecutablePath , FinalRemoteExecutablePath ) , "" , null ) ;
}
else if ( ! Utils . IsRunningOnMono & & BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Mac )
{
RPCUtilHelper . CopyFile ( RemoteExecutablePath , FilePath , false ) ;
if ( BuildConfiguration . bGeneratedSYMFile = = true )
{
string DSYMExt = ".app.dSYM.zip" ;
RPCUtilHelper . CopyFile ( RemoteExecutablePath + DSYMExt , FilePath + DSYMExt , false ) ;
}
2014-03-14 14:13:41 -04:00
}
}
// Generate the stub
if ( BuildConfiguration . bCreateStubIPA | | bUseDangerouslyFastMode )
{
2015-01-22 00:20:01 -05:00
// ensure the plist, entitlements, and provision files are properly copied
var DeployHandler = UEBuildDeploy . GetBuildDeploy ( Target . Platform ) ;
if ( DeployHandler ! = null )
{
DeployHandler . PrepTargetForDeployment ( Target ) ;
}
2014-03-14 14:13:41 -04:00
if ( ! bUseDangerouslyFastMode )
{
// generate the dummy project so signing works
2015-02-27 16:10:22 -05:00
UnrealBuildTool . GenerateProjectFiles ( new XcodeProjectFileGenerator ( ) , new string [ ] { "-NoIntellisense" , "-iosdeployonly" , ( ! string . IsNullOrEmpty ( UnrealBuildTool . GetUProjectPath ( ) ) ? "-game" : "" ) } ) ;
2014-03-14 14:13:41 -04:00
}
2014-07-01 10:58:33 -04:00
// now that
2014-03-14 14:13:41 -04:00
Process StubGenerateProcess = new Process ( ) ;
2014-12-11 10:49:39 -05:00
StubGenerateProcess . StartInfo . WorkingDirectory = Path . GetFullPath ( "..\\Binaries\\DotNET\\IOS" ) ;
StubGenerateProcess . StartInfo . FileName = Path . Combine ( StubGenerateProcess . StartInfo . WorkingDirectory , "iPhonePackager.exe" ) ;
2014-07-01 10:58:33 -04:00
string Arguments = "" ;
2014-03-14 14:13:41 -04:00
string PathToApp = RulesCompiler . GetTargetFilename ( AppName ) ;
// right now, no programs have a Source subdirectory, so assume the PathToApp is directly in the root
if ( Path . GetDirectoryName ( PathToApp ) . Contains ( @"\Engine\Source\Programs" ) )
{
PathToApp = Path . GetDirectoryName ( PathToApp ) ;
}
else
{
2015-02-27 16:10:22 -05:00
Int32 SourceIndex = PathToApp . LastIndexOf ( @"\Intermediate\Source" ) ;
2014-03-14 14:13:41 -04:00
if ( SourceIndex ! = - 1 )
{
PathToApp = PathToApp . Substring ( 0 , SourceIndex ) ;
}
else
{
2015-02-27 16:10:22 -05:00
SourceIndex = PathToApp . LastIndexOf ( @"\Source" ) ;
if ( SourceIndex ! = - 1 )
{
PathToApp = PathToApp . Substring ( 0 , SourceIndex ) ;
}
else
{
throw new BuildException ( "The target was not in a /Source subdirectory" ) ;
}
2014-03-14 14:13:41 -04:00
}
}
if ( bUseDangerouslyFastMode )
{
// the quickness!
2014-07-01 10:58:33 -04:00
Arguments + = "DangerouslyFast " + PathToApp ;
2014-03-14 14:13:41 -04:00
}
else
{
2014-07-01 10:58:33 -04:00
Arguments + = "PackageIPA \"" + PathToApp + "\" -createstub" ;
2014-03-14 14:13:41 -04:00
// if we are making the dsym, then we can strip the debug info from the executable
if ( BuildConfiguration . bStripSymbolsOnIOS | | ( Target . Configuration = = UnrealTargetConfiguration . Shipping ) )
{
2014-07-01 10:58:33 -04:00
Arguments + = " -strip" ;
2014-03-14 14:13:41 -04:00
}
}
2014-07-01 10:58:33 -04:00
Arguments + = " -config " + Target . Configuration + " -mac " + RemoteServerName ;
2014-03-14 14:13:41 -04:00
2014-05-21 06:09:37 -04:00
var BuildPlatform = UEBuildPlatform . GetBuildPlatform ( Target . Platform ) ;
2014-03-14 14:13:41 -04:00
string Architecture = BuildPlatform . GetActiveArchitecture ( ) ;
if ( Architecture ! = "" )
{
// pass along the architecture if we need, skipping the initial -, so we have "-architecture simulator"
2014-07-01 10:58:33 -04:00
Arguments + = " -architecture " + Architecture . Substring ( 1 ) ;
2014-03-14 14:13:41 -04:00
}
2014-12-11 10:49:39 -05:00
if ( ! bUseRPCUtil )
{
Arguments + = " -usessh" ;
Arguments + = " -sshexe \"" + ResolvedSSHExe + "\"" ;
Arguments + = " -sshauth \"" + ResolvedSSHAuthentication + "\"" ;
Arguments + = " -sshuser \"" + ResolvedRSyncUsername + "\"" ;
Arguments + = " -rsyncexe \"" + ResolvedRSyncExe + "\"" ;
Arguments + = " -overridedevroot \"" + UserDevRootMac + "\"" ;
}
2014-03-14 14:13:41 -04:00
// programmers that use Xcode packaging mode should use the following commandline instead, as it will package for Xcode on each compile
2014-07-01 10:58:33 -04:00
// Arguments = "PackageApp " + GameName + " " + Configuration;
2014-12-11 10:49:39 -05:00
StubGenerateProcess . StartInfo . Arguments = Arguments ;
2014-03-14 14:13:41 -04:00
StubGenerateProcess . OutputDataReceived + = new DataReceivedEventHandler ( OutputReceivedDataEventHandler ) ;
StubGenerateProcess . ErrorDataReceived + = new DataReceivedEventHandler ( OutputReceivedDataEventHandler ) ;
OutputReceivedDataEventHandlerEncounteredError = false ;
OutputReceivedDataEventHandlerEncounteredErrorMessage = "" ;
Utils . RunLocalProcess ( StubGenerateProcess ) ;
if ( OutputReceivedDataEventHandlerEncounteredError )
{
throw new Exception ( OutputReceivedDataEventHandlerEncounteredErrorMessage ) ;
}
// now that a slow mode sync has finished, we can now do DangerouslyFast mode again (if requested)
if ( bUseDangerouslyFastModeWasRequested )
{
File . Create ( DangerouslyFastValidFile ) ;
}
else
{
// if we didn't want dangerously fast, then delete the file so that setting/unsetting the flag will do the right thing without a Rebuild
File . Delete ( DangerouslyFastValidFile ) ;
}
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
{
2014-05-09 17:38:40 -04:00
// Copy bundled assets from additional frameworks to the intermediate assets directory (so they can get picked up during staging)
String LocalFrameworkAssets = Path . GetFullPath ( Target . ProjectDirectory + "/Intermediate/IOS/FrameworkAssets" ) ;
String RemoteFrameworkAssets = ConvertPath ( LocalFrameworkAssets ) ;
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
2014-05-12 18:51:03 -04:00
CleanIntermediateDirectory ( RemoteFrameworkAssets ) ;
2014-05-09 17:38:40 -04:00
// Delete the local dest directory if it exists
if ( Directory . Exists ( LocalFrameworkAssets ) )
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
{
2014-05-09 17:38:40 -04:00
Directory . Delete ( LocalFrameworkAssets , true ) ;
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
}
2014-05-09 17:38:40 -04:00
foreach ( UEBuildFramework Framework in RememberedAdditionalFrameworks )
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
{
2014-05-09 17:38:40 -04:00
if ( Framework . OwningModule = = null | | Framework . CopyBundledAssets = = null | | Framework . CopyBundledAssets = = "" )
{
continue ; // Only care if we need to copy bundle assets
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
2014-05-12 18:51:03 -04:00
if ( Framework . OwningModule . Target ! = Target )
{
continue ; // This framework item doesn't belong to this target, skip it
}
2014-11-03 15:48:07 -05:00
string RemoteZipPath = GetRemoteIntermediateFrameworkZipPath ( Framework ) ;
2014-05-09 17:38:40 -04:00
RemoteZipPath = RemoteZipPath . Replace ( ".zip" , "" ) ;
// For now, this is hard coded, but we need to loop over all modules, and copy bundled assets that need it
string RemoteSource = RemoteZipPath + "/" + Framework . CopyBundledAssets ;
string BundleName = Framework . CopyBundledAssets . Substring ( Framework . CopyBundledAssets . LastIndexOf ( '/' ) + 1 ) ;
String RemoteDest = RemoteFrameworkAssets + "/" + BundleName ;
String LocalDest = LocalFrameworkAssets + "\\" + BundleName ;
Log . TraceInformation ( "Copying bundled asset... RemoteSource: {0}, RemoteDest: {1}, LocalDest: {2}" , RemoteSource , RemoteDest , LocalDest ) ;
2014-12-10 11:57:17 -05:00
Hashtable Results = RPCUtilHelper . Command ( "/" , String . Format ( "cp -R -L {0} {1}" , RemoteSource . Replace ( " " , "\\ " ) , RemoteDest . Replace ( " " , "\\ " ) ) , "" , null ) ;
2014-05-09 17:38:40 -04:00
foreach ( DictionaryEntry Entry in Results )
{
Log . TraceInformation ( "{0}" , Entry . Value ) ;
}
// Copy the bundled resource from the remote mac to the local dest
RPCUtilHelper . CopyDirectory ( RemoteDest , LocalDest , RPCUtilHelper . ECopyOptions . None ) ;
}
Support for third party iOS framework bundled assets
* Work in progress, works with RPC utility, local mac support incoming
* Changed AdditionalPublicFrameworks from storing just string, to storing the frame work name, zip name, and bundled asset name that needs to be copied
* We also now store the module that added this framework, so we can derive the module project path, etc when we need it for when we create intermediate directories
#Codereview Josh.Adams, Peter.Sauerbrei, Michael.Noland, Gil.Gribb, Robert.Manuszewski
[CL 2068603 by John Pollard in Main branch]
2014-05-09 16:38:26 -04:00
}
2014-03-14 14:13:41 -04:00
}
}
2014-04-30 14:09:06 -04:00
2014-12-02 14:58:59 -05:00
public override UnrealTargetPlatform GetPlatform ( )
{
return UnrealTargetPlatform . IOS ;
}
2014-04-30 14:09:06 -04:00
public static int RunExecutableAndWait ( string ExeName , string ArgumentList , out string StdOutResults )
{
// Create the process
ProcessStartInfo PSI = new ProcessStartInfo ( ExeName , ArgumentList ) ;
PSI . RedirectStandardOutput = true ;
PSI . UseShellExecute = false ;
PSI . CreateNoWindow = true ;
Process NewProcess = Process . Start ( PSI ) ;
// Wait for the process to exit and grab it's output
StdOutResults = NewProcess . StandardOutput . ReadToEnd ( ) ;
NewProcess . WaitForExit ( ) ;
return NewProcess . ExitCode ;
}
2014-03-14 14:13:41 -04:00
} ;
}