Ensure more export errors are reported to users
Also fixes the timing issue when exporting all presets at the same time, where the error report would try to appear while the progress dialog was still visible.
This commit is contained in:
parent
2f73a059ce
commit
773b4d7764
|
@ -93,7 +93,7 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
|
|||
}
|
||||
p_log->add_newline();
|
||||
|
||||
if (msg_count) {
|
||||
if (msg_count > 0) {
|
||||
p_log->push_table(2);
|
||||
p_log->set_table_column_expand(0, false);
|
||||
p_log->set_table_column_expand(1, true);
|
||||
|
@ -131,10 +131,39 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
|
|||
p_log->pop();
|
||||
p_log->pop();
|
||||
}
|
||||
p_log->pop();
|
||||
p_log->add_newline();
|
||||
} else if (p_err != OK) {
|
||||
// We failed but don't show any user-facing messages. This is bad and should not
|
||||
// be allowed, but just in case this happens, let's give the user something at least.
|
||||
p_log->push_table(2);
|
||||
p_log->set_table_column_expand(0, false);
|
||||
p_log->set_table_column_expand(1, true);
|
||||
|
||||
{
|
||||
Color color = p_log->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
|
||||
Ref<Texture> icon = p_log->get_editor_theme_icon(SNAME("Error"));
|
||||
|
||||
p_log->push_cell();
|
||||
p_log->add_text("\t");
|
||||
if (icon.is_valid()) {
|
||||
p_log->add_image(icon);
|
||||
}
|
||||
p_log->pop();
|
||||
|
||||
p_log->push_cell();
|
||||
p_log->push_color(color);
|
||||
p_log->add_text(vformat("[%s]: %s", TTR("Unknown Error"), vformat(TTR("Export failed with error code %d."), p_err)));
|
||||
p_log->pop();
|
||||
p_log->pop();
|
||||
}
|
||||
|
||||
p_log->pop();
|
||||
p_log->add_newline();
|
||||
}
|
||||
|
||||
p_log->add_newline();
|
||||
|
||||
return has_messages;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,6 +161,7 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_
|
|||
}
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template."));
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -1109,37 +1109,40 @@ void ProjectExportDialog::_export_all_dialog_action(const String &p_str) {
|
|||
}
|
||||
|
||||
void ProjectExportDialog::_export_all(bool p_debug) {
|
||||
String export_target = p_debug ? TTR("Debug") : TTR("Release");
|
||||
EditorProgress ep("exportall", TTR("Exporting All") + " " + export_target, EditorExport::get_singleton()->get_export_preset_count(), true);
|
||||
|
||||
exporting = true;
|
||||
|
||||
bool show_dialog = false;
|
||||
result_dialog_log->clear();
|
||||
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
|
||||
Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_preset(i);
|
||||
if (preset.is_null()) {
|
||||
exporting = false;
|
||||
ERR_FAIL_MSG("Failed to start the export: one of the presets is invalid.");
|
||||
}
|
||||
|
||||
Ref<EditorExportPlatform> platform = preset->get_platform();
|
||||
if (platform.is_null()) {
|
||||
exporting = false;
|
||||
ERR_FAIL_MSG("Failed to start the export: one of the presets has no valid platform.");
|
||||
}
|
||||
{ // Scope for the editor progress, we must free it before showing the dialog at the end.
|
||||
String export_target = p_debug ? TTR("Debug") : TTR("Release");
|
||||
EditorProgress ep("exportall", TTR("Exporting All") + " " + export_target, EditorExport::get_singleton()->get_export_preset_count(), true);
|
||||
|
||||
ep.step(preset->get_name(), i);
|
||||
result_dialog_log->clear();
|
||||
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
|
||||
Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_preset(i);
|
||||
if (preset.is_null()) {
|
||||
exporting = false;
|
||||
ERR_FAIL_MSG("Failed to start the export: one of the presets is invalid.");
|
||||
}
|
||||
|
||||
platform->clear_messages();
|
||||
Error err = platform->export_project(preset, p_debug, preset->get_export_path(), 0);
|
||||
if (err == ERR_SKIP) {
|
||||
exporting = false;
|
||||
return;
|
||||
Ref<EditorExportPlatform> platform = preset->get_platform();
|
||||
if (platform.is_null()) {
|
||||
exporting = false;
|
||||
ERR_FAIL_MSG("Failed to start the export: one of the presets has no valid platform.");
|
||||
}
|
||||
|
||||
ep.step(preset->get_name(), i);
|
||||
|
||||
platform->clear_messages();
|
||||
Error err = platform->export_project(preset, p_debug, preset->get_export_path(), 0);
|
||||
if (err == ERR_SKIP) {
|
||||
exporting = false;
|
||||
return;
|
||||
}
|
||||
bool has_messages = platform->fill_log_messages(result_dialog_log, err);
|
||||
show_dialog = show_dialog || has_messages;
|
||||
}
|
||||
bool has_messages = platform->fill_log_messages(result_dialog_log, err);
|
||||
show_dialog = show_dialog || has_messages;
|
||||
}
|
||||
|
||||
if (show_dialog) {
|
||||
result_dialog->popup_centered_ratio(0.5);
|
||||
}
|
||||
|
@ -1148,7 +1151,6 @@ void ProjectExportDialog::_export_all(bool p_debug) {
|
|||
}
|
||||
|
||||
void ProjectExportDialog::_bind_methods() {
|
||||
ClassDB::bind_method("_export_all", &ProjectExportDialog::_export_all);
|
||||
ClassDB::bind_method("set_export_path", &ProjectExportDialog::set_export_path);
|
||||
ClassDB::bind_method("get_export_path", &ProjectExportDialog::get_export_path);
|
||||
ClassDB::bind_method("get_current_preset", &ProjectExportDialog::get_current_preset);
|
||||
|
|
|
@ -2782,6 +2782,12 @@ Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset>
|
|||
Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int export_format, bool should_sign, int p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
const String base_dir = p_path.get_base_dir();
|
||||
if (!DirAccess::exists(base_dir)) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Target folder does not exist or is inaccessible: \"%s\""), base_dir));
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
String src_apk;
|
||||
Error err;
|
||||
|
||||
|
@ -2856,7 +2862,10 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
|
|||
}
|
||||
const String assets_directory = get_assets_directory(p_preset, export_format);
|
||||
String sdk_path = EDITOR_GET("export/android/android_sdk_path");
|
||||
ERR_FAIL_COND_V_MSG(sdk_path.is_empty(), ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'.");
|
||||
if (sdk_path.is_empty()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'."));
|
||||
return ERR_UNCONFIGURED;
|
||||
}
|
||||
print_verbose("Android sdk path: " + sdk_path);
|
||||
|
||||
// TODO: should we use "package/name" or "application/config/name"?
|
||||
|
@ -3106,10 +3115,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
|
|||
}
|
||||
}
|
||||
|
||||
if (!DirAccess::exists(p_path.get_base_dir())) {
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
Ref<FileAccess> io_fa;
|
||||
zlib_filefunc_def io = zipio_create_io(&io_fa);
|
||||
|
||||
|
@ -3302,10 +3307,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
|
|||
zipClose(unaligned_apk, nullptr);
|
||||
unzClose(pkg);
|
||||
|
||||
if (err != OK) {
|
||||
CLEANUP_AND_RETURN(err);
|
||||
}
|
||||
|
||||
// Let's zip-align (must be done before signing)
|
||||
|
||||
static const int ZIP_ALIGNMENT = 4;
|
||||
|
@ -3392,6 +3393,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
|
|||
// file will invalidate the signature.
|
||||
err = sign_apk(p_preset, p_debug, p_path, ep);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
CLEANUP_AND_RETURN(err);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -620,7 +620,10 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
|
|||
String sizes;
|
||||
|
||||
Ref<DirAccess> da = DirAccess::open(p_iconset_dir);
|
||||
ERR_FAIL_COND_V_MSG(da.is_null(), ERR_CANT_OPEN, "Cannot open directory '" + p_iconset_dir + "'.");
|
||||
if (da.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat(TTR("Could not open a directory at path \"%s\"."), p_iconset_dir));
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
Color boot_bg_color = GLOBAL_GET("application/boot_splash/bg_color");
|
||||
|
||||
|
@ -692,12 +695,20 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
|
|||
json_description += "]}";
|
||||
|
||||
Ref<FileAccess> json_file = FileAccess::open(p_iconset_dir + "Contents.json", FileAccess::WRITE);
|
||||
ERR_FAIL_COND_V(json_file.is_null(), ERR_CANT_CREATE);
|
||||
if (json_file.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat(TTR("Could not write to a file at path \"%s\"."), p_iconset_dir + "Contents.json"));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
CharString json_utf8 = json_description.utf8();
|
||||
json_file->store_buffer((const uint8_t *)json_utf8.get_data(), json_utf8.length());
|
||||
|
||||
Ref<FileAccess> sizes_file = FileAccess::open(p_iconset_dir + "sizes", FileAccess::WRITE);
|
||||
ERR_FAIL_COND_V(sizes_file.is_null(), ERR_CANT_CREATE);
|
||||
if (sizes_file.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat(TTR("Could not write to a file at path \"%s\"."), p_iconset_dir + "sizes"));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
CharString sizes_utf8 = sizes.utf8();
|
||||
sizes_file->store_buffer((const uint8_t *)sizes_utf8.get_data(), sizes_utf8.length());
|
||||
|
||||
|
@ -1219,10 +1230,10 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
|
|||
String asset = p_assets[f_idx];
|
||||
if (asset.begins_with("res://")) {
|
||||
Error err = _copy_asset(p_out_dir, asset, nullptr, p_is_framework, p_should_embed, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
} 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);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
} else {
|
||||
// either SDK-builtin or already a part of the export template
|
||||
IOSExportAsset exported_asset = { asset, p_is_framework, p_should_embed };
|
||||
|
@ -1306,8 +1317,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
|
|||
// We shouldn't embed .xcframework that contains static libraries.
|
||||
// Static libraries are not embedded anyway.
|
||||
err = _copy_asset(dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
|
||||
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
|
||||
// Adding dependencies.
|
||||
// Use separate container for names to check for duplicates.
|
||||
|
@ -1432,15 +1442,15 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
|
|||
{
|
||||
// Export linked plugin dependency
|
||||
err = _export_additional_assets(dest_dir, plugin_linked_dependencies, true, false, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
|
||||
// Export embedded plugin dependency
|
||||
err = _export_additional_assets(dest_dir, plugin_embedded_dependencies, true, true, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
|
||||
// Export plugin files
|
||||
err = _export_additional_assets(dest_dir, plugin_files, false, false, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
}
|
||||
|
||||
// Update CPP
|
||||
|
@ -1496,9 +1506,14 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
|
|||
Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags, bool p_simulator, bool p_skip_ipa) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
String src_pkg_name;
|
||||
String dest_dir = p_path.get_base_dir() + "/";
|
||||
String binary_name = p_path.get_file().get_basename();
|
||||
const String dest_dir = p_path.get_base_dir() + "/";
|
||||
const String binary_name = p_path.get_file().get_basename();
|
||||
const String binary_dir = dest_dir + binary_name;
|
||||
|
||||
if (!DirAccess::exists(dest_dir)) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Target folder does not exist or is inaccessible: \"%s\""), dest_dir));
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
bool export_project_only = p_preset->get("application/export_project_only");
|
||||
|
||||
|
@ -1507,6 +1522,7 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
String team_id = p_preset->get("application/app_store_team_id");
|
||||
ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project.");
|
||||
|
||||
String src_pkg_name;
|
||||
if (p_debug) {
|
||||
src_pkg_name = p_preset->get("custom_template/debug");
|
||||
} else {
|
||||
|
@ -1522,10 +1538,6 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
}
|
||||
}
|
||||
|
||||
if (!DirAccess::exists(dest_dir)) {
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
{
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
if (da.is_valid()) {
|
||||
|
@ -1533,18 +1545,19 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
|
||||
// remove leftovers from last export so they don't interfere
|
||||
// in case some files are no longer needed
|
||||
if (da->change_dir(dest_dir + binary_name + ".xcodeproj") == OK) {
|
||||
if (da->change_dir(binary_dir + ".xcodeproj") == OK) {
|
||||
da->erase_contents_recursive();
|
||||
}
|
||||
if (da->change_dir(dest_dir + binary_name) == OK) {
|
||||
if (da->change_dir(binary_dir) == OK) {
|
||||
da->erase_contents_recursive();
|
||||
}
|
||||
|
||||
da->change_dir(current_dir);
|
||||
|
||||
if (!da->dir_exists(dest_dir + binary_name)) {
|
||||
Error err = da->make_dir(dest_dir + binary_name);
|
||||
if (err) {
|
||||
if (!da->dir_exists(binary_dir)) {
|
||||
Error err = da->make_dir(binary_dir);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Failed to create the directory: \"%s\""), binary_dir));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
@ -1554,10 +1567,11 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
if (ep.step("Making .pck", 0)) {
|
||||
return ERR_SKIP;
|
||||
}
|
||||
String pack_path = dest_dir + binary_name + ".pck";
|
||||
String pack_path = binary_dir + ".pck";
|
||||
Vector<SharedObject> libraries;
|
||||
Error err = save_pack(p_preset, p_debug, pack_path, &libraries);
|
||||
if (err) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1606,7 +1620,10 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
Vector<IOSExportAsset> assets;
|
||||
|
||||
Ref<DirAccess> tmp_app_path = DirAccess::create_for_path(dest_dir);
|
||||
ERR_FAIL_COND_V(tmp_app_path.is_null(), ERR_CANT_CREATE);
|
||||
if (tmp_app_path.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not create and open the directory: \"%s\""), dest_dir));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
print_line("Unzipping...");
|
||||
Ref<FileAccess> io_fa;
|
||||
|
@ -1617,8 +1634,14 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
err = _export_ios_plugins(p_preset, config_data, dest_dir + binary_name, assets, p_debug);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
err = _export_ios_plugins(p_preset, config_data, binary_dir, assets, p_debug);
|
||||
if (err != OK) {
|
||||
// TODO: Improve error reporting by using `add_message` throughout all methods called via `_export_ios_plugins`.
|
||||
// For now a generic top level message would be fine, but we're ought to use proper reporting here instead of
|
||||
// just fail macros and non-descriptive error return values.
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("iOS Plugins"), vformat(TTR("Failed to export iOS plugins with code %d. Please check the output log."), err));
|
||||
return err;
|
||||
}
|
||||
|
||||
//export rest of the files
|
||||
int ret = unzGoToFirstFile(src_pkg_zip);
|
||||
|
@ -1683,8 +1706,8 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
print_line("Creating " + dir_name);
|
||||
Error dir_err = tmp_app_path->make_dir_recursive(dir_name);
|
||||
if (dir_err) {
|
||||
ERR_PRINT("Can't create '" + dir_name + "'.");
|
||||
unzClose(src_pkg_zip);
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create a directory at path \"%s\"."), dir_name));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
}
|
||||
|
@ -1693,8 +1716,8 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
{
|
||||
Ref<FileAccess> f = FileAccess::open(file, FileAccess::WRITE);
|
||||
if (f.is_null()) {
|
||||
ERR_PRINT("Can't write '" + file + "'.");
|
||||
unzClose(src_pkg_zip);
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write to a file at path \"%s\"."), file));
|
||||
return ERR_CANT_CREATE;
|
||||
};
|
||||
f->store_buffer(data.ptr(), data.size());
|
||||
|
@ -1715,7 +1738,7 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
unzClose(src_pkg_zip);
|
||||
|
||||
if (!found_library) {
|
||||
ERR_PRINT("Requested template library '" + library_to_use + "' not found. It might be missing from your template archive.");
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Requested template library '%s' not found. It might be missing from your template archive."), library_to_use));
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
@ -1727,7 +1750,7 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
Vector<String> translations = GLOBAL_GET("internationalization/locale/translations");
|
||||
if (translations.size() > 0) {
|
||||
{
|
||||
String fname = dest_dir + binary_name + "/en.lproj";
|
||||
String fname = binary_dir + "/en.lproj";
|
||||
tmp_app_path->make_dir_recursive(fname);
|
||||
Ref<FileAccess> f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE);
|
||||
f->store_line("/* Localized versions of Info.plist keys */");
|
||||
|
@ -1747,7 +1770,7 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
}
|
||||
|
||||
for (const String &lang : languages) {
|
||||
String fname = dest_dir + binary_name + "/" + lang + ".lproj";
|
||||
String fname = binary_dir + "/" + lang + ".lproj";
|
||||
tmp_app_path->make_dir_recursive(fname);
|
||||
Ref<FileAccess> f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE);
|
||||
f->store_line("/* Localized versions of Info.plist keys */");
|
||||
|
@ -1776,34 +1799,37 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
String dest_lib_file_path = dest_dir + static_lib_path.get_file();
|
||||
Error lib_copy_err = tmp_app_path->copy(static_lib_path, dest_lib_file_path);
|
||||
if (lib_copy_err != OK) {
|
||||
ERR_PRINT("Can't copy '" + static_lib_path + "'.");
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not copy a file at path \"%s\" to \"%s\"."), static_lib_path, dest_lib_file_path));
|
||||
return lib_copy_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String iconset_dir = dest_dir + binary_name + "/Images.xcassets/AppIcon.appiconset/";
|
||||
String iconset_dir = binary_dir + "/Images.xcassets/AppIcon.appiconset/";
|
||||
err = OK;
|
||||
if (!tmp_app_path->dir_exists(iconset_dir)) {
|
||||
err = tmp_app_path->make_dir_recursive(iconset_dir);
|
||||
}
|
||||
if (err) {
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create a directory at path \"%s\"."), iconset_dir));
|
||||
return err;
|
||||
}
|
||||
|
||||
err = _export_icons(p_preset, iconset_dir);
|
||||
if (err) {
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
|
||||
{
|
||||
bool use_storyboard = p_preset->get("storyboard/use_launch_screen_storyboard");
|
||||
|
||||
String launch_image_path = dest_dir + binary_name + "/Images.xcassets/LaunchImage.launchimage/";
|
||||
String splash_image_path = dest_dir + binary_name + "/Images.xcassets/SplashImage.imageset/";
|
||||
String launch_image_path = binary_dir + "/Images.xcassets/LaunchImage.launchimage/";
|
||||
String splash_image_path = binary_dir + "/Images.xcassets/SplashImage.imageset/";
|
||||
|
||||
Ref<DirAccess> launch_screen_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
if (launch_screen_da.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not access the filesystem."));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
|
@ -1816,10 +1842,11 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
}
|
||||
|
||||
err = _export_loading_screen_file(p_preset, splash_image_path);
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Failed to create a file at path \"%s\" with code %d."), splash_image_path, err));
|
||||
} else {
|
||||
print_line("Using Launch Images");
|
||||
|
||||
const String launch_screen_path = dest_dir + binary_name + "/Launch Screen.storyboard";
|
||||
const String launch_screen_path = binary_dir + "/Launch Screen.storyboard";
|
||||
|
||||
launch_screen_da->remove(launch_screen_path);
|
||||
|
||||
|
@ -1829,21 +1856,22 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
}
|
||||
|
||||
err = _export_loading_screen_images(p_preset, launch_image_path);
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Failed to create a file at path \"%s\" with code %d."), launch_image_path, err));
|
||||
}
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
print_line("Exporting additional assets");
|
||||
_export_additional_assets(dest_dir + binary_name, libraries, assets);
|
||||
_export_additional_assets(binary_dir, libraries, assets);
|
||||
_add_assets_to_project(p_preset, project_file_data, assets);
|
||||
String project_file_name = dest_dir + binary_name + ".xcodeproj/project.pbxproj";
|
||||
String project_file_name = binary_dir + ".xcodeproj/project.pbxproj";
|
||||
{
|
||||
Ref<FileAccess> f = FileAccess::open(project_file_name, FileAccess::WRITE);
|
||||
if (f.is_null()) {
|
||||
ERR_PRINT("Can't write '" + project_file_name + "'.");
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write to a file at path \"%s\"."), project_file_name));
|
||||
return ERR_CANT_CREATE;
|
||||
};
|
||||
f->store_buffer(project_file_data.ptr(), project_file_data.size());
|
||||
|
@ -1854,7 +1882,7 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
if (ep.step("Code-signing dylibs", 2)) {
|
||||
return ERR_SKIP;
|
||||
}
|
||||
Ref<DirAccess> dylibs_dir = DirAccess::open(dest_dir + binary_name + "/dylibs");
|
||||
Ref<DirAccess> dylibs_dir = DirAccess::open(binary_dir + "/dylibs");
|
||||
ERR_FAIL_COND_V(dylibs_dir.is_null(), ERR_CANT_OPEN);
|
||||
CodesignData codesign_data(p_preset, p_debug);
|
||||
err = _walk_dir_recursive(dylibs_dir, _codesign, &codesign_data);
|
||||
|
@ -1871,10 +1899,11 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
if (ep.step("Making .xcarchive", 3)) {
|
||||
return ERR_SKIP;
|
||||
}
|
||||
|
||||
String archive_path = p_path.get_basename() + ".xcarchive";
|
||||
List<String> archive_args;
|
||||
archive_args.push_back("-project");
|
||||
archive_args.push_back(dest_dir + binary_name + ".xcodeproj");
|
||||
archive_args.push_back(binary_dir + ".xcodeproj");
|
||||
archive_args.push_back("-scheme");
|
||||
archive_args.push_back(binary_name);
|
||||
archive_args.push_back("-sdk");
|
||||
|
@ -1895,9 +1924,14 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
archive_args.push_back("-allowProvisioningUpdates");
|
||||
archive_args.push_back("-archivePath");
|
||||
archive_args.push_back(archive_path);
|
||||
|
||||
String archive_str;
|
||||
err = OS::get_singleton()->execute("xcodebuild", archive_args, &archive_str, nullptr, true);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Xcode Build"), vformat(TTR("Failed to run xcodebuild with code %d"), err));
|
||||
return err;
|
||||
}
|
||||
|
||||
print_line("xcodebuild (.xcarchive):\n" + archive_str);
|
||||
if (!archive_str.contains("** ARCHIVE SUCCEEDED **")) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Xcode Build"), TTR("Xcode project build failed, see editor log for details."));
|
||||
|
@ -1908,18 +1942,24 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
|
|||
if (ep.step("Making .ipa", 4)) {
|
||||
return ERR_SKIP;
|
||||
}
|
||||
|
||||
List<String> export_args;
|
||||
export_args.push_back("-exportArchive");
|
||||
export_args.push_back("-archivePath");
|
||||
export_args.push_back(archive_path);
|
||||
export_args.push_back("-exportOptionsPlist");
|
||||
export_args.push_back(dest_dir + binary_name + "/export_options.plist");
|
||||
export_args.push_back(binary_dir + "/export_options.plist");
|
||||
export_args.push_back("-allowProvisioningUpdates");
|
||||
export_args.push_back("-exportPath");
|
||||
export_args.push_back(dest_dir);
|
||||
|
||||
String export_str;
|
||||
err = OS::get_singleton()->execute("xcodebuild", export_args, &export_str, nullptr, true);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Xcode Build"), vformat(TTR("Failed to run xcodebuild with code %d"), err));
|
||||
return err;
|
||||
}
|
||||
|
||||
print_line("xcodebuild (.ipa):\n" + export_str);
|
||||
if (!export_str.contains("** EXPORT SUCCEEDED **")) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Xcode Build"), TTR(".ipa export failed, see editor log for details."));
|
||||
|
|
|
@ -79,6 +79,7 @@ Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset>
|
|||
Ref<DirAccess> tmp_app_dir = DirAccess::create_for_path(tmp_dir_path);
|
||||
if (export_as_zip) {
|
||||
if (tmp_app_dir.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not create and open the directory: \"%s\""), tmp_dir_path));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
if (DirAccess::exists(tmp_dir_path)) {
|
||||
|
@ -93,19 +94,18 @@ Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset>
|
|||
// Export project.
|
||||
Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, path, p_flags);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
|
||||
// Save console wrapper.
|
||||
if (err == OK) {
|
||||
int con_scr = p_preset->get("debug/export_console_wrapper");
|
||||
if ((con_scr == 1 && p_debug) || (con_scr == 2)) {
|
||||
String scr_path = path.get_basename() + ".sh";
|
||||
err = _export_debug_script(p_preset, pkg_name, path.get_file(), scr_path);
|
||||
FileAccess::set_unix_permissions(scr_path, 0755);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Console Export"), TTR("Could not create console wrapper."));
|
||||
}
|
||||
int con_scr = p_preset->get("debug/export_console_wrapper");
|
||||
if ((con_scr == 1 && p_debug) || (con_scr == 2)) {
|
||||
String scr_path = path.get_basename() + ".sh";
|
||||
err = _export_debug_script(p_preset, pkg_name, path.get_file(), scr_path);
|
||||
FileAccess::set_unix_permissions(scr_path, 0755);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Console Export"), TTR("Could not create console wrapper."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1266,10 +1266,16 @@ Error EditorExportPlatformMacOS::_export_debug_script(const Ref<EditorExportPres
|
|||
Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
String src_pkg_name;
|
||||
const String base_dir = p_path.get_base_dir();
|
||||
|
||||
if (!DirAccess::exists(base_dir)) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Target folder does not exist or is inaccessible: \"%s\""), base_dir));
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
EditorProgress ep("export", TTR("Exporting for macOS"), 3, true);
|
||||
|
||||
String src_pkg_name;
|
||||
if (p_debug) {
|
||||
src_pkg_name = p_preset->get("custom_template/debug");
|
||||
} else {
|
||||
|
@ -1280,16 +1286,11 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
|
|||
String err;
|
||||
src_pkg_name = find_export_template("macos.zip", &err);
|
||||
if (src_pkg_name.is_empty()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found.") + "\n" + err);
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DirAccess::exists(p_path.get_base_dir())) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("The given export path doesn't exist."));
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
Ref<FileAccess> io_fa;
|
||||
zlib_filefunc_def io = zipio_create_io(&io_fa);
|
||||
|
||||
|
|
|
@ -259,6 +259,7 @@ Error EditorExportPlatformWeb::_build_pwa(const Ref<EditorExportPreset> &p_prese
|
|||
_replace_strings(replaces, sw);
|
||||
Error err = _write_or_error(sw.ptr(), sw.size(), dir.path_join(name + ".service.worker.js"));
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -291,16 +292,19 @@ Error EditorExportPlatformWeb::_build_pwa(const Ref<EditorExportPreset> &p_prese
|
|||
const String icon144_path = p_preset->get("progressive_web_app/icon_144x144");
|
||||
err = _add_manifest_icon(p_path, icon144_path, 144, icons_arr);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
const String icon180_path = p_preset->get("progressive_web_app/icon_180x180");
|
||||
err = _add_manifest_icon(p_path, icon180_path, 180, icons_arr);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
const String icon512_path = p_preset->get("progressive_web_app/icon_512x512");
|
||||
err = _add_manifest_icon(p_path, icon512_path, 512, icons_arr);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
manifest["icons"] = icons_arr;
|
||||
|
@ -308,6 +312,7 @@ Error EditorExportPlatformWeb::_build_pwa(const Ref<EditorExportPreset> &p_prese
|
|||
CharString cs = Variant(manifest).to_json_string().utf8();
|
||||
err = _write_or_error((const uint8_t *)cs.get_data(), cs.length(), dir.path_join(name + ".manifest.json"));
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -439,6 +444,11 @@ Error EditorExportPlatformWeb::export_project(const Ref<EditorExportPreset> &p_p
|
|||
const String base_path = p_path.get_basename();
|
||||
const String base_name = p_path.get_file().get_basename();
|
||||
|
||||
if (!DirAccess::exists(base_dir)) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Target folder does not exist or is inaccessible: \"%s\""), base_dir));
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
// Find the correct template
|
||||
String template_path = p_debug ? custom_debug : custom_release;
|
||||
template_path = template_path.strip_edges();
|
||||
|
@ -447,10 +457,6 @@ Error EditorExportPlatformWeb::export_project(const Ref<EditorExportPreset> &p_p
|
|||
template_path = find_export_template(_get_template_name(extensions, p_debug));
|
||||
}
|
||||
|
||||
if (!DirAccess::exists(base_dir)) {
|
||||
return ERR_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
if (!template_path.is_empty() && !FileAccess::exists(template_path)) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Template file not found: \"%s\"."), template_path));
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
|
@ -480,6 +486,7 @@ Error EditorExportPlatformWeb::export_project(const Ref<EditorExportPreset> &p_p
|
|||
// Extract templates.
|
||||
error = _extract_template(template_path, base_dir, base_name, pwa);
|
||||
if (error) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -510,6 +517,7 @@ Error EditorExportPlatformWeb::export_project(const Ref<EditorExportPreset> &p_p
|
|||
_fix_html(html, p_preset, base_name, p_debug, p_flags, shared_objects, file_sizes);
|
||||
Error err = _write_or_error(html.ptr(), html.size(), p_path);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
html.resize(0);
|
||||
|
@ -543,6 +551,7 @@ Error EditorExportPlatformWeb::export_project(const Ref<EditorExportPreset> &p_p
|
|||
if (pwa) {
|
||||
err = _build_pwa(p_preset, p_path, shared_objects);
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,6 +226,7 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
|
|||
Ref<DirAccess> tmp_app_dir = DirAccess::create_for_path(tmp_dir_path);
|
||||
if (export_as_zip) {
|
||||
if (tmp_app_dir.is_null()) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not create and open the directory: \"%s\""), tmp_dir_path));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
if (DirAccess::exists(tmp_dir_path)) {
|
||||
|
@ -242,8 +243,14 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
|
|||
if (embedded) {
|
||||
pck_path = pck_path.get_basename() + ".tmp";
|
||||
}
|
||||
|
||||
Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, pck_path, p_flags);
|
||||
if (p_preset->get("codesign/enable") && err == OK) {
|
||||
if (err != OK) {
|
||||
// Message is supplied by the subroutine method.
|
||||
return err;
|
||||
}
|
||||
|
||||
if (p_preset->get("codesign/enable")) {
|
||||
_code_sign(p_preset, pck_path);
|
||||
String wrapper_path = p_path.get_basename() + ".console.exe";
|
||||
if (FileAccess::exists(wrapper_path)) {
|
||||
|
@ -251,7 +258,7 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
|
|||
}
|
||||
}
|
||||
|
||||
if (embedded && err == OK) {
|
||||
if (embedded) {
|
||||
Ref<DirAccess> tmp_dir = DirAccess::create_for_path(p_path.get_base_dir());
|
||||
err = tmp_dir->rename(pck_path, p_path);
|
||||
if (err != OK) {
|
||||
|
|
Loading…
Reference in New Issue