Initial commit: DarkForge Linux — Phases 0-12

Complete from-scratch Linux distribution targeting AMD Ryzen 9 9950X3D +
NVIDIA RTX 5090 on ASUS ROG CROSSHAIR X870E HERO.

Deliverables:
- dpack: custom package manager in Rust (3,800 lines)
  - TOML package parser, dependency resolver, build sandbox
  - CRUX Pkgfile and Gentoo ebuild converters
  - Shared library conflict detection
- 124 package definitions across 4 repos (core/extra/desktop/gaming)
- 34 toolchain bootstrap scripts (LFS 13.0 adapted for Zen 5)
- Linux 6.19.8 kernel config (hardware-specific, fully commented)
- SysVinit init system with rc.d service scripts
- Live ISO builder (UEFI-only, squashfs+xorriso)
- Interactive installer (GPT partitioning, EFISTUB boot)
- Integration test checklist (docs/TESTING.md)

No systemd. No bootloader. No display manager.
Kernel boots via EFISTUB → auto-login → dwl Wayland compositor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 11:30:40 +01:00
commit 029642ae5b
206 changed files with 14696 additions and 0 deletions

132
toolchain/README.md Normal file
View File

@@ -0,0 +1,132 @@
# DarkForge Toolchain Bootstrap
Cross-compilation toolchain scripts that build the base system from scratch, following the Linux From Scratch (LFS 13.0) methodology with DarkForge-specific customizations.
## Overview
These scripts implement LFS Chapters 5-7, adapted for:
- **Target:** AMD Ryzen 9 9950X3D (Zen 5, `-march=znver5`)
- **Compiler:** GCC 15.2.0 (full znver5 support)
- **Target triplet:** `x86_64-darkforge-linux-gnu`
The build produces a self-hosting chroot environment capable of compiling everything else.
## Requirements
- A Linux host system (any recent distro)
- ~20GB free disk space
- Internet access (for downloading sources)
- Host tools: bash, gcc, g++, make, bison, gawk, m4, texinfo, xz, wget/curl
### Host System Verification
Check your host has the required tools:
```bash
# Verify essential tools are present
for cmd in bash gcc g++ make bison gawk m4 texinfo xz wget; do
command -v $cmd >/dev/null && echo "OK: $cmd" || echo "MISSING: $cmd"
done
```
## Build Process
### Step 1: Set up the environment
```bash
export LFS=/mnt/darkforge
# Create and mount your target partition
sudo mkdir -pv $LFS
sudo mount /dev/nvme0n1p3 $LFS # adjust device as needed
# Run the environment setup
sudo bash scripts/000-env-setup.sh
```
This creates the `lfs` user, directory structure, and environment variables.
### Step 2: Download sources
```bash
bash scripts/000a-download-sources.sh
```
Downloads all ~30 source tarballs to `$LFS/sources/`.
### Step 3: Build the cross-toolchain (Chapter 5)
```bash
bash scripts/build-all.sh cross
```
Builds: binutils (pass 1) → GCC (pass 1) → Linux headers → glibc → libstdc++
### Step 4: Build temporary tools (Chapter 6)
```bash
bash scripts/build-all.sh temp
```
Builds 17 packages: m4, ncurses, bash, coreutils, diffutils, file, findutils, gawk, grep, gzip, make, patch, sed, tar, xz, binutils (pass 2), GCC (pass 2).
### Step 5: Enter chroot and build native tools (Chapter 7)
```bash
sudo bash scripts/023-chroot-setup.sh
# Now inside the chroot:
bash /sources/toolchain-scripts/024-chroot-essentials.sh
bash /sources/toolchain-scripts/025-gettext.sh
# ... through 030-util-linux.sh
bash /sources/toolchain-scripts/031-cleanup.sh
```
### Step 6: Verify
The cleanup script runs a "Hello World" compilation test. If it passes, the toolchain is ready.
## Script Inventory
| Script | Phase | Description |
|--------|-------|-------------|
| `000-env-setup.sh` | Setup | Creates directories, lfs user, environment |
| `000a-download-sources.sh` | Setup | Downloads all source tarballs |
| `001-binutils-pass1.sh` | Ch.5 | Cross-assembler and linker |
| `002-gcc-pass1.sh` | Ch.5 | Cross-compiler (C/C++) |
| `003-linux-headers.sh` | Ch.5 | Linux API headers |
| `004-glibc.sh` | Ch.5 | GNU C Library (with sanity checks) |
| `005-libstdcxx.sh` | Ch.5 | C++ standard library |
| `006-m4.sh` `020-xz.sh` | Ch.6 | Temporary tools (15 packages) |
| `021-binutils-pass2.sh` | Ch.6 | Native binutils |
| `022-gcc-pass2.sh` | Ch.6 | Native GCC |
| `023-chroot-setup.sh` | Ch.7 | Mount virtual filesystems, enter chroot |
| `024-chroot-essentials.sh` | Ch.7 | Create /etc/passwd, /etc/group, etc. |
| `025-gettext.sh` `030-util-linux.sh` | Ch.7 | Native chroot tools |
| `031-cleanup.sh` | Ch.7 | Strip binaries, run exit criteria test |
| `build-all.sh` | Meta | Master build runner with logging |
## Version Manifest
See `VERSION_MANIFEST.md` for the exact version of every package used, with source URLs and rationale.
## Logs
Build logs are saved to `logs/<script-name>.log` by the master build runner.
## Troubleshooting
If a build fails:
1. Check the log file in `logs/`
2. The most common issue is a missing host dependency
3. The glibc sanity checks (script 004) are critical — if they fail, the entire toolchain is broken
4. GCC pass 1 is the longest build (~4 SBU on the 9950X3D with `-j32`)
## Repository
```
git@git.dannyhaslund.dk:danny8632/darkforge.git
```
Toolchain scripts live in the `toolchain/` directory of the main DarkForge repo.

View File

