private static void RunAssemblyStripper(UnityLinkerRunInformation runInformation) { string output; string error; var rcr = runInformation.rcr; var managedAssemblyFolderPath = runInformation.managedAssemblyFolderPath; var linkXmlFiles = new List <string>(); linkXmlFiles.AddRange(Il2CppBlacklistPaths); if (rcr != null) { linkXmlFiles.Add(WriteMethodsToPreserveBlackList(rcr, runInformation.target)); linkXmlFiles.Add(MonoAssemblyStripping.GenerateLinkXmlToPreserveDerivedTypes(managedAssemblyFolderPath, rcr)); linkXmlFiles.Add(WriteTypesInScenesBlacklist(managedAssemblyFolderPath, rcr)); } linkXmlFiles.AddRange(ProcessBuildPipelineGenerateAdditionalLinkXmlFiles(runInformation)); linkXmlFiles.AddRange(GetUserBlacklistFiles()); if (runInformation.isMonoBackend) { // The old Mono assembly stripper uses per-platform link.xml files if available. Apply these here. var buildToolsDirectory = BuildPipeline.GetBuildToolsDirectory(runInformation.target); if (!string.IsNullOrEmpty(buildToolsDirectory)) { var platformDescriptor = Path.Combine(buildToolsDirectory, "link.xml"); if (File.Exists(platformDescriptor)) { linkXmlFiles.Add(platformDescriptor); } } } WriteEditorData(runInformation); if (!runInformation.performEngineStripping && !UseUnityLinkerEngineModuleStripping) { // if we don't do stripping, add all modules blacklists. linkXmlFiles.AddRange(runInformation.GetModuleBlacklistFiles()); } var tempStripPath = Path.GetFullPath(Path.Combine(managedAssemblyFolderPath, "tempStrip")); ProcessBuildPipelineOnBeforeRun(runInformation); bool addedMoreBlacklists; do { addedMoreBlacklists = false; if (EditorUtility.DisplayCancelableProgressBar("Building Player", "Stripping assemblies", 0.0f)) { throw new OperationCanceledException(); } if (!StripAssembliesTo( tempStripPath, out output, out error, SanitizeLinkXmlFilePaths(linkXmlFiles, runInformation), runInformation)) { throw new Exception("Error in stripping assemblies: " + runInformation.AssembliesToProcess() + ", " + error); } if (runInformation.engineStrippingSupported) { var icallSummaryPath = Path.Combine(managedAssemblyFolderPath, "ICallSummary.txt"); GenerateInternalCallSummaryFile(icallSummaryPath, managedAssemblyFolderPath, tempStripPath); if (runInformation.performEngineStripping && !UseUnityLinkerEngineModuleStripping) { // Find which modules we must include in the build based on Assemblies HashSet <UnityType> nativeClasses; HashSet <string> nativeModules; CodeStrippingUtils.GenerateDependencies(tempStripPath, icallSummaryPath, rcr, runInformation.performEngineStripping, out nativeClasses, out nativeModules, runInformation.il2CppPlatformProvider); // Add module-specific blacklists. addedMoreBlacklists = AddWhiteListsForModules(nativeModules, linkXmlFiles, runInformation.platformProvider.moduleStrippingInformationFolder); } } if (runInformation.performEngineStripping && UseUnityLinkerEngineModuleStripping) { UpdateBuildReport(ReadLinkerToEditorData(tempStripPath), runInformation); } // If we had to add more whitelists, we need to run AssemblyStripper again with the added whitelists. }while (addedMoreBlacklists && !UseUnityLinkerEngineModuleStripping); // keep unstripped files for debugging purposes var tempUnstrippedPath = Path.GetFullPath(Path.Combine(managedAssemblyFolderPath, "tempUnstripped")); if (debugUnstripped) { Directory.CreateDirectory(tempUnstrippedPath); } foreach (var file in Directory.GetFiles(managedAssemblyFolderPath)) { var extension = Path.GetExtension(file); if (string.Equals(extension, ".dll", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".winmd", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".mdb", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".pdb", StringComparison.InvariantCultureIgnoreCase)) { if (debugUnstripped) { File.Move(file, Path.Combine(tempUnstrippedPath, Path.GetFileName(file))); } else { File.Delete(file); } } } foreach (var file in Directory.GetFiles(tempStripPath)) { File.Move(file, Path.Combine(managedAssemblyFolderPath, Path.GetFileName(file))); } foreach (var dir in Directory.GetDirectories(tempStripPath)) { Directory.Move(dir, Path.Combine(managedAssemblyFolderPath, Path.GetFileName(dir))); } Directory.Delete(tempStripPath); ProcessBuildPipelineOnAfterRun(runInformation); }
private static bool StripAssembliesTo(string outputFolder, out string output, out string error, IEnumerable <string> linkXmlFiles, UnityLinkerRunInformation runInformation) { if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } var assemblies = runInformation.AssembliesToProcess(); var args = new List <string> { $"-out={CommandLineFormatter.PrepareFileName(outputFolder)}", }; if (!UseUnityLinkerEngineModuleStripping) { args.Add($"-x={CommandLineFormatter.PrepareFileName(GetModuleWhitelist("Core", runInformation.platformProvider.moduleStrippingInformationFolder))}"); } args.AddRange(linkXmlFiles.Select(path => $"-x={CommandLineFormatter.PrepareFileName(path)}")); args.AddRange(runInformation.SearchDirectories.Select(d => $"-d={CommandLineFormatter.PrepareFileName(d)}")); args.AddRange(assemblies.Select(assembly => $"--include-unity-root-assembly={CommandLineFormatter.PrepareFileName(Path.GetFullPath(assembly))}")); args.Add($"--dotnetruntime={runInformation.argumentProvider.Runtime}"); args.Add($"--dotnetprofile={runInformation.argumentProvider.Profile}"); args.Add("--use-editor-options"); args.Add($"--include-directory={CommandLineFormatter.PrepareFileName(runInformation.managedAssemblyFolderPath)}"); if (EditorUserBuildSettings.allowDebugging) { args.Add("--editor-settings-flag=AllowDebugging"); } if (EditorUserBuildSettings.development) { args.Add("--editor-settings-flag=Development"); } args.Add($"--rule-set={runInformation.argumentProvider.RuleSet}"); args.Add($"--editor-data-file={CommandLineFormatter.PrepareFileName(runInformation.EditorToLinkerDataPath)}"); if (runInformation.platformProvider.AllowOutputToBeMadePlatformDependent) { var platform = runInformation.platformProvider.Platform; if (string.IsNullOrEmpty(platform)) { throw new ArgumentException($"Platform is required if AllowOutputToBeMadePlatformDependent is true"); } args.Add($"--platform={platform}"); } if (runInformation.platformProvider.AllowOutputToBeMadeArchitectureDependent) { var architecture = runInformation.platformProvider.Architecture; if (string.IsNullOrEmpty(architecture)) { throw new ArgumentException($"Architecture is required if AllowOutputToBeMadeArchitectureDependent is true"); } args.Add($"--architecture={architecture}"); } if (!UseUnityLinkerEngineModuleStripping) { args.Add("--disable-engine-module-support"); } if (runInformation.performEngineStripping) { args.Add("--enable-engine-module-stripping"); if (UnityEngine.Connect.UnityConnectSettings.enabled) { args.Add("--engine-stripping-flag=EnableUnityConnect"); } if (UnityEngine.Analytics.PerformanceReporting.enabled) { args.Add("--engine-stripping-flag=EnablePerformanceReporting"); } if (UnityEngine.Analytics.Analytics.enabled) { args.Add("--engine-stripping-flag=EnableAnalytics"); } if (UnityEditor.CrashReporting.CrashReportingSettings.enabled) { args.Add("--engine-stripping-flag=EnableCrashReporting"); } if (UnityEditorInternal.VR.VRModule.ShouldInjectVRDependenciesForBuildTarget(runInformation.target)) { args.Add("--engine-stripping-flag=EnableVR"); } } var modulesAssetPath = runInformation.ModulesAssetFilePath; if (File.Exists(modulesAssetPath)) { args.Add($"--engine-modules-asset-file={CommandLineFormatter.PrepareFileName(modulesAssetPath)}"); } var additionalArgs = System.Environment.GetEnvironmentVariable("UNITYLINKER_ADDITIONAL_ARGS"); if (!string.IsNullOrEmpty(additionalArgs)) { args.Add(additionalArgs); } additionalArgs = Debug.GetDiagnosticSwitch("VMUnityLinkerAdditionalArgs") as string; if (!string.IsNullOrEmpty(additionalArgs)) { args.Add(additionalArgs.Trim('\'')); } return(RunAssemblyLinker(args, out output, out error, UnityLinkerPath, runInformation.managedAssemblyFolderPath)); }
private static void RunAssemblyStripper(UnityLinkerRunInformation runInformation) { string output; string error; var managedAssemblyFolderPath = runInformation.managedAssemblyFolderPath; var linkXmlFiles = GetLinkXmlFiles(runInformation); WriteEditorData(runInformation); var tempStripPath = GetFullPath(Path.Combine(managedAssemblyFolderPath, "tempStrip")); if (EditorUtility.DisplayCancelableProgressBar("Building Player", "Stripping assemblies", 0.0f)) { throw new OperationCanceledException(); } if (!StripAssembliesTo( tempStripPath, out output, out error, linkXmlFiles, runInformation)) { throw new Exception("Error in stripping assemblies: " + runInformation.AssembliesToProcess() + ", " + error); } if (runInformation.engineStrippingSupported) { var icallSummaryPath = Path.Combine(managedAssemblyFolderPath, "ICallSummary.txt"); GenerateInternalCallSummaryFile(icallSummaryPath, managedAssemblyFolderPath, tempStripPath); } if (runInformation.performEngineStripping) { var strippingInfo = runInformation.BuildReportData; if (strippingInfo != null) { UpdateBuildReport(ReadLinkerToEditorData(tempStripPath), strippingInfo); } } // keep unstripped files for debugging purposes var tempUnstrippedPath = GetFullPath(Path.Combine(managedAssemblyFolderPath, "tempUnstripped")); if (debugUnstripped) { Directory.CreateDirectory(tempUnstrippedPath); } foreach (var file in Directory.GetFiles(managedAssemblyFolderPath)) { var extension = Path.GetExtension(file); if (string.Equals(extension, ".dll", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".winmd", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".mdb", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".pdb", StringComparison.InvariantCultureIgnoreCase)) { if (debugUnstripped) { File.Move(file, Path.Combine(tempUnstrippedPath, Path.GetFileName(file))); } else { File.Delete(file); } } } foreach (var file in Directory.GetFiles(tempStripPath)) { File.Move(file, Path.Combine(managedAssemblyFolderPath, Path.GetFileName(file))); } foreach (var dir in Directory.GetDirectories(tempStripPath)) { Directory.Move(dir, Path.Combine(managedAssemblyFolderPath, Path.GetFileName(dir))); } Directory.Delete(tempStripPath); }