From c52d931394418d4189281a747bf96f514a742bfe Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 13:44:13 +1000 Subject: [PATCH 1/9] add support for external translate-c dependency usage --- src/androidbuild/Apk.zig | 48 ++++++++++++++++++++++++------ test/build/build.zig | 41 +++++++++++++++++++++++++ test/build/build.zig.zon | 5 ++++ test/build/src/build_test_main.zig | 8 +++++ 4 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/androidbuild/Apk.zig b/src/androidbuild/Apk.zig index 60ea8d6..25248bd 100644 --- a/src/androidbuild/Apk.zig +++ b/src/androidbuild/Apk.zig @@ -512,19 +512,49 @@ fn doInstallApk(apk: *Apk) Allocator.Error!*Step.InstallFile { while (iter.next()) |it| { const module = it.value_ptr.*; const root_source_file = module.root_source_file orelse continue; + const c_translate_target = module.resolved_target orelse continue; + if (!c_translate_target.result.abi.isAndroid()) continue; switch (root_source_file) { .generated => |gen| { const step = gen.file.step; - if (step.id != .translate_c) { - continue; - } - const c_translate_target = module.resolved_target orelse continue; - if (!c_translate_target.result.abi.isAndroid()) { - continue; + switch (step.id) { + .translate_c => { + // Detect if using Translate-C vendored version + // + // NOTE(jae): 2026-04-29 + // Longterm this will deprecated from Zig + + const translate_c: *std.Build.Step.TranslateC = @fieldParentPtr("step", step); + translate_c.addIncludePath(.{ .cwd_relative = apk.ndk.include_path }); + translate_c.addSystemIncludePath(.{ .cwd_relative = apk.getSystemIncludePath(c_translate_target) }); + }, + .run => { + // Detect if using Translate-C external dependency and make assumptions about the flags + // we can pass into it such as "isystem" and "-I" + // + // Name: https://codeberg.org/ziglang/translate-c/src/commit/71642ad0084d433f14b091a7b2b109f0be915dbb/build/Translator.zig#L89 + // Imports: https://codeberg.org/ziglang/translate-c/src/commit/71642ad0084d433f14b091a7b2b109f0be915dbb/build/Translator.zig#L103-L104 + if (std.mem.startsWith(u8, step.name, "translate-c ") and + (module.import_table.contains("c_builtins") and module.import_table.contains("helpers"))) + { + const run: *std.Build.Step.Run = @fieldParentPtr("step", step); + + const ndk_include_path: LazyPath = .{ .cwd_relative = apk.ndk.include_path }; + const system_include_path: LazyPath = .{ .cwd_relative = apk.getSystemIncludePath(c_translate_target) }; + + // Exposes the system include path `path` to both translate-c and to `t.mod`. + // https://codeberg.org/ziglang/translate-c/src/commit/71642ad0084d433f14b091a7b2b109f0be915dbb/build/Translator.zig#L207-L211 + module.addSystemIncludePath(system_include_path); + run.addPrefixedDirectoryArg("-isystem", system_include_path); + + // Exposes the include path `path` to both translate-c and to `t.mod`. + // https://codeberg.org/ziglang/translate-c/src/commit/71642ad0084d433f14b091a7b2b109f0be915dbb/build/Translator.zig#L203-L206 + module.addIncludePath(ndk_include_path); + run.addPrefixedDirectoryArg("-I", ndk_include_path); + } + }, + else => continue, } - const translate_c: *std.Build.Step.TranslateC = @fieldParentPtr("step", step); - translate_c.addIncludePath(.{ .cwd_relative = apk.ndk.include_path }); - translate_c.addSystemIncludePath(.{ .cwd_relative = apk.getSystemIncludePath(c_translate_target) }); }, else => continue, } diff --git a/test/build/build.zig b/test/build/build.zig index 304964f..8359181 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -46,10 +46,23 @@ pub fn build(b: *std.Build) void { }; for (targets) |target| { + const translate_c_vendored_mod = testTranslateCVendor(b, target, optimize) orelse return; + const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; + const app_module = b.createModule(.{ .target = target, .optimize = optimize, .root_source_file = b.path("src/build_test_main.zig"), + .imports = &.{ + .{ + .name = "translate_c_internal", + .module = translate_c_vendored_mod, + }, + .{ + .name = "translate_c_external", + .module = translate_c_external_mod, + }, + }, }); var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addLibrary(.{ @@ -89,6 +102,34 @@ pub fn build(b: *std.Build) void { } } +/// Test the Translate-C vendored copy, this will eventually be deprecated and removed from Zig but for now exists in 0.16.X +fn testTranslateCVendor(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) ?*std.Build.Module { + const trans_c = b.addTranslateC(.{ + .root_source_file = b.addWriteFiles().add("android_c.h", + \\#include + ), + .target = target, + .optimize = optimize, + }); + return trans_c.createModule(); +} + +/// Test the Translate-C external dependency version +fn testTranslateCExternal(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) ?*std.Build.Module { + const translate_c_import = b.lazyImport(@This(), "translate_c") orelse return null; + const translate_c = b.lazyDependency("translate_c", .{}) orelse return null; + const Translator = translate_c_import.Translator; + + const trans_libandroid: Translator = .init(translate_c, .{ + .c_source_file = b.addWriteFiles().add("android_c.h", + \\#include + ), + .target = target, + .optimize = optimize, + }); + return trans_libandroid.mod; +} + /// Test calling lazyImport and then calling "resolveTargets" /// /// PR: https://github.com/silbinarywolf/zig-android-sdk/pull/83 diff --git a/test/build/build.zig.zon b/test/build/build.zig.zon index 8023e3a..f90d15c 100644 --- a/test/build/build.zig.zon +++ b/test/build/build.zig.zon @@ -14,6 +14,11 @@ .hash = "N-V-__8AABTXlAV0z_BGl5-lZeOEm_d2gHEhExT2qjxMqQ72", .lazy = true, }, + .translate_c = .{ + .url = "git+https://codeberg.org/ziglang/translate-c#7a1a9fdc4ab00835748a6657ecbb835e3d5d45f7", + .hash = "translate_c-0.0.0-Q_BUWvP1BgCjAk6PWv5286tOlvzD9-X-NkuTzh0KxY0Q", + .lazy = true, + }, }, .paths = .{ "build.zig", diff --git a/test/build/src/build_test_main.zig b/test/build/src/build_test_main.zig index 1023159..4febe70 100644 --- a/test/build/src/build_test_main.zig +++ b/test/build/src/build_test_main.zig @@ -4,6 +4,14 @@ const builtin = @import("builtin"); const android = @import("android"); +comptime { + // For vendored translate-c usage, validate at compile-time that this symbol exists + _ = @import("translate_c_internal").__android_log_write; + + // For external translate-c usage, validate at compile-time that this symbol exists + _ = @import("translate_c_external").__android_log_write; +} + const androidbind = @import("android-bind.zig"); /// custom standard options for Android From 0f446b49499d35bd5cebdbfbbd796dc61131e5d7 Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 14:02:15 +1000 Subject: [PATCH 2/9] do the work --- test/build/build.zig | 20 +++++++++++++------- test/build/build.zig.zon | 2 +- test/build/src/build_test_main.zig | 7 ++++++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/test/build/build.zig b/test/build/build.zig index 8359181..b296460 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -6,6 +6,7 @@ const std = @import("std"); const builtin = @import("builtin"); +const log = std.log; const android = @import("android"); @@ -47,7 +48,6 @@ pub fn build(b: *std.Build) void { for (targets) |target| { const translate_c_vendored_mod = testTranslateCVendor(b, target, optimize) orelse return; - const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; const app_module = b.createModule(.{ .target = target, @@ -58,12 +58,13 @@ pub fn build(b: *std.Build) void { .name = "translate_c_internal", .module = translate_c_vendored_mod, }, - .{ - .name = "translate_c_external", - .module = translate_c_external_mod, - }, }, }); + if (builtin.zig_version.pre == null) { + const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; + app_module.addImport("translate_c_external", translate_c_external_mod); + log.info("testTranslateCExternal: add import 'translate_c_external' to {t}", .{target.result.cpu.arch}); + } var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addLibrary(.{ .name = "main", @@ -116,8 +117,9 @@ fn testTranslateCVendor(b: *std.Build, target: std.Build.ResolvedTarget, optimiz /// Test the Translate-C external dependency version fn testTranslateCExternal(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) ?*std.Build.Module { - const translate_c_import = b.lazyImport(@This(), "translate_c") orelse return null; - const translate_c = b.lazyDependency("translate_c", .{}) orelse return null; + const translate_c_dep_name = "translate_c_stable"; + const translate_c_import = b.lazyImport(@This(), translate_c_dep_name) orelse return null; + const translate_c = b.lazyDependency(translate_c_dep_name, .{}) orelse return null; const Translator = translate_c_import.Translator; const trans_libandroid: Translator = .init(translate_c, .{ @@ -147,6 +149,8 @@ fn testLazyImportAndResolveTargets(b: *std.Build, root_target: std.Build.Resolve break :blk &[0]std.Build.ResolvedTarget{}; }; if (android_targets.len != 4) @panic("expected 'resolveTargets' it to return 4 Android targets"); + + log.info("testLazyImportAndResolveTargets: check that resolving android targets worked. Got: {}", .{android_targets.len}); } /// Test the addLibraryFile functionality @@ -158,6 +162,8 @@ fn testAddLibraryFile(b: *std.Build, apk: *android.Apk) void { apk.addLibraryFile(.armeabi_v7a, vulkan_validation_dep.path("armeabi-v7a/libVkLayer_khronos_validation.so")); apk.addLibraryFile(.x86, vulkan_validation_dep.path("x86/libVkLayer_khronos_validation.so")); apk.addLibraryFile(.x86_64, vulkan_validation_dep.path("x86_64/libVkLayer_khronos_validation.so")); + + log.info("testAddLibraryFile: add vulkan validation layers to APK", .{}); } fn testInstallAndAddRunStep(b: *std.Build, apk: *android.Apk) void { diff --git a/test/build/build.zig.zon b/test/build/build.zig.zon index f90d15c..155c3fd 100644 --- a/test/build/build.zig.zon +++ b/test/build/build.zig.zon @@ -14,7 +14,7 @@ .hash = "N-V-__8AABTXlAV0z_BGl5-lZeOEm_d2gHEhExT2qjxMqQ72", .lazy = true, }, - .translate_c = .{ + .translate_c_stable = .{ .url = "git+https://codeberg.org/ziglang/translate-c#7a1a9fdc4ab00835748a6657ecbb835e3d5d45f7", .hash = "translate_c-0.0.0-Q_BUWvP1BgCjAk6PWv5286tOlvzD9-X-NkuTzh0KxY0Q", .lazy = true, diff --git a/test/build/src/build_test_main.zig b/test/build/src/build_test_main.zig index 4febe70..da7f349 100644 --- a/test/build/src/build_test_main.zig +++ b/test/build/src/build_test_main.zig @@ -9,7 +9,12 @@ comptime { _ = @import("translate_c_internal").__android_log_write; // For external translate-c usage, validate at compile-time that this symbol exists - _ = @import("translate_c_external").__android_log_write; + _ = if (builtin.zig_version.pre == null) + // NOTE(jae): 2026-04-29 + // Only test on Zig stable for now as the external Translate-C dep can break or Aro can break with nightly + @import("translate_c_external").__android_log_write + else + void; } const androidbind = @import("android-bind.zig"); From 7c4c3203f045cef79a52175b71a40c95ff033640 Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 14:14:58 +1000 Subject: [PATCH 3/9] add test for translate-c --- test/build/build.zig | 10 ++++++++-- test/build/build.zig.zon | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/test/build/build.zig b/test/build/build.zig index b296460..e429504 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -60,7 +60,10 @@ pub fn build(b: *std.Build) void { }, }, }); - if (builtin.zig_version.pre == null) { + // Must be stable release of Zig *and* 0.16.X or higher + if (builtin.zig_version.pre == null and + builtin.zig_version.major == 0 and builtin.zig_version.minor >= 16) + { const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; app_module.addImport("translate_c_external", translate_c_external_mod); log.info("testTranslateCExternal: add import 'translate_c_external' to {t}", .{target.result.cpu.arch}); @@ -117,7 +120,10 @@ fn testTranslateCVendor(b: *std.Build, target: std.Build.ResolvedTarget, optimiz /// Test the Translate-C external dependency version fn testTranslateCExternal(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) ?*std.Build.Module { - const translate_c_dep_name = "translate_c_stable"; + const translate_c_dep_name = if (comptime builtin.zig_version.major == 0 and builtin.zig_version.minor == 15) + "translate_c_previous_stable" + else + "translate_c_stable"; const translate_c_import = b.lazyImport(@This(), translate_c_dep_name) orelse return null; const translate_c = b.lazyDependency(translate_c_dep_name, .{}) orelse return null; const Translator = translate_c_import.Translator; diff --git a/test/build/build.zig.zon b/test/build/build.zig.zon index 155c3fd..93352aa 100644 --- a/test/build/build.zig.zon +++ b/test/build/build.zig.zon @@ -14,6 +14,13 @@ .hash = "N-V-__8AABTXlAV0z_BGl5-lZeOEm_d2gHEhExT2qjxMqQ72", .lazy = true, }, + // NOTE(jae): 2026-04-29 + // Cannot keep Zig 0.15.X version in without breaking this, would need a seperate test + // .translate_c_previous_stable = .{ + // .url = "git+https://codeberg.org/ziglang/translate-c#cb8973a121a6de43d3ebc6808cd8070d716e7ea1", + // .hash = "translate_c-0.0.0-Q_BUWveCBgAzseZyfMxV_u8lBHp5SaWD8HOk8jSr_UtT", + // .lazy = true, + // }, .translate_c_stable = .{ .url = "git+https://codeberg.org/ziglang/translate-c#7a1a9fdc4ab00835748a6657ecbb835e3d5d45f7", .hash = "translate_c-0.0.0-Q_BUWvP1BgCjAk6PWv5286tOlvzD9-X-NkuTzh0KxY0Q", From 1ccb98e80821f6f6f7a142c1cfdbe70d37f886dc Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 14:24:54 +1000 Subject: [PATCH 4/9] try this --- .github/workflows/ci.yml | 20 ++++++++++---------- test/build/build.zig | 12 ++++++++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57d6ead..7136e1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,15 +93,15 @@ jobs: with: version: ${{ needs.setup.outputs.zig-stable-version }} - - name: Build Test (Zig Stable) + - name: Build Test run: zig build -Dandroid=true --verbose working-directory: test/build - - name: Build Minimal Example (Zig Stable) + - name: Build Minimal Example run: zig build -Dandroid=true --verbose working-directory: examples/minimal - - name: Build SDL2 Example (Zig Stable) + - name: Build SDL2 Example run: | zig build -Dandroid=true --verbose zig build -Dandroid=true -Dcrash-on-exception --verbose @@ -110,7 +110,7 @@ jobs: # NOTE(jae): 2026-04-09 # Raylib example only runs on 0.16.X due to downstream dependencies # - # - name: Build Raylib Example (Zig Stable) + # - name: Build Raylib Example # run: zig build -Dandroid=true --verbose # working-directory: examples/raylib @@ -182,21 +182,21 @@ jobs: with: version: "master" - - name: Build Test (Zig Nightly) + - name: Build Test run: zig build -Dandroid=true --verbose working-directory: test/build - - name: Build Minimal Example (Zig Nightly) + - name: Build Minimal Example run: zig build -Dandroid=true --verbose working-directory: examples/minimal - - name: Build SDL2 Example (Zig Nightly) + - name: Build SDL2 Example run: zig build -Dandroid=true --verbose working-directory: examples/sdl2 # note(jae): 2026-04-09 # Downstream packages for Raylib only support 0.16.X-dev right now. - - name: Build Raylib Example (Zig Nightly) + - name: Build Raylib Example run: zig build -Dandroid=true --verbose working-directory: examples/raylib build-previous-stable: @@ -232,11 +232,11 @@ jobs: with: version: ${{ needs.setup.outputs.zig-previous-stable-version }} - - name: Build Test (Zig Nightly) + - name: Build Test run: zig build -Dandroid=true --verbose working-directory: test/build - - name: Build Minimal Example + - name: Build Minimal Example run: zig build -Dandroid=true --verbose working-directory: examples/minimal diff --git a/test/build/build.zig b/test/build/build.zig index e429504..a13f87c 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -10,6 +10,10 @@ const log = std.log; const android = @import("android"); +/// Make sure this is a stable version of Zig +const is_latest_stable_zig = builtin.zig_version.pre == null and + builtin.zig_version.major == 0 and builtin.zig_version.minor >= 16; + pub fn build(b: *std.Build) void { const exe_name: []const u8 = "build_test"; const root_target = b.standardTargetOptions(.{}); @@ -18,7 +22,9 @@ pub fn build(b: *std.Build) void { // NOTE(jae): 2026-04-12 // Run it *after* the "standardTargets" call - testLazyImportAndResolveTargets(b, root_target); + if (is_latest_stable_zig) { + testLazyImportAndResolveTargets(b, root_target); + } var root_target_single = [_]std.Build.ResolvedTarget{root_target}; const targets: []std.Build.ResolvedTarget = if (android_targets.len == 0) @@ -61,9 +67,7 @@ pub fn build(b: *std.Build) void { }, }); // Must be stable release of Zig *and* 0.16.X or higher - if (builtin.zig_version.pre == null and - builtin.zig_version.major == 0 and builtin.zig_version.minor >= 16) - { + if (is_latest_stable_zig) { const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; app_module.addImport("translate_c_external", translate_c_external_mod); log.info("testTranslateCExternal: add import 'translate_c_external' to {t}", .{target.result.cpu.arch}); From 49008700a4d08edc66e1efb6b6c61d87af357f01 Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 14:51:03 +1000 Subject: [PATCH 5/9] improve testing --- .github/workflows/ci.yml | 12 +++++------ src/androidbuild/androidbuild.zig | 1 + test/build.zig | 21 ++++++++++++++++++++ test/build.zig.zon | 11 +++++++++++ test/build/build.zig | 33 +++++-------------------------- test/build/build.zig.zon | 4 ---- test/lazy_android/build.zig | 30 ++++++++++++++++++++++++++++ test/lazy_android/build.zig.zon | 15 ++++++++++++++ 8 files changed, 89 insertions(+), 38 deletions(-) create mode 100644 test/build.zig create mode 100644 test/build.zig.zon create mode 100644 test/lazy_android/build.zig create mode 100644 test/lazy_android/build.zig.zon diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7136e1f..3b00d2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,8 +94,8 @@ jobs: version: ${{ needs.setup.outputs.zig-stable-version }} - name: Build Test - run: zig build -Dandroid=true --verbose - working-directory: test/build + run: zig build --verbose + working-directory: test - name: Build Minimal Example run: zig build -Dandroid=true --verbose @@ -183,8 +183,8 @@ jobs: version: "master" - name: Build Test - run: zig build -Dandroid=true --verbose - working-directory: test/build + run: zig build --verbose + working-directory: test - name: Build Minimal Example run: zig build -Dandroid=true --verbose @@ -233,8 +233,8 @@ jobs: version: ${{ needs.setup.outputs.zig-previous-stable-version }} - name: Build Test - run: zig build -Dandroid=true --verbose - working-directory: test/build + run: zig build --verbose + working-directory: test - name: Build Minimal Example run: zig build -Dandroid=true --verbose diff --git a/src/androidbuild/androidbuild.zig b/src/androidbuild/androidbuild.zig index 7740768..49a12b5 100644 --- a/src/androidbuild/androidbuild.zig +++ b/src/androidbuild/androidbuild.zig @@ -107,6 +107,7 @@ pub fn standardTargets(b: *std.Build, target: ResolvedTarget) []ResolvedTarget { // Seperated logic into "resolveTargets" so that consumers of this library can create this option themselves and use "b.lazyImport" // See: https://github.com/silbinarywolf/zig-android-sdk/pull/82 const all_targets = b.option(bool, "android", "Build for all Android targets (x86, x86_64, aarch64, arm, etc)") orelse false; + return resolveTargets(b, .{ .default_target = target, .all_targets = all_targets, diff --git a/test/build.zig b/test/build.zig new file mode 100644 index 0000000..455f4b5 --- /dev/null +++ b/test/build.zig @@ -0,0 +1,21 @@ +const Build = @import("std").Build; + +pub fn build(b: *Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const all_step = b.step("all", "Run all tests"); + b.default_step = all_step; + + for (b.available_deps) |available_dep| { + const test_name, _ = available_dep; + const run_example = b.dependency(test_name, .{ + .target = target, + .optimize = optimize, + .android = true, + }).builder.default_step; + const example_step = b.step(test_name, b.fmt("Run the '{s}' test", .{test_name})); + example_step.dependOn(run_example); + all_step.dependOn(example_step); + } +} diff --git a/test/build.zig.zon b/test/build.zig.zon new file mode 100644 index 0000000..2acd7ce --- /dev/null +++ b/test/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = .tests, + .version = "0.0.0", + .fingerprint = 0x1260fc5e4c176d8b, + .minimum_zig_version = "0.16.0", + .paths = .{""}, + .dependencies = .{ + .build = .{ .path = "build" }, + .lazy_android = .{ .path = "lazy_android" }, + }, +} diff --git a/test/build/build.zig b/test/build/build.zig index a13f87c..f1937e9 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -6,7 +6,7 @@ const std = @import("std"); const builtin = @import("builtin"); -const log = std.log; +const log = std.log.scoped(.build); const android = @import("android"); @@ -20,12 +20,6 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const android_targets = android.standardTargets(b, root_target); - // NOTE(jae): 2026-04-12 - // Run it *after* the "standardTargets" call - if (is_latest_stable_zig) { - testLazyImportAndResolveTargets(b, root_target); - } - var root_target_single = [_]std.Build.ResolvedTarget{root_target}; const targets: []std.Build.ResolvedTarget = if (android_targets.len == 0) root_target_single[0..] @@ -53,6 +47,10 @@ pub fn build(b: *std.Build) void { }; for (targets) |target| { + if (!target.result.abi.isAndroid()) { + std.debug.panic("For testing Android builds only. Target(s) should be Android not: {t}", .{target.result.abi}); + } + const translate_c_vendored_mod = testTranslateCVendor(b, target, optimize) orelse return; const app_module = b.createModule(.{ @@ -142,27 +140,6 @@ fn testTranslateCExternal(b: *std.Build, target: std.Build.ResolvedTarget, optim return trans_libandroid.mod; } -/// Test calling lazyImport and then calling "resolveTargets" -/// -/// PR: https://github.com/silbinarywolf/zig-android-sdk/pull/83 -fn testLazyImportAndResolveTargets(b: *std.Build, root_target: std.Build.ResolvedTarget) void { - const all_android_targets = true; - const android_targets: []std.Build.ResolvedTarget = blk: { - if (all_android_targets or root_target.result.abi.isAndroid()) { - if (b.lazyImport(@This(), "lazy_android")) |lazy_android| { - break :blk lazy_android.resolveTargets(b, .{ - .default_target = root_target, - .all_targets = true, - }); - } - } - break :blk &[0]std.Build.ResolvedTarget{}; - }; - if (android_targets.len != 4) @panic("expected 'resolveTargets' it to return 4 Android targets"); - - log.info("testLazyImportAndResolveTargets: check that resolving android targets worked. Got: {}", .{android_targets.len}); -} - /// Test the addLibraryFile functionality /// /// Requested feature here: https://github.com/silbinarywolf/zig-android-sdk/issues/77 diff --git a/test/build/build.zig.zon b/test/build/build.zig.zon index 93352aa..5afb3e6 100644 --- a/test/build/build.zig.zon +++ b/test/build/build.zig.zon @@ -5,10 +5,6 @@ .android = .{ .path = "../..", }, - .lazy_android = .{ - .path = "../..", - .lazy = true, - }, .vulkan_validation = .{ .url = "https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/vulkan-sdk-1.4.341.0/android-binaries-1.4.341.0.zip", .hash = "N-V-__8AABTXlAV0z_BGl5-lZeOEm_d2gHEhExT2qjxMqQ72", diff --git a/test/lazy_android/build.zig b/test/lazy_android/build.zig new file mode 100644 index 0000000..09eb9d1 --- /dev/null +++ b/test/lazy_android/build.zig @@ -0,0 +1,30 @@ +const Build = @import("std").Build; +const log = @import("std").log.scoped(.lazy_android); + +pub fn build(b: *Build) void { + const root_target = b.standardTargetOptions(.{}); + _ = b.standardOptimizeOption(.{}); + + // Test calling lazyImport and then calling "resolveTargets" + // + // PR: https://github.com/silbinarywolf/zig-android-sdk/pull/83 + { + const all_android_targets = b.option(bool, "android", "Custom usage of android flag") orelse false; + if (!all_android_targets) + @panic("expected android=true for the flag"); + const android_targets: []Build.ResolvedTarget = blk: { + if (all_android_targets or root_target.result.abi.isAndroid()) { + if (b.lazyImport(@This(), "lazy_android")) |lazy_android| { + break :blk lazy_android.resolveTargets(b, .{ + .default_target = root_target, + .all_targets = true, + }); + } + } + break :blk &[0]Build.ResolvedTarget{}; + }; + if (android_targets.len != 4) @panic("expected 'resolveTargets' it to return 4 Android targets"); + + log.info("testLazyImportAndResolveTargets: check that resolving android targets worked. Got: {}", .{android_targets.len}); + } +} diff --git a/test/lazy_android/build.zig.zon b/test/lazy_android/build.zig.zon new file mode 100644 index 0000000..bcf3b63 --- /dev/null +++ b/test/lazy_android/build.zig.zon @@ -0,0 +1,15 @@ +.{ + .name = .lazy_android, + .version = "0.0.0", + .fingerprint = 0xf96a46f8318f02b1, + .dependencies = .{ + .lazy_android = .{ + .path = "../..", + .lazy = true, + }, + }, + .paths = .{ + "build.zig", + "build.zig.zon", + }, +} From df194e2babe9872856cf2fe183b367878ee5fc7b Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 14:53:18 +1000 Subject: [PATCH 6/9] avoid lazy loading --- test/build/build.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/build/build.zig b/test/build/build.zig index f1937e9..01a7b7f 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -144,6 +144,10 @@ fn testTranslateCExternal(b: *std.Build, target: std.Build.ResolvedTarget, optim /// /// Requested feature here: https://github.com/silbinarywolf/zig-android-sdk/issues/77 fn testAddLibraryFile(b: *std.Build, apk: *android.Apk) void { + if (!is_latest_stable_zig) { + return; + } + const vulkan_validation_dep = b.lazyDependency("vulkan_validation", .{}) orelse return; apk.addLibraryFile(.arm64_v8a, vulkan_validation_dep.path("arm64-v8a/libVkLayer_khronos_validation.so")); apk.addLibraryFile(.armeabi_v7a, vulkan_validation_dep.path("armeabi-v7a/libVkLayer_khronos_validation.so")); From 5b4bbce810ac057df775f830d0310e047c52fee6 Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 15:18:13 +1000 Subject: [PATCH 7/9] add seperate tests for translate_c --- build.zig.zon | 1 + test/build.zig | 8 +- test/build.zig.zon | 2 +- test/build/build.zig | 41 ++------ test/build/build.zig.zon | 12 --- test/build/src/build_test_main.zig | 8 -- .../android/AndroidManifest.xml | 24 +++++ .../android/res/mipmap/ic_launcher.png | Bin 0 -> 4812 bytes .../android/res/values/strings.xml | 10 ++ test/translate_c_dep/build.zig | 96 ++++++++++++++++++ test/translate_c_dep/build.zig.zon | 25 +++++ .../src/translate_c_dep_main.zig | 8 ++ 12 files changed, 178 insertions(+), 57 deletions(-) create mode 100644 test/translate_c_dep/android/AndroidManifest.xml create mode 100644 test/translate_c_dep/android/res/mipmap/ic_launcher.png create mode 100644 test/translate_c_dep/android/res/values/strings.xml create mode 100644 test/translate_c_dep/build.zig create mode 100644 test/translate_c_dep/build.zig.zon create mode 100644 test/translate_c_dep/src/translate_c_dep_main.zig diff --git a/build.zig.zon b/build.zig.zon index 1add7e8..fbef194 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -7,5 +7,6 @@ "build.zig.zon", "src", }, + .minimum_zig_version = "0.16.0", .fingerprint = 0x92bcb62d42fb2cee, } diff --git a/test/build.zig b/test/build.zig index 455f4b5..86f3e76 100644 --- a/test/build.zig +++ b/test/build.zig @@ -9,13 +9,13 @@ pub fn build(b: *Build) void { for (b.available_deps) |available_dep| { const test_name, _ = available_dep; - const run_example = b.dependency(test_name, .{ + const test_case_dep_step = b.dependency(test_name, .{ .target = target, .optimize = optimize, .android = true, }).builder.default_step; - const example_step = b.step(test_name, b.fmt("Run the '{s}' test", .{test_name})); - example_step.dependOn(run_example); - all_step.dependOn(example_step); + const test_step = b.step(test_name, b.fmt("Run the '{s}' test", .{test_name})); + test_step.dependOn(test_case_dep_step); + all_step.dependOn(test_step); } } diff --git a/test/build.zig.zon b/test/build.zig.zon index 2acd7ce..3e6d565 100644 --- a/test/build.zig.zon +++ b/test/build.zig.zon @@ -2,10 +2,10 @@ .name = .tests, .version = "0.0.0", .fingerprint = 0x1260fc5e4c176d8b, - .minimum_zig_version = "0.16.0", .paths = .{""}, .dependencies = .{ .build = .{ .path = "build" }, .lazy_android = .{ .path = "lazy_android" }, + .translate_c_dep = .{ .path = "translate_c_dep" }, }, } diff --git a/test/build/build.zig b/test/build/build.zig index 01a7b7f..20bff25 100644 --- a/test/build/build.zig +++ b/test/build/build.zig @@ -64,44 +64,21 @@ pub fn build(b: *std.Build) void { }, }, }); - // Must be stable release of Zig *and* 0.16.X or higher - if (is_latest_stable_zig) { - const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; - app_module.addImport("translate_c_external", translate_c_external_mod); - log.info("testTranslateCExternal: add import 'translate_c_external' to {t}", .{target.result.cpu.arch}); - } - var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addLibrary(.{ + const libmain = b.addLibrary(.{ .name = "main", .root_module = app_module, .linkage = .dynamic, - }) else b.addExecutable(.{ - .name = exe_name, - .root_module = app_module, }); - // if building as library for Android, add this target - // NOTE: Android has different CPU targets so you need to build a version of your - // code for x86, x86_64, arm, arm64 and more - if (target.result.abi.isAndroid()) { - const apk: *android.Apk = android_apk orelse @panic("Android APK should be initialized"); - const android_dep = b.dependency("android", .{ - .optimize = optimize, - .target = target, - }); - exe.root_module.addImport("android", android_dep.module("android")); - - apk.addArtifact(exe); - } else { - b.installArtifact(exe); - - // If only 1 target, add "run" step - if (targets.len == 1) { - const run_step = b.step("run", "Run the application"); - const run_cmd = b.addRunArtifact(exe); - run_step.dependOn(&run_cmd.step); - } - } + const apk: *android.Apk = android_apk orelse @panic("Android APK should be initialized"); + const android_dep = b.dependency("android", .{ + .optimize = optimize, + .target = target, + }); + libmain.root_module.addImport("android", android_dep.module("android")); + + apk.addArtifact(libmain); } if (android_apk) |apk| { testInstallAndAddRunStep(b, apk); diff --git a/test/build/build.zig.zon b/test/build/build.zig.zon index 5afb3e6..8489e1c 100644 --- a/test/build/build.zig.zon +++ b/test/build/build.zig.zon @@ -10,18 +10,6 @@ .hash = "N-V-__8AABTXlAV0z_BGl5-lZeOEm_d2gHEhExT2qjxMqQ72", .lazy = true, }, - // NOTE(jae): 2026-04-29 - // Cannot keep Zig 0.15.X version in without breaking this, would need a seperate test - // .translate_c_previous_stable = .{ - // .url = "git+https://codeberg.org/ziglang/translate-c#cb8973a121a6de43d3ebc6808cd8070d716e7ea1", - // .hash = "translate_c-0.0.0-Q_BUWveCBgAzseZyfMxV_u8lBHp5SaWD8HOk8jSr_UtT", - // .lazy = true, - // }, - .translate_c_stable = .{ - .url = "git+https://codeberg.org/ziglang/translate-c#7a1a9fdc4ab00835748a6657ecbb835e3d5d45f7", - .hash = "translate_c-0.0.0-Q_BUWvP1BgCjAk6PWv5286tOlvzD9-X-NkuTzh0KxY0Q", - .lazy = true, - }, }, .paths = .{ "build.zig", diff --git a/test/build/src/build_test_main.zig b/test/build/src/build_test_main.zig index da7f349..28c8da7 100644 --- a/test/build/src/build_test_main.zig +++ b/test/build/src/build_test_main.zig @@ -7,14 +7,6 @@ const android = @import("android"); comptime { // For vendored translate-c usage, validate at compile-time that this symbol exists _ = @import("translate_c_internal").__android_log_write; - - // For external translate-c usage, validate at compile-time that this symbol exists - _ = if (builtin.zig_version.pre == null) - // NOTE(jae): 2026-04-29 - // Only test on Zig stable for now as the external Translate-C dep can break or Aro can break with nightly - @import("translate_c_external").__android_log_write - else - void; } const androidbind = @import("android-bind.zig"); diff --git a/test/translate_c_dep/android/AndroidManifest.xml b/test/translate_c_dep/android/AndroidManifest.xml new file mode 100644 index 0000000..d10678a --- /dev/null +++ b/test/translate_c_dep/android/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + diff --git a/test/translate_c_dep/android/res/mipmap/ic_launcher.png b/test/translate_c_dep/android/res/mipmap/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..7ea4bd87ea6b463338901e4dc0c9c496bdd46541 GIT binary patch literal 4812 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 + + + Zig Build Test + + com.zig.translate_c_dep + diff --git a/test/translate_c_dep/build.zig b/test/translate_c_dep/build.zig new file mode 100644 index 0000000..3f896a1 --- /dev/null +++ b/test/translate_c_dep/build.zig @@ -0,0 +1,96 @@ +//! Test that using translate-c as a dependency works with the Zig Android SDK + +const std = @import("std"); +const builtin = @import("builtin"); +const log = std.log.scoped(.build); + +const android = @import("android"); + +/// Make sure this is a stable version of Zig +const is_latest_stable_zig = builtin.zig_version.pre == null and + builtin.zig_version.major == 0 and builtin.zig_version.minor >= 16; + +pub fn build(b: *std.Build) void { + const exe_name: []const u8 = "translate_c_test"; + const root_target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + const android_targets = android.standardTargets(b, root_target); + + if (!is_latest_stable_zig) { + log.warn("skipping translate-c as dependency test for Zig {}", .{builtin.zig_version_string}); + return; + } + + var root_target_single = [_]std.Build.ResolvedTarget{root_target}; + const targets: []std.Build.ResolvedTarget = if (android_targets.len == 0) + root_target_single[0..] + else + android_targets; + + const android_apk: ?*android.Apk = blk: { + if (android_targets.len == 0) break :blk null; + + const android_sdk = android.Sdk.create(b, .{}); + const apk = android_sdk.createApk(.{ + .name = exe_name, + .api_level = .android15, + .build_tools_version = "35.0.1", + .ndk_version = "29.0.13113456", + }); + const key_store_file = android_sdk.createKeyStore(.example); + apk.setKeyStore(key_store_file); + apk.setAndroidManifest(b.path("android/AndroidManifest.xml")); + apk.addResourceDirectory(b.path("android/res")); + + break :blk apk; + }; + + for (targets) |target| { + if (!target.result.abi.isAndroid()) { + std.debug.panic("For testing Android builds only. Target(s) should be Android not: {t}", .{target.result.abi}); + } + + const app_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .root_source_file = b.path("src/translate_c_dep_main.zig"), + }); + + // Must be stable release of Zig *and* 0.16.X or higher + { + const translate_c_external_mod = testTranslateCExternal(b, target, optimize) orelse return; + app_module.addImport("translate_c_external", translate_c_external_mod); + log.info("testTranslateCExternal: add import 'translate_c_external' to {t}", .{target.result.cpu.arch}); + } + + const libmain = b.addLibrary(.{ + .name = "main", + .root_module = app_module, + .linkage = .dynamic, + }); + + const apk: *android.Apk = android_apk orelse @panic("Android APK should be initialized"); + apk.addArtifact(libmain); + } + if (android_apk) |apk| { + const installed_apk = apk.addInstallApk(); + b.getInstallStep().dependOn(&installed_apk.step); + } +} + +/// Test the Translate-C external dependency version +fn testTranslateCExternal(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) ?*std.Build.Module { + const translate_c_dep_name = "translate_c"; + const translate_c_import = b.lazyImport(@This(), translate_c_dep_name) orelse return null; + const translate_c = b.lazyDependency(translate_c_dep_name, .{}) orelse return null; + const Translator = translate_c_import.Translator; + + const trans_libandroid: Translator = .init(translate_c, .{ + .c_source_file = b.addWriteFiles().add("android_c.h", + \\#include + ), + .target = target, + .optimize = optimize, + }); + return trans_libandroid.mod; +} diff --git a/test/translate_c_dep/build.zig.zon b/test/translate_c_dep/build.zig.zon new file mode 100644 index 0000000..e5efdde --- /dev/null +++ b/test/translate_c_dep/build.zig.zon @@ -0,0 +1,25 @@ +.{ + .name = .translate_c_dep, + .version = "0.0.0", + .fingerprint = 0xe316eba7796ae687, + .dependencies = .{ + .android = .{ + .path = "../..", + }, + .translate_c = .{ + .url = "git+https://codeberg.org/ziglang/translate-c#7a1a9fdc4ab00835748a6657ecbb835e3d5d45f7", + .hash = "translate_c-0.0.0-Q_BUWvP1BgCjAk6PWv5286tOlvzD9-X-NkuTzh0KxY0Q", + }, + // NOTE(jae): 2026-04-29 + // Cannot keep Zig 0.15.X version in without breaking this, would need a seperate test + // .translate_c_previous_stable = .{ + // .url = "git+https://codeberg.org/ziglang/translate-c#cb8973a121a6de43d3ebc6808cd8070d716e7ea1", + // .hash = "translate_c-0.0.0-Q_BUWveCBgAzseZyfMxV_u8lBHp5SaWD8HOk8jSr_UtT", + // .lazy = true, + // }, + }, + .paths = .{ + "build.zig", + "build.zig.zon", + }, +} diff --git a/test/translate_c_dep/src/translate_c_dep_main.zig b/test/translate_c_dep/src/translate_c_dep_main.zig new file mode 100644 index 0000000..1eb7bb4 --- /dev/null +++ b/test/translate_c_dep/src/translate_c_dep_main.zig @@ -0,0 +1,8 @@ +const builtin = @import("builtin"); + +const android = @import("android"); + +comptime { + // For external translate-c usage, validate at compile-time that this symbol exists + _ = @import("translate_c_external").__android_log_write; +} From cccf643dcb71a5dd8eb2a223736a248edd77c717 Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 15:22:33 +1000 Subject: [PATCH 8/9] add minimum zig version --- test/translate_c_dep/build.zig.zon | 1 + 1 file changed, 1 insertion(+) diff --git a/test/translate_c_dep/build.zig.zon b/test/translate_c_dep/build.zig.zon index e5efdde..4d4f9a2 100644 --- a/test/translate_c_dep/build.zig.zon +++ b/test/translate_c_dep/build.zig.zon @@ -2,6 +2,7 @@ .name = .translate_c_dep, .version = "0.0.0", .fingerprint = 0xe316eba7796ae687, + .minimum_zig_version = "0.16.0", .dependencies = .{ .android = .{ .path = "../..", From dc0443b659eadaa4344f2f9f6d51185f6250c6d3 Mon Sep 17 00:00:00 2001 From: Jae B Date: Wed, 29 Apr 2026 15:45:29 +1000 Subject: [PATCH 9/9] test other zig versions --- test/build.zig | 35 +++++++++++++++++++++++++----- test/translate_c_dep/build.zig.zon | 2 +- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/test/build.zig b/test/build.zig index 86f3e76..0f6e6be 100644 --- a/test/build.zig +++ b/test/build.zig @@ -1,4 +1,10 @@ const Build = @import("std").Build; +const builtin = @import("builtin"); +const eql = @import("std").mem.eql; + +/// Make sure this is a stable version of Zig +const is_latest_stable_zig = builtin.zig_version.pre == null and + builtin.zig_version.major == 0 and builtin.zig_version.minor >= 16; pub fn build(b: *Build) void { const target = b.standardTargetOptions(.{}); @@ -9,11 +15,30 @@ pub fn build(b: *Build) void { for (b.available_deps) |available_dep| { const test_name, _ = available_dep; - const test_case_dep_step = b.dependency(test_name, .{ - .target = target, - .optimize = optimize, - .android = true, - }).builder.default_step; + const test_case_dep_step: *Build.Step = blk: { + if (is_latest_stable_zig) { + const dep = b.dependency(test_name, .{ + .target = target, + .optimize = optimize, + .android = true, + }); + break :blk dep.builder.default_step; + } else { + // Skip translate_c_dep as it requires Zig 0.16.0 stable as of 2026-04-29 + if (eql(u8, test_name, "translate_c_dep")) { + continue; + } + + // NOTE(jae): 2026-04-29 + // Due to b.dependency() trying to always load Zig dependencies regardless + // of version requirements, we make other Zig versions invoke build manually + // so that ignoring dependency logic is respected. + const cmd = b.addSystemCommand(&.{ "zig", "build", "-Dandroid=true" }); + cmd.setCwd(b.path(test_name)); + cmd.expectExitCode(0); + break :blk &cmd.step; + } + }; const test_step = b.step(test_name, b.fmt("Run the '{s}' test", .{test_name})); test_step.dependOn(test_case_dep_step); all_step.dependOn(test_step); diff --git a/test/translate_c_dep/build.zig.zon b/test/translate_c_dep/build.zig.zon index 4d4f9a2..d5e065e 100644 --- a/test/translate_c_dep/build.zig.zon +++ b/test/translate_c_dep/build.zig.zon @@ -2,7 +2,7 @@ .name = .translate_c_dep, .version = "0.0.0", .fingerprint = 0xe316eba7796ae687, - .minimum_zig_version = "0.16.0", + .zig_version = "0.16.0", .dependencies = .{ .android = .{ .path = "../..",