ソースを参照

Merge pull request #5003 from IllusionMan1212/more-android-fixes

Android bundling improvements
gingerBill 5 ヶ月 前
コミット
eecc6c1f18
4 ファイル変更92 行追加89 行削除
  1. 24 41
      src/build_settings.cpp
  2. 40 38
      src/bundle_command.cpp
  3. 7 1
      src/linker.cpp
  4. 21 9
      src/main.cpp

+ 24 - 41
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);
-		}
 	}
 }
 
@@ -1781,6 +1764,30 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
 		bc->ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_CONSOLE];
 	}
 
+	if (subtarget == Subtarget_Android) {
+		switch (build_context.build_mode) {
+		case BuildMode_DynamicLibrary:
+		case BuildMode_Object:
+		case BuildMode_Assembly:
+		case BuildMode_LLVM_IR:
+			break;
+		default:
+		case BuildMode_Executable:
+		case BuildMode_StaticLibrary:
+			if ((build_context.command_kind & Command__does_build) != 0) {
+				gb_printf_err("Unsupported -build-mode for -subtarget:android\n");
+				gb_printf_err("\tCurrently only supporting: \n");
+				// gb_printf_err("\t\texe\n");
+				gb_printf_err("\t\tshared\n");
+				gb_printf_err("\t\tobject\n");
+				gb_printf_err("\t\tassembly\n");
+				gb_printf_err("\t\tllvm-ir\n");
+				gb_exit(1);
+			}
+			break;
+		}
+	}
+
 	if (metrics->os == TargetOs_darwin && subtarget == Subtarget_iOS) {
 		switch (metrics->arch) {
 		case TargetArch_arm64:
@@ -1900,30 +1907,6 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
 	if (bc->metrics.os == TargetOs_freestanding) {
 		bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR = !bc->ODIN_DEFAULT_TO_PANIC_ALLOCATOR;
 	}
-
-	if (subtarget == Subtarget_Android) {
-		switch (build_context.build_mode) {
-		case BuildMode_DynamicLibrary:
-		case BuildMode_Object:
-		case BuildMode_Assembly:
-		case BuildMode_LLVM_IR:
-			break;
-		default:
-		case BuildMode_Executable:
-		case BuildMode_StaticLibrary:
-			if ((build_context.command_kind & Command__does_build) != 0) {
-				gb_printf_err("Unsupported -build-mode for -subtarget:android\n");
-				gb_printf_err("\tCurrently only supporting: \n");
-				// gb_printf_err("\t\texe\n");
-				gb_printf_err("\t\tshared\n");
-				gb_printf_err("\t\tobject\n");
-				gb_printf_err("\t\tassembly\n");
-				gb_printf_err("\t\tllvm-ir\n");
-				gb_exit(1);
-			}
-			break;
-		}
-	}
 }
 
 #if defined(GB_SYSTEM_WINDOWS)

+ 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;
 		}

+ 7 - 1
src/linker.cpp

@@ -143,7 +143,7 @@ gb_internal i32 linker_stage(LinkerData *gen) {
 			LIT(target_arch_names[build_context.metrics.arch])
 		);
 #endif
-	} else if (build_context.cross_compiling && build_context.different_os) {
+	} else if (build_context.cross_compiling && (build_context.different_os || selected_subtarget != Subtarget_Default)) {
 		switch (selected_subtarget) {
 		case Subtarget_Android:
 			is_cross_linking = true;
@@ -655,6 +655,11 @@ try_cross_linking:;
 				glue = gb_string_append_length(glue, android_glue_object.text, android_glue_object.len);
 				glue = gb_string_appendc(glue, "\" ");
 
+				glue = gb_string_appendc(glue, "--sysroot \"");
+				glue = gb_string_append_length(glue, ODIN_ANDROID_NDK_TOOLCHAIN.text, ODIN_ANDROID_NDK_TOOLCHAIN.len);
+				glue = gb_string_appendc(glue, "sysroot");
+				glue = gb_string_appendc(glue, "\" ");
+
 				glue = gb_string_appendc(glue, "\"-I");
 				glue = gb_string_append_length(glue, ODIN_ANDROID_NDK_TOOLCHAIN.text, ODIN_ANDROID_NDK_TOOLCHAIN.len);
 				glue = gb_string_appendc(glue, "sysroot/usr/include/");
@@ -840,6 +845,7 @@ try_cross_linking:;
 
 			if (is_android) {
 				link_command_line = gb_string_append_fmt(link_command_line, " --target=aarch64-linux-android%d ", ODIN_ANDROID_API_LEVEL);
+				link_command_line = gb_string_appendc(link_command_line, " -nodefaultlibs");
 			}
 			link_command_line = gb_string_appendc(link_command_line, " -Wno-unused-command-line-argument ");
 			link_command_line = gb_string_appendc(link_command_line, object_files);

+ 21 - 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.");
 		}
 	}
 
@@ -2855,6 +2848,25 @@ gb_internal void print_show_help(String const arg0, String command, String optio
 			print_usage_line(2, "Treats warning messages as error messages.");
 		}
 	}
+
+	if (bundle) {
+		print_usage_line(0, "");
+		print_usage_line(1, "Android-specific flags");
+		print_usage_line(0, "");
+		if (print_flag("-android-keystore:<string>")) {
+			print_usage_line(2, "Specifies the keystore file to use to sign the apk.");
+		}
+
+		if (print_flag("-android-keystore-alias:<string>")) {
+			print_usage_line(2, "Specifies the key alias to use when signing the apk");
+			print_usage_line(2, "Can be omitted if the keystore only contains one key");
+		}
+
+		if (print_flag("-android-keystore-password:<string>")) {
+			print_usage_line(2, "Sets the password to use to unlock the keystore");
+			print_usage_line(2, "If this is omitted, the terminal will prompt you to provide it.");
+		}
+	}
 }
 
 gb_internal void print_show_unused(Checker *c) {