Files
2026-07-13 13:16:30 +08:00

158 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# install-glibc.sh - Install glibc-runner (L2 conditional)
# Extracted from install-glibc-env.sh — glibc runtime only, no Node.js.
# Called by orchestrator when config.env PLATFORM_NEEDS_GLIBC=true.
#
# What it does:
# 1. Install pacman package
# 2. Initialize pacman and install glibc-runner
# 3. Verify glibc dynamic linker
# 4. Create marker file
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
OPENCLAW_DIR="$HOME/.openclaw-android"
GLIBC_LDSO="$PREFIX/glibc/lib/ld-linux-aarch64.so.1"
PACMAN_CONF="$PREFIX/etc/pacman.conf"
echo "=== Installing glibc Runtime ==="
echo ""
# ── Pre-checks ───────────────────────────────
if [ -z "${PREFIX:-}" ]; then
echo -e "${RED}[FAIL]${NC} Not running in Termux (\$PREFIX not set)"
exit 1
fi
ARCH=$(uname -m)
if [ "$ARCH" != "aarch64" ]; then
echo -e "${RED}[FAIL]${NC} glibc environment requires aarch64 (got: $ARCH)"
exit 1
fi
# ── Install supplementary glibc libraries (always runs) ──
# glibc-runner provides core libraries but not all libraries that
# third-party binaries may need (e.g., libcap.so.2 for codex-acp).
# This runs on both fresh install and update to ensure libraries are current.
GLIBC_LIB_DIR="$PREFIX/glibc/lib"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GLIBC_LIBS_SRC="$SCRIPT_DIR/../patches/glibc-libs"
if [ -d "$GLIBC_LIB_DIR" ] && [ -d "$GLIBC_LIBS_SRC" ]; then
for lib in "$GLIBC_LIBS_SRC"/*.so.*; do
[ -f "$lib" ] || continue
filename=$(basename "$lib")
soname=$(echo "$filename" | sed -E 's/^(lib[^.]+\.so\.[0-9]+)\..*/\1/')
if [ ! -f "$GLIBC_LIB_DIR/$filename" ]; then
cp "$lib" "$GLIBC_LIB_DIR/$filename"
[ "$soname" != "$filename" ] && ln -sf "$filename" "$GLIBC_LIB_DIR/$soname"
echo -e "${GREEN}[OK]${NC} Installed $soname"
fi
done
fi
# ── Ensure glibc /etc/hosts exists (always runs) ──
# glibc's getaddrinfo reads $PREFIX/glibc/etc/hosts for localhost resolution.
# Neither glibc nor glibc-runner packages include this file; it comes from
# resolv-conf (via openssl-glibc) which may not be installed.
# Without it, dns.lookup('localhost') can return 0.0.0.0 → gateway bind failure.
GLIBC_ETC="$PREFIX/glibc/etc"
if [ -d "$GLIBC_ETC" ] && [ ! -f "$GLIBC_ETC/hosts" ]; then
cat > "$GLIBC_ETC/hosts" <<'HOSTS'
127.0.0.1 localhost localhost.localdomain
::1 localhost ip6-localhost ip6-loopback
HOSTS
echo -e "${GREEN}[OK]${NC} Created glibc /etc/hosts"
fi
# Check if already installed
if [ -f "$OPENCLAW_DIR/.glibc-arch" ] && [ -x "$GLIBC_LDSO" ]; then
echo -e "${GREEN}[SKIP]${NC} glibc-runner already installed"
exit 0
fi
# ── Step 1: Install pacman ────────────────────
echo "Installing pacman..."
if ! pkg install -y pacman; then
echo -e "${RED}[FAIL]${NC} Failed to install pacman"
exit 1
fi
echo -e "${GREEN}[OK]${NC} pacman installed"
# ── Step 2: Initialize pacman ─────────────────
echo ""
echo "Initializing pacman..."
echo " (This may take a few minutes for GPG key generation)"
# SigLevel workaround: Some devices have a GPGME crypto engine bug
# that prevents signature verification. Temporarily set SigLevel = Never.
SIGLEVEL_PATCHED=false
if [ -f "$PACMAN_CONF" ]; then
if ! grep -q "^SigLevel = Never" "$PACMAN_CONF"; then
cp "$PACMAN_CONF" "${PACMAN_CONF}.bak"
sed -i 's/^SigLevel\s*=.*/SigLevel = Never/' "$PACMAN_CONF"
SIGLEVEL_PATCHED=true
echo -e "${YELLOW}[INFO]${NC} Applied SigLevel = Never workaround (GPGME bug)"
fi
fi
# Initialize pacman keyring (may hang on low-entropy devices)
pacman-key --init 2>/dev/null || true
pacman-key --populate 2>/dev/null || true
# ── Step 3: Install glibc-runner ──────────────
echo ""
echo "Installing glibc-runner..."
# --assume-installed: these packages are provided by Termux's apt but pacman
# doesn't know about them, causing dependency resolution failures
if pacman -Sy glibc-runner --noconfirm --assume-installed bash,patchelf,resolv-conf 2>&1; then
echo -e "${GREEN}[OK]${NC} glibc-runner installed"
else
echo -e "${RED}[FAIL]${NC} Failed to install glibc-runner"
if [ "$SIGLEVEL_PATCHED" = true ] && [ -f "${PACMAN_CONF}.bak" ]; then
mv "${PACMAN_CONF}.bak" "$PACMAN_CONF"
fi
exit 1
fi
# Restore SigLevel after successful install
if [ "$SIGLEVEL_PATCHED" = true ] && [ -f "${PACMAN_CONF}.bak" ]; then
mv "${PACMAN_CONF}.bak" "$PACMAN_CONF"
echo -e "${GREEN}[OK]${NC} Restored pacman SigLevel"
fi
# ── Verify ────────────────────────────────────
if [ ! -x "$GLIBC_LDSO" ]; then
echo -e "${RED}[FAIL]${NC} glibc dynamic linker not found at $GLIBC_LDSO"
exit 1
fi
echo -e "${GREEN}[OK]${NC} glibc dynamic linker available"
if command -v grun &>/dev/null; then
echo -e "${GREEN}[OK]${NC} grun command available"
else
echo -e "${YELLOW}[WARN]${NC} grun command not found (will use ld.so directly)"
fi
# ── Create marker file ────────────────────────
mkdir -p "$OPENCLAW_DIR"
touch "$OPENCLAW_DIR/.glibc-arch"
echo -e "${GREEN}[OK]${NC} glibc architecture marker created"
echo ""
echo -e "${GREEN}glibc runtime installed successfully.${NC}"
echo " ld.so: $GLIBC_LDSO"