Przeglądaj źródła

android bundling improvements

replace `jarsigner` with build tools' `apksigner` which is capable of using newer signature schemes

remove the `android-manifest` flag and assume the file exists in the directory we're bundling

make `android-keystore-alias` and `android-keystore-password` optional.
The former is not needed if there's only one key in the keystore, and the latter will be prompted by `apksigner` if missing

don't change the working directory to the bundled directory to prevent confusion when passing a relative path to
`android-keystore`

add the `res`, `assets`, and `lib` directories to the bundle if they exist in the bundled directory
IllusionMan1212 5 miesięcy temu
rodzic
commit
da885fb807
3 zmienionych plików z 42 dodań i 64 usunięć
  1. 0 17
      src/build_settings.cpp
  2. 40 38
      src/bundle_command.cpp
  3. 2 9
      src/main.cpp

+ 0 - 17
src/build_settings.cpp

@@ -551,11 +551,9 @@ struct BuildContext {
 	String ODIN_ANDROID_NDK_TOOLCHAIN_LIB_LEVEL;
 	String ODIN_ANDROID_NDK_TOOLCHAIN_SYSROOT;
 
-	String ODIN_ANDROID_JAR_SIGNER;
 	String android_keystore;
 	String android_keystore_alias;
 	String android_keystore_password;
-	String android_manifest;
 };
 
 gb_global BuildContext build_context = {0};
@@ -1574,30 +1572,15 @@ gb_internal void init_android_values(bool with_sdk) {
 	bc->ODIN_ANDROID_NDK_TOOLCHAIN_SYSROOT = concatenate_strings(permanent_allocator(), bc->ODIN_ANDROID_NDK_TOOLCHAIN, str_lit("sysroot/"));
 
 
-	bc->ODIN_ANDROID_JAR_SIGNER = normalize_path(permanent_allocator(), make_string_c(gb_get_env("ODIN_ANDROID_JAR_SIGNER", permanent_allocator())), NIX_SEPARATOR_STRING);
-	// Strip trailing slash so system() call doesn't fail.
-	bc->ODIN_ANDROID_JAR_SIGNER = substring(bc->ODIN_ANDROID_JAR_SIGNER, 0, bc->ODIN_ANDROID_JAR_SIGNER.len - 1);
 	if (with_sdk) {
 		if (bc->ODIN_ANDROID_SDK.len == 0)  {
 			gb_printf_err("Error: ODIN_ANDROID_SDK not set, which is required for -build-mode:executable for -subtarget:android");
 			gb_exit(1);
 		}
-		if (bc->ODIN_ANDROID_JAR_SIGNER.len == 0) {
-			gb_printf_err("Error: ODIN_ANDROID_JAR_SIGNER not set, which is required for -build-mode:executable for -subtarget:android");
-			gb_exit(1);
-		}
 		if (bc->android_keystore.len == 0) {
 			gb_printf_err("Error: -android-keystore:<string> has not been set\n");
 			gb_exit(1);
 		}
-		if (bc->android_keystore_alias.len == 0) {
-			gb_printf_err("Error: -android-keystore_alias:<string> has not been set\n");
-			gb_exit(1);
-		}
-		if (bc->android_keystore_password.len == 0) {
-			gb_printf_err("Error: -android-keystore-password:<string> has not been set\n");
-			gb_exit(1);
-		}
 	}
 }
 

+ 40 - 38
src/bundle_command.cpp

