Skip to content

[feat] Support 16 KB page sizes #14895

@VMASPAD

Description

@VMASPAD

Describe the problem

Image

16KB Page Size Support for Tauri Android Apps

The Problem

When building a Tauri Android app that targets Android 15+ (API 35+), Google Play requires 16KB page size support starting November 1, 2025.

Symptoms

  1. AAB metadata shows correct alignment:

    java -jar bundletool-all-1.18.3.jar dump config --bundle=app.aab | grep alignment
    # Output: "alignment": "PAGE_ALIGNMENT_16K" ✅
  2. But native libraries (.so files) have wrong alignment:

    llvm-objdump -p libRaPiMATE_lib.so | grep LOAD
    # Output: LOAD off ... align 2**12 ❌ (4KB instead of 16KB)
  3. App runs in compatibility mode on 16KB devices with performance penalties.

Root Cause

Tauri's build system overrides .cargo/config.toml rustflags, so the standard Rust approach of adding linker flags to cargo configuration doesn't work. The flags need to be injected via build.rs instead.

Describe the solution you'd like

Step 1: Update Gradle Configuration

Edit src-tauri/gen/android/app/build.gradle.kts:

android {
    // Specify NDK r28+ for automatic 16KB support
    ndkVersion = "28.0.12433566"
    
    packaging {
        jniLibs {
            // Enable uncompressed native libraries with 16KB alignment
            useLegacyPackaging = false
        }
    }
}

Requirements:

  • Android Gradle Plugin (AGP) >= 8.5.1
  • NDK >= r28

Step 2: Configure Rust Linker Flags

Edit src-tauri/build.rs:

fn main() {
    let target = std::env::var("TARGET").unwrap_or_default();
    
    if target.contains("android") {
        // Both flags are required for proper 16KB alignment
        println!("cargo:rustc-link-arg=-Wl,-z,max-page-size=16384");
        println!("cargo:rustc-link-arg=-Wl,-z,common-page-size=16384");
    }
    
    tauri_build::build()
}

Why build.rs and not .cargo/config.toml?

Tauri's build system ignores rustflags in .cargo/config.toml. The println! statements in build.rs inject linker arguments directly into the compilation process, which Tauri respects.

Step 3: Clean and Rebuild

# Clean all previous build artifacts
cd src-tauri
cargo clean
cd ..

# Rebuild the AAB with 16KB support
npm run tauri android build -- --aab

Step 4: Verify the Fix

Check AAB metadata:

java -jar bundletool-all-1.18.3.jar dump config \
  --bundle=src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab \
  | grep alignment

Expected output: "alignment": "PAGE_ALIGNMENT_16K"

Verify native library alignment:

# Extract the AAB
cd /tmp
mkdir test_16kb
unzip /path/to/app-universal-release.aab -d test_16kb

# Check ARM64 library alignment
$ANDROID_HOME/ndk/28.0.12433566/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objdump \
  -p test_16kb/base/lib/arm64-v8a/libRaPiMATE_lib.so \
  | grep "LOAD" | head -3

Expected output:

LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14
LOAD off 0x00000000003251b0 vaddr 0x00000000003291b0 paddr 0x00000000003291b0 align 2**14
LOAD off 0x000000000065a780 vaddr 0x0000000000662780 paddr 0x0000000000662780 align 2**14

Note: 2**14 = 16384 (16KB alignment) ✅


Testing on 16KB Emulator (Optional)

Create 16KB Emulator

  1. Open Android Studio SDK Manager
  2. Go to SDK Platforms tab
  3. Check "Show Package Details"
  4. Select: Google APIs Experimental 16 KB Page Size ARM 64 v8a
  5. Click "Apply" to download

Create Virtual Device

# List available system images
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --list | grep "16 KB"

# Create AVD with 16KB page size
$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd \
  -n "Pixel_9_16KB" \
  -k "system-images;android-35;google_apis_16k;arm64-v8a" \
  -d "pixel_9_pro"

# Launch emulator
$ANDROID_HOME/emulator/emulator -avd Pixel_9_16KB

Verify Emulator Configuration

# Should return 16384
adb shell getconf PAGE_SIZE

Install and Test

# Generate APKs from AAB
java -jar bundletool-all-1.18.3.jar build-apks \
  --bundle=app-universal-release.aab \
  --output=rapimate.apks \
  --mode=universal

# Extract universal APK
unzip rapimate.apks -d apks/

# Install on device/emulator
adb install apks/universal.apk

Check logcat for any warnings:

adb logcat | grep -i "page\|compat"

If properly configured, there should be no warnings about "page size compat mode".


Summary

The fix requires two levels of alignment:

  1. ZIP-level alignment (via AGP): Ensures AAB metadata shows PAGE_ALIGNMENT_16K
  2. ELF-level alignment (via linker flags): Ensures .so files have align 2**14

For Tauri apps specifically, linker flags must be set in build.rs using println!("cargo:rustc-link-arg=...") because Tauri overrides .cargo/config.toml.


References

Alternatives considered

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions