Merge pull request #34887 from akien-mga/cli-export-usability

Export: Improve usability of command line interface
This commit is contained in:
Rémi Verschelde 2020-01-08 08:19:39 +01:00 committed by GitHub
commit 6fa716c67b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 160 additions and 177 deletions

View file

@ -1485,41 +1485,29 @@ Ref<Texture> EditorExportPlatformPC::get_logo() const {
bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = true;
bool valid = false;
// Look for export templates (first official, and if defined custom templates).
bool use64 = p_preset->get("binary_format/64_bits");
bool dvalid = exists_export_template(use64 ? debug_file_64 : debug_file_32, &err);
bool rvalid = exists_export_template(use64 ? release_file_64 : release_file_32, &err);
if (use64 && (!exists_export_template(debug_file_64, &err) || !exists_export_template(release_file_64, &err))) {
valid = false;
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (!use64 && (!exists_export_template(debug_file_32, &err) || !exists_export_template(release_file_32, &err))) {
valid = false;
}
String custom_debug_binary = p_preset->get("custom_template/debug");
String custom_release_binary = p_preset->get("custom_template/release");
if (custom_debug_binary == "" && custom_release_binary == "") {
if (!err.empty())
r_error = err;
r_missing_templates = !valid;
return valid;
}
bool dvalid = true;
bool rvalid = true;
if (!FileAccess::exists(custom_debug_binary)) {
dvalid = false;
err += TTR("Custom debug template not found.") + "\n";
}
if (!FileAccess::exists(custom_release_binary)) {
rvalid = false;
err += TTR("Custom release template not found.") + "\n";
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
}
}
valid = dvalid || rvalid;
r_missing_templates = !valid;
if (!err.empty())
r_error = err;
@ -1600,7 +1588,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
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_UNAVAILABLE;
return ERR_INVALID_PARAMETER;
}
FixUpEmbeddedPckFunc fixup_func = get_fixup_embedded_pck_func();

View file

