From 547c703641afb7c50bdb67fd22e0988b9b5b0a9e Mon Sep 17 00:00:00 2001 From: Jae B Date: Tue, 6 May 2025 13:44:53 +1000 Subject: [PATCH 1/6] add support for 'android:hasCode="false"' --- examples/minimal/android/AndroidManifest.xml | 1 + .../android/src/NativeInvocationHandler.java | 15 --------------- examples/minimal/build.zig | 4 +++- examples/minimal/src/minimal.zig | 10 +++++++++- src/androidbuild/apk.zig | 19 ++++++++++++------- 5 files changed, 25 insertions(+), 24 deletions(-) delete mode 100644 examples/minimal/android/src/NativeInvocationHandler.java diff --git a/examples/minimal/android/AndroidManifest.xml b/examples/minimal/android/AndroidManifest.xml index 86a9394..0b81905 100644 --- a/examples/minimal/android/AndroidManifest.xml +++ b/examples/minimal/android/AndroidManifest.xml @@ -7,6 +7,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:hasCode="false" tools:targetApi="31"> 0) { printErrorsAndExit("misconfigured Android APK", errors.items); } From e9066e7f45accd6314ce77926b223e90250165b0 Mon Sep 17 00:00:00 2001 From: Jae B Date: Tue, 6 May 2025 13:54:58 +1000 Subject: [PATCH 2/6] fix sigset error --- src/android/android.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/android/android.zig b/src/android/android.zig index f712a33..01b9e4f 100644 --- a/src/android/android.zig +++ b/src/android/android.zig @@ -199,7 +199,12 @@ const Panic = struct { // } var act = posix.Sigaction{ .handler = .{ .handler = posix.SIG.DFL }, - .mask = posix.empty_sigset, + .mask = if (builtin.zig_version.major == 0 and builtin.zig_version.minor == 14) + // Legacy 0.14.0 + posix.empty_sigset + else + // 0.15.0-dev+ + posix.sigemptyset(), .flags = 0, }; // To avoid a double-panic, do nothing if an error happens here. From 51e282b5b5f82638d115c98add23023a22d69f59 Mon Sep 17 00:00:00 2001 From: Jae B Date: Tue, 6 May 2025 14:01:48 +1000 Subject: [PATCH 3/6] update "tag" in logger to use constant --- src/android/android.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/android/android.zig b/src/android/android.zig index 01b9e4f..753fbcb 100644 --- a/src/android/android.zig +++ b/src/android/android.zig @@ -92,7 +92,7 @@ const LogWriter = struct { /// logs with the package name. /// /// To workaround this, we bake the package name into the Zig binaries. - var tag: [:0]const u8 = android_builtin.package_name; + const tag: [:0]const u8 = android_builtin.package_name; level: Level, @@ -166,6 +166,7 @@ const Panic = struct { threadlocal var panic_stage: usize = 0; fn panic(message: []const u8, ret_addr: ?usize) noreturn { + if (comptime !builtin.abi.isAndroid()) @compileError("do not use Android panic for non-Android builds"); const first_trace_addr = ret_addr orelse @returnAddress(); panicImpl(first_trace_addr, message); } From eecc835c8d829903899f044c0bb65b897c3fc45e Mon Sep 17 00:00:00 2001 From: Jae B Date: Tue, 6 May 2025 14:04:07 +1000 Subject: [PATCH 4/6] improve documentation on __android_log_write --- src/android/android.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/android/android.zig b/src/android/android.zig index 753fbcb..75f29db 100644 --- a/src/android/android.zig +++ b/src/android/android.zig @@ -13,6 +13,9 @@ const android_builtin = struct { pub const package_name: [:0]const u8 = ab.package_name; }; +/// Writes the constant string text to the log, with priority prio and tag tag. +/// Returns: 1 if the message was written to the log, or -EPERM if it was not; see __android_log_is_loggable(). +/// Source: https://developer.android.com/ndk/reference/group/logging extern "log" fn __android_log_write(prio: c_int, tag: [*c]const u8, text: [*c]const u8) c_int; /// Alternate panic implementation that calls __android_log_write so that you can see the logging via "adb logcat" From c794bd485cc96c796a1f1a81d9bee0f7dca3e075 Mon Sep 17 00:00:00 2001 From: Jae B Date: Tue, 6 May 2025 14:06:40 +1000 Subject: [PATCH 5/6] add branch hint to panic --- src/android/android.zig | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/android/android.zig b/src/android/android.zig index 75f29db..9712d8c 100644 --- a/src/android/android.zig +++ b/src/android/android.zig @@ -169,6 +169,7 @@ const Panic = struct { threadlocal var panic_stage: usize = 0; fn panic(message: []const u8, ret_addr: ?usize) noreturn { + @branchHint(.cold); if (comptime !builtin.abi.isAndroid()) @compileError("do not use Android panic for non-Android builds"); const first_trace_addr = ret_addr orelse @returnAddress(); panicImpl(first_trace_addr, message); @@ -245,14 +246,7 @@ const Panic = struct { /// - Provide custom "io" namespace so we can easily customize getStdErr() to be our own writer /// - Provide other functions from std.debug.* fn panicImpl(first_trace_addr: ?usize, msg: []const u8) noreturn { - // NOTE(jae): 2024-09-22 - // Cannot mark this as cold(true) OR setCold() depending on Zig version as we get an invalid builtin function - // comptime { - // if (builtin.zig_version.minor == 13) - // @setCold(true) - // else - // @cold(true); - // } + @branchHint(.cold); if (enable_segfault_handler) { // If a segfault happens while panicking, we want it to actually segfault, not trigger From 675a4dbd886ccb537e0d4d706639bfdbb55444be Mon Sep 17 00:00:00 2001 From: Jae B Date: Tue, 6 May 2025 14:24:43 +1000 Subject: [PATCH 6/6] better docs --- examples/minimal/build.zig | 4 ++++ src/androidbuild/apk.zig | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/minimal/build.zig b/examples/minimal/build.zig index 62fb283..6df20bd 100644 --- a/examples/minimal/build.zig +++ b/examples/minimal/build.zig @@ -34,6 +34,10 @@ pub fn build(b: *std.Build) void { // Add Java files // - If you have 'android:hasCode="false"' in your AndroidManifest.xml then no Java files are required // see: https://developer.android.com/ndk/samples/sample_na + // + // WARNING: If you do not provide Java files AND android:hasCode="false" isn't explicitly set, then you may get the following error on "adb install" + // Scanning Failed.: Package /data/app/base.apk code is missing] + // // apk.addJavaSourceFile(.{ .file = b.path("android/src/X.java") }); break :blk apk; }; diff --git a/src/androidbuild/apk.zig b/src/androidbuild/apk.zig index 7c1ff39..7a55350 100644 --- a/src/androidbuild/apk.zig +++ b/src/androidbuild/apk.zig @@ -207,7 +207,7 @@ fn doInstallApk(apk: *Apk) std.mem.Allocator.Error!*Step.InstallFile { // This validation rule has been removed because if you have `android:hasCode="false"` in your AndroidManifest.xml file // then you can have no Java files. // - // If you do not provide Java files AND hasCode=false isn't set, then you may get the following error on "adb install" + // If you do not provide Java files AND android:hasCode="false" isn't set, then you may get the following error on "adb install" // - Scanning Failed.: Package /data/app/base.apk code is missing] // // Ideally we may want to do something where we can utilize "aapt2 dump X" to determine if "hasCode" is set and if it isn't, throw