fix(android): bake android24→26 clang shim into the docker image itself
Build #13's PATH wrapper trick failed because tauri-cli invokes the linker with an absolute path (/opt/android-sdk/ndk/.../bin/aarch64-linux-android24- clang), which bypasses \$PATH entirely. The pthread_shim logs confirmed the broken API-24 stubs were still being linked: WZP_pthread_shim: dlsym(RTLD_DEFAULT, pthread_create) returned NULL: libdl.a is a stub --- use libdl.so instead Move the fix up a level — into the Dockerfile itself. On image build, for each of the four android ABIs × {clang, clang++}, rename `${abi}24-${suffix}` to `${abi}24-${suffix}.orig` and replace it with a shell wrapper that exec()s `${abi}26-${suffix}`. Any call to the API-24 wrapper — via PATH, absolute path, or otherwise — now transparently runs the API-26 wrapper, which uses the real libc.so/libdl.so bindings. The old bash-c /tmp/wrappers workaround in build-tauri-android.sh is removed now that the image handles it at the right layer. Also add `--shell` to build-tauri-android.sh: opens an interactive docker container on the remote with the same mounts/env as the build, so I can iterate on cargo tauri android build / manually patch files / etc. without the full git push → ssh → rebuild → install loop. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,27 @@ RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/nu
|
||||
"platform-tools" \
|
||||
2>&1 | grep -v '^\[' > /dev/null
|
||||
|
||||
# Work around broken API-24 libc/libdl stubs in the NDK. Rust's pre-compiled
|
||||
# libstd.rlib for aarch64-linux-android links against pthread_create / dlsym
|
||||
# from the sysroot. With --target=...24, those resolve to the API-24 "stub"
|
||||
# libc.a/libdl.a that return "libdl.a is a stub --- use libdl.so instead" at
|
||||
# runtime. API-26 has real dynamic bindings. Tauri-cli hard-codes the
|
||||
# android24-clang path so env var overrides don't stick.
|
||||
#
|
||||
# Permanent fix inside the image: replace every `${abi}24-clang` binary with
|
||||
# a shim that exec()s the corresponding `${abi}26-clang`. Any build using
|
||||
# this image now transparently gets the API-26 sysroot even when the caller
|
||||
# asks for API-24.
|
||||
RUN set -eux; \
|
||||
BIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin; \
|
||||
for abi in aarch64-linux-android armv7a-linux-androideabi i686-linux-android x86_64-linux-android; do \
|
||||
for suffix in clang clang++; do \
|
||||
mv "$BIN/${abi}24-${suffix}" "$BIN/${abi}24-${suffix}.orig"; \
|
||||
printf '#!/bin/sh\nexec "%s/%s26-%s" "$@"\n' "$BIN" "$abi" "$suffix" > "$BIN/${abi}24-${suffix}"; \
|
||||
chmod +x "$BIN/${abi}24-${suffix}"; \
|
||||
done; \
|
||||
done
|
||||
|
||||
# Make SDK world-readable so builder user can access it
|
||||
RUN chmod -R a+rX $ANDROID_HOME
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ REBUILD_RUST=0
|
||||
DO_PULL=1
|
||||
DO_INIT=0
|
||||
BUILD_RELEASE=0
|
||||
DROP_SHELL=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--rust) REBUILD_RUST=1 ;;
|
||||
@@ -43,6 +44,7 @@ for arg in "$@"; do
|
||||
--no-pull) DO_PULL=0 ;;
|
||||
--init) DO_INIT=1 ;;
|
||||
--release) BUILD_RELEASE=1 ;;
|
||||
--shell) DROP_SHELL=1 ;; # interactive debug shell inside container
|
||||
-h|--help)
|
||||
sed -n '3,30p' "$0"
|
||||
exit 0
|
||||
@@ -50,6 +52,34 @@ for arg in "$@"; do
|
||||
esac
|
||||
done
|
||||
|
||||
# ── --shell: drop into an interactive container for fast manual iteration ──
|
||||
# The container is NOT --rm'd so you can keep hacking between invocations,
|
||||
# and has the same mounts / env as the build path above so `cargo tauri
|
||||
# android build ...` just works.
|
||||
if [ "$DROP_SHELL" = "1" ]; then
|
||||
log "Starting interactive shell in wzp-android-builder container..."
|
||||
log " cd /build/source/desktop/src-tauri && cargo tauri android build --debug --target aarch64 --apk"
|
||||
log " (exit the shell with ^D; container will be removed)"
|
||||
ssh -t -A $SSH_OPTS "$REMOTE_HOST" "
|
||||
set -euo pipefail
|
||||
BASE=$BASE_DIR
|
||||
# Make sure the source/cache is writable by uid 1000
|
||||
sudo chown -R 1000:1000 \$BASE/data/source \$BASE/data/cache 2>/dev/null || true
|
||||
docker run --rm -it \
|
||||
--user 1000:1000 \
|
||||
-v \$BASE/data/source:/build/source \
|
||||
-v \$BASE/data/cache/cargo-registry:/home/builder/.cargo/registry \
|
||||
-v \$BASE/data/cache/cargo-git:/home/builder/.cargo/git \
|
||||
-v \$BASE/data/cache/target:/build/source/target \
|
||||
-v \$BASE/data/cache/gradle:/home/builder/.gradle \
|
||||
-v \$BASE/data/cache/android-home:/home/builder/.android \
|
||||
-w /build/source/desktop/src-tauri \
|
||||
wzp-android-builder \
|
||||
bash
|
||||
"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log() { echo -e "\033[1;36m>>> $*\033[0m"; }
|
||||
ssh_cmd() { ssh -A $SSH_OPTS "$REMOTE_HOST" "$@"; }
|
||||
|
||||
@@ -166,30 +196,6 @@ docker run --rm \
|
||||
wzp-android-builder \
|
||||
bash -c '
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Linker wrappers ───────────────────────────────────────────────────────
|
||||
# Tauri-cli hard-codes aarch64-linux-android24-clang as the Rust linker for
|
||||
# the aarch64 target, which resolves pthread_create / dlsym / __init_tcb
|
||||
# against the NDK API-24 *stub* libc.a/libdl.a. Those stubs are designed to
|
||||
# crash if called — they only exist so the API-24 sysroot compiles, not so
|
||||
# symbols actually work. API-26 has the real dynamic bindings to libc.so.
|
||||
#
|
||||
# Rather than fight tauri-cli to change which clang it invokes, we put a
|
||||
# wrapper on $PATH that IS named android24-clang but exec()s the android26
|
||||
# version. Same trick works for every ABI.
|
||||
mkdir -p /tmp/wrappers
|
||||
for abi in aarch64-linux-android armv7a-linux-androideabi i686-linux-android x86_64-linux-android; do
|
||||
for suffix in clang clang++; do
|
||||
cat > /tmp/wrappers/${abi}24-${suffix} <<WRAPPER
|
||||
#!/bin/sh
|
||||
exec /opt/android-sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/linux-x86_64/bin/${abi}26-${suffix} "\$@"
|
||||
WRAPPER
|
||||
chmod +x /tmp/wrappers/${abi}24-${suffix}
|
||||
done
|
||||
done
|
||||
export PATH=/tmp/wrappers:$PATH
|
||||
echo ">>> installed android24→android26 linker wrappers in /tmp/wrappers"
|
||||
|
||||
cd /build/source/desktop
|
||||
|
||||
echo ">>> npm install"
|
||||
|
||||
Reference in New Issue
Block a user