@ -562,46 +562,68 @@ void EditorNode::_fs_changed() {
_mark_unsaved_scenes();
// FIXME: Move this to a cleaner location, it's hacky to do this is _fs_changed.
String export_error;
if (export_defer.preset != "" && !EditorFileSystem::get_singleton()->is_scanning()) {
String preset_name = export_defer.preset;
// Ensures export_project does not loop infinitely, because notifications may
// come during the export.
export_defer.preset = "";
Ref<EditorExportPreset> preset;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); ++i) {
preset = EditorExport::get_singleton()->get_export_preset(i);
if (preset->get_name() == export_defer.preset) {
if (preset->get_name() == preset_name) {
break;
}
preset.unref();
}
if (preset.is_null()) {
String errstr = "Unknown export preset: " + export_defer.preset;
ERR_PRINTS(errstr);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
export_error = vformat("Invalid export preset name: %s.", preset_name);
} else {
Ref<EditorExportPlatform> platform = preset->get_platform();
if (platform.is_null()) {
String errstr = "Preset \"" + export_defer.preset + "\" doesn't have a platform.";
ERR_PRINTS(errstr);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
export_error = vformat("Export preset '%s' doesn't have a matching platform.", preset_name);
} else {
// ensures export_project does not loop infinitely, because notifications may
// come during the export
export_defer.preset = "";
Error err = OK;
// FIXME: This way to export only resources .pck or .zip is pretty hacky
// and undocumented, and might be problematic for platforms where .zip is
// a valid project export format (e.g. macOS).
if (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip")) {
if (export_defer.path.ends_with(".zip")) {
err = platform->export_zip(preset, export_defer.debug, export_defer.path);
} else if (export_defer.path.ends_with(".pck")) {
err = platform->export_pack(preset, export_defer.debug, export_defer.path);
}
} else {
err = platform->export_project(preset, export_defer.debug, export_defer.path);
} else { // Normal project export.
String config_error;
bool missing_templates;
if (!platform->can_export(preset, config_error, missing_templates)) {
ERR_PRINT(vformat("Cannot export project with preset '%s' due to configuration errors:\n%s", preset_name, config_error));
err = missing_templates ? ERR_FILE_NOT_FOUND : ERR_UNCONFIGURED;
} else {
err = platform->export_project(preset, export_defer.debug, export_defer.path);
}
}
if (err != OK) {
ERR_PRINTS(vformat(TTR("Project export failed with error code %d."), (int)err));
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
switch (err) {
case OK:
break;
case ERR_FILE_NOT_FOUND:
export_error = vformat("Project export failed for preset '%s', the export template appears to be missing.", preset_name);
break;
case ERR_FILE_BAD_PATH:
export_error = vformat("Project export failed for preset '%s', the target path '%s' appears to be invalid.", preset_name, export_defer.path);
break;
default:
export_error = vformat("Project export failed with error code %d for preset '%s'.", (int)err, preset_name);
break;
}
}
}
if (!export_error.empty()) {
ERR_PRINT(export_error);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
}
_exit_editor();
}
}
@ -3920,12 +3942,11 @@ void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) {
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) {
Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug) {
export_defer.preset = p_preset;
export_defer.path = p_path;
export_defer.debug = p_debug;
export_defer.password = p_password;
disable_progress_dialog = true;
return OK;
}
@ -6531,12 +6552,6 @@ EditorNode::EditorNode() {
gui_base->add_child(file);
file->set_current_dir("res://");
file_export = memnew(EditorFileDialog);
file_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
gui_base->add_child(file_export);
file_export->set_title(TTR("Export Project"));
file_export->connect("file_selected", this, "_dialog_action");
file_export_lib = memnew(EditorFileDialog);
file_export_lib->set_title(TTR("Export Library"));
file_export_lib->set_mode(EditorFileDialog::MODE_SAVE_FILE);
@ -6547,11 +6562,6 @@ EditorNode::EditorNode() {
file_export_lib->get_vbox()->add_child(file_export_lib_merge);
gui_base->add_child(file_export_lib);
file_export_password = memnew(LineEdit);
file_export_password->set_secret(true);
file_export_password->set_editable(false);
file_export->get_vbox()->add_margin_child(TTR("Password:"), file_export_password);
file_script = memnew(EditorFileDialog);
file_script->set_title(TTR("Open & Run a Script"));
file_script->set_access(EditorFileDialog::ACCESS_FILESYSTEM);

View file

@ -325,18 +325,13 @@ private:
ExportTemplateManager *export_template_manager;
EditorFeatureProfileManager *feature_profile_manager;
EditorFileDialog *file_templates;
EditorFileDialog *file_export;
EditorFileDialog *file_export_lib;
EditorFileDialog *file_script;
CheckBox *file_export_lib_merge;
LineEdit *file_export_password;
String current_path;
MenuButton *update_spinner;
String defer_load_scene;
String defer_export;
String defer_export_platform;
bool defer_export_debug;
Node *_last_instanced_scene;
EditorLog *log;
@ -563,8 +558,6 @@ private:
String preset;
String path;
bool debug;
String password;
} export_defer;
bool disable_progress_dialog;
@ -786,7 +779,7 @@ public:
void _copy_warning(const String &p_str);
Error export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false);
Error export_preset(const String &p_preset, const String &p_path, bool p_debug);
static void register_editor_types();
static void unregister_editor_types();

View file

