summaryrefslogtreecommitdiffstats
path: root/core/extension
diff options
context:
space:
mode:
authorFredia Huya-Kouadio <fhuyakou@gmail.com>2024-02-13 14:26:05 -0800
committerFredia Huya-Kouadio <fhuyakou@gmail.com>2024-04-19 07:55:08 -0700
commitede88cf59d20da54042f16df3fe6ab1aca760d64 (patch)
tree2f9ffd406178cf69ea88946c0eb50fa156af9ae9 /core/extension
parent4a0160241fd0c1e874e297f6b08676cf0761e5e8 (diff)
downloadredot-engine-ede88cf59d20da54042f16df3fe6ab1aca760d64.tar.gz
Fix loading GDExtension dependencies on Android
Diffstat (limited to 'core/extension')
-rw-r--r--core/extension/gdextension.cpp50
-rw-r--r--core/extension/gdextension.h4
2 files changed, 50 insertions, 4 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 546c40e9cb..1735ee51a4 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -46,6 +46,41 @@ String GDExtension::get_extension_list_config_file() {
return ProjectSettings::get_singleton()->get_project_data_path().path_join("extension_list.cfg");
}
+Vector<SharedObject> GDExtension::find_extension_dependencies(const String &p_path, Ref<ConfigFile> p_config, std::function<bool(String)> p_has_feature) {
+ Vector<SharedObject> dependencies_shared_objects;
+ if (p_config->has_section("dependencies")) {
+ List<String> config_dependencies;
+ p_config->get_section_keys("dependencies", &config_dependencies);
+
+ for (const String &dependency : config_dependencies) {
+ Vector<String> dependency_tags = dependency.split(".");
+ bool all_tags_met = true;
+ for (int i = 0; i < dependency_tags.size(); i++) {
+ String tag = dependency_tags[i].strip_edges();
+ if (!p_has_feature(tag)) {
+ all_tags_met = false;
+ break;
+ }
+ }
+
+ if (all_tags_met) {
+ Dictionary dependency_value = p_config->get_value("dependencies", dependency);
+ for (const Variant *key = dependency_value.next(nullptr); key; key = dependency_value.next(key)) {
+ String dependency_path = *key;
+ String target_path = dependency_value[*key];
+ if (dependency_path.is_relative_path()) {
+ dependency_path = p_path.get_base_dir().path_join(dependency_path);
+ }
+ dependencies_shared_objects.push_back(SharedObject(dependency_path, dependency_tags, target_path));
+ }
+ break;
+ }
+ }
+ }
+
+ return dependencies_shared_objects;
+}
+
String GDExtension::find_extension_library(const String &p_path, Ref<ConfigFile> p_config, std::function<bool(String)> p_has_feature, PackedStringArray *r_tags) {
// First, check the explicit libraries.
if (p_config->has_section("libraries")) {
@@ -727,10 +762,18 @@ GDExtensionInterfaceFunctionPtr GDExtension::get_interface_function(const String
return *function;
}
-Error GDExtension::open_library(const String &p_path, const String &p_entry_symbol) {
+Error GDExtension::open_library(const String &p_path, const String &p_entry_symbol, Vector<SharedObject> *p_dependencies) {
String abs_path = ProjectSettings::get_singleton()->globalize_path(p_path);
+
+ Vector<String> abs_dependencies_paths;
+ if (p_dependencies != nullptr && !p_dependencies->is_empty()) {
+ for (const SharedObject &dependency : *p_dependencies) {
+ abs_dependencies_paths.push_back(ProjectSettings::get_singleton()->globalize_path(dependency.path));
+ }
+ }
+
String actual_lib_path;
- Error err = OS::get_singleton()->open_dynamic_library(abs_path, library, true, &actual_lib_path, Engine::get_singleton()->is_editor_hint());
+ Error err = OS::get_singleton()->open_dynamic_library(abs_path, library, true, &actual_lib_path, Engine::get_singleton()->is_editor_hint(), &abs_dependencies_paths);
if (actual_lib_path.get_file() != abs_path.get_file()) {
// If temporary files are generated, let's change the library path to point at the original,
@@ -970,7 +1013,8 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path,
FileAccess::get_modified_time(library_path));
#endif
- err = p_extension->open_library(is_static_library ? String() : library_path, entry_symbol);
+ Vector<SharedObject> library_dependencies = GDExtension::find_extension_dependencies(p_path, config, [](const String &p_feature) { return OS::get_singleton()->has_feature(p_feature); });
+ err = p_extension->open_library(is_static_library ? String() : library_path, entry_symbol, &library_dependencies);
if (err != OK) {
// Unreference the extension so that this loading can be considered a failure.
p_extension.unref();
diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h
index 1f48edecf7..23b1f51208 100644
--- a/core/extension/gdextension.h
+++ b/core/extension/gdextension.h
@@ -37,6 +37,7 @@
#include "core/io/config_file.h"
#include "core/io/resource_loader.h"
#include "core/object/ref_counted.h"
+#include "core/os/shared_object.h"
class GDExtensionMethodBind;
@@ -123,8 +124,9 @@ public:
static String get_extension_list_config_file();
static String find_extension_library(const String &p_path, Ref<ConfigFile> p_config, std::function<bool(String)> p_has_feature, PackedStringArray *r_tags = nullptr);
+ static Vector<SharedObject> find_extension_dependencies(const String &p_path, Ref<ConfigFile> p_config, std::function<bool(String)> p_has_feature);
- Error open_library(const String &p_path, const String &p_entry_symbol);
+ Error open_library(const String &p_path, const String &p_entry_symbol, Vector<SharedObject> *p_dependencies = nullptr);
void close_library();
enum InitializationLevel {