Selaa lähdekoodia

Merge pull request #68362 from bruvzg/android_gde

[Android] Fix GDExtension export and loading.
Rémi Verschelde 2 vuotta sitten
vanhempi
commit
70bde0d762

+ 57 - 35
platform/android/export/export_plugin.cpp

@@ -585,12 +585,13 @@ zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() {
 	return zipfi;
 	return zipfi;
 }
 }
 
 
-Vector<String> EditorExportPlatformAndroid::get_abis() {
-	Vector<String> abis;
-	abis.push_back("armeabi-v7a");
-	abis.push_back("arm64-v8a");
-	abis.push_back("x86");
-	abis.push_back("x86_64");
+Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_abis() {
+	// Should have the same order and size as get_archs.
+	Vector<ABI> abis;
+	abis.push_back(ABI("armeabi-v7a", "arm32"));
+	abis.push_back(ABI("arm64-v8a", "arm64"));
+	abis.push_back(ABI("x86", "x86_32"));
+	abis.push_back(ABI("x86_64", "x86_64"));
 	return abis;
 	return abis;
 }
 }
 
 
@@ -687,14 +688,20 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj
 		return FAILED;
 		return FAILED;
 	}
 	}
 	APKExportData *ed = static_cast<APKExportData *>(p_userdata);
 	APKExportData *ed = static_cast<APKExportData *>(p_userdata);
-	Vector<String> abis = get_abis();
+	Vector<ABI> abis = get_abis();
 	bool exported = false;
 	bool exported = false;
 	for (int i = 0; i < p_so.tags.size(); ++i) {
 	for (int i = 0; i < p_so.tags.size(); ++i) {
 		// shared objects can be fat (compatible with multiple ABIs)
 		// shared objects can be fat (compatible with multiple ABIs)
-		int abi_index = abis.find(p_so.tags[i]);
+		int abi_index = -1;
+		for (int j = 0; j < abis.size(); ++j) {
+			if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) {
+				abi_index = j;
+				break;
+			}
+		}
 		if (abi_index != -1) {
 		if (abi_index != -1) {
 			exported = true;
 			exported = true;
-			String abi = abis[abi_index];
+			String abi = abis[abi_index].abi;
 			String dst_path = String("lib").path_join(abi).path_join(p_so.path.get_file());
 			String dst_path = String("lib").path_join(abi).path_join(p_so.path.get_file());
 			Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
 			Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
 			Error store_err = store_in_apk(ed, dst_path, array);
 			Error store_err = store_in_apk(ed, dst_path, array);
@@ -702,9 +709,7 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj
 		}
 		}
 	}
 	}
 	if (!exported) {
 	if (!exported) {
-		String abis_string = String(" ").join(abis);
-		String err = "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + abis_string;
-		ERR_PRINT(err);
+		ERR_PRINT("Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag: " + join_abis(abis, " ", true));
 		return FAILED;
 		return FAILED;
 	}
 	}
 	return OK;
 	return OK;
@@ -725,16 +730,22 @@ Error EditorExportPlatformAndroid::ignore_apk_file(void *p_userdata, const Strin
 Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const SharedObject &p_so) {
 Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const SharedObject &p_so) {
 	ERR_FAIL_COND_V_MSG(!p_so.path.get_file().begins_with("lib"), FAILED,
 	ERR_FAIL_COND_V_MSG(!p_so.path.get_file().begins_with("lib"), FAILED,
 			"Android .so file names must start with \"lib\", but got: " + p_so.path);
 			"Android .so file names must start with \"lib\", but got: " + p_so.path);
-	Vector<String> abis = get_abis();
+	Vector<ABI> abis = get_abis();
 	CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata);
 	CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata);
 	bool exported = false;
 	bool exported = false;
 	for (int i = 0; i < p_so.tags.size(); ++i) {
 	for (int i = 0; i < p_so.tags.size(); ++i) {
-		int abi_index = abis.find(p_so.tags[i]);
+		int abi_index = -1;
+		for (int j = 0; j < abis.size(); ++j) {
+			if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) {
+				abi_index = j;
+				break;
+			}
+		}
 		if (abi_index != -1) {
 		if (abi_index != -1) {
 			exported = true;
 			exported = true;
 			String base = "res://android/build/libs";
 			String base = "res://android/build/libs";
 			String type = export_data->debug ? "debug" : "release";
 			String type = export_data->debug ? "debug" : "release";
-			String abi = abis[abi_index];
+			String abi = abis[abi_index].abi;
 			String filename = p_so.path.get_file();
 			String filename = p_so.path.get_file();
 			String dst_path = base.path_join(type).path_join(abi).path_join(filename);
 			String dst_path = base.path_join(type).path_join(abi).path_join(filename);
 			Vector<uint8_t> data = FileAccess::get_file_as_array(p_so.path);
 			Vector<uint8_t> data = FileAccess::get_file_as_array(p_so.path);
@@ -745,7 +756,7 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared
 		}
 		}
 	}
 	}
 	ERR_FAIL_COND_V_MSG(!exported, FAILED,
 	ERR_FAIL_COND_V_MSG(!exported, FAILED,
-			"Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + String(" ").join(abis));
+			"Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag:" + join_abis(abis, " ", true));
 	return OK;
 	return OK;
 }
 }
 
 
