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);
    }
示例#2
0
 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.");
    }
示例#4
0
 public virtual NativeProgramFormat CustomizeExecutableForSettings(FriendlyJObject settings) => null;
示例#5
0
    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);
    }
示例#9
0
 public virtual DotsRuntimeCSharpProgramConfiguration CustomizeConfigForSettings(DotsRuntimeCSharpProgramConfiguration config, FriendlyJObject settings) => config;
示例#10
0
    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);
    }