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.
This commit is contained in:
Ignacio Roldán Etchevery 2021-05-21 06:25:24 +02:00
parent 21a739e3b1
commit 4838e609ee
2 changed files with 17 additions and 8 deletions

View file

@ -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<string> CollectSymbols(IDictionary<string, string> assemblies)

View file

@ -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<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next())