Files
UnrealEngineUWP/Engine/Source/Programs/UnrealBuildTool/Platform/Linux/LinuxPlatformSDK.cs
Luke Thatcher 4a694b920b Move AutoSDK script version to Version.txt file inside the AutoSDK directory itself
- Previously, any changes made to AutoSDKs had to be submitted along with a bump in the version string returned by GetRequiredScriptVersionString(). Since this string is in UBT, the string has to be bumped in every branch where we need the AutoSDK changes to get applied.
 - Now, the script version string is stored in Version.txt, meaning there's only one place the version needs to be bumped to force all UBT instances in all branches to reapply an SDK.
 - Made GetRequiredScriptVersionString() private and removed platform implementations.

#rb Josh.Adams,Rolando.Caloca
#preflight 60804447a698b300013e5787

[CL 16076490 by Luke Thatcher in ue5-main branch]
2021-04-21 13:14:12 -04:00

283 lines
8.0 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.IO;
using EpicGames.Core;
using System.Text.RegularExpressions;
#nullable disable
namespace UnrealBuildTool
{
class LinuxPlatformSDK : UEBuildPlatformSDK
{
public override string GetMainVersion()
{
return "v17_clang-10.0.1-centos7";
}
public override void GetValidVersionRange(out string MinVersion, out string MaxVersion)
{
// all that matters is the number after the v, according to TryConvertVersionToInt()
MinVersion = "v10_clang-5.0.0-centos7";
MaxVersion = "v17_clang-10.0.1-centos7";
}
public override void GetValidSoftwareVersionRange(out string MinVersion, out string MaxVersion)
{
MinVersion = MaxVersion = null;
}
public override string GetAutoSDKPlatformName()
{
return TargetPlatformName;
}
public override string GetInstalledSDKVersion()
{
// @todo turnkey: ForceUseSystemCompiler() returns true, we should probably run system clang -V or similar to get version
string SDKDir = GetSDKLocation();
if (string.IsNullOrEmpty(SDKDir))
{
return null;
}
string VersionFile = Path.Combine(SDKDir, SDKVersionFileName());
if (!File.Exists(VersionFile))
{
// ErrorMessage = "Cannot use an old toolchain (missing " + PlatformSDK.SDKVersionFileName() + " file, assuming version earlier than v11)";
return null;
}
StreamReader SDKVersionFile = new StreamReader(VersionFile);
string SDKVersionString = SDKVersionFile.ReadLine();
SDKVersionFile.Close();
return SDKVersionString;
}
public override bool TryConvertVersionToInt(string StringValue, out UInt64 OutValue)
{
// Example: v11_clang-5.0.0-centos7
string FullVersionPattern = @"^v([0-9]+)_.*$";
Match Result = Regex.Match(StringValue, FullVersionPattern);
if (Result.Success)
{
return UInt64.TryParse(Result.Groups[1].Value, out OutValue);
}
OutValue = 0;
return false;
}
protected override bool PlatformSupportsAutoSDKs()
{
return true;
}
protected override bool DoesHookRequireAdmin(SDKHookType Hook)
{
return false;
}
/// <summary>
/// Platform name (embeds architecture for now)
/// </summary>
private const string TargetPlatformName = "Linux_x64";
/// <summary>
/// Force using system compiler and error out if not possible
/// </summary>
private int bForceUseSystemCompiler = -1;
/// <summary>
/// Whether to compile with the verbose flag
/// </summary>
public bool bVerboseCompiler = false;
/// <summary>
/// Whether to link with the verbose flag
/// </summary>
public bool bVerboseLinker = false;
/// <summary>
/// Whether platform supports switching SDKs during runtime
/// </summary>
/// <returns>true if supports</returns>
/// <summary>
/// Returns a path to the internal SDK
/// </summary>
/// <returns>Valid path to the internal SDK, null otherwise</returns>
public override string GetInternalSDKPath()
{
string SDKRoot = Environment.GetEnvironmentVariable(SDKRootEnvVar);
if (!String.IsNullOrEmpty(SDKRoot))
{
string AutoSDKPath = Path.Combine(SDKRoot, "Host" + BuildHostPlatform.Current.Platform, TargetPlatformName, GetAutoSDKDirectoryForMainVersion(), LinuxPlatform.DefaultHostArchitecture);
if (DirectoryReference.Exists(new DirectoryReference(AutoSDKPath)))
{
return AutoSDKPath;
}
}
string InTreeSDKPath = Path.Combine(LinuxPlatformSDK.GetInTreeSDKRoot().FullName, GetMainVersion(), LinuxPlatform.DefaultHostArchitecture);
if (DirectoryReference.Exists(new DirectoryReference(InTreeSDKPath)))
{
return InTreeSDKPath;
}
return null;
}
protected override bool PreferAutoSDK()
{
// 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;
}
public string HaveLinuxDependenciesFile()
{
// This file must have no extension so that GitDeps considers it a binary dependency - it will only be pulled by the Setup script if Linux is enabled.
return "HaveLinuxDependencies";
}
public string SDKVersionFileName()
{
return "ToolchainVersion.txt";
}
/// <summary>
/// Returns the in-tree root for the Linux Toolchain for this host platform.
/// </summary>
private static DirectoryReference GetInTreeSDKRoot()
{
return DirectoryReference.Combine(UnrealBuildTool.RootDirectory, "Engine/Extras/ThirdPartyNotUE/SDKs", "Host" + BuildHostPlatform.Current.Platform, TargetPlatformName);
}
/// <summary>
/// Whether a host can use its system sdk for this platform
/// </summary>
public virtual bool ForceUseSystemCompiler()
{
// by default tools chains don't parse arguments, but we want to be able to check the -bForceUseSystemCompiler flag.
if (bForceUseSystemCompiler == -1)
{
bForceUseSystemCompiler = 0;
string[] CmdLine = Environment.GetCommandLineArgs();
foreach (string CmdLineArg in CmdLine)
{
if (CmdLineArg.Equals("-ForceUseSystemCompiler", StringComparison.OrdinalIgnoreCase))
{
bForceUseSystemCompiler = 1;
break;
}
}
}
return bForceUseSystemCompiler == 1;
}
/// <summary>
/// Returns the root SDK path for all architectures
/// WARNING: Do not cache this value - it may be changed after sourcing OutputEnvVars.txt
/// </summary>
/// <returns>Valid SDK string</returns>
public virtual string GetSDKLocation()
{
// if new multi-arch toolchain is used, prefer it
string MultiArchRoot = Environment.GetEnvironmentVariable("LINUX_MULTIARCH_ROOT");
if (String.IsNullOrEmpty(MultiArchRoot))
{
// check if in-tree SDK is available
DirectoryReference InTreeSDKVersionRoot = GetInTreeSDKRoot();
if (InTreeSDKVersionRoot != null)
{
DirectoryReference InTreeSDKVersionPath = DirectoryReference.Combine(InTreeSDKVersionRoot, GetMainVersion());
if (DirectoryReference.Exists(InTreeSDKVersionPath))
{
MultiArchRoot = InTreeSDKVersionPath.FullName;
}
}
}
return MultiArchRoot;
}
/// <summary>
/// Returns the SDK path for a specific architecture
/// WARNING: Do not cache this value - it may be changed after sourcing OutputEnvVars.txt
/// </summary>
/// <returns>Valid SDK string</returns>
public virtual string GetBaseLinuxPathForArchitecture(string Architecture)
{
// if new multi-arch toolchain is used, prefer it
string MultiArchRoot = GetSDKLocation();
string BaseLinuxPath;
if (!String.IsNullOrEmpty(MultiArchRoot))
{
BaseLinuxPath = Path.Combine(MultiArchRoot, Architecture);
}
else
{
// use cross linux toolchain if LINUX_ROOT is specified
BaseLinuxPath = Environment.GetEnvironmentVariable("LINUX_ROOT");
}
return BaseLinuxPath;
}
/// <summary>
/// Whether the path contains a valid clang version
/// </summary>
private static bool IsValidClangPath(DirectoryReference BaseLinuxPath)
{
FileReference ClangPath = FileReference.Combine(BaseLinuxPath, @"bin", (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64) ? "clang++.exe" : "clang++");
return FileReference.Exists(ClangPath);
}
/// <summary>
/// Whether the required external SDKs are installed for this platform
/// </summary>
protected override SDKStatus HasRequiredManualSDKInternal()
{
// FIXME: UBT should loop across all the architectures and compile for all the selected ones.
// do not cache this value - it may be changed after sourcing OutputEnvVars.txt
string BaseLinuxPath = GetBaseLinuxPathForArchitecture(LinuxPlatform.DefaultHostArchitecture);
if (ForceUseSystemCompiler())
{
if (!String.IsNullOrEmpty(LinuxCommon.WhichClang()) || !String.IsNullOrEmpty(LinuxCommon.WhichGcc()))
{
return SDKStatus.Valid;
}
}
else if (!String.IsNullOrEmpty(BaseLinuxPath))
{
// paths to our toolchains if BaseLinuxPath is specified
BaseLinuxPath = BaseLinuxPath.Replace("\"", "");
if (IsValidClangPath(new DirectoryReference(BaseLinuxPath)))
{
return SDKStatus.Valid;
}
}
return SDKStatus.Invalid;
}
}
}