diff --git a/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/BuildGraphPatchSet.cs b/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/BuildGraphPatchSet.cs index 741bab6e..b91c821b 100644 --- a/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/BuildGraphPatchSet.cs +++ b/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/BuildGraphPatchSet.cs @@ -7,8 +7,11 @@ internal record class BuildGraphPatchSet [JsonPropertyName("File"), JsonRequired] public string File { get; set; } = string.Empty; + [JsonPropertyName("Output4")] + public string? Output4 { get; set; } = null; + [JsonPropertyName("Output5"), JsonRequired] - public string Output { get; set; } = string.Empty; + public string Output5 { get; set; } = string.Empty; [JsonPropertyName("Patches"), JsonRequired] public BuildGraphPatchSetPatch[] Patches { get; set; } = Array.Empty(); diff --git a/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/DefaultBuildGraphPatcher.cs b/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/DefaultBuildGraphPatcher.cs index 56ad1ff9..c5346325 100644 --- a/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/DefaultBuildGraphPatcher.cs +++ b/UET/Redpoint.Uet.BuildPipeline/BuildGraph/Patching/DefaultBuildGraphPatcher.cs @@ -153,6 +153,24 @@ private async Task CopyMissingEngineBitsAsync(string enginePath) public async Task PatchBuildGraphAsync(string enginePath, bool isEngineBuild) { + var buildVersionFilePath = Path.Combine(enginePath, "Engine", "Build", "Build.version"); + var isTargetingUnrealEngine4 = false; + if (File.Exists(buildVersionFilePath)) + { + if (File.ReadAllText(buildVersionFilePath).Contains("UE4", StringComparison.Ordinal)) + { + isTargetingUnrealEngine4 = true; + } + } + if (isTargetingUnrealEngine4) + { + _logger.LogTrace("Detected Unreal Engine 4."); + } + else + { + _logger.LogTrace("Detected Unreal Engine 5."); + } + var patchLevelFilePath = Path.Combine(enginePath, "Engine", "Source", "Programs", "UET.BuildGraphPatchLevel.json"); var buildGraphPatchStatus = new BuildGraphPatchStatus(); var applyPatches = false; @@ -199,6 +217,15 @@ public async Task PatchBuildGraphAsync(string enginePath, bool isEngineBuild) foreach (var patchDefinition in _patches) { + if (string.IsNullOrWhiteSpace(patchDefinition.Output4) && isTargetingUnrealEngine4) + { + continue; + } + if (string.IsNullOrWhiteSpace(patchDefinition.Output5) && !isTargetingUnrealEngine4) + { + continue; + } + var filename = patchDefinition.File.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar); var sourceFile = Path.Combine(enginePath, filename); @@ -396,32 +423,35 @@ await _processExecutor.ExecuteAsync( }; foreach (var project in projects) { - _logger.LogInformation($"Restoring packages for: {project.name}"); - var exitCode = await _processExecutor.ExecuteAsync( - new ProcessSpecification - { - FilePath = dotnetPath, - Arguments = [ - "msbuild", - "/nologo", - "/verbosity:quiet", - project.path, - "/property:Configuration=Development", - "/property:Platform=AnyCPU", - "/p:WarningLevel=0", - "/target:Restore", - "/p:NuGetAudit=False", - ], - EnvironmentVariables = new Dictionary - { - { "NUGET_PACKAGES", nugetStoragePath.Path } - } - }, - CaptureSpecification.Passthrough, - CancellationToken.None).ConfigureAwait(false); - if (exitCode != 0) + if (Path.Exists(project.path)) { - throw new InvalidOperationException($"Failed to rebuild BuildGraph (msbuild restore exited with exit code {exitCode})"); + _logger.LogInformation($"Restoring packages for: {project.name}"); + var exitCode = await _processExecutor.ExecuteAsync( + new ProcessSpecification + { + FilePath = dotnetPath, + Arguments = [ + "msbuild", + "/nologo", + "/verbosity:quiet", + project.path, + "/property:Configuration=Development", + "/property:Platform=AnyCPU", + "/p:WarningLevel=0", + "/target:Restore", + "/p:NuGetAudit=False", + ], + EnvironmentVariables = new Dictionary + { + { "NUGET_PACKAGES", nugetStoragePath.Path } + } + }, + CaptureSpecification.Passthrough, + CancellationToken.None).ConfigureAwait(false); + if (exitCode != 0) + { + throw new InvalidOperationException($"Failed to rebuild BuildGraph (msbuild restore exited with exit code {exitCode})"); + } } } foreach (var project in projects) @@ -431,31 +461,34 @@ await _processExecutor.ExecuteAsync( continue; } - _logger.LogInformation($"Building: {project.name}"); - var exitCode = await _processExecutor.ExecuteAsync( - new ProcessSpecification - { - FilePath = dotnetPath, - Arguments = [ - "msbuild", - "/nologo", - "/verbosity:quiet", - project.path, - "/property:Configuration=Development", - "/property:Platform=AnyCPU", - "/p:WarningLevel=0", - "/p:NuGetAudit=False", - ], - EnvironmentVariables = new Dictionary - { - { "NUGET_PACKAGES", nugetStoragePath.Path } - } - }, - CaptureSpecification.Passthrough, - CancellationToken.None).ConfigureAwait(false); - if (exitCode != 0) + if (Path.Exists(project.path)) { - throw new InvalidOperationException($"Failed to rebuild BuildGraph (msbuild compile exited with exit code {exitCode})"); + _logger.LogInformation($"Building: {project.name}"); + var exitCode = await _processExecutor.ExecuteAsync( + new ProcessSpecification + { + FilePath = dotnetPath, + Arguments = [ + "msbuild", + "/nologo", + "/verbosity:quiet", + project.path, + "/property:Configuration=Development", + "/property:Platform=AnyCPU", + "/p:WarningLevel=0", + "/p:NuGetAudit=False", + ], + EnvironmentVariables = new Dictionary + { + { "NUGET_PACKAGES", nugetStoragePath.Path } + } + }, + CaptureSpecification.Passthrough, + CancellationToken.None).ConfigureAwait(false); + if (exitCode != 0) + { + throw new InvalidOperationException($"Failed to rebuild BuildGraph (msbuild compile exited with exit code {exitCode})"); + } } } diff --git a/UET/uet/Commands/Build/BuildCommand.cs b/UET/uet/Commands/Build/BuildCommand.cs index ecc75f78..1bd4e3b4 100644 --- a/UET/uet/Commands/Build/BuildCommand.cs +++ b/UET/uet/Commands/Build/BuildCommand.cs @@ -31,6 +31,7 @@ internal sealed class Options public Option Deploy; public Option StrictIncludes; public Option StorageVirtualisation; + public Option Legacy; public Option Distribution; @@ -107,6 +108,11 @@ public Options( description: "If set, enables storage virtualisation via UEFS."); StorageVirtualisation.AddAlias("-u"); + Legacy = new Option( + "--legacy", + description: "If set, indicates that the engine is Unreal Engine 4, not Unreal Engine 5. Do not report bugs when using this option - it is unsupported and 'best effort' only."); + Legacy.IsHidden = true; + // ==== .uproject / .uplugin options Shipping = new Option( @@ -288,6 +294,7 @@ public async Task ExecuteAsync(InvocationContext context) var pluginPackage = context.ParseResult.GetValueForOption(_options.PluginPackage); var pluginVersionName = context.ParseResult.GetValueForOption(_options.PluginVersionName); var pluginVersionNumber = context.ParseResult.GetValueForOption(_options.PluginVersionNumber); + var legacy = context.ParseResult.GetValueForOption(_options.Legacy); // Configure the dynamic workspace provider to use workspace virtualisation // if appropriate. @@ -370,6 +377,13 @@ public async Task ExecuteAsync(InvocationContext context) _logger.LogInformation($"--plugin-package: {pluginPackage}"); _logger.LogInformation($"--plugin-version-name: {pluginVersionName}"); _logger.LogInformation($"--plugin-version-number: {pluginVersionNumber}"); + if (legacy) + { + _logger.LogInformation($"--legacy: yes (unsupported)"); + _logger.LogWarning(""); + _logger.LogWarning("Use of the --legacy option is unsupported. Do not report bugs or issues when using this flag."); + _logger.LogWarning(""); + } BuildEngineSpecification engineSpec; switch (engine.Type) @@ -506,7 +520,8 @@ public async Task ExecuteAsync(InvocationContext context) localExecutor: executorName == "local", isPluginRooted: false, commandlinePluginVersionName: pluginVersionName, - commandlinePluginVersionNumber: pluginVersionNumber).ConfigureAwait(false); + commandlinePluginVersionNumber: pluginVersionNumber, + legacy).ConfigureAwait(false); preparePlugin = pluginDistribution.Prepare; break; case BuildConfigEngineDistribution engineDistribution: diff --git a/UET/uet/Commands/Build/DefaultBuildSpecificationGenerator.cs b/UET/uet/Commands/Build/DefaultBuildSpecificationGenerator.cs index c064f52a..fcb9b58a 100644 --- a/UET/uet/Commands/Build/DefaultBuildSpecificationGenerator.cs +++ b/UET/uet/Commands/Build/DefaultBuildSpecificationGenerator.cs @@ -339,6 +339,19 @@ await _dynamicBuildGraphIncludeWriter.WriteBuildGraphMacroInclude( return ($"__SHARED_STORAGE_PATH__/{nodeFilename}", $"__SHARED_STORAGE_PATH__/{macroFilename}"); } + private static bool IsUnrealEngine4(string enginePath) + { + var buildVersionFilePath = Path.Combine(enginePath, "Engine", "Build", "Build.version"); + if (File.Exists(buildVersionFilePath)) + { + if (File.ReadAllText(buildVersionFilePath).Contains("UE4", StringComparison.Ordinal)) + { + return true; + } + } + return false; + } + public async Task BuildConfigPluginToBuildSpecAsync( BuildEngineSpecification engineSpec, BuildGraphEnvironment buildGraphEnvironment, @@ -353,7 +366,8 @@ public async Task BuildConfigPluginToBuildSpecAsync( bool localExecutor, bool isPluginRooted, string? commandlinePluginVersionName, - long? commandlinePluginVersionNumber) + long? commandlinePluginVersionNumber, + bool legacy) { // Determine build matrix. var editorTargetPlatforms = FilterIncompatiblePlatforms((distribution.Build.Editor?.Platforms ?? new[] { BuildConfigPluginBuildEditorPlatform.Win64 }).Select(x => @@ -520,7 +534,7 @@ public async Task BuildConfigPluginToBuildSpecAsync( { "ScriptMacroIncludes", scriptMacroIncludes }, // General options - { "IsUnrealEngine5", "true" }, + { "IsUnrealEngine5", legacy ? "false" : "true" }, // Clean options { $"CleanDirectories", string.Join(";", cleanDirectories) }, @@ -537,7 +551,7 @@ public async Task BuildConfigPluginToBuildSpecAsync( { $"MacPlatforms", $"IOS;Mac" }, { $"StrictIncludes", strictIncludes || strictIncludesAtPluginLevel ? "true" : "false" }, { $"Allow2019", "false" }, - { $"EnginePrefix", "Unreal" }, + { $"EnginePrefix", legacy ? "UE4" : "Unreal" }, // Package options { $"ExecutePackage", executePackage ? "true" : "false" }, diff --git a/UET/uet/Commands/Build/IBuildSpecificationGenerator.cs b/UET/uet/Commands/Build/IBuildSpecificationGenerator.cs index 1e6291a9..7a174556 100644 --- a/UET/uet/Commands/Build/IBuildSpecificationGenerator.cs +++ b/UET/uet/Commands/Build/IBuildSpecificationGenerator.cs @@ -35,7 +35,8 @@ Task BuildConfigPluginToBuildSpecAsync( bool localExecutor, bool isPluginRooted, string? commandlinePluginVersionName, - long? commandlinePluginVersionNumber); + long? commandlinePluginVersionNumber, + bool legacy); Task BuildConfigEngineToBuildSpecAsync( BuildEngineSpecification engineSpec, diff --git a/UET/uet/Commands/Test/TestCommand.cs b/UET/uet/Commands/Test/TestCommand.cs index 87bdd3df..4d36bb6e 100644 --- a/UET/uet/Commands/Test/TestCommand.cs +++ b/UET/uet/Commands/Test/TestCommand.cs @@ -285,7 +285,8 @@ public async Task ExecuteAsync(InvocationContext context) localExecutor: true, isPluginRooted: true, commandlinePluginVersionName: null, - commandlinePluginVersionNumber: null).ConfigureAwait(false); + commandlinePluginVersionNumber: null, + false).ConfigureAwait(false); break; default: throw new NotSupportedException();