From 5c50493238ac57a54fc3a0fe19a1ef79f8bb367e Mon Sep 17 00:00:00 2001
From: Your Name <j@842.be>
Date: Wed, 28 May 2025 22:47:36 +1200
Subject: [PATCH] :-'Generic Commit'

---
 .../install_dropshell_build_host.sh           | 304 ++++++++++++++++++
 1 file changed, 304 insertions(+)
 create mode 100755 dropshell-build/install_dropshell_build_host.sh

diff --git a/dropshell-build/install_dropshell_build_host.sh b/dropshell-build/install_dropshell_build_host.sh
new file mode 100755
index 0000000..a97c92a
--- /dev/null
+++ b/dropshell-build/install_dropshell_build_host.sh
@@ -0,0 +1,304 @@
+#!/bin/bash
+
+set -euo pipefail
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
+
+
+_die() {
+    echo -e "Error: $1" >&2
+    exit 1
+}
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# Function to print status messages
+print_status() {
+    echo -e "${GREEN}[*] $1${NC}"
+}
+
+print_error() {
+    echo -e "${RED}[!] $1${NC}"
+}
+
+print_warning() {
+    echo -e "${YELLOW}[!] $1${NC}"
+}
+
+
+
+#----------------------------------------------------------------------------------------------------------
+# Headers on Host (Native)
+#----------------------------------------------------------------------------------------------------------
+
+
+# Function to check if a package is installed
+function is_package_installed() {
+    dpkg -l "$1" 2>/dev/null | grep -q "^ii"
+}
+
+function install_packages() {
+    local PACKAGES
+    local HAVE_UPDATED=0
+
+    # Detect distribution
+    if [ -f /etc/os-release ]; then
+        . /etc/os-release
+        OS=$NAME
+        VER=$VERSION_ID
+    else
+        print_error "Could not detect distribution"
+        exit 1
+    fi
+
+    print_status "Detected OS: $OS $VER"
+
+    # Define packages based on distribution
+    case $OS in
+        "Ubuntu"|"Debian GNU/Linux")
+            # Common packages for both Ubuntu and Debian
+            PACKAGES="nlohmann-json3-dev wget curl cmake ninja-build mold"
+            ;;
+        *)
+            print_error "Unsupported distribution: $OS"
+            exit 1
+            ;;
+    esac
+
+    # Install missing packages
+    print_status "Checking and installing required packages..."
+    for pkg in $PACKAGES; do
+        if ! is_package_installed "$pkg"; then
+            print_status "Installing $pkg..."
+
+            # Update package lists
+            if [ "$HAVE_UPDATED" -eq 0 ]; then
+                print_status "Updating package lists..."
+                apt-get update
+                HAVE_UPDATED=1
+            fi
+
+            if ! sudo apt-get install -y "$pkg"; then
+                print_error "Failed to install $pkg"
+                exit 1
+            fi
+        else
+            print_status "$pkg is already installed"
+        fi
+    done
+
+}
+
+function install_headers() {
+    # 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 check_path() {
+    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
+}
+
+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 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
+
+    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_packages
+
+    install_headers
+
+    installmusl
+
+    install_openssl_musl
+
+}
+
+main
\ No newline at end of file