@@ -0,0 +1,67 @@
# DarkForge Linux — Phase 0 Toolchain Version Manifest
# Generated: 2026-03-19
# Rule: Always use latest stable release (CLAUDE.md §3)
# Base reference: LFS 13.0 (r13.0-4, 2026-03-14)
## Cross-Toolchain (Chapter 5 equivalents)
| Package | Version | Source URL | Note |
|----------------|---------|-------------------------------------------------------------------------|--------------------------------|
| binutils | 2.46 | https://ftp.gnu.org/gnu/binutils/binutils-2.46.tar.xz | LFS uses 2.46.0 (same) |
| gcc | 15.2.0 | https://ftp.gnu.org/pub/gnu/gcc/gcc-15.2.0/gcc-15.2.0.tar.xz | Supports -march=znver5 |
| glibc | 2.43 | https://ftp.gnu.org/gnu/glibc/glibc-2.43.tar.xz | |
| linux | 6.19.8 | https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.19.8.tar.xz | Headers only for Phase 0 |
| mpfr | 4.2.2 | https://www.mpfr.org/mpfr-current/mpfr-4.2.2.tar.xz | GCC dependency |
| gmp | 6.3.0 | https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz | GCC dependency |
| mpc | 1.3.1 | https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz | GCC dependency |
## Temporary Tools (Chapter 6 equivalents)
| Package | Version | Source URL | Note |
|----------------|---------|-------------------------------------------------------------------------|--------------------------------|
| m4 | 1.4.20 | https://ftp.gnu.org/gnu/m4/m4-1.4.20.tar.xz | Newer than LFS (1.4.19) |
| ncurses | 6.5 | https://invisible-island.net/datafiles/release/ncurses-6.5.tar.gz | |
| bash | 5.3 | https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz | |
| coreutils | 9.6 | https://ftp.gnu.org/gnu/coreutils/coreutils-9.6.tar.xz | LFS 13 uses 9.6 |
| diffutils | 3.10 | https://ftp.gnu.org/gnu/diffutils/diffutils-3.10.tar.xz | |
| file | 5.47 | https://astron.com/pub/file/file-5.47.tar.gz | LFS 13 version |
| findutils | 4.10.0 | https://ftp.gnu.org/gnu/findutils/findutils-4.10.0.tar.xz | |
| gawk | 5.4.0 | https://ftp.gnu.org/gnu/gawk/gawk-5.4.0.tar.xz | |
| grep | 3.14 | https://ftp.gnu.org/gnu/grep/grep-3.14.tar.xz | LFS 13 version |
| gzip | 1.14 | https://ftp.gnu.org/gnu/gzip/gzip-1.14.tar.xz | Newer than LFS (1.13) |
| make | 4.4.1 | https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz | |
| patch | 2.8 | https://ftp.gnu.org/gnu/patch/patch-2.8.tar.xz | Newer than LFS (2.7.6) |
| sed | 4.9 | https://ftp.gnu.org/gnu/sed/sed-4.9.tar.xz | LFS 13 version |
| tar | 1.35 | https://ftp.gnu.org/gnu/tar/tar-1.35.tar.xz | |
| xz | 5.8.1 | https://github.com/tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1.tar.gz | Newer than LFS (5.6.1) |
| zstd | 1.5.7 | https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz | |
## Chroot Packages (Chapter 7 equivalents)
| Package | Version | Source URL | Note |
|----------------|---------|-------------------------------------------------------------------------|--------------------------------|
| gettext | 0.23.1 | https://ftp.gnu.org/gnu/gettext/gettext-0.23.1.tar.xz | Latest stable |
| bison | 3.8.2 | https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz | |
| perl | 5.40.2 | https://www.cpan.org/src/5.0/perl-5.40.2.tar.xz | Latest stable 5.40.x |
| python | 3.13.3 | https://www.python.org/ftp/python/3.13.3/Python-3.13.3.tar.xz | Latest stable 3.13.x |
| texinfo | 7.3 | https://ftp.gnu.org/gnu/texinfo/texinfo-7.3.tar.xz | |
| zlib | 1.3.1 | https://zlib.net/zlib-1.3.1.tar.xz | |
## Compiler Flags (Global Defaults)
```
CFLAGS="-march=znver5 -O2 -pipe -fomit-frame-pointer"
CXXFLAGS="${CFLAGS}"
MAKEFLAGS="-j32"
LDFLAGS="-Wl,-O1,--as-needed"
```
Note: znver5 is supported since GCC 14.1. GCC 15.2.0 has full support.
During cross-compilation (Pass 1), hardware-specific flags are NOT applied — they
only take effect once we have a native compiler targeting our hardware.
## Patches Required
| Patch | Source | Used For |
|------------------------|------------------------------------------------|-----------------|
| glibc-fhs-1.patch | https://www.linuxfromscratch.org/patches/lfs/ | Glibc FHS dirs |

View File

