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 }
/** * Whether the required external SDKs are installed for this platform */ protected override SDKStatus HasRequiredManualSDKInternal() { // if any autosdk setup has been done then the local process environment is suspect if (HasSetupAutoSDK()) { return(SDKStatus.Invalid); } if (!HTML5SDKInfo.IsSDKInstalled()) { return(SDKStatus.Invalid); } try { int InstalledVersion = Convert.ToInt32(HTML5SDKInfo.EmscriptenVersion().Replace(".", "")); int RequiredVersion = Convert.ToInt32(GetRequiredSDKString().Replace(".", "")); if (InstalledVersion >= RequiredVersion) { return(SDKStatus.Valid); } else { Console.WriteLine("EMSCRIPTEN sdk " + HTML5SDKInfo.EmscriptenVersion() + " found which is older than " + RequiredVersion + " Please install the latest emscripten SDK"); return(SDKStatus.Invalid); } } catch (Exception /*ex*/) { return(SDKStatus.Invalid); } }
/** * Returns SDK string as required by the platform * * @return Valid SDK string */ protected override string GetRequiredSDKString() { if (HTML5SDKInfo.IsSDKVersionOverridden()) { return(HTML5SDKInfo.OverriddenSDKVersion()); } return(ExpectedSDKVersion); }
// cache the location of SDK tools public HTML5ToolChain() : base(CPPTargetPlatform.HTML5, false) { if (!HTML5SDKInfo.IsSDKInstalled()) { throw new BuildException("HTML5 SDK is not installed; cannot use toolchain."); } }
public static string EmscriptenVersion() { string BaseSDKPath = HTML5SDKInfo.EmscriptenSDKPath(); string VersionInfo = File.ReadAllText(Path.Combine(BaseSDKPath, "emscripten-version.txt")); VersionInfo = VersionInfo.Trim(); return(VersionInfo); }
// cache the location of SDK tools public HTML5ToolChain() : base(CppPlatform.HTML5, WindowsCompiler.VisualStudio2015) { if (!HTML5SDKInfo.IsSDKInstalled()) { throw new BuildException("HTML5 SDK is not installed; cannot use toolchain."); } }
/// <summary> /// Whether the required external SDKs are installed for this platform /// </summary> protected override SDKStatus HasRequiredManualSDKInternal() { if (!HTML5SDKInfo.IsSDKInstalled()) { return(SDKStatus.Invalid); } return(SDKStatus.Valid); }
public override void PreBuildSync() { Log.TraceInformation("Setting Emscripten SDK "); HTML5SDKInfo.SetupEmscriptenTemp(); HTML5SDKInfo.SetUpEmscriptenConfigFile(); // set some environment variable we'll need. // Forces emcc to use our generated .emscripten config, not the one in the users home directory. Environment.SetEnvironmentVariable("EM_CONFIG", HTML5SDKInfo.DOT_EMSCRIPTEN); Environment.SetEnvironmentVariable("EM_CACHE", HTML5SDKInfo.EMSCRIPTEN_CACHE); }
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")); }
// cache the location of SDK tools public override void RegisterToolChain() { if (HTML5SDKInfo.IsSDKInstalled()) { // set some environment variable we'll need //Environment.SetEnvironmentVariable("EMCC_DEBUG", "cache"); Environment.SetEnvironmentVariable("EMCC_CORES", "8"); Environment.SetEnvironmentVariable("EMCC_OPTIMIZE_NORMALLY", "1"); // finally register the toolchain that is now ready to go Log.TraceVerbose(" Registered for {0}", CPPTargetPlatform.HTML5.ToString()); UEToolChain.RegisterPlatformToolChain(CPPTargetPlatform.HTML5, this); } }
public static void PreBuildSync() { Log.TraceInformation("Setting Emscripten SDK: located in " + HTML5SDKInfo.EMSCRIPTEN_ROOT); 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); } }
// cache the location of SDK tools public HTML5ToolChain() : base(CPPTargetPlatform.HTML5, false) { if (!HTML5SDKInfo.IsSDKInstalled()) { throw new BuildException("HTML5 SDK is not installed; cannot use toolchain."); } // set some environment variable we'll need // Environment.SetEnvironmentVariable("EMCC_DEBUG", "1"); Environment.SetEnvironmentVariable("EMCC_CORES", "8"); Environment.SetEnvironmentVariable("EMCC_OPTIMIZE_NORMALLY", "1"); }
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; } }
// cache the location of SDK tools public override void RegisterToolChain() { if (HTML5SDKInfo.IsSDKInstalled() && HTML5SDKInfo.IsPythonInstalled()) { EMCCPath = "\"" + HTML5SDKInfo.EmscriptenCompiler() + "\""; PythonPath = HTML5SDKInfo.PythonPath(); // set some environment variable we'll need //Environment.SetEnvironmentVariable("EMCC_DEBUG", "cache"); Environment.SetEnvironmentVariable("EMCC_CORES", "8"); Environment.SetEnvironmentVariable("EMCC_FORCE_STDLIBS", "1"); Environment.SetEnvironmentVariable("EMCC_OPTIMIZE_NORMALLY", "1"); // finally register the toolchain that is now ready to go Log.TraceVerbose(" Registered for {0}", CPPTargetPlatform.HTML5.ToString()); UEToolChain.RegisterPlatformToolChain(CPPTargetPlatform.HTML5, this); } }
static string GetLinkArguments(LinkEnvironment LinkEnvironment) { string Result = GetSharedArguments_Global(LinkEnvironment.Config.Target.Configuration, LinkEnvironment.Config.Target.Architecture); if (LinkEnvironment.Config.Target.Architecture != "-win32") { // enable verbose mode Result += " -v"; if (LinkEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug) { // check for alignment/etc checking //Result += " -s SAFE_HEAP=1"; //Result += " -s CHECK_HEAP_ALIGN=1"; //Result += " -s SAFE_DYNCALLS=1"; // enable assertions in non-Shipping/Release builds Result += " -s ASSERTIONS=1"; } if (LinkEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug) { Result += " -O0"; } if (LinkEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug || LinkEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Development) { Result += " -s GL_ASSERTIONS=1 "; } if (LinkEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Development) { Result += " -O2 -s ASM_JS=1 -s OUTLINING_LIMIT=110000 -g2 "; } if (LinkEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Shipping) { Result += " -O3 -s ASM_JS=1 -s OUTLINING_LIMIT=40000"; } Result += " -s CASE_INSENSITIVE_FS=1 "; string BaseSDKPath = HTML5SDKInfo.EmscriptenSDKPath(); Result += " --js-library \"" + BaseSDKPath + "/Src/library_openal.js\" "; } return(Result); }
/** * Whether the required external SDKs are installed for this platform */ protected override SDKStatus HasRequiredManualSDKInternal() { // if any autosdk setup has been done then the local process environment is suspect if (HasSetupAutoSDK()) { return(SDKStatus.Invalid); } try { if (HTML5SDKInfo.EmscriptenVersion().Contains(ExpectedSDKVersion)) { return(SDKStatus.Valid); } else { Console.WriteLine("EMSCRIPTEN sdk " + HTML5SDKInfo.EmscriptenVersion() + " found which is unsupported, Please install version " + ExpectedSDKVersion); return(SDKStatus.Invalid); } } catch (Exception /*ex*/) { return(SDKStatus.Invalid); } }
/// <summary> /// Returns SDK string as required by the platform /// </summary> /// <returns>Valid SDK string</returns> protected override string GetRequiredSDKString() { return(HTML5SDKInfo.EmscriptenVersion()); }
static string GetVersionInfoPath() { string BaseSDKPath = HTML5SDKInfo.EmscriptenSDKPath(); return(Path.Combine(BaseSDKPath, "emscripten-version.txt")); }
public override FileItem LinkFiles(LinkEnvironment LinkEnvironment, bool bBuildImportLibraryOnly, ActionGraph ActionGraph) { FileItem OutputFile; // Make the final javascript file Action LinkAction = ActionGraph.Add(ActionType.Link); LinkAction.CommandDescription = "Link"; // LinkAction.bPrintDebugInfo = true; // ResponseFile lines. List <string> ReponseLines = new List <string>(); LinkAction.bCanExecuteRemotely = false; LinkAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory.FullName; LinkAction.CommandPath = HTML5SDKInfo.Python(); LinkAction.CommandArguments = HTML5SDKInfo.EmscriptenCompiler(); // bool bIsBuildingLibrary = LinkEnvironment.bIsBuildingLibrary || bBuildImportLibraryOnly; // ReponseLines.Add( // bIsBuildingLibrary ? // GetLibArguments(LinkEnvironment) : // GetLinkArguments(LinkEnvironment) // ); ReponseLines.Add(GetLinkArguments(LinkEnvironment)); // Add the input files to a response file, and pass the response file on the command-line. foreach (FileItem InputFile in LinkEnvironment.InputFiles) { //System.Console.WriteLine("File {0} ", InputFile.AbsolutePath); ReponseLines.Add(string.Format(" \"{0}\"", InputFile.AbsolutePath)); LinkAction.PrerequisiteItems.Add(InputFile); } if (!LinkEnvironment.bIsBuildingLibrary) { // Make sure ThirdParty libs are at the end. List <string> ThirdParty = (from Lib in LinkEnvironment.AdditionalLibraries where Lib.Contains("ThirdParty") select Lib).ToList(); LinkEnvironment.AdditionalLibraries.RemoveAll(Element => Element.Contains("ThirdParty")); LinkEnvironment.AdditionalLibraries.AddRange(ThirdParty); foreach (string InputFile in LinkEnvironment.AdditionalLibraries) { FileItem Item = FileItem.GetItemByPath(InputFile); if (Item.AbsolutePath.Contains(".lib")) { continue; } if (Item.ToString().EndsWith(".js")) { ReponseLines.Add(string.Format(" --js-library \"{0}\"", Item.AbsolutePath)); } // WARNING: With --pre-js and --post-js, the order in which these directives are passed to // the compiler is very critical, because that dictates the order in which they are appended. // // Set environment variable [ EMCC_DEBUG=1 ] to see the linker order used in packaging. // See GetSharedArguments_Global() above to set this environment variable else if (Item.ToString().EndsWith(".jspre")) { ReponseLines.Add(string.Format(" --pre-js \"{0}\"", Item.AbsolutePath)); } else if (Item.ToString().EndsWith(".jspost")) { ReponseLines.Add(string.Format(" --post-js \"{0}\"", Item.AbsolutePath)); } else { ReponseLines.Add(string.Format(" \"{0}\"", Item.AbsolutePath)); } LinkAction.PrerequisiteItems.Add(Item); } } // make the file we will create OutputFile = FileItem.GetItemByFileReference(LinkEnvironment.OutputFilePath); LinkAction.ProducedItems.Add(OutputFile); ReponseLines.Add(string.Format(" -o \"{0}\"", OutputFile.AbsolutePath)); FileItem OutputBC = FileItem.GetItemByPath(LinkEnvironment.OutputFilePath.FullName.Replace(".js", ".bc").Replace(".html", ".bc")); LinkAction.ProducedItems.Add(OutputBC); ReponseLines.Add(string.Format(" --save-bc \"{0}\"", OutputBC.AbsolutePath)); LinkAction.StatusDescription = Path.GetFileName(OutputFile.AbsolutePath); FileReference ResponseFileName = GetResponseFileName(LinkEnvironment, OutputFile); FileItem ResponseFileItem = FileItem.CreateIntermediateTextFile(ResponseFileName, ReponseLines); LinkAction.CommandArguments += string.Format(" @\"{0}\"", ResponseFileName); LinkAction.PrerequisiteItems.Add(ResponseFileItem); return(OutputFile); }
public override CPPOutput CompileCPPFiles(CppCompileEnvironment CompileEnvironment, List <FileItem> InputFiles, DirectoryReference OutputDir, string ModuleName, ActionGraph ActionGraph) { string Arguments = GetCLArguments_Global(CompileEnvironment); CPPOutput Result = new CPPOutput(); // Add include paths to the argument list. foreach (DirectoryReference IncludePath in CompileEnvironment.IncludePaths.UserIncludePaths) { AddIncludePath(ref Arguments, IncludePath); } foreach (DirectoryReference IncludePath in CompileEnvironment.IncludePaths.SystemIncludePaths) { AddIncludePath(ref Arguments, IncludePath); } // Add preprocessor definitions to the argument list. foreach (string Definition in CompileEnvironment.Definitions) { Arguments += string.Format(" -D{0}", Definition); } if (bEnableTracing) { Arguments += string.Format(" -D__EMSCRIPTEN_TRACING__"); } // Force include all the requested headers foreach (FileItem ForceIncludeFile in CompileEnvironment.ForceIncludeFiles) { Arguments += String.Format(" -include \"{0}\"", ForceIncludeFile.Location); } foreach (FileItem SourceFile in InputFiles) { Action CompileAction = ActionGraph.Add(ActionType.Compile); CompileAction.CommandDescription = "Compile"; CompileAction.PrerequisiteItems.AddRange(CompileEnvironment.ForceIncludeFiles); // CompileAction.bPrintDebugInfo = true; bool bIsPlainCFile = Path.GetExtension(SourceFile.AbsolutePath).ToUpperInvariant() == ".C"; // Add the C++ source file and its included files to the prerequisite item list. AddPrerequisiteSourceFile(CompileEnvironment, SourceFile, CompileAction.PrerequisiteItems); // Add the source file path to the command-line. string FileArguments = string.Format(" \"{0}\"", SourceFile.AbsolutePath); string ObjectFileExtension = UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.HTML5).GetBinaryExtension(UEBuildBinaryType.Object); // Add the object file to the produced item list. FileItem ObjectFile = FileItem.GetItemByFileReference( FileReference.Combine( OutputDir, Path.GetFileName(SourceFile.AbsolutePath) + ObjectFileExtension ) ); CompileAction.ProducedItems.Add(ObjectFile); FileArguments += string.Format(" -o \"{0}\"", ObjectFile.AbsolutePath); // Add C or C++ specific compiler arguments. if (bIsPlainCFile) { FileArguments += GetCLArguments_C(CompileEnvironment.Architecture); } else { FileArguments += GetCLArguments_CPP(CompileEnvironment); } CompileAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory.FullName; CompileAction.CommandPath = HTML5SDKInfo.Python(); CompileAction.CommandArguments = HTML5SDKInfo.EmscriptenCompiler() + " " + Arguments + FileArguments + CompileEnvironment.AdditionalArguments; //System.Console.WriteLine(CompileAction.CommandArguments); CompileAction.StatusDescription = Path.GetFileName(SourceFile.AbsolutePath); // Don't farm out creation of precomputed headers as it is the critical path task. CompileAction.bCanExecuteRemotely = CompileEnvironment.PrecompiledHeaderAction != PrecompiledHeaderAction.Create; // this is the final output of the compile step (a .abc file) Result.ObjectFiles.Add(ObjectFile); // VC++ always outputs the source file name being compiled, so we don't need to emit this ourselves CompileAction.bShouldOutputStatusDescription = true; // Don't farm out creation of precompiled headers as it is the critical path task. CompileAction.bCanExecuteRemotely = CompileEnvironment.PrecompiledHeaderAction != PrecompiledHeaderAction.Create || CompileEnvironment.bAllowRemotelyCompiledPCHs; } return(Result); }
public override FileItem LinkFiles(LinkEnvironment LinkEnvironment, bool bBuildImportLibraryOnly) { if (LinkEnvironment.Config.Target.Architecture == "-win32") // simulator { return(base.LinkFiles(LinkEnvironment, bBuildImportLibraryOnly)); } FileItem OutputFile; // Make the final javascript file Action LinkAction = new Action(ActionType.Link); // ResponseFile lines. List <string> ReponseLines = new List <string>(); LinkAction.bCanExecuteRemotely = false; LinkAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory.FullName; LinkAction.CommandPath = HTML5SDKInfo.Python(); LinkAction.CommandArguments = HTML5SDKInfo.EmscriptenCompiler(); ReponseLines.Add(GetLinkArguments(LinkEnvironment)); // Add the input files to a response file, and pass the response file on the command-line. foreach (FileItem InputFile in LinkEnvironment.InputFiles) { //System.Console.WriteLine("File {0} ", InputFile.AbsolutePath); ReponseLines.Add(string.Format(" \"{0}\"", InputFile.AbsolutePath)); LinkAction.PrerequisiteItems.Add(InputFile); } if (!LinkEnvironment.Config.bIsBuildingLibrary) { // Make sure ThirdParty libs are at the end. List <string> ThirdParty = (from Lib in LinkEnvironment.Config.AdditionalLibraries where Lib.Contains("ThirdParty") select Lib).ToList(); LinkEnvironment.Config.AdditionalLibraries.RemoveAll(Element => Element.Contains("ThirdParty")); LinkEnvironment.Config.AdditionalLibraries.AddRange(ThirdParty); foreach (string InputFile in LinkEnvironment.Config.AdditionalLibraries) { FileItem Item = FileItem.GetItemByPath(InputFile); if (Item.AbsolutePath.Contains(".lib")) { continue; } if (Item != null) { if (Item.ToString().Contains(".js")) { ReponseLines.Add(string.Format(" --js-library \"{0}\"", Item.AbsolutePath)); } else { ReponseLines.Add(string.Format(" \"{0}\"", Item.AbsolutePath)); } LinkAction.PrerequisiteItems.Add(Item); } } } // make the file we will create OutputFile = FileItem.GetItemByFileReference(LinkEnvironment.Config.OutputFilePath); LinkAction.ProducedItems.Add(OutputFile); ReponseLines.Add(string.Format(" -o \"{0}\"", OutputFile.AbsolutePath)); FileItem OutputBC = FileItem.GetItemByPath(LinkEnvironment.Config.OutputFilePath.FullName.Replace(".js", ".bc").Replace(".html", ".bc")); LinkAction.ProducedItems.Add(OutputBC); ReponseLines.Add(" --emit-symbol-map " + string.Format(" --save-bc \"{0}\"", OutputBC.AbsolutePath)); LinkAction.StatusDescription = Path.GetFileName(OutputFile.AbsolutePath); FileReference ResponseFileName = GetResponseFileName(LinkEnvironment, OutputFile); LinkAction.CommandArguments += string.Format(" @\"{0}\"", ResponseFile.Create(ResponseFileName, ReponseLines)); LinkAction.OutputEventHandler = new DataReceivedEventHandler(RemoteOutputReceivedEventHandler); return(OutputFile); }
public override CPPOutput CompileCPPFiles(UEBuildTarget Target, CPPEnvironment CompileEnvironment, List <FileItem> SourceFiles, string ModuleName) { if (CompileEnvironment.Config.Target.Architecture == "-win32") // simulator { return(base.CompileCPPFiles(Target, CompileEnvironment, SourceFiles, ModuleName)); } string Arguments = GetCLArguments_Global(CompileEnvironment); CPPOutput Result = new CPPOutput(); // Add include paths to the argument list. foreach (string IncludePath in CompileEnvironment.Config.CPPIncludeInfo.IncludePaths) { Arguments += string.Format(" -I\"{0}\"", IncludePath); } foreach (string IncludePath in CompileEnvironment.Config.CPPIncludeInfo.SystemIncludePaths) { Arguments += string.Format(" -I\"{0}\"", IncludePath); } // Add preprocessor definitions to the argument list. foreach (string Definition in CompileEnvironment.Config.Definitions) { Arguments += string.Format(" -D{0}", Definition); } if (bEnableTracing) { Arguments += string.Format(" -D__EMSCRIPTEN_TRACING__"); } var BuildPlatform = UEBuildPlatform.GetBuildPlatformForCPPTargetPlatform(CompileEnvironment.Config.Target.Platform); foreach (FileItem SourceFile in SourceFiles) { Action CompileAction = new Action(ActionType.Compile); bool bIsPlainCFile = Path.GetExtension(SourceFile.AbsolutePath).ToUpperInvariant() == ".C"; // Add the C++ source file and its included files to the prerequisite item list. AddPrerequisiteSourceFile(Target, BuildPlatform, CompileEnvironment, SourceFile, CompileAction.PrerequisiteItems); // Add the source file path to the command-line. string FileArguments = string.Format(" \"{0}\"", SourceFile.AbsolutePath); var ObjectFileExtension = UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.HTML5).GetBinaryExtension(UEBuildBinaryType.Object); // Add the object file to the produced item list. FileItem ObjectFile = FileItem.GetItemByFileReference( FileReference.Combine( CompileEnvironment.Config.OutputDirectory, Path.GetFileName(SourceFile.AbsolutePath) + ObjectFileExtension ) ); CompileAction.ProducedItems.Add(ObjectFile); FileArguments += string.Format(" -o \"{0}\"", ObjectFile.AbsolutePath); // Add C or C++ specific compiler arguments. if (bIsPlainCFile) { FileArguments += GetCLArguments_C(CompileEnvironment.Config.Target.Architecture); } else { FileArguments += GetCLArguments_CPP(CompileEnvironment); } CompileAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory.FullName; CompileAction.CommandPath = HTML5SDKInfo.Python(); CompileAction.CommandArguments = HTML5SDKInfo.EmscriptenCompiler() + " " + Arguments + FileArguments + CompileEnvironment.Config.AdditionalArguments; //System.Console.WriteLine(CompileAction.CommandArguments); CompileAction.StatusDescription = Path.GetFileName(SourceFile.AbsolutePath); CompileAction.OutputEventHandler = new DataReceivedEventHandler(CompileOutputReceivedDataEventHandler); // Don't farm out creation of precomputed headers as it is the critical path task. CompileAction.bCanExecuteRemotely = CompileEnvironment.Config.PrecompiledHeaderAction != PrecompiledHeaderAction.Create; // this is the final output of the compile step (a .abc file) Result.ObjectFiles.Add(ObjectFile); // VC++ always outputs the source file name being compiled, so we don't need to emit this ourselves CompileAction.bShouldOutputStatusDescription = true; // Don't farm out creation of precompiled headers as it is the critical path task. CompileAction.bCanExecuteRemotely = CompileEnvironment.Config.PrecompiledHeaderAction != PrecompiledHeaderAction.Create || BuildConfiguration.bAllowRemotelyCompiledPCHs; } return(Result); }
string GetSharedArguments_Global(CppConfiguration Configuration, bool bOptimizeForSize, string Architecture, bool bEnableShadowVariableWarnings, bool bShadowVariableWarningsAsErrors, bool bEnableUndefinedIdentifierWarnings, bool bUndefinedIdentifierWarningsAsErrors, bool bUseInlining, bool bUE423_OSX_LinkerFix = false) { string Result = " "; // string Result = " -Werror"; Result += " -fdiagnostics-format=msvc"; Result += " -fno-exceptions"; Result += " -Wdelete-non-virtual-dtor"; Result += " -Wno-switch"; // many unhandled cases Result += " -Wno-tautological-constant-out-of-range-compare"; // comparisons from TCHAR being a char Result += " -Wno-tautological-compare"; // comparison of unsigned expression < 0 is always false" (constant comparisons, which are possible with template arguments) Result += " -Wno-tautological-undefined-compare"; // pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate Result += " -Wno-inconsistent-missing-override"; // as of 1.35.0, overriding a member function but not marked as 'override' triggers warnings Result += " -Wno-undefined-var-template"; // 1.36.11 Result += " -Wno-invalid-offsetof"; // using offsetof on non-POD types Result += " -Wno-gnu-string-literal-operator-template"; // allow static FNames if (bEnableShadowVariableWarnings) { Result += " -Wshadow"; //+ (bShadowVariableWarningsAsErrors ? "" : " -Wno-error=shadow"); } if (bEnableUndefinedIdentifierWarnings) { Result += " -Wundef"; //+ (bUndefinedIdentifierWarningsAsErrors ? "" : " -Wno-error=undef"); } // -------------------------------------------------------------------------------- if (Configuration == CppConfiguration.Debug) { // WARNING: UEBuildTarget.cs :: GetCppConfiguration() Result += " -O0"; // faster compile time // DebugGame is forced to Development } // i.e. this will never get hit... else if (bOptimizeForSize) { // Engine/Source/Programs/UnrealBuildTool/HTML5/UEBuildHTML5.cs Result += " -Oz"; // favor size over speed // bCompileForSize=true; // set false, to build -O2 or -O3 } // SOURCE BUILD ONLY else if (Configuration == CppConfiguration.Development) { Result += " -O2"; // aggressive size and speed optimization } else if (Configuration == CppConfiguration.Shipping) { if (bUE423_OSX_LinkerFix && (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)) { // UE-78966 - TEMP HACK - remove this on next EMSCRIPTEN_TOOLCHAIN_UPGRADE_CHECK Result += " -O2"; } else { Result += " -O3"; // favor speed over size } } if (!bUseInlining) { Result += " -fno-inline-functions"; } PrintOnce(Configuration, bOptimizeForSize); // -------------------------------------------------------------------------------- // JavaScript option overrides (see src/settings.js) if (enableSIMD) { // Result += " -msse2 -s SIMD=1"; } if (enableMultithreading) { // Result += " -msse2 -s USE_PTHREADS=1"; Result += " -s USE_PTHREADS=1"; Result += " -DEXPERIMENTAL_OPENGL_RHITHREAD=" + (bMultithreading_UseOffscreenCanvas ? "0" : "1"); // NOTE: use "emscripten native" video, keyboard, mouse } else { // SDL2 is not supported for multi-threading WASM builds // WARNING: SDL2 may be removed in a future UE4 release // can comment out to use "emscripten native" single threaded // Result += " -DHTML5_USE_SDL2"; } if (useLLVMwasmBackend) // experimental - LLVMWasmBackend { Result += " -s WASM_OBJECT_FILES=1"; Environment.SetEnvironmentVariable("EMCC_WASM_BACKEND", "1"); } // -------------------------------------------------------------------------------- // emscripten ports // WARNING: seems emscripten ports cannot be currently used // there might be UE4 changes needed that are found in Engine/Source/ThirdParty/... // Result += " -s USE_ZLIB=1"; // Result += " -s USE_LIBPNG=1"; // Result += " -s USE_VORBIS=1"; // Result += " -s USE_OGG=1"; // Result += " -s USE_FREETYPE=1"; // TAG = 'release_1' // Result += " -s USE_HARFBUZZ=1"; // TAG = '1.2.4 note: path is https://github.com/harfbuzz/harfbuzz/archive/1.2.4.zip // Result += " -s USE_ICU=1"; // TAG = 'release-53-1' // SDL_Audio needs to be linked in [no matter if -DHTML5_USE_SDL2 is used or not] // TODO: remove AudioMixerSDL from Engine/Source/Runtime/Launch/Launch.Build.cs and replace with emscripten native functions // Result += " -s USE_SDL=2"; // -------------------------------------------------------------------------------- // Expect that Emscripten SDK has been properly set up ahead in time (with emsdk and prebundled toolchains this is always the case) // This speeds up builds a tiny bit. Environment.SetEnvironmentVariable("EMCC_SKIP_SANITY_CHECK", "1"); // THESE ARE TEST/DEBUGGING -- TRY NOT TO USE THESE // Environment.SetEnvironmentVariable("EMCC_DEBUG", "1"); // NOTE: try to use -v instead of EMCC_DEBUG // Environment.SetEnvironmentVariable("EMCC_DEBUG_SAVE", "1"); // very useful for compiler bughunts // Environment.SetEnvironmentVariable("EMCC_CORES", "8"); // Environment.SetEnvironmentVariable("EMCC_OPTIMIZE_NORMALLY", "1"); // enable verbose mode // Result += " -v"; // useful for path hunting issues if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux) { // Packaging on Linux needs this - or else system clang will be attempted to be picked up instead of UE4's included emsdk Environment.SetEnvironmentVariable(HTML5SDKInfo.PLATFORM_USER_HOME, HTML5SDKInfo.HTML5Intermediatory); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64 || BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win32) { // Packaging on Window needs this - zap any existing HOME environment variables to prevent any accidental pick ups Environment.SetEnvironmentVariable("HOME", ""); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { Environment.SetEnvironmentVariable("LD_LIBRARY_PATH", HTML5SDKInfo.MacPythonLib()); // UE-75402 } return(Result); }