Files
org.parres.whitenoise/scripts/build_openssl_android.sh
T

203 lines
5.4 KiB
Bash
Executable File

#!/bin/bash
# Build OpenSSL static libraries for Android targets
# This is needed because libsqlite3-sys (SQLCipher) requires libcrypto,
# and Android doesn't ship a system libcrypto.so.
set -eo pipefail
print_step() {
echo -e "\n\033[1;34m=== $1 ===\033[0m"
}
print_success() {
echo -e "\033[1;32m$1\033[0m"
}
print_error() {
echo -e "\033[1;31m$1\033[0m"
}
# Spinner for long-running commands
# Usage: run_quiet "description" logfile command [args...]
run_quiet() {
local desc="$1"
local logfile="$2"
shift 2
printf " %-40s " "$desc"
# Run command in background with output redirected to log file
"$@" >>"$logfile" 2>&1 &
local pid=$!
local spin='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local i=0
while kill -0 "$pid" 2>/dev/null; do
printf "\b%s" "${spin:i++%${#spin}:1}"
sleep 0.1
done
wait "$pid"
local exit_code=$?
if [ $exit_code -eq 0 ]; then
printf "\b\033[1;32m✓\033[0m\n"
else
printf "\b\033[1;31m✗\033[0m\n"
print_error "Command failed. Last 20 lines of log:"
tail -20 "$logfile"
print_error "Full log: $logfile"
exit 1
fi
}
# Configuration
OPENSSL_VERSION="3.4.1"
OPENSSL_SHA256="002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3"
ANDROID_API=33
# Resolve paths
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
OPENSSL_BUILD_DIR="$PROJECT_ROOT/rust/target/openssl"
OPENSSL_SRC_DIR="$OPENSSL_BUILD_DIR/openssl-$OPENSSL_VERSION"
OPENSSL_INSTALL_DIR="$OPENSSL_BUILD_DIR/install"
# Auto-detect Android NDK
if [ -z "$ANDROID_NDK_HOME" ]; then
if [ -n "$NDK_HOME" ]; then
ANDROID_NDK_HOME="$NDK_HOME"
elif [ -n "$ANDROID_HOME" ]; then
NDK_DIR="$ANDROID_HOME/ndk"
if [ -d "$NDK_DIR" ]; then
NDK_VERSION=$(ls "$NDK_DIR" | sort -V | tail -n 1)
if [ -n "$NDK_VERSION" ]; then
ANDROID_NDK_HOME="$NDK_DIR/$NDK_VERSION"
fi
fi
fi
fi
if [ -z "$ANDROID_NDK_HOME" ] || [ ! -d "$ANDROID_NDK_HOME" ]; then
print_error "Android NDK not found. Set ANDROID_NDK_HOME or NDK_HOME."
exit 1
fi
# Detect host OS
case "$(uname -s)" in
Darwin*)
case "$(uname -m)" in
arm64 | aarch64) HOST_TAG="darwin-arm64" ;;
*) HOST_TAG="darwin-x86_64" ;;
esac
;;
Linux*) HOST_TAG="linux-x86_64" ;;
*)
print_error "Unsupported host OS: $(uname -s)"
exit 1
;;
esac
TOOLCHAIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$HOST_TAG"
# Target configurations: (rust_target openssl_target arch)
TARGETS=(
"aarch64-linux-android:android-arm64:aarch64"
"armv7-linux-androideabi:android-arm:armv7a"
"x86_64-linux-android:android-x86_64:x86_64"
)
build_openssl_for_target() {
local rust_target="$1"
local openssl_target="$2"
local arch="$3"
local install_prefix="$OPENSSL_INSTALL_DIR/$rust_target"
# Skip if already built
if [ -f "$install_prefix/lib/libcrypto.a" ]; then
print_success "OpenSSL already built for $rust_target (skipping)"
return 0
fi
print_step "Building OpenSSL for $rust_target ($openssl_target)"
# Clean and re-extract source for each target (OpenSSL doesn't support out-of-tree builds well)
local build_src="$OPENSSL_BUILD_DIR/build-$rust_target"
local logfile="$OPENSSL_BUILD_DIR/$rust_target.log"
rm -rf "$build_src"
: >"$logfile"
cp -r "$OPENSSL_SRC_DIR" "$build_src"
cd "$build_src"
export ANDROID_NDK_ROOT="$ANDROID_NDK_HOME"
export PATH="$TOOLCHAIN/bin:$PATH"
run_quiet "Configuring ($openssl_target)..." "$logfile" \
./Configure "$openssl_target" \
-D__ANDROID_API__=$ANDROID_API \
--prefix="$install_prefix" \
--openssldir="$install_prefix/ssl" \
no-shared \
no-tests \
no-ui-console \
no-stdio \
-fPIC
run_quiet "Compiling..." "$logfile" \
make -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu)" build_libs
run_quiet "Installing headers & libs..." "$logfile" \
make install_dev
cd "$PROJECT_ROOT"
rm -rf "$build_src"
if [ -f "$install_prefix/lib/libcrypto.a" ]; then
print_success " Built OpenSSL for $rust_target"
else
print_error "Failed to build OpenSSL for $rust_target"
print_error "Check log: $logfile"
exit 1
fi
}
# Download OpenSSL source if needed
if [ ! -d "$OPENSSL_SRC_DIR" ]; then
print_step "Downloading OpenSSL $OPENSSL_VERSION"
mkdir -p "$OPENSSL_BUILD_DIR"
cd "$OPENSSL_BUILD_DIR"
TARBALL="openssl-$OPENSSL_VERSION.tar.gz"
if [ ! -f "$TARBALL" ]; then
curl -L --progress-bar -o "$TARBALL" "https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/$TARBALL"
fi
print_step "Verifying tarball integrity"
if command -v shasum >/dev/null 2>&1; then
ACTUAL_SHA256=$(shasum -a 256 "$TARBALL" | awk '{print $1}')
elif command -v sha256sum >/dev/null 2>&1; then
ACTUAL_SHA256=$(sha256sum "$TARBALL" | awk '{print $1}')
else
print_error "No SHA-256 tool found (need shasum or sha256sum)"
exit 1
fi
if [ "$ACTUAL_SHA256" != "$OPENSSL_SHA256" ]; then
print_error "SHA-256 mismatch for $TARBALL"
print_error " Expected: $OPENSSL_SHA256"
print_error " Actual: $ACTUAL_SHA256"
rm -f "$TARBALL"
exit 1
fi
print_success "SHA-256 verified"
tar xzf "$TARBALL"
cd "$PROJECT_ROOT"
fi
# Build for each target
for target_spec in "${TARGETS[@]}"; do
IFS=':' read -r rust_target openssl_target arch <<<"$target_spec"
build_openssl_for_target "$rust_target" "$openssl_target" "$arch"
done
print_success "All OpenSSL Android builds complete!"
echo "Install directory: $OPENSSL_INSTALL_DIR"