Merge pull request #46139 from m4gr3d/add_verbose_logging_android_export_master
Improve verbose logging for the Android export process
This commit is contained in:
commit
622c4fe683
2 changed files with 80 additions and 3 deletions
|
@ -775,6 +775,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
}
|
||||
|
||||
void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) {
|
||||
print_verbose("Building temporary manifest..");
|
||||
String manifest_text =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
"<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
|
||||
|
@ -795,6 +796,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
manifest_text += _get_application_tag(p_preset, plugins_names);
|
||||
manifest_text += "</manifest>\n";
|
||||
String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release"));
|
||||
|
||||
print_verbose("Storing manifest into " + manifest_path + ": " + "\n" + manifest_text);
|
||||
store_string_at_path(manifest_path, manifest_text);
|
||||
}
|
||||
|
||||
|
@ -1476,14 +1479,19 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
if (!project_splash_path.is_empty()) {
|
||||
splash_image.instance();
|
||||
print_verbose("Loading splash image: " + project_splash_path);
|
||||
const Error err = ImageLoader::load_image(project_splash_path, splash_image);
|
||||
if (err) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")");
|
||||
}
|
||||
splash_image.unref();
|
||||
}
|
||||
}
|
||||
|
||||
if (splash_image.is_null()) {
|
||||
// Use the default
|
||||
print_verbose("Using default splash image.");
|
||||
splash_image = Ref<Image>(memnew(Image(boot_splash_png)));
|
||||
}
|
||||
|
||||
|
@ -1494,6 +1502,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
bg_color = boot_splash_bg_color;
|
||||
}
|
||||
|
||||
print_verbose("Creating splash background color image.");
|
||||
splash_bg_color_image.instance();
|
||||
splash_bg_color_image->create(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format());
|
||||
splash_bg_color_image->fill(bg_color);
|
||||
|
@ -1508,19 +1517,24 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
// Regular icon: user selection -> project icon -> default.
|
||||
String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
|
||||
print_verbose("Loading regular icon from " + path);
|
||||
if (path.is_empty() || ImageLoader::load_image(path, icon) != OK) {
|
||||
print_verbose("- falling back to project icon: " + project_icon_path);
|
||||
ImageLoader::load_image(project_icon_path, icon);
|
||||
}
|
||||
|
||||
// Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default).
|
||||
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges();
|
||||
print_verbose("Loading adaptive foreground icon from " + path);
|
||||
if (path.is_empty() || ImageLoader::load_image(path, foreground) != OK) {
|
||||
print_verbose("- falling back to using the regular icon");
|
||||
foreground = icon;
|
||||
}
|
||||
|
||||
// Adaptive background: user selection -> default.
|
||||
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges();
|
||||
if (!path.is_empty()) {
|
||||
print_verbose("Loading adaptive background icon from " + path);
|
||||
ImageLoader::load_image(path, background);
|
||||
}
|
||||
}
|
||||
|
@ -1542,6 +1556,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
const Ref<Image> &background) {
|
||||
// Store the splash image
|
||||
if (splash_image.is_valid() && !splash_image->is_empty()) {
|
||||
print_verbose("Storing splash image in " + String(SPLASH_IMAGE_EXPORT_PATH));
|
||||
Vector<uint8_t> data;
|
||||
_load_image_data(splash_image, data);
|
||||
store_image(SPLASH_IMAGE_EXPORT_PATH, data);
|
||||
|
@ -1549,6 +1564,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
// Store the splash bg color image
|
||||
if (splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
|
||||
print_verbose("Storing splash background image in " + String(SPLASH_BG_COLOR_PATH));
|
||||
Vector<uint8_t> data;
|
||||
_load_image_data(splash_bg_color_image, data);
|
||||
store_image(SPLASH_BG_COLOR_PATH, data);
|
||||
|
@ -1559,12 +1575,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
for (int i = 0; i < icon_densities_count; ++i) {
|
||||
if (main_image.is_valid() && !main_image->is_empty()) {
|
||||
print_verbose("Processing launcher icon for dimension " + itos(launcher_icons[i].dimensions) + " into " + launcher_icons[i].export_path);
|
||||
Vector<uint8_t> data;
|
||||
_process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data);
|
||||
store_image(launcher_icons[i], data);
|
||||
}
|
||||
|
||||
if (foreground.is_valid() && !foreground->is_empty()) {
|
||||
print_verbose("Processing launcher adaptive icon foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path);
|
||||
Vector<uint8_t> data;
|
||||
_process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground,
|
||||
launcher_adaptive_icon_foregrounds[i].dimensions, data);
|
||||
|
@ -1572,6 +1590,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
}
|
||||
|
||||
if (background.is_valid() && !background->is_empty()) {
|
||||
print_verbose("Processing launcher adaptive icon background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path);
|
||||
Vector<uint8_t> data;
|
||||
_process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background,
|
||||
launcher_adaptive_icon_backgrounds[i].dimensions, data);
|
||||
|
@ -2239,6 +2258,7 @@ public:
|
|||
String release_password = p_preset->get("keystore/release_password");
|
||||
|
||||
String apksigner = get_apksigner_path();
|
||||
print_verbose("Starting signing of the " + export_label + " binary using " + apksigner);
|
||||
if (!FileAccess::exists(apksigner)) {
|
||||
EditorNode::add_io_error("'apksigner' could not be found.\nPlease check the command is available in the Android SDK build-tools directory.\nThe resulting " + export_label + " is unsigned.");
|
||||
return OK;
|
||||
|
@ -2287,6 +2307,10 @@ public:
|
|||
args.push_back("--ks-key-alias");
|
||||
args.push_back(user);
|
||||
args.push_back(export_path);
|
||||
if (p_debug) {
|
||||
// We only print verbose logs for debug builds to avoid leaking release keystore credentials.
|
||||
print_verbose("Signing debug binary using: " + String("\n") + apksigner + " " + join_list(args, String(" ")));
|
||||
}
|
||||
int retval;
|
||||
OS::get_singleton()->execute(apksigner, args, nullptr, &retval);
|
||||
if (retval) {
|
||||
|
@ -2302,24 +2326,41 @@ public:
|
|||
args.push_back("verify");
|
||||
args.push_back("--verbose");
|
||||
args.push_back(export_path);
|
||||
if (p_debug) {
|
||||
print_verbose("Verifying signed build using: " + String("\n") + apksigner + " " + join_list(args, String(" ")));
|
||||
}
|
||||
|
||||
OS::get_singleton()->execute(apksigner, args, nullptr, &retval);
|
||||
if (retval) {
|
||||
EditorNode::add_io_error("'apksigner' verification of " + export_label + " failed.");
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
print_verbose("Successfully completed signing build.");
|
||||
return OK;
|
||||
}
|
||||
|
||||
void _clear_assets_directory() {
|
||||
DirAccessRef da_res = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (da_res->dir_exists("res://android/build/assets")) {
|
||||
print_verbose("Clearing assets directory..");
|
||||
DirAccessRef da_assets = DirAccess::open("res://android/build/assets");
|
||||
da_assets->erase_contents_recursive();
|
||||
da_res->remove("res://android/build/assets");
|
||||
}
|
||||
}
|
||||
|
||||
String join_list(List<String> parts, const String &separator) const {
|
||||
String ret;
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
if (i > 0) {
|
||||
ret += separator;
|
||||
}
|
||||
ret += parts[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override {
|
||||
int export_format = int(p_preset->get("custom_template/export_format"));
|
||||
bool should_sign = p_preset->get("package/signed");
|
||||
|
@ -2339,6 +2380,15 @@ public:
|
|||
bool apk_expansion = p_preset->get("apk_expansion/enable");
|
||||
Vector<String> enabled_abis = get_enabled_abis(p_preset);
|
||||
|
||||
print_verbose("Exporting for Android...");
|
||||
print_verbose("- debug build: " + bool_to_string(p_debug));
|
||||
print_verbose("- export path: " + p_path);
|
||||
print_verbose("- export format: " + itos(export_format));
|
||||
print_verbose("- sign build: " + bool_to_string(should_sign));
|
||||
print_verbose("- custom build enabled: " + bool_to_string(use_custom_build));
|
||||
print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion));
|
||||
print_verbose("- enabled abis: " + String(",").join(enabled_abis));
|
||||
|
||||
Ref<Image> splash_image;
|
||||
Ref<Image> splash_bg_color_image;
|
||||
load_splash_refs(splash_image, splash_bg_color_image);
|
||||
|
@ -2374,14 +2424,17 @@ public:
|
|||
}
|
||||
|
||||
if (use_custom_build) {
|
||||
print_verbose("Starting custom build..");
|
||||
//test that installed build version is alright
|
||||
{
|
||||
print_verbose("Checking build version..");
|
||||
FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::READ);
|
||||
if (!f) {
|
||||
EditorNode::get_singleton()->show_warning(TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
|
||||
return ERR_UNCONFIGURED;
|
||||
}
|
||||
String version = f->get_line().strip_edges();
|
||||
print_verbose("- build version: " + version);
|
||||
f->close();
|
||||
if (version != VERSION_FULL_CONFIG) {
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Android build version mismatch:\n Template installed: %s\n Godot Version: %s\nPlease reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
|
||||
|
@ -2389,7 +2442,8 @@ public:
|
|||
}
|
||||
}
|
||||
String sdk_path = EDITOR_GET("export/android/android_sdk_path");
|
||||
ERR_FAIL_COND_V_MSG(sdk_path == "", ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at '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'.");
|
||||
print_verbose("Android sdk path: " + sdk_path);
|
||||
|
||||
// TODO: should we use "package/name" or "application/config/name"?
|
||||
String project_name = get_project_name(p_preset->get("package/name"));
|
||||
|
@ -2405,20 +2459,24 @@ public:
|
|||
//stores all the project files inside the Gradle project directory. Also includes all ABIs
|
||||
_clear_assets_directory();
|
||||
if (!apk_expansion) {
|
||||
print_verbose("Exporting project files..");
|
||||
err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, NULL, ignore_so_file);
|
||||
if (err != OK) {
|
||||
EditorNode::add_io_error("Could not export project files to gradle project\n");
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
print_verbose("Saving apk expansion file..");
|
||||
err = save_apk_expansion_file(p_preset, p_path);
|
||||
if (err != OK) {
|
||||
EditorNode::add_io_error("Could not write expansion package file!");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
print_verbose("Storing command line flags..");
|
||||
store_file_at_path("res://android/build/assets/_cl_", command_line_flags);
|
||||
|
||||
print_verbose("Updating ANDROID_HOME environment to " + sdk_path);
|
||||
OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required
|
||||
String build_command;
|
||||
|
||||
|
@ -2458,6 +2516,8 @@ public:
|
|||
cmdline.push_back(apk_build_command);
|
||||
}
|
||||
|
||||
cmdline.push_back("-p"); // argument to specify the start directory.
|
||||
cmdline.push_back(build_path); // start directory.
|
||||
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
|
||||
cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code.
|
||||
cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name.
|
||||
|
@ -2467,6 +2527,13 @@ public:
|
|||
cmdline.push_back("-Pplugins_maven_repos=" + custom_maven_repos); // argument to specify the list of custom maven repos for the plugins dependencies.
|
||||
cmdline.push_back("-Pperform_zipalign=" + zipalign_flag); // argument to specify whether the build should be zipaligned.
|
||||
cmdline.push_back("-Pperform_signing=" + sign_flag); // argument to specify whether the build should be signed.
|
||||
|
||||
// NOTE: The release keystore is not included in the verbose logging
|
||||
// to avoid accidentally leaking sensitive information when sharing verbose logs for troubleshooting.
|
||||
// Any non-sensitive additions to the command line arguments must be done above this section.
|
||||
// Sensitive additions must be done below the logging statement.
|
||||
print_verbose("Build Android project using gradle command: " + String("\n") + build_command + " " + join_list(cmdline, String(" ")));
|
||||
|
||||
if (should_sign && !p_debug) {
|
||||
// Pass the release keystore info as well
|
||||
String release_keystore = p_preset->get("keystore/release");
|
||||
|
@ -2481,8 +2548,6 @@ public:
|
|||
cmdline.push_back("-Prelease_keystore_alias=" + release_username); // argument to specify the release keystore alias.
|
||||
cmdline.push_back("-Prelease_keystore_password=" + release_password); // argument to specity the release keystore password.
|
||||
}
|
||||
cmdline.push_back("-p"); // argument to specify the start directory.
|
||||
cmdline.push_back(build_path); // start directory.
|
||||
|
||||
int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Building Android Project (gradle)"), build_command, cmdline);
|
||||
if (result != 0) {
|
||||
|
@ -2513,15 +2578,18 @@ public:
|
|||
copy_args.push_back("-Pexport_path=file:" + export_path);
|
||||
copy_args.push_back("-Pexport_filename=" + export_filename);
|
||||
|
||||
print_verbose("Copying Android binary using gradle command: " + String("\n") + build_command + " " + join_list(copy_args, String(" ")));
|
||||
int copy_result = EditorNode::get_singleton()->execute_and_show_output(TTR("Moving output"), build_command, copy_args);
|
||||
if (copy_result != 0) {
|
||||
EditorNode::get_singleton()->show_warning(TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
print_verbose("Successfully completed Android custom build.");
|
||||
return OK;
|
||||
}
|
||||
// This is the start of the Legacy build system
|
||||
print_verbose("Starting legacy build system..");
|
||||
if (p_debug)
|
||||
src_apk = p_preset->get("custom_template/debug");
|
||||
else
|
||||
|
|
|
@ -146,6 +146,9 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
|
|||
String dir = p_path.get_base_dir();
|
||||
Error err = create_directory(dir);
|
||||
if (err != OK) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
print_error("Unable to write data into " + p_path);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
FileAccess *fa = FileAccess::open(p_path, FileAccess::WRITE);
|
||||
|
@ -162,12 +165,14 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
|
|||
// This method will be called ONLY when custom build is enabled.
|
||||
Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
|
||||
String dst_path = p_path.replace_first("res://", "res://android/build/assets/");
|
||||
print_verbose("Saving project files from " + p_path + " into " + dst_path);
|
||||
Error err = store_file_at_path(dst_path, p_data);
|
||||
return err;
|
||||
}
|
||||
|
||||
// Creates strings.xml files inside the gradle project for different locales.
|
||||
Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset, const String &project_name) {
|
||||
print_verbose("Creating strings resources for supported locales for project " + project_name);
|
||||
// Stores the string into the default values directory.
|
||||
String processed_default_xml_string = vformat(godot_project_name_xml_string, project_name.xml_escape(true));
|
||||
store_string_at_path("res://android/build/res/values/godot_project_name_string.xml", processed_default_xml_string);
|
||||
|
@ -175,6 +180,9 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
|
|||
// Searches the Gradle project res/ directory to find all supported locales
|
||||
DirAccessRef da = DirAccess::open("res://android/build/res");
|
||||
if (!da) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
print_error("Unable to open Android resources directory.");
|
||||
}
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
da->list_dir_begin();
|
||||
|
@ -193,6 +201,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
|
|||
if (ProjectSettings::get_singleton()->has_setting(property_name)) {
|
||||
String locale_project_name = ProjectSettings::get_singleton()->get(property_name);
|
||||
String processed_xml_string = vformat(godot_project_name_xml_string, locale_project_name.xml_escape(true));
|
||||
print_verbose("Storing project name for locale " + locale + " under " + locale_directory);
|
||||
store_string_at_path(locale_directory, processed_xml_string);
|
||||
} else {
|
||||
// TODO: Once the legacy build system is deprecated we don't need to have xml files for this else branch
|
||||
|
|
Loading…
Reference in a new issue