diff --git a/editor/export/editor_export_platform_apple_embedded.cpp b/editor/export/editor_export_platform_apple_embedded.cpp index 807962f66b27..f3619418e258 100644 --- a/editor/export/editor_export_platform_apple_embedded.cpp +++ b/editor/export/editor_export_platform_apple_embedded.cpp @@ -416,6 +416,12 @@ String EditorExportPlatformAppleEmbedded::_process_config_file_line(const Ref unique_packages; + for (int i = 0; i < enabled_plugins.size(); i++) { + for (const PluginConfigAppleEmbedded::SPMPackage &package : enabled_plugins[i].spm_packages) { + if (!unique_packages.has(package.url)) { + unique_packages[package.url] = package; + } else { + for (const String &product : package.products) { + if (unique_packages[package.url].products.find(product) == -1) { + unique_packages[package.url].products.push_back(product); + } + } + } + } + } + + Vector sorted_package_urls; + for (const KeyValue &E : unique_packages) { + sorted_package_urls.push_back(E.key); + } + sorted_package_urls.sort(); + + for (const String &url : sorted_package_urls) { + const PluginConfigAppleEmbedded::SPMPackage &package = unique_packages[url]; + String package_id = (++pbx_id).str(); + String package_name = package.url.get_file().get_basename(); + + p_config_data.spm_packages += vformat("\t\t\t\t%s /* %s */,\n", package_id, package_name); + + p_config_data.spm_package_refs += vformat("\t\t%s /* %s */ = {\n", package_id, package_name); + p_config_data.spm_package_refs += "\t\t\tisa = XCRemoteSwiftPackageReference;\n"; + p_config_data.spm_package_refs += vformat("\t\t\trepositoryURL = \"%s\";\n", package.url); + p_config_data.spm_package_refs += "\t\t\trequirement = {\n"; + p_config_data.spm_package_refs += "\t\t\t\tkind = exactVersion;\n"; + p_config_data.spm_package_refs += vformat("\t\t\t\tversion = %s;\n", package.version); + p_config_data.spm_package_refs += "\t\t\t};\n"; + p_config_data.spm_package_refs += "\t\t};\n"; + + for (const String &product : package.products) { + String product_id = (++pbx_id).str(); + String build_file_id = (++pbx_id).str(); + + p_config_data.spm_package_products += vformat("\t\t%s /* %s */ = {\n", product_id, product); + p_config_data.spm_package_products += "\t\t\tisa = XCSwiftPackageProductDependency;\n"; + p_config_data.spm_package_products += vformat("\t\t\tpackage = %s /* %s */;\n", package_id, package_name); + p_config_data.spm_package_products += vformat("\t\t\tproductName = \"%s\";\n", product); + p_config_data.spm_package_products += "\t\t};\n"; + + p_config_data.modules_buildfile += vformat("\t\t%s /* %s in Frameworks */ = {isa = PBXBuildFile; productRef = %s /* %s */; };\n", build_file_id, product, product_id, product); + + p_config_data.modules_buildphase += vformat("\t\t\t\t%s /* %s in Frameworks */,\n", build_file_id, product); + } + } + } + return OK; } @@ -1819,11 +1886,14 @@ Error EditorExportPlatformAppleEmbedded::_export_project_helper(const Ref(), + "", // modules_buildfile + "", // modules_fileref + "", // modules_buildphase + "", // modules_buildgrp + "", // spm_packages + "", // spm_package_refs + "", // spm_package_products + Vector(), // capabilities }; config_data.plist_content += p_preset->get("application/additional_plist_content").operator String() + "\n"; diff --git a/editor/export/editor_export_platform_apple_embedded.h b/editor/export/editor_export_platform_apple_embedded.h index 4536ce05d434..42843c12d07a 100644 --- a/editor/export/editor_export_platform_apple_embedded.h +++ b/editor/export/editor_export_platform_apple_embedded.h @@ -143,6 +143,9 @@ class EditorExportPlatformAppleEmbedded : public EditorExportPlatform { String modules_fileref; String modules_buildphase; String modules_buildgrp; + String spm_packages; + String spm_package_refs; + String spm_package_products; Vector capabilities; }; diff --git a/editor/export/plugin_config_apple_embedded.cpp b/editor/export/plugin_config_apple_embedded.cpp index 5e9933777a9c..59851026208f 100644 --- a/editor/export/plugin_config_apple_embedded.cpp +++ b/editor/export/plugin_config_apple_embedded.cpp @@ -205,6 +205,20 @@ PluginConfigAppleEmbedded PluginConfigAppleEmbedded::load_plugin_config(Refget_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_CAPABILITIES_KEY, Vector()); plugin_config.linker_flags = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_LINKER_FLAGS, Vector()); + + Array spm_packages = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_SPM_PACKAGES_KEY, Array()); + for (int i = 0; i < spm_packages.size(); i++) { + Dictionary package_config = spm_packages[i]; + PluginConfigAppleEmbedded::SPMPackage package; + package.url = package_config.get("url", String()); + package.version = package_config.get("version", String()); + + Array products = package_config.get("products", Array()); + for (int j = 0; j < products.size(); j++) { + package.products.push_back(products[j]); + } + plugin_config.spm_packages.push_back(package); + } } if (config_file->has_section(PluginConfigAppleEmbedded::PLIST_SECTION)) { diff --git a/editor/export/plugin_config_apple_embedded.h b/editor/export/plugin_config_apple_embedded.h index eee1de83f442..7ab52319c8e1 100644 --- a/editor/export/plugin_config_apple_embedded.h +++ b/editor/export/plugin_config_apple_embedded.h @@ -44,6 +44,7 @@ The `dependencies` and fields are optional. - **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 +- **spm_packages**: array of Swift Package Manager dependencies (url, version, products). The `plist` section are optional. - **key**: key and value that would be added in Info.plist file. @@ -65,6 +66,7 @@ struct PluginConfigAppleEmbedded { 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 *DEPENDENCIES_SPM_PACKAGES_KEY = "spm_packages"; inline static const char *PLIST_SECTION = "plist"; @@ -82,6 +84,12 @@ struct PluginConfigAppleEmbedded { String value; }; + struct SPMPackage { + String url; + String version; + Vector products; + }; + // Set to true when the config file is properly loaded. bool valid_config = false; bool supports_targets = false; @@ -104,6 +112,9 @@ struct PluginConfigAppleEmbedded { Vector linker_flags; + // Optional spm_dependencies section. + Vector spm_packages; + // Optional plist section // String value is default value. // Currently supports `string`, `boolean`, `integer`, `raw`, `string_input` types diff --git a/misc/dist/apple_embedded_xcode/godot_apple_embedded.xcodeproj/project.pbxproj b/misc/dist/apple_embedded_xcode/godot_apple_embedded.xcodeproj/project.pbxproj index 10e5226dd613..6bc1b8465e4a 100644 --- a/misc/dist/apple_embedded_xcode/godot_apple_embedded.xcodeproj/project.pbxproj +++ b/misc/dist/apple_embedded_xcode/godot_apple_embedded.xcodeproj/project.pbxproj @@ -176,6 +176,9 @@ productRefGroup = D0BCFE3518AEBDA2004A7AAE /* Products */; projectDirPath = ""; projectRoot = ""; + packageReferences = ( + $spm_packages + ); targets = ( D0BCFE3318AEBDA2004A7AAE /* $binary */, ); @@ -407,6 +410,9 @@ defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ + + $spm_package_refs + $spm_package_products }; rootObject = D0BCFE2C18AEBDA2004A7AAE /* Project object */; }