瀏覽代碼

Fix GDExtensions library export when multiple architectures are set.

bruvzg 2 年之前
父節點
當前提交
c2d678a924
共有 1 個文件被更改,包括 78 次插入51 次删除
  1. 78 51
      editor/plugins/gdextension_export_plugin.h

+ 78 - 51
editor/plugins/gdextension_export_plugin.h

@@ -54,67 +54,94 @@ 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);
-
-		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<String> features_vector;
-		for (const String &E : p_features) {
-			features_vector.append(E);
+	HashSet<String> 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");
+
+	HashSet<String> archs;
+	HashSet<String> features_wo_arch;
+	for (const String &tag : p_features) {
+		if (all_archs.has(tag)) {
+			archs.insert(tag);
+		} else {
+			features_wo_arch.insert(tag);
 		}
-		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<String> 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<String> 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;
+	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<String> 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)));
 		}
 
-		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);
+		List<String> dependencies;
+		if (config->has_section("dependencies")) {
+			config->get_section_keys("dependencies", &dependencies);
+		}
+
+		for (const String &E : dependencies) {
+			Vector<String> 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);
 				}
-				add_shared_object(dependency_path, dependency_tags, target_path);
+				break;
 			}
-			break;
 		}
 	}
 }