public static DotsConfiguration DotsConfigForSettings(FriendlyJObject settingsObject, out CSharpCodeGen codegen) { DotsConfiguration dotsCfg; var codegenString = settingsObject.GetString("DotsConfig"); switch (codegenString) { case "Debug": codegen = CSharpCodeGen.Debug; dotsCfg = DotsConfiguration.Debug; break; case "Develop": codegen = CSharpCodeGen.Release; dotsCfg = DotsConfiguration.Develop; break; case "Release": codegen = CSharpCodeGen.Release; dotsCfg = DotsConfiguration.Release; break; default: throw new ArgumentException( $"Error: Unrecognized codegen {codegenString} in build json file. This is a bug."); } return(dotsCfg); }
public override NativeProgramFormat CustomizeExecutableForSettings(FriendlyJObject settings) { return(GetExecutableFormatForConfig(DotsConfigs.DotsConfigForSettings(settings, out _), settings.GetBool("EnableManagedDebugger")) .WithLinkerSetting <EmscriptenDynamicLinker>(e => e.WithEmscriptenSettings(settings.GetDictionary("EmscriptenSettings")))); }
public static bool ManagedDebuggingForSettings(FriendlyJObject settingsObject) { var managedDebuggingString = settingsObject.GetString("ManagedDebugging"); if (string.IsNullOrEmpty(managedDebuggingString) || managedDebuggingString == "UseBuildConfiguration") { return(DotsConfigForSettings(settingsObject, out var unused) == DotsConfiguration.Debug); } if (managedDebuggingString == "Enabled") { return(true); } if (managedDebuggingString == "Disabled") { return(false); } throw new ArgumentException($"Error: Unrecognized managed debugging option '{managedDebuggingString}' in build json file. This is a bug."); }
public virtual NativeProgramFormat CustomizeExecutableForSettings(FriendlyJObject settings) => null;
public override DotsRuntimeCSharpProgramConfiguration CustomizeConfigForSettings(DotsRuntimeCSharpProgramConfiguration config, FriendlyJObject settings) { var executableFormat = GetExecutableFormatForConfig(DotsConfigs.DotsConfigForSettings(settings, out _), SupportsManagedDebugging && config.EnableManagedDebugging) .WithLinkerSetting <EmscriptenDynamicLinker>(e => e .WithCustomFlags_workaround(new[] { "-s", "TOTAL_STACK=" + (settings.GetString("WasmStackSize") ?? "512KB") }) .WithCustomFlags_workaround(new[] { "-s", "TOTAL_MEMORY=" + (settings.GetString("WasmMemorySize") ?? "128MB") }) .WithCustomFlags_workaround(new[] { "-s", "ALLOW_MEMORY_GROWTH=" + (settings.GetBool("AllowWasmMemoryGrowth")?"1":"0") }) .WithCustomFlags_workaround(new[] { "-s", "MINIFY_HTML=" + (settings.GetBool("MinifyHTMLFile")?"1":"0") }) .WithCustomFlags_workaround(settings.GetBool("MinifyOutputWithClosure") ? new[] { "--closure-args", "\"--platform native --externs " + BuildProgram.BeeRoot.Combine("closure_externs.js").ToString() + "\"", "--closure", "1", "-s", "CLOSURE_WARNINGS=warn" } : new[] { "" }) .WithCustomFlags_workaround(new[] { settings.GetBool("EmbedCpuProfiler")?"--cpuprofiler":"" }) .WithCustomFlags_workaround(new[] { settings.GetBool("EmbedMemoryProfiler")?"--memoryprofiler":"" }) .WithCustomFlags_workaround(new[] { settings.GetBool("IncludeSymbolsForBrowserCallstacks")?"--profiling-funcs":"" }) .WithCustomFlags_workaround(new[] { "-s", "ASSERTIONS=" + (settings.GetBool("EmitRuntimeAllocationDebugChecks")?"2":(settings.GetBool("EmitRuntimeMemoryDebugChecks")?"1":"0")) }) .WithCustomFlags_workaround(new[] { "-s", "SAFE_HEAP=" + (settings.GetBool("EmitRuntimeMemoryDebugChecks")?"1":"0") }) .WithSingleFile(settings.GetBool("SingleFile")) // Specify extra EmscriptenCmdLine overrides last so they can override previous settings. .WithCustomFlags_workaround(new[] { settings.GetString("EmscriptenCmdLine") ?? "" }) ); config.NativeProgramConfiguration = new DotsRuntimeNativeProgramConfiguration( config.NativeProgramConfiguration.CodeGen, config.NativeProgramConfiguration.ToolChain, config.Identifier, config, executableFormat: executableFormat); config.PlatformBuildConfig = new WebBuildConfig { SingleFile = settings.GetBool("SingleFile"), WebTemplateFolder = settings.GetString("WebTemplateFolder"), }; return(config); }
public static Dictionary <string, List <DotsRuntimeCSharpProgramConfiguration> > MakeConfigs() { var platformList = DotsBuildSystemTargets; var settingsDir = new NPath("settings"); if (settingsDir.Exists()) { foreach (var settingsRelative in settingsDir.Files("*.json")) { var settingsFile = settingsRelative.MakeAbsolute(); if (settingsFile.Exists()) { Backend.Current.RegisterFileInfluencingGraph(settingsFile); var settingsObject = new FriendlyJObject { Content = JObject.Parse(settingsFile.ReadAllText()) }; if (settingsObject.GetInt("Version", 0) != AsmDefConfigFile.BuildSettingsFileVersion || AsmDefConfigFile.AsmDefDescriptionFor(settingsObject.GetString("RootAssembly")) == null) { Console.WriteLine($"Found old settings file '{settingsFile}', removing..."); settingsFile.Delete(); continue; } var id = settingsObject.GetString("PlatformTargetIdentifier"); var target = platformList.Single(t => t.Identifier == id); if (!target.ToolChain.CanBuild) { continue; } // Need to know this prior to determining need for burst var mdb = ShouldEnableDevelopmentOptionForSetting("EnableManagedDebugging", new[] { DotsConfiguration.Debug, DotsConfiguration.Develop }, settingsObject); if (!target.ValidateManagedDebugging(ref mdb)) { continue; } if (mdb && DotsConfigForSettings(settingsObject, out var codeGen) == DotsConfiguration.Debug && target.ScriptingBackend == ScriptingBackend.TinyIl2cpp) { Errors.PrintWarning("Debug builds with managed debugging are very slow. It's recommended to use the Develop configuration instead."); } var multithreading = settingsObject.GetBool("EnableMultithreading"); var targetUsesBurst = settingsObject.GetBool("EnableBurst"); if (!targetUsesBurst && multithreading) { // We currently do not support multithreaded debugging anywhere except .NET Framework and CoreCLR (so, Windows only) // or il2cpp full profile bool isFullIl2cpp = target.ScriptingBackend == ScriptingBackend.TinyIl2cpp && mdb; bool isWindows = target.ToolChain.Platform is WindowsPlatform; if (!(isFullIl2cpp || isWindows)) { Errors.PrintWarning($"BuildConfiguration '{settingsFile.FileNameWithoutExtension}' " + $"specified 'EnableBurst=False', but 'Multithreading=True'. Multithreading requires Burst, therefore enabling Burst."); targetUsesBurst = true; } } var dotsCfg = DotsConfigForSettings(settingsObject, out var codegen); var enableProfiler = ShouldEnableDevelopmentOptionForSetting("EnableProfiler", new [] { DotsConfiguration.Develop }, settingsObject); var enableUnityCollectionsChecks = ShouldEnableDevelopmentOptionForSetting("EnableSafetyChecks", new[] { DotsConfiguration.Debug, DotsConfiguration.Develop }, settingsObject); if (!target.CanUseBurst && targetUsesBurst) { Console.WriteLine($"Warning: BuildConfiguration '{settingsFile.FileNameWithoutExtension}' " + $"specified 'EnableBurst', but target ({target.Identifier}) does not support burst yet. Not using burst."); targetUsesBurst = false; } // Workaround to disable burst in web debug builds since it will fail to compile // https://unity3d.atlassian.net/browse/DOTSR-1886 if (targetUsesBurst && target is DotsWebTarget && codegen == CSharpCodeGen.Debug) { Console.WriteLine($"Warning: Web currently does not support building in debug configuration with Burst. Disabling burst...."); targetUsesBurst = false; } var waitForManagedDebugger = settingsObject.GetBool("WaitForManagedDebugger"); var rootAssembly = settingsObject.GetString("RootAssembly"); string finalOutputDir = null; if (settingsObject.Content.TryGetValue("FinalOutputDirectory", out var finalOutputToken)) { finalOutputDir = finalOutputToken.Value <string>(); } var defines = new List <string>(); if (settingsObject.Content.TryGetValue("ScriptingDefines", out var definesJToken)) { defines = ((JArray)definesJToken).Select(token => token.Value <string>()).ToList(); } if (!PerConfigBuildSettings.ContainsKey(rootAssembly)) { PerConfigBuildSettings[rootAssembly] = new List <DotsRuntimeCSharpProgramConfiguration>(); } var identifier = settingsFile.FileNameWithoutExtension; do { PerConfigBuildSettings[rootAssembly] .Add( target.CustomizeConfigForSettings(new DotsRuntimeCSharpProgramConfiguration( csharpCodegen: codegen, cppCodegen: codegen == CSharpCodeGen.Debug ? CodeGen.Debug : CodeGen.Release, nativeToolchain: target.ToolChain, scriptingBackend: target.ScriptingBackend, targetFramework: target.TargetFramework, identifier: identifier, enableUnityCollectionsChecks: enableUnityCollectionsChecks, enableManagedDebugging: mdb, waitForManagedDebugger: waitForManagedDebugger, multiThreadedJobs: multithreading, dotsConfiguration: dotsCfg, enableProfiler: enableProfiler, useBurst: targetUsesBurst, defines: defines, finalOutputDirectory: finalOutputDir), settingsObject)); //We have to introduce the concept of "complementary targets" to accommodate building "fat" binaries on Android, //for both armv7 and arm64 architectures. This means we have to build two copies of the final binaries, and then do one //packaging step to package both steps into a single apk. But also, since C# code is allowed to do #if UNITY_DOTSRUNTIME64 //(and indeed we need that ability for the static type registry to generate correct sizes of things), we need to compile //two sets of c# assemblies, one per architecture, and run il2cpp and burst on each one separately, in order to produce //these two sets of final binaries. //For that purpose, we associate a second DotsRuntimeCSharpProgramConfiguration (known as the complementary target) to //specify the build for the other architecture we wish to compile against, and we do all the building steps up to the final //packaging step for that config as well as the main one. We skip the final packaging step for the complementary config, //and make the packaging step for the main config consume both sets of binaries. //This is a crazy scheme, and we theorize and hope that when we adopt the incremental buildpipeline, we will be able //to use their concept of per-platform custom graph build steps to make this be more reasonable. target = target.ComplementaryTarget; //We use "identifier" as a directory name for all intermediate files. //For complementary target these files will be generated in "target.Identifier" subdirectory. //So for example in case of arm64 complemenary target a path would be //"{target.Identifiler}/android_complementary_arm64". if (target != null) { identifier += "/" + target.Identifier; } } while (target != null); } } } return(PerConfigBuildSettings); }
public static bool ShouldEnableDevelopmentOptionForSetting(string optionName, DotsConfiguration[] enabledByDefaultForConfigurations, FriendlyJObject settingsObject) { var optionString = settingsObject.GetString(optionName); if (string.IsNullOrEmpty(optionString) || optionString == "UseBuildConfiguration") { var dotsConfig = DotsConfigForSettings(settingsObject, out var unused); return(enabledByDefaultForConfigurations.Contains(dotsConfig)); } if (optionString == "Enabled") { return(true); } if (optionString == "Disabled") { return(false); } throw new ArgumentException($"Error: Unrecognized '{optionName}' option '{optionString}' in build json file. This is a bug."); }
public static Dictionary <string, List <DotsRuntimeCSharpProgramConfiguration> > MakeConfigs() { var platformList = DotsBuildSystemTargets; var settingsDir = new NPath("settings"); if (settingsDir.Exists()) { foreach (var settingsRelative in settingsDir.Files("*.json")) { var settingsFile = settingsRelative.MakeAbsolute(); if (settingsFile.Exists()) { Backend.Current.RegisterFileInfluencingGraph(settingsFile); var settingsObject = new FriendlyJObject { Content = JObject.Parse(settingsFile.ReadAllText()) }; var id = settingsObject.GetString("PlatformTargetIdentifier"); var target = platformList.Single(t => t.Identifier == id); if (!target.ToolChain.CanBuild) { continue; } var targetShouldUseBurst = settingsObject.GetBool("UseBurst"); var dotsCfg = DotsConfigForSettings(settingsObject, out var codegen); var enableUnityCollectionsChecks = dotsCfg != DotsConfiguration.Release; if (!target.CanUseBurst && targetShouldUseBurst) { Console.WriteLine($"Warning: BuildConfiguration '{settingsFile.FileNameWithoutExtension}' " + $"specified 'UseBurst', but target ({target.Identifier}) does not support burst yet. Not using burst."); targetShouldUseBurst = false; } var mdb = ManagedDebuggingForSettings(settingsObject); if (target.Identifier == "asmjs" || target.Identifier == "wasm") { mdb = false; } var waitForManagedDebugger = settingsObject.GetBool("WaitForManagedDebugger"); var rootAssembly = settingsObject.GetString("RootAssembly"); string finalOutputDir = null; if (settingsObject.Content.TryGetValue("FinalOutputDirectory", out var finalOutputToken)) { finalOutputDir = finalOutputToken.Value <string>(); } var multithreading = settingsObject.GetBool("EnableMultiThreading"); var defines = new List <string>(); if (settingsObject.Content.TryGetValue("ScriptingDefines", out var definesJToken)) { defines = ((JArray)definesJToken).Select(token => token.Value <string>()).ToList(); } if (!PerConfigBuildSettings.ContainsKey(rootAssembly)) { PerConfigBuildSettings[rootAssembly] = new List <DotsRuntimeCSharpProgramConfiguration>(); } PerConfigBuildSettings[rootAssembly] .Add( new DotsRuntimeCSharpProgramConfiguration( csharpCodegen: codegen, cppCodegen: codegen == CSharpCodeGen.Debug ? CodeGen.Debug : CodeGen.Release, nativeToolchain: target.ToolChain, scriptingBackend: target.ScriptingBackend, targetFramework: target.TargetFramework, identifier: settingsFile.FileNameWithoutExtension, enableUnityCollectionsChecks: enableUnityCollectionsChecks, enableManagedDebugging: mdb, waitForManagedDebugger: waitForManagedDebugger, multiThreadedJobs: multithreading, dotsConfiguration: dotsCfg, useBurst: targetShouldUseBurst, executableFormat: target.CustomizeExecutableForSettings(settingsObject), defines: defines, finalOutputDirectory: finalOutputDir)); } } } return(PerConfigBuildSettings); }
public virtual DotsRuntimeCSharpProgramConfiguration CustomizeConfigForSettings(DotsRuntimeCSharpProgramConfiguration config, FriendlyJObject settings) => config;
public static Dictionary <string, List <DotsRuntimeCSharpProgramConfiguration> > MakeConfigs() { var platformList = DotsBuildSystemTargets; var settingsDir = new NPath("settings"); if (settingsDir.Exists()) { foreach (var settingsRelative in settingsDir.Files("*.json")) { var settingsFile = settingsRelative.MakeAbsolute(); if (settingsFile.Exists()) { Backend.Current.RegisterFileInfluencingGraph(settingsFile); var settingsObject = new FriendlyJObject { Content = JObject.Parse(settingsFile.ReadAllText()) }; var id = settingsObject.GetString("PlatformTargetIdentifier"); var target = platformList.Single(t => t.Identifier == id); if (!target.ToolChain.CanBuild) { continue; } var targetShouldUseBurst = settingsObject.GetBool("UseBurst"); var dotsCfg = DotsConfigForSettings(settingsObject, out var codegen); var enableUnityCollectionsChecks = dotsCfg != DotsConfiguration.Release; /* dotnet reorders struct layout when there are managed components in the job struct, * most notably DisposeSentinel. Mono does not. So disable burst on windows dotnet when * collections checks are enabled. */ var canUseBurst = target.CanUseBurst && !(target is DotsWindowsDotNetTarget && target.ScriptingBackend == ScriptingBackend.Dotnet && enableUnityCollectionsChecks); if (!canUseBurst && targetShouldUseBurst) { Console.WriteLine( "Warning: UseBurst specified, but target does not support burst yet. Not using burst."); targetShouldUseBurst = false; } var mdb = settingsObject.GetBool("EnableManagedDebugging"); var rootAssembly = settingsObject.GetString("RootAssembly"); string finalOutputDir = null; if (settingsObject.Content.TryGetValue("FinalOutputDirectory", out var finalOutputToken)) { finalOutputDir = finalOutputToken.Value <string>(); } var multithreading = settingsObject.GetBool("EnableMultiThreading"); var defines = new List <string>(); if (settingsObject.Content.TryGetValue("ScriptingDefines", out var definesJToken)) { defines = ((JArray)definesJToken).Select(token => token.Value <string>()).ToList(); } if (!PerConfigBuildSettings.ContainsKey(rootAssembly)) { PerConfigBuildSettings[rootAssembly] = new List <DotsRuntimeCSharpProgramConfiguration>(); } PerConfigBuildSettings[rootAssembly] .Add( new DotsRuntimeCSharpProgramConfiguration(codegen, codegen == CSharpCodeGen.Debug ? CodeGen.Debug : CodeGen.Release, target.ToolChain, target.ScriptingBackend, settingsFile.FileNameWithoutExtension, enableUnityCollectionsChecks, mdb, multithreading, dotsCfg, targetShouldUseBurst, target.CustomizeExecutableForSettings(settingsObject), defines, finalOutputDir)); } } } return(PerConfigBuildSettings); }