From 3f5c92e2fa9ef23d7db17736baba887d27f395bd Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Tue, 14 Nov 2023 17:00:04 +0200 Subject: [PATCH] Improve .NET 8 runtime and SDK detection Setting the environment variable `DOTNET_ROLL_FORWARD_TO_PRERELEASE=1` is required to enable runtime support for release candidate builds of future major .NET releases. --- Source/Engine/Scripting/Runtime/DotNet.cpp | 17 +++++------ .../FlaxEngine.CSharp.runtimeconfig.json | 3 +- .../Flax.Build/Build/DotNet/DotNetSdk.cs | 29 ++++++++++++------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index c4371736d..976c992ea 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -1650,9 +1650,9 @@ bool InitHostfxr() const ::String csharpLibraryPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll"); const ::String csharpRuntimeConfigPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.runtimeconfig.json"); if (!FileSystem::FileExists(csharpLibraryPath)) - LOG(Fatal, "Failed to initialize managed runtime, missing file: {0}", csharpLibraryPath); + LOG(Fatal, "Failed to initialize .NET runtime, missing file: {0}", csharpLibraryPath); if (!FileSystem::FileExists(csharpRuntimeConfigPath)) - LOG(Fatal, "Failed to initialize managed runtime, missing file: {0}", csharpRuntimeConfigPath); + LOG(Fatal, "Failed to initialize .NET runtime, missing file: {0}", csharpRuntimeConfigPath); const FLAX_CORECLR_STRING& libraryPath = FLAX_CORECLR_STRING(csharpLibraryPath); // Get path to hostfxr library @@ -1703,9 +1703,9 @@ bool InitHostfxr() Platform::OpenUrl(TEXT("https://dotnet.microsoft.com/en-us/download/dotnet/7.0")); #endif #if USE_EDITOR - LOG(Fatal, "Missing .NET 7 SDK installation required to run Flax Editor."); + LOG(Fatal, "Missing .NET 7 or later SDK installation required to run Flax Editor."); #else - LOG(Fatal, "Missing .NET 7 Runtime installation required to run this application."); + LOG(Fatal, "Missing .NET 7 or later Runtime installation required to run this application."); #endif return true; } @@ -1735,14 +1735,13 @@ bool InitHostfxr() return true; } - // TODO: Implement picking different version of hostfxr, currently prefers highest available version. - // Allow future and preview versions of .NET - String dotnetRollForward; + // TODO: Implement support for picking RC/beta updates of .NET runtime + // Uncomment for enabling support for upcoming .NET major release candidates +#if 0 String dotnetRollForwardPr; - if (Platform::GetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD"), dotnetRollForward)) - Platform::SetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD"), TEXT("LatestMajor")); if (Platform::GetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD_TO_PRERELEASE"), dotnetRollForwardPr)) Platform::SetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD_TO_PRERELEASE"), TEXT("1")); +#endif // Initialize hosting component const char_t* argv[1] = { libraryPath.Get() }; diff --git a/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json b/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json index 202425667..134a0ef98 100644 --- a/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json +++ b/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json @@ -3,7 +3,8 @@ "tfm": "net7.0", "framework": { "name": "Microsoft.NETCore.App", - "version": "7.0.0" + "version": "7.0.0", + "rollForward": "latestMajor" } } } diff --git a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs index eff24dbf3..c2999999d 100644 --- a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs +++ b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs @@ -118,6 +118,11 @@ namespace Flax.Build /// public static Version MinimumVersion => new Version(7, 0); + /// + /// The maximum SDK version. + /// + public static Version MaximumVersion => new Version(8, 0); + /// public override TargetPlatform[] Platforms { @@ -245,21 +250,24 @@ namespace Flax.Build dotnetSdkVersions = GetVersions(Path.Combine(dotnetPath, "sdk")); if (dotnetRuntimeVersions == null) dotnetRuntimeVersions = GetVersions(Path.Combine(dotnetPath, "shared/Microsoft.NETCore.App")); - string dotnetSdkVersion = dotnetSdkVersions.OrderByDescending(ParseVersion).FirstOrDefault(); - string dotnetRuntimeVersion = dotnetRuntimeVersions.OrderByDescending(ParseVersion).FirstOrDefault(); + + dotnetSdkVersions = dotnetSdkVersions.OrderByDescending(ParseVersion); + dotnetRuntimeVersions = dotnetRuntimeVersions.OrderByDescending(ParseVersion); + + string dotnetSdkVersion = dotnetSdkVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major); + string dotnetRuntimeVersion = dotnetRuntimeVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major); if (string.IsNullOrEmpty(dotnetSdkVersion)) dotnetSdkVersion = dotnetPath; + if (dotnetSdkVersion == null && dotnetSdkVersions.Count() > 0) + { + Log.Warning($"Unsupported .NET SDK {dotnetSdkVersions.First()} version found. Minimum version required is .NET {MinimumVersion}."); + return; + } if (string.IsNullOrEmpty(dotnetSdkVersion) || string.IsNullOrEmpty(dotnetRuntimeVersion)) { Log.Warning("Missing .NET SDK"); return; } - int majorVersion = int.Parse(dotnetSdkVersion.Substring(0, dotnetSdkVersion.IndexOf("."))); - if (majorVersion < MinimumVersion.Major) - { - Log.Warning($"Unsupported .NET SDK {dotnetSdkVersion} version found. Minimum version required is .NET {MinimumVersion}."); - return; - } RootPath = dotnetPath; Version = ParseVersion(dotnetSdkVersion); VersionName = dotnetSdkVersion; @@ -452,8 +460,9 @@ namespace Flax.Build private static string GetVersion(IEnumerable versions) { - // TODO: reject 'future' versions like .Net 8? - return versions.OrderByDescending(ParseVersion).FirstOrDefault(); + return versions.OrderByDescending(ParseVersion) + .Where(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major) + .FirstOrDefault(); } private static string SearchForDotnetLocationLinux()