From c2d678a924b7722b6bc846d361cb309d261c6597 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Mon, 27 Feb 2023 17:00:38 +0200 Subject: [PATCH] Fix GDExtensions library export when multiple architectures are set. --- editor/plugins/gdextension_export_plugin.h | 133 +++++++++++++-------- 1 file changed, 80 insertions(+), 53 deletions(-) diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index f3d2867030d..d1c47ab14e1 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -54,68 +54,95 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p String entry_symbol = config->get_value("configuration", "entry_symbol"); - PackedStringArray tags; - String library_path = GDExtension::find_extension_library( - p_path, config, [p_features](String p_feature) { return p_features.has(p_feature); }, &tags); - if (!library_path.is_empty()) { - add_shared_object(library_path, tags); + HashSet all_archs; + all_archs.insert("x86_32"); + all_archs.insert("x86_64"); + all_archs.insert("arm32"); + all_archs.insert("arm64"); + all_archs.insert("rv64"); + all_archs.insert("ppc32"); + all_archs.insert("ppc64"); + all_archs.insert("wasm32"); + all_archs.insert("universal"); - if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) { - String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n" - "extern void add_ios_init_callback(void (*cb)());\n" - "\n" - "extern \"C\" void $ENTRY();\n" - "void $ENTRY_init() {\n" - " if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n" - "}\n" - "struct $ENTRY_struct {\n" - " $ENTRY_struct() {\n" - " add_ios_init_callback($ENTRY_init);\n" - " }\n" - "};\n" - "$ENTRY_struct $ENTRY_struct_instance;\n\n"; - additional_code = additional_code.replace("$ENTRY", entry_symbol); - add_ios_cpp_code(additional_code); - - String linker_flags = "-Wl,-U,_" + entry_symbol; - add_ios_linker_flags(linker_flags); + HashSet archs; + HashSet features_wo_arch; + for (const String &tag : p_features) { + if (all_archs.has(tag)) { + archs.insert(tag); + } else { + features_wo_arch.insert(tag); } - } else { - Vector features_vector; - for (const String &E : p_features) { - features_vector.append(E); - } - ERR_FAIL_MSG(vformat("No suitable library found for GDExtension: %s. Possible feature flags for your platform: %s", p_path, String(", ").join(features_vector))); } - List dependencies; - if (config->has_section("dependencies")) { - config->get_section_keys("dependencies", &dependencies); + if (archs.is_empty()) { + archs.insert("unknown_arch"); // Not archs specified, still try to match. } - for (const String &E : dependencies) { - Vector dependency_tags = E.split("."); - bool all_tags_met = true; - for (int i = 0; i < dependency_tags.size(); i++) { - String tag = dependency_tags[i].strip_edges(); - if (!p_features.has(tag)) { - all_tags_met = false; + for (const String &arch_tag : archs) { + PackedStringArray tags; + String library_path = GDExtension::find_extension_library( + p_path, config, [features_wo_arch, arch_tag](String p_feature) { return features_wo_arch.has(p_feature) || (p_feature == arch_tag); }, &tags); + if (!library_path.is_empty()) { + add_shared_object(library_path, tags); + + if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) { + String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n" + "extern void add_ios_init_callback(void (*cb)());\n" + "\n" + "extern \"C\" void $ENTRY();\n" + "void $ENTRY_init() {\n" + " if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n" + "}\n" + "struct $ENTRY_struct {\n" + " $ENTRY_struct() {\n" + " add_ios_init_callback($ENTRY_init);\n" + " }\n" + "};\n" + "$ENTRY_struct $ENTRY_struct_instance;\n\n"; + additional_code = additional_code.replace("$ENTRY", entry_symbol); + add_ios_cpp_code(additional_code); + + String linker_flags = "-Wl,-U,_" + entry_symbol; + add_ios_linker_flags(linker_flags); + } + } else { + Vector features_vector; + for (const String &E : p_features) { + features_vector.append(E); + } + ERR_FAIL_MSG(vformat("No suitable library found for GDExtension: %s. Possible feature flags for your platform: %s", p_path, String(", ").join(features_vector))); + } + + List dependencies; + if (config->has_section("dependencies")) { + config->get_section_keys("dependencies", &dependencies); + } + + for (const String &E : dependencies) { + Vector dependency_tags = E.split("."); + bool all_tags_met = true; + for (int i = 0; i < dependency_tags.size(); i++) { + String tag = dependency_tags[i].strip_edges(); + if (!p_features.has(tag)) { + all_tags_met = false; + break; + } + } + + if (all_tags_met) { + Dictionary dependency = config->get_value("dependencies", E); + for (const Variant *key = dependency.next(nullptr); key; key = dependency.next(key)) { + String dependency_path = *key; + String target_path = dependency[*key]; + if (dependency_path.is_relative_path()) { + dependency_path = p_path.get_base_dir().path_join(dependency_path); + } + add_shared_object(dependency_path, dependency_tags, target_path); + } break; } } - - if (all_tags_met) { - Dictionary dependency = config->get_value("dependencies", E); - for (const Variant *key = dependency.next(nullptr); key; key = dependency.next(key)) { - String dependency_path = *key; - String target_path = dependency[*key]; - if (dependency_path.is_relative_path()) { - dependency_path = p_path.get_base_dir().path_join(dependency_path); - } - add_shared_object(dependency_path, dependency_tags, target_path); - } - break; - } } }