// Copyright (c) Wojciech Figat. All rights reserved. using System; using System.IO; using Flax.Build; using Flax.Build.NativeCpp; /// /// 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"; } /// public override void Setup(BuildOptions options) { base.Setup(options); options.SourceFiles.Clear(); // Get .NET SDK runtime host var dotnetSdk = DotNetSdk.Instance; if (!dotnetSdk.IsValid) throw new DotNetSdk.MissingException(); if (!dotnetSdk.GetHostRuntime(options.Platform.Target, options.Architecture, out var hostRuntime)) { if (options.Target.IsPreBuilt) return; // Ignore missing Host Runtime when engine is already prebuilt if (options.Flags.HasFlag(BuildFlags.GenerateProject)) return; // Ignore missing Host Runtime at projects evaluation stage (not important) if (Configuration.BuildBindingsOnly) return; // Ignore missing Host Runtime when just building C# bindings (without native code) throw new Exception($"Missing NET SDK runtime for {options.Platform.Target} {options.Architecture}."); } // Setup build configuration switch (options.Platform.Target) { case TargetPlatform.Windows: if (hostRuntime.Type == DotNetSdk.HostType.CoreCLR) { options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "nethost.lib")); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "nethost.dll")); } else if (hostRuntime.Type == DotNetSdk.HostType.Mono) { options.PublicDefinitions.Add("USE_MONO_DYNAMIC_LIB"); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "coreclr.import.lib")); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "coreclr.dll")); } break; case TargetPlatform.XboxOne: case TargetPlatform.XboxScarlett: options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "monosgen-2.0.lib")); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "mono-profiler-aot.lib")); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "System.Globalization.Native-Static.lib")); break; case TargetPlatform.Linux: options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libnethost.a")); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "libnethost.so")); break; case TargetPlatform.Mac: options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libnethost.a")); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "libnethost.dylib")); break; case TargetPlatform.Switch: case TargetPlatform.PS4: case TargetPlatform.PS5: { var type = Flax.Build.Utilities.GetType($"Flax.Build.Platforms.{options.Platform.Target}.nethost"); var onLink = type?.GetMethod("OnLink"); if (onLink != null) { // Custom linking logic overriden by platform tools onLink.Invoke(null, new object[] { options, hostRuntime.Path }); } else { options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.a")); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libSystem.Native.a")); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libSystem.IO.Ports.Native.a")); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libSystem.IO.Compression.Native.a")); options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libSystem.Globalization.Native.a")); } break; } case TargetPlatform.Android: options.PublicDefinitions.Add("USE_MONO_DYNAMIC_LIB"); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.so")); options.Libraries.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.so")); break; case TargetPlatform.iOS: options.PublicDefinitions.Add("USE_MONO_DYNAMIC_LIB"); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.dylib")); options.Libraries.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.dylib")); break; case TargetPlatform.Web: //options.PublicDefinitions.Add("USE_MONO_DYNAMIC_LIB"); options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.a")); options.Libraries.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.a")); foreach (var lib in new string[] { //"libz.a", "libSystem.Native.a", //"libSystem.Globalization.Native.a", //"libSystem.IO.Compression.Native.a", "libmono-component-debugger-stub-static.a",//"libmono-component-debugger-static.a", "libmono-component-hot_reload-stub-static.a",//"libmono-component-hot_reload-static.a", "libmono-component-marshal-ilgen-stub-static.a",//"libmono-component-marshal-ilgen-static.a", "libmono-component-diagnostics_tracing-stub-static.a", //"libmono-profiler-browser.a", "libmono-wasm-eh-js.a", //"libicuuc.a", //"libmono-icall-table.a", /*"libmono-wasm-nosimd.a", "libSystem.Native.a", "libSystem.IO.Compression.Native.a", //"libmono-wasm-eh-wasm.a", //"libmono-ee-interp.a", "libicuuc.a", "libicui18n.a", "libicudata.a", "libbrotlienc.a", "libbrotlidec.a", "libbrotlicommon.a",*/ //"dotnet.native.wasm", }) { options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, lib)); options.Libraries.Add(Path.Combine(hostRuntime.Path, lib)); } //options.DependencyFiles.Add(Path.Combine(hostRuntime.Path, "dotnet.native.wasm")); //options.LinkEnv.InputFiles.Add(Path.Combine(hostRuntime.Path, "dotnet.native.wasm")); //options.SourceFiles.Add(Path.Combine(hostRuntime.Path, "dotnet.native.js")); break; default: throw new InvalidPlatformException(options.Platform.Target); } options.DependencyFiles.Add(Path.Combine(FolderPath, "FlaxEngine.CSharp.runtimeconfig.json")); options.PublicDefinitions.Add("DOTNET_HOST_RUNTIME_IDENTIFIER=" + DotNetSdk.GetHostRuntimeIdentifier(options.Platform.Target, options.Architecture)); switch (hostRuntime.Type) { case DotNetSdk.HostType.CoreCLR: { // Use CoreCLR for runtime hosting options.PublicDefinitions.Add("DOTNET_HOST_CORECLR"); options.ScriptingAPI.Defines.Add("DOTNET_HOST_CORECLR"); options.PublicIncludePaths.Add(hostRuntime.Path); break; } case DotNetSdk.HostType.Mono: { // Use Mono for runtime hosting options.PublicDefinitions.Add("DOTNET_HOST_MONO"); options.ScriptingAPI.Defines.Add("DOTNET_HOST_MONO"); options.PublicIncludePaths.Add(Path.Combine(hostRuntime.Path, "include", "mono-2.0")); break; } default: throw new ArgumentOutOfRangeException(); } } }