@@ -0,0 +1,111 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0: Environment Setup
# ============================================================================
# Purpose: Set up the build environment, directory structure, and variables
# needed for the cross-toolchain bootstrap.
# Inputs: LFS - path to target partition (e.g., /mnt/darkforge)
# Outputs: Environment variables, directory tree, lfs user
# Assumes: Target partition is mounted at $LFS, running as root
# Ref: LFS 13.0 Chapters 2-4
# ============================================================================
set -euo pipefail
# --- Configuration -----------------------------------------------------------
# These must be set before running this script.
# Override via environment or edit here.
LFS="${LFS:-/mnt/darkforge}"
LFS_TGT="x86_64-darkforge-linux-gnu"
# DarkForge hardware-specific flags (applied in native builds, NOT cross-compile)
DF_CFLAGS="-march=znver5 -O2 -pipe -fomit-frame-pointer"
DF_CXXFLAGS="${DF_CFLAGS}"
DF_MAKEFLAGS="-j32"
DF_LDFLAGS="-Wl,-O1,--as-needed"
# --- Verify mount point ------------------------------------------------------
if ! mountpoint -q "${LFS}" 2>/dev/null; then
echo "ERROR: ${LFS} is not a mount point."
echo "Mount the target partition first: mount /dev/<partition> ${LFS}"
exit 1
fi
echo "=== DarkForge Phase 0: Environment Setup ==="
echo "LFS=${LFS}"
echo "LFS_TGT=${LFS_TGT}"
# --- Create directory structure -----------------------------------------------
echo ">>> Creating directory structure..."
mkdir -pv "${LFS}/sources"
mkdir -pv "${LFS}/tools"
mkdir -pv "${LFS}"/{etc,var,usr/{bin,lib,sbin}}
# Create /lib64 symlink for x86_64
case $(uname -m) in
x86_64) mkdir -pv "${LFS}/lib64" ;;
esac
# Symlinks for unified /usr layout (LFS 13.0 style)
for dir in bin lib sbin; do
ln -sfv "usr/${dir}" "${LFS}/${dir}" 2>/dev/null || true
done
# Set sticky bit on sources directory
chmod -v a+wt "${LFS}/sources"
# --- Create lfs user (if not exists) ------------------------------------------
echo ">>> Setting up 'lfs' build user..."
if ! id lfs &>/dev/null; then
groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
echo "Created 'lfs' user."
else
echo "'lfs' user already exists."
fi
# Grant lfs ownership of build directories
chown -v lfs "${LFS}"/{usr{,/*},lib,var,etc,bin,lib64,sbin,tools,sources} 2>/dev/null || true
# --- Write lfs user's shell profile -------------------------------------------
echo ">>> Writing lfs shell profile..."
cat > /home/lfs/.bash_profile << 'PROFILE_EOF'
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
PROFILE_EOF
cat > /home/lfs/.bashrc << BASHRC_EOF
set +h
umask 022
LFS=${LFS}
LC_ALL=POSIX
LFS_TGT=${LFS_TGT}
PATH=${LFS}/tools/bin:/usr/bin
if [ ! -L /bin ]; then PATH=/bin:\$PATH; fi
export LFS LC_ALL LFS_TGT PATH
export MAKEFLAGS="${DF_MAKEFLAGS}"
BASHRC_EOF
chown lfs:lfs /home/lfs/.bash_profile /home/lfs/.bashrc
# --- Write persistent environment config for other scripts --------------------
cat > "${LFS}/sources/darkforge-env.sh" << ENV_EOF
# DarkForge build environment — sourced by all toolchain scripts
export LFS="${LFS}"
export LFS_TGT="${LFS_TGT}"
export LC_ALL=POSIX
export PATH="${LFS}/tools/bin:/usr/bin"
if [ ! -L /bin ]; then export PATH="/bin:\${PATH}"; fi
export MAKEFLAGS="${DF_MAKEFLAGS}"
# Hardware-specific flags (only for native compilation, NOT cross-compile)
export DF_CFLAGS="${DF_CFLAGS}"
export DF_CXXFLAGS="${DF_CXXFLAGS}"
export DF_LDFLAGS="${DF_LDFLAGS}"
ENV_EOF
echo "=== Environment setup complete ==="
echo ""
echo "Next steps:"
echo " 1. Download source tarballs to ${LFS}/sources/"
echo " 2. Switch to lfs user: su - lfs"
echo " 3. Run toolchain build scripts in order (001, 002, ...)"

View File

@@ -0,0 +1,89 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0: Download Source Tarballs
# ============================================================================
# Purpose: Download all source tarballs needed for the toolchain bootstrap.
# Inputs: LFS environment variable (path to target partition)
# Outputs: Source tarballs in ${LFS}/sources/
# Assumes: Internet access, wget or curl available
# ============================================================================
set -euo pipefail
LFS="${LFS:-/mnt/darkforge}"
SRCDIR="${LFS}/sources"
mkdir -p "${SRCDIR}"
cd "${SRCDIR}"
echo "=== DarkForge: Downloading source tarballs ==="
# --- Helper function ----------------------------------------------------------
download() {
local url="$1"
local filename
filename=$(basename "${url}")
if [ -f "${filename}" ]; then
echo " [SKIP] ${filename} already exists"
return 0
fi
echo " [GET] ${filename}"
wget --no-verbose --continue "${url}" -O "${filename}" || {
echo " [FAIL] ${filename} — trying curl fallback"
curl -fLo "${filename}" "${url}" || {
echo " [ERROR] Failed to download ${filename}"
return 1
}
}
}
# --- Cross-Toolchain (Chapter 5) ---------------------------------------------
echo ">>> Cross-Toolchain packages..."
download "https://ftp.gnu.org/gnu/binutils/binutils-2.46.tar.xz"
download "https://ftp.gnu.org/pub/gnu/gcc/gcc-15.2.0/gcc-15.2.0.tar.xz"
download "https://ftp.gnu.org/gnu/glibc/glibc-2.43.tar.xz"
download "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.19.8.tar.xz"
download "https://www.mpfr.org/mpfr-current/mpfr-4.2.2.tar.xz"
download "https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz"
download "https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz"
# --- Temporary Tools (Chapter 6) ---------------------------------------------
echo ">>> Temporary tools packages..."
download "https://ftp.gnu.org/gnu/m4/m4-1.4.20.tar.xz"
download "https://invisible-island.net/datafiles/release/ncurses-6.5.tar.gz"
download "https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz"
download "https://ftp.gnu.org/gnu/coreutils/coreutils-9.6.tar.xz"
download "https://ftp.gnu.org/gnu/diffutils/diffutils-3.10.tar.xz"
download "https://astron.com/pub/file/file-5.47.tar.gz"
download "https://ftp.gnu.org/gnu/findutils/findutils-4.10.0.tar.xz"
download "https://ftp.gnu.org/gnu/gawk/gawk-5.4.0.tar.xz"
download "https://ftp.gnu.org/gnu/grep/grep-3.14.tar.xz"
download "https://ftp.gnu.org/gnu/gzip/gzip-1.14.tar.xz"
download "https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz"
download "https://ftp.gnu.org/gnu/patch/patch-2.8.tar.xz"
download "https://ftp.gnu.org/gnu/sed/sed-4.9.tar.xz"
download "https://ftp.gnu.org/gnu/tar/tar-1.35.tar.xz"
download "https://github.com/tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1.tar.gz"
download "https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz"
# --- Chroot Packages (Chapter 7) ---------------------------------------------
echo ">>> Chroot packages..."
download "https://ftp.gnu.org/gnu/gettext/gettext-0.23.1.tar.xz"
download "https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz"
download "https://www.cpan.org/src/5.0/perl-5.40.2.tar.xz"
download "https://www.python.org/ftp/python/3.13.3/Python-3.13.3.tar.xz"
download "https://ftp.gnu.org/gnu/texinfo/texinfo-7.3.tar.xz"
download "https://zlib.net/zlib-1.3.1.tar.xz"
download "https://github.com/util-linux/util-linux/releases/download/v2.40.4/util-linux-2.40.4.tar.xz"
# --- Patches ------------------------------------------------------------------
echo ">>> Patches..."
download "https://www.linuxfromscratch.org/patches/lfs/13.0/glibc-2.43-fhs-1.patch"
echo ""
echo "=== All downloads complete ==="
echo "Source tarballs are in: ${SRCDIR}/"
ls -lh "${SRCDIR}/" | tail -n +2 | wc -l
echo "files downloaded."

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 5: Binutils Pass 1
# ============================================================================
# Purpose: Build the cross-assembler and cross-linker (binutils) as the
# first component of the cross-toolchain. This must be built first
# because both GCC and Glibc configure tests depend on it.
# Inputs: ${LFS}/sources/binutils-2.46.tar.xz
# Outputs: Cross-binutils installed to ${LFS}/tools/
# Assumes: Running as 'lfs' user, environment sourced from 000-env-setup.sh
# Ref: LFS 13.0 §5.2
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="binutils"
VERSION="2.46"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Cross-Toolchain Pass 1) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
mkdir -v build
cd build
# Configure for cross-compilation
# --target=$LFS_TGT: produce binaries for our target triplet
# --prefix=$LFS/tools: install into the temporary toolchain directory
# --with-sysroot=$LFS: use $LFS as the sysroot for target libraries
# --disable-nls: no internationalization needed for build tools
# --enable-gprofng=no: don't build the profiling tool
# --disable-werror: don't fail on compiler warnings
# --enable-new-dtags: use RUNPATH (modern) instead of RPATH
# --enable-default-hash-style=gnu: GNU hash for faster symbol lookup
../configure \
--prefix="${LFS}/tools" \
--with-sysroot="${LFS}" \
--target="${LFS_TGT}" \
--disable-nls \
--enable-gprofng=no \
--disable-werror \
--enable-new-dtags \
--enable-default-hash-style=gnu
make
make install
# Cleanup
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} Pass 1 complete ==="

View File

@@ -0,0 +1,96 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 5: GCC Pass 1
# ============================================================================
# Purpose: Build the cross-compiler (GCC) as the second component of the
# cross-toolchain. This produces a C/C++ compiler that runs on the
# host but generates code for the target (x86_64-darkforge-linux-gnu).
# No hardware-specific flags (-march=znver5) yet — those come later
# when we have a native compiler.
# Inputs: ${LFS}/sources/gcc-15.2.0.tar.xz, mpfr, gmp, mpc tarballs
# Outputs: Cross-GCC installed to ${LFS}/tools/
# Assumes: Binutils Pass 1 complete, running as 'lfs' user
# Ref: LFS 13.0 §5.3
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="gcc"
VERSION="15.2.0"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Cross-Toolchain Pass 1) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Extract and link GCC's arithmetic library dependencies
tar -xf ../mpfr-4.2.2.tar.xz
mv -v mpfr-4.2.2 mpfr
tar -xf ../gmp-6.3.0.tar.xz
mv -v gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc
# Fix lib64 directory naming on x86_64
# GCC defaults to installing 64-bit libraries in lib64, but LFS/DarkForge
# uses a unified /usr/lib directory. This sed changes the default.
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' -i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
# Configure cross-compiler
# --target=$LFS_TGT: cross-compile for our target
# --with-glibc-version=2.43: tell GCC which glibc version to expect
# --with-newlib: inhibit building libc-dependent code (no libc yet)
# --without-headers: don't look for system headers yet
# --enable-default-pie: position-independent executables by default (security)
# --enable-default-ssp: stack smashing protection by default (security)
# --disable-shared: static link GCC internal libraries
# --disable-multilib: no 32-bit support in the cross-compiler
# (multilib will be addressed later for Steam/Wine compatibility)
# --disable-threads: no threading support yet (no glibc/pthreads)
# --disable-lib*: disable libraries that aren't needed at this stage
# --enable-languages=c,c++: only C and C++ compilers needed
../configure \
--target="${LFS_TGT}" \
--prefix="${LFS}/tools" \
--with-glibc-version=2.43 \
--with-sysroot="${LFS}" \
--with-newlib \
--without-headers \
--enable-default-pie \
--enable-default-ssp \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
make
make install
# Create the full version of the internal limits.h header
# GCC needs this to properly handle system limits.h
cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
"$(dirname "$("${LFS_TGT}-gcc" -print-libgcc-file-name)")/include/limits.h"
# Cleanup
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} Pass 1 complete ==="

View File

@@ -0,0 +1,45 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 5: Linux API Headers
# ============================================================================
# Purpose: Install the Linux kernel API headers into the target sysroot.
# These headers define the kernel-userspace interface that glibc
# needs to compile against. We use kernel 6.19.8 to match our
# target kernel version.
# Inputs: ${LFS}/sources/linux-6.19.8.tar.xz
# Outputs: Kernel headers in ${LFS}/usr/include/
# Assumes: Running as 'lfs' user
# Ref: LFS 13.0 §5.4
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="linux"
VERSION="6.19.8"
SRCDIR="${LFS}/sources"
echo "=== Installing ${PACKAGE}-${VERSION} API Headers ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Clean any stale files or configurations
make mrproper
# Generate the sanitized kernel headers
# The 'headers' target produces userspace-safe versions of kernel headers
make headers
# Remove non-header files from the generated output
find usr/include -type f ! -name '*.h' -delete
# Install headers to target sysroot
cp -rv usr/include "${LFS}/usr"
# Cleanup
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} API Headers installed ==="

124
toolchain/scripts/004-glibc.sh Executable file
View File

@@ -0,0 +1,124 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 5: Glibc (Cross-compiled)
# ============================================================================
# Purpose: Cross-compile the GNU C Library (glibc) for the target system.
# This is the core C library that every program on the final system
# will link against. After this step, we can compile programs that
# actually run on the target.
# Inputs: ${LFS}/sources/glibc-2.43.tar.xz, glibc-2.43-fhs-1.patch
# Outputs: Glibc installed to ${LFS}/usr/lib/, ${LFS}/usr/include/
# Assumes: Binutils Pass 1 + GCC Pass 1 + Linux Headers complete
# Ref: LFS 13.0 §5.5
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="glibc"
VERSION="2.43"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Cross-compiled) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Create LSB compliance symlinks
# The dynamic linker path must be correct for the target architecture
case $(uname -m) in
i?86)
ln -sfv ld-linux.so.2 "${LFS}/lib/ld-lsb.so.3"
;;
x86_64)
ln -sfv ../lib/ld-linux-x86-64.so.2 "${LFS}/lib64"
ln -sfv ../lib/ld-linux-x86-64.so.2 "${LFS}/lib64/ld-lsb-x86-64.so.3"
;;
esac
# Apply the FHS (Filesystem Hierarchy Standard) patch
# This makes glibc install some programs in /usr/sbin instead of /sbin
patch -Np1 -i ../glibc-2.43-fhs-1.patch
mkdir -v build
cd build
# Tell configure to install root-level sbin programs in /usr/sbin
echo "rootsbindir=/usr/sbin" > configparms
# Configure glibc for cross-compilation
# --host=$LFS_TGT: cross-compile for our target
# --build=...: specify the build system (auto-detected)
# --enable-kernel=5.4: support kernels 5.4 and newer
# --disable-nscd: don't build the name service cache daemon
# libc_cv_slibdir=/usr/lib: install shared libs in /usr/lib (not /lib64)
../configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(../scripts/config.guess)" \
--disable-nscd \
libc_cv_slibdir=/usr/lib \
--enable-kernel=5.4
make
make DESTDIR="${LFS}" install
# Fix the hardcoded path in the ldd script
sed '/RTLDLIST=/s@/usr@@g' -i "${LFS}/usr/bin/ldd"
# ============================================================================
# CRITICAL SANITY CHECKS — Do not skip these!
# If any check fails, STOP and investigate before proceeding.
# ============================================================================
echo ""
echo ">>> Running glibc sanity checks..."
echo 'int main(){}' | "${LFS_TGT}-gcc" -x c - -v -Wl,--verbose &> dummy.log
# Check 1: Verify dynamic linker path
echo "--- Check 1: Dynamic linker path ---"
RESULT=$(readelf -l a.out | grep ': /lib')
echo "${RESULT}"
if ! echo "${RESULT}" | grep -q '/lib64/ld-linux-x86-64.so.2'; then
echo "FAIL: Dynamic linker path is wrong!"
exit 1
fi
echo "PASS"
# Check 2: Verify start files are found
echo "--- Check 2: Start files ---"
grep -E -o "${LFS}/lib.*/S?crt[1in].*succeeded" dummy.log
echo "PASS"
# Check 3: Verify header search paths
echo "--- Check 3: Header search paths ---"
grep -B3 "^ ${LFS}/usr/include" dummy.log
echo "PASS"
# Check 4: Verify linker search paths
echo "--- Check 4: Linker search paths ---"
grep 'SEARCH.*/usr/lib' dummy.log | sed 's|; |\n|g'
echo "PASS"
# Check 5: Verify correct libc is found
echo "--- Check 5: libc.so.6 location ---"
grep "/lib.*/libc.so.6 " dummy.log
echo "PASS"
# Check 6: Verify dynamic linker location
echo "--- Check 6: Dynamic linker found ---"
grep found dummy.log
echo "PASS"
# Cleanup test files
rm -v a.out dummy.log
echo ""
# Cleanup source
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} cross-compilation complete ==="
echo "=== All sanity checks passed ==="

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 5: Libstdc++ (from GCC)
# ============================================================================
# Purpose: Build the C++ standard library (libstdc++) for the target.
# This was deferred from GCC Pass 1 because it depends on glibc,
# which wasn't available then. Now that glibc is installed in the
# target sysroot, we can build libstdc++.
# Inputs: ${LFS}/sources/gcc-15.2.0.tar.xz (same source as GCC Pass 1)
# Outputs: libstdc++ in ${LFS}/usr/lib/
# Assumes: GCC Pass 1 + Glibc complete
# Ref: LFS 13.0 §5.6
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="gcc"
VERSION="15.2.0"
SRCDIR="${LFS}/sources"
echo "=== Building libstdc++ from ${PACKAGE}-${VERSION} ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
mkdir -v build
cd build
# Configure only the libstdc++ component
# --host=$LFS_TGT: cross-compile for our target
# --disable-multilib: no 32-bit support at this stage
# --disable-nls: no internationalization
# --disable-libstdcxx-pch: skip precompiled headers (saves time/space)
# --with-gxx-include-dir: point to the cross-compiler's include path
../libstdc++-v3/configure \
--host="${LFS_TGT}" \
--build="$(../config.guess)" \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-pch \
--with-gxx-include-dir="/tools/${LFS_TGT}/include/c++/${VERSION}"
make
make DESTDIR="${LFS}" install
# Remove libtool archive files — they cause problems with cross-compilation
rm -v "${LFS}/usr/lib/lib"{stdc++{,exp,fs},supc++}.la 2>/dev/null || true
# Cleanup
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== libstdc++ from ${PACKAGE}-${VERSION} complete ==="

36
toolchain/scripts/006-m4.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: M4
# ============================================================================
# Purpose: Cross-compile the M4 macro processor. Required by Bison and
# other packages that process m4 macros.
# Inputs: ${LFS}/sources/m4-1.4.20.tar.xz
# Outputs: m4 binary in ${LFS}/usr/
# Assumes: Cross-toolchain (Ch.5) complete
# Ref: LFS 13.0 §6.2
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="m4"
VERSION="1.4.20"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,61 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Ncurses
# ============================================================================
# Purpose: Cross-compile the ncurses library (terminal handling). Required
# by bash, many TUI programs, and the installer.
# Inputs: ${LFS}/sources/ncurses-6.5.tar.gz
# Outputs: ncurses libraries and tic utility in ${LFS}/usr/
# Assumes: Cross-toolchain (Ch.5) complete
# Ref: LFS 13.0 §6.3
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="ncurses"
VERSION="6.5"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.gz"
cd "${PACKAGE}-${VERSION}"
# First, build the tic program that runs on the host
# This is needed to create the terminal database during install
sed -i s/mawk// configure
mkdir build
pushd build
../configure
make -C include
make -C progs tic
popd
# Now cross-compile ncurses for the target
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(./config.guess)" \
--mandir=/usr/share/man \
--with-manpage-format=normal \
--with-shared \
--without-normal \
--with-cxx-shared \
--without-debug \
--without-ada \
--disable-stripping
make
make DESTDIR="${LFS}" TIC_PATH="$(pwd)/build/progs/tic" install
# Fix library so that it can be found by linker
ln -sv libncursesw.so "${LFS}/usr/lib/libncurses.so"
# Create pkg-config compatibility for programs that look for -lncurses
sed -e 's/^#if.*XOPEN.*$/#if 1/' -i "${LFS}/usr/include/curses.h"
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

41
toolchain/scripts/008-bash.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Bash
# ============================================================================
# Purpose: Cross-compile Bash for the temporary tools. This gives us a
# working shell inside the chroot environment.
# Inputs: ${LFS}/sources/bash-5.3.tar.gz
# Outputs: bash binary in ${LFS}/usr/bin/
# Assumes: Cross-toolchain + ncurses complete
# Ref: LFS 13.0 §6.4
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="bash"
VERSION="5.3"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.gz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--build="$(sh support/config.guess)" \
--host="${LFS_TGT}" \
--without-bash-malloc \
bash_cv_strtold_broken=no
make
make DESTDIR="${LFS}" install
# Create /bin/sh symlink pointing to bash
ln -sfv bash "${LFS}/usr/bin/sh"
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,41 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Coreutils
# ============================================================================
# Purpose: Cross-compile GNU coreutils (ls, cp, mv, cat, chmod, etc.)
# for the temporary tools environment.
# Inputs: ${LFS}/sources/coreutils-9.6.tar.xz
# Outputs: Core utilities in ${LFS}/usr/bin/
# Assumes: Cross-toolchain complete
# Ref: LFS 13.0 §6.5
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="coreutils"
VERSION="9.6"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)" \
--enable-install-program=hostname \
gl_cv_macro_MB_CUR_MAX_good=y
make
make DESTDIR="${LFS}" install
# Move some programs to where they're expected
mv -v "${LFS}/usr/bin/chroot" "${LFS}/usr/sbin"
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,34 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Diffutils
# ============================================================================
# Purpose: Cross-compile GNU diffutils (diff, cmp, sdiff, diff3).
# Inputs: ${LFS}/sources/diffutils-3.10.tar.xz
# Outputs: diff utilities in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.6
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="diffutils"
VERSION="3.10"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(./build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

46
toolchain/scripts/011-file.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: File
# ============================================================================
# Purpose: Cross-compile the file utility (determines file types via
# magic numbers). Some build systems use file during configure.
# Inputs: ${LFS}/sources/file-5.47.tar.gz
# Outputs: file binary in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.7
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="file"
VERSION="5.47"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.gz"
cd "${PACKAGE}-${VERSION}"
# Build a host-native 'file' first — needed during cross-compilation
mkdir build
pushd build
../configure --disable-bzlib --disable-libseccomp \
--disable-xzlib --disable-zlib
make
popd
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(./config.guess)"
make FILE_COMPILE="$(pwd)/build/src/file"
make DESTDIR="${LFS}" install
# Remove libtool archive
rm -v "${LFS}/usr/lib/libmagic.la" 2>/dev/null || true
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,35 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Findutils
# ============================================================================
# Purpose: Cross-compile GNU findutils (find, xargs, locate).
# Inputs: ${LFS}/sources/findutils-4.10.0.tar.xz
# Outputs: find, xargs in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.8
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="findutils"
VERSION="4.10.0"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--localstatedir=/var/lib/locate \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

37
toolchain/scripts/013-gawk.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Gawk
# ============================================================================
# Purpose: Cross-compile GNU awk (text processing, used by many build scripts).
# Inputs: ${LFS}/sources/gawk-5.4.0.tar.xz
# Outputs: gawk binary in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.9
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="gawk"
VERSION="5.4.0"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Ensure unneeded files are not installed
sed -i 's/extras//' Makefile.in
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

34
toolchain/scripts/014-grep.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Grep
# ============================================================================
# Purpose: Cross-compile GNU grep (pattern matching).
# Inputs: ${LFS}/sources/grep-3.14.tar.xz
# Outputs: grep in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.10
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="grep"
VERSION="3.14"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(./build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

33
toolchain/scripts/015-gzip.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Gzip
# ============================================================================
# Purpose: Cross-compile GNU gzip (compression/decompression).
# Inputs: ${LFS}/sources/gzip-1.14.tar.xz
# Outputs: gzip/gunzip in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.11
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="gzip"
VERSION="1.14"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

35
toolchain/scripts/016-make.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Make
# ============================================================================
# Purpose: Cross-compile GNU make (build automation).
# Inputs: ${LFS}/sources/make-4.4.1.tar.gz
# Outputs: make in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.12
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="make"
VERSION="4.4.1"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.gz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--without-guile \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

34
toolchain/scripts/017-patch.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Patch
# ============================================================================
# Purpose: Cross-compile GNU patch (applies diff files to originals).
# Inputs: ${LFS}/sources/patch-2.8.tar.xz
# Outputs: patch in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.13
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="patch"
VERSION="2.8"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

34
toolchain/scripts/018-sed.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Sed
# ============================================================================
# Purpose: Cross-compile GNU sed (stream editor).
# Inputs: ${LFS}/sources/sed-4.9.tar.xz
# Outputs: sed in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.14
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="sed"
VERSION="4.9"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(./build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

34
toolchain/scripts/019-tar.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Tar
# ============================================================================
# Purpose: Cross-compile GNU tar (archive utility).
# Inputs: ${LFS}/sources/tar-1.35.tar.xz
# Outputs: tar in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.15
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="tar"
VERSION="1.35"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)"
make
make DESTDIR="${LFS}" install
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

40
toolchain/scripts/020-xz.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Xz
# ============================================================================
# Purpose: Cross-compile xz utilities (LZMA compression). Many source
# tarballs use .tar.xz format, so this is essential.
# Inputs: ${LFS}/sources/xz-5.8.1.tar.gz
# Outputs: xz, xzcat, lzma etc. in ${LFS}/usr/bin/
# Ref: LFS 13.0 §6.16
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="xz"
VERSION="5.8.1"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Temporary Tool) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.gz"
cd "${PACKAGE}-${VERSION}"
./configure \
--prefix=/usr \
--host="${LFS_TGT}" \
--build="$(build-aux/config.guess)" \
--disable-static \
--docdir=/usr/share/doc/xz-${VERSION}
make
make DESTDIR="${LFS}" install
# Remove libtool archive
rm -v "${LFS}/usr/lib/liblzma.la" 2>/dev/null || true
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,53 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: Binutils Pass 2
# ============================================================================
# Purpose: Rebuild binutils with the temporary toolchain. This produces
# binutils that runs on the target and generates code for the target.
# Pass 1 ran on the host; Pass 2 runs on the target (via cross-compiler).
# Inputs: ${LFS}/sources/binutils-2.46.tar.xz
# Outputs: Updated binutils in ${LFS}/usr/
# Assumes: All Chapter 5 + Chapter 6 temp tools (006-020) complete
# Ref: LFS 13.0 §6.17
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="binutils"
VERSION="2.46"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Pass 2) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Remove libtool archive files that cause cross-compilation issues
sed '6009s/$add_dir//' -i ltmain.sh
mkdir -v build
cd build
../configure \
--prefix=/usr \
--build="$(../config.guess)" \
--host="${LFS_TGT}" \
--disable-nls \
--enable-shared \
--enable-gprofng=no \
--disable-werror \
--enable-64-bit-bfd \
--enable-new-dtags \
--enable-default-hash-style=gnu
make
make DESTDIR="${LFS}" install
# Remove libtool archives — they're harmful for cross-compiled libraries
rm -v "${LFS}"/usr/lib/lib{bfd,ctf,ctf-nobfd,opcodes,sframe}.{a,la} 2>/dev/null || true
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} Pass 2 complete ==="

