diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 2fd6a6edd..d09d21bbd 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -1028,9 +1028,6 @@ namespace Flax.Build.Bindings private static void GenerateCSharp(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings) { - if (!bindings.UseBindings) - return; - var contents = new StringBuilder(); buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo); @@ -1081,12 +1078,6 @@ namespace Flax.Build.Bindings // Save generated file contents.AppendLine("#endif"); Utilities.WriteFileIfChanged(bindings.GeneratedCSharpFilePath, contents.ToString()); - - // Ensure that generated file is included into build - if (!moduleBuildInfo.SourceFiles.Contains(bindings.GeneratedCSharpFilePath)) - { - moduleBuildInfo.SourceFiles.Add(bindings.GeneratedCSharpFilePath); - } } internal struct GuidInterop diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs index bc141759c..bd3cd2c2e 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs @@ -245,7 +245,7 @@ namespace Flax.Build.Bindings Module = moduleInfo.Module, Name = moduleInfo.Name, Namespace = moduleInfo.Namespace, - Children = new List(), + IsFromCache = true, }; try { diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index d62a53144..58f1edaae 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1656,10 +1656,10 @@ namespace Flax.Build.Bindings } } - private static bool GenerateCppType(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, object type) + private static void GenerateCppType(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, object type) { if (type is ApiTypeInfo apiTypeInfo && apiTypeInfo.IsInBuild) - return false; + return; try { @@ -1671,16 +1671,12 @@ namespace Flax.Build.Bindings GenerateCppInterface(buildData, contents, moduleInfo, interfaceInfo); else if (type is InjectCppCodeInfo injectCppCodeInfo) contents.AppendLine(injectCppCodeInfo.Code); - else - return false; } catch { Log.Error($"Failed to generate C++ bindings for {type}."); throw; } - - return true; } private static void GenerateCppCppUsedNonPodTypes(BuildData buildData, ApiTypeInfo apiType) @@ -1728,21 +1724,16 @@ namespace Flax.Build.Bindings CppReferencesFiles.Add(fileInfo); } } - var headerPos = contents.Length; foreach (var child in moduleInfo.Children) { foreach (var apiTypeInfo in child.Children) { - if (GenerateCppType(buildData, contents, moduleInfo, apiTypeInfo)) - bindings.UseBindings = true; + GenerateCppType(buildData, contents, moduleInfo, apiTypeInfo); } } - if (!bindings.UseBindings) - return; - GenerateCppModuleSource?.Invoke(buildData, moduleInfo, contents); { @@ -2036,7 +2027,7 @@ namespace Flax.Build.Bindings var binaryModuleSourcePath = Path.Combine(project.ProjectFolderPath, "Source", binaryModuleName + ".Gen.cpp"); contents.AppendLine("// This code was auto-generated. Do not modify it."); contents.AppendLine(); - contents.AppendLine($"#include \"Engine/Scripting/BinaryModule.h\""); + contents.AppendLine("#include \"Engine/Scripting/BinaryModule.h\""); contents.AppendLine($"#include \"{binaryModuleName}.Gen.h\""); contents.AppendLine(); contents.AppendLine($"StaticallyLinkedBinaryModuleInitializer StaticallyLinkedBinaryModule{binaryModuleName}(GetBinaryModule{binaryModuleName});"); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs index 0135f1130..a7e1508eb 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Flax.Build.NativeCpp; @@ -65,7 +66,6 @@ namespace Flax.Build.Bindings Module = module, Name = module.BinaryModuleName, Namespace = string.Empty, - Children = new List(), }; if (string.IsNullOrEmpty(moduleInfo.Name)) throw new Exception("Module name cannot be empty."); @@ -479,41 +479,82 @@ namespace Flax.Build.Bindings throw new Exception($"Invalid #if/endif pairing in file '{fileInfo.Name}'. Failed to generate API bindings for it."); } + private static bool UseBindings(object type) + { + var apiTypeInfo = type as ApiTypeInfo; + if (apiTypeInfo != null && apiTypeInfo.IsInBuild) + return false; + if ((type is ModuleInfo || type is FileInfo) && apiTypeInfo != null) + { + foreach (var child in apiTypeInfo.Children) + { + if (UseBindings(child)) + return true; + } + } + return type is ClassInfo || + type is StructureInfo || + type is InterfaceInfo || + type is InjectCppCodeInfo; + } + /// /// The API bindings generation utility that can produce scripting bindings for another languages to the native code. /// public static void GenerateBindings(BuildData buildData, Module module, ref BuildOptions moduleOptions, out BindingsResult bindings) { // Parse module (or load from cache) + var moduleInfo = ParseModule(buildData, module, moduleOptions); bindings = new BindingsResult { + UseBindings = UseBindings(moduleInfo), GeneratedCppFilePath = Path.Combine(moduleOptions.IntermediateFolder, module.Name + ".Bindings.Gen.cpp"), GeneratedCSharpFilePath = Path.Combine(moduleOptions.IntermediateFolder, module.Name + ".Bindings.Gen.cs"), }; - var moduleInfo = ParseModule(buildData, module, moduleOptions); + + if (bindings.UseBindings) + { + buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo); + + // Ensure that generated files are included into build + if (!moduleBuildInfo.SourceFiles.Contains(bindings.GeneratedCSharpFilePath)) + moduleBuildInfo.SourceFiles.Add(bindings.GeneratedCSharpFilePath); + } + + // Skip if module is cached (no scripting API changed) + if (moduleInfo.IsFromCache) + return; // Process parsed API - foreach (var child in moduleInfo.Children) + using (new ProfileEventScope("Process")) { - try + foreach (var child in moduleInfo.Children) { - foreach (var apiTypeInfo in child.Children) - ProcessAndValidate(buildData, apiTypeInfo); - } - catch (Exception) - { - if (child is FileInfo fileInfo) - Log.Error($"Failed to validate '{fileInfo.Name}' file to generate bindings."); - throw; + try + { + foreach (var apiTypeInfo in child.Children) + ProcessAndValidate(buildData, apiTypeInfo); + } + catch (Exception) + { + if (child is FileInfo fileInfo) + Log.Error($"Failed to validate '{fileInfo.Name}' file to generate bindings."); + throw; + } } } // Generate bindings for scripting - Log.Verbose($"Generating API bindings for {module.Name} ({moduleInfo.Name})"); - GenerateCpp(buildData, moduleInfo, ref bindings); - GenerateCSharp(buildData, moduleInfo, ref bindings); + if (bindings.UseBindings) + { + Log.Verbose($"Generating API bindings for {module.Name} ({moduleInfo.Name})"); + using (new ProfileEventScope("Cpp")) + GenerateCpp(buildData, moduleInfo, ref bindings); + using (new ProfileEventScope("CSharp")) + GenerateCSharp(buildData, moduleInfo, ref bindings); - // TODO: add support for extending this code and support generating bindings for other scripting languages + // TODO: add support for extending this code and support generating bindings for other scripting languages + } } /// diff --git a/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs b/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs index dd83af9d9..68742b554 100644 --- a/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs @@ -11,6 +11,7 @@ namespace Flax.Build.Bindings public class ModuleInfo : ApiTypeInfo { public Module Module; + public bool IsFromCache; public override string ToString() {