2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
using System ;
using System.Collections.Generic ;
using System.Text ;
using System.Diagnostics ;
using System.IO ;
2014-07-17 13:49:42 -04:00
namespace UnrealBuildTool
2014-03-14 14:13:41 -04:00
{
class LinuxPlatform : UEBuildPlatform
{
2014-04-23 18:09:10 -04:00
/** This is the SDK version we support */
2014-10-30 19:44:12 -04:00
static private Dictionary < string , string > ExpectedSDKVersions = new Dictionary < string , string > ( )
{
2015-06-18 13:43:54 -04:00
{ "x86_64-unknown-linux-gnu" , "v6_clang-3.6.0_ld-2.24_glibc-2.12.2" } ,
2014-10-30 19:44:12 -04:00
{ "arm-unknown-linux-gnueabihf" , "arm-unknown-linux-gnueabihf_v5_clang-3.5.0-ld-2.23.1-glibc-2.13" } ,
} ;
2014-04-23 18:09:10 -04:00
/** Platform name (embeds architecture for now) */
static private string TargetPlatformName = "Linux_x64" ;
2014-05-30 10:58:16 -04:00
/** Linux architecture (compiler target triplet) */
2014-10-30 19:44:12 -04:00
// FIXME: for now switching between architectures is hard-coded
static private string DefaultArchitecture = "x86_64-unknown-linux-gnu" ;
//static private string DefaultArchitecture = "arm-unknown-linux-gnueabihf";
2014-05-30 10:58:16 -04:00
/** The current architecture */
public override string GetActiveArchitecture ( )
{
return DefaultArchitecture ;
}
2014-05-30 13:28:40 -04:00
/ * *
* Allow the platform to apply architecture - specific name according to its rules
* /
public override string ApplyArchitectureName ( string BinaryName )
{
// Linux ignores architecture-specific names, although it might be worth it to prepend architecture
return BinaryName ;
}
2014-04-23 18:09:10 -04:00
/ * *
* Whether platform supports switching SDKs during runtime
*
* @return true if supports
* /
2014-07-18 14:21:02 -04:00
protected override bool PlatformSupportsAutoSDKs ( )
2014-04-23 18:09:10 -04:00
{
return true ;
}
/ * *
* Returns platform - specific name used in SDK repository
*
* @return path to SDK Repository
* /
public override string GetSDKTargetPlatformName ( )
{
return TargetPlatformName ;
}
/ * *
* Returns SDK string as required by the platform
*
* @return Valid SDK string
* /
2014-07-18 14:21:02 -04:00
protected override string GetRequiredSDKString ( )
2014-04-23 18:09:10 -04:00
{
2014-10-30 19:44:12 -04:00
string SDKString ;
if ( ! ExpectedSDKVersions . TryGetValue ( GetActiveArchitecture ( ) , out SDKString ) )
{
throw new BuildException ( "LinuxPlatform::GetRequiredSDKString: no toolchain set up for architecture '{0}'" , GetActiveArchitecture ( ) ) ;
}
return SDKString ;
2014-04-23 18:09:10 -04:00
}
2014-07-18 14:21:02 -04:00
protected override String GetRequiredScriptVersionString ( )
{
2014-07-25 21:56:32 -04:00
return "3.0" ;
2014-07-18 14:21:02 -04:00
}
2014-07-24 11:55:02 -04:00
protected override bool PreferAutoSDK ( )
2014-07-24 11:09:55 -04:00
{
// having LINUX_ROOT set (for legacy reasons or for convenience of cross-compiling certain third party libs) should not make UBT skip AutoSDKs
return true ;
}
2014-03-14 14:13:41 -04:00
/ * *
* Whether the required external SDKs are installed for this platform
* /
2014-07-18 14:21:02 -04:00
protected override SDKStatus HasRequiredManualSDKInternal ( )
2014-03-14 14:13:41 -04:00
{
2014-08-06 07:05:15 -04:00
if ( BuildHostPlatform . Current . Platform = = UnrealTargetPlatform . Linux )
2014-04-02 18:09:23 -04:00
{
2014-04-29 21:56:53 -04:00
return SDKStatus . Valid ;
2014-04-02 18:09:23 -04:00
}
2014-03-14 14:13:41 -04:00
string BaseLinuxPath = Environment . GetEnvironmentVariable ( "LINUX_ROOT" ) ;
2014-04-02 18:09:23 -04:00
// we don't have an LINUX_ROOT specified
2014-03-14 14:13:41 -04:00
if ( String . IsNullOrEmpty ( BaseLinuxPath ) )
2014-04-29 21:56:53 -04:00
return SDKStatus . Invalid ;
2014-03-14 14:13:41 -04:00
// paths to our toolchains
BaseLinuxPath = BaseLinuxPath . Replace ( "\"" , "" ) ;
string ClangPath = Path . Combine ( BaseLinuxPath , @"bin\Clang++.exe" ) ;
if ( File . Exists ( ClangPath ) )
2014-04-29 21:56:53 -04:00
return SDKStatus . Valid ;
2014-03-14 14:13:41 -04:00
2014-04-29 21:56:53 -04:00
return SDKStatus . Invalid ;
2014-03-14 14:13:41 -04:00
}
2014-09-30 15:59:01 -04:00
2015-08-04 19:39:07 -04:00
public override bool CanUseXGE ( )
{
// [RCL] 2015-08-04 FIXME: modular (cross-)builds (e.g. editor, UT server) fail with XGE as FixDeps step apparently depends on artifacts (object files) which aren't listed among its prerequisites.
return false ;
}
2014-09-30 15:59:01 -04:00
/ * *
* Register the platform with the UEBuildPlatform class
* /
2014-07-18 14:21:02 -04:00
protected override void RegisterBuildPlatformInternal ( )
2014-03-14 14:13:41 -04:00
{
2014-05-21 06:09:37 -04:00
if ( ( ProjectFileGenerator . bGenerateProjectFiles = = true ) | | ( HasRequiredSDKsInstalled ( ) = = SDKStatus . Valid ) )
2014-03-14 14:13:41 -04:00
{
bool bRegisterBuildPlatform = true ;
string EngineSourcePath = Path . Combine ( ProjectFileGenerator . RootRelativePath , "Engine" , "Source" ) ;
string LinuxTargetPlatformFile = Path . Combine ( EngineSourcePath , "Developer" , "Linux" , "LinuxTargetPlatform" , "LinuxTargetPlatform.Build.cs" ) ;
2014-07-17 13:49:42 -04:00
if ( File . Exists ( LinuxTargetPlatformFile ) = = false )
2014-03-14 14:13:41 -04:00
{
bRegisterBuildPlatform = false ;
}
if ( bRegisterBuildPlatform = = true )
{
// Register this build platform for Linux
if ( BuildConfiguration . bPrintDebugInfo )
{
Console . WriteLine ( " Registering for {0}" , UnrealTargetPlatform . Linux . ToString ( ) ) ;
}
UEBuildPlatform . RegisterBuildPlatform ( UnrealTargetPlatform . Linux , this ) ;
UEBuildPlatform . RegisterPlatformWithGroup ( UnrealTargetPlatform . Linux , UnrealPlatformGroup . Unix ) ;
}
}
}
/ * *
* Retrieve the CPPTargetPlatform for the given UnrealTargetPlatform
*
* @param InUnrealTargetPlatform The UnrealTargetPlatform being build
*
* @return CPPTargetPlatform The CPPTargetPlatform to compile for
* /
public override CPPTargetPlatform GetCPPTargetPlatform ( UnrealTargetPlatform InUnrealTargetPlatform )
{
switch ( InUnrealTargetPlatform )
{
case UnrealTargetPlatform . Linux :
return CPPTargetPlatform . Linux ;
}
throw new BuildException ( "LinuxPlatform::GetCPPTargetPlatform: Invalid request for {0}" , InUnrealTargetPlatform . ToString ( ) ) ;
}
/ * *
* Get the extension to use for the given binary type
*
* @param InBinaryType The binary type being built
*
* @return string The binary extension ( i . e . ' exe ' or ' dll ' )
* /
public override string GetBinaryExtension ( UEBuildBinaryType InBinaryType )
{
switch ( InBinaryType )
{
case UEBuildBinaryType . DynamicLinkLibrary :
return ".so" ;
case UEBuildBinaryType . Executable :
return "" ;
case UEBuildBinaryType . StaticLibrary :
return ".a" ;
2014-06-05 12:11:58 -04:00
case UEBuildBinaryType . Object :
return ".o" ;
case UEBuildBinaryType . PrecompiledHeader :
return ".gch" ;
2014-03-14 14:13:41 -04:00
}
return base . GetBinaryExtension ( InBinaryType ) ;
}
/ * *
* Get the extension to use for debug info for the given binary type
*
* @param InBinaryType The binary type being built
*
* @return string The debug info extension ( i . e . ' pdb ' )
* /
public override string GetDebugInfoExtension ( UEBuildBinaryType InBinaryType )
{
return "" ;
}
/ * *
* Gives the platform a chance to ' override ' the configuration settings
* that are overridden on calls to RunUBT .
*
* @param InPlatform The UnrealTargetPlatform being built
* @param InConfiguration The UnrealTargetConfiguration being built
* /
public override void ResetBuildConfiguration ( UnrealTargetPlatform InPlatform , UnrealTargetConfiguration InConfiguration )
{
ValidateUEBuildConfiguration ( ) ;
}
/ * *
* Validate configuration for this platform
* NOTE : This function can / will modify BuildConfiguration !
*
* @param InPlatform The CPPTargetPlatform being built
* @param InConfiguration The CPPTargetConfiguration being built
* @param bInCreateDebugInfo true if debug info is getting create , false if not
* /
public override void ValidateBuildConfiguration ( CPPTargetConfiguration Configuration , CPPTargetPlatform Platform , bool bCreateDebugInfo )
{
2014-07-17 13:49:42 -04:00
UEBuildConfiguration . bCompileSimplygon = false ;
2014-03-14 14:13:41 -04:00
}
/ * *
* Validate the UEBuildConfiguration for this platform
* This is called BEFORE calling UEBuildConfiguration to allow setting
* various fields used in that function such as CompileLeanAndMean . . .
* /
public override void ValidateUEBuildConfiguration ( )
{
2014-07-17 13:49:42 -04:00
if ( ProjectFileGenerator . bGenerateProjectFiles & & ! ProjectFileGenerator . bGeneratingRocketProjectFiles )
{
// When generating non-Rocket project files we need intellisense generator to include info from all modules,
// including editor-only third party libs
UEBuildConfiguration . bCompileLeanAndMeanUE = false ;
}
2014-03-14 14:13:41 -04:00
BuildConfiguration . bUseUnityBuild = true ;
// Don't stop compilation at first error...
BuildConfiguration . bStopXGECompilationAfterErrors = true ;
BuildConfiguration . bUseSharedPCHs = false ;
}
/ * *
* Whether PDB files should be used
*
* @param InPlatform The CPPTargetPlatform being built
* @param InConfiguration The CPPTargetConfiguration being built
* @param bInCreateDebugInfo true if debug info is getting create , false if not
*
* @return bool true if PDB files should be used , false if not
* /
public override bool ShouldUsePDBFiles ( CPPTargetPlatform Platform , CPPTargetConfiguration Configuration , bool bCreateDebugInfo )
{
return true ;
}
/ * *
* Get a list of extra modules the platform requires .
* This is to allow undisclosed platforms to add modules they need without exposing information about the platfomr .
*
* @param Target The target being build
* @param BuildTarget The UEBuildTarget getting build
* @param PlatformExtraModules OUTPUT the list of extra modules the platform needs to add to the target
* /
public override void GetExtraModules ( TargetInfo Target , UEBuildTarget BuildTarget , ref List < string > PlatformExtraModules )
{
}
/ * *
* Modify the newly created module passed in for this platform .
* This is not required - but allows for hiding details of a
* particular platform .
*
2015-08-28 07:27:26 -04:00
* @param Name The name of the module
* @param Rules The module rules
* @param Target The target being build
* /
public override void ModifyModuleRules ( string ModuleName , ModuleRules Rules , TargetInfo Target )
2014-03-14 14:13:41 -04:00
{
if ( ( Target . Platform = = UnrealTargetPlatform . Win32 ) | | ( Target . Platform = = UnrealTargetPlatform . Win64 ) )
{
if ( ! UEBuildConfiguration . bBuildRequiresCookedData )
{
2015-08-28 07:27:26 -04:00
if ( ModuleName = = "Engine" )
2014-03-14 14:13:41 -04:00
{
if ( UEBuildConfiguration . bBuildDeveloperTools )
{
2015-08-28 07:27:26 -04:00
Rules . PlatformSpecificDynamicallyLoadedModuleNames . Add ( "LinuxTargetPlatform" ) ;
Rules . PlatformSpecificDynamicallyLoadedModuleNames . Add ( "LinuxNoEditorTargetPlatform" ) ;
Rules . PlatformSpecificDynamicallyLoadedModuleNames . Add ( "LinuxServerTargetPlatform" ) ;
2014-03-14 14:13:41 -04:00
}
}
}
// allow standalone tools to use targetplatform modules, without needing Engine
if ( UEBuildConfiguration . bForceBuildTargetPlatforms )
{
2015-08-28 07:27:26 -04:00
Rules . PlatformSpecificDynamicallyLoadedModuleNames . Add ( "LinuxTargetPlatform" ) ;
Rules . PlatformSpecificDynamicallyLoadedModuleNames . Add ( "LinuxNoEditorTargetPlatform" ) ;
Rules . PlatformSpecificDynamicallyLoadedModuleNames . Add ( "LinuxServerTargetPlatform" ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-07-17 13:49:42 -04:00
else if ( Target . Platform = = UnrealTargetPlatform . Linux )
{
bool bBuildShaderFormats = UEBuildConfiguration . bForceBuildShaderFormats ;
if ( ! UEBuildConfiguration . bBuildRequiresCookedData )
{
2015-08-28 07:27:26 -04:00
if ( ModuleName = = "TargetPlatform" )
2014-07-17 13:49:42 -04:00
{
bBuildShaderFormats = true ;
}
}
// allow standalone tools to use target platform modules, without needing Engine
if ( UEBuildConfiguration . bForceBuildTargetPlatforms )
{
2015-08-28 07:27:26 -04:00
Rules . DynamicallyLoadedModuleNames . Add ( "LinuxTargetPlatform" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "LinuxNoEditorTargetPlatform" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "LinuxServerTargetPlatform" ) ;
Rules . DynamicallyLoadedModuleNames . Add ( "AllDesktopTargetPlatform" ) ;
2014-07-17 13:49:42 -04:00
}
if ( bBuildShaderFormats )
{
2015-08-28 07:27:26 -04:00
// Rules.DynamicallyLoadedModuleNames.Add("ShaderFormatD3D");
Rules . DynamicallyLoadedModuleNames . Add ( "ShaderFormatOpenGL" ) ;
2014-07-17 13:49:42 -04:00
}
}
2014-03-14 14:13:41 -04:00
}
/ * *
* Setup the target environment for building
*
* @param InBuildTarget The target being built
* /
public override void SetUpEnvironment ( UEBuildTarget InBuildTarget )
{
InBuildTarget . GlobalCompileEnvironment . Config . Definitions . Add ( "PLATFORM_LINUX=1" ) ;
InBuildTarget . GlobalCompileEnvironment . Config . Definitions . Add ( "LINUX=1" ) ;
2014-04-02 18:09:23 -04:00
InBuildTarget . GlobalCompileEnvironment . Config . Definitions . Add ( "WITH_DATABASE_SUPPORT=0" ) ; //@todo linux: valid?
2014-03-14 14:13:41 -04:00
2015-02-02 17:14:05 -05:00
if ( GetActiveArchitecture ( ) . StartsWith ( "arm" ) )
{
InBuildTarget . GlobalCompileEnvironment . Config . Definitions . Add ( "REQUIRES_ALIGNED_INT_ACCESS" ) ;
}
2014-03-14 14:13:41 -04:00
// link with Linux libraries.
InBuildTarget . GlobalLinkEnvironment . Config . AdditionalLibraries . Add ( "pthread" ) ;
2014-05-29 16:59:18 -04:00
// Disable Simplygon support if compiling against the NULL RHI.
if ( InBuildTarget . GlobalCompileEnvironment . Config . Definitions . Contains ( "USE_NULL_RHI=1" ) )
{
UEBuildConfiguration . bCompileSimplygon = false ;
}
2015-08-26 08:49:08 -04:00
if ( InBuildTarget . TargetType = = TargetRules . TargetType . Server )
{
// Localization shouldn't be needed on servers by default, and ICU is pretty heavy
UEBuildConfiguration . bCompileICU = false ;
}
2014-03-14 14:13:41 -04:00
}
/ * *
* Whether this platform should create debug information or not
*
* @param InPlatform The UnrealTargetPlatform being built
* @param InConfiguration The UnrealTargetConfiguration being built
*
* @return bool true if debug info should be generated , false if not
* /
public override bool ShouldCreateDebugInfo ( UnrealTargetPlatform Platform , UnrealTargetConfiguration Configuration )
{
switch ( Configuration )
{
case UnrealTargetConfiguration . Development :
case UnrealTargetConfiguration . Shipping :
case UnrealTargetConfiguration . Test :
case UnrealTargetConfiguration . Debug :
default :
return true ;
} ;
}
/ * *
* Setup the binaries for this specific platform .
*
* @param InBuildTarget The target being built
* /
public override void SetupBinaries ( UEBuildTarget InBuildTarget )
{
}
}
}