203 lines
5.4 KiB
Bash
Executable File
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"
|