From b193a7abc4dd8777f1daf9932a65629b6a283369 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 25 Feb 2021 13:01:15 +0100 Subject: [PATCH] Add support for binary modules with native-code only --- Source/Editor/Cooker/GameCooker.cpp | 2 +- .../CustomEditors/CustomEditorsUtil.cpp | 6 ++-- .../Editor/Managed/ManagedEditor.Internal.cpp | 4 +-- Source/Editor/Managed/ManagedEditor.cpp | 4 +-- Source/Editor/Scripting/ScriptsBuilder.cpp | 2 +- Source/Engine/Debug/DebugLog.cpp | 2 +- Source/Engine/Graphics/RenderTask.cpp | 2 +- Source/Engine/Scripting/BinaryModule.cpp | 33 +++++++++++++++++- Source/Engine/Scripting/BinaryModule.h | 34 ++++++++++++++++++- .../Scripting/Plugins/PluginManager.cpp | 2 +- Source/Engine/Scripting/Scripting.cpp | 4 +-- Source/Engine/Scripting/StdTypesContainer.cpp | 2 +- Source/FlaxEngine.Gen.cpp | 2 +- Source/FlaxEngine.Gen.h | 4 +-- .../Bindings/BindingsGenerator.CSharp.cs | 4 +++ .../Bindings/BindingsGenerator.Cache.cs | 4 +-- .../Bindings/BindingsGenerator.Cpp.cs | 16 ++++++--- .../Tools/Flax.Build/Bindings/ModuleInfo.cs | 5 ++- .../Flax.Build/Build/DotNet/Builder.DotNet.cs | 3 ++ Source/Tools/Flax.Build/Build/Module.cs | 5 +++ .../Build/NativeCpp/Builder.NativeCpp.cs | 10 ++++++ 21 files changed, 123 insertions(+), 27 deletions(-) diff --git a/Source/Editor/Cooker/GameCooker.cpp b/Source/Editor/Cooker/GameCooker.cpp index efd6763d8..9eca81eba 100644 --- a/Source/Editor/Cooker/GameCooker.cpp +++ b/Source/Editor/Cooker/GameCooker.cpp @@ -456,7 +456,7 @@ int32 GameCookerImpl::ThreadFunction() bool GameCookerService::Init() { - auto editorAssembly = GetBinaryModuleFlaxEngine()->Assembly; + auto editorAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; editorAssembly->Unloading.Bind(OnEditorAssemblyUnloading); return false; diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.cpp b/Source/Editor/CustomEditors/CustomEditorsUtil.cpp index 182175cd6..ffd42d750 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.cpp +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.cpp @@ -73,7 +73,7 @@ MonoReflectionType* CustomEditorsUtil::GetCustomEditor(MonoReflectionType* refTy bool CustomEditorsUtilService::Init() { - TRACK_ASSEMBLY(GetBinaryModuleFlaxEngine()->Assembly); + TRACK_ASSEMBLY(((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly); Scripting::BinaryModuleLoaded.Bind(&OnBinaryModuleLoaded); return false; @@ -84,7 +84,7 @@ void OnAssemblyLoaded(MAssembly* assembly) const auto startTime = DateTime::NowUTC(); // Prepare FlaxEngine - auto engineAssembly = GetBinaryModuleFlaxEngine()->Assembly; + auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; if (!engineAssembly->IsLoaded()) { LOG(Warning, "Cannot load custom editors meta for assembly {0} because FlaxEngine is not loaded.", assembly->ToString()); @@ -173,7 +173,7 @@ void OnAssemblyLoaded(MAssembly* assembly) void OnAssemblyUnloading(MAssembly* assembly) { // Fast clear for editor unloading - if (assembly == GetBinaryModuleFlaxEngine()->Assembly) + if (assembly == ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly) { Cache.Clear(); return; diff --git a/Source/Editor/Managed/ManagedEditor.Internal.cpp b/Source/Editor/Managed/ManagedEditor.Internal.cpp index ae685829b..cd99f3f98 100644 --- a/Source/Editor/Managed/ManagedEditor.Internal.cpp +++ b/Source/Editor/Managed/ManagedEditor.Internal.cpp @@ -900,7 +900,7 @@ public: if (stack && stack->Scope) { const int32 count = stack->Scope->Parameters.Length() + stack->Scope->ReturnedValues.Count(); - const auto mclass = GetBinaryModuleFlaxEngine()->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal"); + const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal"); ASSERT(mclass); result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); VisualScriptLocalManaged local; @@ -954,7 +954,7 @@ public: s = s->PreviousFrame; count++; } - const auto mclass = GetBinaryModuleFlaxEngine()->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame"); + const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame"); ASSERT(mclass); result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); s = stack; diff --git a/Source/Editor/Managed/ManagedEditor.cpp b/Source/Editor/Managed/ManagedEditor.cpp index b32ec54b1..35219a906 100644 --- a/Source/Editor/Managed/ManagedEditor.cpp +++ b/Source/Editor/Managed/ManagedEditor.cpp @@ -175,7 +175,7 @@ ManagedEditor::ManagedEditor() : PersistentScriptingObject(SpawnParams(ObjectID, ManagedEditor::TypeInitializer)) { // Link events - auto editor = GetBinaryModuleFlaxEngine()->Assembly; + auto editor = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; editor->Loaded.Bind(this); ProbesRenderer::OnRegisterBake.Bind(); ProbesRenderer::OnFinishBake.Bind(); @@ -192,7 +192,7 @@ ManagedEditor::ManagedEditor() ManagedEditor::~ManagedEditor() { // Unlink events - auto editor = GetBinaryModuleFlaxEngine()->Assembly; + auto editor = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; editor->Loaded.Unbind(this); ProbesRenderer::OnRegisterBake.Unbind(); ProbesRenderer::OnFinishBake.Unbind(); diff --git a/Source/Editor/Scripting/ScriptsBuilder.cpp b/Source/Editor/Scripting/ScriptsBuilder.cpp index 5c0116a10..1c489b2a9 100644 --- a/Source/Editor/Scripting/ScriptsBuilder.cpp +++ b/Source/Editor/Scripting/ScriptsBuilder.cpp @@ -524,7 +524,7 @@ bool ScriptsBuilderService::Init() _isInited = true; // Link for Editor assembly unload event to clear cached Internal_OnCompilationEnd to prevent errors - auto editorAssembly = GetBinaryModuleFlaxEngine()->Assembly; + auto editorAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; editorAssembly->Unloading.Bind(onEditorAssemblyUnloading); // Listen to scripts reloading events and forward them to c# diff --git a/Source/Engine/Debug/DebugLog.cpp b/Source/Engine/Debug/DebugLog.cpp index edd3b838d..bf1da8d7d 100644 --- a/Source/Engine/Debug/DebugLog.cpp +++ b/Source/Engine/Debug/DebugLog.cpp @@ -104,7 +104,7 @@ bool CacheMethods() if (Internal_SendLog && Internal_SendLogException && Internal_GetStackTrace) return false; - auto engine = GetBinaryModuleFlaxEngine()->Assembly; + auto engine = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; if (engine == nullptr || !engine->IsLoaded()) return true; auto debugLogHandlerClass = engine->GetClass("FlaxEngine.DebugLogHandler"); diff --git a/Source/Engine/Graphics/RenderTask.cpp b/Source/Engine/Graphics/RenderTask.cpp index 9cd99b504..45375a579 100644 --- a/Source/Engine/Graphics/RenderTask.cpp +++ b/Source/Engine/Graphics/RenderTask.cpp @@ -163,7 +163,7 @@ void ManagedPostProcessEffect::FetchInfo() static MMethod* FetchInfoManaged = nullptr; if (FetchInfoManaged == nullptr) { - auto klass = GetBinaryModuleFlaxEngine()->Assembly->GetClass("FlaxEngine.PostProcessEffect"); + auto klass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEngine.PostProcessEffect"); ASSERT(klass); FetchInfoManaged = klass->GetMethod("FetchInfo", 3); ASSERT(FetchInfoManaged); diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 8a92f5f2d..a348b04cd 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -633,7 +633,7 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly) // Cache types for managed-only types that can be used in the engine _firstManagedTypeIndex = Types.Count(); - NativeBinaryModule* flaxEngine = GetBinaryModuleFlaxEngine(); + NativeBinaryModule* flaxEngine = (NativeBinaryModule*)GetBinaryModuleFlaxEngine(); if (flaxEngine->Assembly->IsLoaded()) { // TODO: check only assemblies that references FlaxEngine.CSharp.dll @@ -1039,6 +1039,37 @@ void NativeBinaryModule::Destroy(bool isReloading) } } +NativeOnlyBinaryModule::NativeOnlyBinaryModule(const StringAnsiView& name) + : BinaryModule() + , _name(name) + , Library(nullptr) +{ +} + +const StringAnsi& NativeOnlyBinaryModule::GetName() const +{ + return _name; +} + +bool NativeOnlyBinaryModule::IsLoaded() const +{ + return true; +} + +void NativeOnlyBinaryModule::Destroy(bool isReloading) +{ + BinaryModule::Destroy(isReloading); + + // Release native library + const auto library = Library; + if (library) + { + Library = nullptr; + Platform::FreeLibrary(library); + // Don't do anything after FreeLibrary (this pointer might be invalid) + } +} + Array& StaticallyLinkedBinaryModuleInitializer::GetStaticallyLinkedBinaryModules() { static Array modules; diff --git a/Source/Engine/Scripting/BinaryModule.h b/Source/Engine/Scripting/BinaryModule.h index c2b9da0a4..5d470965b 100644 --- a/Source/Engine/Scripting/BinaryModule.h +++ b/Source/Engine/Scripting/BinaryModule.h @@ -355,7 +355,39 @@ public: void Destroy(bool isReloading) override; }; -typedef NativeBinaryModule* (*GetBinaryModuleFunc)(); +/// +/// The C++ scripting assembly container. +/// +class FLAXENGINE_API NativeOnlyBinaryModule : public BinaryModule +{ +private: + + StringAnsi _name; + +public: + + /// + /// Initializes a new instance of the class. + /// + /// The module name. + NativeOnlyBinaryModule(const StringAnsiView& name); + +public: + + /// + /// The native library (C++ DLL). + /// + void* Library; + +public: + + // [BinaryModule] + const StringAnsi& GetName() const override; + bool IsLoaded() const override; + void Destroy(bool isReloading) override; +}; + +typedef BinaryModule* (*GetBinaryModuleFunc)(); // Helper utility for registering native binary modules that are statically linked. class FLAXENGINE_API StaticallyLinkedBinaryModuleInitializer diff --git a/Source/Engine/Scripting/Plugins/PluginManager.cpp b/Source/Engine/Scripting/Plugins/PluginManager.cpp index b93c52dcf..257af991b 100644 --- a/Source/Engine/Scripting/Plugins/PluginManager.cpp +++ b/Source/Engine/Scripting/Plugins/PluginManager.cpp @@ -66,7 +66,7 @@ void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly) PROFILE_CPU_NAMED("Load Assembly Plugins"); // Prepare FlaxEngine - auto engineAssembly = GetBinaryModuleFlaxEngine()->Assembly; + auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; if (!engineAssembly->IsLoaded()) { LOG(Warning, "Cannot find plugin class types for assembly {0} because FlaxEngine is not loaded.", assembly->ToString()); diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index c8c8184bd..2919ce1ae 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -124,7 +124,7 @@ bool ScriptingService::Init() const auto startTime = DateTime::NowUTC(); // Link for assemblies events - auto engineAssembly = GetBinaryModuleFlaxEngine()->Assembly; + auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; engineAssembly->Loaded.Bind(onEngineLoaded); engineAssembly->Unloading.Bind(onEngineUnloading); @@ -424,7 +424,7 @@ bool Scripting::Load() // Load FlaxEngine const String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll"); - if (GetBinaryModuleFlaxEngine()->Assembly->Load(flaxEnginePath)) + if (((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->Load(flaxEnginePath)) { LOG(Error, "Failed to load FlaxEngine C# assembly."); return true; diff --git a/Source/Engine/Scripting/StdTypesContainer.cpp b/Source/Engine/Scripting/StdTypesContainer.cpp index c91099112..b68916e50 100644 --- a/Source/Engine/Scripting/StdTypesContainer.cpp +++ b/Source/Engine/Scripting/StdTypesContainer.cpp @@ -48,7 +48,7 @@ void StdTypesContainer::Clear() bool StdTypesContainer::Gather() { #define GET_CLASS(assembly, type, typeName) \ - type = CONCAT_MACROS(GetBinaryModule, assembly)()->Assembly->GetClass(typeName); \ + type = ((ManagedBinaryModule*)CONCAT_MACROS(GetBinaryModule, assembly)())->Assembly->GetClass(typeName); \ if (type == nullptr) \ { \ LOG(Error, "Missing managed type: \'{0}\'", String(typeName)); \ diff --git a/Source/FlaxEngine.Gen.cpp b/Source/FlaxEngine.Gen.cpp index 5488da877..d175cbc6a 100644 --- a/Source/FlaxEngine.Gen.cpp +++ b/Source/FlaxEngine.Gen.cpp @@ -5,7 +5,7 @@ StaticallyLinkedBinaryModuleInitializer StaticallyLinkedBinaryModuleFlaxEngine(GetBinaryModuleFlaxEngine); -extern "C" NativeBinaryModule* GetBinaryModuleFlaxEngine() +extern "C" BinaryModule* GetBinaryModuleFlaxEngine() { static NativeBinaryModule module("FlaxEngine", MAssemblyOptions()); return &module; diff --git a/Source/FlaxEngine.Gen.h b/Source/FlaxEngine.Gen.h index 53a18990c..569d2f551 100644 --- a/Source/FlaxEngine.Gen.h +++ b/Source/FlaxEngine.Gen.h @@ -13,5 +13,5 @@ #define FLAXENGINE_COMPANY "Flax" #define FLAXENGINE_COPYRIGHT "Copyright (c) 2012-2021 Wojciech Figat. All rights reserved." -class NativeBinaryModule; -extern "C" FLAXENGINE_API NativeBinaryModule* GetBinaryModuleFlaxEngine(); +class BinaryModule; +extern "C" FLAXENGINE_API BinaryModule* GetBinaryModuleFlaxEngine(); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index fd07f6d2c..84236cfd2 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -1091,6 +1091,10 @@ namespace Flax.Build.Bindings private static unsafe void GenerateCSharp(BuildData buildData, IGrouping binaryModule) { + // Skip generating C# bindings code for native-only modules + if (binaryModule.Any(x => !x.BuildCSharp)) + return; + var contents = new StringBuilder(); var binaryModuleName = binaryModule.Key; var project = Builder.GetModuleProject(binaryModule.First(), buildData); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs index 0c125f2e5..8413917bb 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs @@ -218,7 +218,7 @@ namespace Flax.Build.Bindings using (var writer = new BinaryWriter(stream, Encoding.UTF8)) { // Version - writer.Write(4); + writer.Write(5); writer.Write(File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location).Ticks); // Build options @@ -254,7 +254,7 @@ namespace Flax.Build.Bindings { // Version var version = reader.ReadInt32(); - if (version != 4) + if (version != 5) return false; if (File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location).Ticks != reader.ReadInt64()) return false; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 2c5149914..175b03584 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1991,6 +1991,7 @@ namespace Flax.Build.Bindings // Skip generating C++ bindings code for C#-only modules if (binaryModule.Any(x => !x.BuildNativeCode)) return; + var useCSharp = binaryModule.Any(x => x.BuildCSharp); var contents = new StringBuilder(); var binaryModuleName = binaryModule.Key; @@ -2018,8 +2019,8 @@ namespace Flax.Build.Bindings contents.AppendLine($"#define {binaryModuleNameUpper}_COMPANY \"{project.Company}\""); contents.AppendLine($"#define {binaryModuleNameUpper}_COPYRIGHT \"{project.Copyright}\""); contents.AppendLine(); - contents.AppendLine("class NativeBinaryModule;"); - contents.AppendLine($"extern \"C\" {binaryModuleNameUpper}_API NativeBinaryModule* GetBinaryModule{binaryModuleName}();"); + contents.AppendLine("class BinaryModule;"); + contents.AppendLine($"extern \"C\" {binaryModuleNameUpper}_API BinaryModule* GetBinaryModule{binaryModuleName}();"); GenerateCppBinaryModuleHeader?.Invoke(buildData, binaryModule, contents); Utilities.WriteFileIfChanged(binaryModuleHeaderPath, contents.ToString()); @@ -2033,9 +2034,16 @@ namespace Flax.Build.Bindings contents.AppendLine(); contents.AppendLine($"StaticallyLinkedBinaryModuleInitializer StaticallyLinkedBinaryModule{binaryModuleName}(GetBinaryModule{binaryModuleName});"); contents.AppendLine(); - contents.AppendLine($"extern \"C\" NativeBinaryModule* GetBinaryModule{binaryModuleName}()"); + contents.AppendLine($"extern \"C\" BinaryModule* GetBinaryModule{binaryModuleName}()"); contents.AppendLine("{"); - contents.AppendLine($" static NativeBinaryModule module(\"{binaryModuleName}\", MAssemblyOptions());"); + if (useCSharp) + { + contents.AppendLine($" static NativeBinaryModule module(\"{binaryModuleName}\", MAssemblyOptions());"); + } + else + { + contents.AppendLine($" static NativeOnlyBinaryModule module(\"{binaryModuleName}\");"); + } contents.AppendLine(" return &module;"); contents.AppendLine("}"); GenerateCppBinaryModuleSource?.Invoke(buildData, binaryModule, contents); diff --git a/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs b/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs index 68742b554..75ff73720 100644 --- a/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs @@ -33,6 +33,7 @@ namespace Flax.Build.Bindings writer.Write(Module.FilePath); BindingsGenerator.Write(writer, Module.BinaryModuleName); writer.Write(Module.BuildNativeCode); + writer.Write(Module.BuildCSharp); base.Write(writer); } @@ -42,7 +43,9 @@ namespace Flax.Build.Bindings if (reader.ReadString() != Module.Name || reader.ReadString() != Module.FilePath || BindingsGenerator.Read(reader, Module.BinaryModuleName) != Module.BinaryModuleName || - reader.ReadBoolean() != Module.BuildNativeCode) + reader.ReadBoolean() != Module.BuildNativeCode || + reader.ReadBoolean() != Module.BuildCSharp + ) throw new Exception(); base.Read(reader); diff --git a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs index d591a334f..e2d01a820 100644 --- a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs +++ b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs @@ -23,6 +23,8 @@ namespace Flax.Build var buildOptions = buildData.TargetOptions; foreach (var binaryModule in buildData.BinaryModules) { + if (binaryModule.All(x => !x.BuildCSharp)) + continue; var binaryModuleName = binaryModule.Key; using (new ProfileEventScope(binaryModuleName)) { @@ -71,6 +73,7 @@ namespace Flax.Build var dependencyModule = buildData.Rules.GetModule(dependencyName); if (dependencyModule != null && !string.IsNullOrEmpty(dependencyModule.BinaryModuleName) && + dependencyModule.BuildCSharp && dependencyModule.BinaryModuleName != binaryModuleName && buildData.Modules.TryGetValue(dependencyModule, out var dependencyModuleOptions)) { diff --git a/Source/Tools/Flax.Build/Build/Module.cs b/Source/Tools/Flax.Build/Build/Module.cs index 726cbf946..c623de92d 100644 --- a/Source/Tools/Flax.Build/Build/Module.cs +++ b/Source/Tools/Flax.Build/Build/Module.cs @@ -37,6 +37,11 @@ namespace Flax.Build /// public bool BuildNativeCode = true; + /// + /// True if module has C# code to build. Can be used for native modules without C# bindings nor code. + /// + public bool BuildCSharp = true; + /// /// Initializes a new instance of the class. /// diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs b/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs index 9bafb6232..e52a6055c 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs @@ -831,6 +831,11 @@ namespace Flax.Build // C#-only binary module binaryModuleInfo.NativePath = string.Empty; } + if (!binaryModule.Any(x => x.BuildCSharp)) + { + // Skip C# + binaryModuleInfo.ManagedPath = string.Empty; + } break; } case TargetLinkType.Modular: @@ -850,6 +855,11 @@ namespace Flax.Build // C#-only binary module binaryModuleInfo.NativePath = string.Empty; } + if (!module.BuildCSharp) + { + // Skip C# + binaryModuleInfo.ManagedPath = string.Empty; + } break; } default: throw new ArgumentOutOfRangeException();