View File

@@ -0,0 +1,89 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 6: GCC Pass 2
# ============================================================================
# Purpose: Rebuild GCC with the temporary toolchain. This produces a
# compiler that runs on the target and generates code for the target.
# Unlike Pass 1, this includes libstdc++, threading, and shared libs.
# Hardware-specific flags (-march=znver5) are STILL not applied here;
# they come when we build the final native GCC in the chroot.
# Inputs: ${LFS}/sources/gcc-15.2.0.tar.xz + mpfr, gmp, mpc
# Outputs: Full GCC in ${LFS}/usr/
# Assumes: All Chapter 5 + Chapter 6 packages (006-021) complete
# Ref: LFS 13.0 §6.18
# ============================================================================
set -euo pipefail
source "${LFS}/sources/darkforge-env.sh"
PACKAGE="gcc"
VERSION="15.2.0"
SRCDIR="${LFS}/sources"
echo "=== Building ${PACKAGE}-${VERSION} (Pass 2) ==="
cd "${SRCDIR}"
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Extract and link GCC's arithmetic library dependencies
tar -xf ../mpfr-4.2.2.tar.xz
mv -v mpfr-4.2.2 mpfr
tar -xf ../gmp-6.3.0.tar.xz
mv -v gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc
# Fix lib64 directory naming (same as Pass 1)
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' -i.orig gcc/config/i386/t-linux64
;;
esac
# Override the default build rule for libgcc and libstdc++ headers
# to use our target-specific header directory
sed '/thread_header =/s/@.*@/gthr-posix.h/' \
-i libgcc/Makefile.in libstdc++-v3/include/Makefile.in
mkdir -v build
cd build
# Configure GCC Pass 2
# Key differences from Pass 1:
# --with-build-sysroot=$LFS: use target sysroot during build
# --enable-default-pie/ssp: security hardening
# --disable-bootstrap: skip the 3-stage bootstrap (not building natively yet)
../configure \
--build="$(../config.guess)" \
--host="${LFS_TGT}" \
--target="${LFS_TGT}" \
LDFLAGS_FOR_TARGET=-L"${PWD}/${LFS_TGT}/libgcc" \
--prefix=/usr \
--with-build-sysroot="${LFS}" \
--enable-default-pie \
--enable-default-ssp \
--disable-nls \
--disable-multilib \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libsanitizer \
--disable-libssp \
--disable-libvtv \
--enable-languages=c,c++
make
make DESTDIR="${LFS}" install
# Create cc symlink (many build systems expect 'cc' to exist)
ln -sfv gcc "${LFS}/usr/bin/cc"
# Cleanup
cd "${SRCDIR}"
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} Pass 2 complete ==="
echo ""
echo ">>> Cross-compilation phase (Chapters 5+6) COMPLETE."
echo ">>> Next: Enter chroot environment (Chapter 7 scripts)."

