// Look for any build options in the engine config file. public override void ParseProjectSettings() { base.ParseProjectSettings(); ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", UnrealBuildTool.GetUProjectPath()); string ServerName = RemoteServerName; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RemoteServerName", out ServerName) && !String.IsNullOrEmpty(ServerName)) { RemoteServerName = ServerName; } bool bUseRSync = false; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bUseRSync", out bUseRSync)) { bUseRPCUtil = !bUseRSync; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RSyncUsername", out RSyncUsername); string ConfigKeyPath; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SSHPrivateKeyOverridePath", out ConfigKeyPath)) { if (File.Exists(ConfigKeyPath)) { SSHPrivateKeyOverridePath = ConfigKeyPath; } } } }
// static creation functions for ini files public static ConfigCacheIni CreateConfigCacheIni(UnrealTargetPlatform Platform, string BaseIniName, DirectoryReference ProjectDirectory, DirectoryReference EngineDirectory = null) { if (EngineDirectory == null) { EngineDirectory = UnrealBuildTool.EngineDirectory; } string BaseIniCacheKey = BaseIniName + "_" + Platform.ToString(); // cache base ini for use as the seed for the rest if (!BaseIniCache.ContainsKey(BaseIniCacheKey)) { BaseIniCache.Add(BaseIniCacheKey, new ConfigCacheIni(Platform, BaseIniName, null, EngineDirectory, EngineOnly: true)); } // build the new ini and cache it for later re-use ConfigCacheIni BaseCache = BaseIniCache[BaseIniCacheKey]; string Key = GetIniPlatformName(Platform) + BaseIniName + EngineDirectory.FullName + (ProjectDirectory != null ? ProjectDirectory.FullName : ""); if (!IniCache.ContainsKey(Key)) { IniCache.Add(Key, new ConfigCacheIni(Platform, BaseIniName, ProjectDirectory, EngineDirectory, BaseCache: BaseCache)); } return(IniCache[Key]); }
private void WriteEntitlementsFile(string OutputFilename, FileReference ProjectFile) { // get the settings from the ini file // plist replacements // @todo tvos: Separate TVOS version? ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", DirectoryReference.FromFile(ProjectFile)); bool bSupported = false; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableCloudKitSupport", out bSupported); Directory.CreateDirectory(Path.GetDirectoryName(OutputFilename)); // we need to have something so Xcode will compile, so we just set the get-task-allow, since we know the value, // which is based on distribution or not (true means debuggable) StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine(string.Format("\t<key>get-task-allow</key><{0}/>", /*Config.bForDistribution ? "false" : */ "true")); if (bSupported) { Text.AppendLine("\t<key>com.apple.developer.icloud-container-identifiers</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>iCloud.$(CFBundleIdentifier)</string>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>com.apple.developer.icloud-services</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>CloudKit</string>"); Text.AppendLine("\t</array>"); } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); File.WriteAllText(OutputFilename, Text.ToString()); }
public override void AddExtraModules(TargetInfo Target, List <string> PlatformExtraModules) { string VulkanSDKPath = Environment.GetEnvironmentVariable("VK_SDK_PATH"); if (!String.IsNullOrEmpty(VulkanSDKPath)) { ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.Android, "Engine", DirectoryReference.FromFile(ProjectFile)); bool bSupportsVulkan = false; Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bSupportsVulkan", out bSupportsVulkan); // Make sure we have the .so to compile in the RHI. // Currently using static linking. This check will go away when we support dynamic linking. string VulkanSoPath = System.IO.Path.Combine(VulkanSDKPath, "Source/lib/libvulkan.so"); bool bSoExists = System.IO.File.Exists(VulkanSoPath); if (bSupportsVulkan && bSoExists) { PlatformExtraModules.Add("VulkanRHI"); } else { if (bSupportsVulkan == false) { Log.TraceInformationOnce("Vulkan SDK is installed, but the project disabled Vulkan (bSupportsVulkan setting in Engine). Disabling Vulkan RHI for Android"); } else if (bSoExists == false) { Log.TraceInformationOnce("Vulkan SDK is installed, but [SDK]/Source/lib/libvulkan.so was not found. Disabling Vulkan RHI for Android"); } } } }
public override void ResetBuildConfiguration(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration) { UEBuildConfiguration.bCompileICU = true; // Should we enable Windows XP support { // If it wasnt set as an XML flag, check if it is requested from the commandline. if (!SupportWindowsXPIfAvailable) { string[] CmdLine = Environment.GetCommandLineArgs(); SupportWindowsXPIfAvailable = CmdLine.Contains("-winxp", StringComparer.InvariantCultureIgnoreCase); // ...check if it was supported from a config. if (!SupportWindowsXPIfAvailable) { ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.Win64, "Engine", UnrealBuildTool.GetUProjectPath()); string MinimumOS; if (Ini.GetString("/Script/WindowsTargetPlatform.WindowsTargetSettings", "MinimumOSVersion", out MinimumOS)) { if (string.IsNullOrEmpty(MinimumOS) == false) { SupportWindowsXPIfAvailable = MinimumOS == "MSOS_XP"; } } } } // Win32 XP is only supported at this time. SupportWindowsXP = SupportWindowsXPIfAvailable && (GetCPPTargetPlatform(InPlatform) == CPPTargetPlatform.Win32); } }
public static void ParseArchitectures() { // look in ini settings for what platforms to compile for ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.Android, "Engine", UnrealBuildTool.GetUProjectPath()); List <string> ProjectArches = new List <string>(); bool bBuild = true; if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForArmV7", out bBuild) && bBuild) { ProjectArches.Add("-armv7"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForArm64", out bBuild) && bBuild) { ProjectArches.Add("-arm64"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForx86", out bBuild) && bBuild) { ProjectArches.Add("-x86"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForx8664", out bBuild) && bBuild) { ProjectArches.Add("-x86_64"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("-armv7"); } Arches = ProjectArches.ToArray(); // Parse selected GPU architectures List <string> ProjectGPUArches = new List <string>(); if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForES31", out bBuild) && bBuild) { ProjectGPUArches.Add("-es31"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForGL4", out bBuild) && bBuild) { ProjectGPUArches.Add("-gl4"); } if (ProjectGPUArches.Count == 0 || (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForES2", out bBuild) && bBuild)) { ProjectGPUArches.Add("-es2"); } GPUArchitectures = ProjectGPUArches.ToArray(); List <string> FullArchCombinations = new List <string>(); foreach (string Arch in Arches) { foreach (string GPUArch in GPUArchitectures) { FullArchCombinations.Add(Arch + GPUArch); } } AllComboNames = FullArchCombinations.ToArray(); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser string BrowserPath = Params.Device.Replace("HTML5@", ""); // open the webpage Int32 ServerPort = 8000; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) + ".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = String.Format("http://localhost:{0}/{1}", ServerPort, url); } // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = BrowserPath.ToLower(); var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user"); string BrowserCommandline = url; if (LowerBrowserPath.Contains("chrome")) { BrowserCommandline += " " + String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { BrowserCommandline += " " + String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox")); } string LauncherArguments = string.Format(" -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { BrowserPath, BrowserCommandline, ServerPort, WorkingDirectory }); var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); ProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit); return(BrowserProcess); }
private bool IsVulkanSupportEnabled() { ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.Android, "Engine", DirectoryReference.FromFile(ProjectFile)); bool bSupportsVulkan = false; Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bSupportsVulkan", out bSupportsVulkan); return(bSupportsVulkan); }
public void ParseArchitectures() { // look in ini settings for what platforms to compile for ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Android, "Engine", DirectoryReference.FromFile(ProjectFile)); Arches = new List<string>(); bool bBuild = true; if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForArmV7", out bBuild) && bBuild || UEBuildConfiguration.Architectures.Contains("armv7", StringComparer.OrdinalIgnoreCase)) { Arches.Add("-armv7"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForArm64", out bBuild) && bBuild || UEBuildConfiguration.Architectures.Contains("arm64", StringComparer.OrdinalIgnoreCase)) { Arches.Add("-arm64"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForx86", out bBuild) && bBuild || UEBuildConfiguration.Architectures.Contains("x86", StringComparer.OrdinalIgnoreCase)) { Arches.Add("-x86"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForx8664", out bBuild) && bBuild || UEBuildConfiguration.Architectures.Contains("x64", StringComparer.OrdinalIgnoreCase)) { Arches.Add("-x64"); } // force armv7 if something went wrong if (Arches.Count == 0) { Arches.Add("-armv7"); } // Parse selected GPU architectures GPUArchitectures = new List<string>(); if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForES2", out bBuild) && bBuild || UEBuildConfiguration.GPUArchitectures.Contains("es2", StringComparer.OrdinalIgnoreCase)) { GPUArchitectures.Add("-es2"); } if (Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildForESDeferred", out bBuild) && bBuild || UEBuildConfiguration.GPUArchitectures.Contains("esdeferred", StringComparer.OrdinalIgnoreCase)) { GPUArchitectures.Add("-esdeferred"); } if (GPUArchitectures.Count == 0) { GPUArchitectures.Add("-es2"); } AllComboNames = (from Arch in Arches from GPUArch in GPUArchitectures select Arch + GPUArch).ToList(); }
public static bool CanCreateMapPaks(ProjectParams Param) { bool UseAsyncLevelLoading = false; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Param.RawProjectPath), CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine")); ConfigCache.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "UseAsyncLevelLoading", out UseAsyncLevelLoading); if (Param.Run) return false; return UseAsyncLevelLoading; }
private InstalledPlatformInfo() { List <string> InstalledPlatforms; ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Unknown, "Engine", (DirectoryReference)null); if (Ini.GetArray("InstalledPlatforms", "InstalledPlatformConfigurations", out InstalledPlatforms)) { foreach (string InstalledPlatform in InstalledPlatforms) { ParsePlatformConfiguration(InstalledPlatform); } } }
public static bool CanCreateMapPaks(ProjectParams Param) { bool UseAsyncLevelLoading = false; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Param.RawProjectPath), CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine")); ConfigCache.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "UseAsyncLevelLoading", out UseAsyncLevelLoading); if (Param.Run) { return(false); } return(UseAsyncLevelLoading); }
// Look for any build options in the engine config file. public override void ParseProjectSettings() { base.ParseProjectSettings(); string EngineIniPath = ProjectFile != null ? ProjectFile.Directory.FullName : null; if (String.IsNullOrEmpty(EngineIniPath)) { EngineIniPath = UnrealBuildTool.GetRemoteIniPath(); } ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", EngineIniPath); string ServerName = RemoteServerName; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RemoteServerName", out ServerName) && !String.IsNullOrEmpty(ServerName)) { RemoteServerName = ServerName; } bool bUseRSync = false; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bUseRSync", out bUseRSync)) { bUseRPCUtil = !bUseRSync; string UserName = RSyncUsername; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RSyncUsername", out UserName) && !String.IsNullOrEmpty(UserName)) { RSyncUsername = UserName; } if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "DeltaCopyInstallPath", out OverrideDeltaCopyInstallPath)) { if (!string.IsNullOrEmpty(OverrideDeltaCopyInstallPath)) { SSHExe = Path.Combine(OverrideDeltaCopyInstallPath, Path.GetFileName(SSHExe)); RSyncExe = Path.Combine(OverrideDeltaCopyInstallPath, Path.GetFileName(RSyncExe)); } } string ConfigKeyPath; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SSHPrivateKeyOverridePath", out ConfigKeyPath)) { if (File.Exists(ConfigKeyPath)) { SSHPrivateKeyOverridePath = ConfigKeyPath; } } } }
public WindowsPlatformContext(UnrealTargetPlatform InPlatform, FileReference InProjectFile) : base(InPlatform, InProjectFile) { if (Platform == UnrealTargetPlatform.Win32) { // ...check if it was supported from a config. ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Win64, "Engine", DirectoryReference.FromFile(ProjectFile)); string MinimumOS; if (Ini.GetString("/Script/WindowsTargetPlatform.WindowsTargetSettings", "MinimumOSVersion", out MinimumOS)) { if (string.IsNullOrEmpty(MinimumOS) == false) { SupportWindowsXP = MinimumOS == "MSOS_XP"; } } } }
static void EnsureConfigCacheIsReady() { if (ConfigCache == null) { var CmdLine = Environment.GetCommandLineArgs(); string ProjectPath = UnrealBuildTool.GetUProjectPath(); if (String.IsNullOrEmpty(ProjectPath)) { ParseProjectPath(CmdLine, out ProjectPath); } ConfigCache = new ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", ProjectPath); // always pick from the Engine the root directory and NOT the staged engine directory. // This breaks parse order for user & game config inis so disabled but pulling from the staged directory may still be a problem //string IniFile = Path.GetFullPath(Path.GetDirectoryName(UnrealBuildTool.GetUBTPath()) + "/../../") + "Config/HTML5/HTML5Engine.ini"; //ConfigCache.ParseIniFile(IniFile); } }
public override IProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser string BrowserPath = Params.Devices[0].Replace("HTML5@", ""); // open the webpage Int32 ServerPort = 8000; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath.FullName), CombinePaths(CmdEnv.LocalRoot, "Engine")); ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) + ".html"; if (ClientCmdLine.Contains("filehostip")) { url += "?cookonthefly=true"; } url = String.Format("http://localhost:{0}/{1}", ServerPort, url); // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = BrowserPath.ToLower(); var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory().FullName, "UE4_HTML5", "user"); string BrowserCommandline = url; if (LowerBrowserPath.Contains("chrome")) { BrowserCommandline += " " + String.Format("--user-data-dir=\\\"{0}\\\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { BrowserCommandline += " " + String.Format("-no-remote -profile \\\"{0}\\\"", Path.Combine(ProfileDirectory, "firefox")); } string LauncherArguments = string.Format(" -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { BrowserPath, BrowserCommandline, ServerPort, WorkingDirectory }); var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); IProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit); return(BrowserProcess); }
public LinuxPlatformContext(FileReference InProjectFile) : base(UnrealTargetPlatform.Linux, InProjectFile) { // read settings from the config string EngineIniPath = ProjectFile != null ? ProjectFile.Directory.FullName : null; if (String.IsNullOrEmpty(EngineIniPath)) { // If the project file hasn't been specified, try to get the path from -remoteini command line param EngineIniPath = UnrealBuildTool.GetRemoteIniPath(); } DirectoryReference EngineIniDir = !String.IsNullOrEmpty(EngineIniPath) ? new DirectoryReference(EngineIniPath) : null; ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Linux, "Engine", EngineIniDir); string LinuxArchitectureString; if (Ini.GetString("/Script/LinuxTargetPlatform.LinuxTargetSettings", "TargetArchitecture", out LinuxArchitectureString)) { LinuxArchitecture Architecture; if (Enum.TryParse(LinuxArchitectureString, out Architecture)) { switch (Architecture) { default: System.Console.WriteLine("Architecture enum value {0} does not map to a valid triplet.", Architecture); break; case LinuxArchitecture.X86_64UnknownLinuxGnu: ActiveArchitecture = "x86_64-unknown-linux-gnu"; break; case LinuxArchitecture.ArmUnknownLinuxGnueabihf: ActiveArchitecture = "arm-unknown-linux-gnueabihf"; break; case LinuxArchitecture.AArch64UnknownLinuxGnueabi: ActiveArchitecture = "aarch64-unknown-linux-gnueabi"; break; } } } }
public string GetNdkApiLevel() { // ask the .ini system for what version to use ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Android, "Engine", DirectoryReference.FromFile(ProjectFile)); string NDKLevel; Ini.GetString("/Script/AndroidPlatformEditor.AndroidSDKSettings", "NDKAPILevel", out NDKLevel); if (NDKLevel == "latest") { // get a list of NDK platforms string PlatformsDir = Environment.ExpandEnvironmentVariables("%NDKROOT%/platforms"); if (!Directory.Exists(PlatformsDir)) { throw new BuildException("No platforms found in {0}", PlatformsDir); } // return the largest of them NDKLevel = GetLargestApiLevel(Directory.GetDirectories(PlatformsDir)); } return NDKLevel; }
/// <summary> /// Setup the target environment for building /// </summary> /// <param name="InBuildTarget"> The target being built</param> public override void SetUpEnvironment(UEBuildTarget InBuildTarget) { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("PLATFORM_IOS=1"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("PLATFORM_APPLE=1"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_TTS=0"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_SPEECH_RECOGNITION=0"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_DATABASE_SUPPORT=0"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_EDITOR=0"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("USE_NULL_RHI=0"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("REQUIRES_ALIGNED_INT_ACCESS"); ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", DirectoryReference.FromFile(ProjectFile)); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport", out bNotificationsEnabled); if (bNotificationsEnabled) { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("NOTIFICATIONS_ENABLED"); } if (GetActiveArchitecture() == "-simulator") { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_SIMULATOR=1"); } // we assume now we are building with IOS8 or later if (UEBuildConfiguration.bCompileAgainstEngine) { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("HAS_METAL=1"); InBuildTarget.ExtraModuleNames.Add("MetalRHI"); } else { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("HAS_METAL=0"); } InBuildTarget.GlobalLinkEnvironment.Config.AdditionalFrameworks.Add(new UEBuildFramework("GameKit")); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalFrameworks.Add(new UEBuildFramework("StoreKit")); }
public static string EmscriptenSDKPath() { var ConfigCache = new ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", UnrealBuildTool.GetUProjectPath()); // always pick from the Engine the root directory and NOT the staged engine directory. string IniFile = Path.GetFullPath(Path.GetDirectoryName(UnrealBuildTool.GetUBTPath()) + "/../../") + "Config/HTML5/HTML5Engine.ini"; ConfigCache.ParseIniFile(IniFile); string PlatformName = ""; if (!Utils.IsRunningOnMono) { PlatformName = "Windows"; } else { PlatformName = "Mac"; } string EMCCPath; bool ok = ConfigCache.GetString("HTML5SDKPaths", PlatformName, out EMCCPath); if (ok && System.IO.Directory.Exists(EMCCPath)) { return(EMCCPath); } // try to find SDK Location from env. if (Environment.GetEnvironmentVariable("EMSCRIPTEN") != null && System.IO.Directory.Exists(Environment.GetEnvironmentVariable("EMSCRIPTEN")) ) { return(Environment.GetEnvironmentVariable("EMSCRIPTEN")); } return(""); }
private void SetupXPSupportFromConfiguration() { string[] CmdLine = Environment.GetCommandLineArgs(); bool SupportWindowsXPIfAvailable = false; SupportWindowsXPIfAvailable = CmdLine.Contains("-winxp", StringComparer.InvariantCultureIgnoreCase); // ...check if it was supported from a config. if (!SupportWindowsXPIfAvailable) { ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.Win64, "Engine", UnrealBuildTool.GetUProjectPath()); string MinimumOS; if (Ini.GetString("/Script/WindowsTargetPlatform.WindowsTargetSettings", "MinimumOSVersion", out MinimumOS)) { if (string.IsNullOrEmpty(MinimumOS) == false) { SupportWindowsXPIfAvailable = MinimumOS == "MSOS_XP"; } } } SupportWindowsXP = SupportWindowsXPIfAvailable; }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { Log("Package {0}", Params.RawProjectPath); string PackagePath = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath), "Binaries", "HTML5"); if (!Directory.Exists(PackagePath)) { Directory.CreateDirectory(PackagePath); } string FinalDataLocation = Path.Combine(PackagePath, Params.ShortProjectName) + ".data"; // we need to operate in the root using (new PushedDirectory(Path.Combine(Params.BaseStageDirectory, "HTML5"))) { string PythonPath = HTML5SDKInfo.PythonPath(); string PackagerPath = HTML5SDKInfo.EmscriptenPackager(); string CmdLine = string.Format("\"{0}\" \"{1}\" --preload . --js-output=\"{1}.js\"", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, PythonPath, CmdLine); } // copy the "Executable" to the package directory string GameExe = Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename); if (Params.ClientConfigsToBuild[0].ToString() != "Development") { GameExe += "-HTML5-" + Params.ClientConfigsToBuild[0].ToString(); } GameExe += ".js"; // ensure the ue4game binary exists, if applicable string FullGameExePath = Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe); if (!SC.IsCodeBasedProject && !FileExists_NoExceptions(FullGameExePath)) { Log("Failed to find game application " + FullGameExePath); AutomationTool.ErrorReporter.Error("Stage Failed.", (int)AutomationTool.ErrorCodes.Error_MissingExecutable); throw new AutomationException("Could not find application {0}. You may need to build the UE4 project with your target configuration and platform.", FullGameExePath); } if (Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) != Path.Combine(PackagePath, GameExe)) { File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe), Path.Combine(PackagePath, GameExe), true); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".mem", Path.Combine(PackagePath, GameExe) + ".mem", true); } File.SetAttributes(Path.Combine(PackagePath, GameExe), FileAttributes.Normal); File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".mem", FileAttributes.Normal); // put the HTML file to the package directory string TemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", "Game.html.template"); string OutputFile = Path.Combine(PackagePath, (Params.ClientConfigsToBuild[0].ToString() != "Development" ? (Params.ShortProjectName + "-HTML5-" + Params.ClientConfigsToBuild[0].ToString()) : Params.ShortProjectName)) + ".html"; // find Heap Size. ulong HeapSize; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); int ConfigHeapSize = 0; // Valuer set by Editor UI var bGotHeapSize = ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize); // Fallback if the previous method failed if (!bGotHeapSize && !ConfigCache.GetInt32("BuildSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize)) // in Megs. { // we couldn't find a per config heap size, look for a common one. if (!ConfigCache.GetInt32("BuildSettings", "HeapSize", out ConfigHeapSize)) { ConfigHeapSize = Params.IsCodeBasedProject ? 1024 : 512; Log("Could not find Heap Size setting in .ini for Client config {0}", Params.ClientConfigsToBuild[0].ToString()); } } HeapSize = (ulong)ConfigHeapSize * 1024L * 1024L; // convert to bytes. Log("Setting Heap size to {0} Mb ", ConfigHeapSize); GenerateFileFromTemplate(TemplateFile, OutputFile, Params.ShortProjectName, Params.ClientConfigsToBuild[0].ToString(), Params.StageCommandline, !Params.IsCodeBasedProject, HeapSize); // copy the jstorage files to the binaries directory string JSDir = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5"); string OutDir = PackagePath; File.Copy(JSDir + "/json2.js", OutDir + "/json2.js", true); File.SetAttributes(OutDir + "/json2.js", FileAttributes.Normal); File.Copy(JSDir + "/jStorage.js", OutDir + "/jStorage.js", true); File.SetAttributes(OutDir + "/jStorage.js", FileAttributes.Normal); File.Copy(JSDir + "/moz_binarystring.js", OutDir + "/moz_binarystring.js", true); File.SetAttributes(OutDir + "/moz_binarystring.js", FileAttributes.Normal); PrintRunTime(); }
private void Init(UnrealTargetPlatform Platform, string BaseIniName, DirectoryReference ProjectDirectory, DirectoryReference EngineDirectory, bool EngineOnly = false, ConfigCacheIni BaseCache = null) { InitCommon(); bIsMergingConfigs = true; if (EngineDirectory == null) { EngineDirectory = UnrealBuildTool.EngineDirectory; } if (BaseCache != null) { foreach (KeyValuePair <string, IniSection> Pair in BaseCache.Sections) { Sections.Add(Pair.Key, new IniSection(Pair.Value)); } } if (EngineOnly) { foreach (FileReference IniFileName in EnumerateEngineIniFileNames(EngineDirectory, BaseIniName, Platform)) { if (IniFileName.Exists()) { ParseIniFile(IniFileName); } } } else { foreach (FileReference IniFileName in EnumerateCrossPlatformIniFileNames(ProjectDirectory, EngineDirectory, Platform, BaseIniName, BaseCache != null)) { if (IniFileName.Exists()) { ParseIniFile(IniFileName); } } } }
/** * Check for the default configuration * * return true if the project uses the default build config */ public override bool HasDefaultBuildConfig(UnrealTargetPlatform Platform, string ProjectPath) { ConfigCacheIni ProjIni = new ConfigCacheIni(Platform, "Engine", ProjectPath); ConfigCacheIni DefaultIni = new ConfigCacheIni(Platform, "Engine", null); string DefaultMinVersion = "IOS_6"; string ProjectMinVersion = DefaultMinVersion; ProjIni.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out ProjectMinVersion); DefaultIni.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out DefaultMinVersion); if (DefaultMinVersion != ProjectMinVersion) { return(false); } bool bDefaultBuild = true; bool bProjectBuild = true; ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } // determine if we need to generate the dsym ProjIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGenerateSYMFile", out bProjectBuild); DefaultIni.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGenerateSYMFile", out bDefaultBuild); if (bDefaultBuild != bProjectBuild) { return(false); } return(base.HasDefaultBuildConfig(Platform, ProjectPath)); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); string DeviceSection; if ( Utils.IsRunningOnMono ) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } string browserPath; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); if (!ok) throw new System.Exception ("Incorrect browser configuration in HTML5Engine.ini "); // open the webpage string directory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { var EmscriptenSettings = ReadEmscriptenSettings(); url = "http://127.0.0.1:8000/" + url; // this will be killed UBT instances dies. string input = String.Format(" -m SimpleHTTPServer 8000"); string PythonName = null; // Check the .emscripten file for a possible python path if (EmscriptenSettings.ContainsKey("PYTHON")) { PythonName = EmscriptenSettings["PYTHON"]; Log("Found python path {0} in emscripten file", PythonName); } // The AutoSDK defines this env var as part of its install. See setup.bat/unsetup.bat // If it's missing then just assume that python lives on the path if (PythonName == null && Environment.GetEnvironmentVariable("PYTHON") != null) { PythonName = Environment.GetEnvironmentVariable("PYTHON"); Log("Found python path {0} in PYTHON Environment Variable", PythonName); } // Check if the exe exists if (!System.IO.File.Exists(PythonName)) { Log("Either no python path can be found or it doesn't exist. Using python on PATH"); PythonName = Utils.IsRunningOnMono ? "python" : "python.exe"; } ProcessResult Result = ProcessManager.CreateProcess(PythonName, true, "html5server.log"); Result.ProcessObject.StartInfo.FileName = PythonName; Result.ProcessObject.StartInfo.UseShellExecute = false; Result.ProcessObject.StartInfo.RedirectStandardOutput = true; Result.ProcessObject.StartInfo.RedirectStandardInput = true; Result.ProcessObject.StartInfo.WorkingDirectory = directory; Result.ProcessObject.StartInfo.Arguments = input; Result.ProcessObject.Start(); Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e) { System.Console.WriteLine(e.Data); }; System.Console.WriteLine("Starting Browser Process"); // safari specific hack. string argument = url; if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) argument = ""; ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit); ClientProcess.ProcessObject.EnableRaisingEvents = true; ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e) { System.Console.WriteLine("Browser Process Ended - Killing Webserver"); // send kill. Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); }; // safari needs a hack. // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) { // ClientProcess.ProcessObject.WaitForInputIdle (); Thread.Sleep (2000); Process.Start("/usr/bin/osascript"," -e 'tell application \"Safari\" to open location \"" + url + "\"'" ); } return ClientProcess; } System.Console.WriteLine("Browser Path " + browserPath); ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { Log("Package {0}", Params.RawProjectPath); var EmscriptenSettings = ReadEmscriptenSettings(); string PackagePath = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath), "Binaries", "HTML5"); if (!Directory.Exists(PackagePath)) { Directory.CreateDirectory(PackagePath); } string FinalDataLocation = Path.Combine(PackagePath, Params.ShortProjectName) + ".data"; // we need to operate in the root using (new PushedDirectory(Path.Combine(Params.BaseStageDirectory, "HTML5"))) { string BaseSDKPath = Environment.GetEnvironmentVariable("EMSCRIPTEN"); string PythonPath = null; // Check the .emscripten file for a possible python path if (EmscriptenSettings.ContainsKey("PYTHON")) { PythonPath = EmscriptenSettings["PYTHON"]; Log("Found python path {0} in emscripten file", PythonPath); } // The AutoSDK defines this env var as part of its install. See setup.bat/unsetup.bat // If it's missing then just assume that python lives on the path if (PythonPath == null && Environment.GetEnvironmentVariable("PYTHON") != null) { PythonPath = Environment.GetEnvironmentVariable("PYTHON"); Log("Found python path {0} in PYTHON Environment Variable", PythonPath); } // Check if the exe exists if (!System.IO.File.Exists(PythonPath)) { PythonPath = null; } if (PythonPath == null) { Log("Either no python path can be found or it doesn't exist. Using python on PATH"); } // make the file_packager command line if (Utils.IsRunningOnMono) { string PackagerPath = BaseSDKPath + "/tools/file_packager.py"; if (PythonPath == null) { string CmdLine = string.Format("-c \" python {0} '{1}' --preload . --js-output='{1}.js' \" ", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, "/bin/bash", CmdLine); } else { string CmdLine = string.Format("{0} '{1}' --preload . --js-output='{1}.js' ", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, PythonPath, CmdLine); } } else { string PackagerPath = "\"" + BaseSDKPath + "\\tools\\file_packager.py\""; if (PythonPath == null) { string CmdLine = string.Format("/c python {0} \"{1}\" --preload . --js-output=\"{1}.js\"", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, CommandUtils.CombinePaths(Environment.SystemDirectory, "cmd.exe"), CmdLine); } else { string CmdLine = string.Format("{0} \"{1}\" --preload . --js-output=\"{1}.js\"", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, PythonPath, CmdLine); } } } // copy the "Executable" to the package directory string GameExe = Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename); if (Params.ClientConfigsToBuild[0].ToString() != "Development") { GameExe += "-HTML5-" + Params.ClientConfigsToBuild[0].ToString(); } GameExe += ".js"; if (Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) != Path.Combine(PackagePath, GameExe)) { File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe), Path.Combine(PackagePath, GameExe), true); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".mem", Path.Combine(PackagePath, GameExe) + ".mem", true); } File.SetAttributes(Path.Combine(PackagePath, GameExe), FileAttributes.Normal); File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".mem", FileAttributes.Normal); // put the HTML file to the package directory string TemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", "Game.html.template"); string OutputFile = Path.Combine(PackagePath, (Params.ClientConfigsToBuild[0].ToString() != "Development" ? (Params.ShortProjectName + "-HTML5-" + Params.ClientConfigsToBuild[0].ToString()) : Params.ShortProjectName)) + ".html"; // find Heap Size. ulong HeapSize; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); int ConfigHeapSize; if (!ConfigCache.GetInt32("BuildSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize)) // in Megs. { // we couldn't find a per config heap size, look for a common one. if (!ConfigCache.GetInt32("BuildSettings", "HeapSize", out ConfigHeapSize)) { ConfigHeapSize = Params.IsCodeBasedProject ? 1024 : 512; Log("Could not find Heap Size setting in .ini for Client config {0}", Params.ClientConfigsToBuild[0].ToString()); } } HeapSize = (ulong)ConfigHeapSize * 1024L * 1024L; // convert to bytes. Log("Setting Heap size to {0} Mb ", ConfigHeapSize); GenerateFileFromTemplate(TemplateFile, OutputFile, Params.ShortProjectName, Params.ClientConfigsToBuild[0].ToString(), Params.StageCommandline, !Params.IsCodeBasedProject, HeapSize); // copy the jstorage files to the binaries directory string JSDir = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5"); string OutDir = PackagePath; File.Copy(JSDir + "/json2.js", OutDir + "/json2.js", true); File.SetAttributes(OutDir + "/json2.js", FileAttributes.Normal); File.Copy(JSDir + "/jstorage.js", OutDir + "/jstorage.js", true); File.SetAttributes(OutDir + "/jstorage.js", FileAttributes.Normal); File.Copy(JSDir + "/moz_binarystring.js", OutDir + "/moz_binarystring.js", true); File.SetAttributes(OutDir + "/moz_binarystring.js", FileAttributes.Normal); PrintRunTime(); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); bool ok = false; List <string> Devices; string browserPath = ""; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); if (ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5SDKSettings", "DeviceMap", out Devices)) { foreach (var Dev in Devices) { var Matched = Regex.Match(Dev, "\\(DeviceName=\"(.*)\",DevicePath=\\(FilePath=\"(.*)\"\\)\\)", RegexOptions.IgnoreCase); if (Matched.Success && Matched.Groups[1].ToString() == DeviceName) { browserPath = Matched.Groups[2].ToString(); ok = true; break; } } } if (!ok && HTML5SDKInfo.bAllowFallbackSDKSettings) { string DeviceSection; if (Utils.IsRunningOnMono) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); } if (!ok) { throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini "); } // open the webpage Int32 ServerPort = 8000; ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) + ".html"; string args = "-m "; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = String.Format("http://127.0.0.1:{0}/{1}", ServerPort, url); args += String.Format("-h -s {0} ", ServerPort); } // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = browserPath.ToLower(); args += String.Format("-b \"{0}\" -p \"{1}\" -w \"{2}\" ", browserPath, HTML5SDKInfo.PythonPath(), WorkingDirectory); args += url + " "; var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user"); if (LowerBrowserPath.Contains("chrome")) { args += String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { args += String.Format("-no-remote -profile \"{0}\" -jsconsole", Path.Combine(ProfileDirectory, "firefox")); } //else if (browserPath.Contains("Safari")) {} var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); ProcessResult BrowserProcess = Run(LaunchHelperPath, args, null, ClientRunFlags | ERunOptions.NoWaitForExit); return(BrowserProcess); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); bool ok = false; List<string> Devices; string browserPath = ""; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); if (ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5SDKSettings", "DeviceMap", out Devices)) { foreach (var Dev in Devices) { var Matched = Regex.Match(Dev, "\\(DeviceName=\"(.*)\",DevicePath=\\(FilePath=\"(.*)\"\\)\\)", RegexOptions.IgnoreCase); if (Matched.Success && Matched.Groups[1].ToString() == DeviceName) { browserPath = Matched.Groups[2].ToString(); ok = true; break; } } } if (!ok && HTML5SDKInfo.bAllowFallbackSDKSettings) { string DeviceSection; if (Utils.IsRunningOnMono) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); } if (!ok) { throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini "); } // open the webpage Int32 ServerPort = 8000; ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = String.Format("http://{2}:{0}/{1}", ServerPort, url, Environment.MachineName); } // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = browserPath.ToLower(); var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user"); string BrowserCommandline = url; if (LowerBrowserPath.Contains("chrome")) { BrowserCommandline += " " + String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { BrowserCommandline += " " + String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox")); } string LauncherArguments = string.Format( " -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { browserPath,BrowserCommandline,ServerPort,WorkingDirectory }); var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); ProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { Log("Package {0}", Params.RawProjectPath); Log("Setting Emscripten SDK for packaging.."); HTML5SDKInfo.SetupEmscriptenTemp(); HTML5SDKInfo.SetUpEmscriptenConfigFile(); string PackagePath = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath), "Binaries", "HTML5"); if (!Directory.Exists(PackagePath)) { Directory.CreateDirectory(PackagePath); } string FinalDataLocation = Path.Combine(PackagePath, Params.ShortProjectName) + ".data"; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine")); if (HTMLPakAutomation.CanCreateMapPaks(Params)) { HTMLPakAutomation PakAutomation = new HTMLPakAutomation(Params, SC); // Create Necessary Paks. PakAutomation.CreateEnginePak(); PakAutomation.CreateGamePak(); PakAutomation.CreateContentDirectoryPak(); // Create Emscripten Package from Necessary Paks. - This will be the VFS. PakAutomation.CreateEmscriptenDataPackage(PackagePath, FinalDataLocation); // Create All Map Paks which will be downloaded on the fly. PakAutomation.CreateMapPak(); // Create Delta Paks if setup. List<string> Paks = new List<string>(); ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5TargetSettings", "LevelTransitions", out Paks); if (Paks != null) { foreach (var Pak in Paks) { var Matched = Regex.Matches(Pak, "\"[^\"]+\"", RegexOptions.IgnoreCase); string MapFrom = Path.GetFileNameWithoutExtension(Matched[0].ToString().Replace("\"", "")); string MapTo = Path.GetFileNameWithoutExtension(Matched[1].ToString().Replace("\"", "")); PakAutomation.CreateDeltaMapPaks(MapFrom, MapTo); } } } else { // we need to operate in the root string PythonPath = HTML5SDKInfo.Python(); string PackagerPath = HTML5SDKInfo.EmscriptenPackager(); using (new ScopedEnvVar("EM_CONFIG", HTML5SDKInfo.DOT_EMSCRIPTEN)) { using (new PushedDirectory(Path.Combine(Params.BaseStageDirectory, "HTML5"))) { string CmdLine = string.Format("\"{0}\" \"{1}\" --preload . --js-output=\"{1}.js\"", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, PythonPath, CmdLine); } } } // copy the "Executable" to the package directory string GameExe = Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename); if (Params.ClientConfigsToBuild[0].ToString() != "Development") { GameExe += "-HTML5-" + Params.ClientConfigsToBuild[0].ToString(); } GameExe += ".js"; // ensure the ue4game binary exists, if applicable string FullGameExePath = Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe); if (!SC.IsCodeBasedProject && !FileExists_NoExceptions(FullGameExePath)) { Log("Failed to find game application " + FullGameExePath); throw new AutomationException(ErrorCodes.Error_MissingExecutable, "Stage Failed. Could not find application {0}. You may need to build the UE4 project with your target configuration and platform.", FullGameExePath); } if (Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) != Path.Combine(PackagePath, GameExe)) { File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe), Path.Combine(PackagePath, GameExe), true); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".mem", Path.Combine(PackagePath, GameExe) + ".mem", true); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".symbols", Path.Combine(PackagePath, GameExe) + ".symbols", true); } File.SetAttributes(Path.Combine(PackagePath, GameExe), FileAttributes.Normal); File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".mem", FileAttributes.Normal); File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".symbols", FileAttributes.Normal); // put the HTML file to the package directory string TemplateFileName = "GameX.html.template"; string TemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", TemplateFileName); string OutputFile = Path.Combine(PackagePath, (Params.ClientConfigsToBuild[0].ToString() != "Development" ? (Params.ShortProjectName + "-HTML5-" + Params.ClientConfigsToBuild[0].ToString()) : Params.ShortProjectName)) + ".html"; // find Heap Size. ulong HeapSize; int ConfigHeapSize = 0; // Valuer set by Editor UI var bGotHeapSize = ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize); // Fallback if the previous method failed if (!bGotHeapSize && !ConfigCache.GetInt32("BuildSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize)) // in Megs. { // we couldn't find a per config heap size, look for a common one. if (!ConfigCache.GetInt32("BuildSettings", "HeapSize", out ConfigHeapSize)) { ConfigHeapSize = Params.IsCodeBasedProject ? 1024 : 512; Log("Could not find Heap Size setting in .ini for Client config {0}", Params.ClientConfigsToBuild[0].ToString()); } } HeapSize = (ulong)ConfigHeapSize * 1024L * 1024L; // convert to bytes. Log("Setting Heap size to {0} Mb ", ConfigHeapSize); GenerateFileFromTemplate(TemplateFile, OutputFile, Params.ShortProjectName, Params.ClientConfigsToBuild[0].ToString(), Params.StageCommandline, !Params.IsCodeBasedProject, HeapSize); string MacBashTemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", "RunMacHTML5LaunchHelper.command.template"); string MacBashOutputFile = Path.Combine(PackagePath, "RunMacHTML5LaunchHelper.command"); string MonoPath = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "BatchFiles", "Mac", "SetupMono.sh"); GenerateMacCommandFromTemplate(MacBashTemplateFile, MacBashOutputFile, MonoPath); string JSDir = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5"); string OutDir = PackagePath; // Gather utlity .js files and combine into one file string[] UtilityJavaScriptFiles = Directory.GetFiles(JSDir, "*.js"); string DestinationFile = OutDir + "/Utility.js"; foreach( var UtilityFile in UtilityJavaScriptFiles) { string Data = File.ReadAllText(UtilityFile); File.AppendAllText(DestinationFile, Data); } // Compress all files. These are independent tasks which can be threaded. Task[] CompressionTasks = new Task[6]; //data file. CompressionTasks[0] = Task.Factory.StartNew( () => CompressFile(FinalDataLocation, FinalDataLocation + ".gz")); // data file .js driver. CompressionTasks[1] = Task.Factory.StartNew( () => CompressFile(FinalDataLocation + ".js" , FinalDataLocation + ".js.gz")); // main js. CompressionTasks[2] = Task.Factory.StartNew(() => CompressFile(Path.Combine(PackagePath, GameExe), Path.Combine(PackagePath, GameExe) + ".gz")); // mem init file. CompressionTasks[3] = Task.Factory.StartNew(() => CompressFile(Path.Combine(PackagePath, GameExe) + ".mem", Path.Combine(PackagePath, GameExe) + ".mem.gz")); // symbols file. CompressionTasks[4] = Task.Factory.StartNew(() => CompressFile(Path.Combine(PackagePath, GameExe) + ".symbols", Path.Combine(PackagePath, GameExe) + ".symbols.gz")); // Utility CompressionTasks[5] = Task.Factory.StartNew(() => CompressFile(OutDir + "/Utility.js", OutDir + "/Utility.js.gz")); File.Copy(CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"),CombinePaths(OutDir, "HTML5LaunchHelper.exe"),true); Task.WaitAll(CompressionTasks); PrintRunTime(); }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { Log("Package {0}", Params.RawProjectPath); Log("Setting Emscripten SDK for packaging.."); HTML5SDKInfo.SetupEmscriptenTemp(); HTML5SDKInfo.SetUpEmscriptenConfigFile(); string PackagePath = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath.FullName), "Binaries", "HTML5"); if (!Directory.Exists(PackagePath)) { Directory.CreateDirectory(PackagePath); } string FinalDataLocation = Path.Combine(PackagePath, Params.ShortProjectName) + ".data"; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath.FullName), CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine")); if (HTMLPakAutomation.CanCreateMapPaks(Params)) { HTMLPakAutomation PakAutomation = new HTMLPakAutomation(Params, SC); // Create Necessary Paks. PakAutomation.CreateEnginePak(); PakAutomation.CreateGamePak(); PakAutomation.CreateContentDirectoryPak(); // Create Emscripten Package from Necessary Paks. - This will be the VFS. PakAutomation.CreateEmscriptenDataPackage(PackagePath, FinalDataLocation); // Create All Map Paks which will be downloaded on the fly. PakAutomation.CreateMapPak(); // Create Delta Paks if setup. List <string> Paks = new List <string>(); ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5TargetSettings", "LevelTransitions", out Paks); if (Paks != null) { foreach (var Pak in Paks) { var Matched = Regex.Matches(Pak, "\"[^\"]+\"", RegexOptions.IgnoreCase); string MapFrom = Path.GetFileNameWithoutExtension(Matched[0].ToString().Replace("\"", "")); string MapTo = Path.GetFileNameWithoutExtension(Matched[1].ToString().Replace("\"", "")); PakAutomation.CreateDeltaMapPaks(MapFrom, MapTo); } } } else { // we need to operate in the root string PythonPath = HTML5SDKInfo.Python(); string PackagerPath = HTML5SDKInfo.EmscriptenPackager(); using (new ScopedEnvVar("EM_CONFIG", HTML5SDKInfo.DOT_EMSCRIPTEN)) { using (new PushedDirectory(Path.Combine(Params.BaseStageDirectory, "HTML5"))) { string CmdLine = string.Format("\"{0}\" \"{1}\" --preload . --js-output=\"{1}.js\"", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, PythonPath, CmdLine); } } } // copy the "Executable" to the package directory string GameExe = Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename); if (Params.ClientConfigsToBuild[0].ToString() != "Development") { GameExe += "-HTML5-" + Params.ClientConfigsToBuild[0].ToString(); } GameExe += ".js"; // ensure the ue4game binary exists, if applicable string FullGameExePath = Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe); if (!SC.IsCodeBasedProject && !FileExists_NoExceptions(FullGameExePath)) { Log("Failed to find game application " + FullGameExePath); throw new AutomationException(ExitCode.Error_MissingExecutable, "Stage Failed. Could not find application {0}. You may need to build the UE4 project with your target configuration and platform.", FullGameExePath); } if (Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) != Path.Combine(PackagePath, GameExe)) { File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe), Path.Combine(PackagePath, GameExe), true); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".mem", Path.Combine(PackagePath, GameExe) + ".mem", true); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".symbols", Path.Combine(PackagePath, GameExe) + ".symbols", true); } File.SetAttributes(Path.Combine(PackagePath, GameExe), FileAttributes.Normal); File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".mem", FileAttributes.Normal); File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".symbols", FileAttributes.Normal); // put the HTML file to the package directory string TemplateFileName = "GameX.html.template"; string TemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", TemplateFileName); string OutputFile = Path.Combine(PackagePath, (Params.ClientConfigsToBuild[0].ToString() != "Development" ? (Params.ShortProjectName + "-HTML5-" + Params.ClientConfigsToBuild[0].ToString()) : Params.ShortProjectName)) + ".html"; // find Heap Size. ulong HeapSize; int ConfigHeapSize = 0; // Valuer set by Editor UI var bGotHeapSize = ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize); // Fallback if the previous method failed if (!bGotHeapSize && !ConfigCache.GetInt32("/Script/BuildSettings.BuildSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize)) // in Megs. { // we couldn't find a per config heap size, look for a common one. if (!ConfigCache.GetInt32("/Script/BuildSettings.BuildSettings", "HeapSize", out ConfigHeapSize)) { ConfigHeapSize = Params.IsCodeBasedProject ? 1024 : 512; Log("Could not find Heap Size setting in .ini for Client config {0}", Params.ClientConfigsToBuild[0].ToString()); } } HeapSize = (ulong)ConfigHeapSize * 1024L * 1024L; // convert to bytes. Log("Setting Heap size to {0} Mb ", ConfigHeapSize); GenerateFileFromTemplate(TemplateFile, OutputFile, Params.ShortProjectName, Params.ClientConfigsToBuild[0].ToString(), Params.StageCommandline, !Params.IsCodeBasedProject, HeapSize); string MacBashTemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", "RunMacHTML5LaunchHelper.command.template"); string MacBashOutputFile = Path.Combine(PackagePath, "RunMacHTML5LaunchHelper.command"); string MonoPath = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "BatchFiles", "Mac", "SetupMono.sh"); GenerateMacCommandFromTemplate(MacBashTemplateFile, MacBashOutputFile, MonoPath); string htaccessTemplate = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", "htaccess.template"); string htaccesspath = Path.Combine(PackagePath, ".htaccess"); if (File.Exists(htaccesspath)) { FileAttributes attributes = File.GetAttributes(htaccesspath); if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { attributes &= ~FileAttributes.ReadOnly; File.SetAttributes(htaccesspath, attributes); } } File.Copy(htaccessTemplate, htaccesspath, true); string JSDir = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5"); string OutDir = PackagePath; // Gather utlity .js files and combine into one file string[] UtilityJavaScriptFiles = Directory.GetFiles(JSDir, "*.js"); string DestinationFile = OutDir + "/Utility.js"; File.Delete(DestinationFile); foreach (var UtilityFile in UtilityJavaScriptFiles) { string Data = File.ReadAllText(UtilityFile); File.AppendAllText(DestinationFile, Data); } // Compress all files. These are independent tasks which can be threaded. Task[] CompressionTasks = new Task[6]; //data file. CompressionTasks[0] = Task.Factory.StartNew(() => CompressFile(FinalDataLocation, FinalDataLocation + "gz")); // data file .js driver. CompressionTasks[1] = Task.Factory.StartNew(() => CompressFile(FinalDataLocation + ".js", FinalDataLocation + ".jsgz")); // main js. CompressionTasks[2] = Task.Factory.StartNew(() => CompressFile(Path.Combine(PackagePath, GameExe), Path.Combine(PackagePath, GameExe) + "gz")); // mem init file. CompressionTasks[3] = Task.Factory.StartNew(() => CompressFile(Path.Combine(PackagePath, GameExe) + ".mem", Path.Combine(PackagePath, GameExe) + ".memgz")); // symbols file. CompressionTasks[4] = Task.Factory.StartNew(() => CompressFile(Path.Combine(PackagePath, GameExe) + ".symbols", Path.Combine(PackagePath, GameExe) + ".symbolsgz")); // Utility CompressionTasks[5] = Task.Factory.StartNew(() => CompressFile(OutDir + "/Utility.js", OutDir + "/Utility.jsgz")); File.Copy(CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"), CombinePaths(OutDir, "HTML5LaunchHelper.exe"), true); Task.WaitAll(CompressionTasks); PrintRunTime(); }
public override void SetUpProjectEnvironment(UnrealTargetConfiguration Configuration, TargetInfo Target = null) { if (!bInitializedProject) { base.SetUpProjectEnvironment(Configuration, Target); // update the configuration based on the project file // look in ini settings for what platforms to compile for ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(Platform, "Engine", DirectoryReference.FromFile(ProjectFile)); string MinVersion = "IOS_8"; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarning("IOS 6 is no longer supported in UE4 as 4.11"); RunTimeIOSVersion = "8.0"; break; case "IOS_7": Log.TraceWarning("IOS 7 is no longer supported in UE4 as 4.14"); RunTimeIOSVersion = "8.0"; break; case "IOS_8": RunTimeIOSVersion = "8.0"; break; case "IOS_9": RunTimeIOSVersion = "9.0"; break; case "IOS_10": RunTimeIOSVersion = "10.0"; break; } } bool biPhoneAllowed = true; bool biPadAllowed = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone", out biPhoneAllowed); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad", out biPadAllowed); if (biPhoneAllowed && biPadAllowed) { RunTimeIOSDevices = "1,2"; } else if (biPadAllowed) { RunTimeIOSDevices = "2"; } else if (biPhoneAllowed) { RunTimeIOSDevices = "1"; } ProjectArches = new List <string>(); bool bBuild = true; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); } NonShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { NonShippingArchitectures += "," + ProjectArches[Index]; } ProjectArches.Clear(); if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); ProjectArches.Add("arm64"); } ShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { ShippingArchitectures += "," + ProjectArches[Index]; } // determine if we need to generate the dsym Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMFile", out BuildConfiguration.bGeneratedSYMFile); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMBundle", out BuildConfiguration.bGeneratedSYMBundle); // determie if bitcode should be generated for the shipping code Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForBitcode", out bShipForBitcode); // @todo tvos: We probably want to handle TVOS versions here Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalLinkerFlags", out AdditionalLinkerFlags); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalShippingLinkerFlags", out AdditionalShippingLinkerFlags); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MobileProvision", out MobileProvision); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SigningCertificate", out SigningCertificate); // bundle identifier Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); bInitializedProject = true; } ProvisionData Data = new ProvisionData(); string BundleId = BundleIdentifier.Replace("[PROJECT_NAME]", ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game")).Replace("_", ""); bool bIsTVOS = GetCodesignPlatformName() == "appletvos"; if (!ProvisionCache.ContainsKey(BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString())) { Certificate = SigningCertificate; Provision = MobileProvision; if (!string.IsNullOrEmpty(SigningCertificate)) { // verify the certificate Process IPPProcess = new Process(); if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } else { string IPPCmd = "certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } Utils.RunLocalProcess(IPPProcess); } else { Certificate = bForDistribtion ? "iPhone Distribution" : "iPhone Developer"; bHaveCertificate = true; } if (string.IsNullOrEmpty(MobileProvision) || // no provision specified !File.Exists((BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + MobileProvision) || // file doesn't exist !bHaveCertificate) // certificate doesn't exist { Certificate = ""; Provision = ""; Log.TraceLog("Provision not specified or not found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", searching for compatible match..."); Process IPPProcess = new Process(); if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } else { string IPPCmd = "signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } Utils.RunLocalProcess(IPPProcess); Log.TraceLog("Provision found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", Provision: " + Provision + " Certificate: " + Certificate); } // add to the dictionary Data.MobileProvision = Provision; Data.Certificate = Certificate.Replace("\"", ""); // read the provision to get the UUID string filename = (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + Data.MobileProvision; if (File.Exists(filename)) { string AllText = File.ReadAllText(filename); int idx = AllText.IndexOf("<key>UUID</key>"); if (idx > 0) { idx = AllText.IndexOf("<string>", idx); if (idx > 0) { idx += "<string>".Length; Data.UUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx); } } idx = AllText.IndexOf("<key>com.apple.developer.team-identifier</key>"); if (idx > 0) { idx = AllText.IndexOf("<string>", idx); if (idx > 0) { idx += "<string>".Length; Data.TeamUUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx); } } } else { Log.TraceLog("No matching provision file was discovered. Please ensure you have a compatible provision installed."); } ProvisionCache.Add(BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString(), Data); } else { Data = ProvisionCache[BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString()]; } MobileProvision = Data.MobileProvision; SigningCertificate = Data.Certificate; MobileProvisionUUID = Data.UUID; TeamUUID = Data.TeamUUID; }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { Log("Package {0}", Params.RawProjectPath); string PackagePath = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath), "Binaries", "HTML5"); if (!Directory.Exists(PackagePath)) { Directory.CreateDirectory(PackagePath); } string FinalDataLocation = Path.Combine(PackagePath, Params.ShortProjectName) + ".data"; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine")); if (HTMLPakAutomation.CanCreateMapPaks(Params)) { HTMLPakAutomation PakAutomation = new HTMLPakAutomation(Params, SC); // Create Necessary Paks. PakAutomation.CreateEnginePak(); PakAutomation.CreateGamePak(); PakAutomation.CreateContentDirectoryPak(); // Create Emscripten Package from Necessary Paks. - This will be the VFS. PakAutomation.CreateEmscriptenDataPackage(PackagePath, FinalDataLocation); // Create All Map Paks which will be downloaded on the fly. PakAutomation.CreateMapPak(); // Create Delta Paks if setup. List<string> Paks = new List<string>(); ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5TargetSettings", "LevelTransitions", out Paks); if (Paks != null) { foreach (var Pak in Paks) { var Matched = Regex.Matches(Pak, "\"[^\"]+\"", RegexOptions.IgnoreCase); string MapFrom = Path.GetFileNameWithoutExtension(Matched[0].ToString().Replace("\"", "")); string MapTo = Path.GetFileNameWithoutExtension(Matched[1].ToString().Replace("\"", "")); PakAutomation.CreateDeltaMapPaks(MapFrom, MapTo); } } } else { // we need to operate in the root using (new PushedDirectory(Path.Combine(Params.BaseStageDirectory, "HTML5"))) { string PythonPath = HTML5SDKInfo.PythonPath(); string PackagerPath = HTML5SDKInfo.EmscriptenPackager(); string CmdLine = string.Format("\"{0}\" \"{1}\" --preload . --js-output=\"{1}.js\"", PackagerPath, FinalDataLocation); RunAndLog(CmdEnv, PythonPath, CmdLine); } } // packaging created 2 files - .data.js and .data file. lets compress them. CompressFile(FinalDataLocation, FinalDataLocation); CompressFile(FinalDataLocation + ".js", FinalDataLocation + ".js.gz"); File.Delete(FinalDataLocation + ".js"); // copy the "Executable" to the package directory string GameExe = Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename); if (Params.ClientConfigsToBuild[0].ToString() != "Development") { GameExe += "-HTML5-" + Params.ClientConfigsToBuild[0].ToString(); } GameExe += ".js"; // ensure the ue4game binary exists, if applicable string FullGameExePath = Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe); if (!SC.IsCodeBasedProject && !FileExists_NoExceptions(FullGameExePath)) { Log("Failed to find game application " + FullGameExePath); AutomationTool.ErrorReporter.Error("Stage Failed.", (int)AutomationTool.ErrorCodes.Error_MissingExecutable); throw new AutomationException("Could not find application {0}. You may need to build the UE4 project with your target configuration and platform.", FullGameExePath); } if (Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) != Path.Combine(PackagePath, GameExe)) { // compress all javascript files in place. Log("Compressing and Copying main js executable"); CompressFile(FullGameExePath, Path.Combine(PackagePath, GameExe) + ".gz"); Log("Compressing and copying memory Initialization file"); CompressFile(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".mem", (Path.Combine(PackagePath, GameExe) + ".mem")); File.Copy(Path.Combine(Path.GetDirectoryName(Params.ProjectGameExeFilename), GameExe) + ".symbols", Path.Combine(PackagePath, GameExe) + ".symbols", true); } File.SetAttributes(Path.Combine(PackagePath, GameExe) + ".symbols", FileAttributes.Normal); // put the HTML file to the package directory bool UseExperimentalTemplate = false; ConfigCache.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "UseExperimentalTemplate", out UseExperimentalTemplate); string TemplateFileName = UseExperimentalTemplate ? "GameX.html.template" : "Game.html.template"; string TemplateFile = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5", TemplateFileName); string OutputFile = Path.Combine(PackagePath, (Params.ClientConfigsToBuild[0].ToString() != "Development" ? (Params.ShortProjectName + "-HTML5-" + Params.ClientConfigsToBuild[0].ToString()) : Params.ShortProjectName)) + ".html"; // find Heap Size. ulong HeapSize; int ConfigHeapSize = 0; // Valuer set by Editor UI var bGotHeapSize = ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize); // Fallback if the previous method failed if (!bGotHeapSize && !ConfigCache.GetInt32("BuildSettings", "HeapSize" + Params.ClientConfigsToBuild[0].ToString(), out ConfigHeapSize)) // in Megs. { // we couldn't find a per config heap size, look for a common one. if (!ConfigCache.GetInt32("BuildSettings", "HeapSize", out ConfigHeapSize)) { ConfigHeapSize = Params.IsCodeBasedProject ? 1024 : 512; Log("Could not find Heap Size setting in .ini for Client config {0}", Params.ClientConfigsToBuild[0].ToString()); } } HeapSize = (ulong)ConfigHeapSize * 1024L * 1024L; // convert to bytes. Log("Setting Heap size to {0} Mb ", ConfigHeapSize); GenerateFileFromTemplate(TemplateFile, OutputFile, Params.ShortProjectName, Params.ClientConfigsToBuild[0].ToString(), Params.StageCommandline, !Params.IsCodeBasedProject, HeapSize); string JSDir = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Build", "HTML5"); string OutDir = PackagePath; // Gather utlity .js files and combine into one file string[] UtilityJavaScriptFiles = Directory.GetFiles(JSDir, "*.js"); string DestinationFile = OutDir + "/Utility.js"; foreach( var UtilityFile in UtilityJavaScriptFiles) { string Data = File.ReadAllText(UtilityFile); File.AppendAllText(DestinationFile, Data); } CompressFile(DestinationFile, DestinationFile + ".gz"); // delete uncompressed file. if (File.Exists(DestinationFile)) { File.Delete(DestinationFile); } PrintRunTime(); }
/// <summary> /// checks if the sdk is installed or has been synced /// </summary> /// <returns></returns> private bool HasAnySDK() { string NDKPath = Environment.GetEnvironmentVariable("NDKROOT"); { var configCacheIni = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Unknown, "Engine", (DirectoryReference)null); var AndroidEnv = new Dictionary <string, string>(); Dictionary <string, string> EnvVarNames = new Dictionary <string, string> { { "ANDROID_HOME", "SDKPath" }, { "NDKROOT", "NDKPath" }, { "ANT_HOME", "ANTPath" }, { "JAVA_HOME", "JavaPath" } }; string path; foreach (var kvp in EnvVarNames) { if (configCacheIni.GetPath("/Script/AndroidPlatformEditor.AndroidSDKSettings", kvp.Value, out path) && !string.IsNullOrEmpty(path)) { AndroidEnv.Add(kvp.Key, path); } else { var envValue = Environment.GetEnvironmentVariable(kvp.Key); if (!String.IsNullOrEmpty(envValue)) { AndroidEnv.Add(kvp.Key, envValue); } } } // If we are on Mono and we are still missing a key then go and find it from the .bash_profile if (Utils.IsRunningOnMono && !EnvVarNames.All(s => AndroidEnv.ContainsKey(s.Key))) { string BashProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".bash_profile"); if (!File.Exists(BashProfilePath)) { // Try .bashrc if didn't fine .bash_profile BashProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".bashrc"); } if (File.Exists(BashProfilePath)) { string[] BashProfileContents = File.ReadAllLines(BashProfilePath); // Walk backwards so we keep the last export setting instead of the first for (int LineIndex = BashProfileContents.Length - 1; LineIndex >= 0; --LineIndex) { foreach (var kvp in EnvVarNames) { if (AndroidEnv.ContainsKey(kvp.Key)) { continue; } if (BashProfileContents[LineIndex].StartsWith("export " + kvp.Key + "=")) { string PathVar = BashProfileContents[LineIndex].Split('=')[1].Replace("\"", ""); AndroidEnv.Add(kvp.Key, PathVar); } } } } } // Set for the process foreach (var kvp in AndroidEnv) { Environment.SetEnvironmentVariable(kvp.Key, kvp.Value); } // See if we have an NDK path now... AndroidEnv.TryGetValue("NDKROOT", out NDKPath); } // we don't have an NDKROOT specified if (String.IsNullOrEmpty(NDKPath)) { return(false); } NDKPath = NDKPath.Replace("\"", ""); // need a supported llvm if (!Directory.Exists(Path.Combine(NDKPath, @"toolchains/llvm")) && !Directory.Exists(Path.Combine(NDKPath, @"toolchains/llvm-3.6")) && !Directory.Exists(Path.Combine(NDKPath, @"toolchains/llvm-3.5")) && !Directory.Exists(Path.Combine(NDKPath, @"toolchains/llvm-3.3")) && !Directory.Exists(Path.Combine(NDKPath, @"toolchains/llvm-3.1"))) { return(false); } return(true); }
public override void SetUpProjectEnvironment() { if (!bInitializedProject) { base.SetUpProjectEnvironment(); // update the configuration based on the project file // look in ini settings for what platforms to compile for ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(Platform, "Engine", DirectoryReference.FromFile(ProjectFile)); string MinVersion = "IOS_7"; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarning("IOS 6 is no longer supported in UE4 as 4.11"); RunTimeIOSVersion = "7.0"; break; case "IOS_7": RunTimeIOSVersion = "7.0"; break; case "IOS_8": RunTimeIOSVersion = "8.0"; break; case "IOS_9": RunTimeIOSVersion = "9.0"; break; } } bool biPhoneAllowed = true; bool biPadAllowed = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone", out biPhoneAllowed); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad", out biPadAllowed); if (biPhoneAllowed && biPadAllowed) { RunTimeIOSDevices = "1,2"; } else if (biPadAllowed) { RunTimeIOSDevices = "2"; } else if (biPhoneAllowed) { RunTimeIOSDevices = "1"; } List <string> ProjectArches = new List <string>(); bool bBuild = true; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); } NonShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { NonShippingArchitectures += "," + ProjectArches[Index]; } ProjectArches.Clear(); if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); ProjectArches.Add("arm64"); } ShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { ShippingArchitectures += "," + ProjectArches[Index]; } // determine if we need to generate the dsym Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMFile", out BuildConfiguration.bGeneratedSYMFile); // @todo tvos: We probably want to handle TVOS versions here Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalLinkerFlags", out AdditionalLinkerFlags); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalShippingLinkerFlags", out AdditionalShippingLinkerFlags); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MobileProvision", out MobileProvision); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SigningCertificate", out SigningCertificate); bInitializedProject = true; } }
public override void SetUpProjectEnvironment(UnrealTargetPlatform InPlatform) { base.SetUpProjectEnvironment(InPlatform); // update the configuration based on the project file // look in ini settings for what platforms to compile for ConfigCacheIni Ini = new ConfigCacheIni(InPlatform, "Engine", UnrealBuildTool.GetUProjectPath()); string MinVersion = "IOS_6"; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": RunTimeIOSVersion = "6.1"; break; case "IOS_7": RunTimeIOSVersion = "7.0"; break; case "IOS_8": RunTimeIOSVersion = "8.0"; break; } } bool biPhoneAllowed = true; bool biPadAllowed = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone", out biPhoneAllowed); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad", out biPadAllowed); if (biPhoneAllowed && biPadAllowed) { RunTimeIOSDevices = "1,2"; } else if (biPadAllowed) { RunTimeIOSDevices = "2"; } else if (biPhoneAllowed) { RunTimeIOSDevices = "1"; } List <string> ProjectArches = new List <string>(); bool bBuild = true; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); } NonShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { NonShippingArchitectures += "," + ProjectArches[Index]; } ProjectArches.Clear(); if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); ProjectArches.Add("arm64"); } ShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { ShippingArchitectures += "," + ProjectArches[Index]; } // determine if we need to generate the dsym Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGenerateSYMFile", out BuildConfiguration.bGeneratedSYMFile); }
public static bool GenerateIOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string AppDirectory, UEDeployIOS InThis = null) { // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/IOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/IOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; ProjectName = !String.IsNullOrEmpty(ProjectName) ? ProjectName : GameName; VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) { LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; } // get the settings from the ini file // plist replacements DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", DirRef); // orientations string SupportedOrientations = ""; bool bSupported = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsPortraitOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortrait</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsUpsideDownOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeLeftOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeRightOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n" : ""; // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // disable https requirement bool bDisableHTTPS; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDisableHTTPS", out bDisableHTTPS); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = ""; if (InThis != null) { // required capabilities RequiredCaps += InThis.IOSPlatformContext.GetRequiredCapabilities(); } Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsOpenGLES2", out bSupported); RequiredCaps += bSupported ? "\t\t<string>opengles-2</string>\n" : ""; if (!bSupported) { Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsMetal", out bSupported); RequiredCaps += bSupported ? "\t\t<string>metal</string>\n" : ""; } // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarning("IOS 6 is no longer supported in UE4 as 4.11"); MinVersion = "7.0"; break; case "IOS_7": MinVersion = "7.0"; break; case "IOS_8": MinVersion = "8.0"; break; case "IOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "7.0"; } // Get Facebook Support details bool bEnableFacebookSupport = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableFacebookSupport", out bEnableFacebookSupport); // Write the Facebook App ID if we need it. string FacebookAppID = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "FacebookAppID", out FacebookAppID); bEnableFacebookSupport = bEnableFacebookSupport && !string.IsNullOrWhiteSpace(FacebookAppID); // Add remote-notifications as background mode bool bRemoteNotificationsSupported = false; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport", out bRemoteNotificationsSupported); // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleURLTypes</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleURLName</key>"); Text.AppendLine("\t\t\t<string>com.Epic.Unreal</string>"); Text.AppendLine("\t\t\t<key>CFBundleURLSchemes</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine(string.Format("\t\t\t\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); if (bEnableFacebookSupport) { // This is needed for facebook login to redirect back to the app after completion. Text.AppendLine(string.Format("\t\t\t\t<string>fb{0}</string>", FacebookAppID)); } Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>English</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleName, ProjectName))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIStatusBarHidden</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiresFullScreen</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIViewControllerBasedStatusBarAppearance</key>"); Text.AppendLine("\t<false/>"); Text.AppendLine("\t<key>UISupportedInterfaceOrientations</key>"); Text.AppendLine("\t<array>"); foreach (string Line in SupportedOrientations.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); if (File.Exists(LaunchXib)) { // TODO: compile the xib via remote tool Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); Text.AppendLine("\t<string>LaunchScreen</string>"); bSkipDefaultPNGs = true; } else { // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPhoneConfigs = { "Default-IPhone6-Landscape", "Landscape", "{375, 667}", "8.0", "Default-IPhone6", "Portrait", "{375, 667}", "8.0", "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", "8.0", "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", "8.0", "Default", "Landscape", "{320, 480}", "7.0", "Default", "Portrait", "{320, 480}", "7.0", "Default-568h", "Landscape", "{320, 568}", "7.0", "Default-568h", "Portrait", "{320, 568}", "7.0", }; Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 4) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 3])); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } // close it out Text.AppendLine("\t</array>"); // this is a temp way to inject the iPad Pro without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPadConfigs = { "Default-Landscape", "Landscape", "{768, 1024}", "7.0", "Default-Portrait", "Portrait", "{768, 1024}", "7.0", "Default-Landscape-1336", "Landscape", "{1024, 1366}", "9.0", "Default-Portrait-1336", "Portrait", "{1024, 1366}", "9.0", }; Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPadConfigs.Length; ConfigIndex += 4) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 3])); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } Text.AppendLine("\t</array>"); } Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>iPhoneOS</string>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>MinimumOSVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); // disable exempt encryption Text.AppendLine("\t<key>ITSAppUsesNonExemptEncryption</key>"); Text.AppendLine("\t<false/>"); // disable HTTPS requirement if (bDisableHTTPS) { Text.AppendLine("\t<key>NSAppTransportSecurity</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>NSAllowsArbitraryLoads</key><true/>"); Text.AppendLine("\t\t</dict>"); } if (bEnableFacebookSupport) { Text.AppendLine("\t<key>FacebookAppID</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", FacebookAppID)); } if (!string.IsNullOrEmpty(ExtraData)) { ExtraData = ExtraData.Replace("\\n", "\n"); foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine("\t" + Line); } } } // Add remote-notifications as background mode if (bRemoteNotificationsSupported) { Text.AppendLine("\t<key>UIBackgroundModes</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>remote-notification</string>"); Text.AppendLine("\t</array>"); } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (InThis != null && InThis.UPL != null) { // Allow UPL to modify the plist here XDocument XDoc; try { XDoc = XDocument.Parse(Text.ToString()); } catch (Exception e) { throw new BuildException("plist is invalid {0}\n{1}", e, Text.ToString()); } XDoc.DocumentType.InternalSubset = ""; InThis.UPL.ProcessPluginNode("None", "iosPListUpdates", "", ref XDoc); string result = XDoc.Declaration.ToString() + "\n" + XDoc.ToString().Replace("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"[]>", "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); File.WriteAllText(PListFile, result); } else { File.WriteAllText(PListFile, Text.ToString()); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser string BrowserPath = Params.Device.Replace("HTML5@", ""); // open the webpage Int32 ServerPort = 8000; var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = String.Format("http://localhost:{0}/{1}", ServerPort, url); } // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = BrowserPath.ToLower(); var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user"); string BrowserCommandline = url; if (LowerBrowserPath.Contains("chrome")) { BrowserCommandline += " " + String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { BrowserCommandline += " " + String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox")); } string LauncherArguments = string.Format(" -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { BrowserPath, BrowserCommandline, ServerPort, WorkingDirectory }); var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); ProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); string DeviceSection; if ( Utils.IsRunningOnMono ) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } string browserPath; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); if (!ok) throw new System.Exception ("Incorrect browser configuration in HTML5Engine.ini "); // open the webpage string directory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = "http://127.0.0.1:8000/" + url; // this will be killed UBT instances dies. string input = String.Format(" -m SimpleHTTPServer 8000"); string PythonPath = HTML5SDKInfo.PythonPath(); ProcessResult Result = ProcessManager.CreateProcess(PythonPath, true, "html5server.log"); Result.ProcessObject.StartInfo.FileName = PythonPath; Result.ProcessObject.StartInfo.UseShellExecute = false; Result.ProcessObject.StartInfo.RedirectStandardOutput = true; Result.ProcessObject.StartInfo.RedirectStandardInput = true; Result.ProcessObject.StartInfo.WorkingDirectory = directory; Result.ProcessObject.StartInfo.Arguments = input; Result.ProcessObject.Start(); Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e) { System.Console.WriteLine(e.Data); }; System.Console.WriteLine("Starting Browser Process"); // safari specific hack. string argument = url; if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) argument = ""; // Chrome issue. Firefox may work like this in the future bool bBrowserWillSpawnProcess = browserPath.Contains("chrome") || (browserPath.Contains("Google Chrome") && Utils.IsRunningOnMono); ProcessResult SubProcess = null; ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit); var ProcStartTime = ClientProcess.ProcessObject.StartTime; var ProcName = ClientProcess.ProcessObject.ProcessName; ClientProcess.ProcessObject.EnableRaisingEvents = true; ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e) { System.Console.WriteLine("Browser Process Ended (PID={0})", ClientProcess.ProcessObject.Id); var bFoundChildProcess = false; if (bBrowserWillSpawnProcess) { // Chrome spawns a process from the tab it opens and then lets the process we spawned die, so // catch that process and attach to that instead. var CurrentProcesses = Process.GetProcesses(); foreach (var item in CurrentProcesses) { if (item.Id != ClientProcess.ProcessObject.Id && item.ProcessName == ProcName && item.StartTime >= ProcStartTime && item.StartTime <= ClientProcess.ProcessObject.ExitTime) { var PID = item.Id; System.Console.WriteLine("Found Process {0} with PID {1} which started at {2}. Waiting on that process to end.", item.ProcessName, item.Id, item.StartTime.ToString()); SubProcess = new ProcessResult(item.ProcessName, item, true, item.ProcessName); item.EnableRaisingEvents = true; item.Exited += delegate(System.Object o2, System.EventArgs e2) { System.Console.WriteLine("Browser Process Ended (PID={0}) - Killing Webserver", PID); Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); }; bFoundChildProcess = true; } } } if (!bFoundChildProcess) { System.Console.WriteLine("- Killing Webserver PID({0})", Result.ProcessObject.Id); Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); } }; if (bBrowserWillSpawnProcess) { //Wait for it to do so... ClientProcess.ProcessObject.WaitForExit(); ClientProcess = SubProcess; } // safari needs a hack. // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) { // ClientProcess.ProcessObject.WaitForInputIdle (); Thread.Sleep (2000); Process.Start("/usr/bin/osascript"," -e 'tell application \"Safari\" to open location \"" + url + "\"'" ); } return ClientProcess; } System.Console.WriteLine("Browser Path " + browserPath); ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }