public AsmDefBasedDotsRuntimeCSharpProgram(AsmDefDescription asmDefDescription)
        : base(asmDefDescription.Directory,
               deferConstruction: true
               )
    {
        AsmDefDescription  = asmDefDescription;
        ReferencedPrograms = AsmDefDescription.References.Select(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor).ToArray();

        var referencesEntryPoint = ReferencedPrograms.Any(r => r.FileName.EndsWith(".exe"));

        var isExe = asmDefDescription.DefineConstraints.Contains("UNITY_DOTS_ENTRYPOINT") ||
                    (asmDefDescription.Path.Parent.Files("*.project").Any() && !referencesEntryPoint) ||
                    asmDefDescription.OptionalUnityReferences.Contains("TestAssemblies");

        Construct(asmDefDescription.Name, isExe);

        ProjectFile.AdditionalFiles.Add(asmDefDescription.Path);

        IncludePlatforms = AsmDefDescription.IncludePlatforms;
        ExcludePlatforms = AsmDefDescription.ExcludePlatforms;
        Unsafe           = AsmDefDescription.Unsafe;
        References.Add(config =>
        {
            if (config is DotsRuntimeCSharpProgramConfiguration dotsConfig)
            {
                return(ReferencedPrograms.Where(rp =>
                                                rp.IsSupportedOn(dotsConfig.NativeProgramConfiguration.ToolChain.Platform)));
            }

            //this codepath will be hit for the bindgem invocation
            return(ReferencedPrograms);
        });

        if (BuildProgram.ZeroJobs != null)
        {
            References.Add(BuildProgram.ZeroJobs);
        }
        if (BuildProgram.UnityLowLevel != null)
        {
            References.Add(BuildProgram.UnityLowLevel);
        }

        if (IsTestAssembly)
        {
            References.Add(BuildProgram.NUnitFramework);
            var nunitLiteMain = BuildProgram.BeeRoot.Combine("CSharpSupport/NUnitLiteMain.cs");
            Sources.Add(nunitLiteMain);
            ProjectFile.AddCustomLinkRoot(nunitLiteMain.Parent, "TestRunner");
            References.Add(BuildProgram.NUnitLite);
            References.Add(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(BuildProgramConfigFile.AsmDefDescriptionFor("Unity.Entities")));
        }

        BindGem.ConfigureNativeProgramFor(this);
    }