View File

@@ -0,0 +1,91 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Chroot Environment Setup
# ============================================================================
# Purpose: Prepare the virtual filesystems and enter the chroot environment.
# This script must be run as ROOT on the host system. It mounts
# /dev, /proc, /sys, /run into the LFS tree and enters the chroot.
# Inputs: LFS environment variable
# Outputs: Running chroot environment with virtual filesystems mounted
# Assumes: All Chapter 5+6 scripts (001-022) complete successfully
# Ref: LFS 13.0 §7.2-7.4
# ============================================================================
set -euo pipefail
LFS="${LFS:-/mnt/darkforge}"
echo "=== DarkForge: Setting up chroot environment ==="
# Verify we're running as root
if [ "$(id -u)" -ne 0 ]; then
echo "ERROR: This script must be run as root."
exit 1
fi
# Change ownership from lfs user to root
# (the chroot tools now belong to the system)
chown -R root:root "${LFS}"/{usr,lib,var,etc,bin,sbin,tools} 2>/dev/null || true
case $(uname -m) in
x86_64) chown -R root:root "${LFS}/lib64" ;;
esac
# --- Create essential directory structure ------------------------------------
mkdir -pv "${LFS}"/{dev,proc,sys,run}
mkdir -pv "${LFS}"/{boot,home,mnt,opt,srv}
mkdir -pv "${LFS}/etc"/{opt,sysconfig}
mkdir -pv "${LFS}/lib/firmware"
mkdir -pv "${LFS}/media"/{floppy,cdrom}
mkdir -pv "${LFS}/usr"/{,local/}{include,src}
mkdir -pv "${LFS}/usr/local"/{bin,lib,sbin}
mkdir -pv "${LFS}/usr"/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv "${LFS}/usr"/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv "${LFS}/usr"/{,local/}share/man/man{1..8}
mkdir -pv "${LFS}/var"/{cache,local,log,mail,opt,spool}
mkdir -pv "${LFS}/var/lib"/{color,misc,locate}
ln -sfv /run "${LFS}/var/run"
ln -sfv /run/lock "${LFS}/var/lock"
install -dv -m 0750 "${LFS}/root"
install -dv -m 1777 "${LFS}/tmp" "${LFS}/var/tmp"
# --- Mount virtual kernel filesystems ----------------------------------------
# These expose the host kernel's interfaces inside the chroot
# Bind-mount /dev from host (gives us device nodes)
mount -v --bind /dev "${LFS}/dev"
# Mount devpts for pseudo-terminals
mount -vt devpts devpts -o gid=5,mode=0620 "${LFS}/dev/pts"
# Mount /proc (process info filesystem)
mount -vt proc proc "${LFS}/proc"
# Mount /sys (sysfs — kernel objects)
mount -vt sysfs sysfs "${LFS}/sys"
# Mount /run (tmpfs for runtime data)
mount -vt tmpfs tmpfs "${LFS}/run"
# Handle /dev/shm — some systems make it a symlink
if [ -h "${LFS}/dev/shm" ]; then
install -v -d -m 1777 "${LFS}/$(readlink "${LFS}/dev/shm")"
else
mount -vt tmpfs -o nosuid,nodev tmpfs "${LFS}/dev/shm"
fi
echo ""
echo "=== Virtual filesystems mounted ==="
echo ""
echo "To enter the chroot, run:"
echo ""
echo " chroot \"${LFS}\" /usr/bin/env -i \\"
echo " HOME=/root \\"
echo " TERM=\"\${TERM}\" \\"
echo " PS1='(darkforge chroot) \\u:\\w\\\$ ' \\"
echo " PATH=/usr/bin:/usr/sbin \\"
echo " MAKEFLAGS=\"-j32\" \\"
echo " /bin/bash --login"
echo ""
echo "Then run the chroot build scripts (024-xxx) from inside the chroot."

