You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-04 17:04:49 +00:00
Fix GDExtensions library export when multiple architectures are set.
This commit is contained in:
@@ -54,68 +54,95 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
|
|||||||
|
|
||||||
String entry_symbol = config->get_value("configuration", "entry_symbol");
|
String entry_symbol = config->get_value("configuration", "entry_symbol");
|
||||||
|
|
||||||
PackedStringArray tags;
|
HashSet<String> all_archs;
|
||||||
String library_path = GDExtension::find_extension_library(
|
all_archs.insert("x86_32");
|
||||||
p_path, config, [p_features](String p_feature) { return p_features.has(p_feature); }, &tags);
|
all_archs.insert("x86_64");
|
||||||
if (!library_path.is_empty()) {
|
all_archs.insert("arm32");
|
||||||
add_shared_object(library_path, tags);
|
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"))) {
|
HashSet<String> archs;
|
||||||
String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
|
HashSet<String> features_wo_arch;
|
||||||
"extern void add_ios_init_callback(void (*cb)());\n"
|
for (const String &tag : p_features) {
|
||||||
"\n"
|
if (all_archs.has(tag)) {
|
||||||
"extern \"C\" void $ENTRY();\n"
|
archs.insert(tag);
|
||||||
"void $ENTRY_init() {\n"
|
} else {
|
||||||
" if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n"
|
features_wo_arch.insert(tag);
|
||||||
"}\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)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> dependencies;
|
if (archs.is_empty()) {
|
||||||
if (config->has_section("dependencies")) {
|
archs.insert("unknown_arch"); // Not archs specified, still try to match.
|
||||||
config->get_section_keys("dependencies", &dependencies);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const String &E : dependencies) {
|
for (const String &arch_tag : archs) {
|
||||||
Vector<String> dependency_tags = E.split(".");
|
PackedStringArray tags;
|
||||||
bool all_tags_met = true;
|
String library_path = GDExtension::find_extension_library(
|
||||||
for (int i = 0; i < dependency_tags.size(); i++) {
|
p_path, config, [features_wo_arch, arch_tag](String p_feature) { return features_wo_arch.has(p_feature) || (p_feature == arch_tag); }, &tags);
|
||||||
String tag = dependency_tags[i].strip_edges();
|
if (!library_path.is_empty()) {
|
||||||
if (!p_features.has(tag)) {
|
add_shared_object(library_path, tags);
|
||||||
all_tags_met = false;
|
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user