public TypeResources(NPath typeDbOutputDirectory) { TypeDBOutputDirectory = typeDbOutputDirectory; var typeResources = new DotNetAssembly($"{EditorApplication.applicationContentsPath}/Tools/TypeGenerator/TypeGenerator.exe", Framework.Framework471); _typeGeneratorExecutable = new DotNetRunnableProgram(typeResources, DotNetRuntime.FindFor(typeResources)); }
public PostProcessor(DotNetAssembly[] processors, NPath outputDirectory) { OutputDirectory = outputDirectory; NPath srcDir = Path.GetFullPath(Path.Combine(Package.PackagePath, "Editor/Unity.Build.Classic.Private/Incremental/ILPostProcessing~")); var processorRunnerProgram = new CSharpProgram() { FileName = "ILPostProcessorRunner.exe", Sources = { srcDir, }, References = { EditorApplication.applicationContentsPath + "/Managed/Unity.CompilationPipeline.Common.dll" }, GenerateXmlDoc = XmlDocMode.Disabled, ProjectFilePath = $"{srcDir}/ILProcessor.gen.csproj", CopyReferencesNextToTarget = true, Framework = { Framework.Framework471 } }; _processorRunner = processorRunnerProgram.SetupDefault(); _processorRunnableProgram = new DotNetRunnableProgram(new DotNetAssembly(_processorRunner.Path, Framework.NetStandard20)); _builtProcessors = processors.Select(a => a.DeployTo(Configuration.RootArtifactsPath.Combine("postprocessors"))).ToArray(); _builtProcessorsDependenciesAndSelf = _builtProcessors.SelectMany(bp => bp.RecursiveRuntimeDependenciesIncludingSelf).Distinct().ToArray(); _inputFilesFromPostProcessor = _processorRunner.RecursiveRuntimeDependenciesIncludingSelf.Concat(_builtProcessorsDependenciesAndSelf).Select(p => p.Path).ToArray(); //we are in a funky situation today where user code is compiled against .net standard 2, but unityengine assemblies are compiled against .net47. Postprocessors //need to be able to deep-resolve any typereference, and it's going to encounter references to both netstandard.dll as well as mscorlib.dll and system.dll. We're going //to allow all these typereferences to resolve by resolving against the reference assemblies for both these profiles. _bclFiles = Framework471.Singleton.ReferenceAssemblies.Concat(Netstandard20.Singleton.ReferenceAssemblies).Select(a => a.Path).ToArray(); }
static void AddActions(DotNetAssembly[] inputAssemblies, NPath targetDirectory, NativeProgramConfiguration nativeProgramConfiguration) { var linkerAssembly = new DotNetAssembly(Distribution.Path.Combine("build/UnityLinker.exe"), Framework.Framework471); var linker = new DotNetRunnableProgram(linkerAssembly); var outputDir = targetDirectory; var isFrameworkNone = inputAssemblies.First().Framework == Framework.FrameworkNone; var rootAssemblies = inputAssemblies.Where(a => a.Path.HasExtension("exe")).Concat(new[] { inputAssemblies.First() }).Distinct(); var linkerArguments = new List <string> { $"--out={outputDir.InQuotes()}", "--use-dots-options", "--dotnetprofile=" + (isFrameworkNone ? "unitytiny" : "unityaot"), "--rule-set=experimental", // This will enable modification of method bodies to further reduce size. inputAssemblies.Select(a => $"--include-directory={a.Path.Parent.InQuotes()}") }; linkerArguments.AddRange(rootAssemblies.Select(rootAssembly => $"--include-public-assembly={rootAssembly.Path.InQuotes()}")); // foreach (var inputDirectory in inputFiles.Select(f => f.Path.Parent).Distinct()) // linkerArguments.Add($"--include-directory={inputDirectory.InQuotes()}"); NPath bclDir = Il2CppDependencies.Path.Combine("MonoBleedingEdge/builds/monodistribution/lib/mono/unityaot"); if (!isFrameworkNone) { linkerArguments.Add($"--search-directory={bclDir.InQuotes()}"); } var targetPlatform = GetTargetPlatformForLinker(nativeProgramConfiguration.Platform); if (!string.IsNullOrEmpty(targetPlatform)) { linkerArguments.Add($"--platform={targetPlatform}"); } var targetArchitecture = GetTargetArchitectureForLinker(nativeProgramConfiguration.ToolChain.Architecture); if (!string.IsNullOrEmpty(targetPlatform)) { linkerArguments.Add($"--architecture={targetArchitecture}"); } // var targetFiles = Unity.BuildTools.EnumerableExtensions.Prepend(nonMainOutputs, mainTargetFile); // targetFiles = targetFiles.Append(bcl); var targetFiles = inputAssemblies.SelectMany(a => a.Paths).Select(i => targetDirectory.Combine(i.FileName)).ToArray(); Backend.Current.AddAction( "UnityLinker", targetFiles: targetFiles, inputs: inputAssemblies.SelectMany(a => a.Paths).Concat(linkerAssembly.Paths).ToArray(), executableStringFor: linker.InvocationString, commandLineArguments: linkerArguments.ToArray(), allowUnwrittenOutputFiles: false, allowUnexpectedOutput: false, allowedOutputSubstrings: new[] { "Output action" }); }
private NPath[] SetupIL2CPPConversion(NPath[] linkerOutputFiles, NPath il2cppdata_destinationdir) { var il2cpp = new DotNetAssembly( string.IsNullOrEmpty(CustomIL2CPPLocation) ? $"{EditorApplication.applicationContentsPath}/il2cpp/build/deploy/net471/il2cpp.exe" : $"{CustomIL2CPPLocation}/build/deploy/net471/il2cpp.exe", Framework.Framework471); var netCoreRunRuntime = DotNetRuntime.FindFor(il2cpp); //NetCoreRunRuntime.FromSteve; var il2cppProgram = new DotNetRunnableProgram(il2cpp, netCoreRunRuntime); var extraTypes = new HashSet <string>(); foreach (var extraType in PlayerBuildInterface.ExtraTypesProvider?.Invoke() ?? Array.Empty <string>()) { extraTypes.Add(extraType); } NPath extraTypesFile = Configuration.RootArtifactsPath.Combine("extra-types.txt").MakeAbsolute().WriteAllLines(extraTypes.ToArray()); NPath il2cppOutputDir = Configuration.RootArtifactsPath.Combine("il2cpp"); Backend.Current.AddAction("IL2CPP", Array.Empty <NPath>(), linkerOutputFiles .Concat(il2cpp.Path.Parent.Files()).Concat(netCoreRunRuntime.Inputs) .Concat(new[] { extraTypesFile }) .ToArray(), il2cppProgram.InvocationString, new[] { "--convert-to-cpp", "--emit-null-checks", "--enable-array-bounds-check", "--dotnetprofile=\"unityaot\"", "--libil2cpp-static", $"--extra-types-file={extraTypesFile.InQuotes()}", "--profiler-report", $"--generatedcppdir={il2cppOutputDir.InQuotes(SlashMode.Native)}", $"--directory={linkerOutputFiles.First().Parent.InQuotes(SlashMode.Native)}", }, targetDirectories: new[] { il2cppOutputDir }, allowUnwrittenOutputFiles: true); var il2cppOutputFiles = GuessTargetDirectoryContentsFor(il2cppOutputDir, "dummy.cpp"); var dataDir = il2cppOutputDir.Combine("Data"); foreach (var il2cppdatafile in dataDir.FilesIfExists(recurse: true)) { CopyTool.Instance().Setup(il2cppdata_destinationdir.Combine(il2cppdatafile.RelativeTo(dataDir)), il2cppdatafile); } return(il2cppOutputFiles); }
public static NPath SetupBurst(NPath burstPackage, DotNetAssembly inputAssembly, NPath responseFile, ToolChain toolChain) { var bcl = new DotNetRunnableProgram(new DotNetAssembly(burstPackage.Combine(".Runtime/bcl.exe"), Framework.Framework471)); var targetFile = inputAssembly.Path.Parent.Combine($"burst_output.{toolChain.CppCompiler.ObjectExtension}"); var inputs = Unity.BuildTools.EnumerableExtensions.Append(inputAssembly.RecursiveRuntimeDependenciesIncludingSelf.SelectMany(a => a.Paths), responseFile); Backend.Current.AddAction( "Burst", targetFiles: new[] { targetFile }, inputs: inputs.ToArray(), executableStringFor: bcl.InvocationString, commandLineArguments: new[] { $"--assembly-folder={inputAssembly.Path.Parent}", $"--output={targetFile}", "--keep-intermediate-files", $"@{responseFile.ToString(SlashMode.Native)}" }, allowUnexpectedOutput: false, allowedOutputSubstrings: new[] { "Link succesful", "Method:" }); return(targetFile); }
public void SetupInvocation(DotNetAssembly inputProgram, DotsRuntimeCSharpProgramConfiguration config) { var result = BindGemOutputFor(inputProgram, config); if (result == null) { return; } var assembly = inputProgram; var args = new List <string> { "-v", "-dots", assembly.RuntimeDependencies.Select(rd => $"-r {rd.Path.InQuotes()}"), assembly.RuntimeDependencies.Select(r => BindGemOutputFor(r, config)).ExcludeNulls().Select(bo => $"-cppInclude {bo.Header}"), $"-define_guard BUILD_{assembly.Path.FileName.ToUpper().Replace(".", "_")}", assembly.Path.InQuotes(), "-o", result.Cpp.Parent.Combine(result.Cpp.FileNameWithoutExtension).InQuotes() }; var program = new DotNetRunnableProgram(BuiltBindGemProgram); var inputs = new List <NPath> { BuiltBindGemProgram.Path, assembly.RecursiveRuntimeDependenciesIncludingSelf.Select(d => d.Path) }; // Note: the MakeAbsolute() below also takes care of changing slashes on Windows, // because Windows really hates forward slashes when used as an executable path // to cmd.exe Backend.Current.AddAction( actionName: "BindGem", targetFiles: result.Files, inputs: inputs.ToArray(), executableStringFor: program.InvocationString, commandLineArguments: args.ToArray(), supportResponseFile: false ); }
public override DotNetAssembly SetupSpecificConfiguration(CSharpProgramConfiguration config) { var nonPatchedUnsafeUtility = base.SetupSpecificConfiguration(config); var builtPatcher = new CSharpProgram() { Path = "artifacts/UnsafeUtilityPatcher/UnsafeUtilityPatcher.exe", Sources = { $"{BuildProgram.LowLevelRoot}/UnsafeUtilityPatcher" }, Defines = { "NDESK_OPTIONS" }, Framework = { Bee.DotNet.Framework.Framework471 }, References = { MonoCecil.Paths, }, LanguageVersion = "7.3" }.SetupDefault(); var outDir = nonPatchedUnsafeUtility.Path.Parent.Combine("patched"); NPath nPath = outDir.Combine(nonPatchedUnsafeUtility.Path.FileName); var builtPatcherProgram = new DotNetRunnableProgram(builtPatcher); var args = new[] { $"--output={nPath}", $"--assembly={nonPatchedUnsafeUtility.Path}", }; var result = new DotNetAssembly(nPath, nonPatchedUnsafeUtility.Framework, nonPatchedUnsafeUtility.DebugFormat, nPath.ChangeExtension("pdb"), nonPatchedUnsafeUtility.RuntimeDependencies, nonPatchedUnsafeUtility.ReferenceAssemblyPath); Backend.Current.AddAction("Patch", result.Paths, nonPatchedUnsafeUtility.Paths.Concat(builtPatcher.Paths).ToArray(), builtPatcherProgram.InvocationString, args); return(result); }
public BurstCompiler(string burstTarget, string burstPlatform, NPath outputDirectory) { BurstTarget = burstTarget; BurstPlatform = burstPlatform; OutputDirectory = outputDirectory; // On macOS the PlatformName is set as OSX in bee but it needs to be macOS for bcl. if (burstPlatform == "OSX") { BurstPlatform = "macOS"; } if (burstPlatform == "IOS" && burstTarget == "ARMV8A_AARCH64") { BurstPlatform = "iOS"; } NPath burstDir = Path.GetFullPath("Packages/com.unity.burst/.Runtime"); var burstFiles = burstDir.Files(recurse: true); bool IsManagedBurstLibrary(NPath f) { if (!f.HasExtension(".dll")) { return(false); } if (f.FileName.StartsWith("burst-llvm-")) { return(false); } // These two libraries are not crossgen-compatible. if (f.FileName == "Unity.Cecil.Rocks.dll" || f.FileName == "Newtonsoft.Json.dll") { return(false); } return(true); } var bclAssembly = new DotNetAssembly(burstDir.Combine("bcl.exe"), Framework.Framework471) .WithRuntimeDependencies(burstFiles .Where(IsManagedBurstLibrary) .Select(f => new DotNetAssembly(f, Framework.Framework471)) .ToArray()); #if BURST_NETCORE //todo: turn this to true. we cannot right now because NetCoreRuntime.SteveDore is implemented through a static field, //which is incompatible with our "create graph in editor, and maybe we will create two graphs during the same domain". the creation //of the steve artifact happens only once, but it needs to be registered in each backend. the fact that it doesn't means you can get into //ugly situations where on second builds the dependencies to netcorerun are not properly setup. bool useNetCore = false; if (useNetCore) { var runtime = NetCoreRunRuntime.FromSteve; _dotnetRuntime = runtime; var useCrossGen = false; if (useCrossGen) { bclAssembly = runtime.SetupAheadOfTimeCompilation(bclAssembly, "artifacts/bcl-crossgen"); bclAssembly = bclAssembly.WithPath(bclAssembly.Path.MakeAbsolute(BeeProjectRoot)); foreach (var file in burstFiles.Where(x => !IsManagedBurstLibrary(x))) { var relative = file.RelativeTo(burstDir); var temp = CopyTool.Instance().Setup(bclAssembly.Path.Parent.Combine(relative), file); Backend.Current.AddDependency(temp, bclAssembly.Path); } } } else #else { _dotnetRuntime = DotNetRuntime.FindFor(bclAssembly); } #endif { _burstRunnableProgram = new DotNetRunnableProgram(bclAssembly, _dotnetRuntime); } _burstCompilerInputFiles = burstFiles; var burstPackageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath("Packages/com.unity.burst/somefile"); var burstPackageRawVersion = burstPackageInfo.version; // Remove everything after '-' if this is a preview package. var parts = burstPackageRawVersion.Split('-'); if (parts.Length > 1) { burstPackageRawVersion = parts[0]; } // Get the preview version number. // Default to max int to signal a very high preview number on release. var previewNumber = int.MaxValue; if (parts.Length > 1) { previewNumber = int.Parse(parts[1].Split('.')[1]); } var burstVersion = Version.Parse(burstPackageRawVersion); var burstVersionWithIncludeRootAssemblyReferencesFeature = new Version(1, 3); _installedBurstSupportsIncludeRootAssemblyReferencesFeature = burstVersion >= burstVersionWithIncludeRootAssemblyReferencesFeature; if (!_installedBurstSupportsIncludeRootAssemblyReferencesFeature) { Debug.Log($"Using burst 1.3 instead of {burstVersion.ToString()} will give much better build times. At the time of this writing it is only available by building manually on your machine."); } _installedBurstSupportsCaching = (burstVersion >= new Version(1, 3) && previewNumber > 7) || burstVersion >= new Version(1, 4); if (!_installedBurstSupportsCaching) { Debug.Log($"Using burst 1.3 preview 8 or above instead of {burstVersion.ToString()} will give much better build times. At the time of this writing it is only available by building manually on your machine."); } _installedBurstIs1_3Preview10OrLater = (burstVersion >= new Version(1, 3) && previewNumber >= 10) || burstVersion >= new Version(1, 4); }
private static NPath[] SetupLinker(List <NPath> copiedAssemblies, List <DotNetAssembly> postProcessedPlayerAssemblies, BuildTarget buildTarget, NPath workingDirectory) { /* * Invoking UnityLinker with arguments: -out=C:/dots/Samples/Temp/StagingArea/Data/Managed/tempStrip -x=C:/Users/Lucas/AppData/Local/Temp/tmp5eb9e11d.tmp * -x=C:/dots/Samples/Temp/StagingArea/Data/Managed/TypesInScenes.xml -x=C:/dots/Samples/Temp/StagingArea/Data/Managed/DotsStripping.xml * -d=C:/dots/Samples/Temp/StagingArea/Data/Managed --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/Assembly-CSharp.dll * --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/RotateMe.dll --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/Unity.Scenes.Hybrid.dll * --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/Samples.GridPath.dll --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/Unity.Entities.Hybrid.dll * --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/SubsceneWithBuildSettings.dll --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/HelloCube.dll * --include-unity-root-assembly=C:/dots/Samples/Temp/StagingArea/Data/Managed/Samples.Boids.dll --dotnetruntime=il2cpp --dotnetprofile=unityaot --use-editor-options --include-directory=C:/dots/Samples/Temp/StagingArea/Data/Managed * --editor-settings-flag=Development --rule-set=Conservative --editor-data-file=C:/dots/Samples/Temp/StagingArea/Data/Managed/EditorToUnityLinkerData.json --platform=WindowsDesktop * --engine-modules-asset-file=C:/unity/build/WindowsStandaloneSupport/Whitelists/../modules.asset * C:\unity\build\WindowsEditor\Data\il2cpp\build/deploy/net471/UnityLinker.exe exited after 4100 ms. * * "C:\\code\\unity-src-git\\build\\WindowsEditor\\Data\\il2cpp\\build\\deploy\\net471\\UnityLinker.exe --dotnetruntime=mono --dotnetprofile=unityaot * --use-editor-options --include-directory=\"artifacts\\managedassemblies\" --editor-settings-flag=Development --rule-set=conservative --out=\"artifacts\\linkeroutput\" * --include-unity-root-assembly=\"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/UnityEngine.UI.dll/Release/UnityEngine.UI.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Mathematics.dll/Release/Unity.Mathematics.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Entities.StaticTypeRegistry.dll/Release/Unity.Entities.StaticTypeRegistry.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Burst.dll/Release/Unity.Burst.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.ScriptableBuildPipeline.dll/Release/Unity.ScriptableBuildPipeline.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Collections.dll/Release/Unity.Collections.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Properties.dll/Release/Unity.Properties.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Jobs.dll/Release/Unity.Jobs.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Mathematics.Extensions.dll/Release/Unity.Mathematics.Extensions.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Entities.dll/Release/Unity.Entities.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Transforms.dll/Release/Unity.Transforms.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Entities.Determinism.dll/Release/Unity.Entities.Determinism.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Mathematics.Extensions.Hybrid.dll/Release/Unity.Mathematics.Extensions.Hybrid.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Entities.Hybrid.dll/Release/Unity.Entities.Hybrid.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Transforms.Hybrid.dll/Release/Unity.Transforms.Hybrid.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Scenes.Hybrid.dll/Release/Unity.Scenes.Hybrid.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Unity.Rendering.Hybrid.dll/Release/Unity.Rendering.Hybrid.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Samples.Boids.dll/Release/Samples.Boids.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/HelloCube.dll/Release/HelloCube.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Samples.GridPath.dll/Release/Samples.GridPath.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/SubsceneWithBuildSettings.dll/Release/SubsceneWithBuildSettings.dll\", \"C:/code/dots/Samples/Library/IncrementalClassicBuildPipeline/Win64-LiveLink/artifacts/Assembly-CSharp.dll/Release/Assembly-CSharp.dll\" * --include-unity-root-assembly=\"C:/code/unity-src-git/build/WindowsStandaloneSupport/Variations/win64_development_mono/Data/Managed/UnityEngine.dll\"", * */ DotNetAssembly linker = new DotNetAssembly( string.IsNullOrEmpty(CustomIL2CPPLocation) ? $"{EditorApplication.applicationContentsPath}/il2cpp/build/deploy/net471/UnityLinker.exe" : $"{CustomIL2CPPLocation}/build/deploy/net471/UnityLinker.exe", Framework.Framework471); var linkerProgram = new DotNetRunnableProgram(linker); var linkXmlFiles = NPath.CurrentDirectory.Combine("Assets").Files("link.xml", true); var unityLinkerProcessors = TypeCacheHelper.ConstructTypesDerivedFrom <IUnityLinkerProcessor>(); var linkerData = new UnityLinkerBuildPipelineData(buildTarget, workingDirectory.ToString()); linkXmlFiles = linkXmlFiles.Concat(unityLinkerProcessors.Select(p => (NPath)p.GenerateAdditionalLinkXmlFile(null, linkerData))).ToArray(); var inputFiles = copiedAssemblies .Concat(postProcessedPlayerAssemblies.Select(p => p.Path)) .Concat(linker.Path.Parent.Files()) .Concat(linkXmlFiles) // .Concat(dotNetRuntime.Inputs) .ToArray(); var searchDirectories = new HashSet <NPath>(); foreach (var file in copiedAssemblies) { searchDirectories.Add(file.Parent); } foreach (var file in postProcessedPlayerAssemblies) { searchDirectories.Add(file.Path.Parent); } searchDirectories.Add(_incrementalClassicSharedData.UnityEngineAssembliesDirectory.ToString()); // Pass along the correct platform names for macOS and Windows desktop targets var platformName = _incrementalClassicSharedData.PlatformName == "Windows" ? "WindowsDesktop" : _incrementalClassicSharedData.PlatformName == "UniversalWindows" ? "WinRT" : _incrementalClassicSharedData.PlatformName; platformName = _incrementalClassicSharedData.PlatformName == "OSX" ? "MacOSX" : platformName; NPath linkerOutputDir = Configuration.RootArtifactsPath.Combine("linkeroutput"); Backend.Current.AddAction("UnityLinker", Array.Empty <NPath>(), inputFiles, linkerProgram.InvocationString, new[] { $"--platform={platformName}", "--dotnetruntime=il2cpp", "--dotnetprofile=unityaot", "--use-editor-options", $"--include-directory={copiedAssemblies.First().Parent.InQuotes(SlashMode.Native)}", "--editor-settings-flag=Development", //if you want to boost up from conservative to aggressive, the linker will start to remove MonoBehaviours. We'd need to add a step that analyzes all assets //in the databuild, and build a list of actually used monobehaviours. this goes very much against the concept of incrementalness. Let's stick to conservative for now.t "--rule-set=Conservative", $"--out={linkerOutputDir.InQuotes(SlashMode.Native)}", $"--search-directory={searchDirectories.Select(d=>d.MakeAbsolute().ToString()).SeparateWithComma()}", $"--include-unity-root-assembly={postProcessedPlayerAssemblies.Where(a => a.Path.FileName != "Unity.Serialization.dll").Select(a => a.Path.MakeAbsolute()).InQuotes().SeparateWithComma()}", $"--engine-modules-asset-file={_incrementalClassicSharedData.PlayerPackageDirectory.Combine("modules.asset").InQuotes(SlashMode.Native)}", linkXmlFiles.Select(f => $"--include-link-xml={f}").SeparateWithSpace(), }, allowUnwrittenOutputFiles: true, supportResponseFile: true, targetDirectories: new[] { linkerOutputDir } ); NPath[] linkerOutputFiles = GuessTargetDirectoryContentsFor(linkerOutputDir, "dummy.dll"); return(linkerOutputFiles); }