View File

@@ -0,0 +1,73 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Create Essential Files and Symlinks
# ============================================================================
# Purpose: Create the essential system files (/etc/passwd, /etc/group,
# log files) and symlinks that programs expect to exist.
# This script runs INSIDE the chroot environment.
# Inputs: None (creates files from scratch)
# Outputs: /etc/passwd, /etc/group, log files, essential symlinks
# Assumes: Running inside chroot (script 023 completed)
# Ref: LFS 13.0 §7.6
# ============================================================================
set -euo pipefail
echo "=== DarkForge: Creating essential files and symlinks ==="
# --- Create essential symlinks ------------------------------------------------
# Some programs hardcode paths to /bin/sh, /bin/cat, etc.
# With the unified /usr layout, these are already correct via symlinks
# created in 000-env-setup.sh, but verify:
[ -L /bin ] || { echo "ERROR: /bin should be a symlink to usr/bin"; exit 1; }
[ -L /lib ] || { echo "ERROR: /lib should be a symlink to usr/lib"; exit 1; }
[ -L /sbin ] || { echo "ERROR: /sbin should be a symlink to usr/sbin"; exit 1; }
# --- Create /etc/passwd -------------------------------------------------------
cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF
# --- Create /etc/group --------------------------------------------------------
cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
input:x:24:
mail:x:34:
kvm:x:61:
uuidd:x:80:
wheel:x:97:
users:x:999:
nogroup:x:65534:
EOF
# --- Create log files ---------------------------------------------------------
# These must exist for certain programs to function correctly
install -o root -g utmp -m 664 /dev/null /var/log/lastlog
install -o root -g root -m 600 /dev/null /var/log/btmp
install -o root -g root -m 664 /dev/null /var/log/faillog
install -o root -g utmp -m 664 /dev/null /var/log/wtmp
echo "=== Essential files and symlinks created ==="
echo ""
echo "Next: Run the chroot build scripts (025-xxx) to build additional tools."

