Improve embedded PCK loading and exporting.

Windows export process:
  Limit size of executable with embedded PCK to 4 GB.
  Use "rcedit" before embedding PCK.
  Capture and process "rcedit" errors.

Windows, Linux:
  Add support for PCK loading from executable "pck" section.
This commit is contained in:
bruvzg
2021-12-20 11:28:54 +02:00
parent f4b0c7a1ea
commit c0cc41d6c1
12 changed files with 310 additions and 75 deletions

View File

@@ -1820,6 +1820,18 @@ bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset,
Error EditorExportPlatformPC::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);
Error err = prepare_template(p_preset, p_debug, p_path, p_flags);
if (err == OK) {
err = export_project_data(p_preset, p_debug, p_path, p_flags);
}
return err;
}
Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
if (!DirAccess::exists(p_path.get_base_dir())) {
return ERR_FILE_BAD_PATH;
}
String custom_debug = p_preset->get("custom_template/debug");
String custom_release = p_preset->get("custom_template/release");
@@ -1841,49 +1853,52 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
da->make_dir_recursive(p_path.get_base_dir());
Error err = da->copy(template_path, p_path, get_chmod_flags());
if (err == OK) {
String pck_path;
if (p_preset->get("binary_format/embed_pck")) {
pck_path = p_path;
} else {
pck_path = p_path.get_basename() + ".pck";
return err;
}
Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
String pck_path;
if (p_preset->get("binary_format/embed_pck")) {
pck_path = p_path;
} else {
pck_path = p_path.get_basename() + ".pck";
}
Vector<SharedObject> so_files;
int64_t embedded_pos;
int64_t embedded_size;
Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
if (err == OK && p_preset->get("binary_format/embed_pck")) {
if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
return ERR_INVALID_PARAMETER;
}
Vector<SharedObject> so_files;
err = fixup_embedded_pck(p_path, embedded_pos, embedded_size);
}
int64_t embedded_pos;
int64_t embedded_size;
err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
if (err == OK && p_preset->get("binary_format/embed_pck")) {
if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
return ERR_INVALID_PARAMETER;
if (err == OK && !so_files.is_empty()) {
// If shared object files, copy them.
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < so_files.size() && err == OK; i++) {
String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path);
String target_path;
if (so_files[i].target.is_empty()) {
target_path = p_path.get_base_dir().plus_file(src_path.get_file());
} else {
target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file());
}
err = fixup_embedded_pck(p_path, embedded_pos, embedded_size);
}
if (err == OK && !so_files.is_empty()) {
// If shared object files, copy them.
for (int i = 0; i < so_files.size() && err == OK; i++) {
String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path);
String target_path;
if (so_files[i].target.is_empty()) {
target_path = p_path.get_base_dir().plus_file(src_path.get_file());
} else {
target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file());
if (da->dir_exists(src_path)) {
err = da->make_dir_recursive(target_path);
if (err == OK) {
err = da->copy_dir(src_path, target_path, -1, true);
}
if (da->dir_exists(src_path)) {
err = da->make_dir_recursive(target_path);
if (err == OK) {
err = da->copy_dir(src_path, target_path, -1, true);
}
} else {
err = da->copy(src_path, target_path);
if (err == OK) {
err = sign_shared_object(p_preset, p_debug, target_path);
}
} else {
err = da->copy(src_path, target_path);
if (err == OK) {
err = sign_shared_object(p_preset, p_debug, target_path);
}
}
}