#!/usr/bin/env bash set -euo pipefail # Build BusyBox with ARM toolchain from env.sh and optional sysroot. # # Usage: # ./build.sh [SYSROOT] # # Examples: # ./build.sh # ./build.sh /home/stargazer/arm-uclinuxfdpiceabi/sysroot TOOLCHAIN_PREFIX="${TOOLCHAIN_PREFIX:-arm-uclinuxfdpiceabi}" CC_BIN="${CC_BIN:-${TOOLCHAIN_PREFIX}-gcc}" STRIP_BIN="${STRIP_BIN:-${TOOLCHAIN_PREFIX}-strip}" JOBS="${JOBS:-$(nproc)}" INSTALL_DIR_NAME="${INSTALL_DIR_NAME:-_install}" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BUSYBOX_DIR="${SCRIPT_DIR}/busybox" SYSROOT_DEFAULT="/home/stargazer/arm-uclinuxfdpiceabi/sysroot" SYSROOT="${1:-${SYSROOT:-$SYSROOT_DEFAULT}}" ENV_FILE="${ENV_FILE:-${SCRIPT_DIR}/env.sh}" CONFIG_TEMPLATE="${SCRIPT_DIR}/config/.config" die() { echo "ERROR: $*" >&2 exit 1 } if [ -f "${ENV_FILE}" ]; then # shellcheck disable=SC1090 . "${ENV_FILE}" fi if ! command -v "${CC_BIN}" >/dev/null 2>&1; then die "Compiler not found in PATH: ${CC_BIN}" fi if ! command -v "${STRIP_BIN}" >/dev/null 2>&1; then die "Strip tool not found in PATH: ${STRIP_BIN}" fi if [ ! -d "${BUSYBOX_DIR}" ]; then die "busybox directory not found: ${BUSYBOX_DIR}" fi if [ ! -d "${SYSROOT}" ]; then die "SYSROOT not found: ${SYSROOT}" fi INSTALL_DIR="${SCRIPT_DIR}/${INSTALL_DIR_NAME}" if [ "${INSTALL_DIR}" = "/" ]; then die "Refusing to install into /" fi echo "Compiler: ${CC_BIN}" echo "Strip: ${STRIP_BIN}" echo "SYSROOT: ${SYSROOT}" echo "Source dir: ${BUSYBOX_DIR}" echo "Install dir: ${INSTALL_DIR}" echo "Config template: ${CONFIG_TEMPLATE}" if [ ! -f "${CONFIG_TEMPLATE}" ]; then die "Config template not found: ${CONFIG_TEMPLATE}" fi cd "${BUSYBOX_DIR}" cp "${CONFIG_TEMPLATE}" .config # Force BusyBox shared library build profile. if [ -x "./scripts/config" ]; then ./scripts/config \ -e BUILD_LIBBUSYBOX \ -e FEATURE_SHARED_BUSYBOX \ -d FEATURE_INDIVIDUAL \ -d STATIC \ -d PIE \ -d FEATURE_LIBBUSYBOX_STATIC else echo "WARNING: scripts/config not found; shared library profile not enforced." >&2 fi make oldconfig make -j"${JOBS}" \ CROSS_COMPILE="${TOOLCHAIN_PREFIX}-" \ CC="${CC_BIN}" \ STRIP="${STRIP_BIN}" \ EXTRA_CFLAGS="--sysroot=${SYSROOT}" \ EXTRA_LDFLAGS="--sysroot=${SYSROOT}" make CONFIG_PREFIX="${INSTALL_DIR}" install # If FEATURE_SHARED_BUSYBOX/BUILD_LIBBUSYBOX are enabled, BusyBox also # produces a tiny launcher in 0_lib/ that links against libbusybox. # Install that pair instead of the monolithic ./busybox to actually save space. if [ -f "0_lib/busybox" ]; then install -D -m 0755 "0_lib/busybox" "${INSTALL_DIR}/bin/busybox" fi # Install the exact SONAME that the launcher needs (e.g. libbusybox.so.1.31.1) shopt -s nullglob libbusybox_candidates=(0_lib/libbusybox.so.*) shopt -u nullglob for f in "${libbusybox_candidates[@]}"; do case "${f}" in *_unstripped*|*.map|*.out) continue ;; esac install -D -m 0755 "${f}" "${INSTALL_DIR}/lib/$(basename "${f}")" # Optional convenience symlink (not required at runtime). ln -sf "$(basename "${f}")" "${INSTALL_DIR}/lib/libbusybox.so" 2>/dev/null || true done echo "Build completed successfully." echo "Binary: ${BUSYBOX_DIR}/busybox" echo "Shared library: ${BUSYBOX_DIR}/libbusybox.so" echo "Installed to: ${INSTALL_DIR}"