Exemple #2
0
    protected void Construct(string name, bool isExe)
    {
        FileName = name + (isExe ? ".exe" : ".dll");

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

        Framework.Add(c => !ShouldTargetTinyCorlib(c, this), Bee.DotNet.Framework.Framework471);
        References.Add(c => !ShouldTargetTinyCorlib(c, this), new SystemReference("System"));

        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",
            "NET_DOTS",
            // TODO -- figure out what's gated with this, and if it should have a UNITY_DOTSPLAYER || ...
            "UNITY_2018_3_OR_NEWER",
            // And these might not make sense for DOTS Runtime anyway beacuse they are UnityEngine/UnityEditor APIs.
            // They break the build if we add them.
            //"UNITY_2019_1_OR_NEWER",
            //"UNITY_2019_2_OR_NEWER",
            //"UNITY_2019_3_OR_NEWER",
            // TODO -- removing this breaks Burst, it should be using DOTSPLAYER!
            "UNITY_ZEROPLAYER"
            );

        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");

        CopyReferencesNextToTarget = false;

        WarningsAsErrors = false;
        //hack, fix this in unity.mathematics

        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));
            }
        }
        foreach (var sourcePath in AllSourcePaths)
        {
            var cppFolder     = sourcePath.Combine("cpp~");
            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");

            NPath[] cppFiles = Array.Empty <NPath>();
            if (cppFolder.DirectoryExists())
            {
                cppFiles = cppFolder.Files("*.c*", true);
                ProjectFile.AdditionalFiles.AddRange(cppFolder.Files(true));
                GetOrMakeNativeProgram().Sources.Add(cppFiles);
            }

            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)));
            }

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

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

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

        Defines.Add(c => c.CodeGen == CSharpCodeGen.Debug || (c as DotsRuntimeCSharpProgramConfiguration)?.DotsConfiguration < DotsConfiguration.Release, "DEBUG");

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

        Defines.Add(
            c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.TinyIl2cpp,
            "UNITY_DOTSPLAYER_IL2CPP");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.Dotnet, "UNITY_DOTSPLAYER_DOTNET");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Defines ?? new List <string>());

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

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

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

        Framework.Add(c => !ShouldTargetTinyCorlib(c, this), Bee.DotNet.Framework.Framework471);
        References.Add(c => !ShouldTargetTinyCorlib(c, this), new SystemReference("System"));

        ProjectFile.Path = new NPath(FileName).ChangeExtension(".csproj");

        ProjectFile.ReferenceModeCallback = arg =>
        {
            if (arg == Il2Cpp.TinyCorlib)
            {
                return(ProjectFile.ReferenceMode.ByCSProj);
            }

            //most projects are AsmDefBasedDotsRuntimeCSharpProgram. The remained are things like ZeroJobs. For them we'll look up their packagestatus by the fact that we know
            //it's in the same package as Unity.Entities.CPlusPlus
            var asmdefDotsProgram = (arg as AsmDefBasedDotsRuntimeCSharpProgram)?.AsmDefDescription ?? BuildProgramConfigFile.AsmDefDescriptionFor("Unity.Entities.CPlusPlus");

            switch (asmdefDotsProgram.PackageSource)
            {
            case "NoPackage":
            case "Embedded":
            case "Local":
                return(ProjectFile.ReferenceMode.ByCSProj);

            default:
                return(ProjectFile.ReferenceMode.ByDotNetAssembly);
            }
        };

        LanguageVersion = "7.3";
        Defines.Add(
            "UNITY_2018_3_OR_NEWER",
            "UNITY_DOTSPLAYER",
            "UNITY_ZEROPLAYER", //<-- this was used for a while, let's keep it around to not break people's incoming PR's.
            "NET_TINY",
            "NET_DOTS",
            "UNITY_USE_TINYMATH",
            "UNITY_BINDGEM"
            );

        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");

        CopyReferencesNextToTarget = false;

        WarningsAsErrors = false;
        //hack, fix this in unity.mathematics
        if (SourcePath.FileName == "Unity.Mathematics")
        {
            Sources.Add(SourcePath.Files("*.cs", true).Where(f => f.FileName != "math_unity_conversion.cs" && f.FileName != "PropertyAttributes.cs"));
        }
        else
        {
            var csFilesForDirectory = CSFilesForDirectory(SourcePath).ToList();
            if (csFilesForDirectory.Count == 0)
            {
                csFilesForDirectory.Add(BuildProgram.BeeRoot.Combine("CSharpSupport/PlaceHolderForEmptyProject.cs"));
            }
            Sources.Add(csFilesForDirectory);
        }

        var cppFolder     = SourcePath.Combine("cpp~");
        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");

        NPath[] cppFiles = Array.Empty <NPath>();
        if (cppFolder.DirectoryExists())
        {
            cppFiles = cppFolder.Files("*.c*", true);
            ProjectFile.AdditionalFiles.AddRange(cppFolder.Files(true));
            GetOrMakeNativeProgram().Sources.Add(cppFiles);
        }

        if (prejsFolder.DirectoryExists())
        {
            var jsFiles = prejsFolder.Files("*.js", true);
            ProjectFile.AdditionalFiles.AddRange(prejsFolder.Files(true));
            GetOrMakeNativeProgram().Libraries.Add(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(jsFiles.Select(jsFile => new JavascriptLibrary(jsFile)));
        }

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

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

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

        SupportFiles.Add(SourcePath.Files().Where(f => f.HasExtension("jpg", "png", "wav", "mp3", "jpeg", "mp4", "webm", "ogg")));


        Defines.Add(c => c.CodeGen == CSharpCodeGen.Debug, "DEBUG");

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

        Defines.Add(
            c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.TinyIl2cpp,
            "UNITY_DOTSPLAYER_IL2CPP");
        Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.Dotnet, "UNITY_DOTSPLAYER_DOTNET");

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

        DotsRuntimeCSharpProgramCustomizer.RunAllCustomizersOn(this);
    }
