|
@@ -40,7 +40,7 @@
|
|
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size);
|
|
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size);
|
|
|
|
|
|
class EditorExportPlatformWindows : public EditorExportPlatformPC {
|
|
class EditorExportPlatformWindows : public EditorExportPlatformPC {
|
|
- void _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
|
|
|
|
|
+ Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
|
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
|
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
|
|
|
|
|
public:
|
|
public:
|
|
@@ -60,16 +60,27 @@ Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPres
|
|
}
|
|
}
|
|
|
|
|
|
Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
|
|
Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
|
|
- Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, p_path, p_flags);
|
|
|
|
|
|
+ String pck_path = p_path;
|
|
|
|
+ if (p_preset->get("binary_format/embed_pck")) {
|
|
|
|
+ pck_path = p_path.get_basename() + ".tmp";
|
|
|
|
+ }
|
|
|
|
|
|
- if (err != OK) {
|
|
|
|
- return err;
|
|
|
|
|
|
+ Error err = EditorExportPlatformPC::prepare_template(p_preset, p_debug, pck_path, p_flags);
|
|
|
|
+ if (p_preset->get("application/modify_resources") && err == OK) {
|
|
|
|
+ err = _rcedit_add_data(p_preset, pck_path);
|
|
}
|
|
}
|
|
|
|
|
|
- _rcedit_add_data(p_preset, p_path);
|
|
|
|
|
|
+ if (err == OK) {
|
|
|
|
+ err = EditorExportPlatformPC::export_project_data(p_preset, p_debug, pck_path, p_flags);
|
|
|
|
+ }
|
|
|
|
|
|
if (p_preset->get("codesign/enable") && err == OK) {
|
|
if (p_preset->get("codesign/enable") && err == OK) {
|
|
- err = _code_sign(p_preset, p_path);
|
|
|
|
|
|
+ err = _code_sign(p_preset, pck_path);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (p_preset->get("binary_format/embed_pck") && err == OK) {
|
|
|
|
+ DirAccessRef tmp_dir = DirAccess::create_for_path(p_path.get_base_dir());
|
|
|
|
+ err = tmp_dir->rename(pck_path, p_path);
|
|
}
|
|
}
|
|
|
|
|
|
return err;
|
|
return err;
|
|
@@ -96,6 +107,7 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
|
|
|
|
|
|
|
|
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/modify_resources"), true));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
|
@@ -106,17 +118,16 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
|
|
}
|
|
}
|
|
|
|
|
|
-void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
|
|
|
|
|
|
+Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
|
|
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
|
|
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
|
|
|
|
|
|
- if (rcedit_path.empty()) {
|
|
|
|
- WARN_PRINT("The rcedit tool is not configured in the Editor Settings (Export > Windows > Rcedit). No custom icon or app information data will be embedded in the exported executable.");
|
|
|
|
- return;
|
|
|
|
|
|
+ if (rcedit_path != String() && !FileAccess::exists(rcedit_path)) {
|
|
|
|
+ ERR_PRINT("Could not find rcedit executable at " + rcedit_path + ", aborting.");
|
|
|
|
+ return ERR_FILE_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!FileAccess::exists(rcedit_path)) {
|
|
|
|
- ERR_PRINT("Could not find rcedit executable at " + rcedit_path + ", no icon or app information data will be included.");
|
|
|
|
- return;
|
|
|
|
|
|
+ if (rcedit_path == String()) {
|
|
|
|
+ rcedit_path = "rcedit"; // try to run rcedit from PATH
|
|
}
|
|
}
|
|
|
|
|
|
#ifndef WINDOWS_ENABLED
|
|
#ifndef WINDOWS_ENABLED
|
|
@@ -124,8 +135,8 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
|
|
String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
|
|
String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
|
|
|
|
|
|
if (wine_path != String() && !FileAccess::exists(wine_path)) {
|
|
if (wine_path != String() && !FileAccess::exists(wine_path)) {
|
|
- ERR_PRINT("Could not find wine executable at " + wine_path + ", no icon or app information data will be included.");
|
|
|
|
- return;
|
|
|
|
|
|
+ ERR_PRINT("Could not find wine executable at " + wine_path + ", aborting.");
|
|
|
|
+ return ERR_FILE_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
|
|
if (wine_path == String()) {
|
|
if (wine_path == String()) {
|
|
@@ -183,13 +194,22 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
|
|
args.push_back(trademarks);
|
|
args.push_back(trademarks);
|
|
}
|
|
}
|
|
|
|
|
|
-#ifdef WINDOWS_ENABLED
|
|
|
|
- OS::get_singleton()->execute(rcedit_path, args, true);
|
|
|
|
-#else
|
|
|
|
|
|
+#ifndef WINDOWS_ENABLED
|
|
// On non-Windows we need WINE to run rcedit
|
|
// On non-Windows we need WINE to run rcedit
|
|
args.push_front(rcedit_path);
|
|
args.push_front(rcedit_path);
|
|
- OS::get_singleton()->execute(wine_path, args, true);
|
|
|
|
|
|
+ rcedit_path = wine_path;
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+ String str;
|
|
|
|
+ Error err = OS::get_singleton()->execute(rcedit_path, args, true, nullptr, &str, nullptr, true);
|
|
|
|
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Could not start rcedit executable, configure rcedit path in the Editor Settings (Export > Windows > Rcedit).");
|
|
|
|
+ print_line("rcedit (" + p_path + "): " + str);
|
|
|
|
+
|
|
|
|
+ if (str.find("Fatal error") != -1) {
|
|
|
|
+ return FAILED;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return OK;
|
|
}
|
|
}
|
|
|
|
|
|
Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
|
|
Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
|
|
@@ -326,7 +346,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
|
|
|
|
|
|
String str;
|
|
String str;
|
|
Error err = OS::get_singleton()->execute(signtool_path, args, true, nullptr, &str, nullptr, true);
|
|
Error err = OS::get_singleton()->execute(signtool_path, args, true, nullptr, &str, nullptr, true);
|
|
- ERR_FAIL_COND_V(err != OK, err);
|
|
|
|
|
|
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Could not start signtool executable, configure signtool path in the Editor Settings (Export > Windows > Signtool).");
|
|
|
|
|
|
print_line("codesign (" + p_path + "): " + str);
|
|
print_line("codesign (" + p_path + "): " + str);
|
|
#ifndef WINDOWS_ENABLED
|
|
#ifndef WINDOWS_ENABLED
|
|
@@ -355,7 +375,7 @@ bool EditorExportPlatformWindows::can_export(const Ref<EditorExportPreset> &p_pr
|
|
bool valid = EditorExportPlatformPC::can_export(p_preset, err, r_missing_templates);
|
|
bool valid = EditorExportPlatformPC::can_export(p_preset, err, r_missing_templates);
|
|
|
|
|
|
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
|
|
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
|
|
- if (rcedit_path.empty()) {
|
|
|
|
|
|
+ if (p_preset->get("application/modify_resources") && rcedit_path.empty()) {
|
|
err += TTR("The rcedit tool must be configured in the Editor Settings (Export > Windows > Rcedit) to change the icon or app information data.") + "\n";
|
|
err += TTR("The rcedit tool must be configured in the Editor Settings (Export > Windows > Rcedit) to change the icon or app information data.") + "\n";
|
|
}
|
|
}
|
|
|
|
|
|
@@ -430,6 +450,10 @@ void register_windows_exporter() {
|
|
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
|
|
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
|
|
// Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data
|
|
// Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data
|
|
|
|
|
|
|
|
+ if (p_embedded_size + p_embedded_start >= 0x100000000) { // Check for total executable size
|
|
|
|
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Windows executables cannot be >= 4 GiB.");
|
|
|
|
+ }
|
|
|
|
+
|
|
FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE);
|
|
FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE);
|
|
if (!f) {
|
|
if (!f) {
|
|
return ERR_CANT_OPEN;
|
|
return ERR_CANT_OPEN;
|