@@ -1656,11 +1667,11 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor
 	}
 	}
 }
 }
 
 
-Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) {
-	Vector<String> abis = get_abis();
-	Vector<String> enabled_abis;
+Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) {
+	Vector<ABI> abis = get_abis();
+	Vector<ABI> enabled_abis;
 	for (int i = 0; i < abis.size(); ++i) {
 	for (int i = 0; i < abis.size(); ++i) {
-		bool is_enabled = p_preset->get("architectures/" + abis[i]);
+		bool is_enabled = p_preset->get("architectures/" + abis[i].abi);
 		if (is_enabled) {
 		if (is_enabled) {
 			enabled_abis.push_back(abis[i]);
 			enabled_abis.push_back(abis[i]);
 		}
 		}
@@ -1671,9 +1682,10 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp
 void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
 void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
 	r_features->push_back("etc2");
 	r_features->push_back("etc2");
 
 
-	Vector<String> abis = get_enabled_abis(p_preset);
+	Vector<ABI> abis = get_enabled_abis(p_preset);
 	for (int i = 0; i < abis.size(); ++i) {
 	for (int i = 0; i < abis.size(); ++i) {
-		r_features->push_back(abis[i]);
+		r_features->push_back(abis[i].arch);
+		r_features->push_back(abis[i].abi);
 	}
 	}
 }
 }
 
 
@@ -1697,9 +1709,9 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
 
 
 	// Android supports multiple architectures in an app bundle, so
 	// Android supports multiple architectures in an app bundle, so
 	// we expose each option as a checkbox in the export dialog.
 	// we expose each option as a checkbox in the export dialog.
-	const Vector<String> abis = get_abis();
+	const Vector<ABI> abis = get_abis();
 	for (int i = 0; i < abis.size(); ++i) {
 	for (int i = 0; i < abis.size(); ++i) {
-		const String abi = abis[i];
+		const String abi = abis[i].abi;
 		// All Android devices supporting Vulkan run 64-bit Android,
 		// All Android devices supporting Vulkan run 64-bit Android,
 		// so there is usually no point in exporting for 32-bit Android.
 		// so there is usually no point in exporting for 32-bit Android.
 		const bool is_default = abi == "arm64-v8a";
 		const bool is_default = abi == "arm64-v8a";
@@ -2516,13 +2528,24 @@ void EditorExportPlatformAndroid::_remove_copied_libs() {
 	da->remove(GDNATIVE_LIBS_PATH);
 	da->remove(GDNATIVE_LIBS_PATH);
 }
 }
 
 
-String EditorExportPlatformAndroid::join_list(List<String> parts, const String &separator) const {
+String EditorExportPlatformAndroid::join_list(const List<String> &p_parts, const String &p_separator) {
+	String ret;
+	for (int i = 0; i < p_parts.size(); ++i) {
+		if (i > 0) {
+			ret += p_separator;
+		}
+		ret += p_parts[i];
+	}
+	return ret;
+}
+
+String EditorExportPlatformAndroid::join_abis(const Vector<EditorExportPlatformAndroid::ABI> &p_parts, const String &p_separator, bool p_use_arch) {
 	String ret;
 	String ret;
-	for (int i = 0; i < parts.size(); ++i) {
+	for (int i = 0; i < p_parts.size(); ++i) {
 		if (i > 0) {
 		if (i > 0) {
-			ret += separator;
+			ret += p_separator;
 		}
 		}
-		ret += parts[i];
+		ret += (p_use_arch) ? p_parts[i].arch : p_parts[i].abi;
 	}
 	}
 	return ret;
 	return ret;
 }
 }
@@ -2544,7 +2567,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 	bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build"));
 	bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build"));
 	bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
 	bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
 	bool apk_expansion = p_preset->get("apk_expansion/enable");
 	bool apk_expansion = p_preset->get("apk_expansion/enable");
-	Vector<String> enabled_abis = get_enabled_abis(p_preset);
+	Vector<ABI> enabled_abis = get_enabled_abis(p_preset);
 
 
 	print_verbose("Exporting for Android...");
 	print_verbose("Exporting for Android...");
 	print_verbose("- debug build: " + bool_to_string(p_debug));
 	print_verbose("- debug build: " + bool_to_string(p_debug));
@@ -2553,7 +2576,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 	print_verbose("- sign build: " + bool_to_string(should_sign));
 	print_verbose("- sign build: " + bool_to_string(should_sign));
 	print_verbose("- custom build enabled: " + bool_to_string(use_custom_build));
 	print_verbose("- custom build enabled: " + bool_to_string(use_custom_build));
 	print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion));
 	print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion));
