// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.IO; namespace UnrealBuildTool.Linux { class LinuxPlatform : UEBuildPlatform { /** This is the SDK version we support */ static private string ExpectedSDKVersion = "v3_clang-3.3_ld-2.24_glibc-2.12.2"; /** Platform name (embeds architecture for now) */ static private string TargetPlatformName = "Linux_x64"; /** Linux architecture (compiler target triplet) */ static private string DefaultArchitecture = "x86_64-unknown-linux-gnu"; /** The current architecture */ public override string GetActiveArchitecture() { return DefaultArchitecture; } /** * 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; } /** * Whether platform supports switching SDKs during runtime * * @return true if supports */ public override bool PlatformSupportsSDKSwitching() { 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 */ public override string GetRequiredSDKString() { return ExpectedSDKVersion; } /** * Whether the required external SDKs are installed for this platform */ public override SDKStatus HasRequiredSDKsInstalled() { if (ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Linux) { return SDKStatus.Valid; } // attempt to switch SDKs if (base.HasRequiredSDKsInstalled() == SDKStatus.Valid) { return SDKStatus.Valid; } string BaseLinuxPath = Environment.GetEnvironmentVariable("LINUX_ROOT"); // we don't have an LINUX_ROOT specified if (String.IsNullOrEmpty(BaseLinuxPath)) return SDKStatus.Invalid; // paths to our toolchains BaseLinuxPath = BaseLinuxPath.Replace("\"", ""); string ClangPath = Path.Combine(BaseLinuxPath, @"bin\Clang++.exe"); if (File.Exists(ClangPath)) return SDKStatus.Valid; return SDKStatus.Invalid; } /** * Register the platform with the UEBuildPlatform class */ public override void RegisterBuildPlatform() { //@todo.Rocket: Add platform support if (UnrealBuildTool.RunningRocket() || UnrealBuildTool.BuildingRocket()) { return; } if ((ProjectFileGenerator.bGenerateProjectFiles == true) || (HasRequiredSDKsInstalled() == SDKStatus.Valid)) { bool bRegisterBuildPlatform = true; string EngineSourcePath = Path.Combine(ProjectFileGenerator.RootRelativePath, "Engine", "Source"); string LinuxTargetPlatformFile = Path.Combine(EngineSourcePath, "Developer", "Linux", "LinuxTargetPlatform", "LinuxTargetPlatform.Build.cs"); if ( (File.Exists(LinuxTargetPlatformFile) == false) ) { 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"; case UEBuildBinaryType.Object: return ".o"; case UEBuildBinaryType.PrecompiledHeader: return ".gch"; } 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) { // increase Unity size to avoid too long command lines BuildConfiguration.NumIncludedBytesPerUnityCPP = 1024 * 1024; UEBuildConfiguration.bCompileICU = true; } /** * 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() { BuildConfiguration.bUseUnityBuild = true; UEBuildConfiguration.bCompileAPEX = false; // 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 PlatformExtraModules) { } /** * Modify the newly created module passed in for this platform. * This is not required - but allows for hiding details of a * particular platform. * * @param InModule The newly loaded module * @param Target The target being build */ public override void ModifyNewlyLoadedModule(UEBuildModule InModule, TargetInfo Target) { if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64)) { if (!UEBuildConfiguration.bBuildRequiresCookedData) { if (InModule.ToString() == "Engine") { if (UEBuildConfiguration.bBuildDeveloperTools) { InModule.AddPlatformSpecificDynamicallyLoadedModule("LinuxTargetPlatform"); InModule.AddPlatformSpecificDynamicallyLoadedModule("LinuxNoEditorTargetPlatform"); InModule.AddPlatformSpecificDynamicallyLoadedModule("LinuxServerTargetPlatform"); } } } // allow standalone tools to use targetplatform modules, without needing Engine if (UEBuildConfiguration.bForceBuildTargetPlatforms) { InModule.AddPlatformSpecificDynamicallyLoadedModule("LinuxTargetPlatform"); InModule.AddPlatformSpecificDynamicallyLoadedModule("LinuxNoEditorTargetPlatform"); InModule.AddPlatformSpecificDynamicallyLoadedModule("LinuxServerTargetPlatform"); } } } /** * 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"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_DATABASE_SUPPORT=0"); //@todo linux: valid? // link with Linux libraries. InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("pthread"); // Disable Simplygon support if compiling against the NULL RHI. if (InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Contains("USE_NULL_RHI=1")) { UEBuildConfiguration.bCompileSimplygon = false; } } /** * 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) { } } }