View File

@@ -0,0 +1,34 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Gettext (Chroot)
# ============================================================================
# Purpose: Build gettext (internationalization framework). Many packages
# require gettext's autopoint, msgfmt, etc. during their build.
# Only the minimum needed tools are installed at this stage.
# Inputs: /sources/gettext-0.23.1.tar.xz
# Outputs: gettext utilities in /usr/
# Assumes: Running inside chroot
# Ref: LFS 13.0 §7.7
# ============================================================================
set -euo pipefail
PACKAGE="gettext"
VERSION="0.23.1"
echo "=== Building ${PACKAGE}-${VERSION} (Chroot) ==="
cd /sources
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure --disable-shared
make
# Only install the minimum needed programs
cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin
cd /sources
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

32
toolchain/scripts/026-bison.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Bison (Chroot)
# ============================================================================
# Purpose: Build bison (parser generator). Required by several packages
# that generate parsers during their build process.
# Inputs: /sources/bison-3.8.2.tar.xz
# Outputs: bison in /usr/bin/
# Assumes: Running inside chroot
# Ref: LFS 13.0 §7.8
# ============================================================================
set -euo pipefail
PACKAGE="bison"
VERSION="3.8.2"
echo "=== Building ${PACKAGE}-${VERSION} (Chroot) ==="
cd /sources
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure --prefix=/usr \
--docdir=/usr/share/doc/bison-${VERSION}
make
make install
cd /sources
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

40
toolchain/scripts/027-perl.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Perl (Chroot)
# ============================================================================
# Purpose: Build Perl (scripting language). Many build systems and test
# suites depend on Perl. This is a minimal build for bootstrapping.
# Inputs: /sources/perl-5.40.2.tar.xz
# Outputs: perl in /usr/bin/
# Assumes: Running inside chroot
# Ref: LFS 13.0 §7.9
# ============================================================================
set -euo pipefail
PACKAGE="perl"
VERSION="5.40.2"
echo "=== Building ${PACKAGE}-${VERSION} (Chroot) ==="
cd /sources
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
sh Configure -des \
-D prefix=/usr \
-D vendorprefix=/usr \
-D useshrplib \
-D privlib=/usr/lib/perl5/5.40/core_perl \
-D archlib=/usr/lib/perl5/5.40/core_perl \
-D sitelib=/usr/lib/perl5/5.40/site_perl \
-D sitearch=/usr/lib/perl5/5.40/site_perl \
-D vendorlib=/usr/lib/perl5/5.40/vendor_perl \
-D vendorarch=/usr/lib/perl5/5.40/vendor_perl
make
make install
cd /sources
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

33
toolchain/scripts/028-python.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Python (Chroot)
# ============================================================================
# Purpose: Build Python 3 (scripting language). Required by meson and
# many modern build systems. Minimal build — no pip, no SSL.
# Inputs: /sources/Python-3.13.3.tar.xz
# Outputs: python3 in /usr/bin/
# Assumes: Running inside chroot
# Ref: LFS 13.0 §7.10
# ============================================================================
set -euo pipefail
PACKAGE="Python"
VERSION="3.13.3"
echo "=== Building ${PACKAGE}-${VERSION} (Chroot) ==="
cd /sources
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure --prefix=/usr \
--enable-shared \
--without-ensurepip
make
make install
cd /sources
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Texinfo (Chroot)
# ============================================================================
# Purpose: Build texinfo (documentation tools). Provides makeinfo which
# is needed by many GNU packages to process their documentation.
# Inputs: /sources/texinfo-7.3.tar.xz
# Outputs: makeinfo, info, install-info in /usr/bin/
# Assumes: Running inside chroot
# Ref: LFS 13.0 §7.11
# ============================================================================
set -euo pipefail
PACKAGE="texinfo"
VERSION="7.3"
echo "=== Building ${PACKAGE}-${VERSION} (Chroot) ==="
cd /sources
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
./configure --prefix=/usr
make
make install
cd /sources
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,49 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Util-linux (Chroot)
# ============================================================================
# Purpose: Build util-linux (essential system utilities: mount, fdisk,
# lsblk, etc.). Minimal build for bootstrapping — the full build
# happens in Phase 3.
# Inputs: /sources/util-linux-2.40.4.tar.xz
# Outputs: util-linux programs and libraries in /usr/
# Assumes: Running inside chroot
# Ref: LFS 13.0 §7.12
# ============================================================================
set -euo pipefail
PACKAGE="util-linux"
VERSION="2.40.4"
echo "=== Building ${PACKAGE}-${VERSION} (Chroot) ==="
cd /sources
tar -xf "${PACKAGE}-${VERSION}.tar.xz"
cd "${PACKAGE}-${VERSION}"
# Create the adjtime file location
mkdir -pv /var/lib/hwclock
./configure \
--libdir=/usr/lib \
--runstatedir=/run \
--disable-chfn-chsh \
--disable-login \
--disable-nologin \
--disable-su \
--disable-setpriv \
--disable-runuser \
--disable-pylibmount \
--disable-static \
--disable-liblastlog2 \
--without-python \
ADJTIME_PATH=/var/lib/hwclock/adjtime \
--docdir=/usr/share/doc/util-linux-${VERSION}
make
make install
cd /sources
rm -rf "${PACKAGE}-${VERSION}"
echo "=== ${PACKAGE}-${VERSION} complete ==="

