Skip to content

Commit 00a64c2

Browse files
Fix "Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed" (#24)
Fix "Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed" Resolving this issue was made much easier thanks to @ousttrue here with their fork here: ousttrue@a741b62 Fixes #23
1 parent 50307e9 commit 00a64c2

File tree

3 files changed

+72
-17
lines changed

3 files changed

+72
-17
lines changed

examples/minimal/build.zig

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,19 @@ pub fn build(b: *std.Build) void {
3737
};
3838

3939
for (targets) |target| {
40-
var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addSharedLibrary(.{
41-
.name = exe_name,
42-
.root_source_file = b.path("src/minimal.zig"),
40+
const app_module = b.createModule(.{
4341
.target = target,
4442
.optimize = optimize,
43+
.root_source_file = b.path("src/minimal.zig"),
44+
});
45+
46+
var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addLibrary(.{
47+
.name = exe_name,
48+
.root_module = app_module,
49+
.linkage = .dynamic,
4550
}) else b.addExecutable(.{
4651
.name = exe_name,
47-
.root_source_file = b.path("src/minimal.zig"),
48-
.target = target,
49-
.optimize = optimize,
52+
.root_module = app_module,
5053
});
5154

5255
// if building as library for Android, add this target

examples/sdl2/build.zig

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,18 @@ pub fn build(b: *std.Build) void {
5656

5757
for (targets) |target| {
5858
const exe_name: []const u8 = "sdl-zig-demo";
59-
var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addSharedLibrary(.{
60-
.name = exe_name,
61-
.root_source_file = b.path("src/sdl-zig-demo.zig"),
59+
const app_module = b.createModule(.{
6260
.target = target,
6361
.optimize = optimize,
62+
.root_source_file = b.path("src/sdl-zig-demo.zig"),
63+
});
64+
var exe: *std.Build.Step.Compile = if (target.result.abi.isAndroid()) b.addLibrary(.{
65+
.name = exe_name,
66+
.root_module = app_module,
67+
.linkage = .dynamic,
6468
}) else b.addExecutable(.{
6569
.name = exe_name,
66-
.root_source_file = b.path("src/sdl-zig-demo.zig"),
67-
.target = target,
68-
.optimize = optimize,
70+
.root_module = app_module,
6971
});
7072

7173
const library_optimize = if (!target.result.abi.isAndroid())

src/androidbuild/apk.zig

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ fn doInstallApk(apk: *Apk) std.mem.Allocator.Error!*Step.InstallFile {
362362
// - classes.dex
363363
const apk_files = b.addWriteFiles();
364364

365+
// These files belong in root and *must not* be compressed
366+
// - resources.arsc
367+
const apk_files_not_compressed = b.addWriteFiles();
368+
365369
// Add build artifacts, usually a shared library targetting:
366370
// - aarch64-linux-android
367371
// - arm-linux-androideabi
@@ -491,10 +495,24 @@ fn doInstallApk(apk: *Apk) std.mem.Allocator.Error!*Step.InstallFile {
491495
const extracted_apk_dir = resources_apk.dirname();
492496
jar.setCwd(extracted_apk_dir);
493497
_ = apk_files.addCopyDirectory(extracted_apk_dir, "", .{
494-
// Ignore the *.apk that exists in this directory
495-
.exclude_extensions = &.{".apk"},
498+
.exclude_extensions = &.{
499+
// ignore the *.apk that exists in this directory
500+
".apk",
501+
// ignore resources.arsc as Android 30+ APIs does not supporting
502+
// compressing this in the zip file
503+
".arsc",
504+
},
496505
});
497506
apk_files.step.dependOn(&jar.step);
507+
508+
// Setup directory of additional files that should not be compressed
509+
510+
// NOTE(jae): 2025-03-23 - https://github.com/silbinarywolf/zig-android-sdk/issues/23
511+
// We apply resources.arsc seperately to the zip file to avoid compressing it, otherwise we get the following
512+
// error when we "adb install"
513+
// - "Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary"
514+
_ = apk_files_not_compressed.addCopyFile(extracted_apk_dir.path(b, "resources.arsc"), "resources.arsc");
515+
apk_files_not_compressed.step.dependOn(&jar.step);
498516
}
499517

500518
// Create zip via "jar" as it's cross-platform and aapt2 can't zip *.so or *.dex files.
@@ -513,9 +531,12 @@ fn doInstallApk(apk: *Apk) std.mem.Allocator.Error!*Step.InstallFile {
513531
// Hack to ensure this side-effect re-triggers zipping this up
514532
jar.addFileInput(directory_to_zip.path(b, "AndroidManifest.xml"));
515533

516-
// -c = compress
517-
// -f specify filename
518-
// -M do not include a MANIFEST file
534+
// Written as-is from running "jar --help"
535+
// -c, --create = Create the archive. When the archive file name specified
536+
// -u, --update = Update an existing jar archive
537+
// -f, --file=FILE = The archive file name. When omitted, either stdin or
538+
// -M, --no-manifest = Do not create a manifest file for the entries
539+
// -0, --no-compress = Store only; use no ZIP compression
519540
const compress_zip_arg = "-cfM";
520541
if (b.verbose) jar.addArg(compress_zip_arg ++ "v") else jar.addArg(compress_zip_arg);
521542
const output_zip_file = jar.addOutputFileArg("compiled_code.zip");
@@ -524,6 +545,32 @@ fn doInstallApk(apk: *Apk) std.mem.Allocator.Error!*Step.InstallFile {
524545
break :blk output_zip_file;
525546
};
526547

548+
// Update zip with files that are not compressed (ie. resources.arsc)
549+
const update_zip: *Step = blk: {
550+
const jar = b.addSystemCommand(&[_][]const u8{
551+
apk.tools.java_tools.jar,
552+
});
553+
jar.setName(runNameContext("jar (update zip with uncompressed files)"));
554+
555+
const directory_to_zip = apk_files_not_compressed.getDirectory();
556+
jar.setCwd(directory_to_zip);
557+
// NOTE(jae): 2025-03-23
558+
// Hack to ensure this side-effect re-triggers zipping this up
559+
jar.addFileInput(apk_files_not_compressed.getDirectory().path(b, "resources.arsc"));
560+
561+
// Written as-is from running "jar --help"
562+
// -c, --create = Create the archive. When the archive file name specified
563+
// -u, --update = Update an existing jar archive
564+
// -f, --file=FILE = The archive file name. When omitted, either stdin or
565+
// -M, --no-manifest = Do not create a manifest file for the entries
566+
// -0, --no-compress = Store only; use no ZIP compression
567+
const update_zip_arg = "-ufM0";
568+
if (b.verbose) jar.addArg(update_zip_arg ++ "v") else jar.addArg(update_zip_arg);
569+
jar.addFileArg(zip_file);
570+
jar.addArg(".");
571+
break :blk &jar.step;
572+
};
573+
527574
// NOTE(jae): 2024-09-28 - https://github.com/silbinarywolf/zig-android-sdk/issues/8
528575
// Experimented with using "lint" but it didn't actually catch the issue described
529576
// in the above Github, ie. having "<category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />"
@@ -561,7 +608,10 @@ fn doInstallApk(apk: *Apk) std.mem.Allocator.Error!*Step.InstallFile {
561608
"4",
562609
});
563610

611+
// Depend on zip file and the additional update to it
564612
zipalign.addFileArg(zip_file);
613+
zipalign.step.dependOn(update_zip);
614+
565615
const apk_file = zipalign.addOutputFileArg(b.fmt("aligned-{s}.apk", .{apk_name}));
566616
break :blk apk_file;
567617
};

0 commit comments

Comments
 (0)