// Copyright Epic Games, Inc. All Rights Reserved.
using EpicGames.Core;
using System;
using System.Linq;
using UnrealBuildBase;
using UnrealBuildTool;
namespace AutomationTool
{
public partial class CommandUtils
{
///
/// Runs UBT with the specified command line. Automatically creates a logfile. When
/// no LogName is specified, the executable name is used as logfile base name.
///
/// Environment to use.
/// UBT executable to run.
/// Command line to pass on to UBT.
[Obsolete("Deprecated in UE5.1; function signature has changed")]
public static void RunUBT(CommandEnvironment Env, string UBTExecutable, string CommandLine)
{
if (!FileExists(UBTExecutable))
{
throw new AutomationException("Unable to find UBT executable: " + UBTExecutable);
}
FileReference LogLocation = GetUBTLogLocationFromArgs(Env, CommandLine);
CommandLine += String.Format(" -log=\"{0}\"", LogLocation);
IProcessResult Result = Run(UBTExecutable, CommandLine, Options: ERunOptions.AllowSpew | ERunOptions.NoStdOutCapture);
if (Result.ExitCode != 0)
{
throw new AutomationException((ExitCode)Result.ExitCode, "UnrealBuildTool failed. See log for more details. ({0})", CommandUtils.CombinePaths(Env.FinalLogFolder, LogLocation.GetFileName())) { OutputFormat = AutomationExceptionOutputFormat.Minimal };
}
}
///
/// Runs UBT with the specified command line. Automatically creates a logfile. When
/// no LogName is specified, the executable name is used as logfile base name.
///
/// Environment to use.
/// UBT dll to run.
/// Command line to pass on to UBT.
public static void RunUBT(CommandEnvironment Env, FileReference UnrealBuildToolDll, string CommandLine)
{
if (!FileReference.Exists(UnrealBuildToolDll))
{
throw new AutomationException($"Unable to find UnrealBuildTool.dll: {UnrealBuildToolDll}");
}
FileReference LogLocation = GetUBTLogLocationFromArgs(Env, CommandLine);
CommandLine += String.Format(" -log=\"{0}\"", LogLocation);
CommandLine = $"\"{UnrealBuildToolDll}\" {CommandLine}";
IProcessResult Result = Run(Unreal.DotnetPath.FullName, CommandLine, Options: ERunOptions.AllowSpew | ERunOptions.NoStdOutCapture);
if (Result.ExitCode != 0)
{
throw new AutomationException((ExitCode)Result.ExitCode, "UnrealBuildTool failed. See log for more details. ({0})", CommandUtils.CombinePaths(Env.FinalLogFolder, LogLocation.GetFileName())) { OutputFormat = AutomationExceptionOutputFormat.Minimal };
}
}
///
/// Generates a log file name from a UBT command line
///
/// Environment to use.
/// Command line to pass on to UBT.
///
/// Exception if a log file cannot be named after many attempts
private static FileReference GetUBTLogLocationFromArgs(CommandEnvironment Env, string CommandLine)
{
string[] Arguments = SharedUtils.ParseCommandLine(CommandLine);
string BaseLogName = String.Join("-", Arguments.Where(x => !x.Contains('/') && !x.Contains('\\') && !x.StartsWith("-")));
// Look for the first -Target= argument
if (String.IsNullOrWhiteSpace(BaseLogName))
{
string TargetArgument = Arguments.FirstOrDefault(x => x.StartsWith("-Target=", StringComparison.OrdinalIgnoreCase));
if (!String.IsNullOrEmpty(TargetArgument))
{
string[] TargetArguments = SharedUtils.ParseCommandLine(TargetArgument["-Target=".Length..].Trim());
BaseLogName = String.Join("-", TargetArguments.Where(x => !x.Contains('/') && !x.Contains('\\') && !x.StartsWith("-")));
}
}
if (String.IsNullOrWhiteSpace(BaseLogName))
{
BaseLogName = "Log";
}
string LogName;
for (int Attempt = 1; ; Attempt++)
{
LogName = String.Format("UBA-{0}.txt", (Attempt == 1) ? BaseLogName : String.Format("{0}_{1}", BaseLogName, Attempt));
FileReference LogLocation = FileReference.Combine(new DirectoryReference(Env.LogFolder), LogName);
if (!FileReference.Exists(LogLocation))
{
return LogLocation;
}
if (Attempt >= 100)
{
throw new AutomationException("Unable to find name for UBT log file after {0} attempts", Attempt);
}
}
}
///
/// Builds a UBT Command line.
///
/// Unreal project to build (optional)
/// Target to build.
/// Platform to build for.
/// Configuration to build.
/// Additional arguments to pass on to UBT.
public static string UBTCommandline(FileReference Project, string Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Config, string AdditionalArgs = "")
{
string CmdLine;
if (Project == null)
{
CmdLine = String.Format("{0} {1} {2} {3}", Target, Platform, Config, AdditionalArgs);
}
else
{
CmdLine = String.Format("{0} {1} {2} -Project={3} {4}", Target, Platform, Config, CommandUtils.MakePathSafeToUseWithCommandLine(Project.FullName), AdditionalArgs);
}
return CmdLine;
}
///
/// Builds a target using UBT. Automatically creates a logfile. When
/// no LogName is specified, the executable name is used as logfile base name.
///
/// BuildEnvironment to use.
/// UBT executable to run.
/// Unreal project to build (optional)
/// Target to build.
/// Platform to build for.
/// Configuration to build.
/// Additional arguments to pass on to UBT.
[Obsolete("Deprecated in UE5.1; Use the alternate version below with the UnrealBuildTool.dll, not executable")]
public static void RunUBT(CommandEnvironment Env, string UBTExecutable, FileReference Project, string Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Config, string AdditionalArgs = "")
{
RunUBT(Env, UBTExecutable, UBTCommandline(Project, Target, Platform, Config, AdditionalArgs));
}
///
/// Builds a target using UBT. Automatically creates a logfile. When
/// no LogName is specified, the executable name is used as logfile base name.
///
/// BuildEnvironment to use.
/// UBT dll to run.
/// Unreal project to build (optional)
/// Target to build.
/// Platform to build for.
/// Configuration to build.
/// Additional arguments to pass on to UBT.
public static void RunUBT(CommandEnvironment Env, FileReference UnrealBuildToolDll, FileReference Project, string Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Config, string AdditionalArgs = "")
{
RunUBT(Env, UnrealBuildToolDll, UBTCommandline(Project, Target, Platform, Config, AdditionalArgs));
}
}
}