Add verbose logging to help with troubleshooting the Android build/export process.
This commit is contained in:
parent
6fc9580299
commit
d559def1a9
2 changed files with 81 additions and 3 deletions
platform/android/export
|
@ -786,6 +786,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"
|
||||
|
@ -806,6 +807,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);
|
||||
}
|
||||
|
||||
|
@ -1511,14 +1514,19 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
if (!project_splash_path.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)));
|
||||
}
|
||||
|
||||
|
@ -1529,6 +1537,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);
|
||||
|
@ -1543,19 +1552,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.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.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.empty()) {
|
||||
print_verbose("Loading adaptive background icon from " + path);
|
||||
ImageLoader::load_image(path, background);
|
||||
}
|
||||
}
|
||||
|
@ -1577,6 +1591,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
const Ref<Image> &background) {
|
||||
// Store the splash image
|
||||
if (splash_image.is_valid() && !splash_image->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);
|
||||
|
@ -1584,6 +1599,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
// Store the splash bg color image
|
||||
if (splash_bg_color_image.is_valid() && !splash_bg_color_image->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);
|
||||
|
@ -1594,12 +1610,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
|
||||
for (int i = 0; i < icon_densities_count; ++i) {
|
||||
if (main_image.is_valid() && !main_image->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->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);
|
||||
|
@ -1607,6 +1625,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
}
|
||||
|
||||
if (background.is_valid() && !background->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);
|
||||
|
@ -2207,6 +2226,7 @@ public:
|
|||
|
||||
void _update_custom_build_project() {
|
||||
|
||||
print_verbose("Updating custom build project..");
|
||||
DirAccessRef da = DirAccess::open("res://android");
|
||||
|
||||
ERR_FAIL_COND_MSG(!da, "Cannot open directory 'res://android'.");
|
||||
|
@ -2595,6 +2615,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;
|
||||
|
@ -2645,6 +2666,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, true, NULL, NULL, &retval);
|
||||
if (retval) {
|
||||
|
@ -2660,24 +2685,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, true, NULL, NULL, &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) {
|
||||
int export_format = int(p_preset->get("custom_template/export_format"));
|
||||
bool should_sign = p_preset->get("package/signed");
|
||||
|
@ -2698,6 +2740,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);
|
||||
|
@ -2733,14 +2784,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));
|
||||
|
@ -2748,7 +2802,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.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"));
|
||||
|
@ -2764,20 +2819,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;
|
||||
|
||||
|
@ -2817,6 +2876,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.
|
||||
|
@ -2826,6 +2887,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");
|
||||
|
@ -2840,8 +2908,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) {
|
||||
|
@ -2872,15 +2938,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
|
||||
|
|
|
@ -134,6 +134,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);
|
||||
|
@ -150,12 +153,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) {
|
||||
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);
|
||||
|
@ -163,6 +168,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();
|
||||
|
@ -181,6 +189,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