#!/usr/bin/env bash # Идемпотентно ставит Android-тулчейн под пины upstream.txt (сборка RustDesk APK). # Debian/Ubuntu (VM 118). Android SDK уже в /opt/android-sdk. Ставит в ~/dev. # Ставит только отсутствующее -> после bump-upstream.sh достаточно перезапустить. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" declare -A P while IFS='=' read -r k v; do [[ "$k" =~ ^[A-Z] ]] && P[$k]="${v%$'\r'}"; done < "$ROOT/upstream.txt" FLUTTER_V="${P[ANDROID_FLUTTER_VERSION]}"; RUST_V="${P[RUST_VERSION]}" CARGO_NDK_V="${P[CARGO_NDK_VERSION]}"; FRB_V="${P[FRB_VERSION]}"; CEXPAND_V="${P[CARGO_EXPAND_VERSION]}" NDK_R="${P[NDK_VERSION]}" DEV="$HOME/dev"; mkdir -p "$DEV" echo "== provision-android == Flutter $FLUTTER_V, Rust $RUST_V, NDK $NDK_R, cargo-ndk $CARGO_NDK_V" # --- apt-зависимости --- echo "[apt] deps..." sudo apt-get update -qq sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \ clang libclang-dev cmake ninja-build nasm yasm pkg-config build-essential \ curl git unzip xz-utils zip python3-pip >/dev/null # --- Rust + aarch64-android --- if [ ! -x "$HOME/.cargo/bin/rustc" ] && ! command -v rustc >/dev/null; then echo "[rust] rustup ($RUST_V)..." curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain "$RUST_V" --profile minimal fi source "$HOME/.cargo/env" rustup toolchain install "$RUST_V" -c rustfmt >/dev/null 2>&1 || true rustup default "$RUST_V" >/dev/null rustup target add aarch64-linux-android >/dev/null rustup component add rustfmt >/dev/null 2>&1 || true # --- cargo-инструменты (пины) --- command -v cargo-ndk >/dev/null || { echo "[cargo] cargo-ndk $CARGO_NDK_V..."; cargo install cargo-ndk --version "$CARGO_NDK_V" --locked; } [ -x "$HOME/.cargo/bin/cargo-expand" ] || { echo "[cargo] cargo-expand $CEXPAND_V..."; cargo install cargo-expand --version "$CEXPAND_V" --locked; } [ -x "$HOME/.cargo/bin/flutter_rust_bridge_codegen" ] || { echo "[cargo] FRB $FRB_V..."; cargo install flutter_rust_bridge_codegen --version "$FRB_V" --features uuid --locked; } # --- NDK r28c (напрямую от Google, версия-точная) --- NDK_DIR="$DEV/android-ndk-$NDK_R" if [ ! -d "$NDK_DIR" ]; then echo "[ndk] $NDK_R..." curl -fsSL "https://dl.google.com/android/repository/android-ndk-$NDK_R-linux.zip" -o "$DEV/ndk.zip" unzip -q "$DEV/ndk.zip" -d "$DEV"; rm -f "$DEV/ndk.zip" fi # --- Flutter (linux) --- FLUTTER_DIR="$DEV/flutter" have=""; [ -x "$FLUTTER_DIR/bin/flutter" ] && have="$("$FLUTTER_DIR/bin/flutter" --version 2>/dev/null | grep -oE 'Flutter [0-9]+\.[0-9]+\.[0-9]+' | awk '{print $2}')" if [ "$have" != "$FLUTTER_V" ]; then echo "[flutter] нужен $FLUTTER_V (есть '${have:-—}')..." rm -rf "$FLUTTER_DIR" curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_$FLUTTER_V-stable.tar.xz" -o "$DEV/flutter.tar.xz" tar -xf "$DEV/flutter.tar.xz" -C "$DEV"; rm -f "$DEV/flutter.tar.xz" git config --global --add safe.directory "$FLUTTER_DIR" || true "$FLUTTER_DIR/bin/flutter" --version >/dev/null 2>&1 || true fi # --- vcpkg@пин --- VCPKG_DIR="$DEV/vcpkg"; VCPKG_C="${P[VCPKG_COMMIT_ID]}" [ -d "$VCPKG_DIR/.git" ] || { echo "[vcpkg] clone..."; git clone -q https://github.com/microsoft/vcpkg.git "$VCPKG_DIR"; } if [ "$(git -C "$VCPKG_DIR" rev-parse HEAD)" != "$VCPKG_C" ]; then git -C "$VCPKG_DIR" fetch -q origin; git -C "$VCPKG_DIR" checkout -q "$VCPKG_C"; rm -f "$VCPKG_DIR/vcpkg" fi [ -x "$VCPKG_DIR/vcpkg" ] || (cd "$VCPKG_DIR" && ./bootstrap-vcpkg.sh -disableMetrics >/dev/null) # --- env-файл для сборки --- cat > "$DEV/rd-android.env" </dev/null || true EOF echo "== provision-android готов. env: $DEV/rd-android.env =="