private static IFileBundle Il2CppFromSteve() { var stevedoreArtifact = new StevedoreArtifact("il2cpp"); Backend.Current.Register(stevedoreArtifact); return(stevedoreArtifact); }
public AndroidApkToolchain(AndroidNdk ndk) : base(ndk) { DynamicLibraryFormat = new AndroidApkDynamicLibraryFormat(this); ExecutableFormat = new AndroidApkMainModuleFormat(this); var sdk = new StevedoreArtifact(HostPlatform.Pick( linux: "android-sdk-linux-x86_64", mac: "android-sdk-darwin-x86_64", windows: "android-sdk-windows-x86_64" )); var jdk = new StevedoreArtifact(HostPlatform.Pick( linux: "open-jdk-linux-x64", mac: "open-jdk-mac-x64", windows: "open-jdk-win-x64" )); Backend.Current.Register(sdk); SdkPath = sdk.Path; Backend.Current.Register(jdk); JavaPath = jdk.Path; var gradle = new StevedoreArtifact("gradle"); Backend.Current.Register(gradle); GradlePath = gradle.Path; }
private static IFileBundle Il2CppDepsFromSteve() { var stevedoreArtifact = new StevedoreArtifact("MonoBleedingEdgeSub"); Backend.Current.Register(stevedoreArtifact); return(stevedoreArtifact); }
private static NPath GetOrCreateSteveArtifactPath(String name) { if (!ArtifactPaths.ContainsKey(name)) { var artifact = new StevedoreArtifact(name); ArtifactPaths[name] = artifact.Path; } return(ArtifactPaths[name]); }
protected override void SetupReferences() { base.SetupReferences(); var cecilArtifact = StevedoreArtifact.Testing("unity-cecil/b093701f8ba7b54aea0c62ac08f376b783a0cf98_b3fb8db6e2d68564c9e28c3713b6f742d4c928aef8a420028d3a149af7d67152.zip"); Backend.Current.Register(cecilArtifact); References.Add(cecilArtifact.Path.Combine("lib", "net40", "Unity.Cecil.dll")); References.Add(cecilArtifact.Path.Combine("lib", "net40", "Unity.Cecil.Rocks.dll")); References.Add(cecilArtifact.Path.Combine("lib", "net40", "Unity.Cecil.Mdb.dll")); References.Add(cecilArtifact.Path.Combine("lib", "net40", "Unity.Cecil.Pdb.dll")); }
static void SetupGetEditorToolsFromStevedore() { // since this target and `get-editor-tools` target outputs the same files // we cannot have these two targets side by side in the dag. // We need this to generate the only correct target if (CompileEditorToolsFromSourceFileFlag.FileExists()) { return; } var executablesFromEditorTools = new HashSet <string> { "artifacts/Stevedore/dots-editor-tools/images/osx/cwebp", "artifacts/Stevedore/dots-editor-tools/images/osx/moz-cjpeg", "artifacts/Stevedore/dots-editor-tools/images/osx/pngcrush", "artifacts/Stevedore/dots-editor-tools/manager/DotsEditorTools-macos", }; var EditorTools = new StevedoreArtifact("dots-editor-tools"); Backend.Current.Register(EditorTools); var dependencies = new List <NPath>(); foreach (var file in EditorTools.GetFileList()) { var target = new NPath(file.ToString().Replace(EditorTools.Path.ToString(), InstallationDirectory.ToString())); if ((HostPlatform.IsOSX || HostPlatform.IsLinux) && executablesFromEditorTools.Contains(file.ToString())) { Backend.Current.AddAction("copy and chmod +x", new[] { target }, new[] { file }, $"cp {file.InQuotes()} {target.InQuotes()} && chmod +x {target.InQuotes()}", Array.Empty <string>()); } else { CopyTool.Instance().Setup(target, file); } dependencies.Add(target); } Backend.Current.AddAliasDependency("get-editor-tools", dependencies.ToArray()); }
public static NPath GetUnusualPath(this StevedoreArtifact artifact) { var path = new NPath("artifacts").Combine("Stevedore", artifact.ArtifactName); return(path); }
public BgfxBuild() { var rendererRoot = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Tiny.Rendering.Native").Directory; bool useLocalBgfx = false; BgfxArtifact = new StevedoreArtifact("bgfx-source"); BgfxRoot = BgfxArtifact.Path.ResolveWithFileSystem(); //BgfxRoot = @"C:\Users\sebastianm\gits\bgfx-root"; //useLocalBgfx = true; var bx = BgfxRoot.Combine("bx"); var bgfx = BgfxRoot.Combine("bgfx"); var bimg = BgfxRoot.Combine("bimg"); // Note that these 3 NativePrograms are only linked in as BagOfObjects into the bgfx dll above. // They should not have Libraries themselves (e.g. bgfx should not reference the bx or bimg NativePrograms). // This means that PublicIncludes won't work, which is why Bimg and Bgfx explicitly add BxLib's PublicIncludes // to their own Includes. BxLib = new NativeProgram("bx") { Exceptions = { false }, RTTI = { false }, PublicIncludeDirectories = { bx.Combine("include"), bx.Combine("3rdparty"), }, Sources = { //bx.Combine("src").Files("*.cpp").Except(new[] {bx.Combine("src/amalgamated.cpp"), bx.Combine("src/crtnone.cpp")}) bx.Combine("src/amalgamated.cpp") }, Defines = { "__STDC_FORMAT_MACROS" }, }; BxLib.CompilerSettings().Add(c => c.WithCppLanguageVersion(CppLanguageVersion.Cpp14)); BxLib.CompilerSettingsForMac().Add(c => c.WithObjcArc(false)); BxLib.CompilerSettingsForIos().Add(c => c.WithObjcArc(false)); BxLib.Defines.Add(c => c.Platform is WindowsPlatform, "_CRT_SECURE_NO_WARNINGS"); BxLib.PublicIncludeDirectories.Add(c => c.ToolChain is WindowsToolchain, bx.Combine("include/compat/msvc")); BxLib.PublicIncludeDirectories.Add(c => c.Platform is MacOSXPlatform, bx.Combine("include/compat/osx")); BxLib.PublicIncludeDirectories.Add(c => c.Platform is IosPlatform, bx.Combine("include/compat/ios")); BxLib.CompilerSettingsForEmscripten().Add(Il2Cpp.ManagedDebuggingIsEnabled, c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled)); BimgLib = new NativeProgram("bimg") { Exceptions = { false }, RTTI = { false }, IncludeDirectories = { bimg.Combine("include"), bimg.Combine("3rdparty/astc-codec/include"), // comment out next line once BIMG_DECODE_ASTC lands in bimg bimg.Combine("3rdparty/astc-codec"), }, Sources = { bimg.Combine("src/image.cpp"), bimg.Combine("src/image_gnf.cpp"), // comment out next line once BIMG_DECODE_ASTC lands in bimg bimg.Combine("3rdparty/astc-codec/src/decoder").CombineMany(new [] { "astc_file.cc","codec.cc", "endpoint_codec.cc", "footprint.cc", "integer_sequence_codec.cc", "intermediate_astc_block.cc", "logical_astc_block.cc", "partition.cc", "physical_astc_block.cc", "quantization.cc", "weight_infill.cc" }) }, Defines = { "__STDC_FORMAT_MACROS", "BIMG_DECODE_ENABLE=0" }, }; BimgLib.CompilerSettings().Add(c => c.WithCppLanguageVersion(CppLanguageVersion.Cpp14)); BimgLib.CompilerSettingsForMac().Add(c => c.WithObjcArc(false)); BimgLib.CompilerSettingsForIos().Add(c => c.WithObjcArc(false)); BimgLib.IncludeDirectories.Add(c => BxLib.PublicIncludeDirectories.For(c)); BimgLib.CompilerSettingsForEmscripten().Add(Il2Cpp.ManagedDebuggingIsEnabled, c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled)); BgfxLib = new NativeProgram("bgfx") { Exceptions = { false }, RTTI = { false }, IncludeDirectories = { bimg.Combine("include"), bgfx.Combine("include"), bgfx.Combine("3rdparty"), bgfx.Combine("3rdparty/khronos"), rendererRoot.Combine("cpp~/include"), }, Defines = { "BGFX_SHARED_LIB_BUILD", "__STDC_FORMAT_MACROS" }, }; BgfxLib.CompilerSettings().Add(c => c.WithCppLanguageVersion(CppLanguageVersion.Cpp14)); BgfxLib.CompilerSettingsForMac().Add(c => c.WithObjcArc(false)); BgfxLib.CompilerSettingsForIos().Add(c => c.WithObjcArc(false)); BgfxLib.IncludeDirectories.Add(c => BxLib.PublicIncludeDirectories.For(c)); BgfxLib.Defines.Add(c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.Defines.Contains("RENDERING_ENABLE_TRACE"), "BGFX_CONFIG_DEBUG=1"); BgfxLib.Defines.Add(c => c.ToolChain is WindowsToolchain, "_CRT_SECURE_NO_WARNINGS"); //BgfxLib.Defines.Add("BGFX_CONFIG_DEBUG_UNIFORM=0"); if (!useLocalBgfx) { // when using bgfx from stevedore, this requires pix3.h which we don't distribute BgfxLib.Defines.Add(c => c.Platform is WindowsPlatform, "BGFX_CONFIG_DEBUG_ANNOTATION=0"); } else { BgfxLib.Defines.Add(c => c.Platform is WindowsPlatform, "BGFX_CONFIG_DEBUG_ANNOTATION=0"); ///BgfxLib.IncludeDirectories.Add(bgfx.Combine("3rdparty/dxsdk")); } BgfxLib.Defines.Add("BGFX_CONFIG_MAX_BONES=4"); BgfxLib.Defines.Add(c => (c as DotsRuntimeNativeProgramConfiguration)?.CSharpConfig.EnableProfiler == true, "BGFX_CONFIG_PROFILER=1"); // At some point we need to stop using amalgamated, especially for small-size web builds BgfxLib.Sources.Add(c => !(c.Platform is MacOSXPlatform || c.Platform is IosPlatform), bgfx.Combine("src/amalgamated.cpp")); BgfxLib.Sources.Add(c => (c.Platform is MacOSXPlatform || c.Platform is IosPlatform), bgfx.Combine("src/amalgamated.mm")); // This is a hack that the Khronos eglplatform.h header understands in order to define the EGL types as intptr_t, // which is what emscripten wants. Otherwise we fall into a __unix__ path, which includes X11/Xlib.h, and // all hell breaks loose. BgfxLib.Defines.Add(c => c.Platform is WebGLPlatform, "USE_OZONE"); BgfxLib.CompilerSettingsForEmscripten().Add(Il2Cpp.ManagedDebuggingIsEnabled, c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled)); }
public static NPath GenerateUnusualPath(this StevedoreArtifact artifact) { var path = new NPath("artifacts").Combine("Stevedore", artifact.ArtifactName); return(artifact.UnpackToUnusualLocation(path)); }
static void Main() { BeeRootValue = BuildProgramConfigFile.AsmDefDescriptionFor("Unity.Tiny.Text").Path.Parent.Parent.Parent.Combine("DotsPlayer/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 }; ZeroJobs = new DotsRuntimeCSharpProgram(BeeRoot.Parent.Combine("ZeroJobs"), "Unity.ZeroJobs") { References = { UnityLowLevel }, Unsafe = true }; 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 = BuildProgramConfigFile.AssemblyDefinitions.ToArray(); var gameAsmDefs = asmDefDescriptions.Where(d => d.Path.Parent.Files("*.project").Any()); var gamePrograms = gameAsmDefs.Select(SetupGame).ToArray(); //any asmdef that has .Tests in its name, is going to be our indicator for being a test project for now. var testAsmDefs = asmDefDescriptions.Where(ad => ad.Name.EndsWith(".Tests")); var testPrograms = testAsmDefs.Where(asm => asm.PackageSource != "BuiltIn" && asm.PackageSource != "Registry") .Select(SetupTest) .ExcludeNulls() .ToArray(); var vs = new VisualStudioSolution() { Path = BuildProgramConfigFile.UnityProjectPath.Combine($"{BuildProgramConfigFile.ProjectName}-Dots.sln").RelativeTo(NPath.CurrentDirectory), DefaultSolutionFolderFor = file => (file.Name.Contains("Unity.") || file.Name == "mscorlib") ? "Unity" : "" }; var unityToolsFolder = "Unity/tools"; if (BeeRoot.IsChildOf(BuildProgramConfigFile.UnityProjectPath)) { vs.Projects.Add(new CSharpProjectFileReference("buildprogram.gen.csproj"), unityToolsFolder); } foreach (var gameProgram in gamePrograms) { vs.Projects.Add(gameProgram); } foreach (var testProgram in testPrograms) { vs.Projects.Add(testProgram); } var toolPrograms = new[] { TypeRegistrationTool.EntityBuildUtils, TypeRegistrationTool.TypeRegProgram, BindGem.Instance().Program }; if (BeeRoot.IsChildOf(BuildProgramConfigFile.UnityProjectPath)) { foreach (var p in toolPrograms) { vs.Projects.Add(p, unityToolsFolder); } } foreach (var config in DotsConfigs.Configs) { //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))); })); } Backend.Current.AddAliasDependency("ProjectFiles", vs.Setup()); EditorToolsBuildProgram.Setup(BeeRoot); }
public static EmscriptenToolchain MakeEmscripten(EmscriptenArchitecture arch) { var emscripten = new StevedoreArtifact("emscripten"); var emscriptenVersion = new Version(1, 38, 28); var emscriptenRoot = emscripten.Path.Combine("emscripten-nightly-1.38.28-2019_04_05_07_52"); EmscriptenSdk sdk = null; if (Environment.GetEnvironmentVariable("EMSDK") != null) { Console.WriteLine("Using pre-set environment EMSDK=" + Environment.GetEnvironmentVariable("EMSDK") + ". This should only be used for local development. Unset EMSDK env. variable to use tagged Emscripten version from Stevedore."); NodeExe = Environment.GetEnvironmentVariable("EMSDK_NODE"); return(new EmscriptenToolchain(new EmscriptenSdk( Environment.GetEnvironmentVariable("EMSCRIPTEN"), llvmRoot: Environment.GetEnvironmentVariable("LLVM_ROOT"), pythonExe: Environment.GetEnvironmentVariable("EMSDK_PYTHON"), nodeExe: Environment.GetEnvironmentVariable("EMSDK_NODE"), architecture: arch, // Use a dummy/hardcoded version string to represent Emscripten "incoming" branch (it should be always considered // a "dirty" branch that does not correspond to any tagged release) version: new Version(9, 9, 9), isDownloadable: false ))); } if (HostPlatform.IsWindows) { var llvm = new StevedoreArtifact("emscripten-llvm-win-x64"); var python = new StevedoreArtifact("winpython2-x64"); var node = new StevedoreArtifact("node-win-x64"); NodeExe = node.Path.Combine("node.exe"); sdk = new EmscriptenSdk( emscriptenRoot, llvmRoot: llvm.Path.Combine("emscripten-llvm-e1.38.28-2019_04_05_07_52"), pythonExe: python.Path.Combine("WinPython-64bit-2.7.13.1Zero/python-2.7.13.amd64/python.exe"), nodeExe: NodeExe, architecture: arch, version: emscriptenVersion, isDownloadable: true, backendRegistrables: new[] { emscripten, llvm, python, node }); } if (HostPlatform.IsLinux) { var llvm = new StevedoreArtifact("emscripten-llvm-linux-x64"); var node = new StevedoreArtifact("node-linux-x64"); NodeExe = node.Path.Combine("bin/node"); sdk = new EmscriptenSdk( emscriptenRoot, llvmRoot: llvm.Path.Combine("emscripten-llvm-e1.38.28-2019_03_07_23_26"), pythonExe: "/usr/bin/python2", nodeExe: NodeExe, architecture: arch, version: emscriptenVersion, isDownloadable: true, backendRegistrables: new[] { emscripten, llvm, node }); } if (HostPlatform.IsOSX) { var llvm = new StevedoreArtifact("emscripten-llvm-mac-x64"); var node = new StevedoreArtifact("node-mac-x64"); NodeExe = node.Path.Combine("bin/node"); sdk = new EmscriptenSdk( emscriptenRoot: emscriptenRoot, llvmRoot: llvm.Path.Combine("emscripten-llvm-e1.38.28-2019_04_05_07_52"), pythonExe: "/usr/bin/python", nodeExe: NodeExe, architecture: arch, version: emscriptenVersion, isDownloadable: true, backendRegistrables: new[] { emscripten, llvm, node }); } if (sdk == null) { return(null); } return(new EmscriptenToolchain(sdk)); }
public static EmscriptenToolchain MakeEmscripten(EmscriptenArchitecture arch) { var emscripten = new StevedoreArtifact("emscripten-" + EmscriptenPackageOSName()); var llvm = new StevedoreArtifact("emscripten-" + (UseWasmBackend ? "wasm" : "fc") + "-llvm-" + EmscriptenPackageOSName()); var emscriptenVersion = new Version(1, 39, 17); emscripten.GenerateUnusualPath(); var emscriptenRoot = emscripten.GetUnusualPath(); var llvmPath = llvm.Path.ResolveWithFileSystem(); EmscriptenSdk sdk = null; if (Environment.GetEnvironmentVariable("EMSDK") != null) { Console.WriteLine("Using pre-set environment EMSDK=" + Environment.GetEnvironmentVariable("EMSDK") + ". This should only be used for local development. Unset EMSDK env. variable to use tagged Emscripten version from Stevedore."); NodeExe = Environment.GetEnvironmentVariable("EMSDK_NODE"); sdk = new EmscriptenSdk( Environment.GetEnvironmentVariable("EMSCRIPTEN"), llvmRoot: Environment.GetEnvironmentVariable("LLVM_ROOT"), pythonExe: Environment.GetEnvironmentVariable("EMSDK_PYTHON"), nodeExe: NodeExe, architecture: arch, // Use a dummy/hardcoded version string to represent Emscripten "incoming" branch (it should be always considered // a "dirty" branch that does not correspond to any tagged release) version: new Version(9, 9, 9), isDownloadable: false ); } else if (HostPlatform.IsWindows) { var python = new StevedoreArtifact("winpython2-x64"); var node = new StevedoreArtifact("node-win-x64"); node.GenerateUnusualPath(); NodeExe = node.GetUnusualPath().Combine("node.exe"); var pythonPath = python.Path.Combine("WinPython-64bit-2.7.13.1Zero/python-2.7.13.amd64/python.exe").ResolveWithFileSystem(); sdk = new EmscriptenSdk( emscriptenRoot, llvmRoot: llvmPath, pythonExe: pythonPath, nodeExe: NodeExe, architecture: arch, version: emscriptenVersion, isDownloadable: true ); } else if (HostPlatform.IsLinux) { var node = new StevedoreArtifact("node-linux-x64"); node.GenerateUnusualPath(); NodeExe = node.GetUnusualPath().Combine("bin/node"); sdk = new EmscriptenSdk( emscriptenRoot, llvmRoot: llvmPath, pythonExe: "/usr/bin/python2", nodeExe: NodeExe, architecture: arch, version: emscriptenVersion, isDownloadable: true ); } else if (HostPlatform.IsOSX) { var node = new StevedoreArtifact("node-mac-x64"); node.GenerateUnusualPath(); NodeExe = node.GetUnusualPath().Combine("bin/node"); sdk = new EmscriptenSdk( emscriptenRoot: emscriptenRoot, llvmRoot: llvmPath, pythonExe: "/usr/bin/python", nodeExe: NodeExe, architecture: arch, version: emscriptenVersion, isDownloadable: true ); } if (sdk == null) { return(null); } // All Emsdk components are already pre-setup, so no need to verify the environment. // This avoids issues reported in https://github.com/emscripten-core/emscripten/issues/5042 // (macOS Java check dialog popping up and slight slowdown in compiler invocation times) // BUG: this does not actually work. Emcc is not a child of the Bee build process. // Switch to use something else. // if (Environment.GetEnvironmentVariable("EMCC_SKIP_SANITY_CHECK") == null) // Environment.SetEnvironmentVariable("EMCC_SKIP_SANITY_CHECK", "1"); return(new EmscriptenToolchain(sdk)); }
public static void Add(NativeProgram np) { var allPlatforms = new [] { "Android", "Linux", "Windows", "OSX", "IOS", "WebGL" }; var staticPlatforms = new[] { "IOS", "WebGL", }; var allArtifact = new StevedoreArtifact("nativejobs-all-public"); Backend.Current.Register(allArtifact); np.PublicIncludeDirectories.Add(allArtifact.Path.Combine("Include")); DotsConfiguration DotsConfig(NativeProgramConfiguration npc) => ((DotsRuntimeNativeProgramConfiguration)npc).CSharpConfig.DotsConfiguration; foreach (var platform in allPlatforms) { var platformIncludes = new StevedoreArtifact($"nativejobs-{platform}-public"); var prebuiltLibName = $"nativejobs-{platform}" + (staticPlatforms.Contains(platform) ? "-s" : "-d"); var prebuiltLib = new StevedoreArtifact(prebuiltLibName); Backend.Current.Register(platformIncludes); Backend.Current.Register(prebuiltLib); np.PublicDefines.Add(c => c.Platform.Name == platform, "BASELIB_USE_DYNAMICLIBRARY=1"); np.PublicIncludeDirectories.Add(c => c.Platform.Name == platform, platformIncludes.Path.Combine("Platforms", platform, "Include")); switch (platform) { case "Windows": np.Libraries.Add(c => c.Platform.Name == platform, c => new[] { new MsvcDynamicLibrary(prebuiltLib.Path.Combine("lib", platform.ToLower(), BaselibArchitectureName(c), DotsConfig(c).ToString().ToLower(), "nativejobs.dll")) }); break; case "Linux": case "Android": np.Libraries.Add(c => c.Platform.Name == platform, c => new[] { new DynamicLibrary(prebuiltLib.Path.Combine("lib", platform.ToLower(), BaselibArchitectureName(c), DotsConfig(c).ToString().ToLower(), "libnativejobs.so")) }); break; case "OSX": np.Libraries.Add(c => c.Platform.Name == platform, c => new[] { new DynamicLibrary(prebuiltLib.Path.Combine("lib", platform.ToLower(), BaselibArchitectureName(c), DotsConfig(c).ToString().ToLower(), "libnativejobs.dylib")) }); break; case "IOS": // this is ugly solution, but I don't see any other way to add static librray to Deployables np.Libraries.Add(c => c.Platform.Name == platform, c => new[] { new DynamicLibrary(prebuiltLib.Path.Combine("lib", platform.ToLower(), BaselibArchitectureName(c), DotsConfig(c).ToString().ToLower(), "libnativejobs.a")) }); break; case "WebGL": np.Libraries.Add(c => c.Platform.Name == platform, c => new[] { new StaticLibrary(prebuiltLib.Path.Combine("lib", platform.ToLower(), BaselibArchitectureName(c), DotsConfig(c).ToString().ToLower(), "libnativejobs.bc")) }); break; } } }
public static NativeProgram SetupGLFW() { var glfwArtifacts = new StevedoreArtifact("glfw"); Backend.Current.Register(glfwArtifacts); var glfwRoot = glfwArtifacts.Path; var glfwLib = new NativeProgram("libglfw") { //RootDirectory = glfwRoot, IncludeDirectories = { glfwRoot.Combine("include"), glfwRoot.Combine("src"), }, PublicIncludeDirectories = { glfwRoot.Combine("include") }, Sources = { }, }; glfwLib.Defines.Add(c => c.CodeGen != CodeGen.Debug, "NDEBUG"); glfwLib.Sources.Add(glfwRoot.Combine("src").CombineMany(new string[] { "context.c", "init.c", "input.c", "monitor.c", "vulkan.c", "window.c", })); // // Windows // glfwLib.Defines.Add(c => c.Platform is WindowsPlatform, "_GLFW_WIN32", "_GLFW_BUILD_DLL"); glfwLib.Sources.Add(c => c.Platform is WindowsPlatform, glfwRoot.Combine("src").CombineMany(new string[] { "win32_init.c", "win32_joystick.c", "win32_monitor.c", "win32_time.c", "win32_thread.c", "win32_window.c", "wgl_context.c", "egl_context.c", "osmesa_context.c" })); glfwLib.Libraries.Add(c => c.Platform is WindowsPlatform, new List <string> { "winmm", "gdi32", "opengl32", "user32", "winspool", "shell32", "uuid", "comdlg32", "advapi32" } .ConvertAll(s => new SystemLibrary(s + ".lib")) ); // // Linux // glfwLib.Defines.Add(c => c.Platform is LinuxPlatform, new string[] { "_GLFW_X11", "IL_NO_UTX" }); glfwLib.Sources.Add(c => c.Platform is LinuxPlatform, glfwRoot.Combine("src").CombineMany(new string[] { "input.c", "linux_joystick.c", "x11_init.c", "x11_monitor.c", "x11_window.c", "xkb_unicode.c", "egl_context.c", "glx_context.c", "osmesa_context.c", "posix_thread.c", "posix_time.c" })); glfwLib.Libraries.Add(c => c.Platform is LinuxPlatform, new List <string> { "GL", "X11", "udev", "Xrandr", "dl", "rt" } .ConvertAll(s => new SystemLibrary(s))); // // Mac/iOS // glfwLib.Defines.Add(c => c.Platform is MacOSXPlatform, new string[] { "_GLFW_COCOA" }); glfwLib.Sources.Add(c => c.Platform is MacOSXPlatform, glfwRoot.Combine("src").CombineMany(new string[] { "cocoa_init.m", "cocoa_joystick.m", "cocoa_monitor.m", "cocoa_window.m", "cocoa_time.c", "posix_thread.c", "nsgl_context.m", "egl_context.c", "osmesa_context.c" })); glfwLib.Libraries.Add(c => c.Platform is MacOSXPlatform, new List <string> { "OpenGL", "CoreFoundation", "IOKit", "Cocoa", "CoreData", "CoreVideo" } .ConvertAll(s => new SystemFramework(s))); return(glfwLib); }
private static IFileBundle Il2CppFromSteve() { var stevedoreArtifact = new StevedoreArtifact("il2cpp"); return(stevedoreArtifact); }
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()); } }
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); }
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()); } }