Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion patches/xbuild/xbuild/src/gradle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,19 @@ pub fn build(env: &BuildEnv, libraries: Vec<(Target, PathBuf)>, out: &Path) -> R
}
std::fs::create_dir_all(&assets)?;
std::fs::write(gradle.join("build.gradle"), BUILD_GRADLE)?;
std::fs::write(gradle.join("gradle.properties"), GRADLE_PROPERTIES)?;
// On Android hosts (e.g. Termux), AGP bundles an x86_64 Linux aapt2 that cannot
// run on ARM64. If a native aapt2 is available in PATH, override the bundled one.
let mut gradle_props = GRADLE_PROPERTIES.to_vec();
if cfg!(target_os = "android") {
if let Ok(aapt2_path) = which::which("aapt2") {
let override_line = format!(
"\n# Termux: use native ARM64 aapt2 instead of the x86_64 binary bundled in AGP\nandroid.aapt2FromMavenOverride={}\n",
aapt2_path.display()
);
gradle_props.extend_from_slice(override_line.as_bytes());
}
}
std::fs::write(gradle.join("gradle.properties"), &gradle_props)?;
std::fs::write(gradle.join("settings.gradle"), SETTINGS_GRADLE)?;

let config = env.config().android();
Expand Down
2 changes: 1 addition & 1 deletion patches/xbuild/xbuild/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub enum Platform {

impl Platform {
pub fn host() -> Result<Self> {
Ok(if cfg!(target_os = "linux") {
Ok(if cfg!(target_os = "linux") || cfg!(target_os = "android") {
Platform::Linux
} else if cfg!(target_os = "macos") {
Platform::Macos
Expand Down
95 changes: 95 additions & 0 deletions scripts/build-termux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/data/data/com.termux/files/usr/bin/bash
# build-termux.sh — Build LocalDesktop APK from Termux on Android
#
# Usage:
# bash scripts/build-termux.sh
#
# The script is idempotent: already-installed packages and already-downloaded
# SDK components are skipped automatically.

set -e

REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
ANDROID_HOME="${ANDROID_HOME:-$HOME/.cache/x/Android.sdk}"
CARGO_BIN="$HOME/.cargo/bin"

echo "==> LocalDesktop Termux build"
echo " Repo: $REPO_ROOT"
echo " ANDROID_HOME: $ANDROID_HOME"
echo ""

# ---------------------------------------------------------------------------
# 1. Termux dependencies
# ---------------------------------------------------------------------------
echo "[1/5] Installing Termux packages..."
pkg install -y rust openjdk-17 gradle ndk-multilib aapt2 2>/dev/null | tail -3

# ---------------------------------------------------------------------------
# 2. PATH setup
# ---------------------------------------------------------------------------
export PATH="$CARGO_BIN:$HOME/bin:$PATH"
export ANDROID_HOME

# Fake rustup shim: xbuild calls `rustup target add` to check targets.
# Termux's Rust already ships the aarch64-linux-android target.
RUSTUP_SHIM="$HOME/bin/rustup"
if [ ! -f "$RUSTUP_SHIM" ]; then
echo "[2/5] Installing rustup shim..."
mkdir -p "$HOME/bin"
cat > "$RUSTUP_SHIM" << 'EOF'
#!/data/data/com.termux/files/usr/bin/bash
if [ "$1" = "target" ] && [ "$2" = "add" ]; then
echo "info: component 'rust-std' for target '${3}' is up to date"
exit 0
fi
echo "rustup shim: unsupported command: $*" >&2
exit 1
EOF
chmod +x "$RUSTUP_SHIM"
else
echo "[2/5] rustup shim already present."
fi

# ---------------------------------------------------------------------------
# 3. xbuild (patched fork — Android host support + AGP/KGP compatibility)
# ---------------------------------------------------------------------------
echo "[3/5] Installing xbuild..."
# MALLOC_TAG_LEVEL=0 avoids an LLVM/lld crash caused by Android pointer tagging
MALLOC_TAG_LEVEL=0 cargo install --path "$REPO_ROOT/patches/xbuild/xbuild" --force \
2>&1 | grep -E "Compiling xbuild|Replacing|Installed|error" || true

# ---------------------------------------------------------------------------
# 4. Android SDK build-tools
# ---------------------------------------------------------------------------
echo "[4/5] Downloading Android SDK components..."
mkdir -p "$ANDROID_HOME/licenses"
# Accept standard SDK licenses
printf "24333f8a63b6825ea9c5514f83c2829b004d1fee\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e\n" \
> "$ANDROID_HOME/licenses/android-sdk-license"
printf "84831b9409646a918e30573bab4c9c91346d8abd\n" \
> "$ANDROID_HOME/licenses/android-sdk-preview-license"

if [ ! -d "$ANDROID_HOME/build-tools/34.0.0" ]; then
MALLOC_TAG_LEVEL=0 cargo run --manifest-path "$REPO_ROOT/Cargo.toml" \
--bin download_sdk 2>&1 | grep -v "^ Compiling\|^ Checking\|^warning"
else
echo " build-tools;34.0.0 already present."
fi

# ---------------------------------------------------------------------------
# 5. Build APK
# ---------------------------------------------------------------------------
echo "[5/5] Building APK..."
cd "$REPO_ROOT"
MALLOC_TAG_LEVEL=0 x build --release --platform android --arch arm64 --format apk

APK="$REPO_ROOT/target/x/release/android/localdesktop.apk"
if [ -f "$APK" ]; then
echo ""
echo "✅ Build successful!"
echo " APK: $APK"
echo " Size: $(du -h "$APK" | cut -f1)"
else
echo "❌ Build failed — APK not found." >&2
exit 1
fi
25 changes: 25 additions & 0 deletions src/bin/download_sdk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/// One-shot utility: download Android SDK build-tools;34.0.0 into ANDROID_HOME.
/// Usage: cargo run --bin download_sdk
use std::path::PathBuf;

fn main() {
let android_home = std::env::var("ANDROID_HOME")
.unwrap_or_else(|_| format!("{}/.cache/x/Android.sdk", std::env::var("HOME").unwrap()));
let sdk_dir = PathBuf::from(&android_home);
let build_tools_dir = sdk_dir.join("build-tools").join("34.0.0");

if build_tools_dir.exists() {
println!("build-tools;34.0.0 already present at {}", build_tools_dir.display());
return;
}

println!("Downloading build-tools;34.0.0 into {}...", android_home);
android_sdkmanager::download_and_extract_packages(
&android_home,
android_sdkmanager::HostOs::Linux,
&["build-tools;34.0.0"],
None,
);

println!("Done. build-tools are at {}", build_tools_dir.display());
}
Loading