Beispiel #1
0
    public override void Customize(DotsRuntimeCSharpProgram program)
    {
        if (program.MainSourcePath.FileName != "Unity.ZeroJobs")
        {
            return;
        }

        program.NativeProgram.Libraries.Add(c => c.Platform is LinuxPlatform, new SystemLibrary("rt"));
        program.NativeProgram.Libraries.Add(c => c.Platform is WindowsPlatform, new SystemLibrary("ws2_32.lib"));

        NativeJobsPrebuiltLibrary.Add(program.NativeProgram);
    }
Beispiel #2
0
        public Il2CppOutputProgram(string name) : base(name)
        {
            AddLibIl2CppAsLibraryFor(this);

            var distRoot = Distribution.Path.ResolveWithFileSystem();

            Libraries.Add(BoehmGCProgram);
            Sources.Add(distRoot.Combine("external").Combine("xxHash/xxhash.c"));

            this.DynamicLinkerSettingsForMsvc()
            .Add(l => l.WithSubSystemType(SubSystemType.Console).WithEntryPoint("wWinMainCRTStartup"));

            Libraries.Add(c => c.ToolChain.Platform is WindowsPlatform, new SystemLibrary("kernel32.lib"));

            this.DynamicLinkerSettingsForMsvc().Add(l => l
                                                    .WithSubSystemType(SubSystemType.Console)
                                                    .WithEntryPoint("wWinMainCRTStartup")
                                                    );
            Defines.Add(c => c.ToolChain.DynamicLibraryFormat == null, "FORCE_PINVOKE_INTERNAL=1");

            this.DynamicLinkerSettingsForAndroid().Add(c =>
                                                       ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration == DotsConfiguration.Release, l => l.WithStripAll(true));

            Libraries.Add(c => c.Platform is WebGLPlatform, new PreJsLibrary(BuildProgram.BeeRoot.Parent.Combine("LowLevelSupport~", "WebSupport", "tiny_runtime.js")));
            Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_MONO_DEBUGGER=1");
            Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_DEBUGGER_PORT=56000");

            // Remove this comment to enable the managed debugger log file. It will be written to the working directory. For Web builds, the output will go to the browser's console.
            //Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_MONO_DEBUGGER_LOGFILE=il2cpp-debugger.log");

            Defines.Add(c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration != DotsConfiguration.Release, "IL2CPP_TINY_DEBUG_METADATA");
            CompilerSettings().Add(ManagedDebuggingIsEnabled, c => c.WithExceptions(true));
            CompilerSettings().Add(ManagedDebuggingIsEnabled, c => c.WithRTTI(true));
            IncludeDirectories.Add(ManagedDebuggingIsEnabled, distRoot.Combine("libil2cpp/pch"));

            CompilerSettings().Add(s => s.WithCppLanguageVersion(CppLanguageVersion.Cpp11));

            this.CompilerSettingsForMsvc().Add(c => c.WithWarningPolicies(new [] { new WarningAndPolicy("4102", WarningPolicy.Silent) }));
            this.CompilerSettingsForGcc().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies()));
            this.CompilerSettingsForClang().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies()));
            this.CompilerSettingsForEmscripten().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies()));
            this.CompilerSettingsForIos().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies()));
            NativeJobsPrebuiltLibrary.AddToNativeProgram(this); // Only required for managed debugging
            this.CompilerSettingsForEmscripten().Add(ManagedDebuggingIsEnabled,
                                                     c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled));
            this.CompilerSettingsForGccLike().Add(s => s.WithCustomFlags(new[] { "-fno-strict-overflow" }));
        }
