public HTML5ToolChain(FileReference InProjectFile) : base(CppPlatform.HTML5) { if (!HTML5SDKInfo.IsSDKInstalled()) { throw new BuildException("HTML5 SDK is not installed; cannot use toolchain."); } // ini configs // - normal ConfigCache w/ UnrealBuildTool.ProjectFile takes all game config ini files // (including project config ini files) // - but, during packaging, if -remoteini is used -- need to use UnrealBuildTool.GetRemoteIniPath() // (note: ConfigCache can take null ProjectFile) string EngineIniPath = UnrealBuildTool.GetRemoteIniPath(); DirectoryReference ProjectDir = !String.IsNullOrEmpty(EngineIniPath) ? new DirectoryReference(EngineIniPath) : DirectoryReference.FromFile(InProjectFile); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, ProjectDir, UnrealTargetPlatform.HTML5); // Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableSIMD", out enableSIMD); // Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableMultithreading", out enableMultithreading); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableTracing", out bEnableTracing); // TODO: remove this "fix" when emscripten supports (SIMD & pthreads) + WASM enableSIMD = false; // TODO: double check Engine/Source/Runtime/Core/Private/HTML5/HTML5PlatformProcess.cpp::SupportsMultithreading() enableMultithreading = false; Log.TraceInformation("HTML5ToolChain: EnableSIMD = " + enableSIMD); Log.TraceInformation("HTML5ToolChain: EnableMultithreading " + enableMultithreading); Log.TraceInformation("HTML5ToolChain: EnableTracing = " + bEnableTracing); PrintOnce = new VerbosePrint(PrintOnceOn); // reset }
/// <summary> /// Checks whether the list of dependencies is still valid /// </summary> /// <returns></returns> public bool IsValid() { foreach (KeyValuePair <ConfigDependencyKey, IReadOnlyList <string> > Pair in Dependencies) { // Read the appropriate hierarchy ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(Pair.Key.Type, Pair.Key.ProjectDir, Pair.Key.Platform); // Get the value(s) associated with this key IReadOnlyList <string> NewValues; Hierarchy.TryGetValues(Pair.Key.SectionName, Pair.Key.KeyName, out NewValues); // Check if they're different if (Pair.Value == null) { if (NewValues != null) { return(false); } } else { if (NewValues == null || !Enumerable.SequenceEqual(Pair.Value, NewValues, StringComparer.Ordinal)) { return(false); } } } return(true); }
/// <summary> /// /// </summary> /// <param name="InDirectory"></param> /// <param name="InTargetPlatform"></param> /// <param name="OutRSAKeys"></param> /// <param name="OutAESKey"></param> public static void ParseEncryptionIni(DirectoryReference InDirectory, UnrealTargetPlatform InTargetPlatform, out String[] OutRSAKeys, out String OutAESKey) { OutAESKey = String.Empty; OutRSAKeys = null; ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InDirectory, InTargetPlatform); bool bSigningEnabled; Ini.GetBool("Core.Encryption", "SignPak", out bSigningEnabled); if (bSigningEnabled) { OutRSAKeys = new string[3]; Ini.GetString("Core.Encryption", "rsa.privateexp", out OutRSAKeys[0]); Ini.GetString("Core.Encryption", "rsa.modulus", out OutRSAKeys[1]); Ini.GetString("Core.Encryption", "rsa.publicexp", out OutRSAKeys[2]); if (String.IsNullOrEmpty(OutRSAKeys[0]) || String.IsNullOrEmpty(OutRSAKeys[1]) || String.IsNullOrEmpty(OutRSAKeys[2])) { OutRSAKeys = null; } } bool bEncryptionEnabled; Ini.GetBool("Core.Encryption", "EncryptPak", out bEncryptionEnabled); if (bEncryptionEnabled) { Ini.GetString("Core.Encryption", "aes.key", out OutAESKey); } }
protected static bool DoProjectSettingsMatchDefault(UnrealTargetPlatform Platform, DirectoryReference ProjectDirectoryName, string Section, string[] BoolKeys, string[] IntKeys, string[] StringKeys) { ConfigHierarchy ProjIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, ProjectDirectoryName, Platform); ConfigHierarchy DefaultIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, (DirectoryReference)null, Platform); // look at all bool values if (BoolKeys != null) { foreach (string Key in BoolKeys) { bool Default = false, Project = false; DefaultIni.GetBool(Section, Key, out Default); ProjIni.GetBool(Section, Key, out Project); if (Default != Project) { Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")"); return(false); } } } // look at all int values if (IntKeys != null) { foreach (string Key in IntKeys) { int Default = 0, Project = 0; DefaultIni.GetInt32(Section, Key, out Default); ProjIni.GetInt32(Section, Key, out Project); if (Default != Project) { Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")"); return(false); } } } // look for all string values if (StringKeys != null) { foreach (string Key in StringKeys) { string Default = "", Project = ""; DefaultIni.GetString(Section, Key, out Default); ProjIni.GetString(Section, Key, out Project); if (Default != Project) { Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")"); return(false); } } } // if we get here, we match all important settings return(true); }
/// <summary> /// Protected constructor. Used by TVOSProjectSettings. /// </summary> /// <param name="ProjectFile">The project file to read settings for</param> /// <param name="Platform">The platform to read settings for</param> /// <param name="Bundle">Bundle identifier needed when project file is empty</param> protected IOSProjectSettings(FileReference ProjectFile, UnrealTargetPlatform Platform, string Bundle) { this.ProjectFile = ProjectFile; ConfigCache.ReadSettings(DirectoryReference.FromFile(ProjectFile), Platform, this); if ((ProjectFile == null || string.IsNullOrEmpty(ProjectFile.FullName)) && !string.IsNullOrEmpty(Bundle)) { BundleIdentifier = Bundle; } BundleIdentifier = BundleIdentifier.Replace("[PROJECT_NAME]", ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game")).Replace("_", ""); }
public HTML5ToolChain(FileReference InProjectFile) : base(CppPlatform.HTML5) { if (!HTML5SDKInfo.IsSDKInstalled()) { throw new BuildException("HTML5 SDK is not installed; cannot use toolchain."); } // ini configs // - normal ConfigCache w/ UnrealBuildTool.ProjectFile takes all game config ini files // (including project config ini files) // - but, during packaging, if -remoteini is used -- need to use UnrealBuildTool.GetRemoteIniPath() // (note: ConfigCache can take null ProjectFile) string EngineIniPath = UnrealBuildTool.GetRemoteIniPath(); DirectoryReference ProjectDir = !String.IsNullOrEmpty(EngineIniPath) ? new DirectoryReference(EngineIniPath) : DirectoryReference.FromFile(InProjectFile); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, ProjectDir, UnrealTargetPlatform.HTML5); // Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableSIMD", out enableSIMD); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableMultithreading", out enableMultithreading); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "OffscreenCanvas", out bMultithreading_UseOffscreenCanvas); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "LLVMWasmBackend", out useLLVMwasmBackend); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableTracing", out bEnableTracing); if (useLLVMwasmBackend) { libExt = ".a"; // experimental - LLVMWasmBackend } // TODO: remove this "fix" when emscripten supports WASM with SIMD enableSIMD = false; Log.TraceInformation("HTML5ToolChain: EnableSIMD = " + enableSIMD); Log.TraceInformation("HTML5ToolChain: EnableMultithreading " + enableMultithreading); Log.TraceInformation("HTML5ToolChain: OffscreenCanvas " + bMultithreading_UseOffscreenCanvas); Log.TraceInformation("HTML5ToolChain: LLVMWasmBackend " + useLLVMwasmBackend); Log.TraceInformation("HTML5ToolChain: EnableTracing = " + bEnableTracing); PrintOnce = new VerbosePrint(PrintOnceOn); // reset Log.TraceInformation("Setting Emscripten SDK: located in " + HTML5SDKInfo.EMSCRIPTEN_ROOT); string TempDir = HTML5SDKInfo.SetupEmscriptenTemp(); HTML5SDKInfo.SetUpEmscriptenConfigFile(); if (Environment.GetEnvironmentVariable("EMSDK") == null) // If EMSDK is present, Emscripten is already configured by the developer { // If not using preset emsdk, configure our generated .emscripten config, instead of autogenerating one in the user's home directory. Environment.SetEnvironmentVariable("EM_CONFIG", HTML5SDKInfo.DOT_EMSCRIPTEN); Environment.SetEnvironmentVariable("EM_CACHE", HTML5SDKInfo.EMSCRIPTEN_CACHE); Environment.SetEnvironmentVariable("EMCC_TEMP_DIR", TempDir); } Log.TraceInformation("*** Emscripten Config File: " + Environment.GetEnvironmentVariable("EM_CONFIG")); }
public bool UseVulkan() { // @todo Lumin: Switch to Lumin once we have sub-platform ini ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFile), UnrealTargetPlatform.Android); // go by string bool bUseVulkan = true; Ini.GetBool("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bUseVulkan", out bUseVulkan); return(bUseVulkan); }
public bool UseVulkan() { DirectoryReference DirRef = (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : (ProjectFile != null ? ProjectFile.Directory : null)); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.Lumin); // go by string bool bUseVulkan = true; Ini.GetBool("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bUseVulkan", out bUseVulkan); return(bUseVulkan); }
private InstalledPlatformInfo() { List <string> InstalledPlatforms; ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, (DirectoryReference)null, UnrealTargetPlatform.Unknown); if (Ini.GetArray("InstalledPlatforms", "InstalledPlatformConfigurations", out InstalledPlatforms)) { foreach (string InstalledPlatform in InstalledPlatforms) { ParsePlatformConfiguration(InstalledPlatform); } } }
private string GetElfName(FileReference InNMakeOutputPath) { ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InNMakeOutputPath.Directory.ParentDirectory.ParentDirectory, UnrealTargetPlatform.Lumin); bool bUseMobileRendering = false; Ini.GetBool("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bUseMobileRendering", out bUseMobileRendering); bool bUseVulkan = false; Ini.GetBool("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bUseVulkan", out bUseVulkan); string OutputFileName = string.Format("{0}-arm64-{1}{2}", InNMakeOutputPath.GetFileNameWithoutExtension(), !(bUseMobileRendering || bUseVulkan) ? "lumingl4" : "lumin", InNMakeOutputPath.GetExtension()); return(OutputFileName); }
/// <summary> /// Find the default architecture for the given project /// </summary> public override string GetDefaultArchitecture(FileReference ProjectFile) { string ActiveArchitecture = DefaultArchitecture; // 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; ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, EngineIniDir, UnrealTargetPlatform.Linux); 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; case LinuxArchitecture.I686UnknownLinuxGnu: ActiveArchitecture = "i686-unknown-linux-gnu"; break; } } } return(ActiveArchitecture); }
/// <summary> /// checks if the sdk is installed or has been synced, sets environment variable /// </summary> /// <returns></returns> protected override bool HasAnySDK() { string EnvVarKey = "MLSDK"; string IniVarKey = "MLSDKPath"; string MLSDKPath = Environment.GetEnvironmentVariable(EnvVarKey); { var configCacheIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, (DirectoryReference)null, UnrealTargetPlatform.Unknown); string path; if (GetPath(configCacheIni, "/Script/LuminPlatformEditor.MagicLeapSDKSettings", IniVarKey, out path) && !string.IsNullOrEmpty(path)) { // if the folder specified by the config var doesn't exist, fall back to the env var. if (Directory.Exists(path)) { MLSDKPath = path; } } // Set for the process Environment.SetEnvironmentVariable(EnvVarKey, MLSDKPath); } // we don't have an MLSDK directory specified if (String.IsNullOrEmpty(MLSDKPath)) { return(false); } // we don't have the required MLSDK setup String DetectedVersion = "Unknown"; String VersionFile = string.Format("{0}/include/ml_version.h", MLSDKPath).Replace('/', Path.DirectorySeparatorChar); if (File.Exists(VersionFile)) { string[] VersionText = File.ReadAllLines(VersionFile); String MajorVersion = FindVersionNumber("MLSDK_VERSION_MAJOR", VersionText); String MinorVersion = FindVersionNumber("MLSDK_VERSION_MINOR", VersionText); DetectedVersion = string.Format("{0}.{1}", MajorVersion, MinorVersion); } if (!DetectedVersion.Equals(GetRequiredSDKString())) { Console.WriteLine("*** Found installed MLSDK version {0} but require {1} ***", DetectedVersion, GetRequiredSDKString()); return(false); } return(true); }
static bool bEnableTracing = false; // Debug option public HTML5ToolChain(FileReference InProjectFile) : base(CppPlatform.HTML5, WindowsCompiler.VisualStudio2015) { if (!HTML5SDKInfo.IsSDKInstalled()) { throw new BuildException("HTML5 SDK is not installed; cannot use toolchain."); } // ini configs // - normal ConfigCache w/ UnrealBuildTool.ProjectFile takes all game config ini files // (including project config ini files) // - but, during packaging, if -remoteini is used -- need to use UnrealBuildTool.GetRemoteIniPath() // (note: ConfigCache can take null ProjectFile) string EngineIniPath = UnrealBuildTool.GetRemoteIniPath(); DirectoryReference ProjectDir = !String.IsNullOrEmpty(EngineIniPath) ? new DirectoryReference(EngineIniPath) : DirectoryReference.FromFile(InProjectFile); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, ProjectDir, UnrealTargetPlatform.HTML5); // these will be going away... bool targetingAsmjs = false; // inverted check bool targetWebGL1 = false; // inverted check if (Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "TargetAsmjs", out targetingAsmjs)) { targetingWasm = !targetingAsmjs; } if (Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "TargetWebGL1", out targetWebGL1)) { targetWebGL2 = !targetWebGL1; } Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableSIMD", out enableSIMD); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableMultithreading", out enableMultithreading); Ini.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableTracing", out bEnableTracing); Log.TraceInformation("HTML5ToolChain: TargetWasm = " + targetingWasm); Log.TraceInformation("HTML5ToolChain: TargetWebGL2 = " + targetWebGL2); Log.TraceInformation("HTML5ToolChain: EnableSIMD = " + enableSIMD); Log.TraceInformation("HTML5ToolChain: EnableMultithreading " + enableMultithreading); Log.TraceInformation("HTML5ToolChain: EnableTracing = " + bEnableTracing); // TODO: remove this "fix" when emscripten supports (SIMD & pthreads) + WASM if (targetingWasm) { enableSIMD = false; // TODO: double check Engine/Source/Runtime/Core/Private/HTML5/HTML5PlatformProcess.cpp::SupportsMultithreading() enableMultithreading = false; } }
/// <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"); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFile), UnrealTargetPlatform.IOS); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport", out bNotificationsEnabled); if (bNotificationsEnabled) { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("NOTIFICATIONS_ENABLED=1"); } else { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("NOTIFICATIONS_ENABLED=0"); } if (GetActiveArchitecture() == "-simulator") { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_SIMULATOR=1"); } else { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_SIMULATOR=0"); } // 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")); }
static InstalledPlatformInfo() { List <string> InstalledPlatforms; ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, (DirectoryReference)null, UnrealTargetPlatform.Unknown); bool bHasInstalledPlatformInfo; if (Ini.TryGetValue("InstalledPlatforms", "HasInstalledPlatformInfo", out bHasInstalledPlatformInfo) && bHasInstalledPlatformInfo) { InstalledPlatformConfigurations = new List <InstalledPlatformConfiguration>(); if (Ini.GetArray("InstalledPlatforms", "InstalledPlatformConfigurations", out InstalledPlatforms)) { foreach (string InstalledPlatform in InstalledPlatforms) { ParsePlatformConfiguration(InstalledPlatform); } } } }
public static bool GeneratePList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string ExeName) { string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/Mac"; string DestPListFile = IntermediateDirectory + "/" + ExeName + "-Info.plist"; string SrcPListFile = (bIsUE4Game ? (InEngineDir + "Source/Programs/") : (ProjectDirectory + "/Source/")) + GameName + "/Resources/Mac/Info.plist"; if (!File.Exists(SrcPListFile)) { SrcPListFile = InEngineDir + "/Source/Runtime/Launch/Resources/Mac/Info.plist"; } string PListData = null; if (File.Exists(SrcPListFile)) { PListData = File.ReadAllText(SrcPListFile); } else { return(false); } // bundle identifier // plist replacements DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS); string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); string BundleVersion = MacToolChain.LoadEngineDisplayVersion(); PListData = PListData.Replace("${EXECUTABLE_NAME}", ExeName).Replace("${APP_NAME}", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", "")).Replace("${ICON_NAME}", GameName).Replace("${MACOSX_DEPLOYMENT_TARGET}", MacToolChain.Settings.MinMacOSVersion).Replace("${BUNDLE_VERSION}", BundleVersion); if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } File.WriteAllText(DestPListFile, PListData); return(true); }
public override bool HasSpecificDefaultBuildConfig(UnrealTargetPlatform Platform, DirectoryReference ProjectPath) { ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, ProjectPath, UnrealTargetPlatform.Lumin); bool bUseVulkan = true; Ini.GetBool("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bUseVulkan", out bUseVulkan); List <string> ConfigBoolKeys = new List <string>(); if (!bUseVulkan) { ConfigBoolKeys.Add("bUseMobileRendering"); } // look up Android specific settings if (!DoProjectSettingsMatchDefault(UnrealTargetPlatform.Lumin, ProjectPath, "/Script/LuminRuntimeSettings.LuminRuntimeSettings", ConfigBoolKeys.ToArray(), null, null)) { return(false); } return(true); }
private bool SetupGraphicsDebugger(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment) { string AndroidGraphicsDebugger; ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(Target.ProjectFile), UnrealTargetPlatform.Android); Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "AndroidGraphicsDebugger", out AndroidGraphicsDebugger); if (AndroidGraphicsDebugger.ToLower() == "renderdoc") { string RenderDocPath; AndroidPlatformSDK.GetPath(Ini, "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "RenderDocPath", out RenderDocPath); string RenderDocLibPath = Path.Combine(RenderDocPath, @"android\lib\armeabi-v7a"); if (Directory.Exists(RenderDocLibPath)) { LinkEnvironment.LibraryPaths.Add(new DirectoryReference(RenderDocLibPath)); LinkEnvironment.AdditionalLibraries.Add("VkLayer_GLES_RenderDoc"); return(true); } } return(false); }
public static bool UseTegraGraphicsDebugger(FileReference ProjectFile) { if (!HaveTegraGraphicsDebugger.HasValue) { string ProgramsDir = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); string NVDir = ProgramsDir + "/NVIDIA Corporation"; try { string[] TegraDebuggerDirs = Directory.GetDirectories(NVDir, "Tegra Graphics Debugger *"); if (TegraDebuggerDirs.Length > 0) { TegraDebuggerDir = TegraDebuggerDirs[0].Replace('\\', '/'); HaveTegraGraphicsDebugger = true; string[] V = TegraDebuggerDir.Split(' ').Last().Split('.'); TegraDebuggerVersion = new int[2]; TegraDebuggerVersion[0] = Int32.Parse(V[0]); TegraDebuggerVersion[1] = Int32.Parse(V[1]); } else { HaveTegraGraphicsDebugger = false; } } catch (System.IO.IOException) { HaveTegraGraphicsDebugger = false; } } bool bBuild = false; // TODO: do we need this? ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFile), UnrealTargetPlatform.Lumin); Ini.GetBool( "/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bBuildWithNvTegraGfxDebugger", out bBuild); return(HaveTegraGraphicsDebugger.Value && bBuild); }
public override void GenerateGameProperties(UnrealTargetConfiguration Configuration, StringBuilder VCProjectFileContent, TargetType TargetType, DirectoryReference RootDirectory, FileReference TargetFilePath) { string MinVersion = string.Empty; string MaxTestedVersion = string.Empty; ConfigHierarchy EngineIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, RootDirectory, UnrealTargetPlatform.HoloLens); if (EngineIni != null) { EngineIni.GetString("/Script/HoloLensPlatformEditor.HoloLensTargetSettings", "MinimumPlatformVersion", out MinVersion); EngineIni.GetString("/Script/HoloLensPlatformEditor.HoloLensTargetSettings", "MaximumPlatformVersionTested", out MaxTestedVersion); } if (!string.IsNullOrEmpty(MinVersion)) { VCProjectFileContent.Append(" <WindowsTargetPlatformMinVersion>"+ MinVersion + "</WindowsTargetPlatformMinVersion>" + ProjectFileGenerator.NewLine); } if (!string.IsNullOrEmpty(MaxTestedVersion)) { VCProjectFileContent.Append(" <WindowsTargetPlatformVersion>"+ MaxTestedVersion + "</WindowsTargetPlatformVersion>" + ProjectFileGenerator.NewLine); } WindowsCompiler Compiler = WindowsPlatform.GetDefaultCompiler(TargetFilePath); DirectoryReference PlatformWinMDLocation = HoloLens.GetCppCXMetadataLocation(Compiler, "Latest"); if (PlatformWinMDLocation == null || !FileReference.Exists(FileReference.Combine(PlatformWinMDLocation, "platform.winmd"))) { throw new BuildException("Unable to find platform.winmd for {0} toolchain; '{1}' is an invalid version", WindowsPlatform.GetCompilerName(Compiler), "Latest"); } string FoundationWinMDPath = HoloLens.GetLatestMetadataPathForApiContract("Windows.Foundation.FoundationContract", Compiler); string UniversalWinMDPath = HoloLens.GetLatestMetadataPathForApiContract("Windows.Foundation.UniversalApiContract", Compiler); VCProjectFileContent.Append(" <AdditionalOptions>/ZW /ZW:nostdlib</AdditionalOptions>"+ ProjectFileGenerator.NewLine); VCProjectFileContent.Append(" <NMakePreprocessorDefinitions>$(NMakePreprocessorDefinitions);PLATFORM_HOLOLENS=1;HOLOLENS=1;</NMakePreprocessorDefinitions>"+ ProjectFileGenerator.NewLine); if (PlatformWinMDLocation != null) { VCProjectFileContent.Append(" <NMakeAssemblySearchPath>$(NMakeAssemblySearchPath);"+ PlatformWinMDLocation + "</NMakeAssemblySearchPath>" + ProjectFileGenerator.NewLine); } VCProjectFileContent.Append(" <NMakeForcedUsingAssemblies>$(NMakeForcedUsingAssemblies);"+ FoundationWinMDPath + ";" + UniversalWinMDPath + ";platform.winmd</NMakeForcedUsingAssemblies>" + ProjectFileGenerator.NewLine); }
public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, bool bIsClient, string ProjectName, string InEngineDir, string AppDirectory, UnrealPluginLanguage UPL, string BundleID) { // @todo tvos: THIS! // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/TVOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/TVOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; // @todo tvos: This is really nasty - both IOS and TVOS are setting static vars 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 // @todo tvos: Are we going to make TVOS specific .ini files? DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS); // 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); if (!string.IsNullOrEmpty(BundleID)) { BundleIdentifier = BundleID; } // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = "\t\t<string>arm64</string>\n"; // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumTVOSVersion", out MinVersion)) { switch (MinVersion) { case "TVOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "9.0"; } // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // create the final display name, including converting all entities for XML use string FinalDisplayName = BundleDisplayName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""); FinalDisplayName = FinalDisplayName.Replace("&", "&"); FinalDisplayName = FinalDisplayName.Replace("\"", """); FinalDisplayName = FinalDisplayName.Replace("\'", "'"); FinalDisplayName = FinalDisplayName.Replace("<", "<"); FinalDisplayName = FinalDisplayName.Replace(">", ">"); // 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>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>en</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); string BundleExecutable = bIsUE4Game ? (bIsClient ? "UE4Client" : "UE4Game") : (bIsClient ? GameName + "Client" : GameName); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleExecutable)); 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, InEngineDir))); 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>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>TVTopShelfImage</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImage</key>"); Text.AppendLine("\t\t<string>Top Shelf Image</string>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImageWide</key>"); Text.AppendLine("\t\t<string>Top Shelf Image Wide</string>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>UILaunchImages</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine("\t\t\t<string>{1920, 1080}</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine("\t\t\t<string>Launch Image</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine("\t\t\t<string>9.0</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine("\t\t\t<string>Landscape</string>"); Text.AppendLine("\t\t</dict>"); 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<string>App Icon</string>"); Text.AppendLine("\t</dict>"); /* 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</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</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", "{375, 667}", * "Default-IPhone6", "Portrait", "{375, 667}", * "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", * "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", * "Default", "Landscape", "{320, 480}", * "Default", "Portrait", "{320, 480}", * "Default-568h", "Landscape", "{320, 568}", * "Default-568h", "Portrait", "{320, 568}", * }; * * Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); * Text.AppendLine("\t<array>"); * for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3) * { * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>8.0</string>"); * 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>"); * } * Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * 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)); * 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); * } * } * }*/ // write the iCloud container identifier, if present in the old file if (!string.IsNullOrEmpty(OldPListData)) { int index = OldPListData.IndexOf("ICloudContainerIdentifier"); if (index > 0) { index = OldPListData.IndexOf("<string>", index) + 8; int length = OldPListData.IndexOf("</string>", index) - index; string ICloudContainerIdentifier = OldPListData.Substring(index, length); Text.AppendLine("\t<key>ICloudContainerIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", ICloudContainerIdentifier)); } } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (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 = ""; 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 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 ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFile), Platform); string MinVersion = "IOS_8"; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarningOnce("IOS 6 is no longer supported in UE4 as 4.11"); RunTimeIOSVersion = "8.0"; break; case "IOS_7": Log.TraceWarningOnce("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"; } NonShippingArchitectures = String.Join(",", GetNonShippingArchitectures(Ini)); ShippingArchitectures = String.Join(",", GetShippingArchitectures(Ini)); // 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; }
/// <summary> /// checks if the sdk is installed or has been synced /// </summary> /// <returns></returns> private bool HasAnySDK() { string NDKPath = Environment.GetEnvironmentVariable("NDKROOT"); { ConfigHierarchy configCacheIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, (DirectoryReference)null, UnrealTargetPlatform.Unknown); Dictionary <string, string> 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 (KeyValuePair <string, string> kvp in EnvVarNames) { if (GetPath(configCacheIni, "/Script/AndroidPlatformEditor.AndroidSDKSettings", kvp.Value, out path) && !string.IsNullOrEmpty(path)) { AndroidEnv.Add(kvp.Key, path); } else { string 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 (KeyValuePair <string, string> 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 (KeyValuePair <string, string> 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); }
/// <summary> /// Checks if the editor is currently running and this is a hot-reload /// </summary> public static bool ShouldDoHotReloadFromIDE(BuildConfiguration BuildConfiguration, TargetDescriptor TargetDesc) { // Check if Hot-reload is disabled globally for this project ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(TargetDesc.ProjectFile), TargetDesc.Platform); bool bAllowHotReloadFromIDE; if (Hierarchy.TryGetValue("BuildConfiguration", "bAllowHotReloadFromIDE", out bAllowHotReloadFromIDE) && !bAllowHotReloadFromIDE) { return(false); } if (!BuildConfiguration.bAllowHotReloadFromIDE) { return(false); } // Check if we're using LiveCode instead ConfigHierarchy EditorPerProjectHierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.EditorPerProjectUserSettings, DirectoryReference.FromFile(TargetDesc.ProjectFile), TargetDesc.Platform); bool bEnableLiveCode; if (EditorPerProjectHierarchy.GetBool("/Script/LiveCoding.LiveCodingSettings", "bEnabled", out bEnableLiveCode) && bEnableLiveCode) { return(false); } bool bIsRunning = false; // @todo ubtmake: Kind of cheating here to figure out if an editor target. At this point we don't have access to the actual target description, and // this code must be able to execute before we create or load module rules DLLs so that hot reload can work with bUseUBTMakefiles if (TargetDesc.Name.EndsWith("Editor", StringComparison.OrdinalIgnoreCase)) { string EditorBaseFileName = "UE4Editor"; if (TargetDesc.Configuration != UnrealTargetConfiguration.Development) { EditorBaseFileName = String.Format("{0}-{1}-{2}", EditorBaseFileName, TargetDesc.Platform, TargetDesc.Configuration); } FileReference EditorLocation; if (TargetDesc.Platform == UnrealTargetPlatform.Win64) { EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Win64", String.Format("{0}.exe", EditorBaseFileName)); } else if (TargetDesc.Platform == UnrealTargetPlatform.Mac) { EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Mac", String.Format("{0}.app/Contents/MacOS/{0}", EditorBaseFileName)); } else if (TargetDesc.Platform == UnrealTargetPlatform.Linux) { EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Linux", EditorBaseFileName); } else { throw new BuildException("Unknown editor filename for this platform"); } using (Timeline.ScopeEvent("Finding editor processes for hot-reload")) { DirectoryReference EditorRunsDir = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "EditorRuns"); if (!DirectoryReference.Exists(EditorRunsDir)) { return(false); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64) { foreach (FileReference EditorInstanceFile in DirectoryReference.EnumerateFiles(EditorRunsDir)) { int ProcessId; if (!Int32.TryParse(EditorInstanceFile.GetFileName(), out ProcessId)) { FileReference.Delete(EditorInstanceFile); continue; } Process RunningProcess; try { RunningProcess = Process.GetProcessById(ProcessId); } catch { RunningProcess = null; } if (RunningProcess == null) { FileReference.Delete(EditorInstanceFile); continue; } FileReference MainModuleFile; try { MainModuleFile = new FileReference(RunningProcess.MainModule.FileName); } catch { MainModuleFile = null; } if (!bIsRunning && EditorLocation == MainModuleFile) { bIsRunning = true; } } } else { FileInfo[] EditorRunsFiles = new DirectoryInfo(EditorRunsDir.FullName).GetFiles(); BuildHostPlatform.ProcessInfo[] Processes = BuildHostPlatform.Current.GetProcesses(); foreach (FileInfo File in EditorRunsFiles) { int PID; BuildHostPlatform.ProcessInfo Proc = null; if (!Int32.TryParse(File.Name, out PID) || (Proc = Processes.FirstOrDefault(P => P.PID == PID)) == default(BuildHostPlatform.ProcessInfo)) { // Delete stale files (it may happen if editor crashes). File.Delete(); continue; } // Don't break here to allow clean-up of other stale files. if (!bIsRunning) { // Otherwise check if the path matches. bIsRunning = new FileReference(Proc.Filename) == EditorLocation; } } } } } return(bIsRunning); }
/// <summary> /// Parse crypto settings from INI file /// </summary> public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform) { CryptoSettings Settings = new CryptoSettings(); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform); Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired); // For now, we'll just not parse any keys if data crypto is disabled for this platform. In the future, we might want to use // these keys for non-data purposes (other general purpose encryption maybe?) if (!Settings.bDataCryptoRequired) { return(Settings); } { // Start by parsing the legacy encryption.ini settings Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform); Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning); string[] SigningKeyStrings = new string[3]; Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]); Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]); Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]); if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2])) { SigningKeyStrings = null; } else { Settings.SigningKey = new SigningKeyPair(); Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(SigningKeyStrings[0]); Settings.SigningKey.PrivateKey.Modulus = ParseHexStringToByteArray(SigningKeyStrings[1]); Settings.SigningKey.PublicKey.Exponent = ParseHexStringToByteArray(SigningKeyStrings[2]); Settings.SigningKey.PublicKey.Modulus = Settings.SigningKey.PrivateKey.Modulus; } Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption); Settings.bEnablePakFullAssetEncryption = false; Settings.bEnablePakUAssetEncryption = false; Settings.bEnablePakIniEncryption = Settings.bEnablePakIndexEncryption; string EncryptionKeyString; Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString); Settings.EncryptionKey = new EncryptionKey(); Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString); } Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform); string SectionName = "/Script/CryptoKeys.CryptoKeysSettings"; ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName); // If we have new format crypto keys, read them in over the top of the legacy settings if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0) { Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning); Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption); Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption); Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption); Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption); // Parse encryption key string EncryptionKeyString; Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString); if (!string.IsNullOrEmpty(EncryptionKeyString)) { Settings.EncryptionKey = new EncryptionKey(); Settings.EncryptionKey.Key = System.Convert.FromBase64String(EncryptionKeyString); if (Settings.EncryptionKey.Key.Length != 32) { throw new Exception("The encryption key specified in the crypto config file must be 32 bytes long!"); } } // Parse signing key string PrivateExponent, PublicExponent, Modulus; Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent); Ini.GetString(SectionName, "SigningModulus", out Modulus); Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent); if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus)) { Settings.SigningKey = new SigningKeyPair(); Settings.SigningKey.PublicKey.Exponent = System.Convert.FromBase64String(PublicExponent); Settings.SigningKey.PublicKey.Modulus = System.Convert.FromBase64String(Modulus); Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent); Settings.SigningKey.PrivateKey.Modulus = Settings.SigningKey.PublicKey.Modulus; } } return(Settings); }
private ConfigHierarchy GetConfigCacheIni(ConfigHierarchyType Type) { return(ConfigCache.ReadHierarchy(Type, DirectoryReference.FromFile(ProjectFile), UnrealTargetPlatform.Lumin)); }
/// <summary> /// Setup the target environment for building /// </summary> /// <param name="Target">Settings for the target being compiled</param> /// <param name="CompileEnvironment">The compile environment for this target</param> /// <param name="LinkEnvironment">The link environment for this target</param> public override void SetUpEnvironment(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment) { CompileEnvironment.Definitions.Add("WIN32=1"); if (WindowsPlatform.bUseWindowsSDK10) { // Windows 8 or higher required CompileEnvironment.Definitions.Add("_WIN32_WINNT=0x0602"); CompileEnvironment.Definitions.Add("WINVER=0x0602"); } else { // Windows 7 or higher required CompileEnvironment.Definitions.Add("_WIN32_WINNT=0x0601"); CompileEnvironment.Definitions.Add("WINVER=0x0601"); } CompileEnvironment.Definitions.Add("PLATFORM_WINDOWS=1"); CompileEnvironment.Definitions.Add("DEPTH_32_BIT_CONVERSION=0"); FileReference MorpheusShaderPath = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Shaders", "PS4", "PostProcessHMDMorpheus.usf"); if (FileReference.Exists(MorpheusShaderPath)) { CompileEnvironment.Definitions.Add("HAS_MORPHEUS=1"); //on PS4 the SDK now handles distortion correction. On PC we will still have to handle it manually, CompileEnvironment.Definitions.Add("MORPHEUS_ENGINE_DISTORTION=1"); } // Add path to Intel math libraries when using ICL based on target platform if (WindowsPlatform.bCompileWithICL) { var Result = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "IntelSWTools", "compilers_and_libraries", "windows", "compiler", "lib", Target.Platform == UnrealTargetPlatform.Win32 ? "ia32" : "intel64"); if (!Directory.Exists(Result)) { throw new BuildException("ICL was selected but the required math libraries were not found. Could not find: " + Result); } LinkEnvironment.LibraryPaths.Add(Result); } // Explicitly exclude the MS C++ runtime libraries we're not using, to ensure other libraries we link with use the same // runtime library as the engine. bool bUseDebugCRT = Target.Configuration == UnrealTargetConfiguration.Debug && Target.bDebugBuildsActuallyUseDebugCRT; if (!Target.bUseStaticCRT || bUseDebugCRT) { LinkEnvironment.ExcludedLibraries.Add("LIBCMT"); LinkEnvironment.ExcludedLibraries.Add("LIBCPMT"); } if (!Target.bUseStaticCRT || !bUseDebugCRT) { LinkEnvironment.ExcludedLibraries.Add("LIBCMTD"); LinkEnvironment.ExcludedLibraries.Add("LIBCPMTD"); } if (Target.bUseStaticCRT || bUseDebugCRT) { LinkEnvironment.ExcludedLibraries.Add("MSVCRT"); LinkEnvironment.ExcludedLibraries.Add("MSVCPRT"); } if (Target.bUseStaticCRT || !bUseDebugCRT) { LinkEnvironment.ExcludedLibraries.Add("MSVCRTD"); LinkEnvironment.ExcludedLibraries.Add("MSVCPRTD"); } LinkEnvironment.ExcludedLibraries.Add("LIBC"); LinkEnvironment.ExcludedLibraries.Add("LIBCP"); LinkEnvironment.ExcludedLibraries.Add("LIBCD"); LinkEnvironment.ExcludedLibraries.Add("LIBCPD"); //@todo ATL: Currently, only VSAccessor requires ATL (which is only used in editor builds) // When compiling games, we do not want to include ATL - and we can't when compiling games // made with Launcher build due to VS 2012 Express not including ATL. // If more modules end up requiring ATL, this should be refactored into a BuildTarget flag (bNeedsATL) // that is set by the modules the target includes to allow for easier tracking. // Alternatively, if VSAccessor is modified to not require ATL than we should always exclude the libraries. if (Target.LinkType == TargetLinkType.Monolithic && (Target.Type == TargetType.Game || Target.Type == TargetType.Client || Target.Type == TargetType.Server)) { LinkEnvironment.ExcludedLibraries.Add("atl"); LinkEnvironment.ExcludedLibraries.Add("atls"); LinkEnvironment.ExcludedLibraries.Add("atlsd"); LinkEnvironment.ExcludedLibraries.Add("atlsn"); LinkEnvironment.ExcludedLibraries.Add("atlsnd"); } // Add the library used for the delayed loading of DLLs. LinkEnvironment.AdditionalLibraries.Add("delayimp.lib"); //@todo - remove once FB implementation uses Http module if (Target.bCompileAgainstEngine) { // link against wininet (used by FBX and Facebook) LinkEnvironment.AdditionalLibraries.Add("wininet.lib"); } // Compile and link with Win32 API libraries. LinkEnvironment.AdditionalLibraries.Add("rpcrt4.lib"); //LinkEnvironment.AdditionalLibraries.Add("wsock32.lib"); LinkEnvironment.AdditionalLibraries.Add("ws2_32.lib"); LinkEnvironment.AdditionalLibraries.Add("dbghelp.lib"); LinkEnvironment.AdditionalLibraries.Add("comctl32.lib"); LinkEnvironment.AdditionalLibraries.Add("Winmm.lib"); LinkEnvironment.AdditionalLibraries.Add("kernel32.lib"); LinkEnvironment.AdditionalLibraries.Add("user32.lib"); LinkEnvironment.AdditionalLibraries.Add("gdi32.lib"); LinkEnvironment.AdditionalLibraries.Add("winspool.lib"); LinkEnvironment.AdditionalLibraries.Add("comdlg32.lib"); LinkEnvironment.AdditionalLibraries.Add("advapi32.lib"); LinkEnvironment.AdditionalLibraries.Add("shell32.lib"); LinkEnvironment.AdditionalLibraries.Add("ole32.lib"); LinkEnvironment.AdditionalLibraries.Add("oleaut32.lib"); LinkEnvironment.AdditionalLibraries.Add("uuid.lib"); LinkEnvironment.AdditionalLibraries.Add("odbc32.lib"); LinkEnvironment.AdditionalLibraries.Add("odbccp32.lib"); LinkEnvironment.AdditionalLibraries.Add("netapi32.lib"); LinkEnvironment.AdditionalLibraries.Add("iphlpapi.lib"); LinkEnvironment.AdditionalLibraries.Add("setupapi.lib"); // Required for access monitor device enumeration // Windows Vista/7 Desktop Windows Manager API for Slate Windows Compliance LinkEnvironment.AdditionalLibraries.Add("dwmapi.lib"); // IME LinkEnvironment.AdditionalLibraries.Add("imm32.lib"); // For 64-bit builds, we'll forcibly ignore a linker warning with DirectInput. This is // Microsoft's recommended solution as they don't have a fixed .lib for us. if (Target.Platform == UnrealTargetPlatform.Win64) { LinkEnvironment.AdditionalArguments += " /ignore:4078"; } if (Target.Type != TargetType.Editor) { if (!string.IsNullOrEmpty(Target.WindowsPlatform.CompanyName)) { CompileEnvironment.Definitions.Add(String.Format("PROJECT_COMPANY_NAME={0}", Target.WindowsPlatform.CompanyName)); } if (!string.IsNullOrEmpty(Target.WindowsPlatform.CopyrightNotice)) { CompileEnvironment.Definitions.Add(String.Format("PROJECT_COPYRIGHT_STRING={0}", Target.WindowsPlatform.CopyrightNotice)); } if (!string.IsNullOrEmpty(Target.WindowsPlatform.ProductName)) { CompileEnvironment.Definitions.Add(String.Format("PROJECT_PRODUCT_NAME={0}", Target.WindowsPlatform.ProductName)); } if (Target.ProjectFile != null) { CompileEnvironment.Definitions.Add(String.Format("PROJECT_PRODUCT_IDENTIFIER={0}", Target.ProjectFile.GetFileNameWithoutExtension())); } } // Set up default stack size ConfigHierarchy EngineIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(Target.ProjectFile), UnrealTargetPlatform.Win64); String TargetSettingsIniPath = "/Script/WindowsTargetPlatform.WindowsTargetSettings"; int IniDefaultStackSize = 0; String StackSizeName = Target.Type == TargetType.Editor ? "DefaultStackSizeEditor" : "DefaultStackSize"; if (EngineIni.GetInt32(TargetSettingsIniPath, StackSizeName, out IniDefaultStackSize)) { LinkEnvironment.DefaultStackSize = IniDefaultStackSize; } int IniDefaultStackSizeCommit = 0; String StackSizeCommitName = Target.Type == TargetType.Editor ? "DefaultStackSizeCommitEditor" : "DefaultStackSizeCommit"; if (EngineIni.GetInt32(TargetSettingsIniPath, StackSizeCommitName, out IniDefaultStackSizeCommit)) { LinkEnvironment.DefaultStackSizeCommit = IniDefaultStackSizeCommit; } }
/// <summary> /// Constructor /// </summary> /// <param name="ProjectFile">Project to read settings from</param> public RemoteMac(FileReference ProjectFile) { this.RsyncExe = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Rsync.exe"); this.SshExe = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Ssh.exe"); this.ProjectFile = ProjectFile; this.ProjectDirectory = DirectoryReference.FromFile(ProjectFile); // Apply settings from the XML file XmlConfig.ApplyTo(this); // Get the project config file path DirectoryReference EngineIniPath = ProjectFile != null ? ProjectFile.Directory : null; if (EngineIniPath == null && UnrealBuildTool.GetRemoteIniPath() != null) { EngineIniPath = new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()); } ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, EngineIniPath, UnrealTargetPlatform.IOS); // Read the project settings if we don't have anything in the build configuration settings if (String.IsNullOrEmpty(ServerName)) { // Read the server name string IniServerName; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RemoteServerName", out IniServerName) && !String.IsNullOrEmpty(IniServerName)) { this.ServerName = IniServerName; } else { throw new BuildException("Remote compiling requires a server name. Use the editor (Project Settings > IOS) to set up your remote compilation settings."); } // Parse the username string IniUserName; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RSyncUsername", out IniUserName) && !String.IsNullOrEmpty(IniUserName)) { this.UserName = IniUserName; } } // Split port out from the server name int PortIdx = ServerName.LastIndexOf(':'); if (PortIdx != -1) { string Port = ServerName.Substring(PortIdx + 1); if (!int.TryParse(Port, out ServerPort)) { throw new BuildException("Unable to parse port number from '{0}'", ServerName); } ServerName = ServerName.Substring(0, PortIdx); } // If a user name is not set, use the current user if (String.IsNullOrEmpty(UserName)) { UserName = Environment.UserName; } // Print out the server info Log.TraceInformation("[Remote] Using remote server '{0}' on port {1} (user '{2}')", ServerName, ServerPort, UserName); // Get the path to the SSH private key string OverrideSshPrivateKeyPath; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SSHPrivateKeyOverridePath", out OverrideSshPrivateKeyPath) && !String.IsNullOrEmpty(OverrideSshPrivateKeyPath)) { SshPrivateKey = new FileReference(OverrideSshPrivateKeyPath); if (!FileReference.Exists(SshPrivateKey)) { throw new BuildException("SSH private key specified in config file ({0}) does not exist.", SshPrivateKey); } } // If it's not set, look in the standard locations. If that fails, spawn the batch file to generate one. if (SshPrivateKey == null && !TryGetSshPrivateKey(out SshPrivateKey)) { Log.TraceWarning("No SSH private key found for {0}@{1}. Launching SSH to generate one.", UserName, ServerName); StringBuilder CommandLine = new StringBuilder(); CommandLine.AppendFormat("/C \"\"{0}\"", FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "BatchFiles", "MakeAndInstallSSHKey.bat")); CommandLine.AppendFormat(" \"{0}\"", SshExe); CommandLine.AppendFormat(" \"{0}\"", ServerPort); CommandLine.AppendFormat(" \"{0}\"", RsyncExe); CommandLine.AppendFormat(" \"{0}\"", UserName); CommandLine.AppendFormat(" \"{0}\"", ServerName); CommandLine.AppendFormat(" \"{0}\"", DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments)); CommandLine.AppendFormat(" \"{0}\"", GetLocalCygwinPath(DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments))); CommandLine.AppendFormat(" \"{0}\"", UnrealBuildTool.EngineDirectory); CommandLine.Append("\""); using (Process ChildProcess = Process.Start("C:\\Windows\\System32\\Cmd.exe", CommandLine.ToString())) { ChildProcess.WaitForExit(); } if (!TryGetSshPrivateKey(out SshPrivateKey)) { throw new BuildException("Failed to generate SSH private key for {0}@{1}.", UserName, ServerName); } } // resolve the rest of the strings RsyncAuthentication = ExpandVariables(RsyncAuthentication); SshAuthentication = ExpandVariables(SshAuthentication); // Get the remote base directory RemoteBaseDir = String.Format("/Users/{0}/UE4/Builds/{1}", UserName, Environment.MachineName); // Build the list of directory mappings between the local and remote machines Mappings = new List <RemoteMapping>(); Mappings.Add(new RemoteMapping(UnrealBuildTool.EngineDirectory, GetRemotePath(UnrealBuildTool.EngineDirectory))); if (ProjectFile != null && !ProjectFile.IsUnderDirectory(UnrealBuildTool.EngineDirectory)) { Mappings.Add(new RemoteMapping(ProjectFile.Directory, GetRemotePath(ProjectFile.Directory))); } // Build a list of arguments for SSH CommonSshArguments = new List <string>(); CommonSshArguments.Add("-o BatchMode=yes"); CommonSshArguments.Add(SshAuthentication); CommonSshArguments.Add(String.Format("-p {0}", ServerPort)); CommonSshArguments.Add(String.Format("\"{0}@{1}\"", UserName, ServerName)); // Build a list of arguments for Rsync CommonRsyncArguments = new List <string>(); CommonRsyncArguments.Add("--compress"); CommonRsyncArguments.Add("--recursive"); CommonRsyncArguments.Add("--delete"); // Delete anything not in the source directory CommonRsyncArguments.Add("--delete-excluded"); // Delete anything not in the source directory CommonRsyncArguments.Add("--times"); // Preserve modification times CommonRsyncArguments.Add("--verbose"); CommonRsyncArguments.Add("-m"); CommonRsyncArguments.Add("--chmod=ug=rwX,o=rxX"); CommonRsyncArguments.Add(String.Format("--rsh=\"{0} -p {1}\"", RsyncAuthentication, ServerPort)); }
private ConfigHierarchy GetConfigCacheIni(ConfigHierarchyType Type) { // @todo Lumin: So - this is the problem with subclassing a platform currently - ini files. Lumin will use Android ini files // until I finish and get code over from another branch (key letter Q) that allows for insertion of a subclassed ini platform thing return(ConfigCache.ReadHierarchy(Type, DirectoryReference.FromFile(ProjectFile), UnrealTargetPlatform.Android)); }
/// <summary> /// Parse crypto settings from INI file /// </summary> public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform) { CryptoSettings Settings = new CryptoSettings(); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform); Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired); Ini.GetBool("PlatformCrypto", "PakSigningRequired", out Settings.PakSigningRequired); Ini.GetBool("PlatformCrypto", "PakEncryptionRequired", out Settings.PakEncryptionRequired); { // Start by parsing the legacy encryption.ini settings Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform); Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning); string[] SigningKeyStrings = new string[3]; Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]); Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]); Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]); if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2])) { SigningKeyStrings = null; } else { Settings.SigningKey = new SigningKeyPair(); Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[0]), 64); Settings.SigningKey.PrivateKey.Modulus = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[1]), 64); Settings.SigningKey.PublicKey.Exponent = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[2]), 64); Settings.SigningKey.PublicKey.Modulus = Settings.SigningKey.PrivateKey.Modulus; if ((Settings.SigningKey.PrivateKey.Exponent.Length > 64) || (Settings.SigningKey.PrivateKey.Modulus.Length > 64) || (Settings.SigningKey.PublicKey.Exponent.Length > 64) || (Settings.SigningKey.PublicKey.Modulus.Length > 64)) { throw new Exception(string.Format("[{0}] Signing keys parsed from encryption.ini are too long. They must be a maximum of 64 bytes long!", InProjectDirectory)); } } Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption); Settings.bEnablePakFullAssetEncryption = false; Settings.bEnablePakUAssetEncryption = false; Settings.bEnablePakIniEncryption = Settings.bEnablePakIndexEncryption; string EncryptionKeyString; Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString); Settings.EncryptionKey = new EncryptionKey(); if (EncryptionKeyString.Length > 0) { if (EncryptionKeyString.Length < 32) { Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too short. It must be 32 bytes, so will be padded with 0s, giving sub-optimal security!"); } else if (EncryptionKeyString.Length > 32) { Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too long. It must be 32 bytes, so will be truncated!"); } Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString, 32); } } Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform); string SectionName = "/Script/CryptoKeys.CryptoKeysSettings"; ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName); // If we have new format crypto keys, read them in over the top of the legacy settings if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0) { Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning); Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption); Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption); Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption); Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption); // Parse encryption key string EncryptionKeyString; Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString); if (!string.IsNullOrEmpty(EncryptionKeyString)) { Settings.EncryptionKey = new EncryptionKey(); Settings.EncryptionKey.Key = System.Convert.FromBase64String(EncryptionKeyString); Settings.EncryptionKey.Guid = Guid.Empty.ToString(); Settings.EncryptionKey.Name = "Embedded"; } // Parse secondary encryption keys List <EncryptionKey> SecondaryEncryptionKeys = new List <EncryptionKey>(); List <string> SecondaryEncryptionKeyStrings; if (Ini.GetArray(SectionName, "SecondaryEncryptionKeys", out SecondaryEncryptionKeyStrings)) { foreach (string KeySource in SecondaryEncryptionKeyStrings) { EncryptionKey NewKey = new EncryptionKey(); SecondaryEncryptionKeys.Add(NewKey); Regex Search = new Regex("\\(Guid=(?\'Guid\'.*),Name=\\\"(?\'Name\'.*)\\\",Key=\\\"(?\'Key\'.*)\\\"\\)"); Match Match = Search.Match(KeySource); if (Match.Success) { foreach (string GroupName in Search.GetGroupNames()) { string Value = Match.Groups[GroupName].Value; if (GroupName == "Guid") { NewKey.Guid = Value; } else if (GroupName == "Name") { NewKey.Name = Value; } else if (GroupName == "Key") { NewKey.Key = System.Convert.FromBase64String(Value); } } } } } Settings.SecondaryEncryptionKeys = SecondaryEncryptionKeys.ToArray(); // Parse signing key string PrivateExponent, PublicExponent, Modulus; Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent); Ini.GetString(SectionName, "SigningModulus", out Modulus); Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent); if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus)) { Settings.SigningKey = new SigningKeyPair(); Settings.SigningKey.PublicKey.Exponent = System.Convert.FromBase64String(PublicExponent); Settings.SigningKey.PublicKey.Modulus = System.Convert.FromBase64String(Modulus); Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent); Settings.SigningKey.PrivateKey.Modulus = Settings.SigningKey.PublicKey.Modulus; } } // Parse project dynamic keychain keys if (InProjectDirectory != null) { ConfigHierarchy GameIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, InProjectDirectory, InTargetPlatform); if (GameIni != null) { string Filename; if (GameIni.GetString("ContentEncryption", "ProjectKeyChain", out Filename)) { FileReference ProjectKeyChainFile = FileReference.Combine(InProjectDirectory, "Content", Filename); if (FileReference.Exists(ProjectKeyChainFile)) { List <EncryptionKey> EncryptionKeys = new List <EncryptionKey>(); if (Settings.SecondaryEncryptionKeys != null) { EncryptionKeys.AddRange(Settings.SecondaryEncryptionKeys); } string[] Lines = FileReference.ReadAllLines(ProjectKeyChainFile); foreach (string Line in Lines) { string[] KeyParts = Line.Split(':'); if (KeyParts.Length == 4) { EncryptionKey NewKey = new EncryptionKey(); NewKey.Name = KeyParts[0]; NewKey.Guid = KeyParts[2]; NewKey.Key = System.Convert.FromBase64String(KeyParts[3]); EncryptionKey ExistingKey = EncryptionKeys.Find((EncryptionKey OtherKey) => { return(OtherKey.Guid == NewKey.Guid); }); if (ExistingKey != null && !CompareKey(ExistingKey.Key, NewKey.Key)) { throw new Exception("Found multiple encryption keys with the same guid but different AES keys while merging secondary keys from the project key-chain!"); } EncryptionKeys.Add(NewKey); } } Settings.SecondaryEncryptionKeys = EncryptionKeys.ToArray(); } } } } if (!Settings.bDataCryptoRequired) { CryptoSettings NewSettings = new CryptoSettings(); NewSettings.SecondaryEncryptionKeys = Settings.SecondaryEncryptionKeys; Settings = NewSettings; } else { if (!Settings.PakSigningRequired) { Settings.bEnablePakSigning = false; Settings.SigningKey = null; } if (!Settings.PakEncryptionRequired) { Settings.bEnablePakFullAssetEncryption = false; Settings.bEnablePakIndexEncryption = false; Settings.bEnablePakIniEncryption = false; Settings.EncryptionKey = null; Settings.SigningKey = null; } } // Check if we have a valid signing key that is of the old short form if (Settings.SigningKey != null && Settings.SigningKey.IsValid() && Settings.SigningKey.IsUnsecureLegacyKey()) { Log.TraceWarningOnce("Project signing keys found in '{0}' are of the old insecure short format. Please regenerate them using the project crypto settings panel in the editor!", InProjectDirectory); } // Validate the settings we have read if (Settings.bDataCryptoRequired && Settings.bEnablePakSigning && (Settings.SigningKey == null || !Settings.SigningKey.IsValid())) { Log.TraceWarningOnce("Pak signing is enabled, but no valid signing keys were found. Please generate a key in the editor project crypto settings. Signing will be disabled"); Settings.bEnablePakSigning = false; } if (Settings.bDataCryptoRequired && Settings.IsAnyEncryptionEnabled() && (Settings.EncryptionKey == null || !Settings.EncryptionKey.IsValid())) { Log.TraceWarningOnce("Pak encryption is enabled, but no valid encryption key was found. Please generate a key in the editor project crypto settings. Encryption will be disabled"); Settings.bEnablePakUAssetEncryption = false; Settings.bEnablePakFullAssetEncryption = false; Settings.bEnablePakIndexEncryption = false; Settings.bEnablePakIniEncryption = false; } return(Settings); }