You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-17 14:11:06 +00:00
[iOS export] Improve .xcframework exporting.
Do not embed static .xcframeworks. Automatically convert .xcframeworks with .dylibs to .xcframeworks with .frameworks.
This commit is contained in:
@@ -868,7 +868,183 @@ struct ExportLibsData {
|
|||||||
String dest_dir;
|
String dest_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets) {
|
void EditorExportPlatformIOS::_check_xcframework_content(const String &p_path, int &r_total_libs, int &r_static_libs, int &r_dylibs, int &r_frameworks) const {
|
||||||
|
Ref<PList> plist;
|
||||||
|
plist.instantiate();
|
||||||
|
plist->load_file(p_path.path_join("Info.plist"));
|
||||||
|
Ref<PListNode> root_node = plist->get_root();
|
||||||
|
if (root_node.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Dictionary root = root_node->get_value();
|
||||||
|
if (!root.has("AvailableLibraries")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ref<PListNode> libs_node = root["AvailableLibraries"];
|
||||||
|
if (libs_node.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Array libs = libs_node->get_value();
|
||||||
|
r_total_libs = libs.size();
|
||||||
|
for (int j = 0; j < libs.size(); j++) {
|
||||||
|
Ref<PListNode> lib_node = libs[j];
|
||||||
|
if (lib_node.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Dictionary lib = lib_node->get_value();
|
||||||
|
if (lib.has("BinaryPath")) {
|
||||||
|
Ref<PListNode> path_node = lib["BinaryPath"];
|
||||||
|
if (path_node.is_valid()) {
|
||||||
|
String path = path_node->get_value();
|
||||||
|
if (path.ends_with(".a")) {
|
||||||
|
r_static_libs++;
|
||||||
|
}
|
||||||
|
if (path.ends_with(".dylib")) {
|
||||||
|
r_dylibs++;
|
||||||
|
}
|
||||||
|
if (path.ends_with(".framework")) {
|
||||||
|
r_frameworks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Error EditorExportPlatformIOS::_convert_to_framework(const String &p_source, const String &p_destination, const String &p_id) const {
|
||||||
|
print_line("Converting to .framework", p_source, " -> ", p_destination);
|
||||||
|
|
||||||
|
Ref<DirAccess> da = DirAccess::create_for_path(p_source);
|
||||||
|
if (da.is_null()) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<DirAccess> filesystem_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
|
if (filesystem_da.is_null()) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filesystem_da->dir_exists(p_destination)) {
|
||||||
|
Error make_dir_err = filesystem_da->make_dir_recursive(p_destination);
|
||||||
|
if (make_dir_err) {
|
||||||
|
return make_dir_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String asset = p_source.ends_with("/") ? p_source.left(p_source.length() - 1) : p_source;
|
||||||
|
if (asset.ends_with(".xcframework")) {
|
||||||
|
Ref<PList> plist;
|
||||||
|
plist.instantiate();
|
||||||
|
plist->load_file(p_source.path_join("Info.plist"));
|
||||||
|
Ref<PListNode> root_node = plist->get_root();
|
||||||
|
if (root_node.is_null()) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
Dictionary root = root_node->get_value();
|
||||||
|
if (!root.has("AvailableLibraries")) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
Ref<PListNode> libs_node = root["AvailableLibraries"];
|
||||||
|
if (libs_node.is_null()) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
Array libs = libs_node->get_value();
|
||||||
|
for (int j = 0; j < libs.size(); j++) {
|
||||||
|
Ref<PListNode> lib_node = libs[j];
|
||||||
|
if (lib_node.is_null()) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
Dictionary lib = lib_node->get_value();
|
||||||
|
if (lib.has("BinaryPath") && lib.has("LibraryPath") && lib.has("LibraryIdentifier")) {
|
||||||
|
Ref<PListNode> bpath_node = lib["BinaryPath"];
|
||||||
|
Ref<PListNode> lpath_node = lib["LibraryPath"];
|
||||||
|
Ref<PListNode> lid_node = lib["LibraryIdentifier"];
|
||||||
|
if (bpath_node.is_valid() && lpath_node.is_valid() && lid_node.is_valid()) {
|
||||||
|
String binary_path = bpath_node->get_value();
|
||||||
|
String library_identifier = lid_node->get_value();
|
||||||
|
|
||||||
|
String file_name = binary_path.get_basename().get_file();
|
||||||
|
String framework_name = file_name + ".framework";
|
||||||
|
|
||||||
|
bpath_node->data_string = framework_name.utf8();
|
||||||
|
lpath_node->data_string = framework_name.utf8();
|
||||||
|
if (!filesystem_da->dir_exists(p_destination.path_join(library_identifier))) {
|
||||||
|
filesystem_da->make_dir_recursive(p_destination.path_join(library_identifier));
|
||||||
|
}
|
||||||
|
_convert_to_framework(p_source.path_join(library_identifier).path_join(binary_path), p_destination.path_join(library_identifier).path_join(framework_name), p_id);
|
||||||
|
if (lib.has("DebugSymbolsPath")) {
|
||||||
|
Ref<PListNode> dpath_node = lib["DebugSymbolsPath"];
|
||||||
|
if (dpath_node.is_valid()) {
|
||||||
|
String dpath = dpath_node->get_value();
|
||||||
|
if (da->dir_exists(p_source.path_join(library_identifier).path_join(dpath))) {
|
||||||
|
da->copy_dir(p_source.path_join(library_identifier).path_join(dpath), p_destination.path_join(library_identifier).path_join("dSYMs"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String info_plist = plist->save_text();
|
||||||
|
|
||||||
|
Ref<FileAccess> f = FileAccess::open(p_destination.path_join("Info.plist"), FileAccess::WRITE);
|
||||||
|
if (f.is_valid()) {
|
||||||
|
f->store_string(info_plist);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String file_name = p_destination.get_basename().get_file();
|
||||||
|
String framework_name = file_name + ".framework";
|
||||||
|
|
||||||
|
da->copy(p_source, p_destination.path_join(file_name));
|
||||||
|
|
||||||
|
// Performing `install_name_tool -id @rpath/{name}.framework/{name} ./{name}` on dylib
|
||||||
|
{
|
||||||
|
List<String> install_name_args;
|
||||||
|
install_name_args.push_back("-id");
|
||||||
|
install_name_args.push_back(String("@rpath").path_join(framework_name).path_join(file_name));
|
||||||
|
install_name_args.push_back(p_destination.path_join(file_name));
|
||||||
|
|
||||||
|
OS::get_singleton()->execute("install_name_tool", install_name_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating Info.plist
|
||||||
|
{
|
||||||
|
String info_plist_format = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||||
|
"<plist version=\"1.0\">\n"
|
||||||
|
" <dict>\n"
|
||||||
|
" <key>CFBundleShortVersionString</key>\n"
|
||||||
|
" <string>1.0</string>\n"
|
||||||
|
" <key>CFBundleIdentifier</key>\n"
|
||||||
|
" <string>$id.framework.$name</string>\n"
|
||||||
|
" <key>CFBundleName</key>\n"
|
||||||
|
" <string>$name</string>\n"
|
||||||
|
" <key>CFBundleExecutable</key>\n"
|
||||||
|
" <string>$name</string>\n"
|
||||||
|
" <key>DTPlatformName</key>\n"
|
||||||
|
" <string>iphoneos</string>\n"
|
||||||
|
" <key>CFBundleInfoDictionaryVersion</key>\n"
|
||||||
|
" <string>6.0</string>\n"
|
||||||
|
" <key>CFBundleVersion</key>\n"
|
||||||
|
" <string>1</string>\n"
|
||||||
|
" <key>CFBundlePackageType</key>\n"
|
||||||
|
" <string>FMWK</string>\n"
|
||||||
|
" <key>MinimumOSVersion</key>\n"
|
||||||
|
" <string>12.0</string>\n"
|
||||||
|
" </dict>\n"
|
||||||
|
"</plist>";
|
||||||
|
|
||||||
|
String info_plist = info_plist_format.replace("$id", p_id).replace("$name", file_name);
|
||||||
|
|
||||||
|
Ref<FileAccess> f = FileAccess::open(p_destination.path_join("Info.plist"), FileAccess::WRITE);
|
||||||
|
if (f.is_valid()) {
|
||||||
|
f->store_string(info_plist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorExportPlatformIOS::_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) {
|
||||||
// that is just a random number, we just need Godot IDs not to clash with
|
// that is just a random number, we just need Godot IDs not to clash with
|
||||||
// existing IDs in the project.
|
// existing IDs in the project.
|
||||||
PbxId current_id = { 0x58938401, 0, 0 };
|
PbxId current_id = { 0x58938401, 0, 0 };
|
||||||
@@ -893,7 +1069,12 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese
|
|||||||
|
|
||||||
String type;
|
String type;
|
||||||
if (asset.exported_path.ends_with(".framework")) {
|
if (asset.exported_path.ends_with(".framework")) {
|
||||||
if (asset.should_embed) {
|
int total_libs = 0;
|
||||||
|
int static_libs = 0;
|
||||||
|
int dylibs = 0;
|
||||||
|
int frameworks = 0;
|
||||||
|
_check_xcframework_content(p_out_dir.path_join(asset.exported_path), total_libs, static_libs, dylibs, frameworks);
|
||||||
|
if (asset.should_embed && (static_libs != total_libs)) {
|
||||||
additional_asset_info_format += "$framework_id = {isa = PBXBuildFile; fileRef = $ref_id; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };\n";
|
additional_asset_info_format += "$framework_id = {isa = PBXBuildFile; fileRef = $ref_id; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };\n";
|
||||||
framework_id = (++current_id).str();
|
framework_id = (++current_id).str();
|
||||||
pbx_embeded_frameworks += framework_id + ",\n";
|
pbx_embeded_frameworks += framework_id + ",\n";
|
||||||
@@ -956,12 +1137,12 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EditorExportPlatformIOS::_copy_asset(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 EditorExportPlatformIOS::_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) {
|
||||||
String binary_name = p_out_dir.get_file().get_basename();
|
String binary_name = p_out_dir.get_file().get_basename();
|
||||||
|
|
||||||
Ref<DirAccess> da = DirAccess::create_for_path(p_asset);
|
Ref<DirAccess> da = DirAccess::create_for_path(p_asset);
|
||||||
if (da.is_null()) {
|
if (da.is_null()) {
|
||||||
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't create directory: " + p_asset + ".");
|
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't open directory: " + p_asset + ".");
|
||||||
}
|
}
|
||||||
bool file_exists = da->file_exists(p_asset);
|
bool file_exists = da->file_exists(p_asset);
|
||||||
bool dir_exists = da->dir_exists(p_asset);
|
bool dir_exists = da->dir_exists(p_asset);
|
||||||
@@ -975,7 +1156,8 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String
|
|||||||
String destination;
|
String destination;
|
||||||
String asset_path;
|
String asset_path;
|
||||||
|
|
||||||
bool create_framework = false;
|
Ref<DirAccess> filesystem_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
|
ERR_FAIL_COND_V_MSG(filesystem_da.is_null(), ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_out_dir + "'.");
|
||||||
|
|
||||||
if (p_is_framework && asset.ends_with(".dylib")) {
|
if (p_is_framework && asset.ends_with(".dylib")) {
|
||||||
// For iOS we need to turn .dylib into .framework
|
// For iOS we need to turn .dylib into .framework
|
||||||
@@ -995,8 +1177,56 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String
|
|||||||
asset_path = asset_path.path_join(framework_name);
|
asset_path = asset_path.path_join(framework_name);
|
||||||
destination_dir = p_out_dir.path_join(asset_path);
|
destination_dir = p_out_dir.path_join(asset_path);
|
||||||
destination = destination_dir.path_join(file_name);
|
destination = destination_dir.path_join(file_name);
|
||||||
create_framework = true;
|
|
||||||
} else if (p_is_framework && (asset.ends_with(".framework") || asset.ends_with(".xcframework"))) {
|
// Convert to framework and copy.
|
||||||
|
Error err = _convert_to_framework(p_asset, destination, p_preset->get("application/bundle_identifier"));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else if (p_is_framework && asset.ends_with(".xcframework")) {
|
||||||
|
// For iOS we need to turn .dylib inside .xcframework
|
||||||
|
// into .framework to be able to send application to AppStore
|
||||||
|
|
||||||
|
int total_libs = 0;
|
||||||
|
int static_libs = 0;
|
||||||
|
int dylibs = 0;
|
||||||
|
int frameworks = 0;
|
||||||
|
_check_xcframework_content(p_asset, total_libs, static_libs, dylibs, frameworks);
|
||||||
|
|
||||||
|
asset_path = String("dylibs").path_join(base_dir);
|
||||||
|
String file_name;
|
||||||
|
|
||||||
|
if (!p_custom_file_name) {
|
||||||
|
file_name = p_asset.get_file();
|
||||||
|
} else {
|
||||||
|
file_name = *p_custom_file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_path = asset_path.path_join(file_name);
|
||||||
|
destination_dir = p_out_dir.path_join(asset_path);
|
||||||
|
destination = destination_dir;
|
||||||
|
|
||||||
|
if (dylibs > 0) {
|
||||||
|
// Convert to framework and copy.
|
||||||
|
Error err = _convert_to_framework(p_asset, destination, p_preset->get("application/bundle_identifier"));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Copy as is.
|
||||||
|
if (!filesystem_da->dir_exists(destination_dir)) {
|
||||||
|
Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir);
|
||||||
|
if (make_dir_err) {
|
||||||
|
return make_dir_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Error err = dir_exists ? da->copy_dir(p_asset, destination) : da->copy(p_asset, destination);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p_is_framework && asset.ends_with(".framework")) {
|
||||||
|
// Framework.
|
||||||
asset_path = String("dylibs").path_join(base_dir);
|
asset_path = String("dylibs").path_join(base_dir);
|
||||||
|
|
||||||
String file_name;
|
String file_name;
|
||||||
@@ -1010,7 +1240,20 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String
|
|||||||
asset_path = asset_path.path_join(file_name);
|
asset_path = asset_path.path_join(file_name);
|
||||||
destination_dir = p_out_dir.path_join(asset_path);
|
destination_dir = p_out_dir.path_join(asset_path);
|
||||||
destination = destination_dir;
|
destination = destination_dir;
|
||||||
|
|
||||||
|
// Copy as is.
|
||||||
|
if (!filesystem_da->dir_exists(destination_dir)) {
|
||||||
|
Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir);
|
||||||
|
if (make_dir_err) {
|
||||||
|
return make_dir_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Error err = dir_exists ? da->copy_dir(p_asset, destination) : da->copy(p_asset, destination);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Unknown resource.
|
||||||
asset_path = base_dir;
|
asset_path = base_dir;
|
||||||
|
|
||||||
String file_name;
|
String file_name;
|
||||||
@@ -1024,96 +1267,37 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String
|
|||||||
destination_dir = p_out_dir.path_join(asset_path);
|
destination_dir = p_out_dir.path_join(asset_path);
|
||||||
asset_path = asset_path.path_join(file_name);
|
asset_path = asset_path.path_join(file_name);
|
||||||
destination = p_out_dir.path_join(asset_path);
|
destination = p_out_dir.path_join(asset_path);
|
||||||
}
|
|
||||||
|
|
||||||
Ref<DirAccess> filesystem_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
|
||||||
ERR_FAIL_COND_V_MSG(filesystem_da.is_null(), ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_out_dir + "'.");
|
|
||||||
|
|
||||||
|
// Copy as is.
|
||||||
if (!filesystem_da->dir_exists(destination_dir)) {
|
if (!filesystem_da->dir_exists(destination_dir)) {
|
||||||
Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir);
|
Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir);
|
||||||
if (make_dir_err) {
|
if (make_dir_err) {
|
||||||
return make_dir_err;
|
return make_dir_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error err = dir_exists ? da->copy_dir(p_asset, destination) : da->copy(p_asset, destination);
|
Error err = dir_exists ? da->copy_dir(p_asset, destination) : da->copy(p_asset, destination);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (asset_path.ends_with("/")) {
|
if (asset_path.ends_with("/")) {
|
||||||
asset_path = asset_path.left(asset_path.length() - 1);
|
asset_path = asset_path.left(asset_path.length() - 1);
|
||||||
}
|
}
|
||||||
IOSExportAsset exported_asset = { binary_name.path_join(asset_path), p_is_framework, p_should_embed };
|
IOSExportAsset exported_asset = { binary_name.path_join(asset_path), p_is_framework, p_should_embed };
|
||||||
r_exported_assets.push_back(exported_asset);
|
r_exported_assets.push_back(exported_asset);
|
||||||
|
|
||||||
if (create_framework) {
|
|
||||||
String file_name;
|
|
||||||
|
|
||||||
if (!p_custom_file_name) {
|
|
||||||
file_name = p_asset.get_basename().get_file();
|
|
||||||
} else {
|
|
||||||
file_name = *p_custom_file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
String framework_name = file_name + ".framework";
|
|
||||||
|
|
||||||
// Performing `install_name_tool -id @rpath/{name}.framework/{name} ./{name}` on dylib
|
|
||||||
{
|
|
||||||
List<String> install_name_args;
|
|
||||||
install_name_args.push_back("-id");
|
|
||||||
install_name_args.push_back(String("@rpath").path_join(framework_name).path_join(file_name));
|
|
||||||
install_name_args.push_back(destination);
|
|
||||||
|
|
||||||
OS::get_singleton()->execute("install_name_tool", install_name_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creating Info.plist
|
|
||||||
{
|
|
||||||
String info_plist_format = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
||||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
|
||||||
"<plist version=\"1.0\">\n"
|
|
||||||
"<dict>\n"
|
|
||||||
"<key>CFBundleShortVersionString</key>\n"
|
|
||||||
"<string>1.0</string>\n"
|
|
||||||
"<key>CFBundleIdentifier</key>\n"
|
|
||||||
"<string>com.gdextension.framework.$name</string>\n"
|
|
||||||
"<key>CFBundleName</key>\n"
|
|
||||||
"<string>$name</string>\n"
|
|
||||||
"<key>CFBundleExecutable</key>\n"
|
|
||||||
"<string>$name</string>\n"
|
|
||||||
"<key>DTPlatformName</key>\n"
|
|
||||||
"<string>iphoneos</string>\n"
|
|
||||||
"<key>CFBundleInfoDictionaryVersion</key>\n"
|
|
||||||
"<string>6.0</string>\n"
|
|
||||||
"<key>CFBundleVersion</key>\n"
|
|
||||||
"<string>1</string>\n"
|
|
||||||
"<key>CFBundlePackageType</key>\n"
|
|
||||||
"<string>FMWK</string>\n"
|
|
||||||
"<key>MinimumOSVersion</key>\n"
|
|
||||||
"<string>10.0</string>\n"
|
|
||||||
"</dict>\n"
|
|
||||||
"</plist>";
|
|
||||||
|
|
||||||
String info_plist = info_plist_format.replace("$name", file_name);
|
|
||||||
|
|
||||||
Ref<FileAccess> f = FileAccess::open(destination_dir.path_join("Info.plist"), FileAccess::WRITE);
|
|
||||||
if (f.is_valid()) {
|
|
||||||
f->store_string(info_plist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets) {
|
Error EditorExportPlatformIOS::_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) {
|
||||||
for (int f_idx = 0; f_idx < p_assets.size(); ++f_idx) {
|
for (int f_idx = 0; f_idx < p_assets.size(); ++f_idx) {
|
||||||
const String &asset = p_assets[f_idx];
|
const String &asset = p_assets[f_idx];
|
||||||
if (asset.begins_with("res://")) {
|
if (asset.begins_with("res://")) {
|
||||||
Error err = _copy_asset(p_out_dir, asset, nullptr, p_is_framework, p_should_embed, r_exported_assets);
|
Error err = _copy_asset(p_preset, p_out_dir, asset, nullptr, p_is_framework, p_should_embed, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err != OK, err);
|
ERR_FAIL_COND_V(err != OK, err);
|
||||||
} else if (ProjectSettings::get_singleton()->localize_path(asset).begins_with("res://")) {
|
} else if (ProjectSettings::get_singleton()->localize_path(asset).begins_with("res://")) {
|
||||||
Error err = _copy_asset(p_out_dir, ProjectSettings::get_singleton()->localize_path(asset), nullptr, p_is_framework, p_should_embed, r_exported_assets);
|
Error err = _copy_asset(p_preset, p_out_dir, ProjectSettings::get_singleton()->localize_path(asset), nullptr, p_is_framework, p_should_embed, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err != OK, err);
|
ERR_FAIL_COND_V(err != OK, err);
|
||||||
} else {
|
} else {
|
||||||
// either SDK-builtin or already a part of the export template
|
// either SDK-builtin or already a part of the export template
|
||||||
@@ -1125,26 +1309,26 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets) {
|
Error EditorExportPlatformIOS::_export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets) {
|
||||||
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
|
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
|
||||||
for (int i = 0; i < export_plugins.size(); i++) {
|
for (int i = 0; i < export_plugins.size(); i++) {
|
||||||
Vector<String> linked_frameworks = export_plugins[i]->get_ios_frameworks();
|
Vector<String> linked_frameworks = export_plugins[i]->get_ios_frameworks();
|
||||||
Error err = _export_additional_assets(p_out_dir, linked_frameworks, true, false, r_exported_assets);
|
Error err = _export_additional_assets(p_preset, p_out_dir, linked_frameworks, true, false, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err, err);
|
ERR_FAIL_COND_V(err, err);
|
||||||
|
|
||||||
Vector<String> embedded_frameworks = export_plugins[i]->get_ios_embedded_frameworks();
|
Vector<String> embedded_frameworks = export_plugins[i]->get_ios_embedded_frameworks();
|
||||||
err = _export_additional_assets(p_out_dir, embedded_frameworks, true, true, r_exported_assets);
|
err = _export_additional_assets(p_preset, p_out_dir, embedded_frameworks, true, true, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err, err);
|
ERR_FAIL_COND_V(err, err);
|
||||||
|
|
||||||
Vector<String> project_static_libs = export_plugins[i]->get_ios_project_static_libs();
|
Vector<String> project_static_libs = export_plugins[i]->get_ios_project_static_libs();
|
||||||
for (int j = 0; j < project_static_libs.size(); j++) {
|
for (int j = 0; j < project_static_libs.size(); j++) {
|
||||||
project_static_libs.write[j] = project_static_libs[j].get_file(); // Only the file name as it's copied to the project
|
project_static_libs.write[j] = project_static_libs[j].get_file(); // Only the file name as it's copied to the project
|
||||||
}
|
}
|
||||||
err = _export_additional_assets(p_out_dir, project_static_libs, true, false, r_exported_assets);
|
err = _export_additional_assets(p_preset, p_out_dir, project_static_libs, true, false, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err, err);
|
ERR_FAIL_COND_V(err, err);
|
||||||
|
|
||||||
Vector<String> ios_bundle_files = export_plugins[i]->get_ios_bundle_files();
|
Vector<String> ios_bundle_files = export_plugins[i]->get_ios_bundle_files();
|
||||||
err = _export_additional_assets(p_out_dir, ios_bundle_files, false, false, r_exported_assets);
|
err = _export_additional_assets(p_preset, p_out_dir, ios_bundle_files, false, false, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err, err);
|
ERR_FAIL_COND_V(err, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,7 +1336,7 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
|
|||||||
for (int i = 0; i < p_libraries.size(); ++i) {
|
for (int i = 0; i < p_libraries.size(); ++i) {
|
||||||
library_paths.push_back(p_libraries[i].path);
|
library_paths.push_back(p_libraries[i].path);
|
||||||
}
|
}
|
||||||
Error err = _export_additional_assets(p_out_dir, library_paths, true, true, r_exported_assets);
|
Error err = _export_additional_assets(p_preset, p_out_dir, library_paths, true, true, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err, err);
|
ERR_FAIL_COND_V(err, err);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -1197,7 +1381,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
|
|||||||
String plugin_binary_result_file = plugin.binary.get_file();
|
String plugin_binary_result_file = plugin.binary.get_file();
|
||||||
// We shouldn't embed .xcframework that contains static libraries.
|
// We shouldn't embed .xcframework that contains static libraries.
|
||||||
// Static libraries are not embedded anyway.
|
// Static libraries are not embedded anyway.
|
||||||
err = _copy_asset(dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
|
err = _copy_asset(p_preset, dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err != OK, err);
|
ERR_FAIL_COND_V(err != OK, err);
|
||||||
|
|
||||||
// Adding dependencies.
|
// Adding dependencies.
|
||||||
@@ -1322,15 +1506,15 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
|
|||||||
// Export files
|
// Export files
|
||||||
{
|
{
|
||||||
// Export linked plugin dependency
|
// Export linked plugin dependency
|
||||||
err = _export_additional_assets(dest_dir, plugin_linked_dependencies, true, false, r_exported_assets);
|
err = _export_additional_assets(p_preset, dest_dir, plugin_linked_dependencies, true, false, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err != OK, err);
|
ERR_FAIL_COND_V(err != OK, err);
|
||||||
|
|
||||||
// Export embedded plugin dependency
|
// Export embedded plugin dependency
|
||||||
err = _export_additional_assets(dest_dir, plugin_embedded_dependencies, true, true, r_exported_assets);
|
err = _export_additional_assets(p_preset, dest_dir, plugin_embedded_dependencies, true, true, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err != OK, err);
|
ERR_FAIL_COND_V(err != OK, err);
|
||||||
|
|
||||||
// Export plugin files
|
// Export plugin files
|
||||||
err = _export_additional_assets(dest_dir, plugin_files, false, false, r_exported_assets);
|
err = _export_additional_assets(p_preset, dest_dir, plugin_files, false, false, r_exported_assets);
|
||||||
ERR_FAIL_COND_V(err != OK, err);
|
ERR_FAIL_COND_V(err != OK, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1729,8 +1913,8 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_line("Exporting additional assets");
|
print_line("Exporting additional assets");
|
||||||
_export_additional_assets(binary_dir, libraries, assets);
|
_export_additional_assets(p_preset, binary_dir, libraries, assets);
|
||||||
_add_assets_to_project(p_preset, project_file_data, assets);
|
_add_assets_to_project(dest_dir, p_preset, project_file_data, assets);
|
||||||
String project_file_name = binary_dir + ".xcodeproj/project.pbxproj";
|
String project_file_name = binary_dir + ".xcodeproj/project.pbxproj";
|
||||||
{
|
{
|
||||||
Ref<FileAccess> f = FileAccess::open(project_file_name, FileAccess::WRITE);
|
Ref<FileAccess> f = FileAccess::open(project_file_name, FileAccess::WRITE);
|
||||||
|
|||||||
@@ -133,10 +133,13 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
|
|||||||
Vector<ExportArchitecture> _get_supported_architectures() const;
|
Vector<ExportArchitecture> _get_supported_architectures() const;
|
||||||
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const;
|
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const;
|
||||||
|
|
||||||
void _add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets);
|
void _check_xcframework_content(const String &p_path, int &r_total_libs, int &r_static_libs, int &r_dylibs, int &r_frameworks) const;
|
||||||
Error _export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets);
|
Error _convert_to_framework(const String &p_source, const String &p_destination, const String &p_id) const;
|
||||||
Error _copy_asset(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 String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets);
|
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_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);
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user