#!/bin/bash set -euo pipefail SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" #---------------------------------------------------------------------------------------------------------- # Headers on Host (Native) #---------------------------------------------------------------------------------------------------------- function install_headers() { sudo apt install -y nlohmann-json3-dev wget curl cmake ninja-build mold # put libassert headers on the host. if [ ! -f /usr/local/lib/libassert.a ]; then git clone https://github.com/jeremy-rifkin/libassert.git git checkout v2.1.5 mkdir libassert/build cd "libassert/build" || exit 1 cmake .. -DCMAKE_BUILD_TYPE=Release make -j sudo make install cd ../.. rm -rf libassert fi } #---------------------------------------------------------------------------------------------------------- # OpenSSL for musl cross toolchains #---------------------------------------------------------------------------------------------------------- function install_openssl_musl() { OPENSSL_VERSION=3.5.0 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BUILD_DIR="${SCRIPT_DIR}/build" MUSL_CROSS_DIR="$HOME/.musl-cross" mkdir -p "$BUILD_DIR" # Helper: compare versions (returns 0 if $1 >= $2) version_ge() { [ "$1" = "$2" ] && return 0 [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ] } # Find all installed musl cross toolchains TOOLCHAINS=() for tc in "$MUSL_CROSS_DIR"/*-linux-musl-cross; do [ -d "$tc" ] || continue arch=$(basename "$tc" | sed 's/-linux-musl-cross//') TOOLCHAINS+=("$arch") done if [ ${#TOOLCHAINS[@]} -eq 0 ]; then echo "No musl cross toolchains found in $MUSL_CROSS_DIR. Exiting." exit 1 fi echo "Found musl cross toolchains: ${TOOLCHAINS[*]}" for ARCH in "${TOOLCHAINS[@]}"; do echo "===============================" echo "Checking OpenSSL for $ARCH..." echo "===============================" if [ "$ARCH" = "x86_64" ]; then MUSL_PREFIX="$MUSL_CROSS_DIR/x86_64-linux-musl-cross" OPENSSL_TARGET=linux-x86_64 elif [ "$ARCH" = "aarch64" ]; then MUSL_PREFIX="$MUSL_CROSS_DIR/aarch64-linux-musl-cross" OPENSSL_TARGET=linux-aarch64 else # Try to guess OpenSSL target for other musl toolchains OPENSSL_TARGET="linux-$ARCH" MUSL_PREFIX="$MUSL_CROSS_DIR/${ARCH}-linux-musl-cross" fi SYSROOT="$MUSL_PREFIX/${ARCH}-linux-musl/sysroot" CC="$MUSL_PREFIX/bin/${ARCH}-linux-musl-gcc" AR="$MUSL_PREFIX/bin/${ARCH}-linux-musl-ar" RANLIB="$MUSL_PREFIX/bin/${ARCH}-linux-musl-ranlib" SKIP_BUILD=0 if [ -f "$SYSROOT/usr/lib/libssl.a" ]; then # Try to extract version from opensslv.h OPENSSLV_H="$SYSROOT/usr/include/openssl/opensslv.h" if [ -f "$OPENSSLV_H" ]; then INSTALLED_VERSION=$(grep '# *define *OPENSSL_VERSION_TEXT' "$OPENSSLV_H" | sed -E 's/.*OpenSSL ([0-9.]+)[^ ]*.*/\1/') if [ -n "$INSTALLED_VERSION" ]; then echo "Found installed OpenSSL version: $INSTALLED_VERSION" if version_ge "$INSTALLED_VERSION" "$OPENSSL_VERSION"; then echo "OpenSSL $INSTALLED_VERSION is up-to-date (>= $OPENSSL_VERSION), skipping build for $ARCH." SKIP_BUILD=1 else echo "OpenSSL $INSTALLED_VERSION is older than $OPENSSL_VERSION, will rebuild." fi else echo "Could not determine installed OpenSSL version, will rebuild." fi else echo "No opensslv.h found, will rebuild." fi fi if [ "$SKIP_BUILD" -eq 1 ]; then echo continue fi cd "$BUILD_DIR" if [ ! -d "openssl-${OPENSSL_VERSION}" ]; then if [ ! -f "openssl-${OPENSSL_VERSION}.tar.gz" ]; then wget "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" fi tar xf "openssl-${OPENSSL_VERSION}.tar.gz" fi cd "openssl-${OPENSSL_VERSION}" # Clean previous build for this arch make clean || true echo "Configuring for $ARCH with sysroot $SYSROOT..." CC="$CC" AR="$AR" RANLIB="$RANLIB" ./Configure "$OPENSSL_TARGET" no-shared --prefix="$SYSROOT/usr" echo "Building..." make -j"$(nproc)" echo "Installing to $SYSROOT/usr ..." make install_sw cd "$BUILD_DIR" echo "Done for $ARCH." echo # Remove build dir for next arch to avoid cross contamination rm -rf "openssl-${OPENSSL_VERSION}" tar xf "openssl-${OPENSSL_VERSION}.tar.gz" done echo "OpenSSL built and installed for all detected musl toolchains." } # ---------------------------------------------------------------------------------------------------------- # MUSL CROSS COMPILERS # ---------------------------------------------------------------------------------------------------------- function installmusl() { echo "Installing musl toolchain" # Set install directory if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then USER_HOME=$(eval echo "~${SUDO_USER}") else USER_HOME="$HOME" fi INSTALL_DIR="$USER_HOME/.musl-cross" mkdir -p "$INSTALL_DIR" TMPDIR=$(mktemp -d) trap 'rm -rf "$TMPDIR"' EXIT function install_musl_cross() { local TOOLCHAIN="$1" local MUSL_CC_URL="https://musl.cc" if [ ! -d "$INSTALL_DIR/$TOOLCHAIN" ]; then echo "Downloading $TOOLCHAIN musl cross toolchain..." wget -nc -O "$TMPDIR/$TOOLCHAIN.tgz" "$MUSL_CC_URL/$TOOLCHAIN.tgz" tar -C "$INSTALL_DIR" -xvf "$TMPDIR/$TOOLCHAIN.tgz" fi } function check_path() { if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then local BASHRC="$USER_HOME/.bashrc" local TOOLCHAIN="$1" local MUSL_PATH="$INSTALL_DIR/$TOOLCHAIN/bin" if ! echo "$PATH" | grep -q "$MUSL_PATH"; then echo "Adding $MUSL_PATH to PATH in $BASHRC" PATH_LINE="export PATH=\"$MUSL_PATH:\$PATH\"" if ! grep -Fxq "$PATH_LINE" "$BASHRC"; then echo "" >> "$BASHRC" echo "# Add musl cross compilers to PATH for dropshell" >> "$BASHRC" echo "$PATH_LINE" >> "$BASHRC" echo "Added musl cross compilers to $BASHRC" echo "You should run 'source ~/.bashrc' to update your PATH" else echo "You should run 'source ~/.bashrc' to update your PATH" fi fi fi } TOOLCHAIN_LIST=( "aarch64-linux-musl-cross" "x86_64-linux-musl-cross" ) for TOOLCHAIN in "${TOOLCHAIN_LIST[@]}"; do install_musl_cross "$TOOLCHAIN" check_path "$TOOLCHAIN" done # Clean up rm -rf "$TMPDIR" } #---------------------------------------------------------------------------------------------------------- # Main #---------------------------------------------------------------------------------------------------------- function main() { install_headers installmusl install_openssl_musl } main