From 0e6cc6ec4ba1c5cee8815303cd5b98e14a30ee29 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 27 Mar 2025 10:31:59 +0000 Subject: [PATCH] Use working directory for `aapt` commands --- src/build_settings.cpp | 4 --- src/package_command.cpp | 46 +++++++++++++++++++++---- src/path.cpp | 76 ++++++++++++++++++++++++++++++++++------- 3 files changed, 104 insertions(+), 22 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 100a01da9..1d20ed82b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1585,10 +1585,6 @@ gb_internal void init_android_values(bool with_sdk) { gb_printf_err("Error: -android-keystore_alias: has not been set\n"); gb_exit(1); } - if (bc->android_manifest.len == 0) { - gb_printf_err("Error: -android-manifest: has not been set\n"); - gb_exit(1); - } } } diff --git a/src/package_command.cpp b/src/package_command.cpp index de2fd9d3e..43db46521 100644 --- a/src/package_command.cpp +++ b/src/package_command.cpp @@ -10,11 +10,20 @@ i32 package(String init_directory) { } -i32 package_android(String init_directory) { - i32 result = 0; +i32 package_android(String original_init_directory) { + TEMPORARY_ALLOCATOR_GUARD(); + i32 result = 0; init_android_values(/*with_sdk*/true); + bool init_directory_ok = false; + String init_directory = path_to_fullpath(temporary_allocator(), original_init_directory, &init_directory_ok); + if (!init_directory_ok) { + gb_printf_err("Error: '%.*s' is not a valid directory", LIT(original_init_directory)); + return 1; + } + init_directory = normalize_path(temporary_allocator(), init_directory, NIX_SEPARATOR_STRING); + int const ODIN_ANDROID_API_LEVEL = build_context.ODIN_ANDROID_API_LEVEL; String android_sdk_build_tools = concatenate3_strings(temporary_allocator(), @@ -116,16 +125,37 @@ i32 package_android(String init_directory) { gbString cmd = gb_string_make(heap_allocator(), ""); 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 currectly 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); TIME_SECTION("Android aapt"); { + 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")); + } + 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 (build_context.android_manifest.len != 0) { - cmd = gb_string_append_fmt(cmd, " -M \"%.*s\"", LIT(build_context.android_manifest)); + if (manifest.len != 0) { + 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)); @@ -138,16 +168,19 @@ i32 package_android(String init_directory) { 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 android"); if (build_context.android_keystore.len != 0) { - cmd = gb_string_append_fmt(cmd, " -keystore \"%.*s\"", LIT(build_context.android_keystore)); + String keystore = concatenate_strings(temporary_allocator(), current_directory, build_context.android_keystore); + 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) { - cmd = gb_string_append_fmt(cmd, " \"%.*s\"", LIT(build_context.android_keystore_alias)); + 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); @@ -158,6 +191,7 @@ i32 package_android(String init_directory) { TIME_SECTION("Android zipalign"); { + TEMPORARY_ALLOCATOR_GUARD(); gb_string_clear(cmd); cmd = gb_string_append_length(cmd, android_sdk_build_tools.text, android_sdk_build_tools.len); diff --git a/src/path.cpp b/src/path.cpp index 2c08ddd98..2217622c6 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -30,28 +30,80 @@ gb_internal String remove_directory_from_path(String const &s) { } -// NOTE(Mark Naughton): getcwd as String -#if !defined(GB_SYSTEM_WINDOWS) -gb_internal String get_current_directory(void) { - char cwd[256]; - getcwd(cwd, 256); +#if defined(GB_SYSTEM_WINDOWS) +gb_global SRWLOCK cwd_lock; - return make_string_c(cwd); +String get_working_directory(gbAllocator allocator) { + AcquireSRWLockExclusive(&cwd_lock); + + TEMPORARY_ALLOCATOR_GUARD(); + + DWORD sz_utf16 = GetCurrentDirectoryW(0, nullptr); + wchar_t *dir_buf_wstr = gb_alloc_array(temporary_allocator(), wchar_t, sz_utf16); + if (dir_buf_wstr == nullptr) { + ReleaseSRWLockExclusive(&cwd_lock); + return {}; + } + + DWORD n = GetCurrentDirectoryW(sz_utf16, dir_buf_wstr); + GB_ASSERT(n+1 == sz_utf16); + ReleaseSRWLockExclusive(&cwd_lock); + + + isize buf_len = sz_utf16*4; + u8 *buf = gb_alloc_array(allocator, u8, buf_len); + gb_ucs2_to_utf8(buf, buf_len, cast(u16 *)dir_buf_wstr); + + return make_string_c(cast(char const *)buf); +} + +bool set_working_directory(String dir) { + bool ok = false; + TEMPORARY_ALLOCATOR_GUARD(); + + char const *cdir = alloc_cstring(temporary_allocator(), dir); + wchar_t *wstr = gb__alloc_utf8_to_ucs2(temporary_allocator(), cdir, nullptr); + + AcquireSRWLockExclusive(&cwd_lock); + + ok = SetCurrentDirectoryW(wstr); + + ReleaseSRWLockExclusive(&cwd_lock); + + return ok; } #else -gb_internal String get_current_directory(void) { - gbAllocator a = heap_allocator(); - wchar_t cwd[256]; - GetCurrentDirectoryW(256, cwd); +String get_working_directory(gbAllocator allocator) { + TEMPORARY_ALLOCATOR_GUARD(); - String16 wstr = make_string16_c(cwd); + auto buf = array_make(temporary_allocator()); + size_t size = PATH_MAX: - return string16_to_string(a, wstr); + char const *cwd; + for (; cwd == nullptr; size *= 2) { + array_resize(&buf, size); + + cwd = getcwd(buf.data, buf.count); + if cwd == nullptr && errno() != ERANGE { + return {}; + } + } + + return copy_string(allocator, make_string_c(cwd)); } + +bool set_working_directory(String dir) { + TEMPORARY_ALLOCATOR_GUARD(); + char const *cdir = alloc_cstring(temporary_allocator(), dir); + return !chdir(cdir); +} + #endif + + gb_internal bool path_is_directory(String path); gb_internal String directory_from_path(String const &s) {