-	print_verbose("- enabled abis: " + String(",").join(enabled_abis));
+	print_verbose("- enabled abis: " + join_abis(enabled_abis, ",", false));
 	print_verbose("- export filter: " + itos(p_preset->get_export_filter()));
 	print_verbose("- export filter: " + itos(p_preset->get_export_filter()));
 	print_verbose("- include filter: " + p_preset->get_include_filter());
 	print_verbose("- include filter: " + p_preset->get_include_filter());
 	print_verbose("- exclude filter: " + p_preset->get_exclude_filter());
 	print_verbose("- exclude filter: " + p_preset->get_exclude_filter());
@@ -2676,7 +2699,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 		if (!target_sdk_version.is_valid_int()) {
 		if (!target_sdk_version.is_valid_int()) {
 			target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
 			target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
 		}
 		}
-		String enabled_abi_string = String("|").join(enabled_abis);
+		String enabled_abi_string = join_abis(enabled_abis, "|", false);
 		String sign_flag = should_sign ? "true" : "false";
 		String sign_flag = should_sign ? "true" : "false";
 		String zipalign_flag = "true";
 		String zipalign_flag = "true";
 
 
@@ -2861,7 +2884,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 
 
 	String apk_expansion_pkey = p_preset->get("apk_expansion/public_key");
 	String apk_expansion_pkey = p_preset->get("apk_expansion/public_key");
 
 
-	Vector<String> invalid_abis(enabled_abis);
+	Vector<ABI> invalid_abis(enabled_abis);
 	while (ret == UNZ_OK) {
 	while (ret == UNZ_OK) {
 		//get filename
 		//get filename
 		unz_file_info info;
 		unz_file_info info;
@@ -2924,7 +2947,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 		if (file.ends_with(".so")) {
 		if (file.ends_with(".so")) {
 			bool enabled = false;
 			bool enabled = false;
 			for (int i = 0; i < enabled_abis.size(); ++i) {
 			for (int i = 0; i < enabled_abis.size(); ++i) {
-				if (file.begins_with("lib/" + enabled_abis[i] + "/")) {
+				if (file.begins_with("lib/" + enabled_abis[i].abi + "/")) {
 					invalid_abis.erase(enabled_abis[i]);
 					invalid_abis.erase(enabled_abis[i]);
 					enabled = true;
 					enabled = true;
 					break;
 					break;
@@ -2966,8 +2989,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 	}
 	}
 
 
 	if (!invalid_abis.is_empty()) {
 	if (!invalid_abis.is_empty()) {
-		String unsupported_arch = String(", ").join(invalid_abis);
-		add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch));
+		add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), join_abis(invalid_abis, ", ", false)));
 		CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
 		CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
 	}
 	}
 
 

+ 19 - 3
platform/android/export/export_plugin.h

@@ -99,7 +99,22 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 
 
 	static zip_fileinfo get_zip_fileinfo();
 	static zip_fileinfo get_zip_fileinfo();
 
 
-	static Vector<String> get_abis();
+	struct ABI {
+		String abi;
+		String arch;
+
+		bool operator==(const ABI &p_a) const {
+			return p_a.abi == abi;
+		}
+
+		ABI(const String &p_abi, const String &p_arch) {
+			abi = p_abi;
+			arch = p_arch;
+		}
+		ABI() {}
+	};
+
+	static Vector<ABI> get_abis();
 
 
 	/// List the gdap files in the directory specified by the p_path parameter.
 	/// List the gdap files in the directory specified by the p_path parameter.
 	static Vector<String> list_gdap_files(const String &p_path);
 	static Vector<String> list_gdap_files(const String &p_path);
@@ -152,7 +167,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 			const Ref<Image> &foreground,
 			const Ref<Image> &foreground,
 			const Ref<Image> &background);
 			const Ref<Image> &background);
 
 
-	static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset);
+	static Vector<ABI> get_enabled_abis(const Ref<EditorExportPreset> &p_preset);
 
 
 public:
 public:
 	typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
 	typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
@@ -228,7 +243,8 @@ public:
 
 
 	void _remove_copied_libs();
 	void _remove_copied_libs();
 
 
-	String join_list(List<String> parts, const String &separator) const;
+	static String join_list(const List<String> &p_parts, const String &p_separator);
+	static String join_abis(const Vector<ABI> &p_parts, const String &p_separator, bool p_use_arch);
 
 
 	virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
 	virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
 
 

+ 7 - 2
platform/android/os_android.cpp

@@ -162,11 +162,16 @@ Vector<String> OS_Android::get_granted_permissions() const {
 }
 }
 
 
 Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
 Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
-	p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW);
+	String path = p_path;
+	if (!FileAccess::exists(path)) {
+		path = p_path.get_file();
+	}
+
+	p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
 	ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
 	ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
 
 
 	if (r_resolved_path != nullptr) {
 	if (r_resolved_path != nullptr) {
-		*r_resolved_path = p_path;
+		*r_resolved_path = path;
 	}
 	}
 
 
 	return OK;
 	return OK;