private static string ComputeCustomLocation() { string path = null; // Set local il2cpp path here if (path != null) { return(path); } string envPath = Environment.GetEnvironmentVariable("IL2CPP_FROM_LOCAL"); // Set in CI for testing if (envPath != null) { return(envPath); } // look for a magic asmdef for devmode var asmdef = AsmDefConfigFile.AsmDefDescriptionFor("Il2Cpp.Devmode"); if (asmdef != null) { // make sure it's configured var il2cppPath = asmdef.Path.Parent.Parent.Parent; var exePath = il2cppPath.Combine("build/deploy/net471/il2cpp.exe"); if (!exePath.Exists()) { throw new ArgumentException( $"You have an Il2Cpp.Devmode asmdef in a package you have referenced, but we couldn't find an il2cpp.exe at {exePath}. Either il2cpp isn't actually under devmode (don't reference the package if not), or you didn't build it (run perl build.sh inside PackageSources/il2cpp)"); } return(il2cppPath.ToString()); } return(null); }
//Run ./bee build-lib-webp to compile the webp library located in Unity.Tiny.Image2D.Native.cpp~/libwebp and copy it to Unity.Tiny.Image2D.Authoring/libwebp public override void Customize() { var asmdefRoot = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Tiny.Image2D.Native").Directory; var outputDirectory = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Tiny.Image2D.Authoring").Directory; NativeProgram WebPLib = new NativeProgram("libwebp") { Sources = { asmdefRoot.Combine("cpp~/libwebp"), }, IncludeDirectories = { asmdefRoot.Combine("cpp~/libwebp") }, OutputDirectory = { outputDirectory.Combine("libwebp") } }; DotsRuntimeNativeProgramConfiguration config = DotsConfigs.HostDotnet.NativeProgramConfiguration; var builtWebPLib = WebPLib.SetupSpecificConfiguration(config, config.ToolChain.DynamicLibraryFormat); Backend.Current.AddAliasDependency("build-lib-webp", builtWebPLib.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 Dictionary <string, List <DotsRuntimeCSharpProgramConfiguration> > MakeConfigs() { var platformList = DotsBuildSystemTargets; var settingsDir = new NPath("settings"); if (settingsDir.Exists()) { foreach (var settingsRelative in settingsDir.Files("*.json")) { var settingsFile = settingsRelative.MakeAbsolute(); if (settingsFile.Exists()) { Backend.Current.RegisterFileInfluencingGraph(settingsFile); var settingsObject = new FriendlyJObject { Content = JObject.Parse(settingsFile.ReadAllText()) }; if (settingsObject.GetInt("Version", 0) != AsmDefConfigFile.BuildSettingsFileVersion || AsmDefConfigFile.AsmDefDescriptionFor(settingsObject.GetString("RootAssembly")) == null) { Console.WriteLine($"Found old settings file '{settingsFile}', removing..."); settingsFile.Delete(); continue; } var id = settingsObject.GetString("PlatformTargetIdentifier"); var target = platformList.Single(t => t.Identifier == id); if (!target.ToolChain.CanBuild) { continue; } // Need to know this prior to determining need for burst var mdb = ShouldEnableDevelopmentOptionForSetting("EnableManagedDebugging", new[] { DotsConfiguration.Debug, DotsConfiguration.Develop }, settingsObject); if (!target.ValidateManagedDebugging(ref mdb)) { continue; } if (mdb && DotsConfigForSettings(settingsObject, out var codeGen) == DotsConfiguration.Debug && target.ScriptingBackend == ScriptingBackend.TinyIl2cpp) { Errors.PrintWarning("Debug builds with managed debugging are very slow. It's recommended to use the Develop configuration instead."); } var multithreading = settingsObject.GetBool("EnableMultithreading"); var targetUsesBurst = settingsObject.GetBool("EnableBurst"); if (!targetUsesBurst && multithreading) { // We currently do not support multithreaded debugging anywhere except .NET Framework and CoreCLR (so, Windows only) // or il2cpp full profile bool isFullIl2cpp = target.ScriptingBackend == ScriptingBackend.TinyIl2cpp && mdb; bool isWindows = target.ToolChain.Platform is WindowsPlatform; if (!(isFullIl2cpp || isWindows)) { Errors.PrintWarning($"BuildConfiguration '{settingsFile.FileNameWithoutExtension}' " + $"specified 'EnableBurst=False', but 'Multithreading=True'. Multithreading requires Burst, therefore enabling Burst."); targetUsesBurst = true; } } var dotsCfg = DotsConfigForSettings(settingsObject, out var codegen); var enableProfiler = ShouldEnableDevelopmentOptionForSetting("EnableProfiler", new [] { DotsConfiguration.Develop }, settingsObject); var enableUnityCollectionsChecks = ShouldEnableDevelopmentOptionForSetting("EnableSafetyChecks", new[] { DotsConfiguration.Debug, DotsConfiguration.Develop }, settingsObject); if (!target.CanUseBurst && targetUsesBurst) { Console.WriteLine($"Warning: BuildConfiguration '{settingsFile.FileNameWithoutExtension}' " + $"specified 'EnableBurst', but target ({target.Identifier}) does not support burst yet. Not using burst."); targetUsesBurst = false; } // Workaround to disable burst in web debug builds since it will fail to compile // https://unity3d.atlassian.net/browse/DOTSR-1886 if (targetUsesBurst && target is DotsWebTarget && codegen == CSharpCodeGen.Debug) { Console.WriteLine($"Warning: Web currently does not support building in debug configuration with Burst. Disabling burst...."); targetUsesBurst = false; } var waitForManagedDebugger = settingsObject.GetBool("WaitForManagedDebugger"); var rootAssembly = settingsObject.GetString("RootAssembly"); string finalOutputDir = null; if (settingsObject.Content.TryGetValue("FinalOutputDirectory", out var finalOutputToken)) { finalOutputDir = finalOutputToken.Value <string>(); } var defines = new List <string>(); if (settingsObject.Content.TryGetValue("ScriptingDefines", out var definesJToken)) { defines = ((JArray)definesJToken).Select(token => token.Value <string>()).ToList(); } if (!PerConfigBuildSettings.ContainsKey(rootAssembly)) { PerConfigBuildSettings[rootAssembly] = new List <DotsRuntimeCSharpProgramConfiguration>(); } var identifier = settingsFile.FileNameWithoutExtension; do { PerConfigBuildSettings[rootAssembly] .Add( target.CustomizeConfigForSettings(new DotsRuntimeCSharpProgramConfiguration( csharpCodegen: codegen, cppCodegen: codegen == CSharpCodeGen.Debug ? CodeGen.Debug : CodeGen.Release, nativeToolchain: target.ToolChain, scriptingBackend: target.ScriptingBackend, targetFramework: target.TargetFramework, identifier: identifier, enableUnityCollectionsChecks: enableUnityCollectionsChecks, enableManagedDebugging: mdb, waitForManagedDebugger: waitForManagedDebugger, multiThreadedJobs: multithreading, dotsConfiguration: dotsCfg, enableProfiler: enableProfiler, useBurst: targetUsesBurst, defines: defines, finalOutputDirectory: finalOutputDir), settingsObject)); //We have to introduce the concept of "complementary targets" to accommodate building "fat" binaries on Android, //for both armv7 and arm64 architectures. This means we have to build two copies of the final binaries, and then do one //packaging step to package both steps into a single apk. But also, since C# code is allowed to do #if UNITY_DOTSRUNTIME64 //(and indeed we need that ability for the static type registry to generate correct sizes of things), we need to compile //two sets of c# assemblies, one per architecture, and run il2cpp and burst on each one separately, in order to produce //these two sets of final binaries. //For that purpose, we associate a second DotsRuntimeCSharpProgramConfiguration (known as the complementary target) to //specify the build for the other architecture we wish to compile against, and we do all the building steps up to the final //packaging step for that config as well as the main one. We skip the final packaging step for the complementary config, //and make the packaging step for the main config consume both sets of binaries. //This is a crazy scheme, and we theorize and hope that when we adopt the incremental buildpipeline, we will be able //to use their concept of per-platform custom graph build steps to make this be more reasonable. target = target.ComplementaryTarget; //We use "identifier" as a directory name for all intermediate files. //For complementary target these files will be generated in "target.Identifier" subdirectory. //So for example in case of arm64 complemenary target a path would be //"{target.Identifiler}/android_complementary_arm64". if (target != null) { identifier += "/" + target.Identifier; } } while (target != null); } } } return(PerConfigBuildSettings); }
private NPath GenerateXCodeProject(NPath mainLibPath) { var outputPath = mainLibPath.Parent; var iosPlatformPath = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Build.iOS.DotsRuntime").Path.Parent; var xcodeSrcPath = iosPlatformPath.Combine(TinyProjectName + "~"); var xcodeprojPath = outputPath.Combine($"{TinyProjectName}.xcodeproj"); // copy and patch pbxproj file var pbxPath = xcodeprojPath.Combine("project.pbxproj"); var pbxTemplatePath = xcodeSrcPath.Combine($"{TinyProjectName}.xcodeproj", "project.pbxproj"); var result = SetupXCodeProject(pbxTemplatePath); Backend.Current.AddWriteTextAction(pbxPath, result); m_projectFiles.Add(pbxPath); m_projectFiles.Add(mainLibPath); // copy and patch xcscheme file var xcschemePath = xcodeprojPath.Combine("xcshareddata", "xcschemes", "Tiny-iPhone.xcscheme"); var xcschemeTemplatePath = xcodeSrcPath.Combine($"{TinyProjectName}.xcodeproj", "xcshareddata", "xcschemes", "Tiny-iPhone.xcscheme"); result = SetupXcScheme(xcschemeTemplatePath, m_config == DotsConfiguration.Release); Backend.Current.AddWriteTextAction(xcschemePath, result); m_projectFiles.Add(xcschemePath); // copy and patch Info.plist file var plistPath = outputPath.Combine("Sources", "Info.plist"); var plistTemplatePath = xcodeSrcPath.Combine("Sources", "Info.plist"); result = SetupInfoPlist(plistTemplatePath); Backend.Current.AddWriteTextAction(plistPath, result); m_projectFiles.Add(plistPath); // copy xcodeproj files foreach (var r in xcodeSrcPath.Files(true)) { if (r.Extension != "pbxproj" && r.Extension != "xcscheme" && r.FileName != "Info.plist" && !r.HasDirectory("AppIcon.appiconset")) { var destPath = outputPath.Combine(r.RelativeTo(xcodeSrcPath)); destPath = CopyTool.Instance().Setup(destPath, r); m_projectFiles.Add(destPath); } } // copy icon files var icons = IOSAppToolchain.Config.Icons; CopyIcon(xcodeSrcPath, outputPath, "Icon-iPhone-120.png", icons.iPhone2x); CopyIcon(xcodeSrcPath, outputPath, "Icon-iPhone-180.png", icons.iPhone3x); CopyIcon(xcodeSrcPath, outputPath, "Icon-iPad-152.png", icons.iPad2x); CopyIcon(xcodeSrcPath, outputPath, "Icon-iPad-167.png", icons.iPadPro2x); CopyIcon(xcodeSrcPath, outputPath, "AppStore-1024.png", icons.AppStore); CopyIcon(xcodeSrcPath, outputPath, "Contents.json", null); for (int i = 0; i < Deployables.Length; ++i) { var r = Deployables[i]; if (r is DeployableFile && r.Path.FileName == "testconfig.json") { var path = CopyTool.Instance().Setup(outputPath.Combine(r.Path.FileName), r.Path); m_projectFiles.Add(path); break; } } return(pbxPath); }
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")); } }
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 NPath PackageApp(NPath buildPath, NPath mainLibPath) { var deployedPath = buildPath.Combine(m_gameName + ".apk"); if (m_apkToolchain == null) { Console.WriteLine($"Error: not Android APK toolchain"); return(deployedPath); } var gradleProjectPath = mainLibPath.Parent.Parent.Parent.Parent.Parent; var pathToRoot = new NPath(string.Concat(Enumerable.Repeat("../", gradleProjectPath.Depth))); var apkSrcPath = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Platforms.Android").Path.Parent.Combine("AndroidProjectTemplate~/"); var javaLaunchPath = m_apkToolchain.JavaPath.Combine("bin").Combine("java"); var gradleLaunchPath = m_apkToolchain.GetGradleLaunchJarPath(); var releaseApk = m_codeGen == CodeGen.Release; var gradleCommand = releaseApk ? "assembleRelease" : "assembleDebug"; var deleteCommand = Unity.BuildTools.HostPlatform.IsWindows ? $"del /f /q {deployedPath.InQuotes(SlashMode.Native)} 2> nul" : $"rm -f {deployedPath.InQuotes(SlashMode.Native)}"; var gradleExecutableString = $"{deleteCommand} && cd {gradleProjectPath.InQuotes()} && {javaLaunchPath.InQuotes()} -classpath {gradleLaunchPath.InQuotes()} org.gradle.launcher.GradleMain {gradleCommand} && cd {pathToRoot.InQuotes()}"; var apkPath = gradleProjectPath.Combine("build/outputs/apk").Combine(releaseApk ? "release/gradle-release.apk" : "debug/gradle-debug.apk"); Backend.Current.AddAction( actionName: "Build Gradle project", targetFiles: new[] { apkPath }, inputs: m_apkToolchain.RequiredArtifacts.Append(mainLibPath).Concat(m_supportFiles.Select(d => d.Path)).ToArray(), executableStringFor: gradleExecutableString, commandLineArguments: Array.Empty <string>(), allowUnexpectedOutput: false, allowedOutputSubstrings: new[] { ":*", "BUILD SUCCESSFUL in *" } ); var templateStrings = new Dictionary <string, string> { { "**TINYNAME**", m_gameName.Replace("-", "").ToLower() }, { "**GAMENAME**", m_gameName }, }; // copy and patch project files foreach (var r in apkSrcPath.Files(true)) { var destPath = gradleProjectPath.Combine(r.RelativeTo(apkSrcPath)); if (r.Extension == "template") { destPath = destPath.ChangeExtension(""); var code = r.ReadAllText(); foreach (var t in templateStrings) { if (code.IndexOf(t.Key) != -1) { code = code.Replace(t.Key, t.Value); } } Backend.Current.AddWriteTextAction(destPath, code); } else { destPath = CopyTool.Instance().Setup(destPath, r); } Backend.Current.AddDependency(apkPath, destPath); } var localProperties = new StringBuilder(); localProperties.AppendLine($"sdk.dir={m_apkToolchain.SdkPath}"); localProperties.AppendLine($"ndk.dir={m_apkToolchain.Sdk.Path.MakeAbsolute()}"); var localPropertiesPath = gradleProjectPath.Combine("local.properties"); Backend.Current.AddWriteTextAction(localPropertiesPath, localProperties.ToString()); Backend.Current.AddDependency(apkPath, localPropertiesPath); // copy additional resources and Data files // TODO: better to use move from main lib directory foreach (var r in m_supportFiles) { var targetAssetPath = gradleProjectPath.Combine("src/main/assets"); if (r.Path.FileName == "testconfig.json") { targetAssetPath = buildPath.Combine(r.Path.FileName); } else if (r is DeployableFile && (r as DeployableFile).RelativeDeployPath != null) { targetAssetPath = targetAssetPath.Combine((r as DeployableFile).RelativeDeployPath); } else { targetAssetPath = targetAssetPath.Combine(r.Path.FileName); } Backend.Current.AddDependency(apkPath, CopyTool.Instance().Setup(targetAssetPath, r.Path)); } return(CopyTool.Instance().Setup(deployedPath, apkPath)); }
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()); } }
public NPath PackageApp(NPath buildPath, NPath mainLibPath) { if (m_iosAppToolchain == null) { Console.WriteLine("Error: not IOS App toolchain"); return(mainLibPath); } var iosPlatformPath = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Platforms.iOS").Path.Parent; var xcodeProjectPath = mainLibPath.Parent; var xcodeSrcPath = iosPlatformPath.Combine(TinyProjectName + "~"); var xcodeprojPath = xcodeProjectPath.Combine($"{TinyProjectName}.xcodeproj"); // copy and patch pbxproj file var pbxPath = xcodeprojPath.Combine("project.pbxproj"); var pbxTemplatePath = xcodeSrcPath.Combine($"{TinyProjectName}.xcodeproj", "project.pbxproj"); var exportManifestPath = new NPath(m_gameName).Combine("export.manifest"); var result = SetupXCodeProject(pbxTemplatePath, exportManifestPath.FileExists()); Backend.Current.AddWriteTextAction(pbxPath, result); Backend.Current.AddDependency(pbxPath, mainLibPath); // copy and patch Info.plist file var plistPath = xcodeProjectPath.Combine("Sources", "Info.plist"); var plistTemplatePath = xcodeSrcPath.Combine("Sources", "Info.plist"); result = SetupInfoPlist(plistTemplatePath); Backend.Current.AddWriteTextAction(plistPath, result); Backend.Current.AddDependency(pbxPath, plistPath); // copy xcodeproj files foreach (var r in xcodeSrcPath.Files(true)) { if (r.Extension != "pbxproj" && r.FileName != "Info.plist") { var destPath = xcodeProjectPath.Combine(r.RelativeTo(xcodeSrcPath)); destPath = CopyTool.Instance().Setup(destPath, r); Backend.Current.AddDependency(pbxPath, destPath); } } foreach (var r in m_supportFiles) { if (r.Path.FileName == "testconfig.json") { Backend.Current.AddDependency(pbxPath, CopyTool.Instance().Setup(buildPath.Combine(r.Path.FileName), r.Path)); break; } } // TODO probably it is required to keep previous project since it can be modified by user var outputPath = buildPath.Combine($"{m_gameName}"); Console.WriteLine($"Move project to {outputPath}"); Backend.Current.AddAction( actionName: "Open XCode project folder", targetFiles: new[] { outputPath }, inputs: new[] { pbxPath }, executableStringFor: $"rm -rf {outputPath} && mv {xcodeProjectPath} {outputPath} && open {outputPath}", commandLineArguments: Array.Empty <string>(), allowUnexpectedOutput: true ); return(outputPath); }
private void GenerateGradleProject(NPath gradleProjectPath) { var gradleSrcPath = AsmDefConfigFile.AsmDefDescriptionFor("Unity.Build.Android.DotsRuntime").Path.Parent.Combine("AndroidProjectTemplate~/"); var hasGradleDependencies = false; var gradleDependencies = new StringBuilder(); gradleDependencies.AppendLine(" dependencies {"); var hasKotlin = false; foreach (var d in Deployables.Where(d => (d is DeployableFile))) { var f = d as DeployableFile; if (f.Path.Extension == "aar" || f.Path.Extension == "jar") { gradleDependencies.AppendLine($" compile(name:'{f.Path.FileNameWithoutExtension}', ext:'{f.Path.Extension}')"); hasGradleDependencies = true; } else if (f.Path.Extension == "kt") { hasKotlin = true; } } if (hasGradleDependencies) { gradleDependencies.AppendLine(" }"); } else { gradleDependencies.Clear(); } var kotlinClassPath = hasKotlin ? " classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11'" : ""; var kotlinPlugin = hasKotlin ? "apply plugin: 'kotlin-android'" : ""; var loadLibraries = new StringBuilder(); bool useStaticLib = Deployables.FirstOrDefault(l => l.ToString().Contains("lib_unity_tiny_android.so")) == default(IDeployable); if (useStaticLib) { loadLibraries.AppendLine($" System.loadLibrary(\"{m_gameName}\");"); } else { var rx = new Regex(@".*lib([\w\d_]+)\.so", RegexOptions.Compiled); foreach (var l in Deployables) { var match = rx.Match(l.ToString()); if (match.Success) { loadLibraries.AppendLine($" System.loadLibrary(\"{match.Groups[1].Value}\");"); } } } String abiFilters = ""; if (AndroidApkToolchain.Config.Architectures.Architectures == AndroidArchitecture.ARM64) { abiFilters = "'arm64-v8a'"; } else if (AndroidApkToolchain.Config.Architectures.Architectures == AndroidArchitecture.ARMv7) { abiFilters = "'armeabi-v7a'"; } else if (AndroidApkToolchain.IsFatApk) { abiFilters = "'armeabi-v7a', 'arm64-v8a'"; } else // shouldn't happen { Console.WriteLine($"Tiny android toolchain doesn't support {AndroidApkToolchain.Config.Architectures.Architectures.ToString()} architectures"); } // Android docs say "density" value was added in API level 17, but it doesn't compile with target SDK level lower than 24. string configChanges = ((int)AndroidApkToolchain.Config.APILevels.ResolvedTargetAPILevel > 23) ? AndroidConfigChanges + "|density" : AndroidConfigChanges; var useKeystore = BuildConfiguration.HasComponent <AndroidKeystore>(); var renderOutsideSafeArea = BuildConfiguration.HasComponent <AndroidRenderOutsideSafeArea>(); var icons = AndroidApkToolchain.Config.Icons; var hasBackground = icons.Icons.Any(i => !String.IsNullOrEmpty(i.Background)); var hasCustomIcons = hasBackground || icons.Icons.Any(i => !String.IsNullOrEmpty(i.Foreground) || !String.IsNullOrEmpty(i.Legacy)); var version = AndroidApkToolchain.Config.Settings.Version; var versionFieldCount = version.Revision > 0 ? 4 : 3; var maxRatio = AndroidApkToolchain.Config.AspectRatio.GetMaxAspectRatio(AndroidApkToolchain.Config.APILevels.ResolvedTargetAPILevel); var additionalApplicationMetadata = ""; var additionalPermissions = ""; var additionalFeatures = ""; if (!String.IsNullOrEmpty(maxRatio)) { additionalApplicationMetadata += GetMetaDataString("android.max_aspect", maxRatio); } if (BuildConfiguration.HasComponent <ARCoreSettings>()) { additionalPermissions += GetPermissionString("android.permission.CAMERA"); if (AndroidApkToolchain.Config.ARCore.Requirement == Requirement.Optional) { additionalApplicationMetadata += "\n" + GetMetaDataString("com.google.ar.core", "optional"); } else { additionalApplicationMetadata += "\n" + GetMetaDataString("com.google.ar.core", "required"); additionalFeatures += GetFeatureString("android.hardware.camera.ar", true); } if (AndroidApkToolchain.Config.ARCore.DepthSupport == Requirement.Required) { additionalFeatures += "\n" + GetFeatureString("com.google.ar.core.depth", true); } } var templateStrings = new Dictionary <string, string> { { "**LOADLIBRARIES**", loadLibraries.ToString() }, { "**PACKAGENAME**", AndroidApkToolchain.Config.Identifier.PackageName }, { "**PRODUCTNAME**", AndroidApkToolchain.Config.Settings.ProductName }, { "**VERSIONNAME**", version.ToString(versionFieldCount) }, { "**VERSIONCODE**", AndroidApkToolchain.Config.VersionCode.VersionCode.ToString() }, { "**ORIENTATION**", GetOrientationAttr() }, { "**INSTALLLOCATION**", AndroidApkToolchain.Config.InstallLocation?.PreferredInstallLocationAsString() }, { "**CUTOUTMODE**", AndroidRenderOutsideSafeArea.CutoutMode(renderOutsideSafeArea) }, { "**NOTCHCONFIG**", AndroidRenderOutsideSafeArea.NotchConfig(renderOutsideSafeArea) }, { "**NOTCHSUPPORT**", AndroidRenderOutsideSafeArea.NotchSupport(renderOutsideSafeArea) }, { "**GAMENAME**", m_gameName }, { "**MINSDKVERSION**", ((int)AndroidApkToolchain.Config.APILevels.MinAPILevel).ToString() }, { "**TARGETSDKVERSION**", ((int)AndroidApkToolchain.Config.APILevels.ResolvedTargetAPILevel).ToString() }, { "**CONFIGCHANGES**", configChanges }, { "**ACTIVITY_ASPECT**", String.IsNullOrEmpty(maxRatio) ? "" : $"android:maxAspectRatio=\"{maxRatio}\"" }, { "**ADDITIONAL_APPLICATION_METADATA**", additionalApplicationMetadata }, { "**ADDITIONAL_PERMISSIONS**", additionalPermissions }, { "**ADDITIONAL_FEATURES**", additionalFeatures }, { "**ABIFILTERS**", abiFilters }, { "**SIGN**", AndroidApkToolchain.Config.Keystore.GetSigningConfigs(useKeystore) }, { "**SIGNCONFIG**", AndroidApkToolchain.Config.Keystore.GetSigningConfig(useKeystore) }, { "**DEPENDENCIES**", gradleDependencies.ToString() }, { "**KOTLINCLASSPATH**", kotlinClassPath }, { "**KOTLINPLUGIN**", kotlinPlugin }, { "**ALLOWED_PORTRAIT**", AndroidApkToolchain.AllowedOrientationPortrait ? "true" : "false" }, { "**ALLOWED_REVERSE_PORTRAIT**", AndroidApkToolchain.AllowedOrientationReversePortrait ? "true" : "false" }, { "**ALLOWED_LANDSCAPE**", AndroidApkToolchain.AllowedOrientationLandscape ? "true" : "false" }, { "**ALLOWED_REVERSE_LANDSCAPE**", AndroidApkToolchain.AllowedOrientationReverseLandscape ? "true" : "false" }, { "**BACKGROUND_PATH**", hasBackground ? "mipmap" : "drawable" } }; // copy icon files if (hasCustomIcons) { for (int i = 0; i < icons.Icons.Length; ++i) { var dpi = ((ScreenDPI)i).ToString().ToLower(); if (AndroidApkToolchain.Config.APILevels.TargetSDKSupportsAdaptiveIcons) { CopyIcon(gradleProjectPath, dpi, "ic_launcher_foreground.png", icons.Icons[i].Foreground); CopyIcon(gradleProjectPath, dpi, "ic_launcher_background.png", icons.Icons[i].Background); } CopyIcon(gradleProjectPath, dpi, "app_icon.png", icons.Icons[i].Legacy); } } // copy and patch project files var apiRx = new Regex(@".+res[\\|\/].+-v([0-9]+)$", RegexOptions.Compiled); foreach (var r in gradleSrcPath.Files(true)) { if ((hasCustomIcons && r.HasDirectory("mipmap-mdpi")) || (hasBackground && r.HasDirectory("drawable"))) // skipping icons files if there are custom ones { continue; } if (!AndroidApkToolchain.Config.APILevels.TargetSDKSupportsAdaptiveIcons && r.FileName.StartsWith("ic_launcher_")) { continue; } var match = apiRx.Match(r.Parent.ToString()); if (match.Success) { var api = Int32.Parse(match.Groups[1].Value); if (api > (int)AndroidApkToolchain.Config.APILevels.ResolvedTargetAPILevel) { continue; } } var destPath = gradleProjectPath.Combine(r.RelativeTo(gradleSrcPath)); if (r.Extension == "template") { destPath = destPath.ChangeExtension(""); var code = r.ReadAllText(); foreach (var t in templateStrings) { if (code.IndexOf(t.Key) != -1) { code = code.Replace(t.Key, t.Value); } } Backend.Current.AddWriteTextAction(destPath, code); } else { destPath = CopyTool.Instance().Setup(destPath, r); } m_projectFiles.Add(destPath); } var localProperties = new StringBuilder(); localProperties.AppendLine($"sdk.dir={new NPath(AndroidApkToolchain.Config.ExternalTools.SdkPath).ToString()}"); localProperties.AppendLine($"ndk.dir={new NPath(AndroidApkToolchain.Config.ExternalTools.NdkPath).ToString()}"); var localPropertiesPath = gradleProjectPath.Combine("local.properties"); Backend.Current.AddWriteTextAction(localPropertiesPath, localProperties.ToString()); m_projectFiles.Add(localPropertiesPath); }
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); } }