diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2017-11-20 22:56:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-20 22:56:15 +0100 |
commit | 71a3e71b61690663f5bc6b1b091f578a6d6915f7 (patch) | |
tree | 380303c58fff0dd7e2e6aa4c4b192e48e4a23037 /modules | |
parent | 6065b2d1778cd5dc8c078f3b59e501fb8ccdec9f (diff) | |
parent | 8f0f327f0207cbde27bbfba3ac106b9457d7201b (diff) |
Merge pull request #11783 from endragor/ios-export-frameworks
Allow exporting third-party iOS Frameworks
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdnative/gdnative.cpp | 8 | ||||
-rw-r--r-- | modules/gdnative/gdnative.h | 2 | ||||
-rw-r--r-- | modules/gdnative/register_types.cpp | 89 | ||||
-rw-r--r-- | modules/webm/config.py | 2 |
4 files changed, 54 insertions, 47 deletions
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index f98a16a5d7..de118043ca 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -123,7 +123,7 @@ bool GDNative::initialize() { return false; } #ifdef IPHONE_ENABLED - String path = lib_path.replace("res://", "dylibs/"); + String path = ""; #else String path = ProjectSettings::get_singleton()->globalize_path(lib_path); #endif @@ -148,7 +148,7 @@ bool GDNative::initialize() { // we cheat here a little bit. you saw nothing initialized = true; - err = get_symbol(library->get_symbol_prefix() + init_symbol, library_init); + err = get_symbol(library->get_symbol_prefix() + init_symbol, library_init, false); initialized = false; @@ -280,7 +280,7 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced return *(Variant *)&result; } -Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) { +Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional) { if (!initialized) { ERR_PRINT("No valid library handle, can't get symbol from GDNative object"); @@ -291,7 +291,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) { native_handle, p_procedure_name, r_handle, - true); + p_optional); return result; } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 052ce1fef1..bb260bdd1b 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -141,7 +141,7 @@ public: Variant call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments = Array()); - Error get_symbol(StringName p_procedure_name, void *&r_handle); + Error get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional = true); }; class GDNativeLibraryResourceLoader : public ResourceFormatLoader { diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 8af643df50..34099bf528 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -123,6 +123,11 @@ protected: virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features); }; +struct LibrarySymbol { + char *name; + bool is_required; +}; + void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) { if (p_type != "GDNativeLibrary") { return; @@ -136,7 +141,6 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty Ref<ConfigFile> config = lib->get_config_file(); - String entry_lib_path; { List<String> entry_keys; @@ -161,14 +165,12 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty continue; } - entry_lib_path = config->get_value("entry", key); - break; + String entry_lib_path = config->get_value("entry", key); + add_shared_object(entry_lib_path, tags); } } - Vector<String> dependency_paths; { - List<String> dependency_keys; config->get_section_keys("dependencies", &dependency_keys); @@ -191,47 +193,54 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty continue; } - dependency_paths = config->get_value("dependencies", key); - break; + Vector<String> dependency_paths = config->get_value("dependencies", key); + for (int i = 0; i < dependency_paths.size(); i++) { + add_shared_object(dependency_paths[i], tags); + } } } - bool is_statically_linked = false; - { - - List<String> static_linking_keys; - config->get_section_keys("static_linking", &static_linking_keys); - - for (List<String>::Element *E = static_linking_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - - for (int i = 0; i < tags.size(); i++) { - bool has_feature = p_features.has(tags[i]); - - if (!has_feature) { - skip = true; - break; + if (p_features.has("iOS")) { + // Register symbols in the "fake" dynamic lookup table, because dlsym does not work well on iOS. + LibrarySymbol expected_symbols[] = { + { "gdnative_init", true }, + { "gdnative_terminate", false }, + { "nativescript_init", false }, + { "nativescript_frame", false }, + { "nativescript_thread_enter", false }, + { "nativescript_thread_exit", false }, + { "gdnative_singleton", false } + }; + String declare_pattern = "extern \"C\" void $name(void)$weak;\n"; + String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n" + "extern void add_ios_init_callback(void (*cb)());\n"; + String linker_flags = ""; + for (int i = 0; i < sizeof(expected_symbols) / sizeof(expected_symbols[0]); ++i) { + String full_name = lib->get_symbol_prefix() + expected_symbols[i].name; + String code = declare_pattern.replace("$name", full_name); + code = code.replace("$weak", expected_symbols[i].is_required ? "" : " __attribute__((weak))"); + additional_code += code; + + if (!expected_symbols[i].is_required) { + if (linker_flags.length() > 0) { + linker_flags += " "; } + linker_flags += "-Wl,-U,_" + full_name; } - - if (skip) { - continue; - } - - is_statically_linked = config->get_value("static_linking", key); - break; } - } - if (!is_statically_linked) - add_shared_object(entry_lib_path); + additional_code += String("void $prefixinit() {\n").replace("$prefix", lib->get_symbol_prefix()); + String register_pattern = " if (&$name) register_dynamic_symbol((char *)\"$name\", (void *)$name);\n"; + for (int i = 0; i < sizeof(expected_symbols) / sizeof(expected_symbols[0]); ++i) { + String full_name = lib->get_symbol_prefix() + expected_symbols[i].name; + additional_code += register_pattern.replace("$name", full_name); + } + additional_code += "}\n"; + additional_code += String("struct $prefixstruct {$prefixstruct() {add_ios_init_callback($prefixinit);}};\n").replace("$prefix", lib->get_symbol_prefix()); + additional_code += String("$prefixstruct $prefixstruct_instance;\n").replace("$prefix", lib->get_symbol_prefix()); - for (int i = 0; i < dependency_paths.size(); i++) { - add_shared_object(dependency_paths[i]); + add_ios_cpp_code(additional_code); + add_ios_linker_flags(linker_flags); } } @@ -271,9 +280,7 @@ void register_gdnative_types() { #ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint()) { - EditorNode::add_init_callback(editor_init_callback); - } + EditorNode::add_init_callback(editor_init_callback); #endif ClassDB::register_class<GDNativeLibrary>(); diff --git a/modules/webm/config.py b/modules/webm/config.py index 0374bb36f7..dcae4447d5 100644 --- a/modules/webm/config.py +++ b/modules/webm/config.py @@ -1,5 +1,5 @@ def can_build(platform): - return True + return platform != 'iphone' def configure(env): pass |