iOS Export: turn .dylib into .framework on export

This commit is contained in:
Sergey Minakov 2020-07-02 12:45:14 +03:00
parent 6001e10054
commit 519024829a

View file

@ -762,8 +762,39 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
memdelete(filesystem_da); memdelete(filesystem_da);
return ERR_FILE_NOT_FOUND; return ERR_FILE_NOT_FOUND;
} }
String additional_dir = p_is_framework && asset.ends_with(".dylib") ? "/dylibs/" : "/";
String destination_dir = p_out_dir + additional_dir + asset.get_base_dir().replace("res://", ""); String base_dir = asset.get_base_dir().replace("res://", "");
String destination_dir;
String destination;
String asset_path;
bool create_framework = false;
if (p_is_framework && asset.ends_with(".dylib")) {
// For iOS we need to turn .dylib into .framework
// to be able to send application to AppStore
destination_dir = p_out_dir.plus_file("dylibs").plus_file(base_dir);
String file_name = asset.get_basename().get_file();
String framework_name = file_name + ".framework";
destination_dir = destination_dir.plus_file(framework_name);
destination = destination_dir.plus_file(file_name);
asset_path = destination_dir;
create_framework = true;
} else if (p_is_framework && (asset.ends_with(".framework") || asset.ends_with(".xcframework"))) {
destination_dir = p_out_dir.plus_file("dylibs").plus_file(base_dir);
String file_name = asset.get_file();
destination = destination_dir.plus_file(file_name);
asset_path = destination;
} else {
destination_dir = p_out_dir.plus_file(base_dir);
String file_name = asset.get_file();
destination = destination_dir.plus_file(file_name);
asset_path = destination;
}
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) {
@ -773,15 +804,66 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
} }
} }
String destination = destination_dir.plus_file(asset.get_file());
Error err = dir_exists ? da->copy_dir(asset, destination) : da->copy(asset, destination); Error err = dir_exists ? da->copy_dir(asset, destination) : da->copy(asset, destination);
memdelete(da); memdelete(da);
if (err) { if (err) {
memdelete(filesystem_da); memdelete(filesystem_da);
return err; return err;
} }
IOSExportAsset exported_asset = { destination, p_is_framework }; IOSExportAsset exported_asset = { asset_path, p_is_framework };
r_exported_assets.push_back(exported_asset); r_exported_assets.push_back(exported_asset);
if (create_framework) {
String file_name = asset.get_basename().get_file();
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").plus_file(framework_name).plus_file(file_name));
install_name_args.push_back(destination);
OS::get_singleton()->execute("install_name_tool", install_name_args, true);
}
// 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.gdnative.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);
FileAccess *f = FileAccess::open(asset_path.plus_file("Info.plist"), FileAccess::WRITE);
if (f) {
f->store_string(info_plist);
f->close();
memdelete(f);
}
}
}
} }
} }
memdelete(filesystem_da); memdelete(filesystem_da);