Exemple #4
0
    public AsmDefCSharpProgram(AsmDefDescription asmDefDescription)
        : base(asmDefDescription.Directory,
               asmDefDescription.IncludedAsmRefs.Select(asmref => asmref.Path.Parent),
               deferConstruction: true)
    {
        AsmDefDescription = asmDefDescription;

        var asmDefReferences = AsmDefDescription.References.Select(asmDefDescription1 => BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(asmDefDescription1)).ToList();
        var isExe            = asmDefDescription.DefineConstraints.Contains("UNITY_DOTS_ENTRYPOINT") || asmDefDescription.Name.EndsWith(".Tests");

        Construct(asmDefDescription.Name, isExe);

        ProjectFile.AdditionalFiles.Add(asmDefDescription.Path);

        IncludePlatforms = AsmDefDescription.IncludePlatforms;
        ExcludePlatforms = AsmDefDescription.ExcludePlatforms;
        Unsafe           = AsmDefDescription.AllowUnsafeCode;
        References.Add(config =>
        {
            if (config is DotsRuntimeCSharpProgramConfiguration dotsConfig)
            {
                if (dotsConfig.TargetFramework == TargetFramework.Tiny)
                {
                    return(asmDefReferences.Where(rp => rp.IsSupportedFor(dotsConfig) && !IncompatibleTinyBCLAsmDefs.Contains(rp.FileName)));
                }
                else
                {
                    return(asmDefReferences.Where(rp => rp.IsSupportedFor(dotsConfig)));
                }
            }

            //this codepath will be hit for the bindgem invocation
            return(asmDefReferences);
        });

        if (AsmDefDescription.IsTinyRoot || isExe)
        {
            AsmDefCSharpProgramCustomizer.RunAllAddPlatformImplementationReferences(this);
        }

        if (BuildProgram.UnityTinyBurst != null)
        {
            References.Add(BuildProgram.UnityTinyBurst);
        }
        if (BuildProgram.ZeroJobs != null)
        {
            References.Add(BuildProgram.ZeroJobs);
        }
        if (BuildProgram.UnityLowLevel != null)
        {
            References.Add(BuildProgram.UnityLowLevel);
        }
        if (BuildProgram.TinyIO != null)
        {
            References.Add(BuildProgram.TinyIO);
        }

        // Add in any precompiled references found in the asmdef directory or sub-directory
        foreach (var pcr in asmDefDescription.PrecompiledReferences)
        {
            var files = asmDefDescription.Path.Parent.Files(pcr, true);
            if (files.Any())
            {
                References.Add(files);
            }
        }

        if (IsTestAssembly)
        {
            var nunitLiteMain = BuildProgram.BeeRoot.Combine("CSharpSupport/NUnitLiteMain.cs");
            Sources.Add(nunitLiteMain);

            // Setup for IL2CPP
            var tinyTestFramework = BuildProgram.BeeRoot.Parent.Combine("TinyTestFramework");
            Sources.Add(c => ((DotsRuntimeCSharpProgramConfiguration)c).ScriptingBackend == ScriptingBackend.TinyIl2cpp || ((DotsRuntimeCSharpProgramConfiguration)c).TargetFramework == TargetFramework.Tiny, tinyTestFramework);
            Defines.Add(c => ((DotsRuntimeCSharpProgramConfiguration)c).ScriptingBackend == ScriptingBackend.TinyIl2cpp || ((DotsRuntimeCSharpProgramConfiguration)c).TargetFramework == TargetFramework.Tiny, "UNITY_PORTABLE_TEST_RUNNER");

            // Setup for dotnet
            References.Add(c => ((DotsRuntimeCSharpProgramConfiguration)c).ScriptingBackend == ScriptingBackend.Dotnet && ((DotsRuntimeCSharpProgramConfiguration)c).TargetFramework != TargetFramework.Tiny, BuildProgram.NUnitFramework);
            ProjectFile.AddCustomLinkRoot(nunitLiteMain.Parent, "TestRunner");
            References.Add(c => ((DotsRuntimeCSharpProgramConfiguration)c).ScriptingBackend == ScriptingBackend.Dotnet && ((DotsRuntimeCSharpProgramConfiguration)c).TargetFramework != TargetFramework.Tiny, BuildProgram.NUnitLite);

            // General setup
            References.Add(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(AsmDefConfigFile.AsmDefDescriptionFor("Unity.Entities")));
            References.Add(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(AsmDefConfigFile.AsmDefDescriptionFor("Unity.Tiny.Core")));
            References.Add(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(AsmDefConfigFile.AsmDefDescriptionFor("Unity.Tiny.UnityInstance")));
            References.Add(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(AsmDefConfigFile.AsmDefDescriptionFor("Unity.Collections")));
        }
        else if (IsILPostProcessorAssembly)
        {
            References.Add(BuildProgram.UnityCompilationPipeline);
            References.Add(MonoCecil.Paths);
            References.Add(Il2Cpp.Distribution.Path.Combine("build/deploy/net471/Unity.Cecil.Awesome.dll"));
        }
    }
    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);
    }
    public AsmDefCSharpProgram(AsmDefDescription asmDefDescription)
        : base(asmDefDescription.Directory,
               asmDefDescription.IncludedAsmRefs.Select(asmref => asmref.Path.Parent),
               deferConstruction: true)
    {
        AsmDefDescription = asmDefDescription;

        var asmDefReferences = AsmDefDescription.References.Select(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor).ToList();

        ReferencedPrograms = asmDefReferences.Where(r => !IncompatibleDotRuntimeAsmDefs.Contains(r.AsmDefDescription.Name)).ToArray();

        var isTinyRoot = AsmDefDescription.NamedReferences.Contains("Unity.Tiny.Main") ||
                         asmDefDescription.Path.Parent.Files("*.project").Any();

        var isExe = asmDefDescription.DefineConstraints.Contains("UNITY_DOTS_ENTRYPOINT") || asmDefDescription.Name.EndsWith(".Tests");

        Construct(asmDefDescription.Name, isExe);

        ProjectFile.AdditionalFiles.Add(asmDefDescription.Path);

        IncludePlatforms = AsmDefDescription.IncludePlatforms;
        ExcludePlatforms = AsmDefDescription.ExcludePlatforms;
        Unsafe           = AsmDefDescription.Unsafe;
        References.Add(config =>
        {
            if (config is DotsRuntimeCSharpProgramConfiguration dotsConfig)
            {
                return(ReferencedPrograms.Where(rp => rp.IsSupportedFor(dotsConfig)));
            }

            //this codepath will be hit for the bindgem invocation
            return(ReferencedPrograms);
        });

        if (isTinyRoot || isExe)
        {
            AsmDefCSharpProgramCustomizer.RunAllAddPlatformImplementationReferences(this);
        }

        if (BuildProgram.ZeroJobs != null)
        {
            References.Add(BuildProgram.ZeroJobs);
        }
        if (BuildProgram.UnityLowLevel != null)
        {
            References.Add(BuildProgram.UnityLowLevel);
        }

        if (IsTestAssembly)
        {
            References.Add(BuildProgram.NUnitFramework);
            var nunitLiteMain = BuildProgram.BeeRoot.Combine("CSharpSupport/NUnitLiteMain.cs");
            Sources.Add(nunitLiteMain);
            ProjectFile.AddCustomLinkRoot(nunitLiteMain.Parent, "TestRunner");
            References.Add(BuildProgram.NUnitLite);
            References.Add(BuildProgram.GetOrMakeDotsRuntimeCSharpProgramFor(AsmDefConfigFile.AsmDefDescriptionFor("Unity.Entities")));
        }
        else if (IsILPostProcessorAssembly)
        {
            References.Add(BuildProgram.UnityCompilationPipeline);
            References.Add(StevedoreUnityCecil.Paths);
        }
    }