// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Xml; using EpicGames.Core; using Microsoft.Extensions.Logging; using UnrealBuildTool; namespace AutomationTool.Tasks { /// /// Parameters for a task that strips symbols from a set of files /// public class StripTaskParameters { /// /// The platform toolchain to strip binaries. /// [TaskParameter] public UnrealTargetPlatform Platform { get; set; } /// /// The directory to find files in. /// [TaskParameter(Optional = true)] public DirectoryReference BaseDir { get; set; } /// /// List of file specifications separated by semicolons (for example, Engine/.../*.pdb), or the name of a tag set. /// [TaskParameter(ValidationType = TaskParameterValidationType.FileSpec)] public string Files { get; set; } /// /// Output directory for the stripped files. Defaults to the input path, overwriting the input files. /// [TaskParameter(Optional = true)] public DirectoryReference OutputDir { get; set; } /// /// Tag to be applied to build products of this task. /// [TaskParameter(Optional = true, ValidationType = TaskParameterValidationType.TagList)] public string Tag { get; set; } } /// /// Strips debugging information from a set of files. /// [TaskElement("Strip", typeof(StripTaskParameters))] public class StripTask : BgTaskImpl { readonly StripTaskParameters _parameters; /// /// Construct a spawn task /// /// Parameters for the task public StripTask(StripTaskParameters parameters) { _parameters = parameters; } /// /// ExecuteAsync the task. /// /// Information about the current job /// Set of build products produced by this node. /// Mapping from tag names to the set of files they include public override Task ExecuteAsync(JobContext job, HashSet buildProducts, Dictionary> tagNameToFileSet) { // Get the base directory DirectoryReference baseDir = _parameters.BaseDir; // Get the output directory DirectoryReference outputDir = _parameters.OutputDir; // Find the matching files FileReference[] sourceFiles = ResolveFilespec(baseDir, _parameters.Files, tagNameToFileSet).OrderBy(x => x.FullName).ToArray(); // Create the matching target files FileReference[] targetFiles = sourceFiles.Select(x => FileReference.Combine(outputDir, x.MakeRelativeTo(baseDir))).ToArray(); // Run the stripping command Platform targetPlatform = Platform.GetPlatform(_parameters.Platform); for (int idx = 0; idx < sourceFiles.Length; idx++) { DirectoryReference.CreateDirectory(targetFiles[idx].Directory); if (sourceFiles[idx] == targetFiles[idx]) { Logger.LogInformation("Stripping symbols: {Arg0}", sourceFiles[idx].FullName); } else { Logger.LogInformation("Stripping symbols: {Arg0} -> {Arg1}", sourceFiles[idx].FullName, targetFiles[idx].FullName); } targetPlatform.StripSymbols(sourceFiles[idx], targetFiles[idx]); } // Apply the optional tag to the build products foreach (string tagName in FindTagNamesFromList(_parameters.Tag)) { FindOrAddTagSet(tagNameToFileSet, tagName).UnionWith(targetFiles); } // Add the target files to the set of build products buildProducts.UnionWith(targetFiles); return Task.CompletedTask; } /// /// Output this task out to an XML writer. /// public override void Write(XmlWriter writer) { Write(writer, _parameters); } /// /// Find all the tags which are used as inputs to this task /// /// The tag names which are read by this task public override IEnumerable FindConsumedTagNames() { return FindTagNamesFromFilespec(_parameters.Files); } /// /// Find all the tags which are modified by this task /// /// The tag names which are modified by this task public override IEnumerable FindProducedTagNames() { return FindTagNamesFromList(_parameters.Tag); } } public static partial class StandardTasks { /// /// Strips symbols from a set of files. /// /// /// The platform toolchain to strip binaries. /// The directory to find files in. /// Output directory for the stripped files. Defaults to the input path, overwriting the input files. /// public static async Task StripAsync(FileSet files, UnrealTargetPlatform platform, DirectoryReference baseDir = null, DirectoryReference outputDir = null) { StripTaskParameters parameters = new StripTaskParameters(); parameters.Platform = platform; parameters.BaseDir = baseDir; parameters.Files = String.Join(";", files.Flatten().Values.Select(x => x.FullName)); parameters.OutputDir = outputDir; return await ExecuteAsync(new StripTask(parameters)); } } }