2022-06-03 19:17:37 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Text ;
using EpicGames.Core ;
using Microsoft.Extensions.Logging ;
using UnrealBuildBase ;
namespace UnrealBuildTool
{
abstract class ISPCToolChain : UEToolChain
{
public ISPCToolChain ( ILogger InLogger ) : base ( InLogger )
{
}
2024-04-17 12:53:34 -04:00
protected FileReference ? ProjectFile = null ;
2024-05-22 11:15:45 -04:00
protected bool bMergeModules = false ;
2024-05-23 17:13:00 -04:00
protected bool bAllowUbaCompression = false ;
2024-04-17 12:53:34 -04:00
public override void SetUpGlobalEnvironment ( ReadOnlyTargetRules Target )
{
base . SetUpGlobalEnvironment ( Target ) ;
ProjectFile = Target . ProjectFile ;
2024-05-22 11:15:45 -04:00
bMergeModules = Target . bMergeModules ;
2024-05-23 17:13:00 -04:00
bAllowUbaCompression = Target . bAllowUbaCompression ;
2024-04-17 12:53:34 -04:00
}
2022-06-03 19:17:37 -04:00
/// <summary>
/// Get CPU Instruction set targets for ISPC.
/// </summary>
/// <param name="Platform">Which OS platform to target.</param>
/// <param name="Arch">Which architecture inside an OS platform to target. Only used for Android currently.</param>
/// <returns>List of instruction set targets passed to ISPC compiler</returns>
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
public virtual List < string > GetISPCCompileTargets ( UnrealTargetPlatform Platform , UnrealArch ? Arch )
2022-06-03 19:17:37 -04:00
{
List < string > ISPCTargets = new List < string > ( ) ;
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
// @todo this could be simplified for the arm case - but sse has more options
2022-06-03 19:17:37 -04:00
if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Windows ) | |
( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Unix ) & & Platform ! = UnrealTargetPlatform . LinuxArm64 ) | |
Platform = = UnrealTargetPlatform . Mac )
{
2023-01-09 17:42:09 -05:00
ISPCTargets . AddRange ( new string [ ] { "avx512skx-i32x8" , "avx2" , "avx" , "sse4" } ) ;
2022-06-03 19:17:37 -04:00
}
else if ( Platform = = UnrealTargetPlatform . LinuxArm64 )
{
ISPCTargets . AddRange ( new string [ ] { "neon" } ) ;
}
else if ( Platform = = UnrealTargetPlatform . Android )
{
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
if ( Arch = = UnrealArch . X64 )
2022-06-03 19:17:37 -04:00
{
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
ISPCTargets . Add ( "sse4" ) ;
}
else if ( Arch = = UnrealArch . Arm64 )
{
ISPCTargets . Add ( "neon" ) ;
}
else
{
Logger . LogWarning ( "Invalid Android architecture for ISPC. At least one architecture (arm64, x64) needs to be selected in the project settings to build" ) ;
2022-06-03 19:17:37 -04:00
}
}
2022-12-09 09:12:18 -05:00
else if ( Platform = = UnrealTargetPlatform . IOS )
{
ISPCTargets . Add ( "neon" ) ;
}
2022-06-03 19:17:37 -04:00
else
{
Logger . LogWarning ( "Unsupported ISPC platform target!" ) ;
}
return ISPCTargets ;
}
/// <summary>
/// Get OS target for ISPC.
/// </summary>
/// <param name="Platform">Which OS platform to target.</param>
/// <returns>OS string passed to ISPC compiler</returns>
public virtual string GetISPCOSTarget ( UnrealTargetPlatform Platform )
{
string ISPCOS = "" ;
if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Windows ) )
{
ISPCOS + = "windows" ;
}
else if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Unix ) )
{
ISPCOS + = "linux" ;
}
else if ( Platform = = UnrealTargetPlatform . Android )
{
ISPCOS + = "android" ;
}
2022-12-09 09:12:18 -05:00
else if ( Platform = = UnrealTargetPlatform . IOS )
{
ISPCOS + = "ios" ;
}
2022-06-03 19:17:37 -04:00
else if ( Platform = = UnrealTargetPlatform . Mac )
{
ISPCOS + = "macos" ;
}
else
{
Logger . LogWarning ( "Unsupported ISPC platform target!" ) ;
}
return ISPCOS ;
}
/// <summary>
/// Get CPU architecture target for ISPC.
/// </summary>
/// <param name="Platform">Which OS platform to target.</param>
/// <param name="Arch">Which architecture inside an OS platform to target. Only used for Android currently.</param>
/// <returns>Arch string passed to ISPC compiler</returns>
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
public virtual string GetISPCArchTarget ( UnrealTargetPlatform Platform , UnrealArch ? Arch )
2022-06-03 19:17:37 -04:00
{
string ISPCArch = "" ;
if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Windows ) | |
( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Unix ) & & Platform ! = UnrealTargetPlatform . LinuxArm64 ) | |
Platform = = UnrealTargetPlatform . Mac )
{
ISPCArch + = "x86-64" ;
}
else if ( Platform = = UnrealTargetPlatform . LinuxArm64 )
{
ISPCArch + = "aarch64" ;
}
else if ( Platform = = UnrealTargetPlatform . Android )
{
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
if ( Arch = = UnrealArch . Arm64 )
2022-06-03 19:17:37 -04:00
{
UnrealArch/UnrealArchitectures changes
- Creates the UnrealArchitectures class, which wraps a list of UnrealArch objects
- UnrealArch is a single architecture, expandable enum-like struct
- There is no more concept of "no/default architecture", there is always a valid active architecture when building
- Most uses of "string Architecture" are replaced with one of the two above, depending if multiple architectures are supported or not
- UnrealArch has some platform-extensions for platform-specific naming (like Linux adds in LinuxName that turns, for instance, Arm64 -> aarch64-unknown-linux-gnueabi, which is used in folder names, etc)
- UnrealArch has bIsX64 which can be used determine intel instruction set (as opposed to arm)
- TargetRules class has an "Architecture" accessor that will return a single architecture if the active architectures is a single architecture, or throw an exception if multiple. This is useful in a majority of the cases where a paltform can only have a single architecture active in TargetRules (microsoft platforms, for instance, will create separate targets when compiling multiple architectures at once)
- Added UnrealArchitectureConfig class, which contains all the architecture information for a platform (what architectures are supported, what ones are currently active for given project, etc)
#preflight 63c81fb5b065224750a1759e
#rb mike.fricker,roman.dzieciol,joe.kirchoff,dmytro.vovk,brandon.schaefer [various parts]
#p4v-preflight-copy 23562471
[CL 23829977 by josh adams in ue5-main branch]
2023-01-24 09:30:28 -05:00
ISPCArch + = "aarch64" ;
}
else if ( Arch = = UnrealArch . X64 )
{
ISPCArch + = "x86-64" ;
}
else
{
Logger . LogWarning ( "Invalid Android architecture for ISPC. At least one architecture (arm64, x64) needs to be selected in the project settings to build" ) ;
2022-06-03 19:17:37 -04:00
}
}
2022-12-09 09:12:18 -05:00
else if ( Platform = = UnrealTargetPlatform . IOS )
{
2023-05-30 18:38:07 -04:00
ISPCArch + = "aarch64" ;
2022-12-09 09:12:18 -05:00
}
2022-06-03 19:17:37 -04:00
else
{
Logger . LogWarning ( "Unsupported ISPC platform target!" ) ;
}
return ISPCArch ;
}
/// <summary>
/// Get CPU target for ISPC.
/// </summary>
/// <param name="Platform">Which OS platform to target.</param>
/// <returns>CPU string passed to ISPC compiler</returns>
public virtual string? GetISPCCpuTarget ( UnrealTargetPlatform Platform )
{
return null ; // no specific CPU selected
}
/// <summary>
/// Get host compiler path for ISPC.
/// </summary>
2022-07-22 13:20:45 -04:00
/// <param name="HostPlatform">Which OS build platform is running on.</param>
2022-06-03 19:17:37 -04:00
/// <returns>Path to ISPC compiler</returns>
2022-07-22 13:20:45 -04:00
public virtual string GetISPCHostCompilerPath ( UnrealTargetPlatform HostPlatform )
2022-06-03 19:17:37 -04:00
{
string ISPCCompilerPathCommon = Path . Combine ( Unreal . EngineSourceDirectory . FullName , "ThirdParty" , "Intel" , "ISPC" , "bin" ) ;
string ISPCArchitecturePath = "" ;
string ExeExtension = ".exe" ;
2022-07-22 13:20:45 -04:00
if ( UEBuildPlatform . IsPlatformInGroup ( HostPlatform , UnrealPlatformGroup . Windows ) )
2022-06-03 19:17:37 -04:00
{
ISPCArchitecturePath = "Windows" ;
}
2022-07-22 13:20:45 -04:00
else if ( HostPlatform = = UnrealTargetPlatform . Linux )
2022-06-03 19:17:37 -04:00
{
ISPCArchitecturePath = "Linux" ;
ExeExtension = "" ;
}
2022-07-22 13:20:45 -04:00
else if ( HostPlatform = = UnrealTargetPlatform . Mac )
2022-06-03 19:17:37 -04:00
{
ISPCArchitecturePath = "Mac" ;
ExeExtension = "" ;
}
else
{
Logger . LogWarning ( "Unsupported ISPC host!" ) ;
}
return Path . Combine ( ISPCCompilerPathCommon , ISPCArchitecturePath , "ispc" + ExeExtension ) ;
}
2022-07-22 13:20:45 -04:00
/// <summary>
/// Get the host bytecode-to-obj compiler path for ISPC. Only used for platforms that support compiling ISPC to LLVM bytecode
/// </summary>
/// <param name="HostPlatform">Which OS build platform is running on.</param>
/// <returns>Path to bytecode to obj compiler</returns>
public virtual string? GetISPCHostBytecodeCompilerPath ( UnrealTargetPlatform HostPlatform )
{
// Return null if the platform toolchain doesn't support separate bytecode to obj compilation
return null ;
}
2022-06-03 19:17:37 -04:00
static Dictionary < UnrealTargetPlatform , string > ISPCCompilerVersions = new Dictionary < UnrealTargetPlatform , string > ( ) ;
/// <summary>
/// Returns the version of the ISPC compiler for the specified platform. If GetISPCHostCompilerPath() doesn't return a valid path
/// this will return a -1 version.
/// </summary>
/// <param name="Platform">Which OS build platform is running on.</param>
/// <returns>Version reported by the ISPC compilerr</returns>
public virtual string GetISPCHostCompilerVersion ( UnrealTargetPlatform Platform )
{
if ( ! ISPCCompilerVersions . ContainsKey ( Platform ) )
{
Version ? CompilerVersion = null ;
string CompilerPath = GetISPCHostCompilerPath ( Platform ) ;
if ( ! File . Exists ( CompilerPath ) )
{
Logger . LogWarning ( "No ISPC compiler at {CompilerPath}" , CompilerPath ) ;
CompilerVersion = new Version ( - 1 , - 1 ) ;
}
ISPCCompilerVersions [ Platform ] = RunToolAndCaptureOutput ( new FileReference ( CompilerPath ) , "--version" , "(.*)" ) ! ;
}
return ISPCCompilerVersions [ Platform ] ;
}
/// <summary>
/// Get object file format for ISPC.
/// </summary>
/// <param name="Platform">Which OS build platform is running on.</param>
/// <returns>Object file suffix</returns>
public virtual string GetISPCObjectFileFormat ( UnrealTargetPlatform Platform )
{
string Format = "" ;
if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Windows ) )
{
Format + = "obj" ;
}
else if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Unix ) | |
Platform = = UnrealTargetPlatform . Mac | |
2022-12-09 09:12:18 -05:00
Platform = = UnrealTargetPlatform . IOS | |
2022-06-03 19:17:37 -04:00
Platform = = UnrealTargetPlatform . Android )
{
Format + = "obj" ;
}
else
{
Logger . LogWarning ( "Unsupported ISPC platform target!" ) ;
}
return Format ;
}
/// <summary>
/// Get object file suffix for ISPC.
/// </summary>
/// <param name="Platform">Which OS build platform is running on.</param>
/// <returns>Object file suffix</returns>
public virtual string GetISPCObjectFileSuffix ( UnrealTargetPlatform Platform )
{
string Suffix = "" ;
if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Windows ) )
{
Suffix + = ".obj" ;
}
else if ( UEBuildPlatform . IsPlatformInGroup ( Platform , UnrealPlatformGroup . Unix ) | |
Platform = = UnrealTargetPlatform . Mac | |
2022-12-09 09:12:18 -05:00
Platform = = UnrealTargetPlatform . IOS | |
2022-06-03 19:17:37 -04:00
Platform = = UnrealTargetPlatform . Android )
{
Suffix + = ".o" ;
}
else
{
Logger . LogWarning ( "Unsupported ISPC platform target!" ) ;
}
return Suffix ;
}
private string EscapeDefinitionForISPC ( string Definition )
{
// See: https://github.com/ispc/ispc/blob/4ee767560cd752eaf464c124eb7ef1b0fd37f1df/src/main.cpp#L264 for ispc's argument parsing code, which does the following (and does not support escaping):
// Argument Parses as
// "abc""def" One agrument: abcdef
// "'abc'" One argument: 'abc'
// -D"X="Y Z"" Two arguments: -DX=Y and Z
// -D'X="Y Z"' One argument: -DX="Y Z" (i.e. with quotes in value)
// -DX="Y Z" One argument: -DX=Y Z (this is what we want on the command line)
// Assumes that quotes at the start and end of the value string mean that everything between them should be passed on unchanged.
int DoubleQuoteCount = Definition . Count ( c = > c = = '"' ) ;
bool bHasSingleQuote = Definition . Contains ( '\'' ) ;
bool bHasSpace = Definition . Contains ( ' ' ) ;
string Escaped = Definition ;
if ( DoubleQuoteCount > 0 | | bHasSingleQuote | | bHasSpace )
{
int EqualsIndex = Definition . IndexOf ( '=' ) ;
string Name = Definition [ 0. . EqualsIndex ] ;
string Value = Definition [ ( EqualsIndex + 1 ) . . ] ;
string UnquotedValue = Value ;
// remove one layer of quoting, if present
if ( Value . StartsWith ( '"' ) & & Value . EndsWith ( '"' ) & & Value . Length ! = 1 )
{
UnquotedValue = Value [ 1. . ^ 1 ] ;
DoubleQuoteCount - = 2 ;
}
if ( DoubleQuoteCount = = 0 & & ( bHasSingleQuote | | bHasSpace ) )
{
Escaped = $"{Name}=\" { UnquotedValue } \ "" ;
}
else if ( ! bHasSingleQuote & & ( bHasSpace | | DoubleQuoteCount > 0 ) )
{
// If there are no single quotes, we can use them to quote the value string
Escaped = $"{Name}='{UnquotedValue}'" ;
}
else
{
// Treat all special chars in the value string as needing explicit extra quoting. Thoroughly clumsy.
StringBuilder Requoted = new StringBuilder ( ) ;
foreach ( char c in UnquotedValue )
{
if ( c = = '"' )
{
Requoted . Append ( "'\"'" ) ;
}
else if ( c = = '\'' )
{
Requoted . Append ( "\"'\"" ) ;
}
else if ( c = = ' ' )
{
Requoted . Append ( "\" \"" ) ;
}
else
{
Requoted . Append ( c ) ;
}
}
Escaped = $"{Name}={Requoted}" ;
}
}
return Escaped ;
}
/// <summary>
/// Normalize a path for use in a command line, making it relative to Engine/Source if under the root directory
/// </summary>
/// <param name="Reference">The FileSystemReference to normalize</param>
/// <returns>Normalized path as a string</returns>
2022-12-08 21:33:56 -05:00
protected virtual string NormalizeCommandLinePath ( FileSystemReference Reference )
2022-06-03 19:17:37 -04:00
{
2024-05-22 17:16:35 -04:00
string path = Reference . FullName ;
2022-06-03 19:17:37 -04:00
// Try to use a relative path to shorten command line length.
if ( Reference . IsUnderDirectory ( Unreal . RootDirectory ) )
{
2024-05-22 17:16:35 -04:00
path = Reference . MakeRelativeTo ( Unreal . EngineSourceDirectory ) ;
2022-06-03 19:17:37 -04:00
}
2024-05-22 17:16:35 -04:00
if ( Path . DirectorySeparatorChar = = '/' )
{
path = path . Replace ( "\\" , "/" ) ;
}
else
{
path = path . Replace ( "\\" , "\\\\" ) ;
}
return path ;
2022-06-03 19:17:37 -04:00
}
/// <summary>
/// Normalize a path for use in a command line, making it relative if under the Root Directory
/// </summary>
/// <param name="Item">The FileItem to normalize</param>
/// <returns>Normalized path as a string</returns>
2022-12-08 21:33:56 -05:00
protected virtual string NormalizeCommandLinePath ( FileItem Item )
2022-06-03 19:17:37 -04:00
{
return NormalizeCommandLinePath ( Item . Location ) ;
}
2024-04-17 12:53:34 -04:00
protected virtual IEnumerable < DirectoryItem > GetEnvironmentBasePaths ( CppCompileEnvironment CompileEnvironment )
{
yield return DirectoryItem . GetItemByDirectoryReference ( Unreal . EngineDirectory ) ;
if ( ProjectFile ! = null & & ( ! CompileEnvironment . bUseSharedBuildEnvironment | | CompileEnvironment . AllIncludePath . Any ( x = > x . IsUnderDirectory ( ProjectFile . Directory ) ) ) )
{
yield return DirectoryItem . GetItemByDirectoryReference ( ProjectFile . Directory ) ;
}
yield return DirectoryItem . GetItemByDirectoryReference ( Unreal . RootDirectory ) ;
}
protected virtual IEnumerable < DirectoryItem > GetEnvironmentBasePaths ( LinkEnvironment LinkEnvironment )
{
yield return DirectoryItem . GetItemByDirectoryReference ( Unreal . EngineDirectory ) ;
if ( ProjectFile ! = null & & LinkEnvironment . InputFiles . Any ( x = > x . Location . IsUnderDirectory ( ProjectFile . Directory ) ) )
{
yield return DirectoryItem . GetItemByDirectoryReference ( ProjectFile . Directory ) ;
}
yield return DirectoryItem . GetItemByDirectoryReference ( Unreal . RootDirectory ) ;
}
2023-10-04 20:25:45 -04:00
public override CPPOutput GenerateISPCHeaders ( CppCompileEnvironment CompileEnvironment , IEnumerable < FileItem > InputFiles , DirectoryReference OutputDir , IActionGraphBuilder Graph )
2022-06-03 19:17:37 -04:00
{
CPPOutput Result = new CPPOutput ( ) ;
if ( ! CompileEnvironment . bCompileISPC )
{
return Result ;
}
List < string > CompileTargets = GetISPCCompileTargets ( CompileEnvironment . Platform , null ) ;
List < string > GlobalArguments = new List < string > ( ) ;
// Build target string. No comma on last
2024-04-03 17:18:04 -04:00
string TargetString = String . Join ( ',' , CompileTargets ) ;
2022-06-03 19:17:37 -04:00
2023-04-24 20:05:37 -04:00
string ISPCArch = GetISPCArchTarget ( CompileEnvironment . Platform , null ) ;
2022-06-03 19:17:37 -04:00
// Build target triplet
GlobalArguments . Add ( $"--target-os={GetISPCOSTarget(CompileEnvironment.Platform)}" ) ;
2023-04-24 20:05:37 -04:00
GlobalArguments . Add ( $"--arch={ISPCArch}" ) ;
2022-06-03 19:17:37 -04:00
GlobalArguments . Add ( $"--target={TargetString}" ) ;
GlobalArguments . Add ( $"--emit-{GetISPCObjectFileFormat(CompileEnvironment.Platform)}" ) ;
string? CpuTarget = GetISPCCpuTarget ( CompileEnvironment . Platform ) ;
if ( ! String . IsNullOrEmpty ( CpuTarget ) )
{
GlobalArguments . Add ( $"--cpu={CpuTarget}" ) ;
}
// PIC is needed for modular builds except on Microsoft platforms
if ( ( CompileEnvironment . bIsBuildingDLL | |
CompileEnvironment . bIsBuildingLibrary ) & &
! UEBuildPlatform . IsPlatformInGroup ( CompileEnvironment . Platform , UnrealPlatformGroup . Microsoft ) )
{
GlobalArguments . Add ( "--pic" ) ;
}
// Include paths. Don't use AddIncludePath() here, since it uses the full path and exceeds the max command line length.
// Because ISPC response files don't support white space in arguments, paths with white space need to be passed to the command line directly.
foreach ( DirectoryReference IncludePath in CompileEnvironment . UserIncludePaths )
{
GlobalArguments . Add ( $"-I\" { NormalizeCommandLinePath ( IncludePath ) } \ "" ) ;
}
// System include paths.
foreach ( DirectoryReference SystemIncludePath in CompileEnvironment . SystemIncludePaths )
{
GlobalArguments . Add ( $"-I\" { NormalizeCommandLinePath ( SystemIncludePath ) } \ "" ) ;
}
// Preprocessor definitions.
foreach ( string Definition in CompileEnvironment . Definitions )
{
// TODO: Causes ISPC compiler to generate a spurious warning about the universal character set
if ( ! Definition . Contains ( "\\\\U" ) & & ! Definition . Contains ( "\\\\u" ) )
{
GlobalArguments . Add ( $"-D{EscapeDefinitionForISPC(Definition)}" ) ;
}
}
2024-04-17 12:53:34 -04:00
List < DirectoryItem > RootPaths = new ( GetEnvironmentBasePaths ( CompileEnvironment ) ) ;
2022-06-03 19:17:37 -04:00
foreach ( FileItem ISPCFile in InputFiles )
{
Action CompileAction = Graph . CreateAction ( ActionType . Compile ) ;
2024-04-17 12:53:34 -04:00
CompileAction . RootPaths . AddRange ( RootPaths ) ;
2023-04-24 20:05:37 -04:00
CompileAction . CommandDescription = $"Generate Header [{ISPCArch}]" ;
2022-06-03 19:17:37 -04:00
CompileAction . WorkingDirectory = Unreal . EngineSourceDirectory ;
CompileAction . CommandPath = new FileReference ( GetISPCHostCompilerPath ( BuildHostPlatform . Current . Platform ) ) ;
CompileAction . StatusDescription = Path . GetFileName ( ISPCFile . AbsolutePath ) ;
2024-05-23 17:13:00 -04:00
CompileAction . CommandVersion = GetISPCHostCompilerVersion ( BuildHostPlatform . Current . Platform ) . ToString ( ) ;
2023-05-26 12:48:45 -04:00
CompileAction . ArtifactMode = ArtifactMode . Enabled ;
2022-06-03 19:17:37 -04:00
2023-04-25 19:24:51 -04:00
CompileAction . bCanExecuteRemotely = true ;
2022-06-03 19:17:37 -04:00
// Disable remote execution to workaround mismatched case on XGE
2023-04-25 19:24:51 -04:00
CompileAction . bCanExecuteRemotelyWithXGE = false ;
// TODO: Remove, might work
CompileAction . bCanExecuteRemotelyWithSNDBS = false ;
2022-06-03 19:17:37 -04:00
List < string > Arguments = new List < string > ( ) ;
// Add the ISPC obj file as a prerequisite of the action.
Arguments . Add ( $"\" { NormalizeCommandLinePath ( ISPCFile ) } \ "" ) ;
// Add the ISPC h file to the produced item list.
FileItem ISPCIncludeHeaderFile = FileItem . GetItemByFileReference (
FileReference . Combine (
OutputDir ,
Path . GetFileName ( ISPCFile . AbsolutePath ) + ".generated.dummy.h"
)
) ;
// Add the ISPC file to be compiled.
Arguments . Add ( $"-h \" { NormalizeCommandLinePath ( ISPCIncludeHeaderFile ) } \ "" ) ;
// Generate the included header dependency list
2022-11-02 11:47:47 -04:00
FileItem DependencyListFile = FileItem . GetItemByFileReference ( FileReference . Combine ( OutputDir , Path . GetFileName ( ISPCFile . AbsolutePath ) + ".txt" ) ) ;
Arguments . Add ( $"-MMM \" { NormalizeCommandLinePath ( DependencyListFile ) } \ "" ) ;
CompileAction . DependencyListFile = DependencyListFile ;
CompileAction . ProducedItems . Add ( DependencyListFile ) ;
2022-06-03 19:17:37 -04:00
Arguments . AddRange ( GlobalArguments ) ;
CompileAction . ProducedItems . Add ( ISPCIncludeHeaderFile ) ;
2023-01-27 15:19:25 -05:00
FileReference ResponseFileName = GetResponseFileName ( CompileEnvironment , ISPCIncludeHeaderFile ) ;
2022-06-03 19:17:37 -04:00
FileItem ResponseFileItem = Graph . CreateIntermediateTextFile ( ResponseFileName , Arguments . Select ( x = > Utils . ExpandVariables ( x ) ) ) ;
CompileAction . CommandArguments = $"@\" { NormalizeCommandLinePath ( ResponseFileName ) } \ "" ;
CompileAction . PrerequisiteItems . Add ( ResponseFileItem ) ;
// Add the source file and its included files to the prerequisite item list.
CompileAction . PrerequisiteItems . Add ( ISPCFile ) ;
FileItem ISPCFinalHeaderFile = FileItem . GetItemByFileReference (
FileReference . Combine (
OutputDir ,
Path . GetFileName ( ISPCFile . AbsolutePath ) + ".generated.h"
)
) ;
// Fix interrupted build issue by copying header after generation completes
2022-11-02 11:47:09 -04:00
Action CopyAction = Graph . CreateCopyAction ( ISPCIncludeHeaderFile , ISPCFinalHeaderFile ) ;
2023-04-24 20:05:37 -04:00
CopyAction . CommandDescription = $"{CopyAction.CommandDescription} [{ISPCArch}]" ;
2022-11-02 11:47:09 -04:00
CopyAction . DeleteItems . Clear ( ) ;
2022-09-02 18:36:49 -04:00
CopyAction . PrerequisiteItems . Add ( ISPCFile ) ;
2022-06-03 19:17:37 -04:00
CopyAction . bShouldOutputStatusDescription = false ;
2022-11-02 11:47:09 -04:00
Result . GeneratedHeaderFiles . Add ( ISPCFinalHeaderFile ) ;
2022-06-03 19:17:37 -04:00
Logger . LogDebug ( " ISPC Generating Header {StatusDescription}: \"{CommandPath}\" {CommandArguments}" , CompileAction . StatusDescription , CompileAction . CommandPath , CompileAction . CommandArguments ) ;
}
return Result ;
}
2023-10-04 20:25:45 -04:00
public override CPPOutput CompileISPCFiles ( CppCompileEnvironment CompileEnvironment , IEnumerable < FileItem > InputFiles , DirectoryReference OutputDir , IActionGraphBuilder Graph )
2022-06-03 19:17:37 -04:00
{
CPPOutput Result = new CPPOutput ( ) ;
if ( ! CompileEnvironment . bCompileISPC )
{
return Result ;
}
List < string > CompileTargets = GetISPCCompileTargets ( CompileEnvironment . Platform , null ) ;
List < string > GlobalArguments = new List < string > ( ) ;
// Build target string. No comma on last
string TargetString = "" ;
foreach ( string Target in CompileTargets )
{
2024-04-03 17:18:04 -04:00
if ( Target = = CompileTargets [ ^ 1 ] ) // .Last()
2022-06-03 19:17:37 -04:00
{
TargetString + = Target ;
}
else
{
TargetString + = Target + "," ;
}
}
// Build target triplet
2022-07-22 13:20:45 -04:00
string PlatformObjectFileFormat = GetISPCObjectFileFormat ( CompileEnvironment . Platform ) ;
2023-04-24 20:05:37 -04:00
string ISPCArch = GetISPCArchTarget ( CompileEnvironment . Platform , null ) ;
2022-07-22 13:20:45 -04:00
2022-06-03 19:17:37 -04:00
GlobalArguments . Add ( $"--target-os={GetISPCOSTarget(CompileEnvironment.Platform)}" ) ;
2023-04-24 20:05:37 -04:00
GlobalArguments . Add ( $"--arch={ISPCArch}" ) ;
2022-06-03 19:17:37 -04:00
GlobalArguments . Add ( $"--target={TargetString}" ) ;
2022-07-22 13:20:45 -04:00
GlobalArguments . Add ( $"--emit-{PlatformObjectFileFormat}" ) ;
2022-06-03 19:17:37 -04:00
2023-10-02 13:02:49 -04:00
string? CpuTarget = GetISPCCpuTarget ( CompileEnvironment . Platform ) ;
if ( ! String . IsNullOrEmpty ( CpuTarget ) )
{
GlobalArguments . Add ( $"--cpu={CpuTarget}" ) ;
}
2023-05-30 18:38:07 -04:00
bool bByteCodeOutput = ( PlatformObjectFileFormat = = "llvm" ) ;
2022-07-22 13:20:45 -04:00
List < string > CommonArgs = new List < string > ( ) ;
2022-06-03 19:17:37 -04:00
if ( CompileEnvironment . Configuration = = CppConfiguration . Debug )
{
if ( CompileEnvironment . Platform = = UnrealTargetPlatform . Mac )
{
// Turn off debug symbols on Mac due to dsym generation issue
2022-07-22 13:20:45 -04:00
CommonArgs . Add ( "-O0" ) ;
2022-06-03 19:17:37 -04:00
// Ideally we would be able to turn on symbols and specify the dwarf version, but that does
// does not seem to be working currently, ie:
// GlobalArguments.Add("-g -O0 --dwarf-version=2");
}
else
{
2022-07-22 13:20:45 -04:00
CommonArgs . Add ( "-g -O0" ) ;
2022-06-03 19:17:37 -04:00
}
}
else
{
2022-08-23 12:44:36 -04:00
CommonArgs . Add ( "-O3" ) ;
2022-06-03 19:17:37 -04:00
}
2022-07-22 13:20:45 -04:00
GlobalArguments . AddRange ( CommonArgs ) ;
2022-06-03 19:17:37 -04:00
// PIC is needed for modular builds except on Microsoft platforms
if ( ( CompileEnvironment . bIsBuildingDLL | |
CompileEnvironment . bIsBuildingLibrary ) & &
! UEBuildPlatform . IsPlatformInGroup ( CompileEnvironment . Platform , UnrealPlatformGroup . Microsoft ) )
{
GlobalArguments . Add ( "--pic" ) ;
}
// Include paths. Don't use AddIncludePath() here, since it uses the full path and exceeds the max command line length.
foreach ( DirectoryReference IncludePath in CompileEnvironment . UserIncludePaths )
{
GlobalArguments . Add ( $"-I\" { NormalizeCommandLinePath ( IncludePath ) } \ "" ) ;
}
// System include paths.
foreach ( DirectoryReference SystemIncludePath in CompileEnvironment . SystemIncludePaths )
{
GlobalArguments . Add ( $"-I\" { NormalizeCommandLinePath ( SystemIncludePath ) } \ "" ) ;
}
// Preprocessor definitions.
foreach ( string Definition in CompileEnvironment . Definitions )
{
// TODO: Causes ISPC compiler to generate a spurious warning about the universal character set
if ( ! Definition . Contains ( "\\\\U" ) & & ! Definition . Contains ( "\\\\u" ) )
{
GlobalArguments . Add ( $"-D{EscapeDefinitionForISPC(Definition)}" ) ;
}
}
2024-04-17 12:53:34 -04:00
List < DirectoryItem > RootPaths = new ( GetEnvironmentBasePaths ( CompileEnvironment ) ) ;
2022-06-03 19:17:37 -04:00
foreach ( FileItem ISPCFile in InputFiles )
{
Action CompileAction = Graph . CreateAction ( ActionType . Compile ) ;
2024-04-17 12:53:34 -04:00
CompileAction . RootPaths . AddRange ( RootPaths ) ;
2023-04-24 20:05:37 -04:00
CompileAction . CommandDescription = $"Compile [{ISPCArch}]" ;
2022-06-03 19:17:37 -04:00
CompileAction . WorkingDirectory = Unreal . EngineSourceDirectory ;
CompileAction . CommandPath = new FileReference ( GetISPCHostCompilerPath ( BuildHostPlatform . Current . Platform ) ) ;
CompileAction . StatusDescription = Path . GetFileName ( ISPCFile . AbsolutePath ) ;
2024-05-23 17:13:00 -04:00
CompileAction . CommandVersion = GetISPCHostCompilerVersion ( BuildHostPlatform . Current . Platform ) . ToString ( ) ;
if ( bAllowUbaCompression )
{
CompileAction . CommandVersion = $"{CompileAction.CommandVersion} Compressed" ;
}
2022-06-03 19:17:37 -04:00
2023-04-25 19:24:51 -04:00
CompileAction . bCanExecuteRemotely = true ;
2022-06-03 19:17:37 -04:00
// Disable remote execution to workaround mismatched case on XGE
2023-04-25 19:24:51 -04:00
CompileAction . bCanExecuteRemotelyWithXGE = false ;
// TODO: Remove, might work
CompileAction . bCanExecuteRemotelyWithSNDBS = false ;
2022-06-03 19:17:37 -04:00
2024-04-24 17:58:07 -04:00
CompileAction . ArtifactMode = ArtifactMode . Enabled ;
2022-06-03 19:17:37 -04:00
List < string > Arguments = new List < string > ( ) ;
// Add the ISPC file to be compiled.
Arguments . Add ( $"\" { NormalizeCommandLinePath ( ISPCFile ) } \ "" ) ;
List < FileItem > CompiledISPCObjFiles = new List < FileItem > ( ) ;
2024-05-22 11:15:45 -04:00
string FileName = Path . GetFileName ( ISPCFile . AbsolutePath ) ;
2022-07-22 13:20:45 -04:00
string CompiledISPCObjFileSuffix = bByteCodeOutput ? ".bc" : GetISPCObjectFileSuffix ( CompileEnvironment . Platform ) ;
2022-06-03 19:17:37 -04:00
foreach ( string Target in CompileTargets )
{
string ObjTarget = Target ;
2023-05-31 13:37:21 -04:00
if ( Target . Contains ( '-' ) )
2022-06-03 19:17:37 -04:00
{
// Remove lane width and gang size from obj file name
ObjTarget = Target . Split ( '-' ) [ 0 ] ;
}
FileItem CompiledISPCObjFile ;
if ( CompileTargets . Count > 1 )
{
CompiledISPCObjFile = FileItem . GetItemByFileReference (
FileReference . Combine (
OutputDir ,
2024-05-22 11:15:45 -04:00
FileName + "_" + ObjTarget + CompiledISPCObjFileSuffix
2022-06-03 19:17:37 -04:00
)
) ;
}
else
{
CompiledISPCObjFile = FileItem . GetItemByFileReference (
FileReference . Combine (
OutputDir ,
2024-05-22 11:15:45 -04:00
FileName + CompiledISPCObjFileSuffix
2022-06-03 19:17:37 -04:00
)
) ;
}
// Add the ISA specific ISPC obj files to the produced item list.
CompiledISPCObjFiles . Add ( CompiledISPCObjFile ) ;
}
2022-07-22 13:20:45 -04:00
// Add the common ISPC obj file to the produced item list if it's not already in it
2022-06-03 19:17:37 -04:00
FileItem CompiledISPCObjFileNoISA = FileItem . GetItemByFileReference (
FileReference . Combine (
OutputDir ,
2024-05-22 11:15:45 -04:00
FileName + CompiledISPCObjFileSuffix
2022-06-03 19:17:37 -04:00
)
) ;
2022-07-22 13:20:45 -04:00
if ( CompileTargets . Count > 1 )
{
CompiledISPCObjFiles . Add ( CompiledISPCObjFileNoISA ) ;
}
2022-06-03 19:17:37 -04:00
// Add the output ISPC obj file
Arguments . Add ( $"-o \" { NormalizeCommandLinePath ( CompiledISPCObjFileNoISA ) } \ "" ) ;
// Generate the timing info
if ( CompileEnvironment . bPrintTimingInfo )
{
FileItem TraceFile = FileItem . GetItemByFileReference ( FileReference . FromString ( $"{CompiledISPCObjFileNoISA}.json" ) ) ;
Arguments . Add ( "--time-trace" ) ;
CompileAction . ProducedItems . Add ( TraceFile ) ;
}
Arguments . AddRange ( GlobalArguments ) ;
// Consume the included header dependency list
2024-05-22 11:15:45 -04:00
FileItem DependencyListFile = FileItem . GetItemByFileReference ( FileReference . Combine ( OutputDir , FileName + ".txt" ) ) ;
2022-11-02 11:47:47 -04:00
CompileAction . DependencyListFile = DependencyListFile ;
CompileAction . PrerequisiteItems . Add ( DependencyListFile ) ;
2022-06-03 19:17:37 -04:00
2023-01-17 16:35:14 -05:00
CompileAction . ProducedItems . UnionWith ( CompiledISPCObjFiles ) ;
2022-06-03 19:17:37 -04:00
2023-01-27 15:19:25 -05:00
FileReference ResponseFileName = GetResponseFileName ( CompileEnvironment , CompiledISPCObjFileNoISA ) ;
2022-06-03 19:17:37 -04:00
FileItem ResponseFileItem = Graph . CreateIntermediateTextFile ( ResponseFileName , Arguments . Select ( x = > Utils . ExpandVariables ( x ) ) ) ;
2024-05-22 11:15:45 -04:00
string AdditionalArguments = "" ;
// Must be added after response file is created just to make sure it ends up on the command line and not in the response file
if ( bMergeModules )
{
// EXTRACTEXPORTS can only be interpreted by UBA.. so this action won't build outside uba
AdditionalArguments = " /EXTRACTEXPORTS" ;
FileItem SymFile = FileItem . GetItemByFileReference ( FileReference . Combine ( OutputDir , FileName + ".exi" ) ) ;
CompileAction . ProducedItems . Add ( SymFile ) ;
}
CompileAction . CommandArguments = $"@\" { ResponseFileName } \ "{AdditionalArguments}" ;
2022-06-03 19:17:37 -04:00
CompileAction . PrerequisiteItems . Add ( ResponseFileItem ) ;
// Add the source file and its included files to the prerequisite item list.
CompileAction . PrerequisiteItems . Add ( ISPCFile ) ;
Logger . LogDebug ( " ISPC Compiling {StatusDescription}: \"{CommandPath}\" {CommandArguments}" , CompileAction . StatusDescription , CompileAction . CommandPath , CompileAction . CommandArguments ) ;
2022-07-22 13:20:45 -04:00
if ( bByteCodeOutput )
{
// If the platform toolchain supports bytecode compilation for ISPC, compile the bytecode object files to actual native object files
string? ByteCodeCompilerPath = GetISPCHostBytecodeCompilerPath ( BuildHostPlatform . Current . Platform ) ;
if ( ByteCodeCompilerPath ! = null )
{
List < FileItem > FinalObjectFiles = new List < FileItem > ( ) ;
foreach ( FileItem CompiledBytecodeObjFile in CompiledISPCObjFiles )
{
FileItem FinalCompiledISPCObjFile = FileItem . GetItemByFileReference (
FileReference . Combine (
OutputDir ,
Path . GetFileNameWithoutExtension ( CompiledBytecodeObjFile . AbsolutePath ) + GetISPCObjectFileSuffix ( CompileEnvironment . Platform )
)
) ;
Action PostCompileAction = Graph . CreateAction ( ActionType . Compile ) ;
List < string > PostCompileArgs = new List < string > ( ) ;
PostCompileArgs . Add ( $"\" { NormalizeCommandLinePath ( CompiledBytecodeObjFile ) } \ "" ) ;
PostCompileArgs . Add ( "-c" ) ;
PostCompileArgs . AddRange ( CommonArgs ) ;
PostCompileArgs . Add ( $"-o \" { NormalizeCommandLinePath ( FinalCompiledISPCObjFile ) } \ "" ) ;
// Write the args to a response file
2023-01-27 15:19:25 -05:00
FileReference PostCompileResponseFileName = GetResponseFileName ( CompileEnvironment , FinalCompiledISPCObjFile ) ;
2022-07-22 13:20:45 -04:00
FileItem PostCompileResponseFileItem = Graph . CreateIntermediateTextFile ( PostCompileResponseFileName , PostCompileArgs . Select ( x = > Utils . ExpandVariables ( x ) ) ) ;
PostCompileAction . CommandArguments = $"@\" { PostCompileResponseFileName } \ "" ;
PostCompileAction . PrerequisiteItems . Add ( PostCompileResponseFileItem ) ;
PostCompileAction . PrerequisiteItems . Add ( CompiledBytecodeObjFile ) ;
PostCompileAction . ProducedItems . Add ( FinalCompiledISPCObjFile ) ;
2023-04-24 20:05:37 -04:00
PostCompileAction . CommandDescription = $"CompileByteCode [{ISPCArch}]" ;
2022-07-22 13:20:45 -04:00
PostCompileAction . WorkingDirectory = Unreal . EngineSourceDirectory ;
PostCompileAction . CommandPath = new FileReference ( ByteCodeCompilerPath ) ;
PostCompileAction . StatusDescription = Path . GetFileName ( ISPCFile . AbsolutePath ) ;
2024-05-23 17:13:00 -04:00
CompileAction . CommandVersion = GetISPCHostCompilerVersion ( BuildHostPlatform . Current . Platform ) . ToString ( ) ;
if ( bAllowUbaCompression )
{
CompileAction . CommandVersion = $"{CompileAction.CommandVersion} Compressed" ;
}
2022-07-22 13:20:45 -04:00
2024-05-22 19:25:15 -04:00
PostCompileAction . RootPaths . AddRange ( RootPaths ) ;
PostCompileAction . ArtifactMode = ArtifactMode . Enabled ;
2022-07-22 13:20:45 -04:00
// Disable remote execution to workaround mismatched case on XGE
2024-05-22 19:25:15 -04:00
PostCompileAction . bCanExecuteRemotelyWithXGE = false ;
2022-07-22 13:20:45 -04:00
FinalObjectFiles . Add ( FinalCompiledISPCObjFile ) ;
Logger . LogDebug ( " ISPC Compiling bytecode {StatusDescription}: \"{CommandPath}\" {CommandArguments} {ProducedItems}" , PostCompileAction . StatusDescription , PostCompileAction . CommandPath , PostCompileAction . CommandArguments , PostCompileAction . ProducedItems ) ;
}
// Override the output object files
CompiledISPCObjFiles = FinalObjectFiles ;
}
}
Result . ObjectFiles . AddRange ( CompiledISPCObjFiles ) ;
2022-06-03 19:17:37 -04:00
}
return Result ;
}
}
}