You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
RootDirectory, EngineDirectory, UnrealBuildToolPath are now found in BuildUtilities' UnrealBuild namesapce. The way these are computed has changed. Previously, it was assumed that the application is UnrealBuildTool, and paths were constructed relative to that assembly. Now, the assumption is that the process is located under a "Engine/Build/DotNET" sub-path and paths are constructed relative to that. #jira none #ROBOMERGE-SOURCE: CL 16607440 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v828-16531559) [CL 16607455 by jonathan adamczewski in ue5-release-engine-test branch]
249 lines
9.6 KiB
C#
249 lines
9.6 KiB
C#
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using EpicGames.Core;
|
|
using UnrealBuildBase;
|
|
|
|
namespace UnrealBuildTool
|
|
{
|
|
/// <summary>
|
|
/// Cleans build products and intermediates for the target. This deletes files which are named consistently with the target being built
|
|
/// (e.g. UnrealEditor-Foo-Win64-Debug.dll) rather than an actual record of previous build products.
|
|
/// </summary>
|
|
[ToolMode("Clean", ToolModeOptions.XmlConfig | ToolModeOptions.BuildPlatforms | ToolModeOptions.SingleInstance)]
|
|
class CleanMode : ToolMode
|
|
{
|
|
/// <summary>
|
|
/// Whether to avoid cleaning targets
|
|
/// </summary>
|
|
[CommandLine("-SkipRulesCompile")]
|
|
bool bSkipRulesCompile = false;
|
|
|
|
/// <summary>
|
|
/// Skip pre build targets; just do the main target.
|
|
/// </summary>
|
|
[CommandLine("-SkipPreBuildTargets")]
|
|
public bool bSkipPreBuildTargets = false;
|
|
|
|
/// <summary>
|
|
/// Main entry point
|
|
/// </summary>
|
|
/// <param name="Arguments">Command-line arguments</param>
|
|
/// <returns>One of the values of ECompilationResult</returns>
|
|
public override int Execute(CommandLineArguments Arguments)
|
|
{
|
|
Arguments.ApplyTo(this);
|
|
|
|
// Create the build configuration object, and read the settings
|
|
BuildConfiguration BuildConfiguration = new BuildConfiguration();
|
|
XmlConfig.ApplyTo(BuildConfiguration);
|
|
Arguments.ApplyTo(BuildConfiguration);
|
|
|
|
// Parse all the targets being built
|
|
List<TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, bSkipRulesCompile);
|
|
if (TargetDescriptors.Count == 0)
|
|
{
|
|
throw new BuildException("No targets specified to clean");
|
|
}
|
|
|
|
// Also add implicit descriptors for cleaning UnrealBuildTool
|
|
if (!BuildConfiguration.bDoNotBuildUHT)
|
|
{
|
|
const string UnrealHeaderToolTarget = "UnrealHeaderTool";
|
|
|
|
// Get a list of project files to clean UHT for
|
|
List<FileReference?> ProjectFiles = new List<FileReference?>();
|
|
foreach (TargetDescriptor TargetDesc in TargetDescriptors)
|
|
{
|
|
if (TargetDesc.Name != UnrealHeaderToolTarget && !RemoteMac.HandlesTargetPlatform(TargetDesc.Platform))
|
|
{
|
|
if (ProjectFiles.Count == 0)
|
|
{
|
|
ProjectFiles.Add(null);
|
|
}
|
|
if (TargetDesc.ProjectFile != null && !ProjectFiles.Contains(TargetDesc.ProjectFile))
|
|
{
|
|
ProjectFiles.Add(TargetDesc.ProjectFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add descriptors for cleaning UHT with all these projects
|
|
if (ProjectFiles.Count > 0)
|
|
{
|
|
UnrealTargetConfiguration Configuration = BuildConfiguration.bForceDebugUnrealHeaderTool ? UnrealTargetConfiguration.Debug : UnrealTargetConfiguration.Development;
|
|
string Architecture = UEBuildPlatform.GetBuildPlatform(BuildHostPlatform.Current.Platform).GetDefaultArchitecture(null);
|
|
foreach (FileReference? ProjectFile in ProjectFiles)
|
|
{
|
|
TargetDescriptors.Add(new TargetDescriptor(ProjectFile, UnrealHeaderToolTarget, BuildHostPlatform.Current.Platform, Configuration, Architecture, null));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Output the list of targets that we're cleaning
|
|
Log.TraceInformation("Cleaning {0} binaries...", StringUtils.FormatList(TargetDescriptors.Select(x => x.Name).Distinct()));
|
|
|
|
// Loop through all the targets, and clean them all
|
|
HashSet<FileReference> FilesToDelete = new HashSet<FileReference>();
|
|
HashSet<DirectoryReference> DirectoriesToDelete = new HashSet<DirectoryReference>();
|
|
|
|
for (int Idx = 0; Idx < TargetDescriptors.Count; ++Idx)
|
|
{
|
|
TargetDescriptor TargetDescriptor = TargetDescriptors[Idx];
|
|
|
|
// Create the rules assembly
|
|
RulesAssembly RulesAssembly = RulesCompiler.CreateTargetRulesAssembly(TargetDescriptor.ProjectFile, TargetDescriptor.Name, bSkipRulesCompile, BuildConfiguration.bUsePrecompiled, TargetDescriptor.ForeignPlugin);
|
|
|
|
// Create the rules object
|
|
ReadOnlyTargetRules Target = new ReadOnlyTargetRules(RulesAssembly.CreateTargetRules(TargetDescriptor.Name, TargetDescriptor.Platform, TargetDescriptor.Configuration, TargetDescriptor.Architecture, TargetDescriptor.ProjectFile, TargetDescriptor.AdditionalArguments));
|
|
|
|
if (!bSkipPreBuildTargets && Target.PreBuildTargets.Count > 0)
|
|
{
|
|
foreach (TargetInfo PreBuildTarget in Target.PreBuildTargets)
|
|
{
|
|
TargetDescriptor NewTarget = TargetDescriptor.FromTargetInfo(PreBuildTarget);
|
|
if (!TargetDescriptors.Contains(NewTarget))
|
|
{
|
|
TargetDescriptors.Add(NewTarget);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Find the base folders that can contain binaries
|
|
List<DirectoryReference> BaseDirs = new List<DirectoryReference>();
|
|
BaseDirs.Add(UnrealBuild.EngineDirectory);
|
|
foreach (FileReference Plugin in Plugins.EnumeratePlugins(Target.ProjectFile))
|
|
{
|
|
BaseDirs.Add(Plugin.Directory);
|
|
}
|
|
if (Target.ProjectFile != null)
|
|
{
|
|
BaseDirs.Add(Target.ProjectFile.Directory);
|
|
}
|
|
|
|
// If we're running a precompiled build, remove anything under the engine folder
|
|
BaseDirs.RemoveAll(x => RulesAssembly.IsReadOnly(x));
|
|
|
|
// Get all the names which can prefix build products
|
|
List<string> NamePrefixes = new List<string>();
|
|
if (Target.Type != TargetType.Program)
|
|
{
|
|
NamePrefixes.Add(UEBuildTarget.GetAppNameForTargetType(Target.Type));
|
|
}
|
|
NamePrefixes.Add(Target.Name);
|
|
|
|
// Get the suffixes for this configuration
|
|
List<string> NameSuffixes = new List<string>();
|
|
if (Target.Configuration == Target.UndecoratedConfiguration)
|
|
{
|
|
NameSuffixes.Add("");
|
|
}
|
|
NameSuffixes.Add(String.Format("-{0}-{1}", Target.Platform.ToString(), Target.Configuration.ToString()));
|
|
if (!String.IsNullOrEmpty(Target.Architecture))
|
|
{
|
|
NameSuffixes.AddRange(NameSuffixes.ToArray().Select(x => x + Target.Architecture));
|
|
}
|
|
|
|
// Add all the makefiles and caches to be deleted
|
|
FilesToDelete.Add(TargetMakefile.GetLocation(Target.ProjectFile, Target.Name, Target.Platform, Target.Architecture, Target.Configuration));
|
|
FilesToDelete.UnionWith(SourceFileMetadataCache.GetFilesToClean(Target.ProjectFile));
|
|
|
|
// Add all the intermediate folders to be deleted
|
|
foreach (DirectoryReference BaseDir in BaseDirs)
|
|
{
|
|
foreach (string NamePrefix in NamePrefixes)
|
|
{
|
|
DirectoryReference GeneratedCodeDir = DirectoryReference.Combine(BaseDir, UEBuildTarget.GetPlatformIntermediateFolder(Target.Platform, Target.Architecture), NamePrefix, "Inc");
|
|
if (DirectoryReference.Exists(GeneratedCodeDir))
|
|
{
|
|
DirectoriesToDelete.Add(GeneratedCodeDir);
|
|
}
|
|
|
|
DirectoryReference IntermediateDir = DirectoryReference.Combine(BaseDir, UEBuildTarget.GetPlatformIntermediateFolder(Target.Platform, Target.Architecture), NamePrefix, Target.Configuration.ToString());
|
|
if (DirectoryReference.Exists(IntermediateDir))
|
|
{
|
|
DirectoriesToDelete.Add(IntermediateDir);
|
|
}
|
|
}
|
|
}
|
|
|
|
// List of additional files and directories to clean, specified by the target platform
|
|
List<FileReference> AdditionalFilesToDelete = new List<FileReference>();
|
|
List<DirectoryReference> AdditionalDirectoriesToDelete = new List<DirectoryReference>();
|
|
|
|
// Add all the build products from this target
|
|
string[] NamePrefixesArray = NamePrefixes.Distinct().ToArray();
|
|
string[] NameSuffixesArray = NameSuffixes.Distinct().ToArray();
|
|
foreach (DirectoryReference BaseDir in BaseDirs)
|
|
{
|
|
DirectoryReference BinariesDir = DirectoryReference.Combine(BaseDir, "Binaries", Target.Platform.ToString());
|
|
if (DirectoryReference.Exists(BinariesDir))
|
|
{
|
|
UEBuildPlatform.GetBuildPlatform(Target.Platform).FindBuildProductsToClean(BinariesDir, NamePrefixesArray, NameSuffixesArray, AdditionalFilesToDelete, AdditionalDirectoriesToDelete);
|
|
}
|
|
}
|
|
|
|
// Get all the additional intermediate folders created by this platform
|
|
UEBuildPlatform.GetBuildPlatform(Target.Platform).FindAdditionalBuildProductsToClean(Target, AdditionalFilesToDelete, AdditionalDirectoriesToDelete);
|
|
|
|
// Add the platform's files and directories to the main list
|
|
FilesToDelete.UnionWith(AdditionalFilesToDelete);
|
|
DirectoriesToDelete.UnionWith(AdditionalDirectoriesToDelete);
|
|
}
|
|
|
|
// Delete all the directories, then all the files. By sorting the list of directories before we delete them, we avoid spamming the log if a parent directory is deleted first.
|
|
foreach (DirectoryReference DirectoryToDelete in DirectoriesToDelete.OrderBy(x => x.FullName))
|
|
{
|
|
if (DirectoryReference.Exists(DirectoryToDelete))
|
|
{
|
|
Log.TraceVerbose(" Deleting {0}{1}...", DirectoryToDelete, Path.DirectorySeparatorChar);
|
|
try
|
|
{
|
|
FileUtils.ForceDeleteDirectory(DirectoryToDelete);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
throw new BuildException(Ex, "Unable to delete {0} ({1})", DirectoryToDelete, Ex.Message.TrimEnd());
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (FileReference FileToDelete in FilesToDelete.OrderBy(x => x.FullName))
|
|
{
|
|
if (FileReference.Exists(FileToDelete))
|
|
{
|
|
Log.TraceVerbose(" Deleting " + FileToDelete);
|
|
try
|
|
{
|
|
FileUtils.ForceDeleteFile(FileToDelete);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
throw new BuildException(Ex, "Unable to delete {0} ({1})", FileToDelete, Ex.Message.TrimEnd());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Also clean all the remote targets
|
|
for (int Idx = 0; Idx < TargetDescriptors.Count; Idx++)
|
|
{
|
|
TargetDescriptor TargetDescriptor = TargetDescriptors[Idx];
|
|
if (RemoteMac.HandlesTargetPlatform(TargetDescriptor.Platform))
|
|
{
|
|
RemoteMac RemoteMac = new RemoteMac(TargetDescriptor.ProjectFile);
|
|
RemoteMac.Clean(TargetDescriptor);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|