fix(android): invoke cargo by absolute path in cargoNdk task
android / android (push) Successful in 3m50s
deb / build-publish (push) Successful in 3m11s
ci / bench (push) Successful in 4m45s
apple / swift (push) Successful in 56s
ci / rust (push) Successful in 1m18s
ci / web (push) Successful in 30s
ci / docs-site (push) Successful in 30s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
decky / build-publish (push) Successful in 11s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m34s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m42s
docker / deploy-docs (push) Successful in 18s

Gradle's Exec resolves command[0] via the JVM/daemon's inherited PATH, not
the environment("PATH", …) set on the task (that only reaches the spawned
child). A GUI Android Studio launch — and any daemon it starts — has no
~/.cargo/bin on its PATH, so a bare "cargo" fails with "A problem occurred
starting process 'command 'cargo''". Use the already-computed cargoBin
absolute path; the env PATH still lets cargo/cargo-ndk find their subtools.

Also refresh the README prereqs: add the missing cmake;3.22.1 SDK package
(the cmake crate builds libopus with it) and drop the broken
`brew --prefix openjdk@21` JAVA_HOME hint in favour of `java_home -v 21`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-19 11:09:44 +02:00
parent 822fde1e89
commit 22aff1c7ac
2 changed files with 13 additions and 6 deletions
+7 -5
View File
@@ -30,10 +30,11 @@ clients/android/ Gradle project (this dir)
build.gradle.kts cargoNdk{Debug,Release} → src/main/jniLibs/<abi>/*.so build.gradle.kts cargoNdk{Debug,Release} → src/main/jniLibs/<abi>/*.so
``` ```
## Prerequisites (already set up on the dev Mac) ## Prerequisites
- Android SDK + **NDK r30** (`30.0.14904198`), `platforms;android-37.0`, `build-tools;37.0.0` - Android SDK + **NDK r30** (`30.0.14904198`), `platforms;android-37.0`, `build-tools;37.0.0`,
- **JDK 21** for Gradle/AGP (the machine default JDK 25 is too new for AGP 9.2) **`cmake;3.22.1`** (`sdkmanager "cmake;3.22.1"` — the `cmake` crate builds libopus with it)
- **JDK 21** for Gradle/AGP (AGP 9.2 runs on JDK 1721, *not* a newer default JDK like 25)
- Rust + `rustup target add aarch64-linux-android x86_64-linux-android` + `cargo install cargo-ndk` - Rust + `rustup target add aarch64-linux-android x86_64-linux-android` + `cargo install cargo-ndk`
Toolchain pinned: AGP 9.2.0 · Gradle 9.4.1 · Kotlin 2.3.21 · Compose BOM 2026.05.01 · Toolchain pinned: AGP 9.2.0 · Gradle 9.4.1 · Kotlin 2.3.21 · Compose BOM 2026.05.01 ·
@@ -44,10 +45,11 @@ compileSdk 37 · targetSdk 36 · minSdk 31 · ABIs arm64-v8a + x86_64.
**Android Studio:** open `clients/android` — it uses its bundled JBR 21 automatically. The **Android Studio:** open `clients/android` — it uses its bundled JBR 21 automatically. The
`cargoNdk*` task builds the `.so` as part of the normal build. `cargoNdk*` task builds the `.so` as part of the normal build.
**CLI** (the machine default is JDK 25, so point Gradle at JDK 21): **CLI** (point Gradle at a JDK 21 if your machine default is newer, e.g. JDK 25):
```sh ```sh
export JAVA_HOME="$(brew --prefix openjdk@21)/libexec/openjdk.jdk/Contents/Home" # Adoptium/Temurin 21 (installed by the Android Studio setup, or `brew install temurin@21`):
export JAVA_HOME="$(/usr/libexec/java_home -v 21)"
cd clients/android cd clients/android
./gradlew :app:assembleDebug # cargo-ndk cross-compiles libpunktfunk_android.so first ./gradlew :app:assembleDebug # cargo-ndk cross-compiles libpunktfunk_android.so first
./gradlew :app:installDebug # onto a running emulator/device ./gradlew :app:installDebug # onto a running emulator/device
+6 -1
View File
@@ -78,8 +78,13 @@ fun registerCargoNdk(taskName: String, release: Boolean) =
// (pure C) so the android .so links it instead of looking for the host's libopus.so. // (pure C) so the android .so links it instead of looking for the host's libopus.so.
environment("LIBOPUS_STATIC", "1") environment("LIBOPUS_STATIC", "1")
environment("LIBOPUS_NO_PKG", "1") environment("LIBOPUS_NO_PKG", "1")
// Resolve cargo by ABSOLUTE path: Gradle's Exec resolves command[0] via the JVM's
// inherited PATH, NOT the environment("PATH", …) set above (that only reaches the spawned
// child). A GUI Android Studio launch (and any daemon it started) has no ~/.cargo/bin on
// its PATH, so a bare "cargo" fails to start. The env PATH above still lets cargo/cargo-ndk
// find their subtools.
val cmd = mutableListOf( val cmd = mutableListOf(
"cargo", "ndk", "$cargoBin/cargo", "ndk",
"-t", "arm64-v8a", "-t", "x86_64", "-t", "arm64-v8a", "-t", "x86_64",
// Link against the minSdk-31 sysroot so libaaudio (API 26+) is found. // Link against the minSdk-31 sysroot so libaaudio (API 26+) is found.
"--platform", "31", "--platform", "31",