Example #1
0
    static void Main()
    {
        if (!(Backend.Current is TundraBackend))
        {
            StandaloneBeeDriver.RunBuildProgramInBeeEnvironment("dummy.json", Main);
            return;
        }

        BeeRootValue = AsmDefConfigFile.AsmDefDescriptionFor("Unity.ZeroPlayer.TypeRegGen").Path.Parent.Parent.Combine("bee~");

        StevedoreGlobalSettings.Instance = new StevedoreGlobalSettings
        {
            // Manifest entries always override artifact IDs hard-coded in Bee
            // Setting EnforceManifest to true will also ensure no artifacts
            // are used without being listed in a manifest.
            EnforceManifest = true,
            Manifest        =
            {
                BeeRootValue.Combine("manifest.stevedore"),
            },
        };
        //The stevedore global manifest will override DownloadableCsc.Csc72 artifacts and use Csc73
        CSharpProgram.DefaultConfig = new CSharpProgramConfiguration(CSharpCodeGen.Release, DownloadableCsc.Csc72);

        UnityLowLevel = new DotsRuntimeCSharpProgram($"{LowLevelRoot}/Unity.LowLevel")
        {
            References = { UnsafeUtility.DotNetAssembly },
            Unsafe     = true
        };
        UnityLowLevel.NativeProgram.Libraries.Add(IsLinux, new SystemLibrary("dl"));

        ZeroJobs = new DotsRuntimeCSharpProgram($"{LowLevelRoot}/Unity.ZeroJobs")
        {
            References = { UnityLowLevel },
            Unsafe     = true
        };

        UnityCompilationPipeline = new DotNetAssembly(AsmDefConfigFile.UnityCompilationPipelineAssemblyPath, Framework.NetStandard20);

        var nunit = new StevedoreArtifact("nunit-framework");

        Backend.Current.Register(nunit);
        NUnitLite      = new DotNetAssembly(nunit.Path.Combine("bin", "net40", "nunitlite.dll"), Framework.Framework40);
        NUnitFramework = new DotNetAssembly(nunit.Path.Combine("bin", "net40", "nunit.framework.dll"), Framework.Framework40);

        //any asmdef that sits next to a .project file we will consider a tiny game.
        var asmDefDescriptions = AsmDefConfigFile.AssemblyDefinitions.ToArray();

        BurstCompiler.BurstExecutable = asmDefDescriptions.First(d => d.Name == "Unity.Burst")
                                        .Path.Parent.Parent.Combine(".Runtime/bcl.exe").QuoteForProcessStart();

        var ilPostProcessorPrograms = asmDefDescriptions.Where(d => d.Name.EndsWith(".CodeGen") && !d.DefineConstraints.Contains("!NET_DOTS")).Select(GetOrMakeDotsRuntimeCSharpProgramFor);

        ILPostProcessorAssemblies = ilPostProcessorPrograms.Select(p => p.SetupSpecificConfiguration(DotsConfigs.HostDotnet)).ToArray();
        PerConfigBuildSettings    = DotsConfigs.MakeConfigs();

        var tinyMainAsmDefs = asmDefDescriptions;//.Where(d => d.NamedReferences.Contains("Unity.Tiny.Main"));
        var gameAsmDefs     = tinyMainAsmDefs.Union(AsmDefConfigFile.TestableAssemblyDefinitions);
        var gamePrograms    = gameAsmDefs.Select(SetupGame).ExcludeNulls().ToArray();

        var vs = new VisualStudioSolution
        {
            Path = AsmDefConfigFile.UnityProjectPath.Combine($"{AsmDefConfigFile.ProjectName}-Dots.sln").RelativeTo(NPath.CurrentDirectory),
            DefaultSolutionFolderFor = file => (file.Name.Contains("Unity.") || file.Name == "mscorlib") ? "Unity" : ""
        };

        var unityToolsFolder            = "Unity/tools";
        var unityILPostProcessorsFolder = "Unity/ILPostProcessing";

        if (BeeRoot.IsChildOf(AsmDefConfigFile.UnityProjectPath))
        {
            var buildProjRef = new CSharpProjectFileReference("buildprogram.gen.csproj");
            vs.Projects.Add(buildProjRef, unityToolsFolder);
            vs.Projects.Add(buildProjRef, unityILPostProcessorsFolder);
        }

        foreach (var gameProgram in gamePrograms)
        {
            vs.Projects.Add(gameProgram);
        }

        var toolPrograms = new[]
        { TypeRegistrationTool.EntityBuildUtils, TypeRegistrationTool.TypeRegProgram };

        foreach (var p in toolPrograms)
        {
            vs.Projects.Add(p, unityToolsFolder);
        }

        vs.Projects.Add(ILPostProcessorTool.ILPostProcessorRunnerProgram, unityILPostProcessorsFolder);
        foreach (var p in ilPostProcessorPrograms)
        {
            vs.Projects.Add(p, unityILPostProcessorsFolder);
        }

        foreach (var config in PerConfigBuildSettings.SelectMany(entry => entry.Value))
        {
            //we want dotnet to be the default, and we cannot have nice things: https://aras-p.info/blog/2017/03/23/How-does-Visual-Studio-pick-default-config/platform/
            var solutionConfigName = config.Identifier == "dotnet" ? "Debug (dotnet)": config.Identifier;

            vs.Configurations.Add(new SolutionConfiguration(solutionConfigName, (configurations, file) =>
            {
                var firstOrDefault = configurations.FirstOrDefault(c => c == config);
                return(new Tuple <IProjectConfiguration, bool>(
                           firstOrDefault ?? configurations.First(),
                           firstOrDefault != null || toolPrograms.Any(t => t.ProjectFile == file)));
            }));
        }

        VisualStudioSolution = vs;

        EditorToolsBuildProgram.Setup(BeeRoot);

        // Run this before solution setup, to potentially give this a chance to muck with the VisualStudioSolution
        DotsBuildCustomizer.RunAllCustomizers();

        if (!IsRequestedTargetExactlySingleAppSingleConfig())
        {
            Backend.Current.AddAliasDependency("ProjectFiles", vs.Setup());
        }
    }
