diff --git a/Dockerfile b/Dockerfile index 090ae6e..ffa772e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,49 +1,39 @@ -FROM ubuntu:latest +FROM --platform=$BUILDPLATFORM alpine:latest AS builder +# Add build arguments for platform +ARG TARGETPLATFORM +ARG BUILDPLATFORM -RUN mkdir -p "$HOME/.musl-cross" +# Install build dependencies +RUN apk add --no-cache \ + build-base \ + cmake \ + git \ + musl-dev \ + curl \ + bash \ + musl \ + g++ \ + ninja \ + linux-headers \ + mold -RUN apt-get update && apt-get install -y \ - wget tar curl bash git && \ - rm -rf /var/lib/apt/lists/* +# Set working directory +WORKDIR /build -RUN wget -nc -O "$HOME/.musl-cross/x86_64-linux-musl-cross.tgz" "https://getbin.xyz/x86_64-linux-musl-cross.tgz:latest" && \ - tar -C "$HOME/.musl-cross" -xvf "$HOME/.musl-cross/x86_64-linux-musl-cross.tgz" && \ - rm "$HOME/.musl-cross/x86_64-linux-musl-cross.tgz" +# Copy source files +COPY . . -RUN wget -nc -O "$HOME/.musl-cross/x86_64-linux-musl-native.tgz" "https://getbin.xyz/x86_64-linux-musl-native.tgz:latest" && \ - tar -C "$HOME/.musl-cross" -xvf "$HOME/.musl-cross/x86_64-linux-musl-native.tgz" && \ - rm "$HOME/.musl-cross/x86_64-linux-musl-native.tgz" - -RUN wget -nc -O "$HOME/.musl-cross/aarch64-linux-musl-cross.tgz" "https://getbin.xyz/aarch64-linux-musl-cross.tgz:latest" && \ - tar -C "$HOME/.musl-cross" -xvf "$HOME/.musl-cross/aarch64-linux-musl-cross.tgz" && \ - rm "$HOME/.musl-cross/aarch64-linux-musl-cross.tgz" - - - -RUN apt-get update && apt-get install -y \ - build-essential cmake ninja-build mold nodejs npm perl jq ccache nlohmann-json3-dev \ - ca-certificates upx-ucl autoconf automake libtool gawk \ - && rm -rf /var/lib/apt/lists/* - -RUN install -m 0755 -d /etc/apt/keyrings && \ - curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc && \ - chmod a+r /etc/apt/keyrings/docker.asc && \ - echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ - $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ - tee /etc/apt/sources.list.d/docker.list > /dev/null && \ - apt-get update && \ - apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin && \ - rm -rf /var/lib/apt/lists/* - - -COPY --chmod=0755 ./src/* /usr/local/bin/ - -RUN /usr/local/bin/dropshell-build-install-requirements - -WORKDIR /app - -CMD ["dropshell-build","/app"] +# Configure and build +RUN mkdir -p build_static && \ + cmake -G Ninja -B build_static -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_EXE_LINKER_FLAGS="-static" \ + -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \ + -DBUILD_SHARED_LIBS=OFF \ + ${CMAKE_TOOLCHAIN_FILE:+-DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE} +RUN cmake --build build_static +# Final stage that only contains the binary +FROM scratch AS $PROJECT +COPY --from=builder /build/build_static/$PROJECT /$PROJECT diff --git a/ipdemo/CMakeLists.txt b/ipdemo/CMakeLists.txt index a7ac8a9..09a6a91 100644 --- a/ipdemo/CMakeLists.txt +++ b/ipdemo/CMakeLists.txt @@ -64,52 +64,10 @@ target_include_directories(${PROJECT_EXE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Configure libassert -include(FetchContent) -FetchContent_Declare( - libassert - GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert.git - GIT_TAG v2.1.5 -) -FetchContent_MakeAvailable(libassert) - -# Add cpptrace -FetchContent_Declare( - cpptrace - GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git - GIT_TAG v0.8.3 -) - -# Explicitly configure cpptrace to use libunwind -set(CPPTRACE_UNWIND_WITH_LIBUNWIND ON CACHE BOOL "Use libunwind for unwinding" FORCE) -set(CPPTRACE_UNWIND_WITH_UNWIND OFF CACHE BOOL "Disable libgcc unwind" FORCE) -set(CPPTRACE_UNWIND_WITH_EXECINFO OFF CACHE BOOL "Disable execinfo" FORCE) -set(CPPTRACE_UNWIND_WITH_WINAPI OFF CACHE BOOL "Disable winapi" FORCE) -set(CPPTRACE_UNWIND_WITH_DBGHELP OFF CACHE BOOL "Disable dbghelp" FORCE) -set(CPPTRACE_UNWIND_WITH_NOTHING OFF CACHE BOOL "Disable nothing backend" FORCE) - -# Disable cpptrace auto-configuration -set(CPPTRACE_NO_AUTO_CONFIG ON CACHE BOOL "Disable cpptrace auto-configuration" FORCE) - -# Explicitly set libunwind paths -set(LibUnwind_INCLUDE_DIR "${CMAKE_SYSROOT}/usr/include" CACHE PATH "libunwind include directory" FORCE) -set(LibUnwind_LIBRARY "${CMAKE_SYSROOT}/usr/lib/libunwind.a" CACHE FILEPATH "libunwind library" FORCE) -set(LibUnwind_FOUND TRUE CACHE BOOL "libunwind found" FORCE) - -FetchContent_MakeAvailable(cpptrace) -# Add nlohmann/json -FetchContent_Declare( - nlohmann_json - GIT_REPOSITORY https://github.com/nlohmann/json.git - GIT_TAG v3.11.3 -) -FetchContent_MakeAvailable(nlohmann_json) - # Link libraries target_link_libraries(${PROJECT_EXE_NAME} PRIVATE libassert::assert cpptrace::cpptrace - "${CMAKE_SYSROOT}/usr/lib/libunwind.a" nlohmann_json::nlohmann_json ) diff --git a/publish_scripts_only.sh b/publish_scripts_only.sh deleted file mode 100755 index 4f36444..0000000 --- a/publish_scripts_only.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" - -# download the sos binary -SOS="${SCRIPT_DIR}/temp/sos" -mkdir -p "${SCRIPT_DIR}/temp" - -curl -L -o "${SOS}" https://getbin.xyz/sos -chmod +x "${SOS}" - -# upload the dropshell-build script -"${SOS}" upload "getbin.xyz" "${SCRIPT_DIR}/src/dropshell-build" "dropshell-build:latest" - -# upload the install requirements script -"${SOS}" upload "getbin.xyz" "${SCRIPT_DIR}/src/dropshell-build-install-requirements" "dropshell-build-install-requirements:latest" - -# clean up -rm -rf "${SCRIPT_DIR}/temp" -echo "Done" \ No newline at end of file diff --git a/src/dropshell-build b/src/dropshell-build deleted file mode 100755 index 148b023..0000000 --- a/src/dropshell-build +++ /dev/null @@ -1,367 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" - -HOSTARCH=$(uname -m) - -# set flags from command line -RELEASE=0 -MULTIBUILD=0 - -MUSL_ROOT_PATH="${HOME}/.musl-cross" - -function help() { - echo "Usage: $0 [options]" - echo "Options:" - echo " version Show version information and exit" - echo " " - echo " Build the project using cmake in " - echo " -r, --release Build release version" - echo " -m, --multi Build for multiple architectures" -} - -function version() { - echo "2025.0531.0942" -} - -function die() { - echo "Error: $*" - exit 1 -} - -function centerlittletitle() { - local TITLE="$1" - local WIDTH - # Try tput cols, then stty size, else default to 80 - if command -v tput &> /dev/null; then - WIDTH=$(tput cols 2>/dev/null) - elif command -v stty &> /dev/null && [ -t 1 ]; then - WIDTH=$(stty size 2>/dev/null | awk '{print $2}') - fi - # Fallback to 80 if WIDTH is empty or not a number - if ! [[ "$WIDTH" =~ ^[0-9]+$ ]]; then - WIDTH=80 - fi - local SPACES=$(( (WIDTH - ${#TITLE}) / 2 )) - printf '%*s\n' "$WIDTH" '' | tr ' ' '-' - printf "%*s%s\n" "$SPACES" "" "$TITLE" - printf '%*s\n' "$WIDTH" '' | tr ' ' '-' -} - -function set_current_arch() { - export FULLARCH="$1" - # e.g. aarch64-linux-musl-cross - # ARCH=aarch64 - # ARCH_OS=linux-musl-cross - # FULLARCH=aarch64-linux-musl-cross - # ARCH_SHORT_PREFIX=aarch64-linux-musl - # MUSL_PATH=/home/jde/.musl-cr oss/aarch64-linux-musl-cross - # arch should just be x86_64 or aarch64 - [ -n "$FULLARCH" ] || _die "No toolchain provided" - - export ARCH="${FULLARCH%%-*}" - export ARCH_OS="${FULLARCH#*-}" - export ARCH_SHORT_PREFIX="${FULLARCH%-*}" - export ARCH_MUSL_PATH="${MUSL_ROOT_PATH}/${FULLARCH}" - export ARCH_SYSROOT="${ARCH_MUSL_PATH}/${ARCH_SHORT_PREFIX}/sysroot" - - export LIBPATH="$ARCH_SYSROOT/usr/lib" - [ -d "$LIBPATH" ] || export LIBPATH="$ARCH_SYSROOT/usr/lib64" - - JOBS=$(nproc) # Set JOBS to the number of available CPU cores - - - echo "ARCH: ${ARCH}" - echo "ARCH_OS: ${ARCH_OS}" - echo "ARCH_SHORT_PREFIX: ${ARCH_SHORT_PREFIX}" - echo "ARCH_MUSL_PATH: ${ARCH_MUSL_PATH}" - echo "ARCH_SYSROOT: ${ARCH_SYSROOT}" - echo "LIBPATH: ${LIBPATH}" - - # Set cross-compiler and sysroot - export CC="$ARCH_MUSL_PATH/bin/${ARCH_SHORT_PREFIX}-gcc" - [ -f "$CC" ] || export CC="$ARCH_MUSL_PATH/bin/gcc" - export CXX="${ARCH_MUSL_PATH}/bin/${ARCH_SHORT_PREFIX}-g++" - [ -f "$CXX" ] || export CXX="$ARCH_MUSL_PATH/bin/g++" - export AR="$ARCH_MUSL_PATH/bin/${ARCH_SHORT_PREFIX}-ar" - [ -f "$AR" ] || export AR="$ARCH_MUSL_PATH/bin/ar" - export RANLIB="$ARCH_MUSL_PATH/bin/${ARCH_SHORT_PREFIX}-ranlib" - [ -f "$RANLIB" ] || export RANLIB="$ARCH_MUSL_PATH/bin/ranlib" - - echo "CC: ${CC}" - echo "CXX: ${CXX}" - echo "AR: ${AR}" - echo "RANLIB: ${RANLIB}" - - export CFLAGS="--sysroot=$ARCH_SYSROOT -I$ARCH_SYSROOT/usr/include" - export CXXFLAGS="--sysroot=$ARCH_SYSROOT -I$ARCH_SYSROOT/usr/include" - - export CMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" - export CMAKE_MODULE_LINKER_FLAGS="-fuse-ld=mold" - export CMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" - - export LDFLAGS="--sysroot=$ARCH_SYSROOT" - export MAKEFLAGS="-j${JOBS}" -} - - -OLD_PWD="$PWD" -trap 'cd "${OLD_PWD}"' EXIT - -# ---------------------------------------------------------------------------------------------------------- -# BUILD -# ---------------------------------------------------------------------------------------------------------- - -# function create_openssl_cmake_vars() { -# mkdir -p "$1/cmake/OpenSSL" -# cat < "$1/cmake/OpenSSL/OpenSSLConfig.cmake" -# add_library(OpenSSL::SSL STATIC IMPORTED) -# set_target_properties(OpenSSL::SSL PROPERTIES -# IMPORTED_LOCATION "${OPENSSL_LIBDIR}/libssl.a" -# INTERFACE_INCLUDE_DIRECTORIES "${ARCH_SYSROOT}/usr/include" -# ) -# add_library(OpenSSL::Crypto STATIC IMPORTED) -# set_target_properties(OpenSSL::Crypto PROPERTIES -# IMPORTED_LOCATION "${OPENSSL_LIBDIR}/libcrypto.a" -# INTERFACE_INCLUDE_DIRECTORIES "${ARCH_SYSROOT}/usr/include" -# ) -# EOF -# } - -function build_arch() { - local CMAKE_DIR="$1" - - local ARCH_BUILD_DIR="${CMAKE_DIR}/build/build.$ARCH" - local OUTPUT_DIR="${CMAKE_DIR}/output" - - cd "${CMAKE_DIR}" || exit 1 - - mkdir -p "${ARCH_BUILD_DIR}" - - echo "Building for ${ARCH} in ${ARCH_BUILD_DIR}" - - if [ ! -f "${ARCH_MUSL_PATH}/bin/${ARCH_SHORT_PREFIX}-g++" ]; then - echo "Musl cross toolchain not found for ${ARCH}" - echo "Missing file: ${ARCH_MUSL_PATH}/bin/${ARCH_SHORT_PREFIX}-g++" - exit 1 - fi - - CMAKE_BUILD_TYPE="Release" - if [ "$RELEASE" -eq 0 ]; then - CMAKE_BUILD_TYPE="Debug" - fi - - export SYSROOT="${ARCH_SYSROOT}" - export OPENSSL_ROOT_DIR="${SYSROOT}/usr" - export CCACHE_DIR="${ARCH_BUILD_DIR}/ccache" - - - # if [ -d "${ARCH_SYSROOT}/usr/lib64" ]; then - # export OPENSSL_LIBDIR="${ARCH_SYSROOT}/usr/lib64" - # elif [ -d "${ARCH_SYSROOT}/usr/lib" ]; then - # export OPENSSL_LIBDIR="${ARCH_SYSROOT}/usr/lib" - # else - # echo "Neither lib nor lib64 found in ${ARCH_SYSROOT}/usr" - # exit 1 - # fi - #create_openssl_cmake_vars "$OPENSSL_LIBDIR" - ls -la "${ARCH_SYSROOT}/usr/include/libunwind.h" - ls -la "${ARCH_SYSROOT}/usr/lib/libunwind.a" - - cmake -B "${ARCH_BUILD_DIR}" -G Ninja \ - -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_LINKER=mold \ - -DCMAKE_C_COMPILER_TARGET="${ARCH_SHORT_PREFIX}" \ - -DCMAKE_CXX_COMPILER_TARGET="${ARCH_SHORT_PREFIX}" \ - -DCMAKE_C_FLAGS="${CFLAGS}" \ - -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \ - -DCMAKE_FIND_ROOT_PATH="${ARCH_SYSROOT}" \ - -DCMAKE_SYSROOT="${ARCH_SYSROOT}" \ - -DCMAKE_PREFIX_PATH="${ARCH_SYSROOT}/usr" \ - -DCMAKE_LIBRARY_PATH="${ARCH_SYSROOT}/usr/lib" \ - -DCMAKE_LIBRARY_PATH="${ARCH_SYSROOT}/usr/lib64" \ - -DCMAKE_INCLUDE_PATH="${ARCH_SYSROOT}/usr/include" \ - -DCPPTRACE_STATIC_DEFINE="true" - - cd "${ARCH_BUILD_DIR}" || exit 1 - ninja -k0 -j"${JOBS}" - - # the rest is optional. - - # loop through the build directory and find executables - for executable in "${ARCH_BUILD_DIR}"/*; do - if [ -f "$executable" ] && [ -x "$executable" ]; then - local TARGET_NAME="${executable##*/}" - local TARGET_PATH="${OUTPUT_DIR}/${TARGET_NAME}.${ARCH}" - mkdir -p "${OUTPUT_DIR}" - cp "${executable}" "${TARGET_PATH}" - if command -v upx &> /dev/null ; then - echo "Compressing $TARGET_PATH with upx" - upx "${TARGET_PATH}" - fi - centerlittletitle "Built $TARGET_PATH" - fi - done -} - -function build() { - echo "Building project in directory $1" - if [ ! -d "$1" ]; then - echo "Directory $1 does not exist" - exit 1 - fi - - local CMAKE_DIR="$1" - - # if have the -m option, then build for multiple architectures - if [ $MULTIBUILD -eq 1 ]; then - echo "Building for multiple architectures" - # get all the architectures from the musl-cross-make directory - local musl_toolchains - mapfile -t musl_toolchains < <(ls -d "${MUSL_ROOT_PATH}/"*) - - for tchain in "${musl_toolchains[@]}"; do - local arch="${tchain##*/}" - local buildthis="false" - if [[ "$arch" = "$HOSTARCH"* && "$arch" == *-native ]]; then - # Native toolchain for host arch - buildthis="true" - elif [[ "$arch" != "$HOSTARCH"* && "$arch" != *-native ]]; then - # Cross toolchain for non-host arch - buildthis="true" - fi - if [ "$buildthis" = "true" ]; then - echo "Building for toolchain $arch from $tchain" - set_current_arch "$arch" - build_arch "$CMAKE_DIR" - else - echo "Skipping $tchain" - fi - done - else - echo "Building for host architecture $HOSTARCH" - set_current_arch "$HOSTARCH-linux-musl-native" - build_arch "$CMAKE_DIR" - fi -} - -function buildspawn() { - local CMAKE_DIR="${1:-}" - [ -n "${CMAKE_DIR:-}" ] || die "No CMake Directory given!" - [ -d "$CMAKE_DIR" ] || die "CMake Directory doesn't exist: $CMAKE_DIR" - - # make canonical - CMAKE_DIR=$(realpath "$CMAKE_DIR") - - FLAGS="" - [ $MULTIBUILD -eq 0 ] || FLAGS="$FLAGS -m" - [ $RELEASE -eq 0 ] || FLAGS="$FLAGS -r" - - BUILD_VERSION_FILE="$HOME/.config/dropshell-build/version" - if [ ! -f "$BUILD_VERSION_FILE" ]; then - # check if docker is installed - if ! command -v docker &> /dev/null; then - echo "Neither dropshell-build nor docker appears to be available. Please install one of them." - exit 1 - fi - echo "Using Docker Buildchain." - TAG="latest" - if [ -n "${DROPSHELL_BUILD_TAG-}" ]; then - TAG="$DROPSHELL_BUILD_TAG" - fi - echo "Using Docker Buildchain with tag: $TAG" - - - # Check if we're running in Gitea Actions - if [ -n "${JOB_CONTAINER_NAME:-}" ] && [ -n "${GITHUB_WORKSPACE:-}" ]; then - echo "--------------------------------" - echo "Running in Gitea Actions - using --volumes-from" - echo "--------------------------------" - - echo "GITHUB_WORKSPACE: ${GITHUB_WORKSPACE}" - echo "CMAKE_DIR: ${CMAKE_DIR}" - echo "PWD: ${PWD}" - echo "JOB_CONTAINER_NAME: ${JOB_CONTAINER_NAME}" - - docker run --rm \ - --volumes-from="${JOB_CONTAINER_NAME}" \ - "gitea.jde.nz/public/dropshell-build:${TAG}" \ - bash -c "cd / && rm -rf /app && \ - ln -s ${CMAKE_DIR} /app && \ - cd /app && \ - dropshell-build $FLAGS /app" - else - echo "Running locally" - docker run --rm \ - -u "$(id -u)":"$(id -g)" \ - -v "$CMAKE_DIR":/app \ - "gitea.jde.nz/public/dropshell-build:${TAG}" \ - bash -c "dropshell-build $FLAGS /app" - fi - else - echo "Using local native buildchain" - # shellcheck disable=SC2086 - build "$CMAKE_DIR" - fi -} - - -# ---------------------------------------------------------------------------------------------------------- -# MAIN -# ---------------------------------------------------------------------------------------------------------- - -function main() { - # Process arguments manually to support long options - while [[ $# -gt 0 ]]; do - case $1 in - -r|--release) - RELEASE=1 - shift - ;; - -m|--multi) - MULTIBUILD=1 - shift - ;; - -*) - echo "Unknown option: $1" - help - exit 1 - ;; - *) - # This is not an option, so break from the loop - break - ;; - esac - done - - # check we have at least one argument remaining - if [ $# -eq 0 ]; then - help - exit 1 - fi - - - # get command argument, now that the flags are set - CMD="$1" - - if [ -z "$CMD" ]; then - help - exit 1 - fi - - - case "$CMD" in - version) - version - ;; - *) - buildspawn "$1" - ;; - esac -} - -main "$@" \ No newline at end of file diff --git a/src/dropshell-build-install-requirements b/src/dropshell-build-install-requirements deleted file mode 100755 index 6906c7a..0000000 --- a/src/dropshell-build-install-requirements +++ /dev/null @@ -1,448 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" - -# list of toolchains to install -TOOLCHAIN_LIST=( - "aarch64-linux-musl-cross" - "x86_64-linux-musl-cross" - "x86_64-linux-musl-native" -) - - -# 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 check_packages() { - local PACKAGES - - # 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") - # Common packages for both Ubuntu and Debian - PACKAGES="build-essential cmake git wget tar curl ninja-build \ - mold nodejs npm perl jq ccache upx-ucl nlohmann-json3-dev \ - sed gawk autoconf automake libtool autotools-dev" - ;; - *) - 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_error "Package $pkg is not installed" - exit 1 - else - print_status "$pkg is already installed" - fi - done - -} - -# function install_libassert() { -# # 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 -# } - -#---------------------------------------------------------------------------------------------------------- -# set_current_arch -#---------------------------------------------------------------------------------------------------------- - -function set_current_arch() { - export FULLARCH="$1" - # e.g. aarch64-linux-musl-cross - # ARCH=aarch64 - # ARCH_OS=linux-musl-cross - # FULLARCH=aarch64-linux-musl-cross - # ARCH_SHORT_PREFIX=aarch64-linux-musl - # MUSL_PATH=/home/jde/.musl-cr oss/aarch64-linux-musl-cross - # arch should just be x86_64 or aarch64 - [ -n "$FULLARCH" ] || _die "No toolchain provided" - - export MUSL_ROOT_PATH="${USER_HOME}/.musl-cross" - export ARCH="${FULLARCH%%-*}" - export ARCH_OS="${FULLARCH#*-}" - export ARCH_SHORT_PREFIX="${FULLARCH%-*}" - export ARCH_MUSL_PATH="${MUSL_ROOT_PATH}/${FULLARCH}" - export ARCH_SYSROOT="${ARCH_MUSL_PATH}/${ARCH_SHORT_PREFIX}/sysroot" - - export LIBPATH="$ARCH_SYSROOT/usr/lib" - [ -d "$LIBPATH" ] || export LIBPATH="$ARCH_SYSROOT/usr/lib64" - - echo "ARCH: ${ARCH}" - echo "ARCH_OS: ${ARCH_OS}" - echo "ARCH_SHORT_PREFIX: ${ARCH_SHORT_PREFIX}" - echo "ARCH_MUSL_PATH: ${ARCH_MUSL_PATH}" - echo "ARCH_SYSROOT: ${ARCH_SYSROOT}" - echo "LIBPATH: ${LIBPATH}" - - JOBS=$(nproc) # Set JOBS to the number of available CPU cores - - # Set cross-compiler and sysroot - export CC="$ARCH_MUSL_PATH/bin/${ARCH_SHORT_PREFIX}-gcc" - [ -f "$CC" ] || export CC="$ARCH_MUSL_PATH/bin/gcc" - export CXX="${ARCH_MUSL_PATH}/bin/${ARCH_SHORT_PREFIX}-g++" - [ -f "$CXX" ] || export CXX="$ARCH_MUSL_PATH/bin/g++" - export AR="$ARCH_MUSL_PATH/bin/${ARCH_SHORT_PREFIX}-ar" - [ -f "$AR" ] || export AR="$ARCH_MUSL_PATH/bin/ar" - export RANLIB="$ARCH_MUSL_PATH/bin/${ARCH_SHORT_PREFIX}-ranlib" - [ -f "$RANLIB" ] || export RANLIB="$ARCH_MUSL_PATH/bin/ranlib" - - echo "CC: ${CC}" - echo "CXX: ${CXX}" - echo "AR: ${AR}" - echo "RANLIB: ${RANLIB}" - - export CFLAGS="--sysroot=$ARCH_SYSROOT -I$ARCH_SYSROOT/usr/include" - export CXXFLAGS="--sysroot=$ARCH_SYSROOT -I$ARCH_SYSROOT/usr/include" - - export CMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" - export CMAKE_MODULE_LINKER_FLAGS="-fuse-ld=mold" - export CMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" - - export LDFLAGS="--sysroot=$ARCH_SYSROOT" - export MAKEFLAGS="-j${JOBS}" -} - -#---------------------------------------------------------------------------------------------------------- -# unwind for musl cross toolchains -#---------------------------------------------------------------------------------------------------------- - -function install_unwind_musl() { - set_current_arch "$1" - - [ -d "$ARCH_MUSL_PATH" ] || _die "MUSL_PATH does not exist: $ARCH_MUSL_PATH" - - local BUILD_DIR="${SCRIPT_DIR}/build.$ARCH" - PREVDIR="$PWD" - rm -rf "$BUILD_DIR" && mkdir -p "$BUILD_DIR" && cd "$BUILD_DIR" - - [ ! -f "$LIBPATH/libunwind.a" ] || echo "Unwind $ARCH is already installed" && return - - git clone https://github.com/libunwind/libunwind.git - cd libunwind - autoreconf -i - - # Configure for cross-compiling - CC="$CC" AR="$AR" RANLIB="$RANLIB" ./configure \ - --host="$ARCH_SHORT_PREFIX" \ - --prefix="$ARCH_SYSROOT/usr" \ - --enable-static \ - --disable-shared \ - --disable-minidebuginfo \ - --disable-zlibdebuginfo - - make -j"$JOBS" - ${SUDOCMD:-} make install - - cd "$PREVDIR" - rm -rf "$BUILD_DIR" -} - -#---------------------------------------------------------------------------------------------------------- -# libassert for musl cross toolchains -#---------------------------------------------------------------------------------------------------------- - - -function install_libassert_musl() { - local TOOLCHAIN="$1" - set_current_arch "$TOOLCHAIN" - - echo "Installing libassert for ${ARCH}" - - local BUILD_DIR="/tmp/libassert-build-${ARCH}" - rm -rf "${BUILD_DIR}" - mkdir -p "${BUILD_DIR}" - pushd "${BUILD_DIR}" - - git clone --depth 1 --branch v2.1.5 https://github.com/jeremy-rifkin/libassert.git . - mkdir build && cd build - - cmake .. \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_SYSROOT="${ARCH_SYSROOT}" \ - -DCMAKE_C_COMPILER="${CC}" \ - -DCMAKE_CXX_COMPILER="${CXX}" \ - -DCMAKE_INSTALL_PREFIX="${ARCH_SYSROOT}/usr" \ - -DBUILD_SHARED_LIBS=OFF - - make - make install - - popd - rm -rf "${BUILD_DIR}" -} - -#---------------------------------------------------------------------------------------------------------- -# cpptrace for musl cross toolchains -#---------------------------------------------------------------------------------------------------------- - -function install_cpptrace_musl() { - local TOOLCHAIN="$1" - set_current_arch "$TOOLCHAIN" - - echo "Installing cpptrace for ${ARCH}" - - local BUILD_DIR="/tmp/cpptrace-build-${ARCH}" - rm -rf "${BUILD_DIR}" - mkdir -p "${BUILD_DIR}" - pushd "${BUILD_DIR}" - - git clone --depth 1 --branch v0.8.3 https://github.com/jeremy-rifkin/cpptrace.git . - mkdir build && cd build - - cmake .. \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_SYSROOT="${ARCH_SYSROOT}" \ - -DCMAKE_C_COMPILER="${CC}" \ - -DCMAKE_CXX_COMPILER="${CXX}" \ - -DCMAKE_INSTALL_PREFIX="${ARCH_SYSROOT}/usr" \ - -DCPPTRACE_UNWIND_WITH_LIBUNWIND=ON \ - -DCPPTRACE_UNWIND_WITH_UNWIND=OFF \ - -DCPPTRACE_UNWIND_WITH_EXECINFO=OFF \ - -DCPPTRACE_UNWIND_WITH_WINAPI=OFF \ - -DCPPTRACE_UNWIND_WITH_DBGHELP=OFF \ - -DCPPTRACE_UNWIND_WITH_NOTHING=OFF \ - -DCPPTRACE_NO_AUTO_CONFIG=ON \ - -DLibUnwind_INCLUDE_DIR="${ARCH_SYSROOT}/usr/include" \ - -DLibUnwind_LIBRARY="${ARCH_SYSROOT}/usr/lib/libunwind.a" \ - -DLibUnwind_FOUND=TRUE \ - -DBUILD_SHARED_LIBS=OFF \ - -DCPPTRACE_STATIC_DEFINE=ON - - make -j$(nproc) - make install - - popd - rm -rf "${BUILD_DIR}" -} - -#---------------------------------------------------------------------------------------------------------- -# OpenSSL for musl cross toolchains -#---------------------------------------------------------------------------------------------------------- - -toolchain_to_openssl_target() { - case "$1" in - aarch64-linux-musl-*) echo "linux-aarch64" ;; - x86_64-linux-musl-*) echo "linux-x86_64" ;; - *) _die "unsupported toolchain: $1" ;; - esac -} - -function install_openssl_musl() { - OPENSSL_VERSION=3.5.0 - set_current_arch "${1:-}" - - PREVDIR="$PWD" - - [ -d "$ARCH_MUSL_PATH" ] || _die "MUSL_PATH does not exist: $ARCH_MUSL_PATH" - - [ ! -f "$LIBPATH/libssl.a" ] || echo "OpenSSL $ARCH is already installed" && return - - local BUILD_DIR="${SCRIPT_DIR}/build.$ARCH" - rm -rf "$BUILD_DIR" && mkdir -p "$BUILD_DIR" && cd "$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" ] - } - - echo "===============================" - echo "Checking OpenSSL for $ARCH..." - echo "===============================" - OPENSSL_TARGET=$(toolchain_to_openssl_target "$FULLARCH") - - wget "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" || _die "Failed to download openssl-${OPENSSL_VERSION}.tar.gz" - tar xf "openssl-${OPENSSL_VERSION}.tar.gz" || _die "Failed to extract openssl-${OPENSSL_VERSION}.tar.gz" - cd "openssl-${OPENSSL_VERSION}" || _die "Failed to cd to 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"$JOBS" - echo "Installing to $SYSROOT/usr ..." - ${SUDOCMD:-} make install_sw - - echo "Done for $ARCH." - echo - - cd "$PREVDIR" - rm -rf "$BUILD_DIR" - echo "OpenSSL built and installed for $FULLARCH" -} - - - -# ---------------------------------------------------------------------------------------------------------- -# 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 - - for TOOLCHAIN in "${TOOLCHAIN_LIST[@]}"; do - install_musl_cross "$TOOLCHAIN" - check_path "$TOOLCHAIN" - - install_openssl_musl "$TOOLCHAIN" - install_unwind_musl "$TOOLCHAIN" - install_libassert_musl "$TOOLCHAIN" - install_cpptrace_musl "$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() { - - check_packages - - install_musl - - output_version - - echo "Done" -} - -main "$@"