diff --git a/Flax.flaxproj b/Flax.flaxproj
index bd64ab7e8..52c466fd7 100644
--- a/Flax.flaxproj
+++ b/Flax.flaxproj
@@ -11,6 +11,7 @@
"EditorTarget": "FlaxEditor",
"Configuration": {
"UseCSharp": true,
- "UseLargeWorlds": false
+ "UseLargeWorlds": false,
+ "UseDotNet": true
}
}
\ No newline at end of file
diff --git a/Source/Engine/Scripting/Scripting.Build.cs b/Source/Engine/Scripting/Scripting.Build.cs
index b18a9b1ef..2acb906d7 100644
--- a/Source/Engine/Scripting/Scripting.Build.cs
+++ b/Source/Engine/Scripting/Scripting.Build.cs
@@ -15,7 +15,10 @@ public class Scripting : EngineModule
if (EngineConfiguration.WithCSharp(options))
{
- options.PublicDependencies.Add("mono");
+ if (EngineConfiguration.UseDotNet)
+ options.PublicDependencies.Add("nethost");
+ else
+ options.PublicDependencies.Add("mono");
}
options.PrivateDependencies.Add("Utilities");
diff --git a/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json b/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json
new file mode 100644
index 000000000..9c7f14dd0
--- /dev/null
+++ b/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json
@@ -0,0 +1,9 @@
+{
+ "runtimeOptions": {
+ "tfm": "net7.0",
+ "framework": {
+ "name": "Microsoft.NETCore.App",
+ "version": "7.0.0-rc.2.22472.3"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ThirdParty/nethost/LICENSE.TXT b/Source/ThirdParty/nethost/LICENSE.TXT
new file mode 100644
index 000000000..a616ed188
--- /dev/null
+++ b/Source/ThirdParty/nethost/LICENSE.TXT
@@ -0,0 +1,23 @@
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/Source/ThirdParty/nethost/nethost.Build.cs b/Source/ThirdParty/nethost/nethost.Build.cs
new file mode 100644
index 000000000..d101ff0a5
--- /dev/null
+++ b/Source/ThirdParty/nethost/nethost.Build.cs
@@ -0,0 +1,92 @@
+// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
+
+using System.Collections.Generic;
+using System.IO;
+using System;
+using Flax.Build;
+using Flax.Build.NativeCpp;
+using Flax.Build.Platforms;
+using Microsoft.Win32;
+using System.Linq;
+
+///
+/// Module for nethost (.NET runtime host library)
+///
+public class nethost : ThirdPartyModule
+{
+ ///
+ public override void Init()
+ {
+ base.Init();
+
+ LicenseType = LicenseTypes.MIT;
+ LicenseFilePath = "LICENSE.TXT";
+
+ // Merge third-party modules into engine binary
+ BinaryModuleName = "FlaxEngine";
+ }
+
+ ///
+ private static Version ParseVersion(string version)
+ {
+ // Give precedence to final releases over release candidate / beta releases
+ int rev = 9999;
+ if (version.Contains("-")) // e.g. 7.0.0-rc.2.22472.3
+ {
+ version = version.Substring(0, version.IndexOf("-"));
+ rev = 0;
+ }
+ Version ver = new Version(version);
+ return new Version(ver.Major, ver.Minor, ver.Build, rev);
+ }
+
+ ///
+ public override void Setup(BuildOptions options)
+ {
+ base.Setup(options);
+
+ options.SourceFiles.Clear();
+
+ string appHostRuntimePath;
+ if (options.Platform.Target == TargetPlatform.Windows)
+ {
+ // NOTE: nethost is bundled with SDK, not runtime. Should C# scripting have a hard requirement for SDK to be installed?
+
+ string arch = "x64"; //options.Architecture == TargetArchitecture.x64 ? "x64" : "x86";
+
+ using RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
+
+ using RegistryKey hostKey = baseKey.OpenSubKey(@$"SOFTWARE\dotnet\Setup\InstalledVersions\{arch}\sharedhost");
+ string dotnetPath = (string)hostKey.GetValue("Path");
+
+ using RegistryKey runtimeKey = baseKey.OpenSubKey(@$"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\{arch}\sharedfx\Microsoft.NETCore.App");
+ string[] versions = runtimeKey.GetValueNames();
+
+ string dotnetVersion = versions.OrderByDescending(x => ParseVersion(x)).FirstOrDefault();
+
+ if (string.IsNullOrEmpty(dotnetPath))
+ dotnetPath = Environment.GetEnvironmentVariable("DOTNET_ROOT");
+
+ if (string.IsNullOrEmpty(dotnetPath) || string.IsNullOrEmpty(dotnetVersion))
+ throw new Exception("Failed to find dotnet installation");
+
+ int majorVersion = int.Parse(dotnetVersion.Substring(0, dotnetVersion.IndexOf(".")));
+ if (majorVersion < 7)
+ throw new Exception($"Unsupported dotnet version found, minimum version required is .NET 7 (found {dotnetVersion})");
+
+ appHostRuntimePath = String.Format("{0}packs\\Microsoft.NETCore.App.Host.win-{1}\\{2}\\runtimes\\win-{1}\\native", dotnetPath, arch, dotnetVersion);
+ options.OutputFiles.Add(Path.Combine(appHostRuntimePath, "nethost.lib"));
+ options.DependencyFiles.Add(Path.Combine(appHostRuntimePath, "nethost.dll"));
+ options.PublicIncludePaths.Add(appHostRuntimePath);
+ }
+ else
+ {
+ // /etc/dotnet/install_location
+ throw new InvalidPlatformException(options.Platform.Target);
+ }
+
+ options.PublicIncludePaths.Add(appHostRuntimePath);
+ options.ScriptingAPI.Defines.Add("USE_NETCORE");
+ options.DependencyFiles.Add(Path.Combine(FolderPath, "FlaxEngine.CSharp.runtimeconfig.json"));
+ }
+}
diff --git a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
index 3303a95ea..abcb52a28 100644
--- a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
+++ b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
@@ -5,7 +5,9 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Flax.Build.Graph;
+using Flax.Build.Platforms;
using Flax.Deploy;
+using Microsoft.Win32;
using Task = Flax.Build.Graph.Task;
namespace Flax.Build
@@ -152,7 +154,7 @@ namespace Flax.Build
var outputPath = Path.GetDirectoryName(buildData.Target.GetOutputFilePath(buildOptions));
var outputFile = Path.Combine(outputPath, name + ".dll");
var outputDocFile = Path.Combine(outputPath, name + ".xml");
- string monoRoot, monoPath, cscPath;
+ string monoRoot, monoPath, cscPath, referenceAssemblies, referenceAnalyzers;
switch (buildPlatform)
{
case TargetPlatform.Windows:
@@ -163,11 +165,43 @@ namespace Flax.Build
monoPath = null;
cscPath = Path.Combine(Path.GetDirectoryName(VCEnvironment.MSBuildPath), "Roslyn", "csc.exe");
- if (!File.Exists(cscPath))
+ // dotnet
+ if (WindowsPlatformBase.TryReadDirRegistryKey(@"HKEY_LOCAL_MACHINE\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost", "Path", out string dotnetPath))
+ {
+ static Version ParseVersion(string version)
+ {
+ // Give precedence to final releases over release candidate / beta releases
+ int rev = 9999;
+ if (version.Contains("-")) // e.g. 7.0.0-rc.2.22472.3
+ {
+ version = version.Substring(0, version.IndexOf("-"));
+ rev = 0;
+ }
+ Version ver = new Version(version);
+ return new Version(ver.Major, ver.Minor, ver.Build, rev);
+ }
+#pragma warning disable CA1416
+ string arch = "x64";
+ using RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
+ using RegistryKey sdkVersionsKey = baseKey.OpenSubKey($@"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\{arch}\sdk");
+ using RegistryKey sharedfxVersionsKey = baseKey.OpenSubKey($@"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\{arch}\sharedfx\Microsoft.NETCore.App");
+ using RegistryKey hostfxrKey = baseKey.OpenSubKey($@"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\{arch}\hostfxr");
+
+ string dotnetSdkVersion = sdkVersionsKey.GetValueNames().OrderByDescending(x => ParseVersion(x)).FirstOrDefault();
+ string dotnetSharedfxVersion = sharedfxVersionsKey.GetValueNames().OrderByDescending(x => ParseVersion(x)).FirstOrDefault();
+ string dotnetHostfxrVersion = (string)hostfxrKey.GetValue("Version");
+#pragma warning restore CA1416
+ cscPath = @$"{dotnetPath}sdk\{dotnetSdkVersion}\Roslyn\bincore\csc.dll";
+ referenceAssemblies = @$"{dotnetPath}shared\Microsoft.NETCore.App\{dotnetSharedfxVersion}\";
+ referenceAnalyzers = @$"{dotnetPath}packs\Microsoft.NETCore.App.Ref\{dotnetSharedfxVersion}\analyzers\dotnet\cs\";
+ }
+ else //if (!File.Exists(cscPath))
{
// Fallback to Mono binaries
monoPath = Path.Combine(monoRoot, "bin", "mono.exe");
cscPath = Path.Combine(monoRoot, "lib", "mono", "4.5", "csc.exe");
+ referenceAssemblies = Path.Combine(monoRoot, "lib", "mono", "4.5-api");
+ referenceAnalyzers = "";
}
break;
}
@@ -175,15 +209,19 @@ namespace Flax.Build
monoRoot = Path.Combine(Globals.EngineRoot, "Source", "Platforms", "Editor", "Linux", "Mono");
monoPath = Path.Combine(monoRoot, "bin", "mono");
cscPath = Path.Combine(monoRoot, "lib", "mono", "4.5", "csc.exe");
+ referenceAssemblies = Path.Combine(monoRoot, "lib", "mono", "4.5-api");
+ referenceAnalyzers = "";
break;
case TargetPlatform.Mac:
monoRoot = Path.Combine(Globals.EngineRoot, "Source", "Platforms", "Editor", "Mac", "Mono");
monoPath = Path.Combine(monoRoot, "bin", "mono");
cscPath = Path.Combine(monoRoot, "lib", "mono", "4.5", "csc.exe");
+ referenceAssemblies = Path.Combine(monoRoot, "lib", "mono", "4.5-api");
+ referenceAnalyzers = "";
break;
default: throw new InvalidPlatformException(buildPlatform);
}
- var referenceAssemblies = Path.Combine(monoRoot, "lib", "mono", "4.5-api");
+
if (fileReferences == null)
fileReferences = buildOptions.ScriptingAPI.FileReferences;
else
@@ -207,9 +245,11 @@ namespace Flax.Build
args.Add("/warn:4");
args.Add("/unsafe");
args.Add("/fullpaths");
- args.Add("/langversion:7.3");
+ args.Add("/filealign:512");
+ args.Add("/langversion:latest");
if (buildOptions.ScriptingAPI.IgnoreMissingDocumentationWarnings)
args.Add("-nowarn:1591");
+ args.Add("-nowarn:8632"); // nullable
args.Add(buildData.Configuration == TargetConfiguration.Debug ? "/optimize-" : "/optimize+");
args.Add(string.Format("/out:\"{0}\"", outputFile));
args.Add(string.Format("/doc:\"{0}\"", outputDocFile));
@@ -217,11 +257,13 @@ namespace Flax.Build
args.Add("/define:" + string.Join(";", buildOptions.ScriptingAPI.Defines));
if (buildData.Configuration == TargetConfiguration.Debug)
args.Add("/define:DEBUG");
- args.Add(string.Format("/reference:\"{0}{1}mscorlib.dll\"", referenceAssemblies, Path.DirectorySeparatorChar));
+ args.Add(string.Format("/reference:\"{0}mscorlib.dll\"", referenceAssemblies));
foreach (var reference in buildOptions.ScriptingAPI.SystemReferences)
- args.Add(string.Format("/reference:\"{0}{2}{1}.dll\"", referenceAssemblies, reference, Path.DirectorySeparatorChar));
+ args.Add(string.Format("/reference:\"{0}{1}.dll\"", referenceAssemblies, reference));
foreach (var reference in fileReferences)
args.Add(string.Format("/reference:\"{0}\"", reference));
+ foreach (var analyzer in buildOptions.ScriptingAPI.SystemAnalyzers)
+ args.Add(string.Format("/analyzer:\"{0}{1}.dll\"", referenceAnalyzers, analyzer));
foreach (var sourceFile in sourceFiles)
args.Add("\"" + sourceFile + "\"");
@@ -249,8 +291,8 @@ namespace Flax.Build
// The "/shared" flag enables the compiler server support:
// https://github.com/dotnet/roslyn/blob/main/docs/compilers/Compiler%20Server.md
- task.CommandPath = cscPath;
- task.CommandArguments = $"/noconfig /shared @\"{responseFile}\"";
+ task.CommandPath = "dotnet.exe";
+ task.CommandArguments = $"exec \"{cscPath}\" /noconfig /shared @\"{responseFile}\"";
}
BuildDotNetAssembly?.Invoke(graph, buildData, buildOptions, task, binaryModule);
diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs
index 6cad222ba..c759719c3 100644
--- a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs
+++ b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs
@@ -156,6 +156,11 @@ namespace Flax.Build.NativeCpp
///
public HashSet FileReferences;
+ ///
+ /// The .Net libraries references (dll or exe files paths).
+ ///
+ public HashSet SystemAnalyzers;
+
///
/// True if ignore compilation warnings due to missing code documentation comments.
///
@@ -182,9 +187,53 @@ namespace Flax.Build.NativeCpp
Defines = new HashSet(),
SystemReferences = new HashSet
{
+ "Microsoft.CSharp",
"System",
- "System.Xml",
+
+ "System.Collections",
+ "System.Collections.Concurrent",
+ "System.Collections.NonGeneric",
+ "System.Collections.Specialized",
+ "System.Collections.Immutable",
+ "System.ComponentModel",
+ "System.ComponentModel.DataAnnotations",
+ "System.ComponentModel.Primitives",
+ "System.ComponentModel.TypeConverter",
+ "System.Console",
"System.Core",
+ "System.Globalization",
+ "System.IO",
+ "System.IO.Compression",
+ "System.IO.FileSystem.Watcher",
+ "System.Linq",
+ "System.Linq.Expressions",
+ "System.Net.Http",
+ "System.Net.Primitives",
+ "System.ObjectModel",
+ "System.Private.CoreLib",
+ "System.Private.Uri",
+ "System.Private.Xml",
+
+ "System.Reflection",
+ "System.Runtime",
+ "System.Runtime.CompilerServices.Unsafe",
+ "System.Runtime.InteropServices",
+ "System.Runtime.InteropServices.RuntimeInformation",
+ "System.Runtime.Serialization.Formatters", // BinaryFormatter
+ "System.Security.Cryptography",
+ "System.Security.Cryptography.Algorithms",
+ "System.Security.Cryptography.Primitives",
+ "System.Text.RegularExpressions",
+ "System.Threading.Tasks.Parallel",
+ "System.Xml",
+
+ "System.Reflection.Metadata",
+ "netstandard",
+ },
+ SystemAnalyzers = new HashSet
+ {
+ @"Microsoft.Interop.LibraryImportGenerator",
+ @"Microsoft.Interop.SourceGeneration",
},
FileReferences = new HashSet(),
};
diff --git a/Source/Tools/Flax.Build/Configuration.cs b/Source/Tools/Flax.Build/Configuration.cs
index 4c3f63b0c..33b40cf05 100644
--- a/Source/Tools/Flax.Build/Configuration.cs
+++ b/Source/Tools/Flax.Build/Configuration.cs
@@ -242,6 +242,12 @@ namespace Flax.Build
[CommandLine("useCSharp", "0 to disable C# support in build")]
public static bool UseCSharp = true;
+ ///
+ /// True if .NET support should be enabled.
+ ///
+ [CommandLine("useDotNet", "1 to enable .NET support in build, 0 to enable Mono support in build")]
+ public static bool UseDotNet = true;
+
public static bool WithCSharp(NativeCpp.BuildOptions options)
{
if (options.Platform.Target == TargetPlatform.PS5)
@@ -254,5 +260,10 @@ namespace Flax.Build
// This can be used to selectively control 64-bit coordinates per-platform or build configuration
return UseLargeWorlds;
}
+
+ public static bool WithDotNet(NativeCpp.BuildOptions options)
+ {
+ return UseDotNet;
+ }
}
}
diff --git a/Source/Tools/Flax.Build/Deploy/VCEnvironment.cs b/Source/Tools/Flax.Build/Deploy/VCEnvironment.cs
index 0ca955324..5a0d96b27 100644
--- a/Source/Tools/Flax.Build/Deploy/VCEnvironment.cs
+++ b/Source/Tools/Flax.Build/Deploy/VCEnvironment.cs
@@ -9,6 +9,8 @@ using Flax.Build.Platforms;
using Flax.Build.Projects.VisualStudio;
using Microsoft.Win32;
+#pragma warning disable CA1416
+
namespace Flax.Deploy
{
///
@@ -286,3 +288,5 @@ namespace Flax.Deploy
}
}
}
+
+#pragma warning restore CA1416
diff --git a/Source/Tools/Flax.Build/Platforms/Windows/WindowsPlatformBase.cs b/Source/Tools/Flax.Build/Platforms/Windows/WindowsPlatformBase.cs
index 2673ec817..2416a614a 100644
--- a/Source/Tools/Flax.Build/Platforms/Windows/WindowsPlatformBase.cs
+++ b/Source/Tools/Flax.Build/Platforms/Windows/WindowsPlatformBase.cs
@@ -11,6 +11,8 @@ using Flax.Build.Projects.VisualStudio;
using Flax.Build.Projects.VisualStudioCode;
using Microsoft.Win32;
+#pragma warning disable CA1416
+
namespace Flax.Build.Platforms
{
///
@@ -523,3 +525,5 @@ namespace Flax.Build.Platforms
}
}
}
+
+#pragma warning restore CA1416
diff --git a/Source/Tools/Flax.Build/Properties/AssemblyInfo.cs b/Source/Tools/Flax.Build/Properties/AssemblyInfo.cs
deleted file mode 100644
index 48e41e772..000000000
--- a/Source/Tools/Flax.Build/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
-
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Flax.Build")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Wojciech Figat")]
-[assembly: AssemblyProduct("Flax.Build")]
-[assembly: AssemblyCopyright("Copyright © 2012-2022 Wojciech Figat")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-[assembly: Guid("c99aaf92-d4ad-4847-9ee0-b11e68e93e1e")]
-[assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyFileVersion("1.0.0.0")]