#!/bin/bash # BTC.sh requires GNU Bash 4.0+ (not POSIX sh). It uses: # - [[ ... ]] conditionals, == pattern matching, =~ regex, (( )) arithmetic # - ${var^^} uppercase expansion, associative arrays, process substitution # - set -euo pipefail for strict error handling # BTC-0.4.0.sh - Build Tool Chain # Identity: dcosnet / dcos.net | Multi-Arch Cross-Compilation Forge # Version: 0.4.0 | Persistence: /opt/BTC | Volatile: ramfs # License: GNU AGPLv3 Mandatory Prominent Interactive Notice # Copyright (C) 2012-2026 Jeremy Anderson (info@dcos.net) set -euo pipefail export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES # ============================================================================ # 1. AGPL INTERACTIVE LICENSE COMPLIANCE # ============================================================================ function f_agpl_header() { clear cat << 'EOF' =========================================================================== BTC-0.4.0.sh - Build Tool Chain (AGPLv3 PROTECTED) Cross-Compilation Sovereign Forge =========================================================================== This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License. REMOTE INTERACTION NOTICE: Per Section 13 of the GNU AGPLv3, if you modify this script and offer its toolchain-building capabilities as a service over a network, you MUST make your complete modified source code available. =========================================================================== EOF if [[ ! -f /var/tmp/BTC-AGPL-ACCEPTED ]]; then echo -n "Do you accept the network-sovereignty terms of the AGPLv3? (y/N): " read -r reply if [[ "${reply}" =~ ^[Yy]$ ]]; then touch /var/tmp/BTC-AGPL-ACCEPTED else echo ">> Build aborted: AGPLv3 acceptance is mandatory for execution." exit 1 fi fi } # ============================================================================ # 2. CROSS-COMPILATION TARGET REGISTRY # # Architecture | Target ID | GCC march | ISA | C Library # ------------- | ------------------- | ------------------ | ------ | ---------- # x86_64 | haswell | haswell | AVX2 | glibc # x86_64 | haswell-ep | haswell | AVX2 | glibc # x86_64 | skylake | skylake | AVX2 | glibc # x86_64 | skylake-x | skylake-avx512 | AVX512 | glibc # x86_64 | skylake-server | skylake-server | AVX512 | glibc # x86_64 | znver1 | znver1 | AVX2 | glibc # x86_64 | znver2 | znver2 | AVX2 | glibc # x86_64 | znver3 | znver3 | AVX2 | glibc # x86_64 | znver4 | znver4 | AVX512 | glibc # x86_64 | apu-zn1 | znver1 | AVX2 | glibc # x86_64 | apu-zn2 | znver1 | AVX2 | glibc # x86_64 | apu-zn3 | znver2 | AVX2 | glibc # x86_64 | apu-zn4 | znver3 | AVX2 | glibc # x86_64 | atom-silvermont | silvermont | SSE4_2| glibc # x86_64 | atom-goldmont | goldmont | SSE4_2| glibc # x86_64 | atom-tremont | tremont | SSE4_2| glibc # x86_64 | atom-sierraforest | sierraforest | SSE4_2| glibc # mipsel | mipselr2 | mips32r2 | MIPS32 | musl # arm | armv7 | armv7-a | NEON | musl # tilegx | tilegx | tilegx | TILE | musl # # Host is always an average x86_64 system. All targets listed above # are CROSS-COMPILATION targets (CROSS_MODE=1). The --native flag # auto-probes the host silicon and builds without a target prefix. # # Cross targets use SYSROOT-based cross-compilation (CLFS / Buildroot style). # ============================================================================ # Associative array: target_id → property string # Format: "arch|cpu|march|isa|abi|clib|endian|family|desc|kernel_min|gcc_cfg_extra" declare -A BTC_TARGETS # --- x86_64 Intel family --- BTC_TARGETS[haswell]="x86_64|i686|haswell|AVX2|sysv|glibc|little|intel|Intel Haswell (Xeon E5 v3 / Core i7-4xxx)|4.19|" BTC_TARGETS[haswell-ep]="x86_64|i686|haswell|AVX2|sysv|glibc|little|intel|Intel Haswell-EP X99 (Xeon E5 v3 / E7 v3)|4.19|" BTC_TARGETS[skylake]="x86_64|i686|skylake|AVX2|sysv|glibc|little|intel|Intel Skylake (Core i7-6xxx / Xeon v5)|4.19|" BTC_TARGETS[skylake-x]="x86_64|i686|skylake-avx512|AVX512|sysv|glibc|little|intel|Intel Skylake-X X299 (Core i9-7xxx Xeon Scalable)|4.19|" BTC_TARGETS[skylake-server]="x86_64|i686|skylake-server|AVX512|sysv|glibc|little|intel|Intel Skylake-Server (Xeon SP 1st/2nd Gen Platinum)|4.19|" # --- x86_64 AMD family --- BTC_TARGETS[znver1]="x86_64|i686|znver1|AVX2|sysv|glibc|little|amd|AMD Zen1 Ryzen (Ryzen 1000 / EPYC Naples)|4.19|" BTC_TARGETS[znver2]="x86_64|i686|znver2|AVX2|sysv|glibc|little|amd|AMD Zen2 Ryzen (Ryzen 3000 / EPYC Rome)|4.19|" BTC_TARGETS[znver3]="x86_64|i686|znver3|AVX2|sysv|glibc|little|amd|AMD Zen3 Ryzen (Ryzen 5000 / EPYC Milan)|4.19|" BTC_TARGETS[znver4]="x86_64|i686|znver4|AVX512|sysv|glibc|little|amd|AMD Zen4 Ryzen (Ryzen 7000 / EPYC Genoa)|4.19|" # --- x86_64 AMD APU family (mobile/embedded Zen, 15-54W TDP) --- # APU series 1 (Raven Ridge, 2400GE/3200GE) = Zen 1, AVX2, Vega graphics # APU series 2 (Picasso, 3250U/3500U) = Zen+, AVX2 (GCC march=znver1) # APU series 3 (Renoir/Lucienne, 4500U/4700U)= Zen 2, AVX2 # APU series 4 (Cezanne/Barcelo, 5500U/5700U) = Zen 3, AVX2 # These are cross-compiled from an average x86_64 host for deployment # on APU-based mini-PCs, laptops, and embedded nodes. BTC_TARGETS[apu-zn1]="x86_64|i686|znver1|AVX2|sysv|glibc|little|amd-apu|AMD APU Series 1 Zen (Raven Ridge 2400GE / 3200GE Vega)|4.19|" BTC_TARGETS[apu-zn2]="x86_64|i686|znver1|AVX2|sysv|glibc|little|amd-apu|AMD APU Series 2 Zen+ (Picasso 3250U / 3500U)|4.19|" BTC_TARGETS[apu-zn3]="x86_64|i686|znver2|AVX2|sysv|glibc|little|amd-apu|AMD APU Series 3 Zen2 (Renoir 4500U / 4700U)|4.19|" BTC_TARGETS[apu-zn4]="x86_64|i686|znver3|AVX2|sysv|glibc|little|amd-apu|AMD APU Series 4 Zen3 (Cezanne 5500U / 5700U)|4.19|" # --- x86_64 Intel Atom family (low-power embedded, 4-15W TDP) --- # silvermont = Bay Trail (Z3000 series, E38xx) — in-order, SSE4.2 # goldmont = Apollo Lake (x5-Z8350, N4200) — out-of-order, SSE4.2 # tremont = Elkhart Lake (x6000E series) — improved OoO, SSE4.2 # sierraforest= Sierra Forest (x7000RE, E-core) — hybrid, SSE4.2, GCC 14+ # All Atom targets are cross-compiled for edge/IoT gateways, routers, # and low-power cluster nodes where AVX is not available. BTC_TARGETS[atom-silvermont]="x86_64|i686|silvermont|SSE4_2|sysv|glibc|little|atom|Intel Atom Silvermont (Bay Trail Z3000 / E38xx)|4.14|" BTC_TARGETS[atom-goldmont]="x86_64|i686|goldmont|SSE4_2|sysv|glibc|little|atom|Intel Atom Goldmont (Apollo Lake x5-Z8350 / N4200)|4.14|" BTC_TARGETS[atom-tremont]="x86_64|i686|tremont|SSE4_2|sysv|glibc|little|atom|Intel Atom Tremont (Elkhart Lake x6000E series)|5.4|" BTC_TARGETS[atom-sierraforest]="x86_64|i686|sierraforest|SSE4_2|sysv|glibc|little|atom|Intel Atom Sierra Forest (x7000RE E-core cluster)|6.1|" # --- MIPS (little-endian, soft-float baseline) --- # mips32r2 is the ISA baseline for mipselr2 — covers the MALTA-like # embedded targets that are the closest thing to a "universal mips" # reference platform. Uses musl because glibc MIPS support is # fragmented across kernel versions and vendor patches. BTC_TARGETS[mipselr2]="mipsel|mips|32r2|MIPS32|o32|musl|little|mips|MIPS32R2 Little-Endian (MALTA / embedded routers)|4.9|--with-arch=mips32r2 --with-float=soft --with-abi=32 --disable-libsanitizer" # --- ARMv7 (hard-float, Thumb-2, NEON) --- # armv7-a with NEON and VFPv3-D16 is the "x86 baseline" of the ARM # world — it covers Raspberry Pi 2/3 (32-bit), BeagleBone, Odroid, # and virtually every Cortex-A7/A9/A15/A17 SoC. Uses musl for # cross-compile portability; glibc armv7 is available as a future # clib variant. BTC_TARGETS[armv7]="arm|arm|armv7-a|NEON|eabihf|musl|little|arm|ARMv7-A Hard-Float NEON (Cortex-A7/A9/A15 RPi2/3 32b)|4.9|--with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --enable-target-optspace --disable-libsanitizer --with-abi=aapcs-linux" # --- TileGX (Tilera TILE-Gx72/Metor) --- # The Tile architecture is a 64-bit VLIW mesh network processor. # GCC upstream dropped mainline Tile-Gx support after GCC 11, so # we pin GCC 10.3.0 for Tile-Gx targets. The tilegx triple uses # linux-gnu-abi64. Uses musl as glibc has no Tile-Gx port. BTC_TARGETS[tilegx]="tilegx|tilegx|tilegx|TILE|abi64|musl|little|tile|Tilera TILE-Gx (TILE-Gx72 / TilePro mesh VLIW)|4.14|--with-arch=tilegx --disable-libssp --disable-libquadmath --disable-libatomic" # --- Helper: list all registered targets --- function f_list_targets() { echo ">> BTC-0.4.0 Registered Cross-Compilation Targets:" echo ">> ===============================================" printf ">> %-16s %-10s %-18s %-8s %-6s %s\n" "TARGET_ID" "ARCH" "MARCH" "ISA" "CLIB" "DESCRIPTION" printf ">> %-16s %-10s %-18s %-8s %-6s %s\n" "--------" "----" "-----" "---" "----" "-----------" for tid in $(echo "${!BTC_TARGETS[@]}" | tr ' ' '\n' | sort); do IFS='|' read -r arch cpu march isa abi clib endian family desc kern_min gcc_extra <<< "${BTC_TARGETS[${tid}]}" printf ">> %-16s %-10s %-18s %-8s %-6s %s\n" "${tid}" "${arch}" "${march}" "${isa}" "${clib}" "${desc}" done echo "" echo ">> Usage: BTC.sh Build cross-toolchain for target" echo ">> BTC.sh --native Auto-probe host silicon and build native" echo ">> BTC.sh --list Show this target table" echo ">> BTC.sh --list-json Emit target table as JSON" } function f_list_targets_json() { echo '[' local first=true for tid in $(echo "${!BTC_TARGETS[@]}" | tr ' ' '\n' | sort); do IFS='|' read -r arch cpu march isa abi clib endian family desc kern_min gcc_extra <<< "${BTC_TARGETS[${tid}]}" if [[ "${first}" == "true" ]]; then first=false; else echo ','; fi cat << TJSEP { "id": "${tid}", "arch": "${arch}", "cpu": "${cpu}", "march": "${march}", "isa": "${isa}", "abi": "${abi}", "clib": "${clib}", "endian": "${endian}", "family": "${family}", "description": "${desc}", "kernel_min": "${kern_min}", "gcc_extra": "${gcc_extra}" }TJSEP done echo ']' } # ============================================================================ # 3. TARGET PROBE & SELECTION # ============================================================================ # Resolved target properties (set by f_resolve_target) BTC_T_ARCH="" BTC_T_CPU="" BTC_T_MARCH="" BTC_T_ISA="" BTC_T_ABI="" BTC_T_CLIB="" BTC_T_ENDIAN="" BTC_T_FAMILY="" BTC_T_DESC="" BTC_T_KERN_MIN="" BTC_T_GCC_EXTRA="" BTC_T_ID="" CROSS_MODE=0 # 0 = native, 1 = cross function f_resolve_target() { local target_id="$1" local spec="${BTC_TARGETS[${target_id}]:-}" if [[ -z "${spec}" ]]; then echo ">> [ERROR] Unknown target: '${target_id}'" echo ">> Run 'BTC.sh --list' for available targets." exit 1 fi IFS='|' read -r BTC_T_ARCH BTC_T_CPU BTC_T_MARCH BTC_T_ISA BTC_T_ABI BTC_T_CLIB BTC_T_ENDIAN BTC_T_FAMILY BTC_T_DESC BTC_T_KERN_MIN BTC_T_GCC_EXTRA <<< "${spec}" BTC_T_ID="${target_id}" } function f_silicon_probe() { echo ">> Interrogating Core Topology and Instruction Extensions..." # If an explicit target was passed, use it directly (cross-compile mode) if [[ -n "${BTC_TARGET_ID:-}" ]]; then if [[ "${BTC_TARGET_ID}" == "--native" || -z "${BTC_TARGET_ID}" ]]; then # Native auto-probe path _probe_native else # Cross-compile path f_resolve_target "${BTC_TARGET_ID}" CROSS_MODE=1 _configure_from_target fi else # No argument: auto-probe native (backward compatible) _probe_native fi } function _probe_native() { local RAW_ARCH RAW_ARCH=$(gcc -march=native -Q --help=target 2>/dev/null | grep -m1 "march=" | awk '{print $2}') || true if [[ -z "${RAW_ARCH}" || "${RAW_ARCH}" == "x86-64" ]]; then RAW_ARCH="haswell" fi # Try to match the probed microarch to a registered target local matched="" local probe_lower="${RAW_ARCH,,}" for tid in "${!BTC_TARGETS[@]}"; do if [[ "${tid}" == "${probe_lower}" ]]; then matched="${tid}" break fi done if [[ -z "${matched}" ]]; then # Fallback: use generic "haswell" for unknown x86-64 probed values echo ">> [WARN] Probed microarch '${RAW_ARCH}' not in target registry. Defaulting to 'haswell'." matched="haswell" fi f_resolve_target "${matched}" CROSS_MODE=0 _configure_from_target } function _configure_from_target() { # Derive the target triple case "${BTC_T_ARCH}" in x86_64) TARGET="x86_64-dcosnet-linux-gnu" HOST_ARCH="x86_64-pc-linux-gnu" ;; mipsel) TARGET="mipsel-dcosnet-linux-musl" HOST_ARCH="x86_64-pc-linux-gnu" ;; arm) TARGET="arm-dcosnet-linux-musleabihf" HOST_ARCH="x86_64-pc-linux-gnu" ;; tilegx) TARGET="tilegx-dcosnet-linux-gnu" HOST_ARCH="x86_64-pc-linux-gnu" ;; *) TARGET="${BTC_T_ARCH}-dcosnet-linux-gnu" HOST_ARCH="x86_64-pc-linux-gnu" ;; esac # ISA tag for SYS_LABEL ISA_TAG="${BTC_T_ISA}" OPT_TAG="LTO" SYS_LABEL="DCOSNET-${BTC_T_ID^^}-${ISA_TAG}-${OPT_TAG}" # Override SYS_LABEL for cross-compiles to include the arch family if [[ "${CROSS_MODE}" -eq 1 ]]; then SYS_LABEL="DCOSNET-${BTC_T_FAMILY^^}-${BTC_T_ID^^}-${ISA_TAG}-CROSS" fi # Resource-Safe Threading: Allocate 2GB RAM per core floor to prevent LTO thrashing local total_cpus total_cpus=$(nproc) local free_gb free_gb=$(free -g | awk '/^Mem:/{print $7}') local safe_threads=$(( free_gb / 2 )) if [[ ${safe_threads} -lt 1 ]]; then safe_threads=1; fi if [[ ${safe_threads} -gt ${total_cpus} ]]; then safe_threads=${total_cpus}; fi export v_threads="-j${safe_threads}" # Pin GCC version for Tile-Gx (upstream dropped after GCC 11) if [[ "${BTC_T_FAMILY}" == "tile" ]]; then v_gcc='gcc-10.3.0' fi echo ">> [IDENTITY STAMP] ${SYS_LABEL}" echo ">> [TARGET] ${BTC_T_ID} — ${BTC_T_DESC}" echo ">> [TRIPLE] ${TARGET}" echo ">> [C LIBRARY] ${BTC_T_CLIB}" echo ">> [MODE] $([ "${CROSS_MODE}" -eq 1 ] && echo "CROSS-COMPILE" || echo "NATIVE")" echo ">> [THREAD ALLOCATION] Probed ${total_cpus} cores -> Throttled to ${v_threads} for LTO Safety." } # ============================================================================ # 4. SYSTEM PATHS & STAGING MATRIX # ============================================================================ export SOURCES_ACTIVE=/usr/src export BTC_ARCHIVE=/opt/BTC export SOURCE_CACHE=${BTC_ARCHIVE}/src export RAMDISK_SIZE="12gb" # Upstream Production Matrices (defaults — can be overridden per-target) v_linux='linux-7.1' v_binutils='binutils-2.46' v_gcc='gcc-14.2.0' v_glibc='glibc-2.41' v_libxcrypt='4.4.36' v_gmp='gmp-6.3.0' v_mpfr='mpfr-4.2.1' v_mpc='mpc-1.3.1' v_musl='musl-1.2.5' v_linux_headers='linux-6.12.y' # These are set after f_resolve_target: # NEWROOT, LOGS, HOST_ARCH, TARGET, TARGET_ARCH, GLOBAL_CFLAGS, GLOBAL_LDFLAGS function f_set_paths() { export NEWROOT="${SOURCES_ACTIVE}/${SYS_LABEL}-cleanroom" export LOGS="${BTC_ARCHIVE}/logs/${SYS_LABEL}" # Architecture-specific optimization flags # For non-x86_64, march maps to the per-arch value from the target registry local march_flag="${BTC_T_MARCH}" # ISA-specific extra flags (table-driven via case — SEI CERT CTR50-JP) local isa_extra="" case "${BTC_T_ISA}" in AVX512) isa_extra=" -mavx512f -mavx512dq -mavx512vl -mavx512bw" ;; AVX2) isa_extra=" -mavx2" ;; SSE4_2) isa_extra=" -msse4.2" ;; NEON) isa_extra=" -mfpu=neon -mfloat-abi=hard" ;; MIPS32) isa_extra="" ;; TILE) isa_extra="" ;; esac # C library choice affects linker paths and configure flags if [[ "${BTC_T_CLIB}" == "musl" ]]; then # musl provides its own headers; we still need kernel headers for # syscall definitions, but the C library headers come from musl. # --sysroot must point at NEWROOT which will contain musl installed. export GLOBAL_CFLAGS="-O3 -march=${march_flag}${isa_extra} -flto -ffat-lto-objects --sysroot=${NEWROOT} -pipe" else export GLOBAL_CFLAGS="-O3 -march=${march_flag}${isa_extra} -flto -ffat-lto-objects --sysroot=${NEWROOT} -pipe" fi export GLOBAL_LDFLAGS="-Wl,-O1 -Wl,--as-needed -flto --sysroot=${NEWROOT}" # For native x86_64 builds, keep the i686 build cpu if [[ "${CROSS_MODE}" -eq 0 && "${BTC_T_ARCH}" == "x86_64" ]]; then TARGET_ARCH="${BTC_T_MARCH}" else TARGET_ARCH="${BTC_T_ID}" fi } # ============================================================================ # 5. HARDWARE SENTINEL & TELEMETRY MODULES # ============================================================================ function f_guard() { local max_temp=85 local min_mem=800 local cur_temp local cur_mem # Thermal zones may not exist in containers; guard gracefully if [[ -d /sys/class/thermal ]]; then cur_temp=$(cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null | head -n1 | awk '{print $1/1000}') || cur_temp=0 else cur_temp=0 fi cur_mem=$(free -m | awk '/^Mem:/{print $7}') if (( ${cur_temp%.*} > max_temp )); then echo ">> [WARNING: THERMAL SPIKE] Temp at ${cur_temp}C. Throttling build for cooling phase..." sleep 15 fi if [[ ${cur_mem} -lt ${min_mem} ]]; then echo ">> [WARNING: MEMORY SATURATION] Free memory at ${cur_mem}MB. Yielding pipeline execution..." sleep 20 fi } function f_entropy_shield() { local min_entropy=1000 local cur_entropy if [[ -f /proc/sys/kernel/random/entropy_avail ]]; then cur_entropy=$(cat /proc/sys/kernel/random/entropy_avail) if [[ ${cur_entropy} -lt ${min_entropy} ]]; then echo ">> [ENTROPY DEFICIT] Pool dropped to ${cur_entropy}. Injecting safe hardware-jitter..." find /bin /sbin -type f -exec ls -l {} + > /dev/null 2>&1 & sleep 2 kill $! 2>/dev/null || true fi fi } function f_exec_log() { local cmd="$1" local log_base="$2" f_entropy_shield f_guard echo ">> Executing: ${log_base}" # Note: ${cmd} is sourced from internal build functions only (not user input). # The trust boundary is the BTC.sh script itself — do not expose f_exec_log # as a public API with externally-supplied command strings. stdbuf -oL -eL bash -c "${cmd}" 2>&1 | \ pv -t -r -b -N "${log_base}" | \ tee -a "${LOGS}/${log_base}.log" > /dev/null } function f_tmux_dashboard() { if [[ -n "${TMUX:-}" ]]; then echo ">> Active Tmux session identified. Splitting target tracking matrix..." tmux split-window -h -p 35 "tail -F \"${LOGS}\"/*.log" || true tmux split-window -v -p 50 "watch -n 2 'echo \"=== ENTROPY POOL ===\"; cat /proc/sys/kernel/random/entropy_avail; echo \"=== NETWORK BOUND MATRIX ===\"; ss -tunp | grep -v 127.0.0.1'" || true tmux select-pane -t 0 || true fi } # ============================================================================ # 6. FORENSIC IDENTITY STAMPING LAYER # ============================================================================ function f_stamp_binary() { local target_bin="$1" local log_base="$2" if [[ -f "${target_bin}" && ! -L "${target_bin}" ]]; then # 1. Inject ELF Object Note — use the target's cross-assembler when # building for a different architecture, so the .note.BTC section # uses the correct ELF format (e.g., 32-bit LE for ARMv7). local assembler="gcc" if [[ "${CROSS_MODE}" -eq 1 ]]; then assembler="${TARGET}-gcc" fi cat << EOF > btc_stamp.s .section .note.BTC,"a",@note .long 2f - 1f .long 4f - 3f .long 1 1: .asciz "DCOSNET" 2: .align 4 3: .ascii "Org: dcos.net|K:${v_linux}|Arch:${BTC_T_ID}|Label:${SYS_LABEL}|Forge:${log_base}" 4: .align 4 EOF ${assembler} -c btc_stamp.s -o btc_stamp.o ${TARGET}-objcopy --add-section .note.BTC=btc_stamp.o "${target_bin}" 2>/dev/null || \ objcopy --add-section .note.BTC=btc_stamp.o "${target_bin}" 2>/dev/null || true rm -f btc_stamp.s btc_stamp.o # 2. Append Extended Filesystem Attributes Ledger local bin_hash bin_hash=$(sha256sum "${target_bin}" | awk '{print $1}') setfattr -n user.btc.identity -v "BTC-${SYS_LABEL}-${v_linux}-sovereign" "${target_bin}" 2>/dev/null || true setfattr -n user.btc.hash -v "${bin_hash}" "${target_bin}" 2>/dev/null || true # 3. Separate Debug Symbols & Create External Links if [[ "${BTC_STRIP_MODE:-1}" -eq 1 ]]; then mkdir -p "${BTC_ARCHIVE}/symbols/${SYS_LABEL}" ${TARGET}-objcopy --only-keep-debug "${target_bin}" "${BTC_ARCHIVE}/symbols/${SYS_LABEL}/${log_base}.debug" 2>/dev/null || \ objcopy --only-keep-debug "${target_bin}" "${BTC_ARCHIVE}/symbols/${SYS_LABEL}/${log_base}.debug" 2>/dev/null || true ${TARGET}-strip --strip-unneeded "${target_bin}" 2>/dev/null || \ strip --strip-unneeded "${target_bin}" 2>/dev/null || true ${TARGET}-objcopy --add-gnu-debuglink="${BTC_ARCHIVE}/symbols/${SYS_LABEL}/${log_base}.debug" "${target_bin}" 2>/dev/null || \ objcopy --add-gnu-debuglink="${BTC_ARCHIVE}/symbols/${SYS_LABEL}/${log_base}.debug" "${target_bin}" 2>/dev/null || true fi fi } # ============================================================================ # 7. CLEANROOM MATRIX CONFIGURATION # ============================================================================ function f_setup() { echo ">> Preparing Virtualized Cleanroom Environment..." mkdir -p "${SOURCE_CACHE}" "${LOGS}" "${BTC_ARCHIVE}/symbols/${SYS_LABEL}" if ! mountpoint -q "${SOURCES_ACTIVE}"; then mount -t ramfs -o "size=${RAMDISK_SIZE}" ramfs "${SOURCES_ACTIVE}" echo ">> Ramfs Cleanroom mounted at ${SOURCES_ACTIVE} with ceiling ${RAMDISK_SIZE}." fi mkdir -p "${NEWROOT}" cd "${NEWROOT}" # Create sysroot directory structure mkdir -p bin etc lib lib64 sbin usr var include # Architecture-specific sysroot layout case "${BTC_T_ARCH}" in x86_64) ln -sfv lib "${NEWROOT}/lib64" ;; arm) # ARM EABI HF uses lib + lib/ld-linux-armhf.so.3 ln -sfv lib "${NEWROOT}/lib32" 2>/dev/null || true ;; mipsel) # MIPS o32 ABI: lib is the primary lib dir ;; tilegx) # Tile-Gx 64-bit: lib64 for abi64 ln -sfv lib "${NEWROOT}/lib64" 2>/dev/null || true ;; esac export PATH="${NEWROOT}/bin:${PATH}" } # ============================================================================ # 8. TOOLCHAIN BUILD FUNCTIONS # ============================================================================ # --- 8a. Binutils (all architectures) --- function f_binutils() { cd "${SOURCES_ACTIVE}" tar -xf "${SOURCE_CACHE}/${v_binutils}.tar.xz" mkdir -p "${v_binutils}-build" && cd "${v_binutils}-build" local configure_target="--target=${TARGET}" # Architecture-specific binutils configure patches local binutils_extra="" case "${BTC_T_ARCH}" in arm) binutils_extra="--enable-multilib --with-sysroot=${NEWROOT}" ;; mipsel) binutils_extra="--enable-multilib --with-sysroot=${NEWROOT}" ;; tilegx) binutils_extra="--disable-werror" ;; *) binutils_extra="--enable-default-hash-style=gnu" ;; esac local build_cmd="../${v_binutils}/configure \ --prefix=${NEWROOT} \ --with-sysroot=${NEWROOT} \ ${configure_target} \ --disable-nls \ --enable-gprofng=no \ --disable-werror \ ${binutils_extra}" f_exec_log "${build_cmd}" "binutils-configure" f_exec_log "make ${v_threads}" "binutils-make" f_exec_log "make install" "binutils-install" } # --- 8b. Kernel Headers (all architectures) --- function f_kernel_headers() { cd "${SOURCES_ACTIVE}" # Use stable LTS headers for cross targets that may need older kernels local kernel_src="${v_linux}" if [[ "${BTC_T_FAMILY}" == "tile" ]]; then kernel_src="${v_linux_headers}" fi # For musl targets, we only need sanitized kernel headers (no full # kernel source). For glibc targets we need the full headers. tar -xf "${SOURCE_CACHE}/${kernel_src}.tar.xz" cd "${kernel_src}" f_exec_log "make mrproper" "kernel-headers-clean" f_exec_log "make headers" "kernel-headers-generate" find usr/include -type f ! -name '*.h' -delete mkdir -p "${NEWROOT}/usr/include" cp -rv usr/include/* "${NEWROOT}/usr/include" } # --- 8c. GCC Stage 1 (all architectures) --- function f_gcc_p1() { cd "${SOURCES_ACTIVE}" tar -xf "${SOURCE_CACHE}/${v_gcc}.tar.xz" cd "${v_gcc}" # Nesting Support Libraries internally for Stage-1 execution isolation tar -xf "${SOURCE_CACHE}/${v_gmp}.tar.xz" && mv -v "${v_gmp}" gmp tar -xf "${SOURCE_CACHE}/${v_mpfr}.tar.xz" && mv -v "${v_mpfr}" mpfr tar -xf "${SOURCE_CACHE}/${v_mpc}.tar.gz" && mv -v "${v_mpc}" mpc # Architecture-specific GCC source patches case "${BTC_T_ARCH}" in x86_64) # Enforce 64-bit dynamic linker structural target pathing sed -e '/m64=/s/lib64/lib/' -i.bak gcc/config/i386/t-linux64 ;; arm) # ARM: default to hard-float ABI sed -e 's/#define DEFAULT_ABI_FLOAT SoftF/SoftF_HARDFP/' -i.bak gcc/config/arm/linux-eabi.h 2>/dev/null || true ;; mipsel) # MIPS: default to o32 ABI, soft-float ;; tilegx) # Tile-Gx: no special patches needed for GCC 10.3.0 ;; esac mkdir -p "${SOURCES_ACTIVE}/${v_gcc}-phase1" && cd "${SOURCES_ACTIVE}/${v_gcc}-phase1" # Base configure flags common to all targets local gcc_base="--target=${TARGET} \ --prefix=${NEWROOT} \ --with-sysroot=${NEWROOT} \ --with-newlib \ --without-headers \ --with-arch=${BTC_T_MARCH} \ --with-cpu=${BTC_T_MARCH} \ --enable-default-pie \ --enable-default-ssp \ --disable-nls \ --disable-shared \ --disable-threads \ --disable-libatomic \ --disable-libgomp \ --disable-libquadmath \ --disable-libssp \ --disable-libvtv \ --disable-libstdcxx \ --enable-languages=c,c++" # Per-architecture configure adjustments local gcc_arch_extra="" case "${BTC_T_CLIB}" in glibc) # x86_64 glibc targets: set glibc version for compatibility checks gcc_arch_extra="--with-glibc-version=${v_glibc#*-} --disable-multilib" ;; musl) # Cross targets with musl: disable multilib by default, add arch-specific flags gcc_arch_extra="--disable-multilib ${BTC_T_GCC_EXTRA}" ;; esac local build_cmd="../${v_gcc}/configure ${gcc_base} ${gcc_arch_extra}" f_exec_log "${build_cmd}" "gcc-p1-configure" f_exec_log "make ${v_threads} all-gcc" "gcc-p1-make" f_exec_log "make ${v_threads} all-target-libgcc" "gcc-p1-libgcc" f_exec_log "make install-gcc" "gcc-p1-install" f_exec_log "make install-target-libgcc" "gcc-p1-install-libgcc" } # --- 8d. C Library (glibc or musl) --- function f_clib() { case "${BTC_T_CLIB}" in glibc) f_glibc ;; musl) f_musl ;; *) echo ">> [ERROR] Unsupported C library: ${BTC_T_CLIB}" exit 1 ;; esac } function f_glibc() { cd "${SOURCES_ACTIVE}" tar -xf "${SOURCE_CACHE}/${v_glibc}.tar.xz" mkdir -p "${v_glibc}-build" && cd "${v_glibc}-build" # glibc only supports x86_64 (and a few others) — for non-x86 targets # this function should not be called. Guard: if [[ "${BTC_T_ARCH}" != "x86_64" ]]; then echo ">> [ERROR] glibc does not support ${BTC_T_ARCH}. Use musl via the target registry." exit 1 fi local build_cmd="../${v_glibc}/configure \ --prefix=/usr \ --host=${TARGET} \ --build=${HOST_ARCH} \ --enable-kernel=${BTC_T_KERN_MIN} \ --with-headers=${NEWROOT}/usr/include \ --disable-profile \ --enable-stack-protector=strong \ --disable-werror \ libc_cv_slibdir=/usr/lib" f_exec_log "${build_cmd}" "glibc-configure" f_exec_log "make ${v_threads}" "glibc-make" f_exec_log "make DESTDIR=${NEWROOT} install" "glibc-install" # Sanitize hardcoded host system configurations from dynamic script linkage sed -i "s|${NEWROOT}||g" "${NEWROOT}/usr/bin/ldd" } function f_libxcrypt() { # libxcrypt is only used with glibc — musl has built-in crypt support if [[ "${BTC_T_CLIB}" != "glibc" ]]; then echo ">> [SKIP] libxcrypt: not needed for ${BTC_T_CLIB}" return 0 fi cd "${SOURCES_ACTIVE}" tar -xf "${SOURCE_CACHE}/libxcrypt-${v_libxcrypt}.tar.xz" cd "libxcrypt-${v_libxcrypt}" local build_cmd="./configure \ --prefix=/usr \ --host=${TARGET} \ --build=${HOST_ARCH} \ --enable-hashes=strong,glibc \ --enable-obsolete-api=no \ --disable-static" f_exec_log "${build_cmd}" "libxcrypt-configure" f_exec_log "make ${v_threads}" "libxcrypt-make" f_exec_log "make DESTDIR=${NEWROOT} install" "libxcrypt-install" } function f_musl() { # musl: lightweight C library for cross-compilation # Used by mipsel, armv7, and tilegx targets. # Reference: CLFS (Cross Linux From Scratch) musl cross-compiler chapter. cd "${SOURCES_ACTIVE}" tar -xf "${SOURCE_CACHE}/${v_musl}.tar.gz" cd "${v_musl}" # Build a standalone musl cross-compiler that wraps our stage-1 GCC. # This produces ${TARGET}-musl-gcc and the musl C library installed # into the sysroot. local musl_configure="./configure \ --prefix=/usr \ --host=${TARGET} \ --build=${HOST_ARCH} \ --disable-shared \ --enable-static" # For some targets, musl needs additional architecture hints case "${BTC_T_ARCH}" in arm) musl_configure="${musl_configure} CFLAGS=\"-O2 -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16\"" ;; mipsel) musl_configure="${musl_configure} CFLAGS=\"-O2 -march=mips32r2 -mabi=32 -msoft-float\"" ;; tilegx) musl_configure="${musl_configure} CFLAGS=\"-O2 -march=tilegx\"" ;; esac # Use the cross compiler from stage-1 local cross_cc="${NEWROOT}/bin/${TARGET}-gcc" local cross_ar="${NEWROOT}/bin/${TARGET}-ar" export CC="${cross_cc}" export AR="${cross_ar}" export RANLIB="${NEWROOT}/bin/${TARGET}-ranlib" f_exec_log "CROSS_COMPILE=${TARGET}- ${musl_configure}" "musl-configure" f_exec_log "make ${v_threads}" "musl-make" f_exec_log "make DESTDIR=${NEWROOT} install" "musl-install" # Clean cross-compile env vars unset CC AR RANLIB } # --- 8e. GCC Stage 2 (final compiler) --- function f_gcc_p2() { cd "${SOURCES_ACTIVE}" cd "${v_gcc}" tar -xf "${SOURCE_CACHE}/${v_gmp}.tar.xz" --skip-old-files || true tar -xf "${SOURCE_CACHE}/${v_mpfr}.tar.xz" --skip-old-files || true tar -xf "${SOURCE_CACHE}/${v_mpc}.tar.gz" --skip-old-files || true mkdir -p "${SOURCES_ACTIVE}/${v_gcc}-phase2" && cd "${SOURCES_ACTIVE}/${v_gcc}-phase2" # Base configure for stage 2 — all targets local gcc_p2_base="--prefix=/usr \ --host=${TARGET} \ --build=${HOST_ARCH} \ --with-arch=${BTC_T_MARCH} \ --with-cpu=${BTC_T_MARCH} \ --enable-languages=c,c++ \ --enable-default-pie \ --enable-default-ssp \ --disable-bootstrap" # Per-C-library configure adjustments local gcc_p2_clib="" case "${BTC_T_CLIB}" in glibc) gcc_p2_clib="--disable-multilib --with-sysroot=${NEWROOT}" ;; musl) # musl targets: point GCC at the musl sysroot for C library # headers and runtime. --with-headers and --with-libs link # GCC to the musl installation from f_musl(). gcc_p2_clib="--disable-multilib \ --with-sysroot=${NEWROOT} \ --with-headers=${NEWROOT}/usr/include \ --with-libs=${NEWROOT}/usr/lib \ ${BTC_T_GCC_EXTRA}" ;; esac local build_cmd="../${v_gcc}/configure ${gcc_p2_base} ${gcc_p2_clib}" f_exec_log "${build_cmd}" "gcc-p2-configure" f_exec_log "make ${v_threads}" "gcc-p2-make" f_exec_log "make DESTDIR=${NEWROOT} install" "gcc-p2-install" } # --- 8f. Kernel Binary (architecture-aware) --- function f_kernel_binary() { local kernel_src="${v_linux}" if [[ "${BTC_T_FAMILY}" == "tile" ]]; then kernel_src="${v_linux_headers}" fi cd "${SOURCES_ACTIVE}/${kernel_src}" echo ">> Instantiating Silicon Optimized Monolithic Configuration Matrix for ${BTC_T_ARCH}..." # Select the correct defconfig for the target architecture case "${BTC_T_ARCH}" in x86_64) make defconfig ;; arm) # Multi-v7 is the universal ARMv7 defconfig (covers most Cortex-A SoCs) make multi_v7_defconfig ;; mipsel) # MALTA is the reference MIPS32 platform make malta_defconfig ;; tilegx) # Tile-Gx has its own defconfig make tilegx_defconfig 2>/dev/null || make defconfig ;; *) make defconfig ;; esac # Inject Custom Enterprise Swarm Labels & Architecture Parameters sed -i "s/CONFIG_LOCALVERSION=\"\"/CONFIG_LOCALVERSION=\"-dcosnet-${SYS_LABEL}\"/" .config # Modern Hardening Optimization Suite Injection sed -i "s/# CONFIG_MODULES is not set/CONFIG_MODULES=n/" .config || true echo "CONFIG_MODULES=n" >> .config echo "CONFIG_KALLSYMS=n" >> .config echo "CONFIG_DEBUG_FS=n" >> .config # Cross-compile kernel for non-x86_64 targets local kernel_make_vars="ARCH=${BTC_T_ARCH} CROSS_COMPILE=${TARGET}-" if [[ "${BTC_T_ARCH}" == "arm" ]]; then kernel_make_vars="ARCH=arm CROSS_COMPILE=${TARGET}-" fi f_exec_log "make ${kernel_make_vars} olddefconfig" "kernel-bin-config-merge" f_exec_log "make ${v_threads} ${kernel_make_vars} LOCALVERSION=-dcosnet-${SYS_LABEL}" "kernel-bin-make" # Install kernel image — path varies by architecture mkdir -p "${NEWROOT}/boot" case "${BTC_T_ARCH}" in x86_64) cp -v arch/x86/boot/bzImage "${NEWROOT}/boot/vmlinuz-${v_linux}-${SYS_LABEL}-sovereign" ;; arm) cp -v arch/arm/boot/zImage "${NEWROOT}/boot/vmlinuz-${v_linux}-${SYS_LABEL}-sovereign" 2>/dev/null || \ cp -v arch/arm/boot/Image "${NEWROOT}/boot/vmlinuz-${v_linux}-${SYS_LABEL}-sovereign" # Also copy device tree blobs if built find arch/arm/boot/dts -name '*.dtb' -exec cp -v {} "${NEWROOT}/boot/" \; 2>/dev/null || true ;; mipsel) cp -v vmlinux "${NEWROOT}/boot/vmlinuz-${v_linux}-${SYS_LABEL}-sovereign" ;; tilegx) cp -v arch/tile/boot/vmlinux "${NEWROOT}/boot/vmlinuz-${v_linux}-${SYS_LABEL}-sovereign" 2>/dev/null || \ cp -v vmlinux "${NEWROOT}/boot/vmlinuz-${v_linux}-${SYS_LABEL}-sovereign" ;; esac # Apply Forensic Engine Analysis Verification Stamps to Core Cross-Compiler Tooling find "${NEWROOT}/bin" "${NEWROOT}/usr/bin" -type f -exec bash -c 'f_stamp_binary "$1" "$(basename "$1")"' _ {} \; || true } # ============================================================================ # 9. PACKAGING # ============================================================================ function f_package() { echo ">> Packaging Production Golden Image Artifact Target Matrix..." cd "${NEWROOT}" # --- Integration Manifest for sorcery-go and Fester --- local manifest="${BTC_ARCHIVE}/${SYS_LABEL}-manifest.json" local mode_label="native" if [[ "${CROSS_MODE}" -eq 1 ]]; then mode_label="cross"; fi cat > "${manifest}" << MANIFEST_EOF { "btc_version": "0.4.0", "mode": "${mode_label}", "cross_mode": ${CROSS_MODE}, "sys_label": "${SYS_LABEL}", "target_id": "${BTC_T_ID}", "target_arch": "${BTC_T_ARCH}", "target_cpu": "${BTC_T_CPU}", "target_march": "${BTC_T_MARCH}", "target_triple": "${TARGET}", "host_arch": "${HOST_ARCH}", "isa_tag": "${ISA_TAG}", "opt_tag": "${OPT_TAG}", "abi": "${BTC_T_ABI}", "clib": "${BTC_T_CLIB}", "endian": "${BTC_T_ENDIAN}", "family": "${BTC_T_FAMILY}", "description": "${BTC_T_DESC}", "kernel_min": "${BTC_T_KERN_MIN}", "kernel": "${v_linux}", "binutils": "${v_binutils}", "gcc": "${v_gcc}", "glibc": "${v_glibc}", "musl": "${v_musl}", "libxcrypt": "libxcrypt-${v_libxcrypt}", "golden_image": "${SYS_LABEL}-toolchain-golden.tar.xz", "cflags": "${GLOBAL_CFLAGS}", "ldflags": "${GLOBAL_LDFLAGS}", "stamp_note": ".note.BTC", "stamp_xattr_identity": "user.btc.identity", "stamp_xattr_hash": "user.btc.hash", "org": "dcos.net", "license": "AGPL-3.0-or-later", "integrations": { "sorcery-go": { "config_key": "toolchain", "config_value": "btc", "env_btc_path": "SORCERY_GO_BTC_PATH", "env_btc_root": "SORCERY_GO_BTC_ROOT", "env_btc_syslabel": "SORCERY_GO_BTC_SYS_LABEL" }, "fester": { "config_section": "btc", "config_yaml_key": "btc.enabled / btc.root / btc.target" } } } MANIFEST_EOF echo ">> [INTEGRATION] Manifest written to: ${manifest}" tar -cf - . | xz -9 -T 0 > "${BTC_ARCHIVE}/${SYS_LABEL}-toolchain-golden.tar.xz" echo ">> [SUCCESS] Archive deployed cleanly to: ${BTC_ARCHIVE}/${SYS_LABEL}-toolchain-golden.tar.xz" # Generate SHA-256 checksums of the golden image for CAS integration. local checksum_file="${BTC_ARCHIVE}/${SYS_LABEL}-toolchain-golden.sha256" sha256sum "${BTC_ARCHIVE}/${SYS_LABEL}-toolchain-golden.tar.xz" > "${checksum_file}" echo ">> [INTEGRATION] SHA-256 checksum written to: ${checksum_file}" } # ============================================================================ # 10. MAIN ENTRY RUNTIME MATRIX # ============================================================================ function f_main() { [[ ${EUID} -ne 0 ]] && { echo ">> Error: Root privileges required."; exit 1; } # Parse command-line arguments case "${1:-}" in --list) f_list_targets exit 0 ;; --list-json) f_list_targets_json exit 0 ;; --help|-h) echo "BTC-0.4.0.sh - Sovereign Cross-Compilation Toolchain Forge" echo "" echo "Usage: BTC.sh [TARGET_ID | --native | --list | --list-json]" echo "" echo " TARGET_ID Build cross-toolchain for the specified target" echo " --native Auto-probe host silicon and build native toolchain" echo " --list List all registered cross-compilation targets" echo " --list-json Emit target registry as JSON" echo "" echo "No argument defaults to --native (backward compatible)." f_list_targets exit 0 ;; *) export BTC_TARGET_ID="${1:-}" ;; esac f_agpl_header f_silicon_probe f_set_paths f_setup f_tmux_dashboard # Linear Forge Execution Sequence f_binutils f_kernel_headers f_gcc_p1 f_clib # glibc OR musl (depending on target registry) f_libxcrypt # glibc-only (skipped for musl targets) f_gcc_p2 f_kernel_binary f_package # Clear volatile memory cleanrooms cd / umount -l "${SOURCES_ACTIVE}" 2>/dev/null || true echo ">> [COMPLETE] Sovereign Forge Build Finished Successfully under AGPLv3 Framework." echo ">> [TARGET] ${BTC_T_ID} (${BTC_T_DESC})" echo ">> [LABEL] ${SYS_LABEL}" echo ">> [IMAGE] ${BTC_ARCHIVE}/${SYS_LABEL}-toolchain-golden.tar.xz" } f_main "$@"