Example #2
0
    static void Main()
    {
        BeeRootValue = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Runtime.EntryPoint").Path.Parent.Parent.Combine("bee~");

        Backend.Current.StevedoreSettings = new StevedoreSettings
        {
            // Manifest entries always override artifact IDs hard-coded in Bee
            // Setting EnforceManifest to true will also ensure no artifacts
            // are used without being listed in a manifest.
            EnforceManifest = true,
            Manifest        =
            {
                BeeRootValue.Combine("manifest.stevedore"),
            },
        };

        // When bee needs to run a second time because the Tundra graph has suggested a need to rerun,
        // you cannot use LazyStatics or Statics in cases where you construct a program that gets compiled in the first run.
        // This is because previously bee when it ran a second time would spawn a new process of the buildprogram but in the
        // new bee we actually run it in the same process which means that you need to construct new programs or clear out old state.
        TinyIO         = null;
        UnityTinyBurst = null;

        UnityLowLevel             = null;
        ZeroJobs                  = null;
        ILPostProcessorAssemblies = null;

        ILPostProcessorTool._ilPostProcessorRunnerProgramInternal = null;

        _cache.Clear();
        DotsConfigs.Clear();

        CSharpProgram.DefaultConfig = new CSharpProgramConfiguration(CSharpCodeGen.Release);

        PerConfigBuildSettings = DotsConfigs.MakeConfigs();
        foreach (var rootAssemblyName in PerConfigBuildSettings.Keys)
        {
            AsmDefConfigFile.AsmDefDescriptionFor(rootAssemblyName).IsTinyRoot = true;
        }

        //any asmdef that sits next to a .project file we will consider a tiny game.
        var asmDefDescriptions = AsmDefConfigFile.AssemblyDefinitions.ToArray();
        var burstAsmDef        = asmDefDescriptions.First(d => d.Name == "Unity.Burst");
        var tinyIOAsmDef       = asmDefDescriptions.First(d => d.Name == "Unity.Tiny.IO");

        UnityLowLevel = new DotsRuntimeCSharpProgram($"{LowLevelRoot}/Unity.LowLevel")
        {
            References = { UnsafeUtility.Program },
            Unsafe     = true
        };
        UnityLowLevel.NativeProgram.Libraries.Add(IsLinux, new SystemLibrary("dl"));
        UnityLowLevel.NativeProgram.Libraries.Add(c => c.Platform is AndroidPlatform, new SystemLibrary("log"));

        TinyIO = GetOrMakeDotsRuntimeCSharpProgramFor(tinyIOAsmDef);

        UnityTinyBurst = new DotsRuntimeCSharpProgram($"{LowLevelRoot}/Unity.Tiny.Burst")
        {
            References = { UnityLowLevel },
            Unsafe     = true
        };

        ZeroJobs = new DotsRuntimeCSharpProgram($"{LowLevelRoot}/Unity.ZeroJobs")
        {
            References = { UnityLowLevel, UnityTinyBurst, GetOrMakeDotsRuntimeCSharpProgramFor(burstAsmDef), TinyIO },
            Unsafe     = true
        };

        UnityCompilationPipeline = new DotNetAssembly(
            AsmDefConfigFile.UnityCompilationPipelineAssemblyPath,
            HackedFrameworkToUseForProjectFilesIfNecessary);

        var nunit = new StevedoreArtifact("nunit-framework");

        NUnitLite      = new DotNetAssembly(nunit.Path.Combine("bin", "net40", "nunitlite.dll"), Framework.Framework471);
        NUnitFramework = new DotNetAssembly(nunit.Path.Combine("bin", "net40", "nunit.framework.dll"), Framework.Framework471);

        BurstCompiler.BurstExecutable = GetBurstExecutablePath(burstAsmDef).QuoteForProcessStart();

        var ilPostProcessorPrograms = asmDefDescriptions
                                      .Where(d => d.IsILPostProcessorAssembly)
                                      .Select(GetOrMakeDotsRuntimeCSharpProgramFor);

        ILPostProcessorAssemblies = ilPostProcessorPrograms.Select(p =>
        {
            /*
             * We want to compile the ilpp's for hostdotnet, even though we might be compiling the actual game
             * for something else (e.g. wasm). The ilpp's may reference actual game assemblies, which may have
             * native code. We do not want to set up the native code for those game assemblies for hostdotnet,
             * because a) it makes no sense and b) the native toolchains might not be installed, and it would be
             * dumb to require that to build for an unrelated platform.
             *
             * So, set the NativeProgramConfiguration to null, and set up with that. But first, set the platform,
             * because normally the platform comes from the npc.
             */
            var tmp      = DotsConfigs.HostDotnet;
            tmp.Platform = DotsConfigs.HostDotnet.Platform;
            tmp.NativeProgramConfiguration = null;
            var ret = p.SetupSpecificConfiguration(tmp);
            return(ret);
        })
                                    .ToArray();

        var tinyMainAsmDefs = asmDefDescriptions.Where(a => a.IsTinyRoot);
        var gameAsmDefs     = tinyMainAsmDefs.Union(AsmDefConfigFile.TestableAssemblyDefinitions);

        foreach (var gameAsmdef in gameAsmDefs)
        {
            var gameProgram = GetOrMakeDotsRuntimeCSharpProgramFor(gameAsmdef);
            if (gameProgram.AsmDefDescription.NeedsEntryPointAdded())
            {
                gameProgram.References.Add(
                    GetOrMakeDotsRuntimeCSharpProgramFor(
                        AsmDefConfigFile.AsmDefDescriptionFor("Unity.Runtime.EntryPoint")));
            }
        }
        var gamePrograms = gameAsmDefs.Select(SetupGame).ExcludeNulls().ToArray();


        var vs = new VisualStudioSolution {
            Path = AsmDefConfigFile.UnityProjectPath.Combine($"{AsmDefConfigFile.ProjectName}-Dots.sln").RelativeTo(NPath.CurrentDirectory),
            DefaultSolutionFolderFor = file => (file.Name.Contains("Unity.") || file.Name == "mscorlib") ? "Unity" : ""
        };

        var unityToolsFolder            = "Unity/tools";
        var unityILPostProcessorsFolder = "Unity/ILPostProcessing";

        if (BeeRoot.IsChildOf(AsmDefConfigFile.UnityProjectPath))
        {
            var buildProjRef = new CSharpProjectFileReference("buildprogram.gen.csproj");
            vs.Projects.Add(buildProjRef, unityToolsFolder);
        }
        foreach (var gameProgram in gamePrograms)
        {
            vs.Projects.Add(gameProgram);
        }

        var toolPrograms = new[]
        { TypeRegistrationTool.EntityBuildUtils, TypeRegistrationTool.TypeRegProgram };

        foreach (var p in toolPrograms)
        {
            vs.Projects.Add(p, unityToolsFolder);
        }

        vs.Projects.Add(ILPostProcessorTool.ILPostProcessorRunnerProgram, unityILPostProcessorsFolder);
        foreach (var p in ilPostProcessorPrograms)
        {
            vs.Projects.Add(p, unityILPostProcessorsFolder);
        }

        foreach (var config in PerConfigBuildSettings.SelectMany(entry => entry.Value))
        {
            //we want dotnet to be the default, and we cannot have nice things: https://aras-p.info/blog/2017/03/23/How-does-Visual-Studio-pick-default-config/platform/
            var solutionConfigName = config.Identifier == "dotnet" ? "Debug (dotnet)": config.Identifier;

            vs.Configurations.Add(new SolutionConfiguration(solutionConfigName, (configurations, file) =>
            {
                var firstOrDefault = configurations.FirstOrDefault(c => c == config);
                return(new Tuple <IProjectConfiguration, bool>(
                           firstOrDefault ?? configurations.First(),
                           firstOrDefault != null || toolPrograms.Any(t => t.ProjectFile == file)));
            }));
        }

        VisualStudioSolution = vs;
        EditorToolsBuildProgram.Setup(BeeRoot);

        // Run this before solution setup, to potentially give this a chance to muck with the VisualStudioSolution
        DotsBuildCustomizer.RunAllCustomizers();

        if (!IsRequestedTargetExactlySingleAppSingleConfig())
        {
            Backend.Current.AddAliasDependency("ProjectFiles", vs.Setup());
        }
    }