From 4838e609ee9d46a2dafeeb65cd5ca6bf05819756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20Rold=C3=A1n=20Etchevery?= Date: Fri, 21 May 2021 06:25:24 +0200 Subject: [PATCH] C#+iOS: Fixes for games exported with `Use Interpreter` disabled Added `SystemConfiguration.framework` to the Xcode project to fix undefined symbols errors building without the interpreter, like: `_SCNetworkReachabilityScheduleWithRunLoop`. Added explicit static constructors to the generated `NativeCalls` class to avoid a `TypeInitializationException` at startup when Godot attempts to read the static fields (like `godot_api_hash`) from this class. This seems to be an issue with Mono's AOT compiler and classes with the `beforefieldinit` attribute. Not sure if it only happens when the fields are only accessed via reflection as was our case. Explicitly declaring the static constructor makes the C# compiler not add the `beforefieldinit` attribute to the class. --- .../GodotTools/Export/AotBuilder.cs | 2 ++ modules/mono/editor/bindings_generator.cpp | 23 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index 9cefbdcc1bc..90b7a682c57 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -483,6 +483,8 @@ MONO_AOT_MODE_LAST = 1000, exporter.AddIosFramework("libiconv.tbd"); exporter.AddIosFramework("GSS.framework"); exporter.AddIosFramework("CFNetwork.framework"); + if (!aotOpts.UseInterpreter) + exporter.AddIosFramework("SystemConfiguration.framework"); } private static List CollectSymbols(IDictionary assemblies) diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 8152acb8ad5..5c15c13a981 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -932,6 +932,10 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { cs_icalls_content.append(MEMBER_BEGIN "internal static uint cs_glue_version = "); cs_icalls_content.append(String::num_uint64(CS_GLUE_VERSION) + ";\n"); + // We have issues with beforefieldinit and AOT, so we use explicitly declare + // the static constructor to prevent the class from being beforefieldinit. + cs_icalls_content.append(MEMBER_BEGIN "static NativeCalls()\n" INDENT2 OPEN_BLOCK CLOSE_BLOCK_L2); + #define ADD_INTERNAL_CALL(m_icall) \ if (!m_icall.editor_only) { \ cs_icalls_content.append(MEMBER_BEGIN "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \ @@ -1031,15 +1035,18 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) { cs_icalls_content.append(String::num_uint64(BINDINGS_GENERATOR_VERSION) + ";\n"); cs_icalls_content.append(INDENT2 "internal static uint cs_glue_version = "); cs_icalls_content.append(String::num_uint64(CS_GLUE_VERSION) + ";\n"); - cs_icalls_content.append("\n"); -#define ADD_INTERNAL_CALL(m_icall) \ - if (m_icall.editor_only) { \ - cs_icalls_content.append(INDENT2 "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \ - cs_icalls_content.append(INDENT2 "internal extern static "); \ - cs_icalls_content.append(m_icall.im_type_out + " "); \ - cs_icalls_content.append(m_icall.name + "("); \ - cs_icalls_content.append(m_icall.im_sig + ");\n"); \ + // We have issues with beforefieldinit and AOT, so we use explicitly declare + // the static constructor to prevent the class from being beforefieldinit. + cs_icalls_content.append(MEMBER_BEGIN "static EditorNativeCalls()\n" INDENT2 OPEN_BLOCK CLOSE_BLOCK_L2); + +#define ADD_INTERNAL_CALL(m_icall) \ + if (m_icall.editor_only) { \ + cs_icalls_content.append(MEMBER_BEGIN "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \ + cs_icalls_content.append(INDENT2 "internal extern static "); \ + cs_icalls_content.append(m_icall.im_type_out + " "); \ + cs_icalls_content.append(m_icall.name + "("); \ + cs_icalls_content.append(m_icall.im_sig + ");\n"); \ } for (const List::Element *E = editor_custom_icalls.front(); E; E = E->next())