'Generic Commit'

This commit is contained in:
Your Name
2025-06-01 14:42:57 +12:00
parent 8f02394e60
commit a1e8131da7
3 changed files with 2 additions and 2 deletions

View File

@@ -0,0 +1,348 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# If the user is not root, use sudo
SUDOCMD=""
[ "$EUID" -eq 0 ] || SUDOCMD="sudo"
# If the user is not root, use the home directory of the user who ran the script
USER_HOME="$HOME"
if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
USER_HOME=$(eval echo "~${SUDO_USER}")
fi
# test sudo is working or we're root (return non-zero if not root!)
if ! ${SUDOCMD:-} true; then
echo "Error: This script must be run as root or with sudo privileges." >&2
exit 1
fi
_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
is_package_installed() {
if [ "$OS" = "Alpine Linux" ]; then
apk info | grep -q "^$1$"
else
dpkg -l "$1"
fi
}
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
# cmake make g++ build-essential upx musl-tools wget tar ccache ninja-build mold
PACKAGES="build-essential cmake git wget tar curl ninja-build mold nodejs npm perl jq ccache"
INSTALLCMD="apt-get install -y"
UPDATECMD="apt-get update"
;;
"Alpine Linux")
PACKAGES="build-base cmake git wget tar curl ninja mold nodejs npm linux-headers perl jq ccache"
INSTALLCMD="apk add --no-cache"
UPDATECMD="apk update"
;;
*)
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..."
${SUDOCMD:-} bash -c "${UPDATECMD}"
HAVE_UPDATED=1
fi
if ! bash -c "${SUDOCMD:-} ${INSTALLCMD} $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.
echo "Checking for libassert headers"
if [ ! -f "/usr/local/lib/libassert.a" ]; then
echo "libassert not found, installing..."
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
${SUDOCMD:-} make install
cd ../..
rm -rf libassert
else
echo "libassert headers already installed"
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"
DEST_PATH="$SYSROOT/usr/lib/libssl.a"
if [ -f "$DEST_PATH" ]; then
echo "OpenSSL $ARCH is already installed"
continue
fi
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
else
echo "No libssl.a found, will rebuild."
fi
if [ "$SKIP_BUILD" -eq 1 ]; then
echo "Skipping build for $ARCH."
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}"
echo "----------------------------------------------"
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://getbin.xyz"
if [ ! -d "$INSTALL_DIR/$TOOLCHAIN" ]; then
echo "Downloading $TOOLCHAIN musl cross toolchain..."
wget -nc -O "$TMPDIR/$TOOLCHAIN.tgz" "$MUSL_CC_URL/$TOOLCHAIN.tgz:latest"
tar -C "$INSTALL_DIR" -xvf "$TMPDIR/$TOOLCHAIN.tgz"
else
echo "$TOOLCHAIN musl cross toolchain already installed"
fi
}
function install_musl() {
echo "Installing musl toolchain"
# Set install directory
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"
}
function output_version() {
local VERSIONDATE
local CONFIG_DIR="$USER_HOME/.config/dropshell-build/"
mkdir -p "$CONFIG_DIR"
VERSIONDATE="$(date +%Y.%m%d.%H%M)"
echo "$VERSIONDATE" > "$CONFIG_DIR/version" || echo "Error: Failed to write version file to $CONFIG_DIR/version"
}
#----------------------------------------------------------------------------------------------------------
# Main
#----------------------------------------------------------------------------------------------------------
function main() {
install_packages
install_headers
install_musl
install_openssl_musl
output_version
echo "Done"
}
main "$@"