@ -286,8 +286,10 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" -s, --script <script> Run a script.\n");
OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n");
#ifdef TOOLS_ENABLED
OS::get_singleton()->print(" --export <target> <path> Export the project using the given export target. Export only main pack if path ends with .pck or .zip. <path> is relative to the project directory.\n");
OS::get_singleton()->print(" --export-debug <target> <path> Like --export, but use debug template.\n");
OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n");
OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe').\n");
OS::get_singleton()->print(" The target directory should exist. Only the data pack is exported if <path> ends with .pck or .zip.\n");
OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n");
OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n");
OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n");
OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects).\n");
@ -1513,11 +1515,11 @@ bool Main::start() {
if (_export_preset != "") {
if (game_path == "") {
String err = "Command line param ";
String err = "Command line parameter ";
err += export_debug ? "--export-debug" : "--export";
err += " passed but no destination path given.\n";
err += "Please specify the binary's file path to export to. Aborting export.";
ERR_PRINT(err.utf8().get_data());
ERR_PRINT(err);
return false;
}
}
@ -1698,20 +1700,14 @@ bool Main::start() {
}
#ifdef TOOLS_ENABLED
EditorNode *editor_node = NULL;
if (editor) {
editor_node = memnew(EditorNode);
sml->get_root()->add_child(editor_node);
//root_node->set_editor(editor);
//startup editor
if (_export_preset != "") {
editor_node->export_preset(_export_preset, game_path, export_debug, "", true);
game_path = ""; //no load anything
editor_node->export_preset(_export_preset, game_path, export_debug);
game_path = ""; // Do not load anything.
}
}
#endif

View file

@ -1299,9 +1299,9 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_package/use_custom_build"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
@ -1577,29 +1577,34 @@ public:
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
if (!bool(p_preset->get("custom_package/use_custom_build"))) {
// Look for export templates (first official, and if defined custom templates).
r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String();
if (!bool(p_preset->get("custom_template/use_custom_build"))) {
bool dvalid = exists_export_template("android_debug.apk", &err);
bool rvalid = exists_export_template("android_release.apk", &err);
if (p_preset->get("custom_package/debug") != "") {
if (FileAccess::exists(p_preset->get("custom_package/debug"))) {
r_missing_templates = false;
} else {
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (p_preset->get("custom_package/release") != "") {
if (FileAccess::exists(p_preset->get("custom_package/release"))) {
r_missing_templates = false;
} else {
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
}
}
}
bool valid = !r_missing_templates;
valid = dvalid || rvalid;
} else {
valid = exists_export_template("android_source.zip", &err);
}
r_missing_templates = !valid;
// Validate the rest of the configuration.
String adb = EditorSettings::get_singleton()->get("export/android/adb");
@ -1628,7 +1633,7 @@ public:
}
}
if (bool(p_preset->get("custom_package/use_custom_build"))) {
if (bool(p_preset->get("custom_template/use_custom_build"))) {
String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path");
if (sdk_path == "") {
err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n";
@ -1949,7 +1954,7 @@ public:
EditorProgress ep("export", "Exporting for Android", 105, true);
if (bool(p_preset->get("custom_package/use_custom_build"))) { //custom build
if (bool(p_preset->get("custom_template/use_custom_build"))) { //custom build
//re-generate build.gradle and AndroidManifest.xml
{ //test that installed build version is alright
@ -2017,9 +2022,9 @@ public:
} else {
if (p_debug)
src_apk = p_preset->get("custom_package/debug");
src_apk = p_preset->get("custom_template/debug");
else
src_apk = p_preset->get("custom_package/release");
src_apk = p_preset->get("custom_template/release");
src_apk = src_apk.strip_edges();
if (src_apk == "") {

View file

@ -206,8 +206,8 @@ static const LoadingScreenInfo loading_screen_infos[] = {
void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), ""));
@ -848,9 +848,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project.");
if (p_debug)
src_pkg_name = p_preset->get("custom_package/debug");
src_pkg_name = p_preset->get("custom_template/debug");
else
src_pkg_name = p_preset->get("custom_package/release");
src_pkg_name = p_preset->get("custom_template/release");
if (src_pkg_name == "") {
String err;
@ -1156,25 +1156,30 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
r_missing_templates = find_export_template("iphone.zip") == String();
bool valid = false;
if (p_preset->get("custom_package/debug") != "") {
if (FileAccess::exists(p_preset->get("custom_package/debug"))) {
r_missing_templates = false;
} else {
// Look for export templates (first official, and if defined custom templates).
bool dvalid = exists_export_template("iphone.zip", &err);
bool rvalid = dvalid; // Both in the same ZIP.
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (p_preset->get("custom_package/release") != "") {
if (FileAccess::exists(p_preset->get("custom_package/release"))) {
r_missing_templates = false;
} else {
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
}
}
bool valid = !r_missing_templates;
valid = dvalid || rvalid;
r_missing_templates = !valid;
// Validate the rest of the configuration.
String team_id = p_preset->get("application/app_store_team_id");
if (team_id.length() == 0) {

View file

@ -288,32 +288,32 @@ Ref<Texture> EditorExportPlatformJavaScript::get_logo() const {
bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
bool valid = false;
String err;
bool valid = false;
if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) != "")
valid = true;
else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) != "")
valid = true;
// Look for export templates (first official, and if defined custom templates).
bool dvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG, &err);
bool rvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE, &err);
if (p_preset->get("custom_template/debug") != "") {
if (FileAccess::exists(p_preset->get("custom_template/debug"))) {
valid = true;
} else {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (p_preset->get("custom_template/release") != "") {
if (FileAccess::exists(p_preset->get("custom_template/release"))) {
valid = true;
} else {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
}
}
valid = dvalid || rvalid;
r_missing_templates = !valid;
// Validate the rest of the configuration.
if (p_preset->get("vram_texture_compression/for_mobile")) {
String etc_error = test_etc2();
if (etc_error != String()) {

View file

@ -118,8 +118,8 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset>
void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
@ -459,9 +459,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
EditorProgress ep("export", "Exporting for OSX", 3, true);
if (p_debug)
src_pkg_name = p_preset->get("custom_package/debug");
src_pkg_name = p_preset->get("custom_template/debug");
else
src_pkg_name = p_preset->get("custom_package/release");
src_pkg_name = p_preset->get("custom_template/release");
if (src_pkg_name == "") {
String err;
@ -796,33 +796,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
bool valid = false;
String err;
bool valid = false;
if (exists_export_template("osx.zip", &err)) {
valid = true;
}
// Look for export templates (first official, and if defined custom templates).
if (p_preset->get("custom_package/debug") != "") {
if (FileAccess::exists(p_preset->get("custom_package/debug"))) {
valid = true;
} else {
bool dvalid = exists_export_template("osx.zip", &err);
bool rvalid = dvalid; // Both in the same ZIP.
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (p_preset->get("custom_package/release") != "") {
if (FileAccess::exists(p_preset->get("custom_package/release"))) {
valid = true;
} else {
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
}
}
valid = dvalid || rvalid;
r_missing_templates = !valid;
if (!err.empty())
r_error = err;
r_missing_templates = !valid;
return valid;
}

View file

@ -1090,15 +1090,14 @@ public:
}
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = true;
bool valid = false;
// Look for export templates (first official, and if defined custom templates).
Platform arch = (Platform)(int)(p_preset->get("architecture/target"));
String custom_debug_binary = p_preset->get("custom_template/debug");
String custom_release_binary = p_preset->get("custom_template/release");
String platform_infix;
switch (arch) {
case EditorExportPlatformUWP::ARM: {
platform_infix = "arm";
@ -1111,38 +1110,26 @@ public:
} break;
}
if (!exists_export_template("uwp_" + platform_infix + "_debug.zip", &err) || !exists_export_template("uwp_" + platform_infix + "_release.zip", &err)) {
valid = false;
r_missing_templates = true;
}
bool dvalid = exists_export_template("uwp_" + platform_infix + "_debug.zip", &err);
bool rvalid = exists_export_template("uwp_" + platform_infix + "_release.zip", &err);
if (!valid && custom_debug_binary == "" && custom_release_binary == "") {
if (!err.empty()) {
r_error = err;
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
}
return valid;
}
bool dvalid = true;
bool rvalid = true;
valid = dvalid || rvalid;
r_missing_templates = !valid;
if (!FileAccess::exists(custom_debug_binary)) {
dvalid = false;
err += TTR("Custom debug template not found.") + "\n";
}
if (!FileAccess::exists(custom_release_binary)) {
rvalid = false;
err += TTR("Custom release template not found.") + "\n";
}
if (dvalid || rvalid)
valid = true;
if (!valid) {
r_error = err;
return valid;
}
// Validate the rest of the configuration.
if (!_valid_resource_name(p_preset->get("package/short_name"))) {
valid = false;