2022-06-01 06:59:18 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.IO ;
using EpicGames.Core ;
using Microsoft.Extensions.Logging ;
2023-01-10 16:44:45 -05:00
using UnrealBuildBase ;
2022-06-01 06:59:18 -04:00
namespace UnrealBuildTool
{
/// <summary>
/// Android-specific target settings
/// </summary>
public partial class AndroidTargetRules
{
/// <summary>
/// Enables address sanitizer (ASan)
/// </summary>
[CommandLine("-EnableASan")]
public bool bEnableAddressSanitizer = false ;
/// <summary>
/// Enables HW address sanitizer (HWASan)
/// </summary>
[CommandLine("-EnableHWASan")]
public bool bEnableHWAddressSanitizer = false ;
/// <summary>
/// Enables thread sanitizer (TSan)
/// </summary>
//[CommandLine("-EnableTSan")]
public bool bEnableThreadSanitizer = false ;
/// <summary>
/// Enables undefined behavior sanitizer (UBSan)
/// </summary>
[CommandLine("-EnableUBSan")]
public bool bEnableUndefinedBehaviorSanitizer = false ;
/// <summary>
/// Enables minimal undefined behavior sanitizer (UBSan)
/// </summary>
[CommandLine("-EnableMinUBSan")]
public bool bEnableMinimalUndefinedBehaviorSanitizer = false ;
2023-04-14 10:52:39 -04:00
/// <summary>
/// Enables runtime ray tracing support.
/// </summary>
2024-06-25 11:27:22 -04:00
[ConfigFile(ConfigHierarchyType.Engine, "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings")]
2023-04-14 10:52:39 -04:00
public bool bEnableRayTracing = false ;
2024-04-09 19:40:32 -04:00
2024-06-25 11:27:22 -04:00
/// <summary>
/// Enables the desktop renderer.
/// </summary>
[ConfigFile(ConfigHierarchyType.Engine, "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings")]
public bool bSupportsVulkanSM5 = false ;
2024-04-09 19:40:32 -04:00
/// <summary>
/// Enables ASIS plugin and STANDALONE support.
/// </summary>
[ConfigFile(ConfigHierarchyType.Engine, "/Script/AndroidSingleInstanceServiceEditor.AndroidSingleInstanceServiceRuntimeSettings")]
public bool bEnableASISPlugin = false ;
2022-06-01 06:59:18 -04:00
}
/// <summary>
/// Read-only wrapper for Android-specific target settings
/// </summary>
public partial class ReadOnlyAndroidTargetRules
{
/// <summary>
/// The private mutable settings object
/// </summary>
private AndroidTargetRules Inner ;
/// <summary>
/// Constructor
/// </summary>
/// <param name="Inner">The settings object to wrap</param>
public ReadOnlyAndroidTargetRules ( AndroidTargetRules Inner )
{
this . Inner = Inner ;
}
/// <summary>
/// Accessors for fields on the inner TargetRules instance
/// </summary>
#region Read - only accessor properties
2023-05-30 18:38:07 -04:00
#pragma warning disable CS1591
2022-06-01 06:59:18 -04:00
2023-05-30 18:01:50 -04:00
public bool bEnableAddressSanitizer = > Inner . bEnableAddressSanitizer ;
2022-06-01 06:59:18 -04:00
2023-05-30 18:01:50 -04:00
public bool bEnableHWAddressSanitizer = > Inner . bEnableHWAddressSanitizer ;
2022-06-01 06:59:18 -04:00
2023-05-30 18:01:50 -04:00
public bool bEnableThreadSanitizer = > Inner . bEnableThreadSanitizer ;
2022-06-01 06:59:18 -04:00
2023-05-30 18:01:50 -04:00
public bool bEnableUndefinedBehaviorSanitizer = > Inner . bEnableUndefinedBehaviorSanitizer ;
2022-06-01 06:59:18 -04:00
2023-05-30 18:01:50 -04:00
public bool bEnableMinimalUndefinedBehaviorSanitizer = > Inner . bEnableMinimalUndefinedBehaviorSanitizer ;
2022-06-01 06:59:18 -04:00
2023-05-30 18:01:50 -04:00
public bool bEnableRayTracing = > Inner . bEnableRayTracing ;
2023-04-14 10:52:39 -04:00
2024-06-25 11:27:22 -04:00
public bool bSupportsVulkanSM5 = > Inner . bSupportsVulkanSM5 ;
2024-04-09 19:40:32 -04:00
public bool bEnableASISPlugin = > Inner . bEnableASISPlugin ;
2023-05-30 18:01:50 -04:00
public AndroidTargetRules TargetRules = > Inner ;
2022-06-01 06:59:18 -04:00
2023-05-30 18:38:07 -04:00
#pragma warning restore CS1591
2022-06-01 06:59:18 -04:00
#endregion
}
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
class AndroidArchitectureConfig : UnrealArchitectureConfig
{
public AndroidArchitectureConfig ( )
2024-02-23 12:34:07 -05:00
: base ( UnrealArchitectureMode . SingleTargetLinkSeparately , new [ ] { UnrealArch . Arm64 , UnrealArch . X64 } )
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 override UnrealArchitectures ActiveArchitectures ( FileReference ? ProjectFile , string? TargetName ) = > GetProjectArchitectures ( ProjectFile , false ) ;
public override string GetFolderNameForArchitecture ( UnrealArch Architecture )
{
return Architecture = = UnrealArch . Arm64 ? "a" : "x" ;
}
private static UnrealArchitectures ? CachedActiveArchitectures = null ;
private static FileReference ? CachedActiveArchesProject = null ;
private UnrealArchitectures GetProjectArchitectures ( FileReference ? ProjectFile , bool bGetAllSupported )
{
if ( CachedActiveArchitectures = = null | | ProjectFile ! = CachedActiveArchesProject )
{
List < string > ActiveArches = new ( ) ;
CachedActiveArchesProject = ProjectFile ;
// look in ini settings for what platforms to compile for
ConfigHierarchy Ini = ConfigCache . ReadHierarchy ( ConfigHierarchyType . Engine , DirectoryReference . FromFile ( ProjectFile ) , UnrealTargetPlatform . Android ) ;
bool bBuild ;
bool bUnsupportedBinaryBuildArch = false ;
if ( Ini . GetBool ( "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings" , "bBuildForArm64" , out bBuild ) & & bBuild )
{
ActiveArches . Add ( "arm64" ) ;
}
if ( Ini . GetBool ( "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings" , "bBuildForx8664" , out bBuild ) & & bBuild )
{
2024-02-23 12:34:07 -05:00
ActiveArches . Add ( "x64" ) ;
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
}
// we expect one to be specified
if ( ActiveArches . Count = = 0 )
{
if ( bUnsupportedBinaryBuildArch )
{
throw new BuildException ( "Only architectures unsupported by binary-only engine selected." ) ;
}
else
{
throw new BuildException ( "At least one architecture must be specified in Android project settings." ) ;
}
}
CachedActiveArchitectures = new UnrealArchitectures ( ActiveArches ) ;
}
return CachedActiveArchitectures ;
}
}
2022-06-01 06:59:18 -04:00
class AndroidPlatform : UEBuildPlatform
{
UEBuildPlatformSDK SDK ;
2023-05-30 18:38:07 -04:00
public AndroidPlatform ( UnrealTargetPlatform InTargetPlatform , UEBuildPlatformSDK InSDK , ILogger InLogger )
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
: base ( InTargetPlatform , InSDK , new AndroidArchitectureConfig ( ) , InLogger )
2022-06-01 06:59:18 -04:00
{
SDK = InSDK ;
}
public AndroidPlatform ( AndroidPlatformSDK InSDK , ILogger InLogger ) : this ( UnrealTargetPlatform . Android , InSDK , InLogger )
{
}
public override void ResetTarget ( TargetRules Target )
{
ValidateTarget ( Target ) ;
Target . bDeployAfterCompile = true ;
}
public override void ValidateTarget ( TargetRules Target )
{
2023-05-30 18:59:32 -04:00
if ( ! String . IsNullOrWhiteSpace ( Environment . GetEnvironmentVariable ( "CLANG_STATIC_ANALYZER_MODE" ) ) )
2022-07-15 11:25:34 -04:00
{
Target . StaticAnalyzer = StaticAnalyzer . Default ;
Target . StaticAnalyzerOutputType = ( Environment . GetEnvironmentVariable ( "CLANG_ANALYZER_OUTPUT" ) ? . Contains ( "html" , StringComparison . OrdinalIgnoreCase ) = = true ) ? StaticAnalyzerOutputType . Html : StaticAnalyzerOutputType . Text ;
2023-08-23 20:33:44 -04:00
Target . StaticAnalyzerMode = String . Equals ( Environment . GetEnvironmentVariable ( "CLANG_STATIC_ANALYZER_MODE" ) , "shallow" , StringComparison . OrdinalIgnoreCase ) ? StaticAnalyzerMode . Shallow : StaticAnalyzerMode . Deep ;
2022-07-15 11:25:34 -04:00
}
else if ( Target . StaticAnalyzer = = StaticAnalyzer . Clang )
{
Target . StaticAnalyzer = StaticAnalyzer . Default ;
}
2022-07-21 12:07:06 -04:00
// Disable linking and ignore build outputs if we're using a static analyzer
2022-07-15 11:25:34 -04:00
if ( Target . StaticAnalyzer = = StaticAnalyzer . Default )
{
Target . bDisableLinking = true ;
2022-07-21 12:07:06 -04:00
Target . bIgnoreBuildOutputs = true ;
2023-08-23 20:33:44 -04:00
// Clang static analysis requires non unity builds
Target . bUseUnityBuild = false ;
2022-07-15 11:25:34 -04:00
}
2022-06-01 06:59:18 -04:00
Target . bCompileRecast = true ;
2024-09-10 10:26:02 -04:00
Target . bCompileISPC = true ;
2023-01-10 16:44:45 -05: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
// disable plugins by architecture (if we are compiling for multiple architectures, we still need to disable the plugin for all architectures)
if ( Target . Architectures . Contains ( UnrealArch . Arm64 ) & & Target . Name ! = "UnrealHeaderTool" )
2023-01-10 16:44:45 -05:00
{
2024-07-23 19:39:24 -04:00
Target . DisablePlugins . AddRange ( Array . Empty < string > ( ) ) ;
2023-01-10 16:44:45 -05:00
}
2022-06-01 06:59:18 -04:00
}
public override bool CanUseXGE ( )
{
// Disable when building on Linux
return BuildHostPlatform . Current . Platform ! = UnrealTargetPlatform . Linux ;
}
public override bool IsBuildProduct ( string FileName , string [ ] NamePrefixes , string [ ] NameSuffixes )
{
return IsBuildProductWithArch ( FileName , NamePrefixes , NameSuffixes , ".so" )
| | IsBuildProductWithArch ( FileName , NamePrefixes , NameSuffixes , ".apk" )
| | IsBuildProductWithArch ( FileName , NamePrefixes , NameSuffixes , ".a" ) ;
}
static bool IsBuildProductWithArch ( string Name , string [ ] NamePrefixes , string [ ] NameSuffixes , string Extension )
{
// Strip off the extension, then a CPU suffix, before testing whether it matches a build product name.
if ( Name . EndsWith ( Extension , StringComparison . InvariantCultureIgnoreCase ) )
{
int ExtensionEndIdx = Name . Length - Extension . Length ;
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
foreach ( string CpuSuffix in AndroidToolChain . AllCpuSuffixes . Values )
2022-06-01 06:59:18 -04:00
{
int CpuIdx = ExtensionEndIdx - CpuSuffix . Length ;
if ( CpuIdx > 0 & & String . Compare ( Name , CpuIdx , CpuSuffix , 0 , CpuSuffix . Length , StringComparison . InvariantCultureIgnoreCase ) = = 0 )
{
return IsBuildProductName ( Name , 0 , CpuIdx , NamePrefixes , NameSuffixes ) ;
}
}
}
return false ;
}
public override string GetBinaryExtension ( UEBuildBinaryType InBinaryType )
{
switch ( InBinaryType )
{
case UEBuildBinaryType . DynamicLinkLibrary :
return ".so" ;
case UEBuildBinaryType . Executable :
return ".so" ;
case UEBuildBinaryType . StaticLibrary :
return ".a" ;
}
return base . GetBinaryExtension ( InBinaryType ) ;
}
public override string [ ] GetDebugInfoExtensions ( ReadOnlyTargetRules InTarget , UEBuildBinaryType InBinaryType )
{
2024-07-23 19:39:24 -04:00
return Array . Empty < string > ( ) ;
2022-06-01 06:59:18 -04:00
}
public override void FindAdditionalBuildProductsToClean ( ReadOnlyTargetRules Target , List < FileReference > FilesToDelete , List < DirectoryReference > DirectoriesToDelete )
{
base . FindAdditionalBuildProductsToClean ( Target , FilesToDelete , DirectoriesToDelete ) ;
2023-05-30 18:38:07 -04:00
if ( Target . ProjectFile ! = null )
2022-06-01 06:59:18 -04:00
{
DirectoriesToDelete . Add ( DirectoryReference . Combine ( DirectoryReference . FromFile ( Target . ProjectFile ) , "Intermediate" , "Android" ) ) ;
}
}
public virtual bool HasSpecificDefaultBuildConfig ( UnrealTargetPlatform Platform , DirectoryReference ProjectPath , ILogger Logger )
{
string [ ] BoolKeys = new string [ ] {
2023-05-30 18:38:07 -04:00
"bBuildForArm64" , "bBuildForX8664" ,
2022-06-01 06:59:18 -04:00
"bBuildForES31" , "bBuildWithHiddenSymbolVisibility" , "bSaveSymbols"
} ;
string [ ] StringKeys = new string [ ] {
"NDKAPILevelOverride"
} ;
// look up Android specific settings
if ( ! DoProjectSettingsMatchDefault ( Platform , ProjectPath , "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings" ,
BoolKeys , null , StringKeys , Logger ) )
{
return false ;
}
return true ;
}
public override bool HasDefaultBuildConfig ( UnrealTargetPlatform Platform , DirectoryReference ProjectPath )
{
// @todo Lumin: This is kinda messy - better way?
if ( HasSpecificDefaultBuildConfig ( Platform , ProjectPath , Logger ) = = false )
{
return false ;
}
2023-05-30 18:38:07 -04:00
2022-06-01 06:59:18 -04:00
// any shared-between-all-androids would be here
// check the base settings
return base . HasDefaultBuildConfig ( Platform , ProjectPath ) ;
}
public override bool ShouldCompileMonolithicBinary ( UnrealTargetPlatform InPlatform )
{
// This platform currently always compiles monolithic
return true ;
}
/// <summary>
/// Modify the rules for a newly created module, where the target is a different host platform.
/// This is not required - but allows for hiding details of a particular platform.
/// </summary>
/// <param name="ModuleName">The name of the module</param>
/// <param name="Rules">The module rules</param>
/// <param name="Target">The target being build</param>
public override void ModifyModuleRulesForOtherPlatform ( string ModuleName , ModuleRules Rules , ReadOnlyTargetRules Target )
{
// don't do any target platform stuff if not available for host and opted in
// do not require SDK to build it since we don't necessarily need it for editor building
2023-09-26 09:13:27 -04:00
if ( ! UEBuildPlatform . IsPlatformAvailableForTarget ( Platform , Target , bIgnoreSDKCheck : true ) )
2022-06-01 06:59:18 -04:00
{
return ;
}
if ( ( Target . Platform = = UnrealTargetPlatform . Win64 ) | | ( Target . Platform = = UnrealTargetPlatform . Mac ) | | ( Target . Platform = = UnrealTargetPlatform . Linux ) )
{
bool bBuildShaderFormats = Target . bForceBuildShaderFormats ;
if ( ! Target . bBuildRequiresCookedData )
{
if ( ModuleName = = "Engine" )
{
if ( Target . bBuildDeveloperTools )
{
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidTargetPlatform" ) ;
2024-01-29 04:50:19 -05:00
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidTargetPlatformSettings" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidTargetPlatformControls" ) ;
2022-06-01 06:59:18 -04:00
}
}
else if ( ModuleName = = "TargetPlatform" )
{
bBuildShaderFormats = true ;
Rules . DynamicallyLoadedModuleNames . Add ( "TextureFormatDXT" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "TextureFormatASTC" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "TextureFormatETC2" ) ; // ETC2
if ( Target . bBuildDeveloperTools )
{
//Rules.DynamicallyLoadedModuleNames.Add("AudioFormatADPCM"); //@todo android: android audio
}
}
}
// allow standalone tools to use targetplatform modules, without needing Engine
if ( ModuleName = = "TargetPlatform" )
{
if ( Target . bForceBuildTargetPlatforms )
{
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidTargetPlatform" ) ;
2024-01-29 04:50:19 -05:00
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidTargetPlatformSettings" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidTargetPlatformControls" ) ;
2022-06-01 06:59:18 -04:00
}
if ( bBuildShaderFormats )
{
//Rules.DynamicallyLoadedModuleNames.Add("ShaderFormatAndroid"); //@todo android: ShaderFormatAndroid
}
}
if ( ModuleName = = "UnrealEd" )
{
Rules . DynamicallyLoadedModuleNames . Add ( "AndroidPlatformEditor" ) ;
}
}
}
public override List < FileReference > FinalizeBinaryPaths ( FileReference BinaryName , FileReference ? ProjectFile , ReadOnlyTargetRules Target )
{
// make multiple output binaries
List < FileReference > AllBinaries = new List < FileReference > ( ) ;
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
foreach ( UnrealArch Architecture in Target . Architectures . Architectures )
2022-06-01 06:59:18 -04:00
{
string BinaryPath ;
if ( Target . bShouldCompileAsDLL )
{
BinaryPath = Path . Combine ( BinaryName . Directory . FullName , Target . Configuration . ToString ( ) , "libUnreal.so" ) ;
}
else
{
BinaryPath = AndroidToolChain . InlineArchName ( BinaryName . FullName , Architecture ) ;
}
AllBinaries . Add ( new FileReference ( BinaryPath ) ) ;
}
return AllBinaries ;
}
public override void AddExtraModules ( ReadOnlyTargetRules Target , List < string > PlatformExtraModules )
{
if ( Target . Type ! = TargetType . Program )
{
PlatformExtraModules . Add ( "VulkanRHI" ) ;
}
}
/// <summary>
/// Modify the rules for a newly created module, in a target that's being built for this platform.
/// This is not required - but allows for hiding details of a particular platform.
/// </summary>
/// <param name="ModuleName">The name of the module</param>
/// <param name="Rules">The module rules</param>
/// <param name="Target">The target being build</param>
public override void ModifyModuleRulesForActivePlatform ( string ModuleName , ModuleRules Rules , ReadOnlyTargetRules Target )
{
}
2024-04-09 19:40:32 -04:00
public static bool IsMakeAAREnabled ( ReadOnlyTargetRules Target )
2023-12-11 13:59:52 -05:00
{
2024-04-09 19:40:32 -04:00
return Target . AndroidPlatform . bEnableASISPlugin ;
2023-12-11 13:59:52 -05:00
}
2022-06-01 06:59:18 -04:00
public virtual void SetUpSpecificEnvironment ( ReadOnlyTargetRules Target , CppCompileEnvironment CompileEnvironment , LinkEnvironment LinkEnvironment , ILogger Logger )
{
string NDKPath = Environment . GetEnvironmentVariable ( "NDKROOT" ) ! ;
NDKPath = NDKPath . Replace ( "\"" , "" ) ;
2023-01-10 16:44:45 -05:00
AndroidToolChain ToolChain = new AndroidToolChain ( Target . ProjectFile , Logger ) ;
2022-06-01 06:59:18 -04:00
// figure out the NDK version
string? NDKToolchainVersion = SDK . GetInstalledVersion ( ) ;
2024-04-02 20:29:22 -04:00
ulong NDKVersionInt ;
2022-06-01 06:59:18 -04:00
SDK . TryConvertVersionToInt ( NDKToolchainVersion , out NDKVersionInt ) ;
// PLATFORM_ANDROID_NDK_VERSION is in the form 150100, where 15 is major version, 01 is the letter (1 is 'a'), 00 indicates beta revision if letter is 00
2023-05-30 18:59:32 -04:00
CompileEnvironment . Definitions . Add ( String . Format ( "PLATFORM_ANDROID_NDK_VERSION={0}" , NDKVersionInt ) ) ;
2022-06-01 06:59:18 -04:00
Logger . LogInformation ( "NDK toolchain: {Version}, NDK version: {NdkVersion}, ClangVersion: {ClangVersion}" , NDKToolchainVersion , NDKVersionInt , ToolChain . GetClangVersionString ( ) ) ;
CompileEnvironment . Definitions . Add ( "PLATFORM_DESKTOP=0" ) ;
CompileEnvironment . Definitions . Add ( "PLATFORM_CAN_SUPPORT_EDITORONLY_DATA=0" ) ;
CompileEnvironment . Definitions . Add ( "WITH_OGGVORBIS=1" ) ;
CompileEnvironment . Definitions . Add ( "UNICODE" ) ;
CompileEnvironment . Definitions . Add ( "_UNICODE" ) ;
CompileEnvironment . Definitions . Add ( "PLATFORM_ANDROID=1" ) ;
CompileEnvironment . Definitions . Add ( "ANDROID=1" ) ;
CompileEnvironment . Definitions . Add ( "WITH_EDITOR=0" ) ;
CompileEnvironment . Definitions . Add ( "USE_NULL_RHI=0" ) ;
2024-04-09 19:40:32 -04:00
2022-06-01 06:59:18 -04:00
DirectoryReference NdkDir = new DirectoryReference ( NDKPath ) ;
//CompileEnvironment.SystemIncludePaths.Add(DirectoryReference.Combine(NdkDir, "sources/cxx-stl/llvm-libc++/include"));
// the toolchain will actually filter these out
LinkEnvironment . SystemLibraryPaths . Add ( DirectoryReference . Combine ( NdkDir , "sources/cxx-stl/llvm-libc++/libs/arm64-v8a" ) ) ;
LinkEnvironment . SystemLibraryPaths . Add ( DirectoryReference . Combine ( NdkDir , "sources/cxx-stl/llvm-libc++/libs/x86_64" ) ) ;
CompileEnvironment . SystemIncludePaths . Add ( DirectoryReference . Combine ( NdkDir , "sources/android/native_app_glue" ) ) ;
CompileEnvironment . SystemIncludePaths . Add ( DirectoryReference . Combine ( NdkDir , "sources/android/cpufeatures" ) ) ;
//@TODO: Tegra Gfx Debugger - standardize locations - for now, change the hardcoded paths and force this to return true to test
if ( UseTegraGraphicsDebugger ( Target ) )
{
//LinkEnvironment.LibraryPaths.Add("ThirdParty/NVIDIA/TegraGfxDebugger");
//LinkEnvironment.LibraryPaths.Add("F:/NVPACK/android-kk-egl-t124-a32/stub");
//LinkEnvironment.AdditionalLibraries.Add("Nvidia_gfx_debugger_stub");
}
if ( ! UseTegraGraphicsDebugger ( Target ) )
{
LinkEnvironment . SystemLibraries . Add ( "GLESv3" ) ;
LinkEnvironment . SystemLibraries . Add ( "EGL" ) ;
}
LinkEnvironment . SystemLibraries . Add ( "android" ) ;
LinkEnvironment . SystemLibraries . Add ( "OpenSLES" ) ;
}
public override void SetUpEnvironment ( ReadOnlyTargetRules Target , CppCompileEnvironment CompileEnvironment , LinkEnvironment LinkEnvironment )
{
CompileEnvironment . Definitions . Add ( "PLATFORM_DESKTOP=0" ) ;
CompileEnvironment . Definitions . Add ( "PLATFORM_CAN_SUPPORT_EDITORONLY_DATA=0" ) ;
CompileEnvironment . Definitions . Add ( "WITH_OGGVORBIS=1" ) ;
CompileEnvironment . Definitions . Add ( "UNICODE" ) ;
CompileEnvironment . Definitions . Add ( "_UNICODE" ) ;
CompileEnvironment . Definitions . Add ( "PLATFORM_ANDROID=1" ) ;
CompileEnvironment . Definitions . Add ( "ANDROID=1" ) ;
CompileEnvironment . Definitions . Add ( "WITH_EDITOR=0" ) ;
CompileEnvironment . Definitions . Add ( "USE_NULL_RHI=0" ) ;
2024-06-25 11:27:22 -04:00
if ( Target . AndroidPlatform . bEnableRayTracing & & Target . AndroidPlatform . bSupportsVulkanSM5 )
2023-04-14 10:52:39 -04:00
{
Logger . LogInformation ( "Compiling with ray tracing enabled" ) ;
CompileEnvironment . Definitions . Add ( "RHI_RAYTRACING=1" ) ;
}
2024-04-09 19:40:32 -04:00
if ( Target . AndroidPlatform . bEnableASISPlugin )
{
Logger . LogInformation ( "Compiling with USE_ANDROID_STANDALONE" ) ;
CompileEnvironment . Definitions . Add ( "USE_ANDROID_STANDALONE=1" ) ;
}
2023-10-10 18:40:01 -04:00
if ( Target . bPGOOptimize | | Target . bPGOProfile )
2022-06-01 06:59:18 -04:00
{
Logger . LogInformation ( "PGO {PgoType} build" , Target . bPGOOptimize ? "optimize" : "profile" ) ;
2022-09-22 17:40:58 -04:00
if ( Target . bPGOOptimize )
2022-06-01 06:59:18 -04:00
{
2023-10-10 18:40:01 -04:00
CompileEnvironment . PGODirectory = DirectoryReference . Combine ( Target . ProjectFile ? . Directory ? ? Unreal . WritableEngineDirectory , "Platforms" , "Android" , "Build" , "PGO" ) . FullName ;
2023-05-30 18:59:32 -04:00
CompileEnvironment . PGOFilenamePrefix = String . Format ( "{0}-Android" , Target . Name ) ;
2022-06-01 06:59:18 -04:00
LinkEnvironment . PGODirectory = CompileEnvironment . PGODirectory ;
LinkEnvironment . PGOFilenamePrefix = CompileEnvironment . PGOFilenamePrefix ;
Logger . LogInformation ( "PGO Dir: {PgoDir}" , CompileEnvironment . PGODirectory ) ;
Logger . LogInformation ( "PGO Prefix: {PgoPrefix}" , CompileEnvironment . PGOFilenamePrefix ) ;
}
}
CompileEnvironment . Definitions . Add ( "INT64_T_TYPES_NOT_LONG_LONG=1" ) ;
SetUpSpecificEnvironment ( Target , CompileEnvironment , LinkEnvironment , Logger ) ;
// deliberately not linking stl or stdc++ here (c++_shared is default)
LinkEnvironment . SystemLibraries . Add ( "c" ) ;
LinkEnvironment . SystemLibraries . Add ( "dl" ) ;
LinkEnvironment . SystemLibraries . Add ( "log" ) ;
LinkEnvironment . SystemLibraries . Add ( "m" ) ;
LinkEnvironment . SystemLibraries . Add ( "z" ) ;
LinkEnvironment . SystemLibraries . Add ( "atomic" ) ;
}
private bool UseTegraGraphicsDebugger ( ReadOnlyTargetRules Target )
{
// Disable for now
return false ;
}
public override bool ShouldCreateDebugInfo ( ReadOnlyTargetRules Target )
{
switch ( Target . Configuration )
{
case UnrealTargetConfiguration . Development :
case UnrealTargetConfiguration . Shipping :
case UnrealTargetConfiguration . Test :
case UnrealTargetConfiguration . Debug :
default :
return true ;
2024-04-03 17:18:04 -04:00
}
2022-06-01 06:59:18 -04:00
}
2023-05-30 18:59:32 -04:00
public static ClangToolChainOptions CreateToolChainOptions ( AndroidTargetRules TargetRules )
2022-06-01 06:59:18 -04:00
{
ClangToolChainOptions Options = ClangToolChainOptions . None ;
if ( TargetRules . bEnableAddressSanitizer )
{
Options | = ClangToolChainOptions . EnableAddressSanitizer ;
}
else if ( TargetRules . bEnableHWAddressSanitizer )
{
Options | = ClangToolChainOptions . EnableHWAddressSanitizer ;
}
if ( TargetRules . bEnableThreadSanitizer )
{
Options | = ClangToolChainOptions . EnableThreadSanitizer ;
}
if ( TargetRules . bEnableUndefinedBehaviorSanitizer )
{
Options | = ClangToolChainOptions . EnableUndefinedBehaviorSanitizer ;
}
else if ( TargetRules . bEnableMinimalUndefinedBehaviorSanitizer )
{
Options | = ClangToolChainOptions . EnableMinimalUndefinedBehaviorSanitizer ;
}
return Options ;
}
public override UEToolChain CreateToolChain ( ReadOnlyTargetRules Target )
{
ClangToolChainOptions Options = CreateToolChainOptions ( Target . AndroidPlatform . TargetRules ) ;
2022-09-22 17:40:58 -04:00
if ( Target . bAllowLTCG & & Target . bPreferThinLTO )
{
Options | = ClangToolChainOptions . EnableThinLTO ;
}
2023-01-10 16:44:45 -05:00
return new AndroidToolChain ( Target . ProjectFile , Options , Logger ) ;
2022-06-01 06:59:18 -04:00
}
public virtual UEToolChain CreateTempToolChainForProject ( FileReference ? ProjectFile )
{
AndroidTargetRules TargetRules = new AndroidTargetRules ( ) ;
CommandLine . ParseArguments ( Environment . GetCommandLineArgs ( ) , TargetRules , Logger ) ;
ClangToolChainOptions Options = CreateToolChainOptions ( TargetRules ) ;
2023-01-10 16:44:45 -05:00
return new AndroidToolChain ( ProjectFile , Options , Logger ) ;
2022-06-01 06:59:18 -04:00
}
/// <inheritdoc/>
public override void Deploy ( TargetReceipt Receipt )
{
// do not package data if building via UBT
new UEDeployAndroid ( Receipt . ProjectFile , false , Logger ) . PrepTargetForDeployment ( Receipt ) ;
}
}
class AndroidPlatformFactory : UEBuildPlatformFactory
{
2023-05-30 18:01:50 -04:00
public override UnrealTargetPlatform TargetPlatform = > UnrealTargetPlatform . Android ;
2022-06-01 06:59:18 -04:00
public override void RegisterBuildPlatforms ( ILogger Logger )
{
AndroidPlatformSDK SDK = new AndroidPlatformSDK ( Logger ) ;
// Register this build platform
UEBuildPlatform . RegisterBuildPlatform ( new AndroidPlatform ( SDK , Logger ) , Logger ) ;
UEBuildPlatform . RegisterPlatformWithGroup ( UnrealTargetPlatform . Android , UnrealPlatformGroup . Android ) ;
2023-05-22 15:17:32 -04:00
UEBuildPlatform . RegisterPlatformWithGroup ( UnrealTargetPlatform . Android , UnrealPlatformGroup . ThirtyHz ) ;
2022-06-01 06:59:18 -04:00
}
}
2024-07-23 19:39:24 -04:00
}