Beispiel #3
0
    private static DotsRuntimeCSharpProgram SetupGame(AsmDefDescription game)
    {
        var gameProgram       = GetOrMakeDotsRuntimeCSharpProgramFor(game);
        var configToSetupGame = new Dictionary <DotsRuntimeCSharpProgramConfiguration, DotNetAssembly>();

        if (!PerConfigBuildSettings.ContainsKey(game.Name))
        {
            return(null);
        }

        var configsToUse = PerConfigBuildSettings[game.Name].Where(config => !CanSkipSetupOf(game.Name, config));

        foreach (var config in configsToUse)
        {
            var   withoutExt     = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier);
            NPath exportManifest = withoutExt.Combine("export.manifest");
            Backend.Current.RegisterFileInfluencingGraph(exportManifest);
            if (exportManifest.FileExists())
            {
                var dataFiles = exportManifest.MakeAbsolute().ReadAllLines();
                foreach (var dataFile in dataFiles.Select(d => new NPath(d)))
                {
                    gameProgram.SupportFiles.Add(
                        c => c.Equals(config),
                        new DeployableFile(dataFile, GetDeployPathFromExportPath(dataFile)));
                }
            }

            gameProgram.ProjectFile.StartInfo.Add(
                c => c == config,
                StartInfoFor(config, EntryPointExecutableFor(gameProgram, config)));
            gameProgram.ProjectFile.BuildCommand.Add(
                c => c == config,
                new BeeBuildCommand(GameDeployBinaryFor(gameProgram, config).ToString(), false, false).ToExecuteArgs());
        }

        foreach (var config in configsToUse)
        {
            DotNetAssembly setupGame = gameProgram.SetupSpecificConfiguration(config);

            if (config.TargetFramework == TargetFramework.Tiny)
            {
                var tinyStandard = new DotNetAssembly(Il2Cpp.Distribution.Path.Combine("build/profiles/Tiny/Facades/netstandard.dll"), Framework.FrameworkNone);
                setupGame = setupGame.WithDeployables(tinyStandard);
            }

            var postILProcessedGame = ILPostProcessorTool.SetupInvocation(
                setupGame,
                config,
                gameProgram.Defines.For(config).ToArray());

            var postTypeRegGenGame = TypeRegistrationTool.SetupInvocation(postILProcessedGame, config);
            configToSetupGame[config] = postTypeRegGenGame;
        }

        var il2CppOutputProgram = new Il2Cpp.Il2CppOutputProgram(gameProgram.AsmDefDescription.Name);

        var configToSetupGameBursted = new Dictionary <DotsRuntimeCSharpProgramConfiguration, DotNetAssembly>();

        foreach (var kvp in configToSetupGame)
        {
            var config    = kvp.Key;
            var setupGame = kvp.Value;

            if (config.UseBurst)
            {
                BurstCompiler burstCompiler = null;
                if (config.Platform is WindowsPlatform)
                {
                    burstCompiler      = new BurstCompilerForWindows64();
                    burstCompiler.Link = false;
                }
                else if (config.Platform is MacOSXPlatform)
                {
                    burstCompiler      = new BurstCompilerForMac();
                    burstCompiler.Link = false;
                }
                else if (config.Platform is IosPlatform)
                {
                    burstCompiler = new BurstCompilerForiOS();
                    burstCompiler.EnableStaticLinkage = true;
                    burstCompiler.ObjectFileExtension = "a";
                }
                else if (config.Platform is LinuxPlatform)
                {
                    burstCompiler = new BurstCompilerForLinuxWaitingForBurstRelease();
                }
                else if (config.Platform is AndroidPlatform)
                {
                    burstCompiler = new BurstCompilerForAndroid();
                    burstCompiler.EnableStaticLinkage = false;
                    burstCompiler.Link = false;
                    burstCompiler.EnableDirectExternalLinking = true;
                    if (config.NativeProgramConfiguration.ToolChain.Architecture is Arm64Architecture)
                    {
                        burstCompiler.TargetArchitecture = "ARMV8A_AARCH64";
                    }
                }
                else if (config.Platform is WebGLPlatform)
                {
                    burstCompiler = new BurstCompilerForEmscripten();
                    burstCompiler.EnableStaticLinkage = true;
                    burstCompiler.DisableVectors      = false;
                }

                // Only generate marshaling info for platforms that require marshalling (e.g. Windows DotNet)
                // but also if collection checks are enabled (as that is why we need marshalling)
                burstCompiler.EnableJobMarshalling &= config.EnableUnityCollectionsChecks;
                burstCompiler.SafetyChecks          = config.EnableUnityCollectionsChecks;
                burstCompiler.DisableWarnings       = "BC1370"; // Suppress warning for burst function throwing an exception

                var            outputDir    = $"artifacts/{game.Name}/{config.Identifier}_bursted";
                var            burstLibName = "lib_burst_generated";
                DotNetAssembly burstedGame  = setupGame;

                var burstlib = BurstCompiler.SetupBurstCompilationForAssemblies(
                    burstCompiler,
                    setupGame,
                    new NPath(outputDir).Combine("bclobj"),
                    outputDir,
                    burstLibName,
                    out burstedGame);
                if ((config.Platform is IosPlatform || config.Platform is AndroidPlatform) &&
                    config.NativeProgramConfiguration.ToolChain.DynamicLibraryFormat.Extension == "a") // static lib based toolchain
                {
                    il2CppOutputProgram.Libraries.Add(c => c.Equals(config.NativeProgramConfiguration), burstlib);
                    il2CppOutputProgram.Defines.Add(
                        c => c.Equals(config.NativeProgramConfiguration),
                        $"FORCE_PINVOKE_{burstLibName}_INTERNAL");
                }
                else if (config.Platform is WebGLPlatform)
                {
                    il2CppOutputProgram.Libraries.Add(c => c.Equals(config.NativeProgramConfiguration), burstlib);
                }
                else
                {
                    var burstDynamicLib = new NativeProgram(burstLibName);
                    burstDynamicLib.Libraries.Add(c => c.Equals(config.NativeProgramConfiguration), burstlib);
                    burstDynamicLib.Libraries.Add(
                        c => c.Equals(config.NativeProgramConfiguration),
                        gameProgram.TransitiveReferencesFor(config)
                        .Where(
                            p => p is DotsRuntimeCSharpProgram &&
                            ((DotsRuntimeCSharpProgram)p).NativeProgram != null)
                        .Select(
                            p => new NativeProgramAsLibrary(((DotsRuntimeCSharpProgram)p).NativeProgram)
                    {
                        BuildMode = NativeProgramLibraryBuildMode.Dynamic
                    }));

                    if (config.Platform is IosPlatform || config.Platform is AndroidPlatform)
                    {
                        NativeJobsPrebuiltLibrary.AddToNativeProgram(burstDynamicLib);
                    }

                    DotsRuntimeCSharpProgram.SetupDotsRuntimeNativeProgram(burstLibName, burstDynamicLib);

                    var builtBurstLib = burstDynamicLib.SetupSpecificConfiguration(
                        config.NativeProgramConfiguration,
                        config.NativeProgramConfiguration.ToolChain.DynamicLibraryFormat);
                    burstedGame = burstedGame.WithDeployables(builtBurstLib);
                }

                configToSetupGameBursted[config] = burstedGame;
            }
            else
            {
                configToSetupGameBursted[config] = setupGame;
            }
        }

        var configToSetupGameStripped = new Dictionary <DotsRuntimeCSharpProgramConfiguration, DotNetAssembly>();

        foreach (var kvp in configToSetupGameBursted)
        {
            var config    = kvp.Key;
            var setupGame = kvp.Value;

            if (config.ScriptingBackend == ScriptingBackend.TinyIl2cpp)
            {
                setupGame = Il2Cpp.UnityLinker.SetupInvocation(setupGame, $"artifacts/{game.Name}/{config.Identifier}_stripped", config.NativeProgramConfiguration);
                il2CppOutputProgram.SetupConditionalSourcesAndLibrariesForConfig(config, setupGame);
                configToSetupGameStripped[kvp.Key] = setupGame;
            }
            else
            {
                configToSetupGameStripped[kvp.Key] = kvp.Value;
            }
        }

        foreach (var kvp in configToSetupGameStripped)
        {
            var   config     = kvp.Key;
            var   setupGame  = kvp.Value;
            NPath deployPath = GameDeployDirectoryFor(gameProgram, config);

            IDeployable deployedGame;
            NPath       entryPointExecutable = null;

            if (config.ScriptingBackend == ScriptingBackend.TinyIl2cpp)
            {
                var   tinyShellFileName = "tiny_shell.html";
                NPath tinyShellPath     = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier, "WebTemplate", tinyShellFileName);
                il2CppOutputProgram.DynamicLinkerSettingsForEmscripten().Add(c => c.WithShellFile(tinyShellPath));

                var builtNativeProgram = il2CppOutputProgram.SetupSpecificConfiguration(
                    config.NativeProgramConfiguration,
                    config.NativeProgramConfiguration.ExecutableFormat
                    )
                                         .WithDeployables(setupGame.RecursiveRuntimeDependenciesIncludingSelf.SelectMany(a => a.Deployables.Where(d => !(d is DotNetAssembly) && !(d is StaticLibrary)))
                                                          .ToArray());

                if (builtNativeProgram is IPackagedAppExtension)
                {
                    (builtNativeProgram as IPackagedAppExtension).SetAppPackagingParameters(
                        gameProgram.AsmDefDescription.Name, config.DotsConfiguration);
                }

                if (config.PlatformBuildConfig is WebBuildConfig webBuildConfig)
                {
                    if (webBuildConfig.SingleFile)
                    {
                        deployedGame = new DeployableFile(GameDeployBinaryFor(gameProgram, config));
                        CopyTool.Instance().Setup(deployedGame.Path, (builtNativeProgram as EmscriptenExecutable).Path);
                    }
                    else
                    {
                        deployedGame = builtNativeProgram.DeployTo(deployPath);
                    }

                    var webTemplateFolder = webBuildConfig.WebTemplateFolder;
                    if (String.IsNullOrEmpty(webTemplateFolder))
                    {
                        webTemplateFolder = LowLevelRoot.Combine("WebSupport", "WebTemplates", "Default").ToString();
                    }
                    if (new NPath(webTemplateFolder).IsRelative)
                    {
                        webTemplateFolder = new NPath("../..").Combine(webTemplateFolder).MakeAbsolute().ToString();
                    }
                    if (!new NPath(webTemplateFolder).Combine(tinyShellFileName).FileExists())
                    {
                        throw new InvalidProgramException($"Web template folder \"{webTemplateFolder}\" doesn't contain \"{tinyShellFileName}\" file.");
                    }

                    foreach (var templateFilePath in new NPath(webTemplateFolder).Files(recurse:true))
                    {
                        string fileRelativePath = templateFilePath.ToString().Substring(webTemplateFolder.Length + 1);
                        if (fileRelativePath == tinyShellFileName)
                        {
                            NPath shellPackager = LowLevelRoot.Combine("WebSupport", "package_shell_file.js");
                            NPath tinyShellJS   = LowLevelRoot.Combine("WebSupport", "tiny_shell.js");
                            var   inputs        = new List <NPath> {
                                TinyEmscripten.NodeExe, shellPackager, templateFilePath, tinyShellJS
                            };
                            var commandLineArguments = new List <string> {
                                shellPackager.ToString(), "--outputHtml", tinyShellPath.ToString(), "--inputShellHtml", templateFilePath.ToString(), "--inputShellJs", tinyShellJS.ToString()
                            };
                            NPath exportManifest = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier, "export.manifest");
                            if (webBuildConfig.SingleFile && exportManifest.FileExists())
                            {
                                inputs.Add(exportManifest.MakeAbsolute().ReadAllLines().Select(d => new NPath(d)));
                                NPath assetRootDirectory = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier);
                                commandLineArguments.AddRange(new List <string> {
                                    "--assetRootDirectory", assetRootDirectory.ToString(), "--assetManifest", exportManifest.ToString()
                                });
                            }
                            Backend.Current.AddAction(
                                actionName: "Package Shell File",
                                targetFiles: new NPath[] { tinyShellPath },
                                inputs: inputs.ToArray(),
                                executableStringFor: TinyEmscripten.NodeExe.InQuotes(),
                                commandLineArguments: commandLineArguments.Select(d => d.InQuotes()).ToArray()
                                );
                            Backend.Current.AddDependency(deployedGame.Path, tinyShellPath);
                        }
                        else if (!templateFilePath.HasExtension("meta"))
                        {
                            var targetPath = deployPath.Combine(fileRelativePath);
                            CopyTool.Instance().Setup(targetPath, templateFilePath);
                            Backend.Current.AddDependency(deployedGame.Path, targetPath);
                        }
                    }
                }
                else
                {
                    deployedGame = builtNativeProgram.DeployTo(deployPath);
                }

                entryPointExecutable = deployedGame.Path;
                if (config.EnableManagedDebugging && !(builtNativeProgram is IPackagedAppExtension))
                {
                    Backend.Current.AddDependency(deployedGame.Path, Il2Cpp.CopyIL2CPPMetadataFile(deployPath, setupGame));
                }

                // make sure http-server gets fetched from stevedore.  this should probably go elsewhere, but this is
                // a convenient quick hack place.
                if (config.PlatformBuildConfig is WebBuildConfig)
                {
                    var httpserver = new StevedoreArtifact("http-server");
                    httpserver.GenerateUnusualPath();
                    var httpserverpath = httpserver.GetUnusualPath().Combine("bin", "http-server");
                    Backend.Current.AddDependency(deployedGame.Path, httpserverpath);
                }
            }
            else
            {
                deployedGame = setupGame.DeployTo(deployPath);

                var dotNetAssembly = (DotNetAssembly)deployedGame;

                //Usually a dotnet runtime game does not have a static void main(), and instead references another "entrypoint asmdef" that provides it.
                //This is convenient, but what makes it weird is that you have to start YourEntryPoint.exe  instead of YourGame.exe.   Until we have a better
                //solution for this, we're going to copy YourEntryPoint.exe to YourGame.exe, so that it's easier to find, and so that when it runs and you look
                //at the process name you understand what it is.
                if (deployedGame.Path.HasExtension("dll"))
                {
                    var to = deployPath.Combine(deployedGame.Path.ChangeExtension("exe").FileName);
                    // Do an explicit check for the entrypoint.exe as a program may refer to other exes as assembly references
                    var from = dotNetAssembly.RecursiveRuntimeDependenciesIncludingSelf.SingleOrDefault(a => a.Path.FileName == "Unity.Runtime.EntryPoint.exe")?.Path;
                    if (from == null)
                    {
                        throw new InvalidProgramException($"Program {dotNetAssembly.Path} is an executable-like thing, but doesn't reference anything with Main");
                    }
                    Backend.Current.AddDependency(deployedGame.Path, CopyTool.Instance().Setup(to, from));
                    entryPointExecutable = to;
                }
                else
                {
                    entryPointExecutable = deployedGame.Path;
                }
            }

            //Because we use multidag, and try to not run all the setupcode when we just want to create projectfiles, we have a bit of a challenge.
            //Projectfiles require exact start and build commands. So we need to have a cheap way to calculate those. However, it's important that they
            //exactly match the actual place where the buildprogram is going to place our files. If these don't match things break down. The checks
            //in this block, they compare the "quick way to determine where the binary will be placed, and what the start executable is",  with the
            //actual return values returned from .DeployTo(), when we do run the actual buildcode.
            NPath deployedGamePath = GameDeployBinaryFor(gameProgram, config);

            //Identifier with slash means that this is complementary target and we should skip steps which are main target specific.
            //See comment in DotsConfigs.cs DotsConfigs.MakeConfigs() method for details.
            if (config.Identifier.IndexOf('/') != -1)
            {
                continue;
            }

            if (deployedGame.Path != deployedGamePath)
            {
                throw new InvalidProgramException($"We expected deployPath to be {deployedGamePath}, but in reality it was {deployedGame.Path}");
            }
            var expectedEntryPointExecutable = EntryPointExecutableFor(gameProgram, config);
            if (entryPointExecutable != expectedEntryPointExecutable)
            {
                throw new InvalidProgramException($"We expected entryPointExecutable to be {expectedEntryPointExecutable}, but in reality it was {entryPointExecutable}");
            }

            Backend.Current.AddAliasDependency(config.Identifier, deployedGamePath);
        }

        return(gameProgram);
    }
    protected void Construct(string name, bool isExe)
    {
        FileName = name + (isExe ? ".exe" : ".dll");

        Framework.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, Bee.DotNet.Framework.FrameworkNone);
        References.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, Il2Cpp.TinyCorlib);

        Framework.Add(
            c => GetTargetFramework(c, this) == TargetFramework.NetStandard20,
            BuildProgram.HackedFrameworkToUseForProjectFilesIfNecessary);

        ProjectFile.Path = DeterminePathForProjectFile();

        ProjectFile.ReferenceModeCallback = arg =>
        {
            // Most projects are AsmDefCSharpProgram. For everything else we'll look up their
            // packagestatus by the fact that we know it's in the same package as Unity.Entities.CPlusPlus
            // XXX This is not true any more!
            //var asmdefDotsProgram = (arg as AsmDefCSharpProgram)?.AsmDefDescription ?? AsmDefConfigFile.AsmDefDescriptionFor("Unity.Entities.CPlusPlus");
            return(ProjectFile.ReferenceMode.ByCSProj);
        };

        LanguageVersion = "7.3";
        Defines.Add(
            "UNITY_DOTSPLAYER", // this is deprecated and we should remove in the distant future
            "UNITY_DOTSRUNTIME",
            "UNITY_2018_3_OR_NEWER",
            "UNITY_2019_1_OR_NEWER",
            "UNITY_2019_2_OR_NEWER",
            "UNITY_2019_3_OR_NEWER",
            "UNITY_2020_1_OR_NEWER",
            "UNITY_ENTITIES_0_12_OR_NEWER"
            );

        Defines.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, "NET_DOTS");
        Defines.Add(c => GetTargetFramework(c, this) == TargetFramework.NetStandard20, "NET_STANDARD_2_0");

        // Managed components are unsupported when using the Tiny BCL
        Defines.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, "UNITY_DISABLE_MANAGED_COMPONENTS");

        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 32, "UNITY_DOTSPLAYER32");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 32, "UNITY_DOTSRUNTIME32");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 64, "UNITY_DOTSPLAYER64");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 64, "UNITY_DOTSRUNTIME64");

        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is WebGLPlatform, "UNITY_WEBGL");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is WindowsPlatform, "UNITY_WINDOWS");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is MacOSXPlatform, "UNITY_MACOSX");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is LinuxPlatform, "UNITY_LINUX");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is IosPlatform, "UNITY_IOS");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is AndroidPlatform, "UNITY_ANDROID");
        Defines.Add(c => !((DotsRuntimeCSharpProgramConfiguration)c).MultiThreadedJobs, "UNITY_SINGLETHREADED_JOBS");

        // Adds stack traces to mallocs until we get a better system for memory leaks
        //Defines.Add("UNITY_DOTSRUNTIME_TRACEMALLOCS");

        CopyReferencesNextToTarget = false;

        WarningsAsErrors = ShouldEnableWarningsAsErrors(name);

        foreach (var sourcePath in AllSourcePaths)
        {
            if (sourcePath.FileName == "Unity.Mathematics")
            {
                Sources.Add(sourcePath.Files("*.cs", true)
                            .Where(f => f.FileName != "math_unity_conversion.cs" && f.FileName != "PropertyAttributes.cs"));
            }
            else
            {
                Sources.Add(new CustomProvideFiles(sourcePath));
            }
        }
        bool hasCpp = false;

        foreach (var sourcePath in AllSourcePaths)
        {
            var cppFolder      = sourcePath.Combine("cpp~");
            var androidFolder  = sourcePath.Combine("android~");
            var prejsFolder    = sourcePath.Combine("prejs~");
            var jsFolder       = sourcePath.Combine("js~");
            var postjsFolder   = sourcePath.Combine("postjs~");
            var beeFolder      = sourcePath.Combine("bee~");
            var includeFolder  = cppFolder.Combine("include");
            var bindingsFolder = sourcePath.Combine("bindings~");

            if (cppFolder.DirectoryExists())
            {
                ProjectFile.AdditionalFiles.AddRange(cppFolder.Files(true));

                var cppFiles = cppFolder.Files("*.c*", true);
                GetOrMakeNativeProgram().Sources.Add(cppFiles);

                var mmFiles = cppFolder.Files("*.m*", true);
                GetOrMakeNativeProgram().Sources.Add(c => (c.Platform is MacOSXPlatform || c.Platform is IosPlatform), mmFiles);

                GetOrMakeNativeProgram().DynamicLinkerSettingsForAndroid().Add(c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration == DotsConfiguration.Release, l => l.WithStripAll(true));

                hasCpp = true;
            }

            if (prejsFolder.DirectoryExists())
            {
                var jsFiles = prejsFolder.Files("*.js", true);
                ProjectFile.AdditionalFiles.AddRange(prejsFolder.Files(true));
                GetOrMakeNativeProgram()
                .Libraries.Add(c => c.Platform is WebGLPlatform,
                               jsFiles.Select(jsFile => new PreJsLibrary(jsFile)));
            }

            //todo: get rid of having both a regular js and a prejs folder
            if (jsFolder.DirectoryExists())
            {
                var jsFiles = jsFolder.Files("*.js", true);
                ProjectFile.AdditionalFiles.AddRange(jsFolder.Files(true));
                GetOrMakeNativeProgram()
                .Libraries.Add(c => c.Platform is WebGLPlatform,
                               jsFiles.Select(jsFile => new JavascriptLibrary(jsFile)));
            }

            if (postjsFolder.DirectoryExists())
            {
                var jsFiles = postjsFolder.Files("*.js", true);
                ProjectFile.AdditionalFiles.AddRange(postjsFolder.Files(true));
                GetOrMakeNativeProgram()
                .Libraries.Add(c => c.Platform is WebGLPlatform,
                               jsFiles.Select(jsFile => new PostJsLibrary(jsFile)));
            }

            // .jslib files in asmdef dir, like Unity
            var jslibFiles = sourcePath.Files("*.jslib", true);
            if (jslibFiles.Any())
            {
                ProjectFile.AdditionalFiles.AddRange(jslibFiles);
                GetOrMakeNativeProgram()
                .Libraries.Add(c => c.Platform is WebGLPlatform,
                               jslibFiles.Select(jsFile => new JavascriptLibrary(jsFile)));
            }

            if (beeFolder.DirectoryExists())
            {
                ProjectFile.AdditionalFiles.AddRange(beeFolder.Files("*.cs"));
            }

            if (includeFolder.DirectoryExists())
            {
                GetOrMakeNativeProgram().PublicIncludeDirectories.Add(includeFolder);
            }

            if (bindingsFolder.DirectoryExists())
            {
                NativeJobsPrebuiltLibrary.AddBindings(this, bindingsFolder);
            }

            if (androidFolder.DirectoryExists())
            {
                foreach (var extraFile in androidFolder.Files(true).Where(f => f.HasExtension("java", "kt", "aar", "jar")))
                {
                    SupportFiles.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is AndroidPlatform, new DeployableFile(extraFile, extraFile.RelativeTo(androidFolder)));
                }
            }
        }

        if (hasCpp)
        {
            GetOrMakeNativeProgram().Libraries.Add(c => c.Platform is LinuxPlatform, new SystemLibrary("rt"));
            GetOrMakeNativeProgram().Libraries.Add(c => c.Platform is LinuxPlatform, new SystemLibrary("atomic"));
            GetOrMakeNativeProgram().Libraries.Add(c => c.Platform is WindowsPlatform, new SystemLibrary("ws2_32.lib"));
            NativeJobsPrebuiltLibrary.AddToNativeProgram(GetOrMakeNativeProgram());
        }

        SupportFiles.Add(AllSourcePaths.SelectMany(p =>
                                                   p.Files()
                                                   .Where(f => f.HasExtension("jpg", "png", "wav", "mp3", "jpeg", "mp4", "webm", "ogg", "ttf", "json"))));

        Defines.Add(c => ((DotsRuntimeCSharpProgramConfiguration)c).EnableUnityCollectionsChecks, "ENABLE_UNITY_COLLECTIONS_CHECKS");

        bool isConfigDebug(CSharpProgramConfiguration c) =>
        c.CodeGen == CSharpCodeGen.Debug || (c as DotsRuntimeCSharpProgramConfiguration)?.DotsConfiguration < DotsConfiguration.Release;

        Defines.Add(isConfigDebug, "DEBUG");

        bool isConfigDevelop(CSharpProgramConfiguration c) => (c as DotsRuntimeCSharpProgramConfiguration)?.DotsConfiguration == DotsConfiguration.Develop;

        Defines.Add(isConfigDevelop, "DEVELOP");

        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.EnableProfiler == true, "ENABLE_PROFILER");

        // Many systems needs their own DOTS Runtime specific profiler define since they will get scanned by
        // the hybrid builds/editor, but they will use the DOTS Runtime-specific profiler API.
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.EnableProfiler == true, "ENABLE_DOTSRUNTIME_PROFILER");

        // Only enable player connection when we need it
        // - To support logging ("debug" builds)
        // - To support profiling
        // - To support il2cpp managed debugging (multicast)
        Defines.Add(c => isConfigDebug(c) || (c as DotsRuntimeCSharpProgramConfiguration)?.EnableProfiler == true || IsManagedDebuggingWithIL2CPPEnabled(c), "ENABLE_PLAYERCONNECTION");

        // Multicasting
        // - Is a supplement to player connection in non-webgl builds
        // - Is needed for identification in webgl builds, too, if il2cpp managed debugging is enabled
        Defines.Add(c => !((c as DotsRuntimeCSharpProgramConfiguration).Platform is WebGLPlatform) || IsManagedDebuggingWithIL2CPPEnabled(c), "ENABLE_MULTICAST");

        // Special define used mainly for debugging multithread jobs without bursting them
        Defines.Add(c => !(c as DotsRuntimeCSharpProgramConfiguration).UseBurst && (c as DotsRuntimeCSharpProgramConfiguration).MultiThreadedJobs, "UNITY_DOTSRUNTIME_MULTITHREAD_NOBURST");

        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.TinyIl2cpp, "UNITY_DOTSPLAYER_IL2CPP"); // deprecated version
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.TinyIl2cpp, "UNITY_DOTSRUNTIME_IL2CPP");

        Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c), "UNITY_DOTSPLAYER_IL2CPP_MANAGED_DEBUGGER"); // deprecated version
        Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c), "UNITY_DOTSRUNTIME_IL2CPP_MANAGED_DEBUGGER");

        Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c) && (c as DotsRuntimeCSharpProgramConfiguration).WaitForManagedDebugger, "UNITY_DOTSPLAYER_IL2CPP_WAIT_FOR_MANAGED_DEBUGGER"); // deprecated version
        Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c) && (c as DotsRuntimeCSharpProgramConfiguration).WaitForManagedDebugger, "UNITY_DOTSRUNTIME_IL2CPP_WAIT_FOR_MANAGED_DEBUGGER");

        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.Dotnet, "UNITY_DOTSPLAYER_DOTNET"); // deprecated version
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.Dotnet, "UNITY_DOTSRUNTIME_DOTNET");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Defines ?? new List <string>());

        ProjectFile.RedirectMSBuildBuildTargetToBee = true;
        ProjectFile.AddCustomLinkRoot(MainSourcePath, ".");
        ProjectFile.RootNameSpace = "";

        DotsRuntimeCSharpProgramCustomizer.RunAllCustomizersOn(this);
    }
