mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
build: pin the app's packaging NDK to the Arti revision
AGP runs the NDK's llvm-strip over everything merged into jniLibs, so the
NDK is an APK input and not just a concern for whoever compiles Arti. No
module set ndkVersion, so the app silently used AGP's own default --
28.2.13676358 on AGP 9.4.0 ("Because no explicit NDK was requested, the
default version [...] for this Android Gradle Plugin will be used") --
while tools/arti-build/ANDROID_NDK_VERSION pins 30.0.16248370 and the
committed libarti_android.so are stamped r30/16248370 in
.note.android.ident. The library was built with r30 and stripped with r28,
and on a machine with no NDK installed it shipped unstripped instead: three
different APKs from one source tree, which is what F-Droid's rebuild
verification cannot have. The default also moves with every AGP bump.
:amethyst now reads ndkVersion straight from ANDROID_NDK_VERSION rather
than duplicating it into the version catalog, so the packaging toolchain
and the reproducibility pin cannot drift: bumping the pin (which already
means rebuilding the .so) moves both. Verified by reflecting the resolved
android.ndkVersion out of a configured build: :amethyst = 30.0.16248370.
The other Android modules (:benchmark, :baselineprofile, :nappletHost) keep
AGP's default -- none of them package native libraries, so no strip step
there ever resolves an NDK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ck919Y21reMU6LVrev1QJo
This commit is contained in:
@@ -109,6 +109,15 @@ Rust toolchain + the exact Android NDK revision pinned in
|
||||
`tools/arti-build/ANDROID_NDK_VERSION` for Arti) documented in their READMEs —
|
||||
they are **not** required to build Amethyst from the committed sources.
|
||||
|
||||
The NDK half of that Arti pin does reach the ordinary Android build, though:
|
||||
`:amethyst` sets `ndkVersion` from `ANDROID_NDK_VERSION`, because AGP strips
|
||||
the committed `.so` with the NDK's `llvm-strip` while packaging the APK. The
|
||||
Rust toolchain stays irrelevant, but Studio/AGP will fetch that NDK revision
|
||||
(`sdkmanager "ndk;$(cat tools/arti-build/ANDROID_NDK_VERSION)"` to pre-install
|
||||
it). Without any NDK the build still succeeds — AGP warns and packages the
|
||||
library unstripped, which is fine to run but no longer byte-comparable to a
|
||||
release APK.
|
||||
|
||||
---
|
||||
|
||||
## Per-format build commands
|
||||
|
||||
@@ -74,6 +74,29 @@ android {
|
||||
.get()
|
||||
.toInt()
|
||||
|
||||
// Packaging toolchain: AGP runs the NDK's llvm-strip over everything that
|
||||
// lands in jniLibs — our committed libarti_android.so included — so the
|
||||
// NDK revision is a build input for the APK, not just for whoever compiles
|
||||
// Arti. Left unset it silently follows AGP's own default (28.2.13676358 on
|
||||
// AGP 9.4.0), which moves with every AGP bump and is a different toolchain
|
||||
// from the one that produced the .so, while a machine with no NDK at all
|
||||
// packages the library unstripped ("Unable to strip the following
|
||||
// libraries") — three different APKs from the same source, which is
|
||||
// exactly what F-Droid's rebuild verification cannot have.
|
||||
//
|
||||
// Read straight from the Arti pin rather than copied into the version
|
||||
// catalog: the two can then never drift, and bumping ANDROID_NDK_VERSION
|
||||
// (which also means rebuilding the .so) moves the packaging toolchain with
|
||||
// it. See tools/arti-build/README.md → "Reproducible builds".
|
||||
ndkVersion =
|
||||
providers
|
||||
.fileContents(layout.settingsDirectory.file("tools/arti-build/ANDROID_NDK_VERSION"))
|
||||
.asText
|
||||
.orNull
|
||||
?.trim()
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?: error("tools/arti-build/ANDROID_NDK_VERSION is missing or empty — it pins the NDK that strips src/main/jniLibs")
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.vitorpamplona.amethyst"
|
||||
minSdk =
|
||||
|
||||
@@ -49,6 +49,14 @@ committed binary wasn't tampered with. **Five** things have to be fixed:
|
||||
> pinned output was verified with. `cargo-ndk` only wraps the NDK, so a mismatch
|
||||
> is a warning rather than an error — but it is the next thing to check if your
|
||||
> rebuild does not match.
|
||||
>
|
||||
> **The app build reads this pin too.** `amethyst/build.gradle.kts` sets
|
||||
> `ndkVersion` from `ANDROID_NDK_VERSION`, because AGP runs the NDK's
|
||||
> `llvm-strip` over `src/main/jniLibs/` while packaging — the toolchain that
|
||||
> strips the library is as much an APK input as the one that compiled it. Unset,
|
||||
> `ndkVersion` follows AGP's own default (r28 on AGP 9.4.0) and moves with every
|
||||
> AGP bump. So bumping this file changes what packagers need installed, not only
|
||||
> what rebuilders need: bump it, rebuild the `.so`, and commit both.
|
||||
|
||||
`repro-env.sh` (sourced by both build scripts) also sets `CARGO_INCREMENTAL=0`
|
||||
and a fixed `SOURCE_DATE_EPOCH` derived from the Arti tag. The size-optimized
|
||||
|
||||
Reference in New Issue
Block a user