diff --git a/Source/ThirdParty/nethost/nethost.Build.cs b/Source/ThirdParty/nethost/nethost.Build.cs
index 8b355d765..75a8a3ab6 100644
--- a/Source/ThirdParty/nethost/nethost.Build.cs
+++ b/Source/ThirdParty/nethost/nethost.Build.cs
@@ -32,7 +32,7 @@ public class nethost : ThirdPartyModule
// Get .NET SDK runtime host
var dotnetSdk = DotNetSdk.Instance;
if (!dotnetSdk.IsValid)
- throw new Exception($"Missing NET SDK {DotNetSdk.MinimumVersion}.");
+ throw new DotNetSdk.MissingException();
if (!dotnetSdk.GetHostRuntime(options.Platform.Target, options.Architecture, out var hostRuntime))
{
if (options.Target.IsPreBuilt)
diff --git a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
index 6e9fbea83..c8e709d86 100644
--- a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
+++ b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
@@ -164,7 +164,7 @@ namespace Flax.Build
#if USE_NETCORE
var dotnetSdk = DotNetSdk.Instance;
if (!dotnetSdk.IsValid)
- throw new Exception("Cannot compile C# without .NET SDK");
+ throw new DotNetSdk.MissingException();
string dotnetPath = "dotnet", referenceAnalyzers;
string[] runtimeVersionNameParts = dotnetSdk.RuntimeVersionName.Split('.');
string runtimeVersionShort = runtimeVersionNameParts[0] + '.' + runtimeVersionNameParts[1];
diff --git a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs
index 8eea4d6dd..e7506d363 100644
--- a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs
+++ b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs
@@ -106,6 +106,20 @@ namespace Flax.Build
}
}
+ ///
+ /// Exception when .NET SDK is missing.
+ ///
+ public sealed class MissingException : Exception
+ {
+ ///
+ /// Init with a proper message.
+ ///
+ public MissingException()
+ : base(string.IsNullOrEmpty(Configuration.Dotnet) ? $"Missing .NET SDK {MinimumVersion} (or higher)." : $"Missing .NET SDK {Configuration.Dotnet}.")
+ {
+ }
+ }
+
private Dictionary, HostRuntime> _hostRuntimes = new();
///
@@ -223,7 +237,7 @@ namespace Flax.Build
// We need to support two paths here:
// 1. We are running an x64 binary and we are running on an arm64 host machine
// 2. We are running an Arm64 binary and we are targeting an x64 host machine
- if (Flax.Build.Platforms.MacPlatform.GetProcessIsTranslated() || isRunningOnArm64Targetx64)
+ if (Flax.Build.Platforms.MacPlatform.GetProcessIsTranslated() || isRunningOnArm64Targetx64)
{
rid = "osx-x64";
dotnetPath = Path.Combine(dotnetPath, "x64");
@@ -260,18 +274,23 @@ namespace Flax.Build
Log.Verbose($"Found the following .NET SDK versions: {string.Join(", ", dotnetSdkVersions)}");
Log.Verbose($"Found the following .NET runtime versions: {string.Join(", ", dotnetRuntimeVersions)}");
- 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);
+ var dotnetSdkVersion = GetVersion(dotnetSdkVersions);
+ var dotnetRuntimeVersion = GetVersion(dotnetRuntimeVersions);
+ var minVer = string.IsNullOrEmpty(Configuration.Dotnet) ? MinimumVersion.ToString() : Configuration.Dotnet;
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}.");
+ if (dotnetSdkVersions.Any())
+ Log.Warning($"Unsupported .NET SDK versions found: {string.Join(", ", dotnetSdkVersions)}. Minimum version required is .NET {minVer}.");
+ else
+ Log.Warning($"Missing .NET SDK. Minimum version required is .NET {minVer}.");
return;
}
- if (string.IsNullOrEmpty(dotnetSdkVersion) || string.IsNullOrEmpty(dotnetRuntimeVersion))
+ if (string.IsNullOrEmpty(dotnetRuntimeVersion))
{
- Log.Warning("Missing .NET SDK");
+ if (dotnetRuntimeVersions.Any())
+ Log.Warning($"Unsupported .NET runtime versions found: {string.Join(", ", dotnetRuntimeVersions)}. Minimum version required is .NET {minVer}.");
+ else
+ Log.Warning($"Missing .NET runtime. Minimum version required is .NET {minVer}.");
return;
}
RootPath = dotnetPath;
@@ -434,7 +453,7 @@ namespace Flax.Build
exists = Directory.Exists(path);
if (exists)
- _hostRuntimes[new KeyValuePair(platform, arch)] = new HostRuntime(platform, path);
+ _hostRuntimes[new KeyValuePair(platform, arch)] = new HostRuntime(platform, Utilities.NormalizePath(path));
return exists;
}
@@ -456,6 +475,8 @@ namespace Flax.Build
}
if (!Version.TryParse(version, out var ver))
return null;
+ if (ver.Build == -1)
+ return new Version(ver.Major, ver.Minor);
return new Version(ver.Major, ver.Minor, ver.Build, rev);
}
@@ -466,9 +487,42 @@ namespace Flax.Build
private static string GetVersion(IEnumerable versions)
{
- return versions.OrderByDescending(ParseVersion)
- .Where(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major)
- .FirstOrDefault();
+ Version dotnetVer = null;
+ int dotnetVerNum = -1;
+ if (!string.IsNullOrEmpty(Configuration.Dotnet))
+ {
+ dotnetVer = ParseVersion(Configuration.Dotnet);
+ if (int.TryParse(Configuration.Dotnet, out var tmp) && tmp >= MinimumVersion.Major)
+ dotnetVerNum = tmp;
+ }
+ var sorted = versions.OrderByDescending(ParseVersion);
+ foreach (var version in sorted)
+ {
+ var v = ParseVersion(version);
+
+ // Filter by version specified in command line
+ if (dotnetVer != null)
+ {
+ if (dotnetVer.Major != v.Major)
+ continue;
+ if (dotnetVer.Minor != v.Minor)
+ continue;
+ if (dotnetVer.Revision != -1 && dotnetVer.Revision != v.Revision)
+ continue;
+ if (dotnetVer.Build != -1 && dotnetVer.Build != v.Build)
+ continue;
+ }
+ else if (dotnetVerNum != -1)
+ {
+ if (dotnetVerNum != v.Major)
+ continue;
+ }
+
+ // Filter by min/max versions supported by Flax.Build
+ if (v.Major >= MinimumVersion.Major && v.Major <= MaximumVersion.Major)
+ return version;
+ }
+ return null;
}
private static bool IsValidVersion(string versionPath)
diff --git a/Source/Tools/Flax.Build/Configuration.cs b/Source/Tools/Flax.Build/Configuration.cs
index 8ca11b007..f58ffcaf3 100644
--- a/Source/Tools/Flax.Build/Configuration.cs
+++ b/Source/Tools/Flax.Build/Configuration.cs
@@ -225,10 +225,24 @@ namespace Flax.Build
[CommandLine("compiler", "", "Overrides the compiler to use for building. Eg. v140 overrides the toolset when building for Windows.")]
public static string Compiler = null;
+ ///
+ /// Specifies the dotnet SDK version to use for the build. Eg. set to '7' to use .NET 7 even if .NET 8 is installed.
+ ///
+ [CommandLine("dotnet", "", "Specifies the dotnet SDK version to use for the build. Eg. set to '7' to use .NET 7 even if .NET 8 is installed.")]
+ public static string Dotnet = null;
+
///
/// Custom configuration defines provided via command line for the build tool.
///
public static List CustomDefines = new List();
+
+ internal static void PassArgs(ref string cmdLine)
+ {
+ if (!string.IsNullOrEmpty(Compiler))
+ cmdLine += " -compiler=" + Compiler;
+ if (!string.IsNullOrEmpty(Dotnet))
+ cmdLine += " -dotnet=" + Dotnet;
+ }
}
///
diff --git a/Source/Tools/Flax.Build/Deploy/FlaxBuild.cs b/Source/Tools/Flax.Build/Deploy/FlaxBuild.cs
index b4e8b8680..13f467ccf 100644
--- a/Source/Tools/Flax.Build/Deploy/FlaxBuild.cs
+++ b/Source/Tools/Flax.Build/Deploy/FlaxBuild.cs
@@ -17,8 +17,7 @@ namespace Flax.Deploy
var flaxBuildTool = Path.Combine(Globals.EngineRoot, buildPlatform == TargetPlatform.Windows ? "Binaries/Tools/Flax.Build.exe" : "Binaries/Tools/Flax.Build");
var format = "-build -buildtargets={0} -log -logfile= -perf -platform={1} -arch={2} -configuration={3}";
var cmdLine = string.Format(format, target, platform, architecture, configuration);
- if (!string.IsNullOrEmpty(Configuration.Compiler))
- cmdLine += " -compiler=" + Configuration.Compiler;
+ Configuration.PassArgs(ref cmdLine);
Log.Info($"Building {target} for {platform} {architecture} {configuration}...");
int result = Utilities.Run(flaxBuildTool, cmdLine, null, root);
diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/VCProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/VCProjectGenerator.cs
index 84607f6a1..4eba06cb0 100644
--- a/Source/Tools/Flax.Build/Projects/VisualStudio/VCProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/VisualStudio/VCProjectGenerator.cs
@@ -172,8 +172,7 @@ namespace Flax.Build.Projects.VisualStudio
configuration.Configuration,
configuration.Platform,
target.Name);
- if (!string.IsNullOrEmpty(Configuration.Compiler))
- cmdLine += " -compiler=" + Configuration.Compiler;
+ Configuration.PassArgs(ref cmdLine);
vcProjectFileContent.AppendLine(string.Format(" ", configuration.Name));
if (platform is IVisualStudioProjectCustomizer customizer)
diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs
index eda2f7a95..b04531d9f 100644
--- a/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs
@@ -731,8 +731,7 @@ namespace Flax.Build.Projects.VisualStudio
configuration.Configuration,
configuration.Platform,
configuration.Target);
- if (!string.IsNullOrEmpty(Configuration.Compiler))
- cmdLine += " -compiler=" + Configuration.Compiler;
+ Configuration.PassArgs(ref cmdLine);
str.AppendLine(string.Format(" ", cmdLine, extraArgs, configuration.Name));
}
diff --git a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs
index 5c4b2dbe0..15b236972 100644
--- a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs
@@ -201,6 +201,8 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddUnnamedField(string.Format("-buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("-compiler={0}", Configuration.Compiler));
+ if (!string.IsNullOrEmpty(Configuration.Dotnet))
+ json.AddUnnamedField(string.Format("-dotnet={0}", Configuration.Dotnet));
}
json.EndArray();
@@ -228,6 +230,8 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
+ if (!string.IsNullOrEmpty(Configuration.Dotnet))
+ json.AddUnnamedField(string.Format("-dotnet={0}", Configuration.Dotnet));
}
json.EndArray();
@@ -255,6 +259,8 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
+ if (!string.IsNullOrEmpty(Configuration.Dotnet))
+ json.AddUnnamedField(string.Format("-dotnet={0}", Configuration.Dotnet));
}
json.EndArray();