iOS: Fix loading of xcframework dynamic libraries.

The logic used to determine whether to invoke the in-memory registration or to
delegate the loading of a library is incorrect for xcframework packages - as
these can contain either static or dynamic libraries.

This change instead lets the operating system handle the library request, and if
it fails, it attempts to load from the internal registry.

With this change, xcframeworks containing dynamic libraries work without
workarounds on iOS.

With an additional fallback case courtesy of @bruvzg

This fixes https://github.com/godotengine/godot/issues/112783
This commit is contained in:
Miguel de Icaza
2025-11-14 15:56:11 -05:00
parent bd2ca13c6f
commit b1465d6af0
3 changed files with 20 additions and 7 deletions

View File

@ -279,6 +279,11 @@ Error OS_AppleEmbedded::open_dynamic_library(const String &p_path, void *&p_libr
path = get_framework_executable(get_executable_path().get_base_dir().path_join(p_path.get_file().get_basename() + ".framework"));
}
if (!FileAccess::exists(path)) {
// Load .dylib from within the executable path.
path = get_framework_executable(get_executable_path().get_base_dir().path_join(p_path.get_file().get_basename() + ".dylib"));
}
if (!FileAccess::exists(path)) {
// Load .dylib or framework from a standard iOS location.
path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file()));
@ -289,8 +294,16 @@ Error OS_AppleEmbedded::open_dynamic_library(const String &p_path, void *&p_libr
path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file().get_basename() + ".framework"));
}
ERR_FAIL_COND_V(!FileAccess::exists(path), ERR_FILE_NOT_FOUND);
if (!FileAccess::exists(path)) {
// Load .dylib from a standard iOS location.
path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file().get_basename() + ".dylib"));
}
if (!FileAccess::exists(path) && (p_path.ends_with(".a") || p_path.ends_with(".xcframework"))) {
path = String(); // Try loading static library.
} else {
ERR_FAIL_COND_V(!FileAccess::exists(path), ERR_FILE_NOT_FOUND);
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", p_path, dlerror()));