@@ -126,16 +126,6 @@ i32 bundle_android(String original_init_directory) {
 	defer (gb_string_free(cmd));
 
 
-	String current_directory = normalize_path(temporary_allocator(), get_working_directory(temporary_allocator()), NIX_SEPARATOR_STRING);
-	defer (set_working_directory(current_directory));
-
-	if (current_directory.len != 0) {
-		bool ok = set_working_directory(init_directory);
-		if (!ok) {
-			gb_printf_err("Error: Unable to correctly set the current working directory to '%.*s'\n", LIT(init_directory));
-		}
-	}
-
 	String output_filename = str_lit("test");
 	String output_apk = path_remove_extension(output_filename);
 
@@ -144,63 +134,75 @@ i32 bundle_android(String original_init_directory) {
 		TEMPORARY_ALLOCATOR_GUARD();
 		gb_string_clear(cmd);
 
-		String manifest = {};
-		if (build_context.android_manifest.len != 0) {
-			manifest = concatenate_strings(temporary_allocator(), current_directory, build_context.android_manifest);
-		} else {
-			manifest = concatenate_strings(temporary_allocator(), init_directory, str_lit("AndroidManifest.xml"));
-		}
+		String manifest = concatenate_strings(temporary_allocator(), init_directory, str_lit("AndroidManifest.xml"));
 
 		cmd = gb_string_append_length(cmd, android_sdk_build_tools.text, android_sdk_build_tools.len);
 		cmd = gb_string_appendc(cmd, "aapt");
 		cmd = gb_string_appendc(cmd, " package -f");
-		if (manifest.len != 0) {
-			cmd = gb_string_append_fmt(cmd, " -M \"%.*s\"", LIT(manifest));
-		}
+		cmd = gb_string_append_fmt(cmd, " -M \"%.*s\"", LIT(manifest));
 		cmd = gb_string_append_fmt(cmd, " -I \"%.*sandroid.jar\"", LIT(android_sdk_platforms));
 		cmd = gb_string_append_fmt(cmd, " -F \"%.*s.apk-build\"", LIT(output_apk));
 
+		String resources_dir = concatenate_strings(temporary_allocator(), init_directory, str_lit("res"));
+		if (gb_file_exists((const char *)resources_dir.text)) {
+			cmd = gb_string_append_fmt(cmd, " -S \"%.*s\"", LIT(resources_dir));
+		}
+
+		String assets_dir = concatenate_strings(temporary_allocator(), init_directory, str_lit("assets"));
+		if (gb_file_exists((const char *)assets_dir.text)) {
+			cmd = gb_string_append_fmt(cmd, " -A \"%.*s\"", LIT(assets_dir));
+		}
+
+		String lib_dir = concatenate_strings(temporary_allocator(), init_directory, str_lit("lib"));
+		if (gb_file_exists((const char *)lib_dir.text)) {
+			cmd = gb_string_append_fmt(cmd, " \"%.*s\"", LIT(lib_dir));
+		}
+
 		result = system_exec_command_line_app("android-aapt", cmd);
 		if (result) {
 			return result;
 		}
 	}
 
-	TIME_SECTION("Android jarsigner");
+	TIME_SECTION("Android zipalign");
 	{
 		TEMPORARY_ALLOCATOR_GUARD();
 		gb_string_clear(cmd);
 
-		cmd = gb_string_append_length(cmd, build_context.ODIN_ANDROID_JAR_SIGNER.text, build_context.ODIN_ANDROID_JAR_SIGNER.len);
-		cmd = gb_string_append_fmt(cmd, " -storepass \"%.*s\"", LIT(build_context.android_keystore_password));
-		if (build_context.android_keystore.len != 0) {
-			String keystore = normalize_path(temporary_allocator(), build_context.android_keystore, NIX_SEPARATOR_STRING);
-			keystore = substring(keystore, 0, keystore.len - 1);
-			cmd = gb_string_append_fmt(cmd, " -keystore \"%.*s\"", LIT(keystore));
-		}
-		cmd = gb_string_append_fmt(cmd, " \"%.*s.apk-build\"", LIT(output_apk));
-		if (build_context.android_keystore_alias.len != 0) {
-			String keystore_alias = build_context.android_keystore_alias;
-			cmd = gb_string_append_fmt(cmd, " \"%.*s\"", LIT(keystore_alias));
-		}
+		cmd = gb_string_append_length(cmd, android_sdk_build_tools.text, android_sdk_build_tools.len);
+		cmd = gb_string_appendc(cmd, "zipalign");
+		cmd = gb_string_appendc(cmd, " -f 4");
+		cmd = gb_string_append_fmt(cmd, " \"%.*s.apk-build\" \"%.*s.apk\"", LIT(output_apk), LIT(output_apk));
 
-		result = system_exec_command_line_app("android-jarsigner", cmd);
+		result = system_exec_command_line_app("android-zipalign", cmd);
 		if (result) {
 			return result;
 		}
 	}
 
-	TIME_SECTION("Android zipalign");
+	TIME_SECTION("Android apksigner");
 	{
 		TEMPORARY_ALLOCATOR_GUARD();
 		gb_string_clear(cmd);
 
 		cmd = gb_string_append_length(cmd, android_sdk_build_tools.text, android_sdk_build_tools.len);
-		cmd = gb_string_appendc(cmd, "zipalign");
-		cmd = gb_string_appendc(cmd, " -f 4");
-		cmd = gb_string_append_fmt(cmd, " \"%.*s.apk-build\" \"%.*s.apk\"", LIT(output_apk), LIT(output_apk));
+		cmd = gb_string_appendc(cmd, "apksigner");
+		cmd = gb_string_appendc(cmd, " sign");
 
-		result = system_exec_command_line_app("android-zipalign", cmd);
+		String keystore = normalize_path(temporary_allocator(), build_context.android_keystore, NIX_SEPARATOR_STRING);
+		keystore = substring(keystore, 0, keystore.len - 1);
+		cmd = gb_string_append_fmt(cmd, " --ks \"%.*s\"", LIT(keystore));
+
+		if (build_context.android_keystore_alias.len != 0) {
+			cmd = gb_string_append_fmt(cmd, " --ks-key-alias \"%.*s\"", LIT(build_context.android_keystore_alias));
+		}
+		if (build_context.android_keystore_password.len != 0) {
+			cmd = gb_string_append_fmt(cmd, " --ks-pass pass:\"%.*s\"", LIT(build_context.android_keystore_password));
+		}
+
+		cmd = gb_string_append_fmt(cmd, " \"%.*s.apk\"", LIT(output_apk));
+
+		result = system_exec_command_line_app("android-apksigner", cmd);
 		if (result) {
 			return result;
 		}

+ 2 - 9
src/main.cpp

@@ -413,7 +413,6 @@ enum BuildFlagKind {
 	BuildFlag_AndroidKeystore,
 	BuildFlag_AndroidKeystoreAlias,
 	BuildFlag_AndroidKeystorePassword,
-	BuildFlag_AndroidManifest,
 
 	BuildFlag_COUNT,
 };
@@ -634,7 +633,6 @@ gb_internal bool parse_build_flags(Array<String> args) {
 	add_flag(&build_flags, BuildFlag_AndroidKeystore,         str_lit("android-keystore"),          BuildFlagParam_String,  Command_bundle_android);
 	add_flag(&build_flags, BuildFlag_AndroidKeystoreAlias,    str_lit("android-keystore-alias"),    BuildFlagParam_String,  Command_bundle_android);
 	add_flag(&build_flags, BuildFlag_AndroidKeystorePassword, str_lit("android-keystore-password"), BuildFlagParam_String,  Command_bundle_android);
-	add_flag(&build_flags, BuildFlag_AndroidManifest,         str_lit("android-manifest"),          BuildFlagParam_String,  Command_bundle_android);
 
 
 	Array<String> flag_args = {};
@@ -1671,11 +1669,6 @@ gb_internal bool parse_build_flags(Array<String> args) {
 							GB_ASSERT(value.kind == ExactValue_String);
 							build_context.android_keystore_password = value.value_string;
 							break;
-
-						case BuildFlag_AndroidManifest:
-							GB_ASSERT(value.kind == ExactValue_String);
-							build_context.android_manifest = value.value_string;
-							break;
 						}
 					}
 
@@ -2208,7 +2201,7 @@ gb_internal void remove_temp_files(lbGenerator *gen) {
 		return;
 	}
 
-	TIME_SECTION("remove keep temp files");
+	TIME_SECTION("remove temp files");
 
 	for (String const &path : gen->output_temp_paths) {
 		gb_file_remove(cast(char const *)path.text);
@@ -2560,7 +2553,7 @@ gb_internal void print_show_help(String const arg0, String command, String optio
 		if (print_flag("-minimum-os-version:<string>")) {
 			print_usage_line(2, "Sets the minimum OS version targeted by the application.");
 			print_usage_line(2, "Default: -minimum-os-version:11.0.0");
-			print_usage_line(2, "Only used when target is Darwin, if given, linking mismatched versions will emit a warning.");
+			print_usage_line(2, "Only used when target is Darwin or subtarget is Android, if given, linking mismatched versions will emit a warning.");
 		}
 	}