diff --git a/.claude/skills/gcc-example/SKILL.md b/.claude/skills/gcc-example/SKILL.md index 45ef8e2..3c8667a 100644 --- a/.claude/skills/gcc-example/SKILL.md +++ b/.claude/skills/gcc-example/SKILL.md @@ -11,23 +11,17 @@ The `examples/bsp/` BSP directory builds GCC and binutils from source using putu ```bash cd /path/to/pup/examples/bsp && \ - make -f Makefile.pup SRCDIR=../../source-root -``` - -Or directly with putup: - -```bash -cd /path/to/pup/examples/bsp && \ + scripts/download-source.sh ../../source-root && \ putup configure --config configs/x86_64-linux.config \ - -C . -S ../../source-root -B ../../build-gcc + -C . -S ../../source-root -B ../../build-gcc && \ putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) ``` - `-C .` — config tree (BSP root: Tupfiles, tup.config, Tuprules.tup) -- `-S ../source-root` — assembled source tree (gcc/ + binutils/ subdirs, read-only) -- `-B ../build-gcc` — build output directory +- `-S ../../source-root` — assembled source tree (gcc/ + binutils/ subdirs, read-only) +- `-B ../../build-gcc` — build output directory -After editing any `tup.config`, re-run `putup configure` to propagate to the build dir. +After editing any `defaults.config`, re-run `putup configure` to propagate to the build dir. ## Architecture @@ -166,7 +160,7 @@ The `tm-preds.h` is generated by `genpreds -h` and declares predicate functions Each library (gmp, mpfr, mpc, libiberty, libcpp, libdecnumber, libbacktrace) has: - Its own `Tuprules.tup` with `?=` defaults -- Its own `tup.config` for library-specific config +- Its own `defaults.config` for library-specific config (copied to `tup.config` by Tupfile rule) - Its own `Tupfile` for compilation rules The root `Tuprules.tup` sets prefixed DIR vars (`GMP_DIR = gmp`, etc.) that override the `?=` defaults when building as part of the larger project. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26499fc..cd7a3de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -185,10 +185,13 @@ jobs: run: chmod +x build/putup - name: Download source working-directory: examples/bsp - run: make -f Makefile.pup download-source SRCDIR=../../source-root + run: scripts/download-source.sh ../../source-root + - name: Configure + working-directory: examples/bsp + run: ../../build/putup configure --config configs/x86_64-linux.config -C . -S ../../source-root -B ../../build-gcc - name: Build working-directory: examples/bsp - run: make -f Makefile.pup PUTUP=../../build/putup SRCDIR=../../source-root + run: ../../build/putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) - name: Smoke test cc1 run: | echo 'int main() { return 0; }' > /tmp/test.c diff --git a/docs/plans/2026-03-09-eliminate-makefile-preprocessing-design.md b/docs/plans/2026-03-09-eliminate-makefile-preprocessing-design.md new file mode 100644 index 0000000..f3bed5f --- /dev/null +++ b/docs/plans/2026-03-09-eliminate-makefile-preprocessing-design.md @@ -0,0 +1,164 @@ +# Eliminate Makefile.pup Preprocessing + +## Problem + +The BSP example (`examples/bsp/`) uses `Makefile.pup` as a wrapper that runs +preprocessing steps before invoking putup. Two targets mutate the config tree +at `make` time: + +1. **`setup-host-configs`** — copies platform-specific `configs/host-darwin/*.config` + files over `defaults.config` files in the source tree. Mutates 9 config files + based on the `HOST` variable. + +2. **`resolve-mpn`** — runs `scripts/resolve-mpn.sh` to scan the GMP source tree + for assembly files, then writes `gcc/gmp/mpn/defaults.config` and appends + MPN-dependent variables to `gcc/gmp/defaults.config`. + +This violates putup's design: the build system should be the single source of +truth for build logic. Preprocessing steps that mutate the config tree are +invisible to putup's dependency tracking and make builds non-reproducible. + +## Design Goals + +- **Zero preprocessing**: `putup configure && putup` is the complete build command +- **Config tree is immutable**: no step writes into the `-C` tree at build time +- **Platform selection via `--config`**: the only knob for platform targeting +- **Scoped config merging**: child `defaults.config` provides library defaults; + parent `--config` overrides on collision + +## Solution + +### 1. Eliminate `setup-host-configs` + +Different libraries need different values for the same `CONFIG_` key on darwin +(e.g., `CONFIG_HAVE_ALLOCA_H` is `n` for binutils but `1` for gmp). This means +per-library overrides cannot all live in the root platform config — scoped merge +would force one value on all libraries. + +Instead, libraries with platform-specific configs get a `defaults-darwin.config` +alongside their `defaults.config`. The Tupfile selects via `ifeq`: + +```tup +ifeq (@(HOST_OS),darwin) +: defaults-darwin.config |> ^ INSTALL %o^ cp %f %o |> tup.config +else +: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +endif +``` + +Only 3 libraries have meaningful differences: **binutils**, **gcc**, **libcpp**. +The other 6 libraries have identical configs across platforms (or the existing +defaults.config already works on both). + +For **libbacktrace**, the only difference is `BACKTRACE_FORMAT` (elf vs macho). +This is already in the root platform config (`x86_64-linux.config`), so the +darwin platform config just needs `CONFIG_BACKTRACE_FORMAT=macho`. + +**Create**: `defaults-darwin.config` in binutils/, gcc/gcc/, gcc/libcpp/ +**Modify**: Those 3 Tupfiles to add `ifeq` selection +**Modify**: `darwin-x86_64-linux.config` — add `CONFIG_BACKTRACE_FORMAT=macho` +**Delete**: `examples/bsp/configs/host-darwin/` (entire directory, 9 files) + +### 2. Make `resolve-mpn` a config-generating Tupfile rule + +Add `CONFIG_MPN_CPU` to the platform configs (default: `generic`). The GMP mpn +Tupfile reads `@(MPN_CPU)` and runs `resolve-mpn.sh` as a config-generating rule: + +```tup +# In gcc/gmp/mpn/Tupfile: +: |> ^ RESOLVE-MPN %o^ $(SCRIPTS)/resolve-mpn.sh @(MPN_CPU) $(GMP_SRC)/mpn > %o |> tup.config +``` + +For the parent-scope variables (`GMP_MPARAM`, `ASM_ENABLED`), the GMP Tupfile's +config rule copies `defaults.config` and appends MPN-dependent lines computed +from `@(MPN_CPU)`: + +```tup +# In gcc/gmp/Tupfile: +: defaults.config |> ^ GEN %o^ cp %f %o && \ + cpu="@(MPN_CPU)"; \ + if [ -z "$cpu" ] || [ "$cpu" = "generic" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> %o; \ + echo "CONFIG_NO_ASM=1" >> %o; \ + else \ + arch="${cpu%%/*}"; \ + if [ -f "mpn/$arch/gmp-mparam.h" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/$arch/gmp-mparam.h" >> %o; \ + else \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> %o; \ + fi; \ + echo "CONFIG_ASM_ENABLED=y" >> %o; \ + fi |> tup.config +``` + +**Move** `resolve-mpn.sh` stays in `scripts/` — it becomes a build-time tool +invoked by the Tupfile rule rather than a Makefile preprocessing step. + +**Delete**: `examples/bsp/gcc/gmp/mpn/defaults.config` (fully generated) + +**Modify**: `examples/bsp/gcc/gmp/defaults.config` — remove the 3 MPN-dependent +lines (`GMP_MPARAM`, `ASM_ENABLED`, `NO_ASM`), which are now generated. + +### 3. Remove `Makefile.pup` + +With preprocessing eliminated, the Makefile wrapper serves no purpose. The +canonical build command becomes: + +```bash +putup configure --config configs/x86_64-linux.config -C . -S ../../source-root -B ../../build-gcc +putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) +``` + +Extract the download logic (`download-source`, `download-binutils`) into a +standalone `scripts/download-source.sh` for users who need to fetch tarballs. + +**Delete**: `examples/bsp/Makefile.pup` + +**Create**: `examples/bsp/scripts/download-source.sh` (download logic only) + +### 4. Update CI + +Replace `make -f Makefile.pup configure` with direct putup invocations in +`.github/workflows/ci.yml`. The `build-gcc-bsp` job becomes: + +```yaml +- name: Download source + run: cd examples/bsp && scripts/download-source.sh + +- name: Configure + run: cd examples/bsp && putup configure --config configs/x86_64-linux.config -C . -S ../../source-root -B ../../build-gcc + +- name: Build + run: cd examples/bsp && putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) +``` + +## File Changes + +| # | File | Action | +|---|------|--------| +| 1 | `examples/bsp/Makefile.pup` | Delete | +| 2 | `examples/bsp/scripts/resolve-mpn.sh` | Keep (becomes build-time tool) | +| 3 | `examples/bsp/scripts/download-source.sh` | Create (extracted from Makefile.pup) | +| 4 | `examples/bsp/configs/host-darwin/` (9 files) | Delete directory | +| 5 | `examples/bsp/configs/darwin-x86_64-linux.config` | Modify — add backtrace override, update comments | +| 6 | `examples/bsp/configs/x86_64-linux.config` | Modify — add `CONFIG_MPN_CPU=generic` | +| 7 | `examples/bsp/binutils/defaults-darwin.config` | Create (from host-darwin/binutils.config) | +| 8 | `examples/bsp/binutils/Tupfile` | Modify — add ifeq darwin selection | +| 9 | `examples/bsp/gcc/gcc/defaults-darwin.config` | Create (from host-darwin/gcc.config) | +| 10 | `examples/bsp/gcc/gcc/Tupfile` | Modify — add ifeq darwin selection | +| 11 | `examples/bsp/gcc/libcpp/defaults-darwin.config` | Create (from host-darwin/libcpp.config) | +| 12 | `examples/bsp/gcc/libcpp/Tupfile` | Modify — add ifeq darwin selection | +| 13 | `examples/bsp/gcc/gmp/defaults.config` | Modify — remove MPN-dependent lines | +| 14 | `examples/bsp/gcc/gmp/Tupfile` | Modify — config rule computes MPN vars | +| 15 | `examples/bsp/gcc/gmp/mpn/defaults.config` | Delete | +| 16 | `examples/bsp/gcc/gmp/mpn/Tupfile` | Modify — config rule runs resolve-mpn.sh | +| 17 | `.github/workflows/ci.yml` | Modify — direct putup commands | +| 18 | `docs/reference.md` | Modify — update Makefile.pup references | +| 19 | `.claude/skills/gcc-example/SKILL.md` | Modify — update build commands | + +## Verification + +1. `putup configure --config configs/x86_64-linux.config -C . -S ../../source-root -B ../../build-gcc` succeeds +2. `putup -C . -S ../../source-root -B ../../build-gcc` builds successfully +3. CI `build-gcc-bsp` job passes +4. Darwin cross-compile config contains all necessary overrides diff --git a/docs/plans/2026-03-09-eliminate-makefile-preprocessing.md b/docs/plans/2026-03-09-eliminate-makefile-preprocessing.md new file mode 100644 index 0000000..4053d09 --- /dev/null +++ b/docs/plans/2026-03-09-eliminate-makefile-preprocessing.md @@ -0,0 +1,460 @@ +# Eliminate Makefile.pup Preprocessing — Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Remove all preprocessing from the BSP example so `putup configure && putup` is the complete build — no Makefile wrapper, no external scripts mutating the config tree. + +**Architecture:** Two Makefile preprocessing steps (`setup-host-configs`, `resolve-mpn`) become Tupfile-driven. Darwin configs use per-library `ifeq` selection. MPN source resolution becomes a config-generating rule. `Makefile.pup` is deleted; download logic moves to a standalone script. + +**Tech Stack:** Tupfile rules, shell scripts, putup config-generating rules, CI YAML. + +**Design doc:** `docs/plans/2026-03-09-eliminate-makefile-preprocessing-design.md` + +--- + +### Task 1: Eliminate setup-host-configs — per-library darwin configs + +The `setup-host-configs` Makefile target copies `configs/host-darwin/*.config` over each library's `defaults.config` when `HOST=darwin`. This mutates the config tree. + +**Replacement:** Libraries with platform-specific differences get a `defaults-darwin.config` file. The Tupfile uses `ifeq (@(HOST_OS),darwin)` to select which config to copy. `@(HOST_OS)` comes from the root platform config (e.g., `darwin-x86_64-linux.config` has `CONFIG_HOST_OS=darwin`). + +**Only 3 libraries need darwin variants** (the others have identical configs across platforms): +- binutils (HAVE_ALLOCA_H, DECL_BASENAME, DECL_SBRK, DECL_ENVIRON differ) +- gcc/gcc (MALLINFO, POSIX_FALLOCATE, GNU_AS/LD, asm features differ) +- gcc/libcpp (*_unlocked functions, DECL_BASENAME, SIZEOF_DEV_T differ) + +For libbacktrace, the only darwin difference is `BACKTRACE_FORMAT=macho` — this goes in the root darwin platform config since no other library uses that key. + +**Files:** +- Create: `examples/bsp/binutils/defaults-darwin.config` +- Create: `examples/bsp/gcc/gcc/defaults-darwin.config` +- Create: `examples/bsp/gcc/libcpp/defaults-darwin.config` +- Modify: `examples/bsp/binutils/Tupfile:1-2` +- Modify: `examples/bsp/gcc/gcc/Tupfile:1-2` +- Modify: `examples/bsp/gcc/libcpp/Tupfile:1-2` +- Modify: `examples/bsp/configs/darwin-x86_64-linux.config` +- Delete: `examples/bsp/configs/host-darwin/` (entire directory) + +**Step 1: Create defaults-darwin.config for binutils** + +Copy `configs/host-darwin/binutils.config` to `binutils/defaults-darwin.config`: + +```bash +cp examples/bsp/configs/host-darwin/binutils.config examples/bsp/binutils/defaults-darwin.config +``` + +**Step 2: Create defaults-darwin.config for gcc** + +```bash +cp examples/bsp/configs/host-darwin/gcc.config examples/bsp/gcc/gcc/defaults-darwin.config +``` + +**Step 3: Create defaults-darwin.config for libcpp** + +```bash +cp examples/bsp/configs/host-darwin/libcpp.config examples/bsp/gcc/libcpp/defaults-darwin.config +``` + +**Step 4: Update binutils/Tupfile — ifeq darwin selection** + +Replace line 2: +```tup +: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +``` + +With: +```tup +ifeq (@(HOST_OS),darwin) +: defaults-darwin.config |> ^ INSTALL %o^ cp %f %o |> tup.config +else +: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +endif +``` + +**Step 5: Update gcc/gcc/Tupfile — ifeq darwin selection** + +Same pattern as step 4: replace line 2 with the ifeq block. + +**Step 6: Update gcc/libcpp/Tupfile — ifeq darwin selection** + +Same pattern as step 4: replace line 2 with the ifeq block. + +**Step 7: Update darwin-x86_64-linux.config** + +Add libbacktrace override and update comments. The file should become: + +``` +# GCC Libraries - macOS host, x86-64 Linux target (cross-compiler) +# +# Usage: +# putup configure --config configs/darwin-x86_64-linux.config \ +# -C . -S ../../source-root -B ../../build-gcc +# +# Builds cc1 on macOS (Apple Silicon) that generates x86_64 Linux code. +# Host compiler is Apple Clang; target config reuses x86_64-pc-linux-gnu. + +# Toolchain (Apple Clang as host compiler) +CONFIG_CC=clang +CONFIG_CXX=clang++ +CONFIG_AR=ar +CONFIG_HOSTCC=clang++ + +# Platform selection +CONFIG_TARGET=x86_64-pc-linux-gnu +CONFIG_HOST_OS=darwin +CONFIG_PLATFORM_LDFLAGS=-lm -lpthread -lz -liconv +CONFIG_EXTRA_MODES_FILE=config/i386/i386-modes.def +CONFIG_DECIMAL_FORMAT=bid + +# MPN CPU target (generic for cross-compile) +CONFIG_MPN_CPU=generic + +# libbacktrace: Mach-O format on macOS +CONFIG_BACKTRACE_FORMAT=macho +``` + +**Step 8: Delete host-darwin/ directory** + +```bash +rm -rf examples/bsp/configs/host-darwin/ +``` + +**Step 9: Commit** + +```bash +git add examples/bsp/binutils/defaults-darwin.config \ + examples/bsp/gcc/gcc/defaults-darwin.config \ + examples/bsp/gcc/libcpp/defaults-darwin.config \ + examples/bsp/binutils/Tupfile \ + examples/bsp/gcc/gcc/Tupfile \ + examples/bsp/gcc/libcpp/Tupfile \ + examples/bsp/configs/darwin-x86_64-linux.config +git rm -rf examples/bsp/configs/host-darwin/ +git commit -m "bsp: eliminate setup-host-configs — use ifeq for darwin config selection + +Libraries with darwin-specific configs (binutils, gcc, libcpp) get a +defaults-darwin.config alongside their defaults.config. The Tupfile +selects via ifeq (@(HOST_OS),darwin). No more Makefile preprocessing. + +Co-Authored-By: Claude Opus 4.6 " +``` + +--- + +### Task 2: Make resolve-mpn a config-generating Tupfile rule + +The `resolve-mpn` Makefile target runs `scripts/resolve-mpn.sh` as a preprocessing step to generate `gcc/gmp/mpn/defaults.config` and append MPN-dependent lines to `gcc/gmp/defaults.config`. This becomes Tupfile-driven. + +**Key insight:** During `putup configure`, only the root `tup.config` is active for `@()` variable resolution. So `CONFIG_MPN_CPU` must be in the root platform config for the config-generating rules to read it. + +**Files:** +- Modify: `examples/bsp/configs/x86_64-linux.config` +- Modify: `examples/bsp/gcc/gmp/defaults.config:100-101` +- Modify: `examples/bsp/gcc/gmp/Tupfile:2` +- Modify: `examples/bsp/gcc/gmp/mpn/Tupfile:1-2` +- Delete: `examples/bsp/gcc/gmp/mpn/defaults.config` + +**Step 1: Add CONFIG_MPN_CPU to x86_64-linux.config** + +Append after the `CONFIG_BACKTRACE_ELF_SIZE=64` line: + +``` +# MPN CPU target (generic = pure C, x86_64 = arch asm, x86_64/core2 = CPU asm) +CONFIG_MPN_CPU=generic +``` + +**Step 2: Remove MPN-dependent lines from gmp/defaults.config** + +Remove the last 2 lines of `examples/bsp/gcc/gmp/defaults.config`: + +``` +CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h +CONFIG_NO_ASM=1 +``` + +These are now generated by the Tupfile config rule. + +**Step 3: Update gmp/Tupfile config rule** + +Replace line 2: +```tup +: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +``` + +With a rule that copies defaults.config and appends MPN-dependent variables: +```tup +: defaults.config |> ^ GEN %o^ cp %f %o && \ + cpu="@(MPN_CPU)"; \ + if [ -z "$cpu" ] || [ "$cpu" = "generic" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> %o; \ + echo "CONFIG_NO_ASM=1" >> %o; \ + else \ + arch="${cpu%%/*}"; \ + if [ -f "mpn/$arch/gmp-mparam.h" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/$arch/gmp-mparam.h" >> %o; \ + else \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> %o; \ + fi; \ + echo "CONFIG_ASM_ENABLED=y" >> %o; \ + fi |> tup.config +``` + +**Why this works:** `@(MPN_CPU)` is expanded by putup at parse time from the root config. The shell sees a literal string (e.g., `cpu="generic"` or `cpu="x86_64/core2"`). The `${cpu%%/*}` pattern strips the CPU subdir to get the arch. CWD at execution time is source-tree `gcc/gmp/`, so `mpn/$arch/gmp-mparam.h` resolves correctly. + +**Step 4: Update gmp/mpn/Tupfile config rule** + +Replace line 2: +```tup +: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +``` + +With: +```tup +: $(S)/scripts/resolve-mpn.sh |> ^ RESOLVE-MPN %o^ sh %f @(MPN_CPU) . > %o |> tup.config +``` + +**How this works:** +- `$(S)` = BSP root (set in root `Tuprules.tup` as `$(TUP_CWD)`) +- `$(S)/scripts/resolve-mpn.sh` references the config tree's script file +- putup resolves the input to the correct cross-tree path (`%f` works via PR #11 fix) +- `sh %f` runs the script regardless of execute permissions +- `@(MPN_CPU)` is expanded at parse time from root config (e.g., `generic`) +- `.` is the mpn source directory — CWD at execution time is source-tree `gcc/gmp/mpn/` +- stdout redirects to `%o` which becomes `tup.config` + +**Step 5: Delete gmp/mpn/defaults.config** + +```bash +rm examples/bsp/gcc/gmp/mpn/defaults.config +``` + +**Step 6: Commit** + +```bash +git add examples/bsp/configs/x86_64-linux.config \ + examples/bsp/gcc/gmp/defaults.config \ + examples/bsp/gcc/gmp/Tupfile \ + examples/bsp/gcc/gmp/mpn/Tupfile +git rm examples/bsp/gcc/gmp/mpn/defaults.config +git commit -m "bsp: make resolve-mpn a config-generating Tupfile rule + +MPN source resolution (generic C vs arch-specific asm) is now driven +by @(MPN_CPU) in the platform config, read by Tupfile rules during +putup configure. No more Makefile preprocessing step. + +Co-Authored-By: Claude Opus 4.6 " +``` + +--- + +### Task 3: Remove Makefile.pup — extract download script + +With both preprocessing steps eliminated, `Makefile.pup` has no purpose. Extract the download logic into a standalone shell script. + +**Files:** +- Create: `examples/bsp/scripts/download-source.sh` +- Delete: `examples/bsp/Makefile.pup` + +**Step 1: Create download-source.sh** + +```bash +#!/bin/sh +# download-source.sh — Download and assemble GCC + binutils source trees +# +# Usage: scripts/download-source.sh [SRCDIR] +# +# Environment: +# GCC_VERSION GCC version to download (default: 15.2.0) +# BINUTILS_VERSION binutils version to download (default: 2.44) + +set -e + +GCC_VERSION=${GCC_VERSION:-15.2.0} +BINUTILS_VERSION=${BINUTILS_VERSION:-2.44} +SRCDIR=${1:-../../source-root} + +# Download binutils +if [ ! -d "$SRCDIR/binutils" ]; then + echo "Downloading binutils $BINUTILS_VERSION..." + mkdir -p "$SRCDIR/binutils" + curl -L "https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.xz" \ + | tar xJ --strip-components=1 -C "$SRCDIR/binutils" +else + echo "$SRCDIR/binutils already exists" +fi + +# Download GCC + prerequisites +if [ ! -d "$SRCDIR/gcc" ]; then + echo "Downloading GCC $GCC_VERSION..." + mkdir -p "$SRCDIR/gcc" + curl -L "https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.xz" \ + | tar xJ --strip-components=1 -C "$SRCDIR/gcc" + cd "$SRCDIR/gcc" && ./contrib/download_prerequisites +else + echo "$SRCDIR/gcc already exists" +fi +``` + +Make executable: +```bash +chmod +x examples/bsp/scripts/download-source.sh +``` + +**Step 2: Delete Makefile.pup** + +```bash +rm examples/bsp/Makefile.pup +``` + +**Step 3: Commit** + +```bash +git add examples/bsp/scripts/download-source.sh +git rm examples/bsp/Makefile.pup +git commit -m "bsp: remove Makefile.pup, extract download script + +The canonical build command is now: + putup configure --config configs/x86_64-linux.config -C . -S ../src -B ../build + putup -C . -S ../src -B ../build -j\$(nproc) + +Co-Authored-By: Claude Opus 4.6 " +``` + +--- + +### Task 4: Update CI workflow + +Replace `make -f Makefile.pup` with direct putup invocations. + +**Files:** +- Modify: `.github/workflows/ci.yml:173-196` + +**Step 1: Update build-gcc-bsp job** + +Replace the `Download source` and `Build` steps (lines 186-196): + +```yaml + build-gcc-bsp: + needs: build-linux + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-linux + path: build/ + - name: Fix permissions + run: chmod +x build/putup + - name: Download source + working-directory: examples/bsp + run: scripts/download-source.sh ../../source-root + - name: Configure + working-directory: examples/bsp + run: ../../build/putup configure --config configs/x86_64-linux.config -C . -S ../../source-root -B ../../build-gcc + - name: Build + working-directory: examples/bsp + run: ../../build/putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) + - name: Smoke test cc1 + run: | + echo 'int main() { return 0; }' > /tmp/test.c + build-gcc/gcc/gcc/cc1 /tmp/test.c -quiet -o /tmp/test.s + grep 'GCC.*15.2.0' /tmp/test.s +``` + +**Step 2: Commit** + +```bash +git add .github/workflows/ci.yml +git commit -m "ci: use direct putup commands for BSP build + +Co-Authored-By: Claude Opus 4.6 " +``` + +--- + +### Task 5: Update documentation and skill files + +**Files:** +- Modify: `.claude/skills/gcc-example/SKILL.md:12-15` +- Modify: `docs/reference.md` (grep for Makefile.pup references) + +**Step 1: Update SKILL.md build commands** + +Replace lines 12-15 (the `make -f Makefile.pup` section): + +```markdown +## Build Command + +```bash +cd /path/to/pup/examples/bsp && \ + scripts/download-source.sh ../../source-root && \ + putup configure --config configs/x86_64-linux.config \ + -C . -S ../../source-root -B ../../build-gcc && \ + putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) +``` + +Or step by step: + +```bash +cd /path/to/pup/examples/bsp && \ + putup configure --config configs/x86_64-linux.config \ + -C . -S ../../source-root -B ../../build-gcc + putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) +``` +``` + +Remove the "Or directly with putup:" paragraph (that IS the primary command now). + +**Step 2: Update self-contained library convention section** + +In SKILL.md, update: +``` +- Its own `tup.config` for library-specific config +``` +to: +``` +- Its own `defaults.config` for library-specific config (copied to `tup.config` by Tupfile rule) +``` + +**Step 3: Search reference.md for Makefile.pup references** + +Run: `grep -n Makefile.pup docs/reference.md` + +Update or remove any references. The main one is likely in the examples section. + +**Step 4: Commit** + +```bash +git add .claude/skills/gcc-example/SKILL.md docs/reference.md +git commit -m "docs: update BSP build commands — Makefile.pup removed + +Co-Authored-By: Claude Opus 4.6 " +``` + +--- + +### Task 6: Verify via CI + +**Step 1: Push branch and create PR** + +```bash +git push -u origin HEAD +gh pr create --title "bsp: eliminate Makefile.pup preprocessing" --body "..." +``` + +**Step 2: Monitor CI** + +The `build-gcc-bsp` job is the critical gate. It will: +1. Download source tarballs via the new `download-source.sh` +2. Run `putup configure` (which executes config-generating rules including resolve-mpn) +3. Build the full GCC + binutils toolchain +4. Smoke test cc1 + +Expected: all green. If `build-gcc-bsp` fails, check: +- `resolve-mpn.sh` path resolution in 3-tree mode (`%f` expansion) +- `@(MPN_CPU)` availability during configure (must be in root config) +- ifeq `@(HOST_OS)` resolution (must be in root config — linux config doesn't set it, so the `else` branch fires, which is correct) + +**Important:** `x86_64-linux.config` does NOT set `CONFIG_HOST_OS`. This means `@(HOST_OS)` is empty during configure for linux builds. The `ifeq (@(HOST_OS),darwin)` will NOT match, so the `else` branch (linux defaults.config) is used. This is the correct behavior. diff --git a/examples/bsp/Makefile.pup b/examples/bsp/Makefile.pup deleted file mode 100644 index 68b76a8..0000000 --- a/examples/bsp/Makefile.pup +++ /dev/null @@ -1,116 +0,0 @@ -# Makefile.pup - Build GCC cross-compiler toolchain with putup -# -# Usage: -# make -f Makefile.pup # Build toolchain (libraries + compilers + tools) -# make -f Makefile.pup clean # Clean build artifacts -# make -f Makefile.pup distclean # Full clean -# -# Assembly support: -# make -f Makefile.pup MPN_CPU=x86_64 # x86-64 arch-level assembly -# make -f Makefile.pup MPN_CPU=x86_64/core2 # CPU-specific assembly -# make -f Makefile.pup MPN_CPU=generic # Pure C (default) -# -# Cross-compiler (macOS host → x86-64 Linux target): -# make -f Makefile.pup PLATFORM=darwin-x86_64-linux HOST=darwin -# -# 3-tree layout: -# -C . BSP root (examples/bsp/) -# -S $(SRCDIR) Assembled source tree (gcc/, binutils/ subdirs) -# -B $(BUILD) Build output directory - -.PHONY: all build configure resolve-mpn setup-host-configs \ - clean distclean download-source download-binutils - -PLATFORM ?= x86_64-linux -HOST ?= linux -SRCDIR ?= ../../source-root -BUILD ?= ../../build-gcc -MPN_CPU ?= generic -PUTUP ?= putup -TREES = -C . -S $(SRCDIR) -B $(BUILD) - -all: build - -build: resolve-mpn setup-host-configs - $(PUTUP) configure --config configs/$(PLATFORM).config $(TREES) - $(PUTUP) $(TREES) -j$$(nproc) - -configure: resolve-mpn setup-host-configs - $(PUTUP) configure --config configs/$(PLATFORM).config $(TREES) - -# Copy host-specific library configs when building for non-Linux hosts. -# Linux configs are the in-tree defaults; other hosts overlay from configs/host-$(HOST)/. -# To restore Linux defaults: git checkout -- gcc/*/defaults.config binutils/defaults.config -setup-host-configs: - @if [ "$(HOST)" != "linux" ] && [ -d configs/host-$(HOST) ]; then \ - for cfg in configs/host-$(HOST)/*.config; do \ - lib=$$(basename "$$cfg" .config); \ - if [ -f "$$lib/defaults.config" ]; then \ - echo " COPY $$lib/defaults.config (host-$(HOST))"; \ - cp "$$cfg" "$$lib/defaults.config"; \ - elif [ -f "gcc/$$lib/defaults.config" ]; then \ - echo " COPY gcc/$$lib/defaults.config (host-$(HOST))"; \ - cp "$$cfg" "gcc/$$lib/defaults.config"; \ - fi; \ - done; \ - fi - -# Resolve mpn sources for the selected CPU target. -# - gcc/gmp/mpn/defaults.config: source lists and per-function toggles (child scope) -# - gcc/gmp/defaults.config: GMP_MPARAM and ASM_ENABLED (parent scope, visible to gmp/Tupfile) -resolve-mpn: - @scripts/resolve-mpn.sh $(MPN_CPU) $(SRCDIR)/gcc/gmp/mpn > gcc/gmp/mpn/defaults.config - @grep -v '^CONFIG_GMP_MPARAM=\|^CONFIG_ASM_ENABLED=\|^CONFIG_NO_ASM=' gcc/gmp/defaults.config > gcc/gmp/defaults.config.tmp && mv gcc/gmp/defaults.config.tmp gcc/gmp/defaults.config - @if [ "$(MPN_CPU)" != "generic" ]; then \ - arch=$${MPN_CPU%%/*}; \ - if [ -f "$(SRCDIR)/gcc/gmp/mpn/$$arch/gmp-mparam.h" ]; then \ - echo "CONFIG_GMP_MPARAM=mpn/$$arch/gmp-mparam.h" >> gcc/gmp/defaults.config; \ - else \ - echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gcc/gmp/defaults.config; \ - fi; \ - echo "CONFIG_ASM_ENABLED=y" >> gcc/gmp/defaults.config; \ - else \ - echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gcc/gmp/defaults.config; \ - echo "CONFIG_NO_ASM=1" >> gcc/gmp/defaults.config; \ - fi - -# Multi-variant: build for multiple platforms in parallel -# make -f Makefile.pup multi SRCDIR=../../source-root -PLATFORMS ?= x86_64-linux aarch64-linux -multi: - @for p in $(PLATFORMS); do \ - $(PUTUP) configure --config configs/$$p.config -C . -S $(SRCDIR) -B $(BUILD)-$$p; \ - done - $(PUTUP) $(foreach p,$(PLATFORMS),-B $(BUILD)-$(p)) -C . -S $(SRCDIR) -j$$(nproc) - -# Download and assemble source tree. -# Source assembly: extract each tarball, rename into $(SRCDIR)/. -GCC_VERSION ?= 15.2.0 -BINUTILS_VERSION ?= 2.44 - -download-source: download-binutils - @if [ ! -d "$(SRCDIR)/gcc" ]; then \ - echo "Downloading GCC $(GCC_VERSION)..."; \ - mkdir -p $(SRCDIR)/gcc; \ - curl -L "https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.xz" \ - | tar xJ --strip-components=1 -C $(SRCDIR)/gcc; \ - cd $(SRCDIR)/gcc && ./contrib/download_prerequisites; \ - else \ - echo "$(SRCDIR)/gcc already exists"; \ - fi - -download-binutils: - @if [ ! -d "$(SRCDIR)/binutils" ]; then \ - echo "Downloading binutils $(BINUTILS_VERSION)..."; \ - mkdir -p $(SRCDIR)/binutils; \ - curl -L "https://ftp.gnu.org/gnu/binutils/binutils-$(BINUTILS_VERSION).tar.xz" \ - | tar xJ --strip-components=1 -C $(SRCDIR)/binutils; \ - else \ - echo "$(SRCDIR)/binutils already exists"; \ - fi - -clean: - $(PUTUP) clean $(TREES) - -distclean: - $(PUTUP) distclean $(TREES) diff --git a/examples/bsp/README.md b/examples/bsp/README.md index c9840e8..f8f3ab3 100644 --- a/examples/bsp/README.md +++ b/examples/bsp/README.md @@ -54,16 +54,18 @@ examples/bsp/ (config tree) source-root/ (source tree) ```bash cd examples/bsp -# Assemble source tree (or use: make -f Makefile.pup download-source) -# ... see above ... +# Download source (or assemble manually — see above) +scripts/download-source.sh ../../source-root -# Build (macOS host → x86-64 Linux target) -make -f Makefile.pup SRCDIR=../../source-root PLATFORM=darwin-x86_64-linux HOST=darwin +# Configure + build (native x86-64 Linux) +putup configure --config configs/x86_64-linux.config \ + -C . -S ../../source-root -B ../../build-gcc +putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) -# Or directly with putup: +# Cross-compile (macOS host → x86-64 Linux target) putup configure --config configs/darwin-x86_64-linux.config \ -C . -S ../../source-root -B ../../build-gcc -putup -C . -S ../../source-root -B ../../build-gcc -j8 +putup -C . -S ../../source-root -B ../../build-gcc -j$(nproc) ``` ## Scoped Builds @@ -93,29 +95,30 @@ putup configure -S /path/to/gcc-15.2.0 -B /path/to/build putup -S /path/to/gcc-15.2.0 -B /path/to/build ``` -## Makefile Targets +## Build Commands + +| Command | Description | +|---------|-------------| +| `scripts/download-source.sh [SRCDIR]` | Download GCC + binutils tarballs | +| `putup configure --config configs/.config -C . -S -B ` | Configure | +| `putup -C . -S -B -j$(nproc)` | Build | +| `putup clean -C . -S -B ` | Clean build artifacts | +| `putup distclean -C . -S -B ` | Full clean (remove build directory) | + +**Platform configs:** `configs/x86_64-linux.config`, `configs/darwin-x86_64-linux.config` -| Target | Description | -|--------|-------------| -| `make -f Makefile.pup` | Full build (resolve-mpn + configure + build) | -| `make -f Makefile.pup configure` | Configure only (no build) | -| `make -f Makefile.pup download-source` | Download GCC + binutils tarballs into `SRCDIR` | -| `make -f Makefile.pup clean` | Clean build artifacts | -| `make -f Makefile.pup distclean` | Full clean (remove build directory) | -| `make -f Makefile.pup multi` | Multi-variant parallel build for `PLATFORMS` | +**Environment variables for `download-source.sh`:** + +| Variable | Default | Description | +|----------|---------|-------------| +| `GCC_VERSION` | `15.2.0` | GCC tarball version | +| `BINUTILS_VERSION` | `2.44` | binutils tarball version | -**Variables:** +**Config variables (in platform config):** | Variable | Default | Description | |----------|---------|-------------| -| `PLATFORM` | `x86_64-linux` | Config file selector (`configs/$(PLATFORM).config`) | -| `HOST` | `linux` | Host OS (overlays `configs/host-$(HOST)/` if not linux) | -| `SRCDIR` | `../../source-root` | Assembled source tree path | -| `BUILD` | `../../build-gcc` | Build output directory | -| `MPN_CPU` | `generic` | GMP assembly target (`generic`, `x86_64`, `x86_64/core2`) | -| `PUTUP` | `putup` | Path to putup binary (override for CI) | -| `GCC_VERSION` | `15.2.0` | GCC tarball version for `download-source` | -| `BINUTILS_VERSION` | `2.44` | binutils tarball version for `download-source` | +| `CONFIG_MPN_CPU` | `generic` | GMP assembly target (`generic`, `x86_64`, `x86_64/core2`) | ## Architecture diff --git a/examples/bsp/binutils/Tupfile b/examples/bsp/binutils/Tupfile index a1ec142..5218029 100644 --- a/examples/bsp/binutils/Tupfile +++ b/examples/bsp/binutils/Tupfile @@ -1,5 +1,9 @@ include_rules +ifeq (@(HOST_OS),darwin) +: defaults-darwin.config |> ^ INSTALL %o^ cp %f %o |> tup.config +else : defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +endif # ============================================================ # binutils — cross-assembler (as) + cross-archiver (ar) diff --git a/examples/bsp/configs/host-darwin/binutils.config b/examples/bsp/binutils/defaults-darwin.config similarity index 100% rename from examples/bsp/configs/host-darwin/binutils.config rename to examples/bsp/binutils/defaults-darwin.config diff --git a/examples/bsp/configs/darwin-x86_64-linux.config b/examples/bsp/configs/darwin-x86_64-linux.config index bf3c1c4..9d751a0 100644 --- a/examples/bsp/configs/darwin-x86_64-linux.config +++ b/examples/bsp/configs/darwin-x86_64-linux.config @@ -1,7 +1,8 @@ # GCC Libraries - macOS host, x86-64 Linux target (cross-compiler) # # Usage: -# make -f Makefile.pup PLATFORM=darwin-x86_64-linux HOST=darwin +# putup configure --config configs/darwin-x86_64-linux.config \ +# -C . -S ../../source-root -B ../../build-gcc # # Builds cc1 on macOS (Apple Silicon) that generates x86_64 Linux code. # Host compiler is Apple Clang; target config reuses x86_64-pc-linux-gnu. @@ -18,3 +19,9 @@ CONFIG_HOST_OS=darwin CONFIG_PLATFORM_LDFLAGS=-lm -lpthread -lz -liconv CONFIG_EXTRA_MODES_FILE=config/i386/i386-modes.def CONFIG_DECIMAL_FORMAT=bid + +# MPN CPU target (generic for cross-compile) +CONFIG_MPN_CPU=generic + +# libbacktrace: Mach-O format on macOS +CONFIG_BACKTRACE_FORMAT=macho diff --git a/examples/bsp/configs/host-darwin/gmp.config b/examples/bsp/configs/host-darwin/gmp.config deleted file mode 100644 index a280c8c..0000000 --- a/examples/bsp/configs/host-darwin/gmp.config +++ /dev/null @@ -1,101 +0,0 @@ -# GMP 6.2.1 - macOS (aarch64-apple-darwin) config.h defines -# -# Key differences from Linux: no sys_sysinfo, no hidden_alias (macOS linker), -# no obstack_vprintf, host CPU is aarch64 not x86_64. - -# Architecture -CONFIG_LIMB_BITS=64 -CONFIG_NAIL_BITS=0 - -# MPN CPU target -CONFIG_MPN_CPU=generic - -# Feature detection -CONFIG_HAVE_ALARM=1 -CONFIG_HAVE_ALLOCA=1 -CONFIG_HAVE_ALLOCA_H=1 -CONFIG_HAVE_ATTRIBUTE_CONST=1 -CONFIG_HAVE_ATTRIBUTE_MALLOC=1 -CONFIG_HAVE_ATTRIBUTE_MODE=1 -CONFIG_HAVE_ATTRIBUTE_NORETURN=1 -CONFIG_HAVE_CLOCK=1 -CONFIG_HAVE_CLOCK_GETTIME=1 -CONFIG_HAVE_DECL_FGETC=1 -CONFIG_HAVE_DECL_FSCANF=1 -CONFIG_HAVE_DECL_OPTARG=1 -CONFIG_HAVE_DECL_SYS_ERRLIST=0 -CONFIG_HAVE_DECL_SYS_NERR=0 -CONFIG_HAVE_DECL_UNGETC=1 -CONFIG_HAVE_DECL_VFPRINTF=1 -CONFIG_HAVE_DLFCN_H=1 -CONFIG_HAVE_DOUBLE_IEEE_LITTLE_ENDIAN=1 -CONFIG_HAVE_FCNTL_H=1 -CONFIG_HAVE_FLOAT_H=1 -CONFIG_HAVE_GETPAGESIZE=1 -CONFIG_HAVE_GETRUSAGE=1 -CONFIG_HAVE_GETTIMEOFDAY=1 -CONFIG_HAVE_INTMAX_T=1 -CONFIG_HAVE_INTPTR_T=1 -CONFIG_HAVE_INTTYPES_H=1 -CONFIG_HAVE_LANGINFO_H=1 -CONFIG_HAVE_LIMB_LITTLE_ENDIAN=1 -CONFIG_HAVE_LOCALECONV=1 -CONFIG_HAVE_LOCALE_H=1 -CONFIG_HAVE_LONG_DOUBLE=1 -CONFIG_HAVE_LONG_LONG=1 -CONFIG_HAVE_MEMORY_H=1 -CONFIG_HAVE_MEMSET=1 -CONFIG_HAVE_MMAP=1 -CONFIG_HAVE_MPROTECT=1 -CONFIG_HAVE_NL_LANGINFO=1 -CONFIG_HAVE_NL_TYPES_H=1 -CONFIG_HAVE_POPEN=1 -CONFIG_HAVE_PTRDIFF_T=1 -CONFIG_HAVE_RAISE=1 -CONFIG_HAVE_SIGACTION=1 -CONFIG_HAVE_SIGALTSTACK=1 -CONFIG_HAVE_SIGNAL_H=1 -CONFIG_HAVE_STACK_T=1 -CONFIG_HAVE_STDINT_H=1 -CONFIG_HAVE_STDLIB_H=1 -CONFIG_HAVE_STRCHR=1 -CONFIG_HAVE_STRERROR=1 -CONFIG_HAVE_STRING_H=1 -CONFIG_HAVE_STRINGS_H=1 -CONFIG_HAVE_STRNLEN=1 -CONFIG_HAVE_STRTOL=1 -CONFIG_HAVE_STRTOUL=1 -CONFIG_HAVE_SYSCONF=1 -CONFIG_HAVE_SYS_MMAN_H=1 -CONFIG_HAVE_SYS_PARAM_H=1 -CONFIG_HAVE_SYS_RESOURCE_H=1 -CONFIG_HAVE_SYS_STAT_H=1 -CONFIG_HAVE_SYS_TIME_H=1 -CONFIG_HAVE_SYS_TIMES_H=1 -CONFIG_HAVE_SYS_TYPES_H=1 -CONFIG_HAVE_TIMES=1 -CONFIG_HAVE_UINT_LEAST32_T=1 -CONFIG_HAVE_UNISTD_H=1 -CONFIG_HAVE_VSNPRINTF=1 -CONFIG_LSYM_PREFIX="_" -CONFIG_RETSIGTYPE=void -CONFIG_SIZEOF_UNSIGNED=4 -CONFIG_SIZEOF_UNSIGNED_SHORT=2 -CONFIG_SIZEOF_VOID_P=8 -CONFIG_TIME_WITH_SYS_TIME=1 -CONFIG_TUNE_SQR_TOOM2_MAX=SQR_TOOM2_MAX_GENERIC -CONFIG_PACKAGE="gmp" -CONFIG_PACKAGE_BUGREPORT="gmp-bugs@gmp.org" -CONFIG_PACKAGE_NAME="GNU MP" -CONFIG_PACKAGE_STRING="GNU MP 6.2.1" -CONFIG_PACKAGE_TARNAME="gmp" -CONFIG_PACKAGE_VERSION="6.2.1" -CONFIG_SIZEOF_MP_LIMB_T=8 -CONFIG_SIZEOF_UNSIGNED_LONG=8 -CONFIG_SIZEOF_UNSIGNED_LONG_LONG=8 -CONFIG_STDC_HEADERS=1 -CONFIG_VERSION="6.2.1" -CONFIG_WANT_FFT=1 -CONFIG_WANT_TMP_ALLOCA=1 -CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h -CONFIG_NO_ASM=1 diff --git a/examples/bsp/configs/host-darwin/libbacktrace.config b/examples/bsp/configs/host-darwin/libbacktrace.config deleted file mode 100644 index 645b8cb..0000000 --- a/examples/bsp/configs/host-darwin/libbacktrace.config +++ /dev/null @@ -1,48 +0,0 @@ -# libbacktrace - macOS (aarch64-apple-darwin) config.h defines -# -# Key differences from Linux: Mach-O format (not ELF), no dl_iterate_phdr, -# no link.h, no _GNU_SOURCE. - -# Object format: macho (macOS) instead of elf (Linux) -CONFIG_BACKTRACE_FORMAT=macho - -# Atomics -CONFIG_HAVE_ATOMIC_FUNCTIONS=1 -CONFIG_HAVE_SYNC_FUNCTIONS=1 - -# Functions -CONFIG_HAVE_CLOCK_GETTIME=1 -CONFIG_HAVE_FCNTL=1 -CONFIG_HAVE_LSTAT=1 -CONFIG_HAVE_READLINK=1 - -# Declarations -CONFIG_HAVE_DECL_GETPAGESIZE=1 -CONFIG_HAVE_DECL_STRNLEN=1 -CONFIG_HAVE_DECL__PGMPTR=0 - -# Headers -CONFIG_HAVE_DLFCN_H=1 -CONFIG_HAVE_INTTYPES_H=1 -CONFIG_HAVE_MEMORY_H=1 -CONFIG_HAVE_STDINT_H=1 -CONFIG_HAVE_STDLIB_H=1 -CONFIG_HAVE_STRINGS_H=1 -CONFIG_HAVE_STRING_H=1 -CONFIG_HAVE_SYS_MMAN_H=1 -CONFIG_HAVE_SYS_STAT_H=1 -CONFIG_HAVE_SYS_TYPES_H=1 -CONFIG_HAVE_UNISTD_H=1 - -# Compression (optional, can link -lz) -CONFIG_HAVE_ZLIB=1 - -# Sizes -CONFIG_SIZEOF_CHAR=1 -CONFIG_SIZEOF_SHORT=2 -CONFIG_SIZEOF_INT=4 -CONFIG_SIZEOF_LONG=8 -CONFIG_SIZEOF_VOID_P=8 - -# Misc -CONFIG_STDC_HEADERS=1 diff --git a/examples/bsp/configs/host-darwin/libdecnumber.config b/examples/bsp/configs/host-darwin/libdecnumber.config deleted file mode 100644 index de25363..0000000 --- a/examples/bsp/configs/host-darwin/libdecnumber.config +++ /dev/null @@ -1,7 +0,0 @@ -# libdecnumber - macOS (aarch64-apple-darwin) config.h defines -# -# Identical to Linux — libdecnumber only needs endianness and standard headers. - -CONFIG_STDC_HEADERS=1 -CONFIG_HAVE_STRING_H=1 -CONFIG_HAVE_STDLIB_H=1 diff --git a/examples/bsp/configs/host-darwin/libiberty.config b/examples/bsp/configs/host-darwin/libiberty.config deleted file mode 100644 index 4fb2d0a..0000000 --- a/examples/bsp/configs/host-darwin/libiberty.config +++ /dev/null @@ -1,132 +0,0 @@ -# libiberty - macOS (aarch64-apple-darwin) config.h defines -# -# Key differences from Linux: no canonicalize_file_name, no on_exit, -# no pipe2, no sys_prctl_h, no sys_sysinfo_h, no __fsetlocking, -# no stdio_ext.h, no sigsetmask, no strverscmp. - -# Headers -CONFIG_HAVE_ALLOCA_H=1 -CONFIG_HAVE_FCNTL_H=1 -CONFIG_HAVE_INTTYPES_H=1 -CONFIG_HAVE_LIMITS_H=1 -CONFIG_HAVE_MEMORY_H=1 -CONFIG_HAVE_SPAWN_H=1 -CONFIG_HAVE_STDINT_H=1 -CONFIG_HAVE_STDLIB_H=1 -CONFIG_HAVE_STRINGS_H=1 -CONFIG_HAVE_STRING_H=1 -CONFIG_HAVE_SYS_FILE_H=1 -CONFIG_HAVE_SYS_MMAN_H=1 -CONFIG_HAVE_SYS_PARAM_H=1 -CONFIG_HAVE_SYS_RESOURCE_H=1 -CONFIG_HAVE_SYS_STAT_H=1 -CONFIG_HAVE_SYS_TIME_H=1 -CONFIG_HAVE_SYS_TYPES_H=1 -CONFIG_HAVE_SYS_WAIT_H=1 -CONFIG_HAVE_TIME_H=1 -CONFIG_HAVE_UNISTD_H=1 - -# Functions -CONFIG_HAVE_ASPRINTF=1 -CONFIG_HAVE_ATEXIT=1 -CONFIG_HAVE_BASENAME=1 -CONFIG_HAVE_BCMP=1 -CONFIG_HAVE_BCOPY=1 -CONFIG_HAVE_BSEARCH=1 -CONFIG_HAVE_BZERO=1 -CONFIG_HAVE_CALLOC=1 -CONFIG_HAVE_CLOCK=1 -CONFIG_HAVE_FFS=1 -CONFIG_HAVE_FORK=1 -CONFIG_HAVE_GETCWD=1 -CONFIG_HAVE_GETPAGESIZE=1 -CONFIG_HAVE_GETRLIMIT=1 -CONFIG_HAVE_GETRUSAGE=1 -CONFIG_HAVE_GETTIMEOFDAY=1 -CONFIG_HAVE_INDEX=1 -CONFIG_HAVE_INSQUE=1 -CONFIG_HAVE_MEMCHR=1 -CONFIG_HAVE_MEMCMP=1 -CONFIG_HAVE_MEMCPY=1 -CONFIG_HAVE_MEMMEM=1 -CONFIG_HAVE_MEMMOVE=1 -CONFIG_HAVE_MEMSET=1 -CONFIG_HAVE_MKSTEMPS=1 -CONFIG_HAVE_MMAP=1 -CONFIG_HAVE_POSIX_SPAWN=1 -CONFIG_HAVE_POSIX_SPAWNP=1 -CONFIG_HAVE_PSIGNAL=1 -CONFIG_HAVE_PUTENV=1 -CONFIG_HAVE_RANDOM=1 -CONFIG_HAVE_REALPATH=1 -CONFIG_HAVE_RENAME=1 -CONFIG_HAVE_RINDEX=1 -CONFIG_HAVE_SBRK=1 -CONFIG_HAVE_SETENV=1 -CONFIG_HAVE_SETRLIMIT=1 -CONFIG_HAVE_SNPRINTF=1 -CONFIG_HAVE_STPCPY=1 -CONFIG_HAVE_STPNCPY=1 -CONFIG_HAVE_STRCASECMP=1 -CONFIG_HAVE_STRCHR=1 -CONFIG_HAVE_STRDUP=1 -CONFIG_HAVE_STRERROR=1 -CONFIG_HAVE_STRNCASECMP=1 -CONFIG_HAVE_STRNDUP=1 -CONFIG_HAVE_STRNLEN=1 -CONFIG_HAVE_STRRCHR=1 -CONFIG_HAVE_STRSIGNAL=1 -CONFIG_HAVE_STRSTR=1 -CONFIG_HAVE_STRTOD=1 -CONFIG_HAVE_STRTOL=1 -CONFIG_HAVE_STRTOLL=1 -CONFIG_HAVE_STRTOUL=1 -CONFIG_HAVE_STRTOULL=1 -CONFIG_HAVE_SYSCONF=1 -CONFIG_HAVE_TIMES=1 -CONFIG_HAVE_TMPNAM=1 -CONFIG_HAVE_VASPRINTF=1 -CONFIG_HAVE_VFORK=1 -CONFIG_HAVE_VFPRINTF=1 -CONFIG_HAVE_VPRINTF=1 -CONFIG_HAVE_VSPRINTF=1 -CONFIG_HAVE_WAIT3=1 -CONFIG_HAVE_WAIT4=1 -CONFIG_HAVE_WAITPID=1 -CONFIG_HAVE_WORKING_FORK=1 -CONFIG_HAVE_WORKING_VFORK=1 - -# Types -CONFIG_HAVE_INTPTR_T=1 -CONFIG_HAVE_UINTPTR_T=1 -CONFIG_HAVE_LONG_LONG=1 - -# Declarations -CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=0 -CONFIG_HAVE_DECL_CALLOC=1 -CONFIG_HAVE_DECL_FFS=1 -CONFIG_HAVE_DECL_GETENV=1 -CONFIG_HAVE_DECL_GETOPT=1 -CONFIG_HAVE_DECL_MALLOC=1 -CONFIG_HAVE_DECL_REALLOC=1 -CONFIG_HAVE_DECL_SBRK=0 -CONFIG_HAVE_DECL_SNPRINTF=1 -CONFIG_HAVE_DECL_STRNLEN=1 -CONFIG_HAVE_DECL_STRTOL=1 -CONFIG_HAVE_DECL_STRTOLL=1 -CONFIG_HAVE_DECL_STRTOUL=1 -CONFIG_HAVE_DECL_STRTOULL=1 -CONFIG_HAVE_DECL_VASPRINTF=1 -CONFIG_HAVE_DECL_VSNPRINTF=1 - -# Sizes -CONFIG_SIZEOF_INT=4 -CONFIG_SIZEOF_LONG=8 -CONFIG_SIZEOF_LONG_LONG=8 -CONFIG_SIZEOF_SIZE_T=8 - -# Misc -CONFIG_STDC_HEADERS=1 -CONFIG_TIME_WITH_SYS_TIME=1 -CONFIG_UNSIGNED_64BIT_TYPE=unsigned long diff --git a/examples/bsp/configs/host-darwin/mpc.config b/examples/bsp/configs/host-darwin/mpc.config deleted file mode 100644 index d4568ae..0000000 --- a/examples/bsp/configs/host-darwin/mpc.config +++ /dev/null @@ -1,24 +0,0 @@ -# MPC 1.2.1 - macOS (aarch64-apple-darwin) config.h defines -# -# Identical to Linux — MPC is pure C with no platform-specific features. - -CONFIG_HAVE_INTTYPES_H=1 -CONFIG_HAVE_LOCALE_H=1 -CONFIG_HAVE_LOCALECONV=1 -CONFIG_HAVE_MEMORY_H=1 -CONFIG_HAVE_SETLOCALE=1 -CONFIG_HAVE_STDINT_H=1 -CONFIG_HAVE_STDLIB_H=1 -CONFIG_HAVE_STRING_H=1 -CONFIG_HAVE_STRINGS_H=1 -CONFIG_HAVE_SYS_STAT_H=1 -CONFIG_HAVE_SYS_TIME_H=1 -CONFIG_HAVE_SYS_TYPES_H=1 -CONFIG_HAVE_UNISTD_H=1 -CONFIG_PACKAGE="mpc" -CONFIG_PACKAGE_NAME="mpc" -CONFIG_PACKAGE_STRING="mpc 1.2.1" -CONFIG_PACKAGE_TARNAME="mpc" -CONFIG_PACKAGE_VERSION="1.2.1" -CONFIG_STDC_HEADERS=1 -CONFIG_VERSION="1.2.1" diff --git a/examples/bsp/configs/host-darwin/mpfr.config b/examples/bsp/configs/host-darwin/mpfr.config deleted file mode 100644 index f92072b..0000000 --- a/examples/bsp/configs/host-darwin/mpfr.config +++ /dev/null @@ -1,31 +0,0 @@ -# MPFR 4.1.0 - macOS (aarch64-apple-darwin) config.h defines -# -# Nearly identical to Linux. Only endianness representation differs slightly. - -CONFIG_HAVE_ALLOCA=1 -CONFIG_HAVE_ALLOCA_H=1 -CONFIG_HAVE_INTTYPES_H=1 -CONFIG_HAVE_LOCALE_H=1 -CONFIG_HAVE_LOCALECONV=1 -CONFIG_HAVE_LONG_LONG=1 -CONFIG_HAVE_MEMORY_H=1 -CONFIG_HAVE_SETLOCALE=1 -CONFIG_HAVE_STDARG=1 -CONFIG_HAVE_STDINT_H=1 -CONFIG_HAVE_STDLIB_H=1 -CONFIG_HAVE_STRING_H=1 -CONFIG_HAVE_STRINGS_H=1 -CONFIG_HAVE_SYS_STAT_H=1 -CONFIG_HAVE_SYS_TIME_H=1 -CONFIG_HAVE_SYS_TYPES_H=1 -CONFIG_HAVE_UNISTD_H=1 -CONFIG_HAVE_VA_COPY=1 -CONFIG_HAVE_WCHAR_H=1 -CONFIG_HAVE_LITTLE_ENDIAN=1 -CONFIG_PACKAGE="mpfr" -CONFIG_PACKAGE_NAME="MPFR" -CONFIG_PACKAGE_STRING="MPFR 4.1.0" -CONFIG_PACKAGE_TARNAME="mpfr" -CONFIG_PACKAGE_VERSION="4.1.0" -CONFIG_STDC_HEADERS=1 -CONFIG_VERSION="4.1.0" diff --git a/examples/bsp/configs/x86_64-linux.config b/examples/bsp/configs/x86_64-linux.config index 7433a5b..72e9a96 100644 --- a/examples/bsp/configs/x86_64-linux.config +++ b/examples/bsp/configs/x86_64-linux.config @@ -1,10 +1,12 @@ # GCC Libraries - x86-64 Linux toolchain (native) # # Usage: -# putup configure --config configs/x86_64-linux.config -S ../gcc-15.2.0 -B ../build-gcc +# putup configure --config configs/x86_64-linux.config \ +# -C . -S ../../source-root -B ../../build-gcc # -# Per-library configs live in gmp/tup.config, mpfr/tup.config, mpc/tup.config. -# Scoped config merging combines these with the toolchain vars below. +# Per-library configs live in defaults.config files, copied to tup.config by +# Tupfile rules during configure. Scoped config merging combines these with +# the toolchain vars below. # Toolchain CONFIG_CC=gcc @@ -21,3 +23,6 @@ CONFIG_EXTRA_MODES_FILE=config/i386/i386-modes.def # libbacktrace: ELF format on Linux, 64-bit CONFIG_BACKTRACE_FORMAT=elf CONFIG_BACKTRACE_ELF_SIZE=64 + +# MPN CPU target (generic = pure C, x86_64 = arch asm, x86_64/core2 = CPU asm) +CONFIG_MPN_CPU=generic diff --git a/examples/bsp/gcc/gcc/Tupfile b/examples/bsp/gcc/gcc/Tupfile index d4bdcc6..10206e7 100644 --- a/examples/bsp/gcc/gcc/Tupfile +++ b/examples/bsp/gcc/gcc/Tupfile @@ -1,5 +1,9 @@ include_rules +ifeq (@(HOST_OS),darwin) +: defaults-darwin.config |> ^ INSTALL %o^ cp %f %o |> tup.config +else : defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +endif # ============================================================ # GCC 15.2.0 — C compiler backend diff --git a/examples/bsp/configs/host-darwin/gcc.config b/examples/bsp/gcc/gcc/defaults-darwin.config similarity index 100% rename from examples/bsp/configs/host-darwin/gcc.config rename to examples/bsp/gcc/gcc/defaults-darwin.config diff --git a/examples/bsp/gcc/gmp/Tupfile b/examples/bsp/gcc/gmp/Tupfile index 8debbce..02b5e18 100644 --- a/examples/bsp/gcc/gmp/Tupfile +++ b/examples/bsp/gcc/gmp/Tupfile @@ -1,5 +1,18 @@ include_rules -: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +: defaults.config |> ^ GEN %o^ cp %f %o && \ + cpu="@(MPN_CPU)"; \ + if [ -z "$cpu" ] || [ "$cpu" = "generic" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> %o; \ + echo "CONFIG_NO_ASM=1" >> %o; \ + else \ + arch="${cpu%%/*}"; \ + if [ -f "mpn/$arch/gmp-mparam.h" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/$arch/gmp-mparam.h" >> %o; \ + else \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> %o; \ + fi; \ + echo "CONFIG_ASM_ENABLED=y" >> %o; \ + fi |> tup.config # ============================================================ # GMP 6.2.1 diff --git a/examples/bsp/gcc/gmp/defaults.config b/examples/bsp/gcc/gmp/defaults.config index a280c8c..0a24f8c 100644 --- a/examples/bsp/gcc/gmp/defaults.config +++ b/examples/bsp/gcc/gmp/defaults.config @@ -97,5 +97,3 @@ CONFIG_STDC_HEADERS=1 CONFIG_VERSION="6.2.1" CONFIG_WANT_FFT=1 CONFIG_WANT_TMP_ALLOCA=1 -CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h -CONFIG_NO_ASM=1 diff --git a/examples/bsp/gcc/gmp/mpn/Tupfile b/examples/bsp/gcc/gmp/mpn/Tupfile index 9ab015d..8049473 100644 --- a/examples/bsp/gcc/gmp/mpn/Tupfile +++ b/examples/bsp/gcc/gmp/mpn/Tupfile @@ -1,5 +1,5 @@ include_rules -: defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +: $(S)/scripts/resolve-mpn.sh |> ^ RESOLVE-MPN %o^ sh %f @(MPN_CPU) . > %o |> tup.config # MPN — low-level multiprecision arithmetic # diff --git a/examples/bsp/gcc/gmp/mpn/defaults.config b/examples/bsp/gcc/gmp/mpn/defaults.config deleted file mode 100644 index d8a5628..0000000 --- a/examples/bsp/gcc/gmp/mpn/defaults.config +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG_MPN_ARCH=generic -CONFIG_MPN_SUBDIR=generic -CONFIG_C_SOURCES=generic/add_1.c generic/add.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/addmul_1.c generic/add_n.c generic/add_n_sub_n.c generic/bdiv_dbm1c.c generic/bdiv_q_1.c generic/bdiv_q.c generic/bdiv_qr.c generic/binvert.c generic/broot.c generic/brootinv.c generic/bsqrt.c generic/bsqrtinv.c generic/cmp.c generic/cnd_add_n.c generic/cnd_sub_n.c generic/cnd_swap.c generic/comb_tables.c generic/com.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_divappr_q.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/div_q.c generic/div_qr_1.c generic/div_qr_1n_pi1.c generic/div_qr_1n_pi2.c generic/div_qr_1u_pi2.c generic/div_qr_2.c generic/div_qr_2n_pi1.c generic/div_qr_2u_pi1.c generic/divrem_1.c generic/divrem_2.c generic/divrem.c generic/dump.c generic/fib2m.c generic/fib2_ui.c generic/gcd_11.c generic/gcd_1.c generic/gcd_22.c generic/gcd.c generic/gcdext_1.c generic/gcdext.c generic/gcdext_lehmer.c generic/gcd_subdiv_step.c generic/get_d.c generic/get_str.c generic/hgcd2.c generic/hgcd2_jacobi.c generic/hgcd_appr.c generic/hgcd.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/invertappr.c generic/invert.c generic/jacbase.c generic/jacobi_2.c generic/jacobi.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul1_inverse_vector.c generic/matrix22_mul.c generic/mod_1_1.c generic/mod_1_2.c generic/mod_1_3.c generic/mod_1_4.c generic/mod_1.c generic/mod_34lsub1.c generic/mode1o.c generic/mu_bdiv_q.c generic/mu_bdiv_qr.c generic/mu_divappr_q.c generic/mu_div_q.c generic/mu_div_qr.c generic/mul_1.c generic/mul_basecase.c generic/mul.c generic/mul_fft.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid_basecase.c generic/mulmid.c generic/mulmid_n.c generic/mulmod_bnm1.c generic/mul_n.c generic/neg.c generic/nussbaumer_mul.c generic/perfpow.c generic/perfsqr.c generic/pow_1.c generic/powlo.c generic/powm.c generic/pre_divrem_1.c generic/pre_mod_1.c generic/random2.c generic/random.c generic/redc_1.c generic/redc_2.c generic/redc_n.c generic/remove.c generic/rootrem.c generic/rshift.c generic/sbpi1_bdiv_q.c generic/sbpi1_bdiv_qr.c generic/sbpi1_bdiv_r.c generic/sbpi1_divappr_q.c generic/sbpi1_div_q.c generic/sbpi1_div_qr.c generic/scan0.c generic/scan1.c generic/sec_invert.c generic/sec_mul.c generic/sec_powm.c generic/sec_sqr.c generic/sec_tabselect.c generic/set_str.c generic/sizeinbase.c generic/sqr_basecase.c generic/sqr.c generic/sqrlo_basecase.c generic/sqrlo.c generic/sqrmod_bnm1.c generic/sqrtrem.c generic/strongfibo.c generic/sub_1.c generic/sub.c generic/sub_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/submul_1.c generic/sub_n.c generic/tdiv_qr.c generic/toom22_mul.c generic/toom2_sqr.c generic/toom32_mul.c generic/toom33_mul.c generic/toom3_sqr.c generic/toom42_mul.c generic/toom42_mulmid.c generic/toom43_mul.c generic/toom44_mul.c generic/toom4_sqr.c generic/toom52_mul.c generic/toom53_mul.c generic/toom54_mul.c generic/toom62_mul.c generic/toom63_mul.c generic/toom6h_mul.c generic/toom6_sqr.c generic/toom8h_mul.c generic/toom8_sqr.c generic/toom_couple_handling.c generic/toom_eval_dgr3_pm1.c generic/toom_eval_dgr3_pm2.c generic/toom_eval_pm1.c generic/toom_eval_pm2.c generic/toom_eval_pm2exp.c generic/toom_eval_pm2rexp.c generic/toom_interpolate_12pts.c generic/toom_interpolate_16pts.c generic/toom_interpolate_5pts.c generic/toom_interpolate_6pts.c generic/toom_interpolate_7pts.c generic/toom_interpolate_8pts.c generic/trialdiv.c generic/zero.c generic/zero_p.c -CONFIG_ASM_SOURCES= -CONFIG_C_and_n=y -CONFIG_C_andn_n=y -CONFIG_C_ior_n=y -CONFIG_C_iorn_n=y -CONFIG_C_nand_n=y -CONFIG_C_nior_n=y -CONFIG_C_xnor_n=y -CONFIG_C_xor_n=y -CONFIG_C_popcount=y -CONFIG_C_hamdist=y -CONFIG_C_sec_add_1=y -CONFIG_C_sec_sub_1=y -CONFIG_C_sec_div_qr=y -CONFIG_C_sec_div_r=y -CONFIG_C_sec_pi1_div_qr=y -CONFIG_C_sec_pi1_div_r=y diff --git a/examples/bsp/gcc/libcpp/Tupfile b/examples/bsp/gcc/libcpp/Tupfile index 85e70c9..d74ecaa 100644 --- a/examples/bsp/gcc/libcpp/Tupfile +++ b/examples/bsp/gcc/libcpp/Tupfile @@ -1,5 +1,9 @@ include_rules +ifeq (@(HOST_OS),darwin) +: defaults-darwin.config |> ^ INSTALL %o^ cp %f %o |> tup.config +else : defaults.config |> ^ INSTALL %o^ cp %f %o |> tup.config +endif # ============================================================ # libcpp - C preprocessor library (GCC 15.2.0) diff --git a/examples/bsp/configs/host-darwin/libcpp.config b/examples/bsp/gcc/libcpp/defaults-darwin.config similarity index 100% rename from examples/bsp/configs/host-darwin/libcpp.config rename to examples/bsp/gcc/libcpp/defaults-darwin.config diff --git a/examples/bsp/scripts/download-source.sh b/examples/bsp/scripts/download-source.sh new file mode 100755 index 0000000..6d2bc40 --- /dev/null +++ b/examples/bsp/scripts/download-source.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# download-source.sh — Download and assemble GCC + binutils source trees +# +# Usage: scripts/download-source.sh [SRCDIR] +# +# Environment: +# GCC_VERSION GCC version to download (default: 15.2.0) +# BINUTILS_VERSION binutils version to download (default: 2.44) + +set -e + +GCC_VERSION=${GCC_VERSION:-15.2.0} +BINUTILS_VERSION=${BINUTILS_VERSION:-2.44} +SRCDIR=${1:-../../source-root} + +# Download binutils +if [ ! -d "$SRCDIR/binutils" ]; then + echo "Downloading binutils $BINUTILS_VERSION..." + mkdir -p "$SRCDIR/binutils" + curl -L "https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.xz" \ + | tar xJ --strip-components=1 -C "$SRCDIR/binutils" +else + echo "$SRCDIR/binutils already exists" +fi + +# Download GCC + prerequisites +if [ ! -d "$SRCDIR/gcc" ]; then + echo "Downloading GCC $GCC_VERSION..." + mkdir -p "$SRCDIR/gcc" + curl -L "https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.xz" \ + | tar xJ --strip-components=1 -C "$SRCDIR/gcc" + cd "$SRCDIR/gcc" && ./contrib/download_prerequisites +else + echo "$SRCDIR/gcc already exists" +fi