View File

@@ -0,0 +1,68 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0, Chapter 7: Cleanup Temporary Tools
# ============================================================================
# Purpose: Clean up the temporary toolchain now that we have native tools
# in the chroot. Remove documentation, static libraries, and the
# cross-compiler tools directory.
# Inputs: None
# Outputs: Cleaned filesystem, removed /tools
# Assumes: Running inside chroot, all chroot builds (024-030) complete
# Ref: LFS 13.0 §7.13
# ============================================================================
set -euo pipefail
echo "=== DarkForge: Cleaning up temporary tools ==="
# Remove documentation installed by temporary packages
rm -rf /usr/share/{info,man,doc}/*
# Remove libtool .la files (they cause problems in final builds)
find /usr/{lib,libexec} -name \*.la -delete 2>/dev/null || true
# Remove the cross-compiler toolchain directory
# We no longer need it — native compiler is in /usr/bin/gcc
rm -rf /tools
echo "=== Cleanup complete ==="
echo ""
echo ">>> PHASE 0 COMPLETE!"
echo ""
echo "The chroot environment now has:"
echo " - Native GCC ${GCC_VERSION:-15.2.0} compiler"
echo " - GNU binutils"
echo " - glibc"
echo " - Bash, coreutils, make, and essential build tools"
echo " - Perl, Python 3, bison, gettext, texinfo"
echo " - util-linux"
echo ""
echo "Exit criteria check: Can we compile a Hello World?"
echo ""
# --- Exit criteria test -------------------------------------------------------
cat > /tmp/hello.c << 'EOF'
#include <stdio.h>
int main(void) {
printf("DarkForge Linux: Phase 0 toolchain bootstrap successful!\n");
return 0;
}
EOF
echo "Compiling test program..."
gcc -o /tmp/hello /tmp/hello.c
echo "Running test program..."
/tmp/hello
# Verify the binary is dynamically linked to our glibc
echo ""
echo "Binary details:"
file /tmp/hello
ldd /tmp/hello
# Cleanup test
rm -f /tmp/hello /tmp/hello.c
echo ""
echo ">>> Phase 0 exit criteria: PASSED"
echo ">>> Ready to proceed to Phase 1 (dpack core)."

127
toolchain/scripts/build-all.sh Executable file
View File

@@ -0,0 +1,127 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — Phase 0: Master Build Runner
# ============================================================================
# Purpose: Run all toolchain build scripts in sequence with logging.
# This is a convenience wrapper that executes each script,
# logs output, and stops on any failure.
# Inputs: LFS environment variable, all source tarballs downloaded
# Outputs: Complete cross-toolchain and temporary tools
# Assumes: Running as 'lfs' user (scripts 001-022), root for 023+
# ============================================================================
set -euo pipefail
LFS="${LFS:-/mnt/darkforge}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="${SCRIPT_DIR}/../logs"
mkdir -p "${LOG_DIR}"
# Color output helpers
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
run_script() {
local script="$1"
local name
name=$(basename "${script}" .sh)
local logfile="${LOG_DIR}/${name}.log"
echo -e "${YELLOW}>>> [$(date '+%H:%M:%S')] Starting: ${name}${NC}"
if bash "${script}" 2>&1 | tee "${logfile}"; then
echo -e "${GREEN}>>> [$(date '+%H:%M:%S')] PASSED: ${name}${NC}"
echo ""
else
echo -e "${RED}>>> [$(date '+%H:%M:%S')] FAILED: ${name}${NC}"
echo "Log file: ${logfile}"
echo "Fix the issue and re-run this script to continue."
exit 1
fi
}
echo "============================================================"
echo " DarkForge Linux — Phase 0 Toolchain Bootstrap"
echo " Target: AMD Ryzen 9 9950X3D (Zen 5)"
echo " LFS: ${LFS}"
echo " Logs: ${LOG_DIR}/"
echo "============================================================"
echo ""
# --- Phase selection ---
PHASE="${1:-all}"
case "${PHASE}" in
cross|all)
echo "=== CHAPTER 5: Cross-Toolchain ==="
run_script "${SCRIPT_DIR}/001-binutils-pass1.sh"
run_script "${SCRIPT_DIR}/002-gcc-pass1.sh"
run_script "${SCRIPT_DIR}/003-linux-headers.sh"
run_script "${SCRIPT_DIR}/004-glibc.sh"
run_script "${SCRIPT_DIR}/005-libstdcxx.sh"
echo ""
;;&
temp|all)
echo "=== CHAPTER 6: Temporary Tools ==="
run_script "${SCRIPT_DIR}/006-m4.sh"
run_script "${SCRIPT_DIR}/007-ncurses.sh"
run_script "${SCRIPT_DIR}/008-bash.sh"
run_script "${SCRIPT_DIR}/009-coreutils.sh"
run_script "${SCRIPT_DIR}/010-diffutils.sh"
run_script "${SCRIPT_DIR}/011-file.sh"
run_script "${SCRIPT_DIR}/012-findutils.sh"
run_script "${SCRIPT_DIR}/013-gawk.sh"
run_script "${SCRIPT_DIR}/014-grep.sh"
run_script "${SCRIPT_DIR}/015-gzip.sh"
run_script "${SCRIPT_DIR}/016-make.sh"
run_script "${SCRIPT_DIR}/017-patch.sh"
run_script "${SCRIPT_DIR}/018-sed.sh"
run_script "${SCRIPT_DIR}/019-tar.sh"
run_script "${SCRIPT_DIR}/020-xz.sh"
run_script "${SCRIPT_DIR}/021-binutils-pass2.sh"
run_script "${SCRIPT_DIR}/022-gcc-pass2.sh"
echo ""
echo "=== Cross-compilation phases complete ==="
echo ">>> Next: Run 023-chroot-setup.sh as ROOT"
echo ">>> Then enter chroot and run 024-031 scripts"
;;&
chroot|all)
if [ "${PHASE}" = "all" ]; then
echo ""
echo "=== STOP: Chapters 5+6 are done. ==="
echo "Run the following as ROOT to continue:"
echo ""
echo " sudo bash ${SCRIPT_DIR}/023-chroot-setup.sh"
echo ""
echo "Then enter the chroot and run:"
echo " bash /sources/toolchain-scripts/024-chroot-essentials.sh"
echo " bash /sources/toolchain-scripts/025-gettext.sh"
echo " bash /sources/toolchain-scripts/026-bison.sh"
echo " bash /sources/toolchain-scripts/027-perl.sh"
echo " bash /sources/toolchain-scripts/028-python.sh"
echo " bash /sources/toolchain-scripts/029-texinfo.sh"
echo " bash /sources/toolchain-scripts/030-util-linux.sh"
echo " bash /sources/toolchain-scripts/031-cleanup.sh"
fi
;;
*)
echo "Usage: $0 [cross|temp|chroot|all]"
echo ""
echo " cross - Run Chapter 5 (cross-toolchain) only"
echo " temp - Run Chapter 6 (temporary tools) only"
echo " chroot - Show Chapter 7 (chroot) instructions"
echo " all - Run everything (default)"
exit 0
;;
esac
echo ""
echo "============================================================"
echo " Build complete. Check logs in: ${LOG_DIR}/"
echo "============================================================"