Beispiel #5
0
    static NativeProgram CreateLibIl2CppProgram(bool useExceptions, NativeProgram boehmGcProgram = null, string libil2cppname = "libil2cpptiny")
    {
        var fileList = Distribution.GetFileList(libil2cppname).ResolveWithFileSystem().ToArray();

        var nPaths       = fileList.Where(f => f.HasExtension("cpp")).ToArray();
        var win32Sources = nPaths.Where(p => p.HasDirectory("Win32")).ToArray();
        var posixSources = nPaths.Where(p => p.HasDirectory("Posix")).ToArray();

        nPaths = nPaths.Except(win32Sources).Except(posixSources).ToArray();

        var program = new NativeProgram(libil2cppname)
        {
            Sources =
            {
                nPaths,
                { c => c.Platform.HasPosix,posixSources                      },
                { c => c.Platform is WindowsPlatform,win32Sources                      }
            },
            Exceptions = { useExceptions },
            PublicIncludeDirectories =
            {
                Distribution.Path.Combine(libil2cppname),
                Distribution.Path.Combine("libil2cpp")
            },
            PublicDefines =
            {
                "NET_4_0",
                "GC_NOT_DLL",
                "RUNTIME_IL2CPP",

                "LIBIL2CPP_IS_IN_EXECUTABLE=1",
                { c => c.ToolChain is VisualStudioToolchain,"NOMINMAX",               "WIN32_THREADS", "IL2CPP_TARGET_WINDOWS=1" },
                { c => c.CodeGen == CodeGen.Debug,"DEBUG",                  "IL2CPP_DEBUG" },
                { c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration != DotsConfiguration.Release,"IL2CPP_TINY_DEBUG_METADATA" },
            },
            Libraries =
            {
                {
                    c => c.Platform is WindowsPlatform,
                    new[]
                    {
                        "user32.lib", "advapi32.lib", "ole32.lib", "oleaut32.lib", "Shell32.lib", "Crypt32.lib",
                        "psapi.lib", "version.lib", "MsWSock.lib", "ws2_32.lib", "Iphlpapi.lib", "Dbghelp.lib"
                    }.Select(s => new SystemLibrary(s))
                },
                { c => c.Platform is MacOSXPlatform,  new PrecompiledLibrary[] { new SystemFramework("CoreFoundation") } },
                { c => c.Platform is LinuxPlatform,   new SystemLibrary("dl") },
                { c => c.Platform is AndroidPlatform, new[]                    { new SystemLibrary("log")              } }
            },
            Defines =
            {
                { c => c.Platform is AndroidPlatform && c.ToolChain.Architecture is Arm64Architecture && ManagedDebuggingIsEnabled(c), "TARGET_ARM64" },
            }
        };

        program.Libraries.Add(BoehmGCProgram);

        program.RTTI.Set(c => useExceptions && c.ToolChain.EnablingExceptionsRequiresRTTI);

        if (libil2cppname == "libil2cpptiny")
        {
            program.Sources.Add(Distribution.GetFileList("libil2cpp/os").ResolveWithFileSystem());
            program.Sources.Add(Distribution.GetFileList("libil2cpp/gc").ResolveWithFileSystem());
            program.Sources.Add(Distribution.GetFileList("libil2cpp/utils").ResolveWithFileSystem());
            program.Sources.Add(Distribution.GetFileList("libil2cpp/vm-utils").ResolveWithFileSystem());
            program.Sources.Add(Distribution.GetFileList("libil2cpp/codegen").ResolveWithFileSystem());
            program.PublicIncludeDirectories.Add(Distribution.Path.Combine("libil2cpp"));
            program.PublicIncludeDirectories.Add(Distribution.Path.Combine("libil2cpp", "pch"));
        }
        else
        {
            program.Defines.Add(ManagedDebuggingIsEnabled,
                                "IL2CPP_MONO_DEBUGGER=1",
                                "PLATFORM_UNITY",
                                "UNITY_USE_PLATFORM_STUBS",
                                "ENABLE_OVERRIDABLE_ALLOCATORS",
                                "IL2CPP_ON_MONO=1",
                                "DISABLE_JIT=1",
                                "DISABLE_REMOTING=1",
                                "HAVE_CONFIG_H",
                                "MONO_DLL_EXPORT=1");

            program.IncludeDirectories.Add(ManagedDebuggingIsEnabled,
                                           new[]
            {
                Distribution.Path.Combine("external/mono/mono/eglib"),
                Distribution.Path.Combine("external/mono/mono"),
                Distribution.Path.Combine("external/mono/"),
                Distribution.Path.Combine("external/mono/mono/sgen"),
                Distribution.Path.Combine("external/mono/mono/utils"),
                Distribution.Path.Combine("external/mono/mono/metadata"),
                Distribution.Path.Combine("external/mono/metadata/private"),
                Distribution.Path.Combine("libmono/config"),
                Distribution.Path.Combine("libil2cpp/os/c-api"),
                Distribution.Path.Combine("libil2cpp/pch"),
            }.ResolveWithFileSystem());

            var MonoSourceDir = Distribution.Path.Combine("external/mono").ResolveWithFileSystem();
            program.Sources.Add(ManagedDebuggingIsEnabled,
                                new []
            {
                "mono/eglib/garray.c",
                "mono/eglib/gbytearray.c",
                "mono/eglib/gdate-unity.c",
                "mono/eglib/gdir-unity.c",
                "mono/eglib/gerror.c",
                "mono/eglib/gfile-unity.c",
                "mono/eglib/gfile.c",
                "mono/eglib/ghashtable.c",
                "mono/eglib/giconv.c",
                "mono/eglib/glist.c",
                "mono/eglib/gmarkup.c",
                "mono/eglib/gmem.c",
                "mono/eglib/gmisc-unity.c",
                "mono/eglib/goutput.c",
                "mono/eglib/gpath.c",
                "mono/eglib/gpattern.c",
                "mono/eglib/gptrarray.c",
                "mono/eglib/gqsort.c",
                "mono/eglib/gqueue.c",
                "mono/eglib/gshell.c",
                "mono/eglib/gslist.c",
                "mono/eglib/gspawn.c",
                "mono/eglib/gstr.c",
                "mono/eglib/gstring.c",
                "mono/eglib/gunicode.c",
                "mono/eglib/gutf8.c",
                "mono/metadata/mono-hash.c",
                "mono/metadata/profiler.c",
                "mono/mini/debugger-agent.c",
                "mono/utils/atomic.c",
                "mono/utils/bsearch.c",
                "mono/utils/dlmalloc.c",
                "mono/utils/hazard-pointer.c",
                "mono/utils/json.c",
                "mono/utils/lock-free-alloc.c",
                "mono/utils/lock-free-array-queue.c",
                "mono/utils/lock-free-queue.c",
                "mono/utils/memfuncs.c",
                "mono/utils/mono-codeman.c",
                "mono/utils/mono-conc-hashtable.c",
                "mono/utils/mono-context.c",
                "mono/utils/mono-counters.c",
                "mono/utils/mono-dl.c",
                "mono/utils/mono-error.c",
                "mono/utils/mono-filemap.c",
                "mono/utils/mono-hwcap.c",
                "mono/utils/mono-internal-hash.c",
                "mono/utils/mono-io-portability.c",
                "mono/utils/mono-linked-list-set.c",
                "mono/utils/mono-log-common.c",
                "mono/utils/mono-logger.c",
                "mono/utils/mono-math.c",
                "mono/utils/mono-md5.c",
                "mono/utils/mono-mmap-windows.c",
                "mono/utils/mono-mmap.c",
                "mono/utils/mono-networkinterfaces.c",
                "mono/utils/mono-os-mutex.c",
                "mono/utils/mono-path.c",
                "mono/utils/mono-poll.c",
                "mono/utils/mono-proclib-windows.c",
                "mono/utils/mono-proclib.c",
                "mono/utils/mono-property-hash.c",
                "mono/utils/mono-publib.c",
                "mono/utils/mono-sha1.c",
                "mono/utils/mono-stdlib.c",
                "mono/utils/mono-threads-coop.c",
                "mono/utils/mono-threads-state-machine.c",
                "mono/utils/mono-threads.c",
                "mono/utils/mono-tls.c",
                "mono/utils/mono-uri.c",
                "mono/utils/mono-value-hash.c",
                "mono/utils/monobitset.c",
                "mono/utils/networking-missing.c",
                "mono/utils/networking.c",
                "mono/utils/parse.c",
                "mono/utils/strenc.c",
                "mono/utils/unity-rand.c",
                "mono/utils/unity-time.c",
                "mono/utils/mono-dl-unity.c",
                "mono/utils/mono-log-unity.c",
                "mono/utils/mono-threads-unity.c",
                "mono/utils/networking-unity.c",
                "mono/utils/os-event-unity.c",
                "mono/metadata/console-unity.c",
                "mono/metadata/file-mmap-unity.c",
                "mono/metadata/w32error-unity.c",
                "mono/metadata/w32event-unity.c",
                "mono/metadata/w32file-unity.c",
                "mono/metadata/w32mutex-unity.c",
                "mono/metadata/w32process-unity.c",
                "mono/metadata/w32semaphore-unity.c",
                "mono/metadata/w32socket-unity.c"
            }.Select(path => MonoSourceDir.Combine(path)));

            program.Sources.Add(c => c.ToolChain.Platform is WindowsPlatform && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/eglib/gunicode-win32.c"));
            program.Sources.Add(c => c.ToolChain.Platform is WindowsPlatform && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-os-wait-win32.c"));

            program.Sources.Add(c => c.ToolChain.Platform is WebGLPlatform && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-web.c"));

            program.Sources.Add(c => c.ToolChain.Architecture is IntelArchitecture && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-x86.c"));
            program.Sources.Add(c => c.ToolChain.Architecture is ARMv7Architecture && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-arm.c"));
            program.Sources.Add(c => c.ToolChain.Architecture is Arm64Architecture && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-arm64.c"));

            program.IncludeDirectories.Add(ManagedDebuggingIsEnabled, Distribution.Path.Combine("libil2cpp/debugger"));
        }

        program.PublicDefines.Add("IL2CPP_TINY");
        program.PublicIncludeDirectories.Add(Distribution.Path.Combine("external").Combine("xxHash"));
        program.CompilerSettings().Add(s => s.WithCppLanguageVersion(CppLanguageVersion.Cpp11));

        program.CompilerSettingsForGcc().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies()));

        // Use Baselib headers and library code from the NativeJobs library.
        NativeJobsPrebuiltLibrary.AddToNativeProgram(program);

        //program.CompilerSettingsForMsvc().Add(l => l.WithCompilerRuntimeLibrary(CompilerRuntimeLibrary.None));

        program.CompilerSettingsForEmscripten().Add(ManagedDebuggingIsEnabled, c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled));
        program.StaticLinkerSettings().Add(c => c.ToolChain is EmscriptenToolchain && ManagedDebuggingIsEnabled(c), s => s.WithCustomFlags_workaround(new[] { "-s", "USE_PTHREADS=1" }));

        return(program);
    }