feat: godot-engine-source-4.3-stable
This commit is contained in:
parent
c59a7dcade
commit
7125d019b5
11149 changed files with 5070401 additions and 0 deletions
51
engine/platform/ios/export/export.cpp
Normal file
51
engine/platform/ios/export/export.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**************************************************************************/
|
||||
/* export.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#include "export_plugin.h"
|
||||
|
||||
#include "editor/export/editor_export.h"
|
||||
|
||||
void register_ios_exporter_types() {
|
||||
GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformIOS);
|
||||
}
|
||||
|
||||
void register_ios_exporter() {
|
||||
#ifdef MACOS_ENABLED
|
||||
EDITOR_DEF("export/ios/ios_deploy", "");
|
||||
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/ios/ios_deploy", PROPERTY_HINT_GLOBAL_FILE, "*"));
|
||||
#endif
|
||||
|
||||
Ref<EditorExportPlatformIOS> platform;
|
||||
platform.instantiate();
|
||||
|
||||
EditorExport::get_singleton()->add_export_platform(platform);
|
||||
}
|
||||
37
engine/platform/ios/export/export.h
Normal file
37
engine/platform/ios/export/export.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**************************************************************************/
|
||||
/* export.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IOS_EXPORT_H
|
||||
#define IOS_EXPORT_H
|
||||
|
||||
void register_ios_exporter_types();
|
||||
void register_ios_exporter();
|
||||
|
||||
#endif // IOS_EXPORT_H
|
||||
3253
engine/platform/ios/export/export_plugin.cpp
Normal file
3253
engine/platform/ios/export/export_plugin.cpp
Normal file
File diff suppressed because it is too large
Load diff
301
engine/platform/ios/export/export_plugin.h
Normal file
301
engine/platform/ios/export/export_plugin.h
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/**************************************************************************/
|
||||
/* export_plugin.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IOS_EXPORT_PLUGIN_H
|
||||
#define IOS_EXPORT_PLUGIN_H
|
||||
|
||||
#include "godot_plugin_config.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/image_loader.h"
|
||||
#include "core/io/marshalls.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
#include "core/io/zip_io.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/templates/safe_refcount.h"
|
||||
#include "core/version.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/export/editor_export_platform.h"
|
||||
#include "main/splash.gen.h"
|
||||
#include "scene/resources/image_texture.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
// Optional environment variables for defining confidential information. If any
|
||||
// of these is set, they will override the values set in the credentials file.
|
||||
const String ENV_IOS_PROFILE_UUID_DEBUG = "GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG";
|
||||
const String ENV_IOS_PROFILE_UUID_RELEASE = "GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE";
|
||||
|
||||
class EditorExportPlatformIOS : public EditorExportPlatform {
|
||||
GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
|
||||
|
||||
Ref<ImageTexture> logo;
|
||||
Ref<ImageTexture> run_icon;
|
||||
|
||||
// Plugins
|
||||
mutable SafeFlag plugins_changed;
|
||||
SafeFlag devices_changed;
|
||||
|
||||
struct Device {
|
||||
String id;
|
||||
String name;
|
||||
bool simulator = false;
|
||||
bool wifi = false;
|
||||
bool use_ios_deploy = false;
|
||||
};
|
||||
|
||||
Vector<Device> devices;
|
||||
Mutex device_lock;
|
||||
|
||||
Mutex plugins_lock;
|
||||
mutable Vector<PluginConfigIOS> plugins;
|
||||
#ifdef MACOS_ENABLED
|
||||
Thread check_for_changes_thread;
|
||||
SafeFlag quit_request;
|
||||
SafeFlag has_runnable_preset;
|
||||
|
||||
static bool _check_xcode_install();
|
||||
static void _check_for_changes_poll_thread(void *ud);
|
||||
void _update_preset_status();
|
||||
#endif
|
||||
|
||||
typedef Error (*FileHandler)(String p_file, void *p_userdata);
|
||||
static Error _walk_dir_recursive(Ref<DirAccess> &p_da, FileHandler p_handler, void *p_userdata);
|
||||
static Error _codesign(String p_file, void *p_userdata);
|
||||
void _blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot);
|
||||
|
||||
struct IOSConfigData {
|
||||
String pkg_name;
|
||||
String binary_name;
|
||||
String plist_content;
|
||||
String architectures;
|
||||
String linker_flags;
|
||||
String cpp_code;
|
||||
String modules_buildfile;
|
||||
String modules_fileref;
|
||||
String modules_buildphase;
|
||||
String modules_buildgrp;
|
||||
Vector<String> capabilities;
|
||||
bool use_swift_runtime;
|
||||
};
|
||||
struct ExportArchitecture {
|
||||
String name;
|
||||
bool is_default = false;
|
||||
|
||||
ExportArchitecture() {}
|
||||
|
||||
ExportArchitecture(String p_name, bool p_is_default) {
|
||||
name = p_name;
|
||||
is_default = p_is_default;
|
||||
}
|
||||
};
|
||||
|
||||
struct IOSExportAsset {
|
||||
String exported_path;
|
||||
bool is_framework = false; // framework is anything linked to the binary, otherwise it's a resource
|
||||
bool should_embed = false;
|
||||
};
|
||||
|
||||
String _get_additional_plist_content();
|
||||
String _get_linker_flags();
|
||||
String _get_cpp_code();
|
||||
void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const IOSConfigData &p_config, bool p_debug);
|
||||
Error _export_loading_screen_file(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir);
|
||||
Error _export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir);
|
||||
|
||||
Vector<ExportArchitecture> _get_supported_architectures() const;
|
||||
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const;
|
||||
|
||||
bool _archive_has_arm64(const String &p_path, uint32_t *r_cputype = nullptr, uint32_t *r_cpusubtype = nullptr) const;
|
||||
int _archive_convert_to_simulator(const String &p_path) const;
|
||||
void _check_xcframework_content(const String &p_path, int &r_total_libs, int &r_static_libs, int &r_dylibs, int &r_frameworks) const;
|
||||
Error _convert_to_framework(const String &p_source, const String &p_destination, const String &p_id) const;
|
||||
|
||||
void _add_assets_to_project(const String &p_out_dir, const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets);
|
||||
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets);
|
||||
Error _copy_asset(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const String &p_asset, const String *p_custom_file_name, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets);
|
||||
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets);
|
||||
Error _export_ios_plugins(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &dest_dir, Vector<IOSExportAsset> &r_exported_assets, bool p_debug);
|
||||
|
||||
Error _export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags, bool p_simulator, bool p_oneclick);
|
||||
|
||||
bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const;
|
||||
|
||||
protected:
|
||||
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
|
||||
virtual void get_export_options(List<ExportOption> *r_options) const override;
|
||||
virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override;
|
||||
virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override;
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
virtual String get_name() const override { return "iOS"; }
|
||||
virtual String get_os_name() const override { return "iOS"; }
|
||||
virtual Ref<Texture2D> get_logo() const override { return logo; }
|
||||
virtual Ref<Texture2D> get_run_icon() const override { return run_icon; }
|
||||
|
||||
virtual int get_options_count() const override;
|
||||
virtual String get_options_tooltip() const override;
|
||||
virtual Ref<ImageTexture> get_option_icon(int p_index) const override;
|
||||
virtual String get_option_label(int p_index) const override;
|
||||
virtual String get_option_tooltip(int p_index) const override;
|
||||
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) override;
|
||||
|
||||
virtual bool poll_export() override {
|
||||
bool dc = devices_changed.is_set();
|
||||
if (dc) {
|
||||
// don't clear unless we're reporting true, to avoid race
|
||||
devices_changed.clear();
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
virtual bool should_update_export_options() override {
|
||||
bool export_options_changed = plugins_changed.is_set();
|
||||
if (export_options_changed) {
|
||||
// don't clear unless we're reporting true, to avoid race
|
||||
plugins_changed.clear();
|
||||
}
|
||||
return export_options_changed;
|
||||
}
|
||||
|
||||
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override {
|
||||
List<String> list;
|
||||
if (p_preset.is_valid()) {
|
||||
bool project_only = p_preset->get("application/export_project_only");
|
||||
if (project_only) {
|
||||
list.push_back("xcodeproj");
|
||||
} else {
|
||||
list.push_back("ipa");
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
|
||||
|
||||
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
|
||||
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;
|
||||
|
||||
virtual void get_platform_features(List<String> *r_features) const override {
|
||||
r_features->push_back("mobile");
|
||||
r_features->push_back("ios");
|
||||
}
|
||||
|
||||
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override {
|
||||
}
|
||||
|
||||
EditorExportPlatformIOS();
|
||||
~EditorExportPlatformIOS();
|
||||
|
||||
/// List the gdip files in the directory specified by the p_path parameter.
|
||||
static Vector<String> list_plugin_config_files(const String &p_path, bool p_check_directories) {
|
||||
Vector<String> dir_files;
|
||||
Ref<DirAccess> da = DirAccess::open(p_path);
|
||||
if (da.is_valid()) {
|
||||
da->list_dir_begin();
|
||||
while (true) {
|
||||
String file = da->get_next();
|
||||
if (file.is_empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (file == "." || file == "..") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (da->current_is_hidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (da->current_is_dir()) {
|
||||
if (p_check_directories) {
|
||||
Vector<String> directory_files = list_plugin_config_files(p_path.path_join(file), false);
|
||||
for (int i = 0; i < directory_files.size(); ++i) {
|
||||
dir_files.push_back(file.path_join(directory_files[i]));
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file.ends_with(PluginConfigIOS::PLUGIN_CONFIG_EXT)) {
|
||||
dir_files.push_back(file);
|
||||
}
|
||||
}
|
||||
da->list_dir_end();
|
||||
}
|
||||
|
||||
return dir_files;
|
||||
}
|
||||
|
||||
static Vector<PluginConfigIOS> get_plugins() {
|
||||
Vector<PluginConfigIOS> loaded_plugins;
|
||||
|
||||
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().path_join("ios/plugins");
|
||||
|
||||
if (DirAccess::exists(plugins_dir)) {
|
||||
Vector<String> plugins_filenames = list_plugin_config_files(plugins_dir, true);
|
||||
|
||||
if (!plugins_filenames.is_empty()) {
|
||||
Ref<ConfigFile> config_file = memnew(ConfigFile);
|
||||
for (int i = 0; i < plugins_filenames.size(); i++) {
|
||||
PluginConfigIOS config = PluginConfigIOS::load_plugin_config(config_file, plugins_dir.path_join(plugins_filenames[i]));
|
||||
if (config.valid_config) {
|
||||
loaded_plugins.push_back(config);
|
||||
} else {
|
||||
print_error("Invalid plugin config file " + plugins_filenames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return loaded_plugins;
|
||||
}
|
||||
|
||||
static Vector<PluginConfigIOS> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
|
||||
Vector<PluginConfigIOS> enabled_plugins;
|
||||
Vector<PluginConfigIOS> all_plugins = get_plugins();
|
||||
for (int i = 0; i < all_plugins.size(); i++) {
|
||||
PluginConfigIOS plugin = all_plugins[i];
|
||||
bool enabled = p_presets->get("plugins/" + plugin.name);
|
||||
if (enabled) {
|
||||
enabled_plugins.push_back(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
return enabled_plugins;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // IOS_EXPORT_PLUGIN_H
|
||||
286
engine/platform/ios/export/godot_plugin_config.cpp
Normal file
286
engine/platform/ios/export/godot_plugin_config.cpp
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/**************************************************************************/
|
||||
/* godot_plugin_config.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "godot_plugin_config.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
String PluginConfigIOS::resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
|
||||
String absolute_path;
|
||||
|
||||
if (dependency_path.is_empty()) {
|
||||
return absolute_path;
|
||||
}
|
||||
|
||||
if (dependency_path.is_absolute_path()) {
|
||||
return dependency_path;
|
||||
}
|
||||
|
||||
String res_path = ProjectSettings::get_singleton()->globalize_path("res://");
|
||||
absolute_path = plugin_config_dir.path_join(dependency_path);
|
||||
|
||||
return absolute_path.replace(res_path, "res://");
|
||||
}
|
||||
|
||||
String PluginConfigIOS::resolve_system_dependency_path(String dependency_path) {
|
||||
String absolute_path;
|
||||
|
||||
if (dependency_path.is_empty()) {
|
||||
return absolute_path;
|
||||
}
|
||||
|
||||
if (dependency_path.is_absolute_path()) {
|
||||
return dependency_path;
|
||||
}
|
||||
|
||||
String system_path = "/System/Library/Frameworks";
|
||||
|
||||
return system_path.path_join(dependency_path);
|
||||
}
|
||||
|
||||
Vector<String> PluginConfigIOS::resolve_local_dependencies(String plugin_config_dir, Vector<String> p_paths) {
|
||||
Vector<String> paths;
|
||||
|
||||
for (int i = 0; i < p_paths.size(); i++) {
|
||||
String path = resolve_local_dependency_path(plugin_config_dir, p_paths[i]);
|
||||
|
||||
if (path.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
paths.push_back(path);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
Vector<String> PluginConfigIOS::resolve_system_dependencies(Vector<String> p_paths) {
|
||||
Vector<String> paths;
|
||||
|
||||
for (int i = 0; i < p_paths.size(); i++) {
|
||||
String path = resolve_system_dependency_path(p_paths[i]);
|
||||
|
||||
if (path.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
paths.push_back(path);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
bool PluginConfigIOS::validate_plugin(PluginConfigIOS &plugin_config) {
|
||||
bool valid_name = !plugin_config.name.is_empty();
|
||||
bool valid_binary_name = !plugin_config.binary.is_empty();
|
||||
bool valid_initialize = !plugin_config.initialization_method.is_empty();
|
||||
bool valid_deinitialize = !plugin_config.deinitialization_method.is_empty();
|
||||
|
||||
bool fields_value = valid_name && valid_binary_name && valid_initialize && valid_deinitialize;
|
||||
|
||||
if (!fields_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String plugin_extension = plugin_config.binary.get_extension().to_lower();
|
||||
|
||||
if ((plugin_extension == "a" && FileAccess::exists(plugin_config.binary)) ||
|
||||
(plugin_extension == "xcframework" && DirAccess::exists(plugin_config.binary))) {
|
||||
plugin_config.valid_config = true;
|
||||
plugin_config.supports_targets = false;
|
||||
} else {
|
||||
String file_path = plugin_config.binary.get_base_dir();
|
||||
String file_name = plugin_config.binary.get_basename().get_file();
|
||||
String file_extension = plugin_config.binary.get_extension();
|
||||
String release_file_name = file_path.path_join(file_name + ".release." + file_extension);
|
||||
String debug_file_name = file_path.path_join(file_name + ".debug." + file_extension);
|
||||
|
||||
if ((plugin_extension == "a" && FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) ||
|
||||
(plugin_extension == "xcframework" && DirAccess::exists(release_file_name) && DirAccess::exists(debug_file_name))) {
|
||||
plugin_config.valid_config = true;
|
||||
plugin_config.supports_targets = true;
|
||||
}
|
||||
}
|
||||
|
||||
return plugin_config.valid_config;
|
||||
}
|
||||
|
||||
String PluginConfigIOS::get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug) {
|
||||
if (!plugin_config.supports_targets) {
|
||||
return plugin_config.binary;
|
||||
}
|
||||
|
||||
String plugin_binary_dir = plugin_config.binary.get_base_dir();
|
||||
String plugin_name_prefix = plugin_config.binary.get_basename().get_file();
|
||||
String plugin_extension = plugin_config.binary.get_extension();
|
||||
String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + "." + plugin_extension;
|
||||
|
||||
return plugin_binary_dir.path_join(plugin_file);
|
||||
}
|
||||
|
||||
uint64_t PluginConfigIOS::get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path) {
|
||||
uint64_t last_updated = FileAccess::get_modified_time(config_path);
|
||||
|
||||
if (!plugin_config.supports_targets) {
|
||||
last_updated = MAX(last_updated, FileAccess::get_modified_time(plugin_config.binary));
|
||||
} else {
|
||||
String file_path = plugin_config.binary.get_base_dir();
|
||||
String file_name = plugin_config.binary.get_basename().get_file();
|
||||
String plugin_extension = plugin_config.binary.get_extension();
|
||||
String release_file_name = file_path.path_join(file_name + ".release." + plugin_extension);
|
||||
String debug_file_name = file_path.path_join(file_name + ".debug." + plugin_extension);
|
||||
|
||||
last_updated = MAX(last_updated, FileAccess::get_modified_time(release_file_name));
|
||||
last_updated = MAX(last_updated, FileAccess::get_modified_time(debug_file_name));
|
||||
}
|
||||
|
||||
return last_updated;
|
||||
}
|
||||
|
||||
PluginConfigIOS PluginConfigIOS::load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
|
||||
PluginConfigIOS plugin_config = {};
|
||||
|
||||
if (!config_file.is_valid()) {
|
||||
return plugin_config;
|
||||
}
|
||||
|
||||
config_file->clear();
|
||||
|
||||
Error err = config_file->load(path);
|
||||
|
||||
if (err != OK) {
|
||||
return plugin_config;
|
||||
}
|
||||
|
||||
String config_base_dir = path.get_base_dir();
|
||||
|
||||
plugin_config.name = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_NAME_KEY, String());
|
||||
plugin_config.use_swift_runtime = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_USE_SWIFT_KEY, false);
|
||||
plugin_config.initialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_INITIALIZE_KEY, String());
|
||||
plugin_config.deinitialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_DEINITIALIZE_KEY, String());
|
||||
|
||||
String binary_path = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_BINARY_KEY, String());
|
||||
plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path);
|
||||
|
||||
if (config_file->has_section(PluginConfigIOS::DEPENDENCIES_SECTION)) {
|
||||
Vector<String> linked_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKED_KEY, Vector<String>());
|
||||
Vector<String> embedded_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
|
||||
Vector<String> system_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_SYSTEM_KEY, Vector<String>());
|
||||
Vector<String> files = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_FILES_KEY, Vector<String>());
|
||||
|
||||
plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies);
|
||||
plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies);
|
||||
plugin_config.system_dependencies = resolve_system_dependencies(system_dependencies);
|
||||
|
||||
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);
|
||||
|
||||
plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
|
||||
|
||||
plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
|
||||
}
|
||||
|
||||
if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) {
|
||||
List<String> keys;
|
||||
config_file->get_section_keys(PluginConfigIOS::PLIST_SECTION, &keys);
|
||||
|
||||
for (const String &key : keys) {
|
||||
Vector<String> key_components = key.split(":");
|
||||
|
||||
String key_value = "";
|
||||
PluginConfigIOS::PlistItemType key_type = PluginConfigIOS::PlistItemType::UNKNOWN;
|
||||
|
||||
if (key_components.size() == 1) {
|
||||
key_value = key_components[0];
|
||||
key_type = PluginConfigIOS::PlistItemType::STRING;
|
||||
} else if (key_components.size() == 2) {
|
||||
key_value = key_components[0];
|
||||
|
||||
if (key_components[1].to_lower() == "string") {
|
||||
key_type = PluginConfigIOS::PlistItemType::STRING;
|
||||
} else if (key_components[1].to_lower() == "integer") {
|
||||
key_type = PluginConfigIOS::PlistItemType::INTEGER;
|
||||
} else if (key_components[1].to_lower() == "boolean") {
|
||||
key_type = PluginConfigIOS::PlistItemType::BOOLEAN;
|
||||
} else if (key_components[1].to_lower() == "raw") {
|
||||
key_type = PluginConfigIOS::PlistItemType::RAW;
|
||||
} else if (key_components[1].to_lower() == "string_input") {
|
||||
key_type = PluginConfigIOS::PlistItemType::STRING_INPUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (key_value.is_empty() || key_type == PluginConfigIOS::PlistItemType::UNKNOWN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value;
|
||||
|
||||
switch (key_type) {
|
||||
case PluginConfigIOS::PlistItemType::STRING: {
|
||||
String raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, String());
|
||||
value = "<string>" + raw_value + "</string>";
|
||||
} break;
|
||||
case PluginConfigIOS::PlistItemType::INTEGER: {
|
||||
int raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, 0);
|
||||
Dictionary value_dictionary;
|
||||
String value_format = "<integer>$value</integer>";
|
||||
value_dictionary["value"] = raw_value;
|
||||
value = value_format.format(value_dictionary, "$_");
|
||||
} break;
|
||||
case PluginConfigIOS::PlistItemType::BOOLEAN:
|
||||
if (config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, false)) {
|
||||
value = "<true/>";
|
||||
} else {
|
||||
value = "<false/>";
|
||||
}
|
||||
break;
|
||||
case PluginConfigIOS::PlistItemType::RAW: {
|
||||
String raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, String());
|
||||
value = raw_value;
|
||||
} break;
|
||||
case PluginConfigIOS::PlistItemType::STRING_INPUT: {
|
||||
String raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, String());
|
||||
value = raw_value;
|
||||
} break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
plugin_config.plist[key_value] = PluginConfigIOS::PlistItem{ key_type, value };
|
||||
}
|
||||
}
|
||||
|
||||
if (validate_plugin(plugin_config)) {
|
||||
plugin_config.last_updated = get_plugin_modification_time(plugin_config, path);
|
||||
}
|
||||
|
||||
return plugin_config;
|
||||
}
|
||||
135
engine/platform/ios/export/godot_plugin_config.h
Normal file
135
engine/platform/ios/export/godot_plugin_config.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/**************************************************************************/
|
||||
/* godot_plugin_config.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IOS_GODOT_PLUGIN_CONFIG_H
|
||||
#define IOS_GODOT_PLUGIN_CONFIG_H
|
||||
|
||||
#include "core/error/error_list.h"
|
||||
#include "core/io/config_file.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
/*
|
||||
The `config` section and fields are required and defined as follow:
|
||||
- **name**: name of the plugin
|
||||
- **binary**: path to static `.a` library
|
||||
- **use_swift_runtime**: optional boolean field used to determine if Swift runtime is used
|
||||
|
||||
The `dependencies` and fields are optional.
|
||||
- **linked**: dependencies that should only be linked.
|
||||
- **embedded**: dependencies that should be linked and embedded into application.
|
||||
- **system**: system dependencies that should be linked.
|
||||
- **capabilities**: capabilities that would be used for `UIRequiredDeviceCapabilities` options in Info.plist file.
|
||||
- **files**: files that would be copied into application
|
||||
|
||||
The `plist` section are optional.
|
||||
- **key**: key and value that would be added in Info.plist file.
|
||||
*/
|
||||
|
||||
struct PluginConfigIOS {
|
||||
inline static const char *PLUGIN_CONFIG_EXT = ".gdip";
|
||||
|
||||
inline static const char *CONFIG_SECTION = "config";
|
||||
inline static const char *CONFIG_NAME_KEY = "name";
|
||||
inline static const char *CONFIG_BINARY_KEY = "binary";
|
||||
inline static const char *CONFIG_USE_SWIFT_KEY = "use_swift_runtime";
|
||||
inline static const char *CONFIG_INITIALIZE_KEY = "initialization";
|
||||
inline static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization";
|
||||
|
||||
inline static const char *DEPENDENCIES_SECTION = "dependencies";
|
||||
inline static const char *DEPENDENCIES_LINKED_KEY = "linked";
|
||||
inline static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded";
|
||||
inline static const char *DEPENDENCIES_SYSTEM_KEY = "system";
|
||||
inline static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
|
||||
inline static const char *DEPENDENCIES_FILES_KEY = "files";
|
||||
inline static const char *DEPENDENCIES_LINKER_FLAGS = "linker_flags";
|
||||
|
||||
inline static const char *PLIST_SECTION = "plist";
|
||||
|
||||
enum PlistItemType {
|
||||
UNKNOWN,
|
||||
STRING,
|
||||
INTEGER,
|
||||
BOOLEAN,
|
||||
RAW,
|
||||
STRING_INPUT,
|
||||
};
|
||||
|
||||
struct PlistItem {
|
||||
PlistItemType type;
|
||||
String value;
|
||||
};
|
||||
|
||||
// Set to true when the config file is properly loaded.
|
||||
bool valid_config = false;
|
||||
bool supports_targets = false;
|
||||
// Unix timestamp of last change to this plugin.
|
||||
uint64_t last_updated = 0;
|
||||
|
||||
// Required config section
|
||||
String name;
|
||||
String binary;
|
||||
bool use_swift_runtime;
|
||||
String initialization_method;
|
||||
String deinitialization_method;
|
||||
|
||||
// Optional dependencies section
|
||||
Vector<String> linked_dependencies;
|
||||
Vector<String> embedded_dependencies;
|
||||
Vector<String> system_dependencies;
|
||||
|
||||
Vector<String> files_to_copy;
|
||||
Vector<String> capabilities;
|
||||
|
||||
Vector<String> linker_flags;
|
||||
|
||||
// Optional plist section
|
||||
// String value is default value.
|
||||
// Currently supports `string`, `boolean`, `integer`, `raw`, `string_input` types
|
||||
// <name>:<type> = <value>
|
||||
HashMap<String, PlistItem> plist;
|
||||
|
||||
static String resolve_local_dependency_path(String plugin_config_dir, String dependency_path);
|
||||
|
||||
static String resolve_system_dependency_path(String dependency_path);
|
||||
|
||||
static Vector<String> resolve_local_dependencies(String plugin_config_dir, Vector<String> p_paths);
|
||||
|
||||
static Vector<String> resolve_system_dependencies(Vector<String> p_paths);
|
||||
|
||||
static bool validate_plugin(PluginConfigIOS &plugin_config);
|
||||
|
||||
static String get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug);
|
||||
|
||||
static uint64_t get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path);
|
||||
|
||||
static PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path);
|
||||
};
|
||||
|
||||
#endif // IOS_GODOT_PLUGIN_CONFIG_H
|
||||
1
engine/platform/ios/export/logo.svg
Normal file
1
engine/platform/ios/export/logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path fill="#bfbfbf" d="M1 23.27h2.504V12.61H1zm1.247-12.057c.784 0 1.398-.603 1.398-1.358 0-.764-.614-1.367-1.398-1.367-.774 0-1.388.603-1.388 1.367 0 .755.614 1.358 1.388 1.358zm9.594-2.695c-4.233 0-6.888 2.886-6.888 7.502s2.654 7.492 6.888 7.492c4.224 0 6.88-2.876 6.88-7.492s-2.656-7.502-6.88-7.502zm0 2.212c2.585 0 4.234 2.052 4.234 5.29 0 3.228-1.649 5.28-4.234 5.28-2.594 0-4.233-2.052-4.233-5.28 0-3.238 1.639-5.29 4.233-5.29zm7.936 8.458c.11 2.675 2.303 4.324 5.641 4.324 3.51 0 5.723-1.73 5.723-4.485 0-2.162-1.247-3.379-4.194-4.053l-1.67-.382c-1.78-.422-2.513-.985-2.513-1.95 0-1.208 1.106-2.012 2.745-2.012 1.66 0 2.796.814 2.916 2.172H30.9c-.06-2.554-2.172-4.284-5.37-4.284-3.158 0-5.4 1.74-5.4 4.314 0 2.072 1.267 3.36 3.942 3.973l1.88.442c1.83.433 2.575 1.036 2.575 2.082 0 1.207-1.217 2.072-2.967 2.072-1.77 0-3.107-.875-3.268-2.213h-2.514z"/></svg>
|
||||
|
After Width: | Height: | Size: 928 B |
1
engine/platform/ios/export/run_icon.svg
Normal file
1
engine/platform/ios/export/run_icon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#fff" d="M.462 11.653H1.72V6.296H.462Zm.627-6.059a.687.687 0 0 0 .702-.682.688.688 0 0 0-.702-.687.687.687 0 0 0-.698.687c0 .38.309.682.698.682zM5.91 4.24c-2.127 0-3.461 1.45-3.461 3.77 0 2.32 1.333 3.765 3.461 3.765 2.123 0 3.457-1.445 3.457-3.765 0-2.32-1.334-3.77-3.457-3.77zm0 1.112c1.299 0 2.128 1.03 2.128 2.658 0 1.622-.829 2.653-2.128 2.653-1.304 0-2.127-1.03-2.127-2.653 0-1.627.823-2.658 2.127-2.658zm3.988 4.25c.055 1.344 1.157 2.173 2.835 2.173 1.764 0 2.876-.87 2.876-2.254 0-1.086-.627-1.698-2.108-2.037l-.839-.192c-.895-.212-1.263-.495-1.263-.98 0-.607.556-1.01 1.38-1.01.834 0 1.405.408 1.465 1.09h1.244c-.03-1.283-1.092-2.152-2.699-2.152-1.587 0-2.714.874-2.714 2.168 0 1.041.637 1.688 1.981 1.997l.945.222c.92.217 1.294.52 1.294 1.046 0 .606-.611 1.041-1.49 1.041-.89 0-1.562-.44-1.643-1.112H9.899Z"/></svg>
|
||||
|
After Width: | Height: | Size: 900 B |
Loading…
Add table
Add a link
Reference in a new issue