mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-30 18:02:02 +00:00
Merge pull request #5003 from IllusionMan1212/more-android-fixes
Android bundling improvements
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,52 +134,36 @@ 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");
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
result = system_exec_command_line_app("android-jarsigner", cmd);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
TIME_SECTION("Android zipalign");
|
||||
{
|
||||
TEMPORARY_ALLOCATOR_GUARD();
|
||||
@@ -206,5 +180,33 @@ i32 bundle_android(String original_init_directory) {
|
||||
}
|
||||
}
|
||||
|
||||
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, "apksigner");
|
||||
cmd = gb_string_appendc(cmd, " sign");
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
30
src/main.cpp
30
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) {
|
||||
|
||||
Reference in New Issue
Block a user