From cede70f2be59e8b4f9f32a8c7f5abd456570cc93 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:15:49 +0800 Subject: [PATCH 01/16] Add GCC example: build GMP, MPFR, MPC from source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build GCC's three prerequisite libraries using putup with a 3-tree layout (-C/-S/-B) against a read-only GCC source tree. Each library is self-contained with ?= defaults for standalone builds. Per-component tup.config files use prefix-free entries — the directory scope provides the namespace via scoped config merging. Co-Authored-By: Claude Opus 4.6 --- examples/gcc/Makefile.pup | 67 +++++++ examples/gcc/README.md | 206 +++++++++++++++++++ examples/gcc/Tupfile | 7 + examples/gcc/Tupfile.ini | 1 + examples/gcc/Tuprules.tup | 16 ++ examples/gcc/configs/aarch64-linux.config | 11 + examples/gcc/configs/x86_64-linux.config | 11 + examples/gcc/gmp/Tupfile | 66 ++++++ examples/gcc/gmp/Tuprules.tup | 32 +++ examples/gcc/gmp/mpf/Tupfile | 20 ++ examples/gcc/gmp/mpn/Tupfile | 232 ++++++++++++++++++++++ examples/gcc/gmp/mpn/tup.config | 31 +++ examples/gcc/gmp/mpq/Tupfile | 12 ++ examples/gcc/gmp/mpz/Tupfile | 45 +++++ examples/gcc/gmp/printf/Tupfile | 11 + examples/gcc/gmp/rand/Tupfile | 9 + examples/gcc/gmp/scanf/Tupfile | 8 + examples/gcc/gmp/tup.config | 108 ++++++++++ examples/gcc/mpc/Tupfile | 5 + examples/gcc/mpc/Tuprules.tup | 20 ++ examples/gcc/mpc/src/Tupfile | 25 +++ examples/gcc/mpc/tup.config | 24 +++ examples/gcc/mpfr/Tupfile | 11 + examples/gcc/mpfr/Tuprules.tup | 18 ++ examples/gcc/mpfr/src/Tupfile | 56 ++++++ examples/gcc/mpfr/tup.config | 31 +++ examples/gcc/scripts/resolve-mpn.sh | 169 ++++++++++++++++ src/cli/cmd_configure.cpp | 8 +- 28 files changed, 1256 insertions(+), 4 deletions(-) create mode 100644 examples/gcc/Makefile.pup create mode 100644 examples/gcc/README.md create mode 100644 examples/gcc/Tupfile create mode 100644 examples/gcc/Tupfile.ini create mode 100644 examples/gcc/Tuprules.tup create mode 100644 examples/gcc/configs/aarch64-linux.config create mode 100644 examples/gcc/configs/x86_64-linux.config create mode 100644 examples/gcc/gmp/Tupfile create mode 100644 examples/gcc/gmp/Tuprules.tup create mode 100644 examples/gcc/gmp/mpf/Tupfile create mode 100644 examples/gcc/gmp/mpn/Tupfile create mode 100644 examples/gcc/gmp/mpn/tup.config create mode 100644 examples/gcc/gmp/mpq/Tupfile create mode 100644 examples/gcc/gmp/mpz/Tupfile create mode 100644 examples/gcc/gmp/printf/Tupfile create mode 100644 examples/gcc/gmp/rand/Tupfile create mode 100644 examples/gcc/gmp/scanf/Tupfile create mode 100644 examples/gcc/gmp/tup.config create mode 100644 examples/gcc/mpc/Tupfile create mode 100644 examples/gcc/mpc/Tuprules.tup create mode 100644 examples/gcc/mpc/src/Tupfile create mode 100644 examples/gcc/mpc/tup.config create mode 100644 examples/gcc/mpfr/Tupfile create mode 100644 examples/gcc/mpfr/Tuprules.tup create mode 100644 examples/gcc/mpfr/src/Tupfile create mode 100644 examples/gcc/mpfr/tup.config create mode 100755 examples/gcc/scripts/resolve-mpn.sh diff --git a/examples/gcc/Makefile.pup b/examples/gcc/Makefile.pup new file mode 100644 index 0000000..36be17e --- /dev/null +++ b/examples/gcc/Makefile.pup @@ -0,0 +1,67 @@ +# Makefile.pup - Build GCC prerequisite libraries with putup +# +# Usage: +# make -f Makefile.pup # Build GMP + MPFR + MPC +# 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) +# +# 3-tree layout: +# -C . Tupfiles live here (examples/gcc/) +# -S $(SRCDIR) GCC source tree (read-only) +# -B $(BUILD) Build output directory + +.PHONY: all build configure resolve-mpn clean distclean + +PLATFORM ?= x86_64-linux +SRCDIR ?= ../gcc-15.2.0 +BUILD ?= ../build-gcc +MPN_CPU ?= generic +TREES = -C . -S $(SRCDIR) -B $(BUILD) + +all: build + +build: resolve-mpn + putup configure --config configs/$(PLATFORM).config $(TREES) + putup $(TREES) -j$$(nproc) + +configure: resolve-mpn + putup configure --config configs/$(PLATFORM).config $(TREES) + +# Resolve mpn sources for the selected CPU target. +# - gmp/mpn/tup.config: source lists and per-function toggles (child scope) +# - gmp/tup.config: GMP_MPARAM and ASM_ENABLED (parent scope, visible to gmp/Tupfile) +resolve-mpn: + @scripts/resolve-mpn.sh $(MPN_CPU) $(SRCDIR)/gmp/mpn > gmp/mpn/tup.config + @sed -i '/^CONFIG_GMP_MPARAM=/d;/^CONFIG_ASM_ENABLED=/d;/^CONFIG_NO_ASM=/d' gmp/tup.config + @if [ "$(MPN_CPU)" != "generic" ]; then \ + arch=$${MPN_CPU%%/*}; \ + if [ -f "$(SRCDIR)/gmp/mpn/$$arch/gmp-mparam.h" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/$$arch/gmp-mparam.h" >> gmp/tup.config; \ + else \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gmp/tup.config; \ + fi; \ + echo "CONFIG_ASM_ENABLED=y" >> gmp/tup.config; \ + else \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gmp/tup.config; \ + echo "CONFIG_NO_ASM=1" >> gmp/tup.config; \ + fi + +# Multi-variant: build for multiple platforms in parallel +# make -f Makefile.pup multi SRCDIR=../gcc-15.2.0 +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) + +clean: + putup clean $(TREES) + +distclean: + putup distclean $(TREES) diff --git a/examples/gcc/README.md b/examples/gcc/README.md new file mode 100644 index 0000000..0e2b200 --- /dev/null +++ b/examples/gcc/README.md @@ -0,0 +1,206 @@ +# GCC Prerequisite Libraries + +Build GCC's bundled [GMP](https://gmplib.org/), [MPFR](https://www.mpfr.org/), and [MPC](http://www.multiprecision.org/mpc/) libraries using putup. + +## Quick Start + +```bash +# 1. Download and extract GCC (includes GMP, MPFR, MPC) +cd /path/to +wget https://gcc.gnu.org/pub/gcc/releases/gcc-15.2.0/gcc-15.2.0.tar.xz +tar xf gcc-15.2.0.tar.xz +cd gcc-15.2.0 && ./contrib/download_prerequisites && cd .. + +# 2. Build (3-tree: -C = Tupfiles, -S = GCC sources, -B = output) +cd examples/gcc +make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc +``` + +Or directly (after running resolve-mpn): + +```bash +scripts/resolve-mpn.sh generic /path/to/gcc-15.2.0/gmp/mpn > gmp/mpn/tup.config +putup configure --config configs/x86_64-linux.config -C . -S /path/to/gcc-15.2.0 -B build +putup -C . -S /path/to/gcc-15.2.0 -B build +``` + +## What Gets Built + +| Library | Version | Output | +|---------|---------|--------| +| GMP | 6.2.1 | `build/gmp/libgmp.a` | +| MPFR | 4.1.0 | `build/mpfr/src/libmpfr.a` | +| MPC | 1.2.1 | `build/mpc/src/libmpc.a` | + +## Dependency Chain + +``` +GMP (no deps) → libgmp.a + ↓ +MPFR (needs GMP headers) → libmpfr.a + ↓ +MPC (needs GMP + MPFR headers) → libmpc.a +``` + +## Per-Component Configuration + +Each library has its own `tup.config` with prefix-free entries. The directory scope +provides the namespace via scoped config merging: + +``` +configs/x86_64-linux.config → Root: CC, AR, HOSTCC (toolchain) +gmp/tup.config → GMP: HAVE_ALLOCA, SIZEOF_UNSIGNED_LONG, ... +mpfr/tup.config → MPFR: HAVE_ALLOCA, HAVE_VA_COPY, ... +mpc/tup.config → MPC: HAVE_INTTYPES_H, HAVE_LOCALECONV, ... +``` + +`putup configure --config` installs the root config and copies subdir configs to the +build tree in a single invocation. Scoped config merging then combines them: + +- `@(CC)` in gmp/ resolves to `gcc` (from root tup.config) +- `@(HAVE_ALLOCA)` in gmp/ resolves to `1` (from gmp/tup.config) +- `@(HAVE_ALLOCA)` in mpfr/ resolves to `1` (from mpfr/tup.config) + +Each library's `!gen-config` reads the raw `$(B)/tup.config` to generate `config.h`, +stripping the 7-char `CONFIG_` prefix from each entry. + +### Standalone vs Composed + +Each library is self-contained and can be built independently: + +```bash +# Standalone: build just GMP +cd gmp && putup configure && putup +``` + +When composed under the root project, the root `Tuprules.tup` sets toolchain variables +that override each library's `?=` defaults. The same `tup.config` file serves as the +root config in standalone mode and as a scoped subdir config in composed mode. + +### Multi-Variant Builds + +Build multiple platforms in parallel with a single putup invocation: + +```bash +# Configure each variant (different toolchain per variant) +putup configure --config configs/x86_64-linux.config -C . -S ../gcc-15.2.0 -B ../build-gcc-x86_64-linux +putup configure --config configs/aarch64-linux.config -C . -S ../gcc-15.2.0 -B ../build-gcc-aarch64-linux + +# Build both variants in parallel +putup -C . -S ../gcc-15.2.0 -B ../build-gcc-x86_64-linux -B ../build-gcc-aarch64-linux -j$(nproc) +``` + +Or via the Makefile: + +```bash +make -f Makefile.pup multi SRCDIR=../gcc-15.2.0 +``` + +Per-library tup.config files are shared across variants — only the root toolchain +config differs. Each `-B` directory gets its own copy of the subdir configs via +`putup configure`. + +### Adding a New Platform + +Create a new toolchain config file: + +```bash +cp configs/x86_64-linux.config configs/myplatform.config +# Edit toolchain vars (CC, AR, HOSTCC) +make -f Makefile.pup PLATFORM=myplatform +``` + +Per-library configs are platform-independent for this generic C build. For platforms +needing different feature detection, override individual library configs. + +## Build Features Demonstrated + +- **Assembly support**: CPU-specific `.asm → m4 → assembler` pipeline with config-driven source selection +- **foo-y conditional compilation**: Kbuild-inspired pattern for toggling multi-function sources without `ifeq` +- **Multi-variant parallel builds**: Multiple `-B` directories built simultaneously with different toolchain configs +- **Per-component scoped configs**: Each library has its own `tup.config`, merged with root via scoped config merging +- **Prefix-free config entries**: No `CONFIG_GMP_` prefix needed; directory scope provides the namespace +- **Multi-directory builds**: GMP spans 8 subdirectories, each with its own Tupfile +- **Host tool generation**: GMP table generators compiled and run during the build +- **3-tree builds**: Tupfiles, GCC sources, and build output in separate directories (`-C`, `-S`, `-B`) +- **Cross-directory groups**: Subdirectory objects collected via `../` into parent +- **Header generation**: gmp.h generated from template via sed with `@()` substitutions +- **Inter-library dependencies**: Order-only groups ensure correct build ordering +- **Self-contained libraries**: Each library has its own `Tuprules.tup` with `?=` defaults; buildable alone or composed +- **Nested `include_rules`**: Root `Tuprules.tup` sets toolchain, per-library `Tuprules.tup` adds flags and bang macros + +## Files + +| File | Purpose | +|------|---------| +| `Makefile.pup` | Make wrapper for putup commands (`PLATFORM`, `MPN_CPU`) | +| `scripts/resolve-mpn.sh` | Resolve mpn sources for a CPU target | +| `Tupfile.ini` | Project root marker | +| `Tuprules.tup` | Toolchain vars (CC, AR, HOSTCC), library directory names | +| `configs/x86_64-linux.config` | Toolchain config (x86-64 Linux, native) | +| `configs/aarch64-linux.config` | Toolchain config (AArch64 Linux, cross) | +| `gmp/tup.config` | GMP platform config + assembly flags (`GMP_MPARAM`, `ASM_ENABLED`) | +| `gmp/mpn/tup.config` | MPN source resolution (generated by `scripts/resolve-mpn.sh`) | +| `gmp/Tuprules.tup` | GMP CFLAGS, `!cc`, `!m4asm`, `!gen-config` | +| `mpfr/tup.config` | MPFR platform config (prefix-free) | +| `mpfr/Tuprules.tup` | MPFR CFLAGS, `!cc`, `!gen-config` | +| `mpc/tup.config` | MPC platform config (prefix-free) | +| `mpc/Tuprules.tup` | MPC CFLAGS, `!cc`, `!gen-config` | +| `gmp/Tupfile` | GMP config generation, table generators, top-level sources, archive | +| `gmp/{mpn,mpz,mpq,mpf,printf,scanf,rand}/Tupfile` | Per-directory compilation | +| `mpfr/Tupfile` | MPFR config generation | +| `mpfr/src/Tupfile` | MPFR source compilation + archive | +| `mpc/Tupfile` | MPC config generation | +| `mpc/src/Tupfile` | MPC source compilation + archive | + +## Assembly Support + +By default, GMP builds in generic C mode (equivalent to `--disable-assembly`). +For CPU-specific assembly, pass `MPN_CPU`: + +```bash +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) +``` + +### How it works + +GMP ships per-CPU assembly routines under `mpn/` (e.g., `mpn/x86_64/`, `mpn/x86_64/core2/`). +The `.asm` files are m4 macros processed into assembly: + +``` +.asm → m4 (config.m4 + asm-defs.m4) → pipe → assembler → .o +``` + +The `resolve-mpn` target runs `scripts/resolve-mpn.sh` to walk GMP's priority chain +(`x86_64/core2 → x86_64 → generic`), picking the best available implementation for +each mpn function. Functions without assembly automatically fall back to generic C. + +This produces two config files: + +| File | Scope | Contents | +|------|-------|----------| +| `gmp/mpn/tup.config` | mpn/ subdirectory | Source lists, per-function y/n toggles | +| `gmp/tup.config` | gmp/ directory | `CONFIG_GMP_MPARAM`, `CONFIG_ASM_ENABLED` | + +### The foo-y pattern + +Multi-function sources (one `.asm` or `.c` producing multiple `.o` via `-DOPERATION_`) +use the Kbuild-inspired `foo-y` conditional compilation pattern: + +```tup +# Variable is non-empty when CONFIG_ASM_add_n=y, empty when unset +aors_add_n-@(ASM_add_n) = x86_64/aors_n.asm + +# foreach over a possibly-empty variable: 0 or 1 rules, no conditionals +: foreach $(aors_add_n-y) |> ... -DOPERATION_add_n ... |> add_n.o +``` + +This keeps `gmp/mpn/Tupfile` completely conditional-free — all source selection is +driven by tup.config entries, resolved once at configure time. + +## Notes + +- Requires: gcc (or compatible C compiler), m4 (for assembly mode) +- MPFR's `mpfr-mini-gmp.c` compiles to empty when not using mini-gmp mode diff --git a/examples/gcc/Tupfile b/examples/gcc/Tupfile new file mode 100644 index 0000000..f8919fb --- /dev/null +++ b/examples/gcc/Tupfile @@ -0,0 +1,7 @@ +include_rules + +# Root Tupfile - nothing to do here +# Libraries are built by their respective Tupfiles: +# gmp/Tupfile → libgmp.a +# mpfr/src/Tupfile → libmpfr.a +# mpc/src/Tupfile → libmpc.a diff --git a/examples/gcc/Tupfile.ini b/examples/gcc/Tupfile.ini new file mode 100644 index 0000000..e9839ba --- /dev/null +++ b/examples/gcc/Tupfile.ini @@ -0,0 +1 @@ +# GCC Libraries - pup build configuration diff --git a/examples/gcc/Tuprules.tup b/examples/gcc/Tuprules.tup new file mode 100644 index 0000000..1ce846a --- /dev/null +++ b/examples/gcc/Tuprules.tup @@ -0,0 +1,16 @@ +# Tuprules.tup - GCC in-tree library build (root rules) +# +# Sets project-wide variables from tup.config. +# Per-library CFLAGS, !cc, and !gen-config live in +# gmp/Tuprules.tup, mpfr/Tuprules.tup, mpc/Tuprules.tup. + +S = $(TUP_CWD) +B = $(TUP_VARIANT_OUTPUTDIR)/$(S) + +CC = @(CC) +AR = @(AR) +HOSTCC = @(HOSTCC) + +GMP_DIR = gmp +MPFR_DIR = mpfr +MPC_DIR = mpc diff --git a/examples/gcc/configs/aarch64-linux.config b/examples/gcc/configs/aarch64-linux.config new file mode 100644 index 0000000..ca1ffb7 --- /dev/null +++ b/examples/gcc/configs/aarch64-linux.config @@ -0,0 +1,11 @@ +# GCC Libraries - AArch64 Linux cross-compile toolchain +# +# Usage: +# putup configure --config configs/aarch64-linux.config -S ../gcc-15.2.0 -B ../build-gcc-aarch64 +# +# Per-library configs live in gmp/tup.config, mpfr/tup.config, mpc/tup.config. +# Scoped config merging combines these with the toolchain vars below. + +CONFIG_CC=aarch64-linux-gnu-gcc +CONFIG_AR=aarch64-linux-gnu-ar +CONFIG_HOSTCC=gcc diff --git a/examples/gcc/configs/x86_64-linux.config b/examples/gcc/configs/x86_64-linux.config new file mode 100644 index 0000000..c68ad12 --- /dev/null +++ b/examples/gcc/configs/x86_64-linux.config @@ -0,0 +1,11 @@ +# GCC Libraries - x86-64 Linux toolchain +# +# Usage: +# putup configure --config configs/x86_64-linux.config -S ../gcc-15.2.0 -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. + +CONFIG_CC=gcc +CONFIG_AR=ar +CONFIG_HOSTCC=gcc diff --git a/examples/gcc/gmp/Tupfile b/examples/gcc/gmp/Tupfile new file mode 100644 index 0000000..c99d077 --- /dev/null +++ b/examples/gcc/gmp/Tupfile @@ -0,0 +1,66 @@ +include_rules + +# ============================================================ +# GMP 6.2.1 +# ============================================================ + +# --- Phase 1: Generate config.h, gmp-mparam.h, gmp.h, and config.m4 --- + +: |> !gen-config |> config.h + +: @(GMP_MPARAM) |> ^ GEN %o^ cp %f %o |> gmp-mparam.h + +ifeq (@(ASM_ENABLED),y) +: |> ^ GEN %o^ ( \ + echo 'changequote(<,>)ifdef(<__CONFIG_M4_INCLUDED__>,,)'; \ + echo 'define(,<$(LIMB_BITS)>)'; \ + echo 'define(,<$(NAIL_BITS)>)'; \ + echo 'define(,)define(,1)>)' \ + ) > %o |> config.m4 +endif + +: gmp-h.in |> ^ GEN %o^ sed \ + -e 's/@HAVE_HOST_CPU_FAMILY_power@/0/g' \ + -e 's/@HAVE_HOST_CPU_FAMILY_powerpc@/0/g' \ + -e 's/@GMP_LIMB_BITS@/@(LIMB_BITS)/g' \ + -e 's/@GMP_NAIL_BITS@/@(NAIL_BITS)/g' \ + -e 's/@DEFN_LONG_LONG_LIMB@//g' \ + -e 's/@LIBGMP_DLL@/0/g' \ + -e 's/@CC@/@(CC)/g' \ + -e 's/@CFLAGS@//g' \ + %f > %o |> gmp.h + +# --- Phase 2: Build table generators (self-contained via mini-gmp) --- + +: gen-fac.c |> ^ HOSTCC %o^ $(HOSTCC) %f -o %o |> gen-fac +: gen-fib.c |> ^ HOSTCC %o^ $(HOSTCC) %f -o %o |> gen-fib +: gen-bases.c |> ^ HOSTCC %o^ $(HOSTCC) %f -o %o -lm |> gen-bases +: gen-trialdivtab.c |> ^ HOSTCC %o^ $(HOSTCC) %f -o %o -lm |> gen-trialdivtab +: gen-jacobitab.c |> ^ HOSTCC %o^ $(HOSTCC) %f -o %o |> gen-jacobitab +: gen-psqr.c |> ^ HOSTCC %o^ $(HOSTCC) %f -o %o -lm |> gen-psqr + +# --- Phase 3: Generate table headers and sources --- + +: gen-fac |> ^ GEN %o^ %f $(LIMB_BITS) $(NAIL_BITS) > %o |> fac_table.h +: gen-fib |> ^ GEN %o^ %f header $(LIMB_BITS) $(NAIL_BITS) > %o |> fib_table.h +: gen-fib |> ^ GEN %o^ %f table $(LIMB_BITS) $(NAIL_BITS) > %o |> mpn/fib_table.c +: gen-bases |> ^ GEN %o^ %f header $(LIMB_BITS) $(NAIL_BITS) > %o |> mp_bases.h +: gen-bases |> ^ GEN %o^ %f table $(LIMB_BITS) $(NAIL_BITS) > %o |> mpn/mp_bases.c +: gen-trialdivtab |> ^ GEN %o^ %f $(LIMB_BITS) 8000 > %o |> trialdivtab.h +: gen-jacobitab |> ^ GEN %o^ %f > %o |> jacobitab.h +: gen-psqr |> ^ GEN %o^ %f $(LIMB_BITS) $(NAIL_BITS) > %o |> perfsqr.h + +# --- Phase 4: Compile top-level GMP sources --- + +srcs = assert.c compat.c errno.c extract-dbl.c invalid.c memory.c +srcs += mp_bpl.c mp_clz_tab.c mp_dv_tab.c mp_minv_tab.c +srcs += mp_get_fns.c mp_set_fns.c +srcs += version.c nextprime.c primesieve.c +srcs += tal-reent.c + +: foreach $(srcs) |> !cc |> %B.o + +# --- Phase 5: Archive all GMP objects into libgmp.a --- +# All subdirectories contribute objects to via ../. + +: |> ^ AR %o^ $(AR) rcs %o % |> libgmp.a $(S)/ diff --git a/examples/gcc/gmp/Tuprules.tup b/examples/gcc/gmp/Tuprules.tup new file mode 100644 index 0000000..83ab46b --- /dev/null +++ b/examples/gcc/gmp/Tuprules.tup @@ -0,0 +1,32 @@ +# GMP build rules (self-contained with ?= defaults) +# +# Composed mode: parent sets S, B, CC, AR, HOSTCC, GMP_DIR before this runs. +# Standalone mode: ?= defaults take effect. + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +AR ?= ar +HOSTCC ?= gcc +LIMB_BITS ?= @(LIMB_BITS) +NAIL_BITS ?= @(NAIL_BITS) +GMP_DIR ?= . + +CFLAGS = -O2 -std=gnu11 +CFLAGS += -D__GMP_WITHIN_GMP -DHAVE_CONFIG_H +CFLAGS += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) + +!cc = | $(S)/$(GMP_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o + +!m4asm = | $(S)/$(GMP_DIR)/ |> ^ M4ASM %b^ \ + m4 -DPIC -DOPERATION_%B \ + -I$(S)/$(GMP_DIR)/mpn \ + -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 \ + $(S)/$(GMP_DIR)/mpn/asm-defs.m4 \ + %f \ + | $(CC) -c -x assembler - -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/gmp/mpf/Tupfile b/examples/gcc/gmp/mpf/Tupfile new file mode 100644 index 0000000..bf8bb49 --- /dev/null +++ b/examples/gcc/gmp/mpf/Tupfile @@ -0,0 +1,20 @@ +include_rules + +# MPF - multiprecision floating-point + +srcs = abs.c add.c add_ui.c ceilfloor.c clear.c clears.c +srcs += cmp.c cmp_d.c cmp_si.c cmp_ui.c cmp_z.c +srcs += div.c div_2exp.c div_ui.c dump.c eq.c +srcs += fits_sint.c fits_slong.c fits_sshort.c +srcs += fits_uint.c fits_ulong.c fits_ushort.c +srcs += get_d.c get_d_2exp.c get_dfl_prec.c get_prc.c get_si.c get_str.c get_ui.c +srcs += init.c init2.c inits.c inp_str.c int_p.c +srcs += iset.c iset_d.c iset_si.c iset_str.c iset_ui.c +srcs += mul.c mul_2exp.c mul_ui.c neg.c out_str.c +srcs += pow_ui.c random2.c reldiff.c +srcs += set.c set_d.c set_dfl_prec.c set_prc.c set_prc_raw.c +srcs += set_q.c set_si.c set_str.c set_ui.c set_z.c +srcs += size.c sqrt.c sqrt_ui.c sub.c sub_ui.c swap.c trunc.c +srcs += ui_div.c ui_sub.c urandomb.c + +: foreach $(srcs) |> !cc |> %B.o ../ diff --git a/examples/gcc/gmp/mpn/Tupfile b/examples/gcc/gmp/mpn/Tupfile new file mode 100644 index 0000000..27ab8bc --- /dev/null +++ b/examples/gcc/gmp/mpn/Tupfile @@ -0,0 +1,232 @@ +include_rules + +# MPN — low-level multiprecision arithmetic +# +# Source selection is config-driven via gmp/mpn/tup.config (generated by +# scripts/resolve-mpn.sh). In generic mode, all sources are C with template +# functions enabled. In assembly mode, .asm files replace selected C sources +# and the foo-y pattern toggles individual template outputs. + +# --- Bang macros --- + +!cc-op = | $(S)/$(GMP_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -DOPERATION_%B -c %f -o %o |> %B.o ../ + +# --- Bulk sources (foreach over config lists) --- + +: foreach @(C_SOURCES) |> !cc-op |> +: foreach @(ASM_SOURCES) |> !m4asm |> %B.o ../ + +# ===================================================================== +# Multi-function assembly (foo-y pattern) +# +# Each .asm is compiled multiple times with different -DOPERATION_ to +# produce separate .o files. The variable name encodes the toggle: +# varname-@(FLAG) = path +# When FLAG=y, $(varname-y) expands to the path. Otherwise it's empty. +# ===================================================================== + +# aors_n.asm → add_n, sub_n +aors_add_n-@(ASM_add_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_n.asm +aors_sub_n-@(ASM_sub_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_n.asm + +: foreach $(aors_add_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_n^ \ + m4 -DPIC -DOPERATION_add_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> add_n.o ../ + +: foreach $(aors_sub_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_n^ \ + m4 -DPIC -DOPERATION_sub_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> sub_n.o ../ + +# aorsmul_1.asm → addmul_1, submul_1 +aorsmul_addmul_1-@(ASM_addmul_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/aorsmul_1.asm +aorsmul_submul_1-@(ASM_submul_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/aorsmul_1.asm + +: foreach $(aorsmul_addmul_1-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM addmul_1^ \ + m4 -DPIC -DOPERATION_addmul_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> addmul_1.o ../ + +: foreach $(aorsmul_submul_1-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM submul_1^ \ + m4 -DPIC -DOPERATION_submul_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> submul_1.o ../ + +# aors_err1_n.asm → add_err1_n, sub_err1_n +aors_err1_add-@(ASM_add_err1_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err1_n.asm +aors_err1_sub-@(ASM_sub_err1_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err1_n.asm + +: foreach $(aors_err1_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_err1_n^ \ + m4 -DPIC -DOPERATION_add_err1_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> add_err1_n.o ../ + +: foreach $(aors_err1_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_err1_n^ \ + m4 -DPIC -DOPERATION_sub_err1_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> sub_err1_n.o ../ + +# aors_err2_n.asm → add_err2_n, sub_err2_n +aors_err2_add-@(ASM_add_err2_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err2_n.asm +aors_err2_sub-@(ASM_sub_err2_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err2_n.asm + +: foreach $(aors_err2_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_err2_n^ \ + m4 -DPIC -DOPERATION_add_err2_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> add_err2_n.o ../ + +: foreach $(aors_err2_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_err2_n^ \ + m4 -DPIC -DOPERATION_sub_err2_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> sub_err2_n.o ../ + +# aors_err3_n.asm → add_err3_n, sub_err3_n +aors_err3_add-@(ASM_add_err3_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err3_n.asm +aors_err3_sub-@(ASM_sub_err3_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err3_n.asm + +: foreach $(aors_err3_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_err3_n^ \ + m4 -DPIC -DOPERATION_add_err3_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> add_err3_n.o ../ + +: foreach $(aors_err3_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_err3_n^ \ + m4 -DPIC -DOPERATION_sub_err3_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> sub_err3_n.o ../ + +# logops_n.asm → and_n, andn_n, ior_n, iorn_n, nand_n, nior_n, xnor_n, xor_n +logops_asm_and_n-@(ASM_and_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_andn_n-@(ASM_andn_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_ior_n-@(ASM_ior_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_iorn_n-@(ASM_iorn_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_nand_n-@(ASM_nand_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_nior_n-@(ASM_nior_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_xnor_n-@(ASM_xnor_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm +logops_asm_xor_n-@(ASM_xor_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm + +: foreach $(logops_asm_and_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM and_n^ \ + m4 -DPIC -DOPERATION_and_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> and_n.o ../ + +: foreach $(logops_asm_andn_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM andn_n^ \ + m4 -DPIC -DOPERATION_andn_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> andn_n.o ../ + +: foreach $(logops_asm_ior_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM ior_n^ \ + m4 -DPIC -DOPERATION_ior_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> ior_n.o ../ + +: foreach $(logops_asm_iorn_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM iorn_n^ \ + m4 -DPIC -DOPERATION_iorn_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> iorn_n.o ../ + +: foreach $(logops_asm_nand_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM nand_n^ \ + m4 -DPIC -DOPERATION_nand_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> nand_n.o ../ + +: foreach $(logops_asm_nior_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM nior_n^ \ + m4 -DPIC -DOPERATION_nior_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> nior_n.o ../ + +: foreach $(logops_asm_xnor_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM xnor_n^ \ + m4 -DPIC -DOPERATION_xnor_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> xnor_n.o ../ + +: foreach $(logops_asm_xor_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM xor_n^ \ + m4 -DPIC -DOPERATION_xor_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> xor_n.o ../ + +# popham.asm → popcount, hamdist +popham_asm_popcount-@(ASM_popcount) = @(MPN_ARCH)/@(MPN_SUBDIR)/popham.asm +popham_asm_hamdist-@(ASM_hamdist) = @(MPN_ARCH)/@(MPN_SUBDIR)/popham.asm + +: foreach $(popham_asm_popcount-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM popcount^ \ + m4 -DPIC -DOPERATION_popcount -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> popcount.o ../ + +: foreach $(popham_asm_hamdist-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM hamdist^ \ + m4 -DPIC -DOPERATION_hamdist -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> hamdist.o ../ + +# sec_aors_1.asm → sec_add_1, sec_sub_1 +sec_aors_1_asm_add-@(ASM_sec_add_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/sec_aors_1.asm +sec_aors_1_asm_sub-@(ASM_sec_sub_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/sec_aors_1.asm + +: foreach $(sec_aors_1_asm_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sec_add_1^ \ + m4 -DPIC -DOPERATION_sec_add_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> sec_add_1.o ../ + +: foreach $(sec_aors_1_asm_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sec_sub_1^ \ + m4 -DPIC -DOPERATION_sec_sub_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ + $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ + | $(CC) -c -x assembler - -o %o |> sec_sub_1.o ../ + +# ===================================================================== +# Template C rules (foo-y pattern) +# +# Each template .c is compiled with different -DOPERATION_ values. +# In generic mode all are enabled (CONFIG_C_=y). In assembly +# mode, functions with .asm replacements are disabled (CONFIG_C_=n). +# ===================================================================== + +# logops_n.c → and_n, andn_n, ior_n, iorn_n, nand_n, nior_n, xnor_n, xor_n +logops_and_n-@(C_and_n) = generic/logops_n.c +logops_andn_n-@(C_andn_n) = generic/logops_n.c +logops_ior_n-@(C_ior_n) = generic/logops_n.c +logops_iorn_n-@(C_iorn_n) = generic/logops_n.c +logops_nand_n-@(C_nand_n) = generic/logops_n.c +logops_nior_n-@(C_nior_n) = generic/logops_n.c +logops_xnor_n-@(C_xnor_n) = generic/logops_n.c +logops_xor_n-@(C_xor_n) = generic/logops_n.c + +: foreach $(logops_and_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC and_n^ $(CC) $(CFLAGS) -DOPERATION_and_n -c %f -o %o |> and_n.o ../ +: foreach $(logops_andn_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC andn_n^ $(CC) $(CFLAGS) -DOPERATION_andn_n -c %f -o %o |> andn_n.o ../ +: foreach $(logops_ior_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC ior_n^ $(CC) $(CFLAGS) -DOPERATION_ior_n -c %f -o %o |> ior_n.o ../ +: foreach $(logops_iorn_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC iorn_n^ $(CC) $(CFLAGS) -DOPERATION_iorn_n -c %f -o %o |> iorn_n.o ../ +: foreach $(logops_nand_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC nand_n^ $(CC) $(CFLAGS) -DOPERATION_nand_n -c %f -o %o |> nand_n.o ../ +: foreach $(logops_nior_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC nior_n^ $(CC) $(CFLAGS) -DOPERATION_nior_n -c %f -o %o |> nior_n.o ../ +: foreach $(logops_xnor_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC xnor_n^ $(CC) $(CFLAGS) -DOPERATION_xnor_n -c %f -o %o |> xnor_n.o ../ +: foreach $(logops_xor_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC xor_n^ $(CC) $(CFLAGS) -DOPERATION_xor_n -c %f -o %o |> xor_n.o ../ + +# popham.c → popcount, hamdist +popham_popcount-@(C_popcount) = generic/popham.c +popham_hamdist-@(C_hamdist) = generic/popham.c + +: foreach $(popham_popcount-y) | $(S)/$(GMP_DIR)/ |> ^ CC popcount^ $(CC) $(CFLAGS) -DOPERATION_popcount -c %f -o %o |> popcount.o ../ +: foreach $(popham_hamdist-y) | $(S)/$(GMP_DIR)/ |> ^ CC hamdist^ $(CC) $(CFLAGS) -DOPERATION_hamdist -c %f -o %o |> hamdist.o ../ + +# sec_aors_1.c → sec_add_1, sec_sub_1 +sec_aors_1_add-@(C_sec_add_1) = generic/sec_aors_1.c +sec_aors_1_sub-@(C_sec_sub_1) = generic/sec_aors_1.c + +: foreach $(sec_aors_1_add-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_add_1^ $(CC) $(CFLAGS) -DOPERATION_sec_add_1 -c %f -o %o |> sec_add_1.o ../ +: foreach $(sec_aors_1_sub-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_sub_1^ $(CC) $(CFLAGS) -DOPERATION_sec_sub_1 -c %f -o %o |> sec_sub_1.o ../ + +# sec_div.c → sec_div_qr, sec_div_r (always C, no asm variant) +sec_div_qr-@(C_sec_div_qr) = generic/sec_div.c +sec_div_r-@(C_sec_div_r) = generic/sec_div.c + +: foreach $(sec_div_qr-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_div_qr^ $(CC) $(CFLAGS) -DOPERATION_sec_div_qr -c %f -o %o |> sec_div_qr.o ../ +: foreach $(sec_div_r-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_div_r^ $(CC) $(CFLAGS) -DOPERATION_sec_div_r -c %f -o %o |> sec_div_r.o ../ + +# sec_pi1_div.c → sec_pi1_div_qr, sec_pi1_div_r (always C, no asm variant) +sec_pi1_div_qr-@(C_sec_pi1_div_qr) = generic/sec_pi1_div.c +sec_pi1_div_r-@(C_sec_pi1_div_r) = generic/sec_pi1_div.c + +: foreach $(sec_pi1_div_qr-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_pi1_div_qr^ $(CC) $(CFLAGS) -DOPERATION_sec_pi1_div_qr -c %f -o %o |> sec_pi1_div_qr.o ../ +: foreach $(sec_pi1_div_r-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_pi1_div_r^ $(CC) $(CFLAGS) -DOPERATION_sec_pi1_div_r -c %f -o %o |> sec_pi1_div_r.o ../ + +# --- Generated table sources (produced by gmp/Tupfile generators) --- +: foreach fib_table.c mp_bases.c |> !cc-op |> diff --git a/examples/gcc/gmp/mpn/tup.config b/examples/gcc/gmp/mpn/tup.config new file mode 100644 index 0000000..5dbb28e --- /dev/null +++ b/examples/gcc/gmp/mpn/tup.config @@ -0,0 +1,31 @@ +# GMP mpn source resolution — generic C mode (no assembly) +# +# Generated by: scripts/resolve-mpn.sh generic +# Regenerate for assembly: scripts/resolve-mpn.sh x86_64 > gmp/mpn/tup.config + +CONFIG_MPN_ARCH=generic +CONFIG_MPN_SUBDIR=generic + +# Single-function sources (foreach-compatible — one .c per .o) +CONFIG_C_SOURCES=generic/add.c generic/add_1.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/add_n.c generic/add_n_sub_n.c generic/addmul_1.c generic/bdiv_dbm1c.c generic/bdiv_q.c generic/bdiv_q_1.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/com.c generic/comb_tables.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dcpi1_divappr_q.c generic/div_q.c generic/div_qr_1.c generic/div_qr_1n_pi1.c generic/div_qr_2.c generic/div_qr_2n_pi1.c generic/div_qr_2u_pi1.c generic/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/divrem.c generic/divrem_1.c generic/divrem_2.c generic/dump.c generic/fib2_ui.c generic/fib2m.c generic/gcd.c generic/gcd_1.c generic/gcd_11.c generic/gcd_22.c generic/gcd_subdiv_step.c generic/gcdext.c generic/gcdext_1.c generic/gcdext_lehmer.c generic/get_d.c generic/get_str.c generic/hgcd.c generic/hgcd2.c generic/hgcd2_jacobi.c generic/hgcd_appr.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/invert.c generic/invertappr.c generic/jacbase.c generic/jacobi.c generic/jacobi_2.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul.c generic/matrix22_mul1_inverse_vector.c generic/mod_1.c generic/mod_1_1.c generic/mod_1_2.c generic/mod_1_3.c generic/mod_1_4.c generic/mod_34lsub1.c generic/mode1o.c generic/mu_bdiv_q.c generic/mu_bdiv_qr.c generic/mu_div_q.c generic/mu_div_qr.c generic/mu_divappr_q.c generic/mul.c generic/mul_1.c generic/mul_basecase.c generic/mul_fft.c generic/mul_n.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid.c generic/mulmid_basecase.c generic/mulmid_n.c generic/mulmod_bnm1.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/random.c generic/random2.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_div_q.c generic/sbpi1_div_qr.c generic/sbpi1_divappr_q.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.c generic/sqr_basecase.c generic/sqrlo.c generic/sqrlo_basecase.c generic/sqrmod_bnm1.c generic/sqrtrem.c generic/strongfibo.c generic/sub.c generic/sub_1.c generic/sub_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/sub_n.c generic/submul_1.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/toom6_sqr.c generic/toom6h_mul.c generic/toom8_sqr.c generic/toom8h_mul.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 + +# Single-function assembly sources (empty in generic mode) +CONFIG_ASM_SOURCES= + +# Template C toggles — all enabled in generic mode (no assembly replacements) +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/gcc/gmp/mpq/Tupfile b/examples/gcc/gmp/mpq/Tupfile new file mode 100644 index 0000000..49727d9 --- /dev/null +++ b/examples/gcc/gmp/mpq/Tupfile @@ -0,0 +1,12 @@ +include_rules + +# MPQ - multiprecision rationals + +srcs = abs.c aors.c canonicalize.c clear.c clears.c +srcs += cmp.c cmp_si.c cmp_ui.c div.c equal.c +srcs += get_d.c get_den.c get_num.c get_str.c +srcs += init.c inits.c inp_str.c inv.c md_2exp.c mul.c neg.c out_str.c +srcs += set.c set_d.c set_den.c set_f.c set_num.c +srcs += set_si.c set_str.c set_ui.c set_z.c swap.c + +: foreach $(srcs) |> !cc |> %B.o ../ diff --git a/examples/gcc/gmp/mpz/Tupfile b/examples/gcc/gmp/mpz/Tupfile new file mode 100644 index 0000000..6a22fe3 --- /dev/null +++ b/examples/gcc/gmp/mpz/Tupfile @@ -0,0 +1,45 @@ +include_rules + +# MPZ - multiprecision integers + +srcs = 2fac_ui.c abs.c add.c add_ui.c aorsmul.c aorsmul_i.c and.c +srcs += array_init.c bin_ui.c bin_uiui.c +srcs += cdiv_q.c cdiv_q_ui.c cdiv_qr.c cdiv_qr_ui.c +srcs += cdiv_r.c cdiv_r_ui.c cdiv_ui.c +srcs += cfdiv_q_2exp.c cfdiv_r_2exp.c +srcs += clear.c clears.c clrbit.c +srcs += cmp.c cmp_d.c cmp_si.c cmp_ui.c cmpabs.c cmpabs_d.c cmpabs_ui.c +srcs += com.c combit.c cong.c cong_2exp.c cong_ui.c +srcs += divexact.c divegcd.c dive_ui.c divis.c divis_ui.c divis_2exp.c +srcs += dump.c export.c +srcs += fac_ui.c fdiv_q.c fdiv_q_ui.c fdiv_qr.c fdiv_qr_ui.c +srcs += fdiv_r.c fdiv_r_ui.c fdiv_ui.c +srcs += fib_ui.c fib2_ui.c +srcs += fits_sint.c fits_slong.c fits_sshort.c +srcs += fits_uint.c fits_ulong.c fits_ushort.c +srcs += gcd.c gcd_ui.c gcdext.c +srcs += get_d.c get_d_2exp.c get_si.c get_str.c get_ui.c getlimbn.c +srcs += hamdist.c import.c +srcs += init.c init2.c inits.c inp_raw.c inp_str.c invert.c +srcs += ior.c iset.c iset_d.c iset_si.c iset_str.c iset_ui.c +srcs += jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c +srcs += lcm.c lcm_ui.c limbs_finish.c limbs_modify.c limbs_read.c limbs_write.c +srcs += lucmod.c lucnum_ui.c lucnum2_ui.c +srcs += mfac_uiui.c millerrabin.c mod.c mul.c mul_2exp.c mul_si.c mul_ui.c +srcs += n_pow_ui.c neg.c nextprime.c +srcs += oddfac_1.c out_raw.c out_str.c +srcs += perfpow.c perfsqr.c popcount.c +srcs += pow_ui.c powm.c powm_sec.c powm_ui.c +srcs += pprime_p.c primorial_ui.c prodlimbs.c +srcs += random.c random2.c realloc.c realloc2.c remove.c roinit_n.c +srcs += root.c rootrem.c rrandomb.c +srcs += scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c set_ui.c +srcs += setbit.c size.c sizeinbase.c +srcs += sqrt.c sqrtrem.c stronglucas.c +srcs += sub.c sub_ui.c swap.c +srcs += tdiv_q.c tdiv_q_2exp.c tdiv_q_ui.c +srcs += tdiv_qr.c tdiv_qr_ui.c +srcs += tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tdiv_ui.c +srcs += tstbit.c ui_pow_ui.c ui_sub.c urandomb.c urandomm.c xor.c + +: foreach $(srcs) |> !cc |> %B.o ../ diff --git a/examples/gcc/gmp/printf/Tupfile b/examples/gcc/gmp/printf/Tupfile new file mode 100644 index 0000000..00802c9 --- /dev/null +++ b/examples/gcc/gmp/printf/Tupfile @@ -0,0 +1,11 @@ +include_rules + +# GMP printf functions + +srcs = asprintf.c asprntffuns.c doprnt.c doprntf.c doprnti.c fprintf.c +srcs += obprintf.c obprntffuns.c obvprintf.c +srcs += printf.c printffuns.c repl-vsnprintf.c +srcs += snprintf.c snprntffuns.c sprintf.c sprintffuns.c +srcs += vasprintf.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c + +: foreach $(srcs) |> !cc |> %B.o ../ diff --git a/examples/gcc/gmp/rand/Tupfile b/examples/gcc/gmp/rand/Tupfile new file mode 100644 index 0000000..7f4e91c --- /dev/null +++ b/examples/gcc/gmp/rand/Tupfile @@ -0,0 +1,9 @@ +include_rules + +# GMP random number generation + +srcs = rand.c randbui.c randclr.c randdef.c randiset.c +srcs += randlc2s.c randlc2x.c randmt.c randmts.c randmui.c +srcs += rands.c randsd.c randsdui.c + +: foreach $(srcs) |> !cc |> %B.o ../ diff --git a/examples/gcc/gmp/scanf/Tupfile b/examples/gcc/gmp/scanf/Tupfile new file mode 100644 index 0000000..1708638 --- /dev/null +++ b/examples/gcc/gmp/scanf/Tupfile @@ -0,0 +1,8 @@ +include_rules + +# GMP scanf functions + +srcs = doscan.c fscanf.c fscanffuns.c scanf.c sscanf.c sscanffuns.c +srcs += vfscanf.c vscanf.c vsscanf.c + +: foreach $(srcs) |> !cc |> %B.o ../ diff --git a/examples/gcc/gmp/tup.config b/examples/gcc/gmp/tup.config new file mode 100644 index 0000000..d97795b --- /dev/null +++ b/examples/gcc/gmp/tup.config @@ -0,0 +1,108 @@ +# GMP 6.2.1 - x86-64 Linux config.h defines +# +# Prefix-free: scoped config merging namespaces these under gmp/. +# @(HAVE_ALLOCA) in gmp/ resolves from this file. +# @(CC) in gmp/ resolves from the root tup.config. + +# Architecture +CONFIG_LIMB_BITS=64 +CONFIG_NAIL_BITS=0 + +# MPN CPU target: "generic" for pure C, or a CPU path like "x86_64" or "x86_64/core2" +CONFIG_MPN_CPU=generic +CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h + +# 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_HIDDEN_ALIAS=1 +CONFIG_HAVE_HOST_CPU_FAMILY_x86_64=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_OBSTACK_VPRINTF=1 +CONFIG_HAVE_POPEN=1 +CONFIG_HAVE_PTRDIFF_T=1 +CONFIG_HAVE_QUAD_T=1 +CONFIG_HAVE_RAISE=1 +CONFIG_HAVE_SIGACTION=1 +CONFIG_HAVE_SIGALTSTACK=1 +CONFIG_HAVE_SIGNAL_H=1 +CONFIG_HAVE_SIGSTACK=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_SYSINFO_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_NO_ASM=1 +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 diff --git a/examples/gcc/mpc/Tupfile b/examples/gcc/mpc/Tupfile new file mode 100644 index 0000000..1bc5ab6 --- /dev/null +++ b/examples/gcc/mpc/Tupfile @@ -0,0 +1,5 @@ +include_rules + +# MPC 1.2.1 - generated files + +: |> !gen-config |> config.h diff --git a/examples/gcc/mpc/Tuprules.tup b/examples/gcc/mpc/Tuprules.tup new file mode 100644 index 0000000..43575ae --- /dev/null +++ b/examples/gcc/mpc/Tuprules.tup @@ -0,0 +1,20 @@ +# MPC build rules (self-contained with ?= defaults) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +AR ?= ar +GMP_DIR ?= ../gmp +MPFR_DIR ?= ../mpfr +MPC_DIR ?= . + +CFLAGS = -O2 -std=gnu11 -DHAVE_CONFIG_H +CFLAGS += -I$(B)/$(MPC_DIR) -I$(S)/$(MPC_DIR)/src +CFLAGS += -I$(B)/$(MPFR_DIR) -I$(B)/$(MPFR_DIR)/src -I$(S)/$(MPFR_DIR)/src +CFLAGS += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) + +!cc = | $(S)/$(GMP_DIR)/ $(S)/$(MPFR_DIR)/ $(S)/$(MPC_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/mpc/src/Tupfile b/examples/gcc/mpc/src/Tupfile new file mode 100644 index 0000000..b0c5fea --- /dev/null +++ b/examples/gcc/mpc/src/Tupfile @@ -0,0 +1,25 @@ +include_rules + +# MPC 1.2.1 - all library sources + +srcs = abs.c acos.c acosh.c add.c add_fr.c add_si.c add_ui.c arg.c +srcs += asin.c asinh.c atan.c atanh.c +srcs += clear.c cmp.c cmp_abs.c cmp_si_si.c conj.c cos.c cosh.c +srcs += div.c div_2si.c div_2ui.c div_fr.c div_ui.c dot.c +srcs += exp.c fma.c fr_div.c fr_sub.c +srcs += get_prec.c get_prec2.c get_version.c get_x.c +srcs += imag.c init2.c init3.c inp_str.c +srcs += log.c log10.c mem.c +srcs += mul.c mul_2si.c mul_2ui.c mul_fr.c mul_i.c mul_si.c mul_ui.c +srcs += neg.c norm.c out_str.c +srcs += pow.c pow_d.c pow_fr.c pow_ld.c pow_si.c pow_ui.c pow_z.c +srcs += proj.c real.c rootofunity.c +srcs += set.c set_prec.c set_str.c set_x.c set_x_x.c +srcs += sin.c sin_cos.c sinh.c sqr.c sqrt.c strtoc.c +srcs += sub.c sub_fr.c sub_ui.c sum.c swap.c +srcs += tan.c tanh.c uceil_log2.c ui_div.c ui_ui_sub.c urandom.c + +: foreach $(srcs) |> !cc |> + +# Archive +: |> ^ AR %o^ $(AR) rcs %o % |> libmpc.a $(S)/ diff --git a/examples/gcc/mpc/tup.config b/examples/gcc/mpc/tup.config new file mode 100644 index 0000000..89aa987 --- /dev/null +++ b/examples/gcc/mpc/tup.config @@ -0,0 +1,24 @@ +# MPC 1.2.1 - x86-64 Linux config.h defines +# +# Prefix-free: scoped config merging namespaces these under mpc/. + +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/gcc/mpfr/Tupfile b/examples/gcc/mpfr/Tupfile new file mode 100644 index 0000000..27d9bc1 --- /dev/null +++ b/examples/gcc/mpfr/Tupfile @@ -0,0 +1,11 @@ +include_rules + +# MPFR 4.1.0 - generated files + +: |> !gen-config |> config.h + +# mparam.h - architecture-specific tuning (auto-selects via compiler macros) +: src/mparam_h.in |> ^ GEN %o^ cp %f %o |> src/mparam.h + +# get_patches.c - empty patch list +: |> ^ GEN %o^ printf '#include \nconst char * const mpfr_patches[] = { NULL };\n' > %o |> src/get_patches.c diff --git a/examples/gcc/mpfr/Tuprules.tup b/examples/gcc/mpfr/Tuprules.tup new file mode 100644 index 0000000..35f792a --- /dev/null +++ b/examples/gcc/mpfr/Tuprules.tup @@ -0,0 +1,18 @@ +# MPFR build rules (self-contained with ?= defaults) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +AR ?= ar +GMP_DIR ?= ../gmp +MPFR_DIR ?= . + +CFLAGS = -O2 -std=gnu11 -DHAVE_CONFIG_H +CFLAGS += -I$(B)/$(MPFR_DIR) -I$(B)/$(MPFR_DIR)/src -I$(S)/$(MPFR_DIR)/src +CFLAGS += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) + +!cc = | $(S)/$(GMP_DIR)/ $(S)/$(MPFR_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/mpfr/src/Tupfile b/examples/gcc/mpfr/src/Tupfile new file mode 100644 index 0000000..c2c200b --- /dev/null +++ b/examples/gcc/mpfr/src/Tupfile @@ -0,0 +1,56 @@ +include_rules + +# MPFR 4.1.0 - all library sources + +srcs = abort_prec_max.c acos.c acosh.c add.c add1.c add1sp.c add_d.c add_ui.c +srcs += agm.c ai.c asin.c asinh.c atan.c atan2.c atanh.c +srcs += bernoulli.c beta.c buildopt.c +srcs += cache.c cbrt.c check.c clear.c clears.c +srcs += cmp.c cmp2.c cmpabs.c cmpabs_ui.c cmp_d.c cmp_ld.c cmp_si.c cmp_ui.c +srcs += comparisons.c constant.c const_catalan.c const_euler.c const_log2.c const_pi.c +srcs += copysign.c cos.c cosh.c cot.c coth.c csc.c csch.c +srcs += d_div.c d_sub.c digamma.c dim.c +srcs += div.c div_2exp.c div_2si.c div_2ui.c div_d.c div_ui.c dot.c dump.c +srcs += eint.c eq.c erandom.c erf.c erfc.c exceptions.c +srcs += exp.c exp10.c exp_2.c exp2.c exp3.c expm1.c extract.c +srcs += factorial.c fits_intmax.c fits_sint.c fits_slong.c fits_sshort.c +srcs += fits_uint.c fits_uintmax.c fits_ulong.c fits_ushort.c +srcs += fma.c fmma.c fms.c fpif.c frac.c free_cache.c frexp.c +srcs += gamma.c gamma_inc.c gammaonethird.c get_d.c get_d128.c get_d64.c +srcs += get_exp.c get_f.c get_float128.c get_flt.c get_ld.c get_q.c +srcs += get_si.c get_sj.c get_str.c get_ui.c get_uj.c get_z.c get_z_exp.c +srcs += gmp_op.c grandom.c hypot.c +srcs += init.c init2.c inits.c inits2.c inp_str.c int_ceil_log2.c +srcs += isinf.c isinteger.c isnan.c isnum.c isqrt.c isregular.c iszero.c +srcs += jn.c li2.c lngamma.c +srcs += log.c log10.c log1p.c log2.c log_ui.c logging.c +srcs += min_prec.c minmax.c modf.c mp_clz_tab.c mpfr-gmp.c mpfr-mini-gmp.c mpn_exp.c +srcs += mul.c mul_2exp.c mul_2si.c mul_2ui.c mul_d.c mulders.c mul_ui.c +srcs += nbits_ulong.c neg.c next.c nrandom.c odd_p.c out_str.c pool.c +srcs += pow.c pow_si.c pow_ui.c pow_z.c powerof2.c +srcs += printf.c print_raw.c print_rnd_mode.c +srcs += random_deviate.c rec_sqrt.c reldiff.c rem1.c rint.c rndna.c root.c +srcs += round_near_x.c round_p.c round_prec.c +srcs += scale2.c sec.c sech.c +srcs += set.c set_d.c set_d128.c set_d64.c set_dfl_prec.c set_exp.c set_f.c +srcs += set_float128.c set_flt.c set_inf.c set_ld.c +srcs += set_nan.c set_prc_raw.c set_prec.c set_q.c set_rnd.c +srcs += set_si.c set_si_2exp.c set_sj.c set_str.c set_str_raw.c +srcs += set_ui.c set_ui_2exp.c set_uj.c set_z.c set_z_exp.c set_zero.c +srcs += setmax.c setmin.c setsign.c sgn.c signbit.c +srcs += si_op.c sin.c sin_cos.c sinh.c sinh_cosh.c sqr.c sqrt.c sqrt_ui.c +srcs += stack_interface.c strtofr.c sub.c sub1.c sub1sp.c sub_d.c sub_ui.c +srcs += subnormal.c sum.c swap.c +srcs += tan.c tanh.c total_order.c ubf.c +srcs += uceil_exp2.c uceil_log2.c ufloor_log2.c +srcs += ui_div.c ui_pow.c ui_pow_ui.c ui_sub.c +srcs += urandom.c urandomb.c vasprintf.c version.c volatile.c +srcs += yn.c zeta.c zeta_ui.c + +# Generated source +srcs += get_patches.c + +: foreach $(srcs) |> !cc |> + +# Archive +: |> ^ AR %o^ $(AR) rcs %o % |> libmpfr.a $(S)/ diff --git a/examples/gcc/mpfr/tup.config b/examples/gcc/mpfr/tup.config new file mode 100644 index 0000000..96a7432 --- /dev/null +++ b/examples/gcc/mpfr/tup.config @@ -0,0 +1,31 @@ +# MPFR 4.1.0 - x86-64 Linux config.h defines +# +# Prefix-free: scoped config merging namespaces these under mpfr/. + +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/gcc/scripts/resolve-mpn.sh b/examples/gcc/scripts/resolve-mpn.sh new file mode 100755 index 0000000..4df0079 --- /dev/null +++ b/examples/gcc/scripts/resolve-mpn.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# resolve-mpn.sh — Resolve GMP mpn sources for a given CPU target +# +# Usage: resolve-mpn.sh +# +# Outputs tup.config entries to stdout for gmp/mpn/tup.config. +# Generic mode emits all C sources with template functions enabled. +# Assembly mode walks the priority chain, emitting per-function y/n +# toggles for the foo-y conditional compilation pattern. + +set -e + +cpu="$1" +mpn_src="$2" + +if [ -z "$cpu" ] || [ -z "$mpn_src" ]; then + echo "Usage: resolve-mpn.sh " >&2 + exit 1 +fi + +# --- Multi-function file → output function mapping --- +# Static across all architectures. Only the directory changes. + +multi_funcs() { + case "$1" in + aors_n) echo "add_n sub_n" ;; + aorsmul_1) echo "addmul_1 submul_1" ;; + aors_err1_n) echo "add_err1_n sub_err1_n" ;; + aors_err2_n) echo "add_err2_n sub_err2_n" ;; + aors_err3_n) echo "add_err3_n sub_err3_n" ;; + logops_n) echo "and_n andn_n ior_n iorn_n nand_n nior_n xnor_n xor_n" ;; + popham) echo "popcount hamdist" ;; + sec_aors_1) echo "sec_add_1 sec_sub_1" ;; + esac +} + +is_multi_asm() { + case "$1" in + aors_n|aorsmul_1|aors_err1_n|aors_err2_n|aors_err3_n) return 0 ;; + logops_n|popham|sec_aors_1) return 0 ;; + *) return 1 ;; + esac +} + +is_template_file() { + case "$1" in + logops_n|popham|sec_aors_1|sec_div|sec_pi1_div) return 0 ;; + *) return 1 ;; + esac +} + +# All template output functions (16 total) +all_template_funcs="and_n andn_n ior_n iorn_n nand_n nior_n xnor_n xor_n +popcount hamdist sec_add_1 sec_sub_1 sec_div_qr sec_div_r sec_pi1_div_qr sec_pi1_div_r" + +# --- Generic mode --- + +if [ "$cpu" = "generic" ]; then + c_files="" + for f in "$mpn_src"/generic/*.c; do + [ -f "$f" ] || continue + func=$(basename "$f" .c) + is_template_file "$func" && continue + c_files="${c_files:+$c_files }generic/$(basename "$f")" + done + + echo "CONFIG_MPN_ARCH=generic" + echo "CONFIG_MPN_SUBDIR=generic" + echo "CONFIG_C_SOURCES=$c_files" + echo "CONFIG_ASM_SOURCES=" + for func in $all_template_funcs; do + echo "CONFIG_C_$func=y" + done + exit 0 +fi + +# --- Assembly mode --- + +arch="${cpu%%/*}" +if [ "$cpu" = "$arch" ]; then + cpu_subdir="" +else + cpu_subdir="${cpu#*/}" +fi + +# Walk priority chain: cpu-specific dir → arch dir. +# Higher priority wins; once a function is resolved, lower levels skip it. +asm_funcs="" # all functions with asm (for C exclusion) +single_asm_files="" # single-function .asm paths (for ASM_SOURCES) +multi_asm_funcs="" # functions from multi-function .asm (for CONFIG_ASM_ entries) + +collect_asm() { + dir="$1" + full="$mpn_src/$dir" + [ -d "$full" ] || return 0 + for f in "$full"/*.asm; do + [ -f "$f" ] || continue + base=$(basename "$f" .asm) + + if is_multi_asm "$base"; then + funcs=$(multi_funcs "$base") + any_new=false + for func in $funcs; do + case " $asm_funcs " in + *" $func "*) ;; + *) any_new=true; break ;; + esac + done + $any_new || continue + + for func in $funcs; do + case " $asm_funcs " in + *" $func "*) ;; + *) asm_funcs="$asm_funcs $func" + multi_asm_funcs="$multi_asm_funcs $func" ;; + esac + done + else + case " $asm_funcs " in + *" $base "*) continue ;; + esac + asm_funcs="$asm_funcs $base" + single_asm_files="${single_asm_files:+$single_asm_files }$dir/$(basename "$f")" + fi + done +} + +if [ -n "$cpu_subdir" ]; then + collect_asm "$arch/$cpu_subdir" +fi +collect_asm "$arch" + +# Collect generic C sources, excluding: +# - Functions replaced by asm (single or multi-function) +# - Template source files (handled by foo-y rules) +c_files="" +for f in "$mpn_src"/generic/*.c; do + [ -f "$f" ] || continue + func=$(basename "$f" .c) + is_template_file "$func" && continue + skip=false + for af in $asm_funcs; do + if [ "$func" = "$af" ]; then + skip=true + break + fi + done + $skip || c_files="${c_files:+$c_files }generic/$(basename "$f")" +done + +# --- Output tup.config entries --- + +echo "CONFIG_MPN_ARCH=$arch" +echo "CONFIG_MPN_SUBDIR=$cpu_subdir" +echo "CONFIG_C_SOURCES=$c_files" +echo "CONFIG_ASM_SOURCES=$single_asm_files" + +# Per-function asm toggles (multi-function asm outputs only) +for func in $multi_asm_funcs; do + echo "CONFIG_ASM_$func=y" +done + +# Template C toggles: y when no asm, n when asm replaces it +for func in $all_template_funcs; do + case " $asm_funcs " in + *" $func "*) echo "CONFIG_C_$func=n" ;; + *) echo "CONFIG_C_$func=y" ;; + esac +done diff --git a/src/cli/cmd_configure.cpp b/src/cli/cmd_configure.cpp index 6395589..8eee485 100644 --- a/src/cli/cmd_configure.cpp +++ b/src/cli/cmd_configure.cpp @@ -47,10 +47,10 @@ auto install_source_configs( ProjectLayout const& layout, std::string_view variant_name, bool verbose -) -> int +) -> void { if (layout.config_root == layout.output_root) { - return 0; + return; } auto config_canonical = std::filesystem::weakly_canonical(layout.config_root); @@ -60,8 +60,9 @@ auto install_source_configs( for (auto it = std::filesystem::recursive_directory_iterator(config_canonical, ec); it != std::filesystem::recursive_directory_iterator(); - ++it) { + it.increment(ec)) { if (ec) { + fprintf(stderr, "[%.*s] Warning: error scanning configs: %s\n", static_cast(variant_name.size()), variant_name.data(), ec.message().c_str()); break; } @@ -91,7 +92,6 @@ auto install_source_configs( if (count > 0) { printf("[%.*s] Installed %d source config(s)\n", static_cast(variant_name.size()), variant_name.data(), count); } - return count; } auto configure_single_variant( From bf84476586998fec595975bcde2e4af8463a65a5 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:42:14 +0800 Subject: [PATCH 02/16] Extend GCC example: build cc1 C compiler from source Add libiberty, libdecnumber, libbacktrace, libcpp libraries and the full gcc/ build pipeline (config headers, ~25 generator programs, ~500 backend objects, cc1 link) to the GCC example. The generator bootstrap chain builds genmodes first, then BUILD_RTL support objects, then all RTL generators that produce insn-*.h and insn-*.cc from machine description files. Pre-generated files from gengtype and genmatch are expected in gcc/pre-generated/. Co-Authored-By: Claude Opus 4.6 --- examples/gcc/Makefile.pup | 4 +- examples/gcc/README.md | 235 ++++---- examples/gcc/Tupfile | 23 +- examples/gcc/Tuprules.tup | 12 +- examples/gcc/configs/aarch64-linux.config | 3 +- examples/gcc/configs/x86_64-linux.config | 3 +- examples/gcc/gcc/Tupfile | 687 ++++++++++++++++++++++ examples/gcc/gcc/Tuprules.tup | 61 ++ examples/gcc/gcc/analyzer/Tupfile | 28 + examples/gcc/gcc/c-family/Tupfile | 22 + examples/gcc/gcc/c/Tupfile | 12 + examples/gcc/gcc/config/i386/Tupfile | 24 + examples/gcc/gcc/tup.config | 127 ++++ examples/gcc/libbacktrace/Tupfile | 29 + examples/gcc/libbacktrace/Tuprules.tup | 17 + examples/gcc/libbacktrace/tup.config | 53 ++ examples/gcc/libcpp/Tupfile | 24 + examples/gcc/libcpp/Tuprules.tup | 19 + examples/gcc/libcpp/tup.config | 93 +++ examples/gcc/libdecnumber/Tupfile | 25 + examples/gcc/libdecnumber/Tuprules.tup | 17 + examples/gcc/libdecnumber/tup.config | 8 + examples/gcc/libiberty/Tupfile | 41 ++ examples/gcc/libiberty/Tuprules.tup | 21 + examples/gcc/libiberty/tup.config | 145 +++++ 25 files changed, 1616 insertions(+), 117 deletions(-) create mode 100644 examples/gcc/gcc/Tupfile create mode 100644 examples/gcc/gcc/Tuprules.tup create mode 100644 examples/gcc/gcc/analyzer/Tupfile create mode 100644 examples/gcc/gcc/c-family/Tupfile create mode 100644 examples/gcc/gcc/c/Tupfile create mode 100644 examples/gcc/gcc/config/i386/Tupfile create mode 100644 examples/gcc/gcc/tup.config create mode 100644 examples/gcc/libbacktrace/Tupfile create mode 100644 examples/gcc/libbacktrace/Tuprules.tup create mode 100644 examples/gcc/libbacktrace/tup.config create mode 100644 examples/gcc/libcpp/Tupfile create mode 100644 examples/gcc/libcpp/Tuprules.tup create mode 100644 examples/gcc/libcpp/tup.config create mode 100644 examples/gcc/libdecnumber/Tupfile create mode 100644 examples/gcc/libdecnumber/Tuprules.tup create mode 100644 examples/gcc/libdecnumber/tup.config create mode 100644 examples/gcc/libiberty/Tupfile create mode 100644 examples/gcc/libiberty/Tuprules.tup create mode 100644 examples/gcc/libiberty/tup.config diff --git a/examples/gcc/Makefile.pup b/examples/gcc/Makefile.pup index 36be17e..f599f64 100644 --- a/examples/gcc/Makefile.pup +++ b/examples/gcc/Makefile.pup @@ -1,7 +1,7 @@ -# Makefile.pup - Build GCC prerequisite libraries with putup +# Makefile.pup - Build GCC's cc1 C compiler with putup # # Usage: -# make -f Makefile.pup # Build GMP + MPFR + MPC +# make -f Makefile.pup # Build cc1 (all libraries + compiler) # make -f Makefile.pup clean # Clean build artifacts # make -f Makefile.pup distclean # Full clean # diff --git a/examples/gcc/README.md b/examples/gcc/README.md index 0e2b200..d7b7071 100644 --- a/examples/gcc/README.md +++ b/examples/gcc/README.md @@ -1,6 +1,8 @@ -# GCC Prerequisite Libraries +# GCC cc1 — C Compiler from Source -Build GCC's bundled [GMP](https://gmplib.org/), [MPFR](https://www.mpfr.org/), and [MPC](http://www.multiprecision.org/mpc/) libraries using putup. +Build GCC's `cc1` C compiler from the GCC 15.2.0 source tree using putup. +This builds everything from source: prerequisite math libraries, compiler support +libraries, ~25 host generator programs, and the ~500-file cc1 backend. ## Quick Start @@ -11,47 +13,88 @@ wget https://gcc.gnu.org/pub/gcc/releases/gcc-15.2.0/gcc-15.2.0.tar.xz tar xf gcc-15.2.0.tar.xz cd gcc-15.2.0 && ./contrib/download_prerequisites && cd .. -# 2. Build (3-tree: -C = Tupfiles, -S = GCC sources, -B = output) -cd examples/gcc -make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc -``` +# 2. Generate pre-generated files (gengtype/genmatch outputs) +cd gcc-15.2.0 && mkdir build && cd build +../configure --disable-bootstrap --enable-languages=c && make -j$(nproc) +cd ../.. -Or directly (after running resolve-mpn): +# 3. Copy pre-generated files into the example +cd examples/gcc +cp /path/to/gcc-15.2.0/build/gcc/gtype-desc.cc gcc/pre-generated/ +cp /path/to/gcc-15.2.0/build/gcc/gt-*.h gcc/pre-generated/ +cp /path/to/gcc-15.2.0/build/gcc/gtype-desc.h gcc/pre-generated/ +cp /path/to/gcc-15.2.0/build/gcc/gimple-match-*.cc gcc/pre-generated/ +cp /path/to/gcc-15.2.0/build/gcc/generic-match-*.cc gcc/pre-generated/ -```bash -scripts/resolve-mpn.sh generic /path/to/gcc-15.2.0/gmp/mpn > gmp/mpn/tup.config -putup configure --config configs/x86_64-linux.config -C . -S /path/to/gcc-15.2.0 -B build -putup -C . -S /path/to/gcc-15.2.0 -B build +# 4. Build cc1 +make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc ``` ## What Gets Built -| Library | Version | Output | -|---------|---------|--------| -| GMP | 6.2.1 | `build/gmp/libgmp.a` | -| MPFR | 4.1.0 | `build/mpfr/src/libmpfr.a` | -| MPC | 1.2.1 | `build/mpc/src/libmpc.a` | +``` +Phase 1-4 (independent libraries, parallel): + gmp/ → libgmp.a Math library + mpfr/ → libmpfr.a Multi-precision floats (needs GMP) + mpc/ → libmpc.a Complex arithmetic (needs GMP + MPFR) + libiberty/ → libiberty.a Utility library + libdecnumber/ → libdecnumber.a Decimal floating-point (DPD variant) + libbacktrace/ → libbacktrace.a Stack unwinding (ELF/mmap) + libcpp/ → libcpp.a C preprocessor + +Phase 5 (generators, need libiberty): + gcc/ → genmodes, genattr, genemit, genrecog, ... (~25 host programs) + → insn-*.h, insn-*.cc (generated machine descriptions) + +Phase 6 (cc1, needs everything): + gcc/ → cc1 C compiler (~500 objects) +``` ## Dependency Chain ``` -GMP (no deps) → libgmp.a - ↓ -MPFR (needs GMP headers) → libmpfr.a - ↓ -MPC (needs GMP + MPFR headers) → libmpc.a +GMP ──────────────────────────────────→ libgmp.a ──→ cc1 + ↓ ↑ +MPFR (needs GMP) ─────────────────→ libmpfr.a ────────┘ + ↓ ↑ +MPC (needs GMP + MPFR) ──────────→ libmpc.a ──────────┘ + ↑ +libiberty ─→ libiberty.a ─→ generators ─→ insn-*.h ───┘ + ↓ ↑ ↑ +libdecnumber ──────────────→ libdecnumber.a ┘ │ +libbacktrace ──────────────→ libbacktrace.a ───────────┘ + ↑ +libcpp ────────────────────→ libcpp.a ─────────────────┘ ``` +## Pre-generated Files + +Two GCC generators are too complex to implement initially: + +- **gengtype** scans all source files to produce GC type descriptors + (`gtype-desc.cc`, `gtype-desc.h`, `gt-*.h`) +- **genmatch** depends on libcpp and produces pattern matchers + (`gimple-match-*.cc`, `generic-match-*.cc`) + +These must be copied from a configured GCC build into `gcc/pre-generated/`. +The outputs are target-independent (gengtype) or stable across x86_64 builds +(genmatch), so they only need to be generated once. + ## Per-Component Configuration Each library has its own `tup.config` with prefix-free entries. The directory scope provides the namespace via scoped config merging: ``` -configs/x86_64-linux.config → Root: CC, AR, HOSTCC (toolchain) +configs/x86_64-linux.config → Root: CC, CXX, AR, HOSTCC (toolchain) gmp/tup.config → GMP: HAVE_ALLOCA, SIZEOF_UNSIGNED_LONG, ... mpfr/tup.config → MPFR: HAVE_ALLOCA, HAVE_VA_COPY, ... mpc/tup.config → MPC: HAVE_INTTYPES_H, HAVE_LOCALECONV, ... +libiberty/tup.config → libiberty: HAVE_SBRK, HAVE_MMAP, ... +libdecnumber/tup.config → libdecnumber: endianness, float format +libbacktrace/tup.config → libbacktrace: BACKTRACE_ELF_SIZE, HAVE_DL_ITERATE_PHDR, ... +libcpp/tup.config → libcpp: HAVE_ICONV, ENABLE_NLS, ... +gcc/tup.config → GCC: HOST_BITS_PER_*, SIZEOF_*, HAVE_*, ... ``` `putup configure --config` installs the root config and copies subdir configs to the @@ -96,62 +139,25 @@ Or via the Makefile: make -f Makefile.pup multi SRCDIR=../gcc-15.2.0 ``` -Per-library tup.config files are shared across variants — only the root toolchain -config differs. Each `-B` directory gets its own copy of the subdir configs via -`putup configure`. +## Generator Bootstrap -### Adding a New Platform +GCC generates machine-specific code from `.md` (machine description) files. +The generators form a bootstrap chain: -Create a new toolchain config file: - -```bash -cp configs/x86_64-linux.config configs/myplatform.config -# Edit toolchain vars (CC, AR, HOSTCC) -make -f Makefile.pup PLATFORM=myplatform ``` +genmodes (no RTL deps) + → insn-modes.h, insn-modes-inline.h, min-insn-modes.cc + → compile min-insn-modes.o -Per-library configs are platform-independent for this generic C build. For platforms -needing different feature detection, override individual library configs. +BUILD_RTL objects (need min-insn-modes.o) + → rtl.o, read-md.o, read-rtl.o, gensupport.o, ... -## Build Features Demonstrated +genconditions → gencondmd.cc → compile+link gencondmd → insn-conditions.md -- **Assembly support**: CPU-specific `.asm → m4 → assembler` pipeline with config-driven source selection -- **foo-y conditional compilation**: Kbuild-inspired pattern for toggling multi-function sources without `ifeq` -- **Multi-variant parallel builds**: Multiple `-B` directories built simultaneously with different toolchain configs -- **Per-component scoped configs**: Each library has its own `tup.config`, merged with root via scoped config merging -- **Prefix-free config entries**: No `CONFIG_GMP_` prefix needed; directory scope provides the namespace -- **Multi-directory builds**: GMP spans 8 subdirectories, each with its own Tupfile -- **Host tool generation**: GMP table generators compiled and run during the build -- **3-tree builds**: Tupfiles, GCC sources, and build output in separate directories (`-C`, `-S`, `-B`) -- **Cross-directory groups**: Subdirectory objects collected via `../` into parent -- **Header generation**: gmp.h generated from template via sed with `@()` substitutions -- **Inter-library dependencies**: Order-only groups ensure correct build ordering -- **Self-contained libraries**: Each library has its own `Tuprules.tup` with `?=` defaults; buildable alone or composed -- **Nested `include_rules`**: Root `Tuprules.tup` sets toolchain, per-library `Tuprules.tup` adds flags and bang macros - -## Files - -| File | Purpose | -|------|---------| -| `Makefile.pup` | Make wrapper for putup commands (`PLATFORM`, `MPN_CPU`) | -| `scripts/resolve-mpn.sh` | Resolve mpn sources for a CPU target | -| `Tupfile.ini` | Project root marker | -| `Tuprules.tup` | Toolchain vars (CC, AR, HOSTCC), library directory names | -| `configs/x86_64-linux.config` | Toolchain config (x86-64 Linux, native) | -| `configs/aarch64-linux.config` | Toolchain config (AArch64 Linux, cross) | -| `gmp/tup.config` | GMP platform config + assembly flags (`GMP_MPARAM`, `ASM_ENABLED`) | -| `gmp/mpn/tup.config` | MPN source resolution (generated by `scripts/resolve-mpn.sh`) | -| `gmp/Tuprules.tup` | GMP CFLAGS, `!cc`, `!m4asm`, `!gen-config` | -| `mpfr/tup.config` | MPFR platform config (prefix-free) | -| `mpfr/Tuprules.tup` | MPFR CFLAGS, `!cc`, `!gen-config` | -| `mpc/tup.config` | MPC platform config (prefix-free) | -| `mpc/Tuprules.tup` | MPC CFLAGS, `!cc`, `!gen-config` | -| `gmp/Tupfile` | GMP config generation, table generators, top-level sources, archive | -| `gmp/{mpn,mpz,mpq,mpf,printf,scanf,rand}/Tupfile` | Per-directory compilation | -| `mpfr/Tupfile` | MPFR config generation | -| `mpfr/src/Tupfile` | MPFR source compilation + archive | -| `mpc/Tupfile` | MPC config generation | -| `mpc/src/Tupfile` | MPC source compilation + archive | +All other generators (read .md files, produce insn-*.h / insn-*.cc) + → genattr, genattrtab, genautomata, gencodes, genconfig, ... + → genemit (10 split outputs), genrecog (10 split outputs + header) +``` ## Assembly Support @@ -164,43 +170,60 @@ make -f Makefile.pup MPN_CPU=x86_64/core2 # CPU-specific assembly make -f Makefile.pup MPN_CPU=generic # Pure C (default) ``` -### How it works - -GMP ships per-CPU assembly routines under `mpn/` (e.g., `mpn/x86_64/`, `mpn/x86_64/core2/`). -The `.asm` files are m4 macros processed into assembly: - -``` -.asm → m4 (config.m4 + asm-defs.m4) → pipe → assembler → .o -``` - -The `resolve-mpn` target runs `scripts/resolve-mpn.sh` to walk GMP's priority chain -(`x86_64/core2 → x86_64 → generic`), picking the best available implementation for -each mpn function. Functions without assembly automatically fall back to generic C. - -This produces two config files: - -| File | Scope | Contents | -|------|-------|----------| -| `gmp/mpn/tup.config` | mpn/ subdirectory | Source lists, per-function y/n toggles | -| `gmp/tup.config` | gmp/ directory | `CONFIG_GMP_MPARAM`, `CONFIG_ASM_ENABLED` | - -### The foo-y pattern - -Multi-function sources (one `.asm` or `.c` producing multiple `.o` via `-DOPERATION_`) -use the Kbuild-inspired `foo-y` conditional compilation pattern: +## Files -```tup -# Variable is non-empty when CONFIG_ASM_add_n=y, empty when unset -aors_add_n-@(ASM_add_n) = x86_64/aors_n.asm +| File | Purpose | +|------|---------| +| `Makefile.pup` | Make wrapper for putup commands | +| `scripts/resolve-mpn.sh` | Resolve mpn sources for a CPU target | +| `Tupfile.ini` | Project root marker | +| `Tuprules.tup` | Toolchain vars (CC, CXX, AR, HOSTCC), directory names | +| `configs/x86_64-linux.config` | Toolchain config (x86-64 Linux, native) | +| `configs/aarch64-linux.config` | Toolchain config (AArch64 Linux, cross) | +| **GMP** | | +| `gmp/{Tuprules.tup,tup.config,Tupfile}` | Config, rules, top-level sources | +| `gmp/{mpn,mpz,mpq,mpf,printf,scanf,rand}/Tupfile` | Per-directory compilation | +| **MPFR** | | +| `mpfr/{Tuprules.tup,tup.config,Tupfile}` | Config generation | +| `mpfr/src/Tupfile` | Source compilation + archive | +| **MPC** | | +| `mpc/{Tuprules.tup,tup.config,Tupfile}` | Config generation | +| `mpc/src/Tupfile` | Source compilation + archive | +| **libiberty** | | +| `libiberty/{Tuprules.tup,tup.config,Tupfile}` | Utility library | +| **libdecnumber** | | +| `libdecnumber/{Tuprules.tup,tup.config,Tupfile}` | Decimal number library | +| **libbacktrace** | | +| `libbacktrace/{Tuprules.tup,tup.config,Tupfile}` | Backtrace library | +| **libcpp** | | +| `libcpp/{Tuprules.tup,tup.config,Tupfile}` | C preprocessor library | +| **GCC (cc1)** | | +| `gcc/{Tuprules.tup,tup.config,Tupfile}` | Config headers, generators, backend | +| `gcc/c/Tupfile` | C frontend objects | +| `gcc/c-family/Tupfile` | C-family shared objects | +| `gcc/analyzer/Tupfile` | Static analyzer objects | +| `gcc/config/i386/Tupfile` | x86_64 target-specific objects | +| `gcc/pre-generated/` | gengtype + genmatch outputs | -# foreach over a possibly-empty variable: 0 or 1 rules, no conditionals -: foreach $(aors_add_n-y) |> ... -DOPERATION_add_n ... |> add_n.o -``` +## Build Features Demonstrated -This keeps `gmp/mpn/Tupfile` completely conditional-free — all source selection is -driven by tup.config entries, resolved once at configure time. +- **Host-tool bootstrapping**: ~25 generator programs compiled and run during the build +- **Generated source pipeline**: `.md` → generators → `insn-*.h` / `insn-*.cc` → cc1 +- **Multi-output generators**: genemit produces 10 split files, genrecog produces 10 + header +- **~500-file C++ compilation**: Full GCC backend with analyzer, C frontend, target-specific code +- **Cross-directory groups**: Subdirectory objects collected via `../` into parent +- **Assembly support**: CPU-specific `.asm → m4 → assembler` pipeline with config-driven source selection +- **foo-y conditional compilation**: Kbuild-inspired pattern for toggling multi-function sources without `ifeq` +- **Multi-variant parallel builds**: Multiple `-B` directories built simultaneously with different toolchain configs +- **Per-component scoped configs**: Each library has its own `tup.config`, merged with root via scoped config merging +- **Multi-directory builds**: 15+ subdirectories, each with its own Tupfile +- **3-tree builds**: Tupfiles, GCC sources, and build output in separate directories (`-C`, `-S`, `-B`) +- **Self-contained libraries**: Each library has its own `Tuprules.tup` with `?=` defaults; buildable alone or composed +- **Nested `include_rules`**: Root `Tuprules.tup` sets toolchain, per-library `Tuprules.tup` adds flags and bang macros +- **Inter-library dependencies**: Order-only groups ensure correct build ordering ## Notes -- Requires: gcc (or compatible C compiler), m4 (for assembly mode) -- MPFR's `mpfr-mini-gmp.c` compiles to empty when not using mini-gmp mode +- Requires: gcc, g++, m4 (for GMP assembly mode), gawk (for GCC options pipeline) +- Target: x86_64-linux native (host == target) +- Pre-generated files must be provided from a configured GCC build (see Quick Start) diff --git a/examples/gcc/Tupfile b/examples/gcc/Tupfile index f8919fb..5ebc6c9 100644 --- a/examples/gcc/Tupfile +++ b/examples/gcc/Tupfile @@ -1,7 +1,22 @@ include_rules # Root Tupfile - nothing to do here -# Libraries are built by their respective Tupfiles: -# gmp/Tupfile → libgmp.a -# mpfr/src/Tupfile → libmpfr.a -# mpc/src/Tupfile → libmpc.a +# Components are built by their respective Tupfiles: +# +# Prerequisite libraries: +# gmp/Tupfile → libgmp.a +# mpfr/src/Tupfile → libmpfr.a +# mpc/src/Tupfile → libmpc.a +# +# Compiler support libraries: +# libiberty/Tupfile → libiberty.a +# libdecnumber/Tupfile → libdecnumber.a +# libbacktrace/Tupfile → libbacktrace.a +# libcpp/Tupfile → libcpp.a +# +# C compiler: +# gcc/Tupfile → cc1 (config headers, generators, backend) +# gcc/c/Tupfile → C frontend objects +# gcc/c-family/Tupfile → C-family shared objects +# gcc/analyzer/Tupfile → Static analyzer objects +# gcc/config/i386/Tupfile → x86_64 target-specific objects diff --git a/examples/gcc/Tuprules.tup b/examples/gcc/Tuprules.tup index 1ce846a..415b520 100644 --- a/examples/gcc/Tuprules.tup +++ b/examples/gcc/Tuprules.tup @@ -1,16 +1,22 @@ -# Tuprules.tup - GCC in-tree library build (root rules) +# Tuprules.tup - GCC in-tree build (root rules) # # Sets project-wide variables from tup.config. -# Per-library CFLAGS, !cc, and !gen-config live in -# gmp/Tuprules.tup, mpfr/Tuprules.tup, mpc/Tuprules.tup. +# Per-library CFLAGS, !cc, and !gen-config live in each +# library's own Tuprules.tup (gmp/, mpfr/, mpc/, libiberty/, etc.). S = $(TUP_CWD) B = $(TUP_VARIANT_OUTPUTDIR)/$(S) CC = @(CC) +CXX = @(CXX) AR = @(AR) HOSTCC = @(HOSTCC) GMP_DIR = gmp MPFR_DIR = mpfr MPC_DIR = mpc +LIBIBERTY_DIR = libiberty +LIBCPP_DIR = libcpp +LIBDECNUMBER_DIR = libdecnumber +LIBBACKTRACE_DIR = libbacktrace +GCC_DIR = gcc diff --git a/examples/gcc/configs/aarch64-linux.config b/examples/gcc/configs/aarch64-linux.config index ca1ffb7..d925ae5 100644 --- a/examples/gcc/configs/aarch64-linux.config +++ b/examples/gcc/configs/aarch64-linux.config @@ -7,5 +7,6 @@ # Scoped config merging combines these with the toolchain vars below. CONFIG_CC=aarch64-linux-gnu-gcc +CONFIG_CXX=aarch64-linux-gnu-g++ CONFIG_AR=aarch64-linux-gnu-ar -CONFIG_HOSTCC=gcc +CONFIG_HOSTCC=g++ diff --git a/examples/gcc/configs/x86_64-linux.config b/examples/gcc/configs/x86_64-linux.config index c68ad12..a91299a 100644 --- a/examples/gcc/configs/x86_64-linux.config +++ b/examples/gcc/configs/x86_64-linux.config @@ -7,5 +7,6 @@ # Scoped config merging combines these with the toolchain vars below. CONFIG_CC=gcc +CONFIG_CXX=g++ CONFIG_AR=ar -CONFIG_HOSTCC=gcc +CONFIG_HOSTCC=g++ diff --git a/examples/gcc/gcc/Tupfile b/examples/gcc/gcc/Tupfile new file mode 100644 index 0000000..666d458 --- /dev/null +++ b/examples/gcc/gcc/Tupfile @@ -0,0 +1,687 @@ +include_rules + +# ============================================================ +# GCC 15.2.0 — C compiler backend (x86_64-linux) +# ============================================================ +# +# Builds cc1 from the GCC source tree via five phases: +# 1. Config headers + options pipeline +# 2. Generator bootstrap (genmodes → BUILD_RTL → generators) +# 3. Machine-description → insn-*.h / insn-*.cc +# 4. Backend + common object compilation +# 5. cc1 link +# +# Pre-generated files (gtype-desc.cc, gimple-match-*, generic-match-*) +# must be placed in pre-generated/ from a configured GCC build. + +SRC = $(S)/$(GCC_DIR) + +# Machine description inputs (x86_64-linux) +MD = common.md config/i386/i386.md + +# ============================================================ +# Phase 1: Config headers → +# ============================================================ + +# auto-host.h from tup.config +: |> !gen-config |> auto-host.h + +# bconfig.h — build-machine config (generators only) +: |> ^ GEN %o^ echo '#include "auto-host.h"' > %o |> bconfig.h + +# config.h — target config (not for generators) +: |> ^ GEN %o^ ( \ + echo '#ifndef GCC_CONFIG_H'; \ + echo '#define GCC_CONFIG_H'; \ + echo '#ifdef GENERATOR_FILE'; \ + echo '#error config.h is not for generator programs'; \ + echo '#endif'; \ + echo '#include "auto-host.h"'; \ + echo '#endif'; \ + ) > %o |> config.h + +# bversion.h +: |> ^ GEN %o^ ( \ + echo '#define BUILDING_GCC_MAJOR 15'; \ + echo '#define BUILDING_GCC_MINOR 2'; \ + echo '#define BUILDING_GCC_PATCHLEVEL 0'; \ + echo '#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)'; \ + ) > %o |> bversion.h + +# version.h +: |> ^ GEN %o^ ( \ + echo '#ifndef VERSION_H'; \ + echo '#define VERSION_H'; \ + echo '#define GCC_major_version 15'; \ + echo '#define version_string "15.2.0"'; \ + echo '#define pkgversion_string "(Tup) "'; \ + echo '#define bug_report_url ""'; \ + echo '#define GCOV_VERSION ((gcov_unsigned_t)0x4235322a)'; \ + echo '#endif'; \ + ) > %o |> version.h + +# configargs.h — configure arguments (stub for tup build) +: |> ^ GEN %o^ ( \ + echo 'static const char configuration_arguments[] = "tup-build x86_64-pc-linux-gnu";'; \ + echo 'static const char thread_model[] = "posix";'; \ + echo 'static const struct { const char *name, *value; } configure_default_options[] = { { NULL, NULL } };'; \ + ) > %o |> configargs.h + +# --- Options pipeline --- +# .opt files → optionlist → options.h, options.cc, options-save.cc, options-urls.cc + +OPT_FILES = c-family/c.opt common.opt params.opt analyzer/analyzer.opt +OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt + +: $(OPT_FILES) |> ^ GEN optionlist^ \ + LC_ALL=C awk -f $(SRC)/opt-gather.awk %f > %o \ + |> optionlist + +: optionlist |> ^ GEN %o^ \ + awk -f $(SRC)/opt-functions.awk -f $(SRC)/opt-read.awk \ + -f $(SRC)/opth-gen.awk < %f > %o \ + |> options.h + +: optionlist |> ^ GEN %o^ \ + awk -f $(SRC)/opt-functions.awk -f $(SRC)/opt-read.awk \ + -f $(SRC)/optc-gen.awk \ + -v header_name="config.h system.h coretypes.h options.h tm.h" < %f > %o \ + |> options.cc + +: optionlist |> ^ GEN %o^ \ + awk -f $(SRC)/opt-functions.awk -f $(SRC)/opt-read.awk \ + -f $(SRC)/optc-save-gen.awk \ + -v header_name="config.h system.h coretypes.h tm.h" < %f > %o \ + |> options-save.cc + +: optionlist |> ^ GEN %o^ \ + awk -f $(SRC)/opt-functions.awk -f $(SRC)/opt-read.awk \ + -f $(SRC)/options-urls-cc-gen.awk \ + -v header_name="config.h system.h coretypes.h tm.h" < %f > %o \ + |> options-urls.cc + +# tm_p.h — target machine prototypes for x86_64-linux-gnu +: |> ^ GEN %o^ ( \ + echo '#ifndef GCC_TM_P_H'; \ + echo '#define GCC_TM_P_H'; \ + echo '#ifdef IN_GCC'; \ + echo '# include "config/i386/i386-protos.h"'; \ + echo '#endif'; \ + echo '#endif'; \ + ) > %o |> tm_p.h + +# tm.h — target machine description for x86_64-linux-gnu +# Includes options.h and the i386 target header chain. +: |> ^ GEN %o^ ( \ + echo '#ifndef GCC_TM_H'; \ + echo '#define GCC_TM_H'; \ + echo '#define LIBC_GLIBC 1'; \ + echo '#define LIBC_UCLIBC 2'; \ + echo '#define LIBC_BIONIC 3'; \ + echo '#define LIBC_MUSL 4'; \ + echo '#ifdef IN_GCC'; \ + echo '# include "options.h"'; \ + echo '# include "config/i386/i386.h"'; \ + echo '# include "config/i386/unix.h"'; \ + echo '# include "config/i386/att.h"'; \ + echo '# include "config/elfos.h"'; \ + echo '# include "config/gnu-user.h"'; \ + echo '# include "config/glibc-stdint.h"'; \ + echo '# include "config/i386/x86-64.h"'; \ + echo '# include "config/i386/gnu-user-common.h"'; \ + echo '# include "config/i386/gnu-user64.h"'; \ + echo '# include "config/linux.h"'; \ + echo '# include "config/linux-android.h"'; \ + echo '# include "config/i386/linux-common.h"'; \ + echo '# include "config/i386/linux64.h"'; \ + echo '# include "config/initfini-array.h"'; \ + echo '#endif'; \ + echo '#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET'; \ + echo '# include "insn-constants.h"'; \ + echo '# include "insn-flags.h"'; \ + echo '#endif'; \ + echo '#if defined IN_GCC && !defined GENERATOR_FILE'; \ + echo '# include "insn-modes.h"'; \ + echo '#endif'; \ + echo '#include "defaults.h"'; \ + echo '#endif'; \ + ) > %o |> tm.h + +# ============================================================ +# Phase 2: Generator bootstrap +# ============================================================ +# +# Bootstrap chain: +# errors.o → genmodes → insn-modes.h +# insn-modes.h → BUILD_RTL objects +# BUILD_RTL + BUILD_MD → genconditions → gencondmd → insn-conditions.md +# insn-conditions.md → all RTL generators + +# Host support objects (prefixed to avoid collision with target objects) +: errors.cc |> !hostcxx |> host-errors.o + +# genmodes needs EXTRA_MODES_FILE for i386 +: genmodes.cc |> ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) \ + -DEXTRA_MODES_FILE=\"config/i386/i386-modes.def\" -c %f -o %o \ + |> host-genmodes.o + +: host-genmodes.o host-errors.o |> ^ LINK genmodes^ $(HOSTCC) %f -o %o |> genmodes + +: | genmodes |> ^ GEN %o^ ./genmodes -h > %o |> insn-modes.h +: | genmodes |> ^ GEN %o^ ./genmodes -i > %o |> insn-modes-inline.h +: | genmodes |> ^ GEN %o^ ./genmodes > %o |> insn-modes.cc +: | genmodes |> ^ GEN %o^ ./genmodes -m > %o |> min-insn-modes.cc + +# min-insn-modes.o (host, from generated source) +: min-insn-modes.cc | |> \ + ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-min-insn-modes.o + +# BUILD_RTL objects (need insn-modes.h + insn-modes-inline.h) +BUILD_RTL_DEPS = insn-modes.h insn-modes-inline.h + +: rtl.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-rtl.o +: read-rtl.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-read-rtl.o +: ggc-none.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-ggc-none.o +: vec.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-vec.o +: gensupport.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gensupport.o +: print-rtl.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-print-rtl.o +: hash-table.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-hash-table.o +: sort.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-sort.o +: inchash.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-inchash.o + +# BUILD_MD +: read-md.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-read-md.o + +BUILD_RTL = host-rtl.o host-read-rtl.o host-ggc-none.o host-vec.o +BUILD_RTL += host-min-insn-modes.o host-gensupport.o host-print-rtl.o +BUILD_RTL += host-hash-table.o host-sort.o +BUILD_MD = host-read-md.o +BUILD_ERRORS = host-errors.o + +# --- genconditions → gencondmd bootstrap --- + +: genconditions.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genconditions.o + +: host-genconditions.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) \ + $(LIBIBERTY_A) |> ^ LINK genconditions^ $(HOSTCC) %f -o %o |> genconditions + +: $(MD) | genconditions |> ^ GEN %o^ ./genconditions %f > %o |> gencondmd.cc + +: gencondmd.cc | |> \ + ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-gencondmd.o + +: host-gencondmd.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK gencondmd^ $(HOSTCC) %f -o %o |> gencondmd + +: | gencondmd |> ^ GEN %o^ ./gencondmd > %o |> insn-conditions.md + +# ============================================================ +# Phase 3: Generators +# ============================================================ +# +# Each generator: compile → link → run. +# RTL generators link with BUILD_RTL + BUILD_MD + BUILD_ERRORS. +# Non-RTL generators link with BUILD_ERRORS only. + +# --- Helper: compile + link an RTL generator --- +# (Each generator is hand-written for clarity) + +# gengenrtl (no MD input, uses rtl.def) +: gengenrtl.cc |> !hostcxx |> host-gengenrtl.o +: host-gengenrtl.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK gengenrtl^ $(HOSTCC) %f -o %o |> gengenrtl +: | gengenrtl |> ^ GEN %o^ ./gengenrtl > %o |> genrtl.h + +# gencheck (no MD input, uses tree.def) +: gencheck.cc |> !hostcxx |> host-gencheck.o +: host-gencheck.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK gencheck^ $(HOSTCC) %f -o %o |> gencheck +: | gencheck |> ^ GEN %o^ ./gencheck > %o |> tree-check.h + +# genhooks (no MD input, produces multiple hook headers) +: genhooks.cc |> !hostcxx |> host-genhooks.o +: host-genhooks.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genhooks^ $(HOSTCC) %f -o %o |> genhooks +: | genhooks |> ^ GEN %o^ ./genhooks "Target Hook" > %o \ + |> target-hooks-def.h +: | genhooks |> ^ GEN %o^ ./genhooks "Common Target Hook" > %o \ + |> common-target-hooks-def.h + +# gencfn-macros (no MD input) +: gencfn-macros.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gencfn-macros.o +: host-gencfn-macros.o $(BUILD_ERRORS) host-hash-table.o host-vec.o \ + host-ggc-none.o host-sort.o $(LIBIBERTY_A) |> \ + ^ LINK gencfn-macros^ $(HOSTCC) %f -o %o |> gencfn-macros +: | gencfn-macros |> ^ GEN %o^ ./gencfn-macros -c > %o \ + |> case-cfn-macros.h + +# genconstants (MD input only, no insn-conditions.md) +: genconstants.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genconstants.o +: host-genconstants.o $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genconstants^ $(HOSTCC) %f -o %o |> genconstants +: $(MD) | genconstants |> ^ GEN %o^ ./genconstants %f > %o \ + |> insn-constants.h + +# genenums (MD input only) +: genenums.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genenums.o +: host-genenums.o $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genenums^ $(HOSTCC) %f -o %o |> genenums +: $(MD) | genenums |> ^ GEN %o^ ./genenums %f > %o |> insn-enums.cc + +# --- Simple RTL generators (MD + insn-conditions.md → header output) --- + +: genattr.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattr.o +: host-genattr.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genattr^ $(HOSTCC) %f -o %o |> genattr +: $(MD) insn-conditions.md | genattr |> ^ GEN %o^ ./genattr %f > %o \ + |> insn-attr.h + +: genattr-common.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattr-common.o +: host-genattr-common.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genattr-common^ $(HOSTCC) %f -o %o |> genattr-common +: $(MD) insn-conditions.md | genattr-common |> ^ GEN %o^ ./genattr-common %f > %o \ + |> insn-attr-common.h + +: gencodes.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gencodes.o +: host-gencodes.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK gencodes^ $(HOSTCC) %f -o %o |> gencodes +: $(MD) insn-conditions.md | gencodes |> ^ GEN %o^ ./gencodes %f > %o \ + |> insn-codes.h + +: genconfig.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genconfig.o +: host-genconfig.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genconfig^ $(HOSTCC) %f -o %o |> genconfig +: $(MD) insn-conditions.md | genconfig |> ^ GEN %o^ ./genconfig %f > %o \ + |> insn-config.h + +: genflags.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genflags.o +: host-genflags.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genflags^ $(HOSTCC) %f -o %o |> genflags +: $(MD) insn-conditions.md | genflags |> ^ GEN %o^ ./genflags %f > %o \ + |> insn-flags.h + +: gentarget-def.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gentarget-def.o +: host-gentarget-def.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK gentarget-def^ $(HOSTCC) %f -o %o |> gentarget-def +: $(MD) insn-conditions.md | gentarget-def |> ^ GEN %o^ ./gentarget-def %f > %o \ + |> insn-target-def.h + +# --- Simple RTL generators (MD + insn-conditions.md → source output) --- + +: genautomata.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genautomata.o +: host-genautomata.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genautomata^ $(HOSTCC) %f -o %o -lm |> genautomata +: $(MD) insn-conditions.md | genautomata |> ^ GEN %o^ ./genautomata %f > %o \ + |> insn-automata.cc + +: genextract.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genextract.o +: host-genextract.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genextract^ $(HOSTCC) %f -o %o |> genextract +: $(MD) insn-conditions.md | genextract |> ^ GEN %o^ ./genextract %f > %o \ + |> insn-extract.cc + +: genoutput.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genoutput.o +: host-genoutput.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genoutput^ $(HOSTCC) %f -o %o |> genoutput +: $(MD) insn-conditions.md | genoutput |> ^ GEN %o^ ./genoutput %f > %o \ + |> insn-output.cc + +: genpeep.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genpeep.o +: host-genpeep.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genpeep^ $(HOSTCC) %f -o %o |> genpeep +: $(MD) insn-conditions.md | genpeep |> ^ GEN %o^ ./genpeep %f > %o \ + |> insn-peep.cc + +# --- Multi-output RTL generators --- + +# genattrtab → 3 files +: genattrtab.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattrtab.o +: host-genattrtab.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genattrtab^ $(HOSTCC) %f -o %o |> genattrtab +: $(MD) insn-conditions.md | genattrtab |> ^ GEN insn-attrtab^ \ + ./genattrtab %f -Ainsn-attrtab.cc -Dinsn-dfatab.cc -Linsn-latencytab.cc \ + |> insn-attrtab.cc insn-dfatab.cc insn-latencytab.cc + +# genopinit → 2 files +: genopinit.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genopinit.o +: host-genopinit.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genopinit^ $(HOSTCC) %f -o %o |> genopinit +: $(MD) insn-conditions.md | genopinit |> ^ GEN insn-opinit^ \ + ./genopinit %f -hinsn-opinit.h -cinsn-opinit.cc \ + |> insn-opinit.h insn-opinit.cc + +# genpreds → 3 files (separate invocations) +: genpreds.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genpreds.o +: host-genpreds.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genpreds^ $(HOSTCC) %f -o %o |> genpreds +: $(MD) | genpreds |> ^ GEN %o^ ./genpreds %f > %o |> insn-preds.cc +: $(MD) | genpreds |> ^ GEN %o^ ./genpreds -h %f > %o |> tm-preds.h +: $(MD) | genpreds |> ^ GEN %o^ ./genpreds -c %f > %o |> tm-constrs.h + +# genemit → 10 split files +: genemit.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genemit.o +: host-genemit.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genemit^ $(HOSTCC) %f -o %o |> genemit +: $(MD) insn-conditions.md | genemit |> ^ GEN insn-emit-*^ \ + ./genemit %f \ + -O insn-emit-1.cc -O insn-emit-2.cc -O insn-emit-3.cc \ + -O insn-emit-4.cc -O insn-emit-5.cc -O insn-emit-6.cc \ + -O insn-emit-7.cc -O insn-emit-8.cc -O insn-emit-9.cc \ + -O insn-emit-10.cc \ + |> insn-emit-1.cc insn-emit-2.cc insn-emit-3.cc insn-emit-4.cc \ + insn-emit-5.cc insn-emit-6.cc insn-emit-7.cc insn-emit-8.cc \ + insn-emit-9.cc insn-emit-10.cc + +# genrecog → 10 split files + header +: genrecog.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genrecog.o +: host-genrecog.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) \ + host-hash-table.o host-inchash.o $(LIBIBERTY_A) |> \ + ^ LINK genrecog^ $(HOSTCC) %f -o %o |> genrecog +: $(MD) insn-conditions.md | genrecog |> ^ GEN insn-recog-*^ \ + ./genrecog %f -Hinsn-recog.h \ + -O insn-recog-1.cc -O insn-recog-2.cc -O insn-recog-3.cc \ + -O insn-recog-4.cc -O insn-recog-5.cc -O insn-recog-6.cc \ + -O insn-recog-7.cc -O insn-recog-8.cc -O insn-recog-9.cc \ + -O insn-recog-10.cc \ + |> insn-recog.h insn-recog-1.cc insn-recog-2.cc insn-recog-3.cc \ + insn-recog-4.cc insn-recog-5.cc insn-recog-6.cc insn-recog-7.cc \ + insn-recog-8.cc insn-recog-9.cc insn-recog-10.cc + +# --- Other generated headers --- + +# pass-instances.def from passes.def +: passes.def |> ^ GEN %o^ \ + awk -f $(SRC)/gen-pass-instances.awk %f > %o \ + |> pass-instances.def + +# ============================================================ +# Phase 4: Generated source compilation → +# ============================================================ + +# Options pipeline outputs +: options.cc |> !cxx |> options.o +: options-save.cc |> !cxx |> options-save.o +: options-urls.cc |> !cxx |> options-urls.o + +# insn-modes (from genmodes) +: insn-modes.cc |> !cxx |> insn-modes.o + +# insn-emit split (from genemit) +: foreach insn-emit-1.cc insn-emit-2.cc insn-emit-3.cc insn-emit-4.cc \ + insn-emit-5.cc insn-emit-6.cc insn-emit-7.cc insn-emit-8.cc \ + insn-emit-9.cc insn-emit-10.cc |> !cxx |> %B.o + +# insn-recog split (from genrecog) +: foreach insn-recog-1.cc insn-recog-2.cc insn-recog-3.cc insn-recog-4.cc \ + insn-recog-5.cc insn-recog-6.cc insn-recog-7.cc insn-recog-8.cc \ + insn-recog-9.cc insn-recog-10.cc |> !cxx |> %B.o + +# Other generated sources +gen_srcs = insn-attrtab.cc insn-dfatab.cc insn-latencytab.cc +gen_srcs += insn-automata.cc insn-extract.cc insn-output.cc insn-peep.cc +gen_srcs += insn-preds.cc insn-opinit.cc insn-enums.cc +: foreach $(gen_srcs) |> !cxx |> %B.o + +# ============================================================ +# Phase 5: Backend objects (OBJS from Makefile.in) +# ============================================================ +# ~445 source files from gcc/. Excludes: +# - analyzer/* (compiled in analyzer/Tupfile) +# - config/i386/* (compiled in config/i386/Tupfile) +# - pre-generated gtype-desc.cc, gimple-match-*, generic-match-* +# - Generated insn-*.cc and options*.cc (compiled above) + +objs = ggc-page.cc adjust-alignment.cc alias.cc alloc-pool.cc +objs += auto-inc-dec.cc auto-profile.cc +objs += bb-reorder.cc bitmap.cc builtins.cc caller-save.cc +objs += calls.cc ccmp.cc cfg.cc cfganal.cc cfgbuild.cc cfgcleanup.cc +objs += cfgexpand.cc cfghooks.cc cfgloop.cc cfgloopanal.cc +objs += cfgloopmanip.cc cfgrtl.cc +objs += ctfc.cc ctfout.cc btfout.cc +objs += symtab.cc symtab-thunks.cc symtab-clones.cc +objs += cgraph.cc cgraphbuild.cc cgraphunit.cc cgraphclones.cc +objs += combine.cc combine-stack-adj.cc compare-elim.cc context.cc +objs += convert.cc coroutine-passes.cc coverage.cc +objs += cppdefault.cc cprop.cc cse.cc cselib.cc +objs += data-streamer.cc data-streamer-in.cc data-streamer-out.cc +objs += dbgcnt.cc dce.cc ddg.cc debug.cc +objs += df-core.cc df-problems.cc df-scan.cc dfp.cc digraph.cc +objs += dojump.cc dominance.cc domwalk.cc double-int.cc dse.cc +objs += dumpfile.cc dwarf2asm.cc dwarf2cfi.cc +objs += dwarf2codeview.cc dwarf2ctf.cc dwarf2out.cc +objs += early-remat.cc emit-rtl.cc et-forest.cc except.cc +objs += explow.cc expmed.cc expr.cc ext-dce.cc +objs += fibonacci_heap.cc file-prefix-map.cc final.cc fixed-value.cc +objs += fold-const.cc fold-const-call.cc fold-mem-offsets.cc +objs += function.cc function-abi.cc function-tests.cc fwprop.cc +objs += gcc-attribute-urlifier.cc gcc-rich-location.cc gcc-urlifier.cc +objs += gcse.cc gcse-common.cc ggc-common.cc ggc-tests.cc +objs += gimple.cc gimple-array-bounds.cc gimple-builder.cc +objs += gimple-expr.cc gimple-if-to-switch.cc gimple-iterator.cc +objs += gimple-fold.cc gimple-harden-conditionals.cc +objs += gimple-harden-control-flow.cc gimple-laddress.cc +objs += gimple-loop-interchange.cc gimple-loop-jam.cc +objs += gimple-loop-versioning.cc gimple-low.cc gimple-lower-bitint.cc +objs += gimple-predicate-analysis.cc gimple-pretty-print.cc +objs += gimple-range.cc gimple-range-cache.cc gimple-range-edge.cc +objs += gimple-range-fold.cc gimple-range-gori.cc gimple-range-infer.cc +objs += gimple-range-op.cc gimple-range-phi.cc gimple-range-trace.cc +objs += gimple-ssa-backprop.cc gimple-ssa-isolate-paths.cc +objs += gimple-ssa-nonnull-compare.cc gimple-ssa-sccopy.cc +objs += gimple-ssa-split-paths.cc gimple-ssa-store-merging.cc +objs += gimple-ssa-strength-reduction.cc gimple-ssa-sprintf.cc +objs += gimple-ssa-warn-access.cc gimple-ssa-warn-alloca.cc +objs += gimple-ssa-warn-restrict.cc +objs += gimple-streamer-in.cc gimple-streamer-out.cc +objs += gimple-walk.cc gimple-warn-recursion.cc +objs += gimplify.cc gimplify-me.cc godump.cc graph.cc +objs += graphds.cc graphviz.cc +objs += graphite.cc graphite-isl-ast-to-gimple.cc +objs += graphite-dependences.cc graphite-optimize-isl.cc +objs += graphite-poly.cc graphite-scop-detection.cc +objs += graphite-sese-to-poly.cc +objs += haifa-sched.cc hash-map-tests.cc hash-set-tests.cc +objs += hw-doloop.cc hwint.cc ifcvt.cc ree.cc +objs += inchash.cc incpath.cc init-regs.cc internal-fn.cc +objs += ipa-locality-cloning.cc ipa-cp.cc ipa-sra.cc ipa-devirt.cc +objs += ipa-fnsummary.cc ipa-polymorphic-call.cc ipa-split.cc +objs += ipa-inline.cc ipa-comdats.cc ipa-free-lang-data.cc +objs += ipa-visibility.cc ipa-inline-analysis.cc ipa-inline-transform.cc +objs += ipa-modref.cc ipa-modref-tree.cc ipa-predicate.cc ipa-profile.cc +objs += ipa-prop.cc ipa-param-manipulation.cc ipa-pure-const.cc +objs += ipa-icf.cc ipa-icf-gimple.cc ipa-reference.cc +objs += ipa-ref.cc ipa-utils.cc ipa-strub.cc ipa.cc +objs += ira.cc pair-fusion.cc ira-build.cc ira-costs.cc +objs += ira-conflicts.cc ira-color.cc ira-emit.cc ira-lives.cc +objs += jump.cc langhooks.cc late-combine.cc lazy-diagnostic-path.cc +objs += lcm.cc lists.cc +objs += loop-doloop.cc loop-init.cc loop-invariant.cc loop-iv.cc +objs += loop-unroll.cc lower-subreg.cc +objs += lra.cc lra-assigns.cc lra-coalesce.cc lra-constraints.cc +objs += lra-eliminations.cc lra-lives.cc lra-remat.cc lra-spills.cc +objs += lto-cgraph.cc lto-streamer.cc lto-streamer-out.cc +objs += lto-section-in.cc lto-section-out.cc +objs += lto-opts.cc lto-compress.cc +objs += mcf.cc mode-switching.cc modulo-sched.cc multiple_target.cc +objs += omp-offload.cc omp-expand.cc omp-general.cc omp-low.cc +objs += omp-oacc-kernels-decompose.cc omp-oacc-neuter-broadcast.cc +objs += omp-simd-clone.cc opt-problem.cc +objs += optabs.cc optabs-libfuncs.cc optabs-query.cc optabs-tree.cc +objs += optinfo.cc opts-global.cc +objs += ordered-hash-map-tests.cc passes.cc prime-paths.cc path-coverage.cc +objs += plugin.cc pointer-query.cc postreload-gcse.cc postreload.cc +objs += predict.cc print-rtl.cc print-rtl-function.cc print-tree.cc +objs += profile.cc profile-count.cc +objs += range.cc range-op.cc range-op-float.cc range-op-ptr.cc +objs += read-md.cc read-rtl.cc read-rtl-function.cc +objs += real.cc realmpfr.cc recog.cc reg-stack.cc +objs += regcprop.cc reginfo.cc regrename.cc regstat.cc +objs += reload.cc reload1.cc reorg.cc resource.cc rtl-error.cc +objs += rtl-ssa/accesses.cc rtl-ssa/blocks.cc rtl-ssa/changes.cc +objs += rtl-ssa/functions.cc rtl-ssa/insns.cc rtl-ssa/movement.cc +objs += rtl-tests.cc rtl.cc rtlhash.cc rtlanal.cc rtlhooks.cc +objs += rtx-vector-builder.cc run-rtl-passes.cc +objs += sched-deps.cc sched-ebb.cc sched-rgn.cc +objs += sel-sched-ir.cc sel-sched-dump.cc sel-sched.cc +objs += selftest-rtl.cc selftest-run-tests.cc +objs += sese.cc shrink-wrap.cc simplify-rtx.cc +objs += sparseset.cc spellcheck.cc spellcheck-tree.cc +objs += splay-tree-utils.cc sreal.cc stack-ptr-mod.cc statistics.cc +objs += stmt.cc stor-layout.cc avoid-store-forwarding.cc store-motion.cc +objs += streamer-hooks.cc stringpool.cc substring-locations.cc +objs += target-globals.cc targhooks.cc timevar.cc tracer.cc +objs += trans-mem.cc tree-affine.cc +objs += asan.cc tsan.cc ubsan.cc sanopt.cc sancov.cc +objs += simple-diagnostic-path.cc +objs += tree-assume.cc tree-call-cdce.cc tree-cfg.cc tree-cfgcleanup.cc +objs += tree-chrec.cc tree-complex.cc tree-data-ref.cc tree-dfa.cc +objs += tree-diagnostic.cc +objs += tree-dump.cc tree-eh.cc tree-emutls.cc tree-if-conv.cc +objs += tree-inline.cc tree-into-ssa.cc tree-iterator.cc +objs += tree-logical-location.cc tree-loop-distribution.cc +objs += crc-verification.cc gimple-crc-optimization.cc +objs += sym-exec/sym-exec-expression.cc sym-exec/sym-exec-state.cc +objs += sym-exec/sym-exec-condition.cc +objs += tree-nested.cc tree-nrv.cc tree-object-size.cc tree-outof-ssa.cc +objs += tree-parloops.cc tree-phinodes.cc tree-predcom.cc +objs += tree-pretty-print.cc tree-profile.cc tree-scalar-evolution.cc +objs += tree-sra.cc tree-switch-conversion.cc +objs += tree-ssa-address.cc tree-ssa-alias.cc tree-ssa-ccp.cc +objs += tree-ssa-coalesce.cc tree-ssa-copy.cc tree-ssa-dce.cc +objs += tree-ssa-dom.cc tree-ssa-dse.cc tree-ssa-forwprop.cc +objs += tree-ssa-ifcombine.cc tree-ssa-live.cc tree-ssa-loop-ch.cc +objs += tree-ssa-loop-im.cc tree-ssa-loop-ivcanon.cc +objs += tree-ssa-loop-ivopts.cc tree-ssa-loop-manip.cc +objs += tree-ssa-loop-niter.cc tree-ssa-loop-prefetch.cc +objs += tree-ssa-loop-split.cc tree-ssa-loop-unswitch.cc +objs += tree-ssa-loop.cc tree-ssa-math-opts.cc tree-ssa-operands.cc +objs += gimple-range-path.cc tree-ssa-phiopt.cc tree-ssa-phiprop.cc +objs += tree-ssa-pre.cc tree-ssa-propagate.cc tree-ssa-reassoc.cc +objs += tree-ssa-sccvn.cc tree-ssa-scopedtables.cc tree-ssa-sink.cc +objs += tree-ssa-strlen.cc tree-ssa-structalias.cc +objs += tree-ssa-tail-merge.cc tree-ssa-ter.cc +objs += tree-ssa-threadbackward.cc tree-ssa-threadedge.cc +objs += tree-ssa-threadupdate.cc tree-ssa-uncprop.cc +objs += tree-ssa-uninit.cc tree-ssa.cc tree-ssanames.cc tree-stdarg.cc +objs += tree-streamer.cc tree-streamer-in.cc tree-streamer-out.cc +objs += tree-tailcall.cc tree-vect-generic.cc gimple-isel.cc +objs += tree-vect-patterns.cc tree-vect-data-refs.cc +objs += tree-vect-stmts.cc tree-vect-loop.cc tree-vect-loop-manip.cc +objs += tree-vect-slp.cc tree-vect-slp-patterns.cc tree-vectorizer.cc +objs += tree-vector-builder.cc tree-vrp.cc tree.cc +objs += tristate.cc typed-splay-tree.cc valtrack.cc +objs += value-pointer-equiv.cc value-query.cc value-range.cc +objs += value-range-pretty-print.cc value-range-storage.cc +objs += value-relation.cc value-prof.cc var-tracking.cc +objs += varasm.cc varpool.cc vec-perm-indices.cc vmsdbgout.cc +objs += vr-values.cc vtable-verify.cc warning-control.cc web.cc +objs += wide-int.cc wide-int-print.cc + +# Special -D flags for a few objects +: toplev.cc | |> ^ CXX %b^ \ + $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ + |> toplev.o + +: lto-streamer-in.cc | |> ^ CXX %b^ \ + $(CXX) $(TARGET_CXXFLAGS) -DTARGET_MACHINE=\"x86_64-pc-linux-gnu\" -c %f -o %o \ + |> lto-streamer-in.o + +: optinfo-emit-json.cc | |> ^ CXX %b^ \ + $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ + |> optinfo-emit-json.o + +: tree-diagnostic-client-data-hooks.cc | |> ^ CXX %b^ \ + $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ + |> tree-diagnostic-client-data-hooks.o + +: cppbuiltin.cc | |> ^ CXX %b^ \ + $(CXX) $(TARGET_CXXFLAGS) -DBASEVER=\"15.2.0\" -c %f -o %o \ + |> cppbuiltin.o + +: foreach $(objs) |> !cxx |> %B.o + +# ============================================================ +# Phase 6: Common objects (OBJS-libcommon + OBJS-libcommon-target) +# ============================================================ +# These are utility objects shared across GCC frontends. +# For cc1, we compile them once and link directly. + +common = diagnostic-spec.cc diagnostic.cc diagnostic-color.cc +common += diagnostic-format-json.cc diagnostic-format-sarif.cc +common += diagnostic-format-text.cc diagnostic-global-context.cc +common += diagnostic-macro-unwinding.cc diagnostic-path.cc +common += diagnostic-show-locus.cc edit-context.cc +common += pretty-print.cc intl.cc json.cc json-parsing.cc +common += sbitmap.cc vec.cc input.cc hash-table.cc memory-block.cc +common += selftest.cc selftest-diagnostic.cc sort.cc +common += selftest-diagnostic-path.cc selftest-json.cc +common += selftest-logical-location.cc +common += text-art/box-drawing.cc text-art/canvas.cc text-art/ruler.cc +common += text-art/selftests.cc text-art/style.cc text-art/styled-string.cc +common += text-art/table.cc text-art/theme.cc text-art/tree-widget.cc +common += text-art/widget.cc + +# OBJS-libcommon-target (unique entries not in common or main objs) +common += opts.cc opts-common.cc opts-diagnostic.cc +common += hooks.cc file-find.cc opt-suggestions.cc + +: foreach $(common) |> !cxx |> %B.o + +: prefix.cc | |> ^ CXX %b^ \ + $(CXX) $(TARGET_CXXFLAGS) -DPREFIX=\"/usr/local\" -DBASEVER=\"15.2.0\" -c %f -o %o \ + |> prefix.o + +# Target-specific common objects (from subdirectories) +: common/common-targhooks.cc |> !cxx |> common-targhooks.o +: common/config/i386/i386-common.cc |> !cxx |> i386-common.o + +# Host hooks (Linux host) +: config/host-linux.cc |> !cxx |> host-linux.o + +# main.o +: main.cc |> !cxx |> main.o + +# cc1-checksum.o (stub — real GCC uses genchecksum to embed a binary hash) +: |> ^ GEN %o^ echo 'const unsigned char executable_checksum[16] = {0};' > %o \ + |> cc1-checksum.cc +: cc1-checksum.cc |> !cxx |> cc1-checksum.o + +# attribs.o (C frontend, but compiled in gcc/) +: attribs.cc |> !cxx |> attribs.o + +# ============================================================ +# Phase 7: Pre-generated sources +# ============================================================ +# gengtype and genmatch outputs must be copied from a configured +# GCC build into pre-generated/ before building. +# +# cp build-gcc/gcc/gtype-desc.cc pre-generated/ +# cp build-gcc/gcc/gimple-match-*.cc pre-generated/ +# cp build-gcc/gcc/gimple-match-auto.h pre-generated/ +# cp build-gcc/gcc/gimple-match-exports.cc pre-generated/ +# cp build-gcc/gcc/generic-match-*.cc pre-generated/ +# cp build-gcc/gcc/generic-match-auto.h pre-generated/ +# cp build-gcc/gcc/gt-*.h pre-generated/ +# cp build-gcc/gcc/gtype-desc.h pre-generated/ + +: pre-generated/gtype-desc.cc |> !cxx |> gtype-desc.o +: pre-generated/gimple-match-exports.cc |> !cxx |> gimple-match-exports.o + +: foreach pre-generated/gimple-match-[0-9]*.cc |> !cxx |> %B.o +: foreach pre-generated/generic-match-[0-9]*.cc |> !cxx |> %B.o + +# ============================================================ +# Phase 8: Link cc1 +# ============================================================ +# Collects objects from this directory and subdirectories: +# gcc/c/ → ../ (C frontend) +# gcc/c-family/ → ../ (C-family shared code) +# gcc/analyzer/ → ../ (static analyzer) +# gcc/config/i386/ → ../../ (x86_64 target) + +: $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) \ + $(LIBIBERTY_A) $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) |> \ + ^ LINK cc1^ $(CXX) % \ + $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) $(LIBIBERTY_A) \ + $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) \ + -lm -ldl -lpthread -lz -o %o |> cc1 diff --git a/examples/gcc/gcc/Tuprules.tup b/examples/gcc/gcc/Tuprules.tup new file mode 100644 index 0000000..99e1859 --- /dev/null +++ b/examples/gcc/gcc/Tuprules.tup @@ -0,0 +1,61 @@ +# gcc/ build rules (self-contained with ?= defaults) +# +# Two compilation modes: +# HOST — generator programs (run on build machine) +# TARGET — cc1 backend objects (run on target) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +CXX ?= g++ +AR ?= ar +HOSTCC ?= g++ +GCC_DIR ?= . +GMP_DIR ?= gmp +MPFR_DIR ?= mpfr +MPC_DIR ?= mpc +LIBIBERTY_DIR ?= libiberty +LIBCPP_DIR ?= libcpp +LIBDECNUMBER_DIR ?= libdecnumber +LIBBACKTRACE_DIR ?= libbacktrace + +# Resolved library paths +LIBIBERTY_A = $(B)/$(LIBIBERTY_DIR)/libiberty.a +LIBCPP_A = $(B)/$(LIBCPP_DIR)/libcpp.a +LIBDECNUMBER_A = $(B)/$(LIBDECNUMBER_DIR)/libdecnumber.a +LIBBACKTRACE_A = $(B)/$(LIBBACKTRACE_DIR)/libbacktrace.a +LIBGMP_A = $(B)/$(GMP_DIR)/libgmp.a +LIBMPFR_A = $(B)/$(MPFR_DIR)/src/libmpfr.a +LIBMPC_A = $(B)/$(MPC_DIR)/src/libmpc.a + +# Common include paths +GCC_INCLUDES = -I$(B)/$(GCC_DIR) -I$(S)/$(GCC_DIR) +GCC_INCLUDES += -I$(S)/$(GCC_DIR)/../include +GCC_INCLUDES += -I$(S)/$(LIBCPP_DIR)/include +GCC_INCLUDES += -I$(B)/$(LIBDECNUMBER_DIR) -I$(S)/$(LIBDECNUMBER_DIR) +GCC_INCLUDES += -I$(B)/$(LIBBACKTRACE_DIR) -I$(S)/$(LIBBACKTRACE_DIR) +GCC_INCLUDES += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) +GCC_INCLUDES += -I$(B)/$(MPFR_DIR)/src -I$(S)/$(MPFR_DIR)/src +GCC_INCLUDES += -I$(B)/$(MPC_DIR)/src -I$(S)/$(MPC_DIR)/src + +# --- HOST compilation (generators) --- + +HOST_CXXFLAGS = -O0 -std=gnu++14 +HOST_CXXFLAGS += -DGENERATOR_FILE -DHAVE_CONFIG_H +HOST_CXXFLAGS += $(GCC_INCLUDES) + +!hostcxx = | $(S)/$(GCC_DIR)/ |> \ + ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> %B.o + +# --- TARGET compilation (cc1 objects) --- + +TARGET_CXXFLAGS = -O2 -std=gnu++14 +TARGET_CXXFLAGS += -DIN_GCC -DHAVE_CONFIG_H +TARGET_CXXFLAGS += $(GCC_INCLUDES) + +!cxx = | $(S)/$(GCC_DIR)/ $(S)/$(GCC_DIR)/ |> \ + ^ CXX %b^ $(CXX) $(TARGET_CXXFLAGS) -c %f -o %o |> + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/gcc/analyzer/Tupfile b/examples/gcc/gcc/analyzer/Tupfile new file mode 100644 index 0000000..6257584 --- /dev/null +++ b/examples/gcc/gcc/analyzer/Tupfile @@ -0,0 +1,28 @@ +include_rules + +# ============================================================ +# gcc/analyzer/ — Static analyzer (GCC 15.2.0) +# ============================================================ +# Objects contribute to ../ for the cc1 link. +# Source list from ANALYZER_OBJS in Makefile.in. + +srcs = access-diagram.cc analysis-plan.cc analyzer.cc +srcs += analyzer-language.cc analyzer-logging.cc analyzer-pass.cc +srcs += analyzer-selftests.cc bar-chart.cc bounds-checking.cc +srcs += call-details.cc call-info.cc call-string.cc call-summary.cc +srcs += checker-event.cc checker-path.cc complexity.cc +srcs += constraint-manager.cc diagnostic-manager.cc +srcs += engine.cc feasible-graph.cc function-set.cc +srcs += infinite-loop.cc infinite-recursion.cc +srcs += kf.cc kf-analyzer.cc kf-lang-cp.cc +srcs += known-function-manager.cc pending-diagnostic.cc +srcs += program-point.cc program-state.cc +srcs += ranges.cc record-layout.cc region.cc region-model.cc +srcs += region-model-asm.cc region-model-manager.cc +srcs += region-model-reachability.cc +srcs += sm.cc sm-file.cc sm-fd.cc sm-malloc.cc +srcs += sm-pattern-test.cc sm-sensitive.cc sm-signal.cc sm-taint.cc +srcs += state-purge.cc store.cc supergraph.cc +srcs += svalue.cc symbol.cc trimmed-graph.cc varargs.cc + +: foreach $(srcs) |> !cxx |> %B.o ../ diff --git a/examples/gcc/gcc/c-family/Tupfile b/examples/gcc/gcc/c-family/Tupfile new file mode 100644 index 0000000..c241ba1 --- /dev/null +++ b/examples/gcc/gcc/c-family/Tupfile @@ -0,0 +1,22 @@ +include_rules + +# ============================================================ +# gcc/c-family/ — C language family shared code (GCC 15.2.0) +# ============================================================ +# Objects contribute to ../ for the cc1 link. +# Source list from C_COMMON_OBJS + stub-objc. + +srcs = stub-objc.cc +srcs += c-common.cc c-cppbuiltin.cc c-dump.cc c-format.cc +srcs += c-gimplify.cc c-indentation.cc c-lex.cc c-omp.cc +srcs += c-opts.cc c-pch.cc c-ppoutput.cc c-pragma.cc +srcs += c-pretty-print.cc c-semantics.cc c-ada-spec.cc c-ubsan.cc +srcs += known-headers.cc c-attribs.cc c-warn.cc c-spellcheck.cc +srcs += c-type-mismatch.cc + +: foreach $(srcs) |> !cxx |> %B.o ../ + +# c-target-hooks-def.h (generated by genhooks in parent dir) +: | $(S)/$(GCC_DIR)/ |> ^ GEN %o^ \ + $(B)/$(GCC_DIR)/genhooks "C Target Hook" > %o \ + |> c-target-hooks-def.h diff --git a/examples/gcc/gcc/c/Tupfile b/examples/gcc/gcc/c/Tupfile new file mode 100644 index 0000000..48252c1 --- /dev/null +++ b/examples/gcc/gcc/c/Tupfile @@ -0,0 +1,12 @@ +include_rules + +# ============================================================ +# gcc/c/ — C language frontend (GCC 15.2.0) +# ============================================================ +# Objects contribute to ../ for the cc1 link. + +srcs = c-lang.cc c-errors.cc c-decl.cc c-typeck.cc +srcs += c-convert.cc c-aux-info.cc c-objc-common.cc +srcs += c-parser.cc c-fold.cc gimple-parser.cc + +: foreach $(srcs) |> !cxx |> %B.o ../ diff --git a/examples/gcc/gcc/config/i386/Tupfile b/examples/gcc/gcc/config/i386/Tupfile new file mode 100644 index 0000000..d0d9608 --- /dev/null +++ b/examples/gcc/gcc/config/i386/Tupfile @@ -0,0 +1,24 @@ +include_rules + +# ============================================================ +# gcc/config/i386/ — x86_64 target-specific code (GCC 15.2.0) +# ============================================================ +# Objects contribute to ../../ for the cc1 link. +# Source list from out_object_file, extra_objs, c_target_objs in config.gcc. + +# Main target description (out_object_file = i386.o) +: i386.cc |> !cxx |> i386.o ../../ + +# C frontend target hooks (c_target_objs) +: i386-c.cc |> !cxx |> i386-c.o ../../ + +# extra_objs for i386 +srcs = x86-tune-sched.cc x86-tune-sched-bd.cc +srcs += x86-tune-sched-atom.cc x86-tune-sched-core.cc +srcs += i386-options.cc i386-builtins.cc +srcs += i386-expand.cc i386-features.cc + +: foreach $(srcs) |> !cxx |> %B.o ../../ + +# x86_64-linux extra (config.gcc line 5928) +: gnu-property.cc |> !cxx |> gnu-property.o ../../ diff --git a/examples/gcc/gcc/tup.config b/examples/gcc/gcc/tup.config new file mode 100644 index 0000000..6ce176e --- /dev/null +++ b/examples/gcc/gcc/tup.config @@ -0,0 +1,127 @@ +# gcc/ - x86-64 Linux auto-host.h defines +# +# These generate auto-host.h via !gen-config. +# Cross-referenced with gcc/configure.ac output for x86_64-pc-linux-gnu. + +# Host word sizes +CONFIG_HOST_BITS_PER_CHAR=8 +CONFIG_HOST_BITS_PER_SHORT=16 +CONFIG_HOST_BITS_PER_INT=32 +CONFIG_HOST_BITS_PER_LONG=64 +CONFIG_HOST_BITS_PER_LONGLONG=64 + +# Type sizes +CONFIG_SIZEOF_SHORT=2 +CONFIG_SIZEOF_INT=4 +CONFIG_SIZEOF_LONG=8 +CONFIG_SIZEOF_LONG_LONG=8 +CONFIG_SIZEOF_VOID_P=8 +CONFIG_SIZEOF__BOOL=1 + +# Headers +CONFIG_HAVE_ALLOCA_H=1 +CONFIG_HAVE_DLFCN_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_FTW_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_LANGINFO_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_LOCALE_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_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_TIMES_H=1 +CONFIG_HAVE_SYS_TIME_H=1 +CONFIG_HAVE_SYS_TYPES_H=1 +CONFIG_HAVE_SYS_WAIT_H=1 +CONFIG_HAVE_UNISTD_H=1 + +# Functions +CONFIG_HAVE_ALLOCA=1 +CONFIG_HAVE_ATOQ=1 +CONFIG_HAVE_CLEARERR_UNLOCKED=1 +CONFIG_HAVE_CLOCK=1 +CONFIG_HAVE_CLOCK_GETTIME=1 +CONFIG_HAVE_FEOF_UNLOCKED=1 +CONFIG_HAVE_FERROR_UNLOCKED=1 +CONFIG_HAVE_FFLUSH_UNLOCKED=1 +CONFIG_HAVE_FGETC_UNLOCKED=1 +CONFIG_HAVE_FILENO_UNLOCKED=1 +CONFIG_HAVE_FOPEN_UNLOCKED=1 +CONFIG_HAVE_FPUTC_UNLOCKED=1 +CONFIG_HAVE_FPUTS_UNLOCKED=1 +CONFIG_HAVE_FREAD_UNLOCKED=1 +CONFIG_HAVE_FWRITE_UNLOCKED=1 +CONFIG_HAVE_GETCHAR_UNLOCKED=1 +CONFIG_HAVE_GETC_UNLOCKED=1 +CONFIG_HAVE_GETRLIMIT=1 +CONFIG_HAVE_GETRUSAGE=1 +CONFIG_HAVE_GETTIMEOFDAY=1 +CONFIG_HAVE_ICONV=1 +CONFIG_HAVE_LANGINFO_CODESET=1 +CONFIG_HAVE_LSTAT=1 +CONFIG_HAVE_MADVISE=1 +CONFIG_HAVE_MALLINFO=1 +CONFIG_HAVE_MALLINFO2=1 +CONFIG_HAVE_MMAP=1 +CONFIG_HAVE_MMAP_ANON=1 +CONFIG_HAVE_MMAP_DEV_ZERO=1 +CONFIG_HAVE_MMAP_FILE=1 +CONFIG_HAVE_POSIX_FALLOCATE=1 +CONFIG_HAVE_PUTCHAR_UNLOCKED=1 +CONFIG_HAVE_PUTC_UNLOCKED=1 +CONFIG_HAVE_SETLOCALE=1 +CONFIG_HAVE_SETRLIMIT=1 +CONFIG_HAVE_SIGACTION=1 +CONFIG_HAVE_SYSCONF=1 +CONFIG_HAVE_TIMES=1 +CONFIG_HAVE_UCHAR=1 +CONFIG_HAVE_VFORK=1 +CONFIG_HAVE_WORKING_FORK=1 +CONFIG_HAVE_WORKING_VFORK=1 + +# Declarations +CONFIG_HAVE_DECL_ABORT=1 +CONFIG_HAVE_DECL_ASPRINTF=1 +CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_CLEARERR_UNLOCKED=1 +CONFIG_HAVE_DECL_ERRNO=1 +CONFIG_HAVE_DECL_FEOF_UNLOCKED=1 +CONFIG_HAVE_DECL_FERROR_UNLOCKED=1 +CONFIG_HAVE_DECL_FFLUSH_UNLOCKED=1 +CONFIG_HAVE_DECL_FGETC_UNLOCKED=1 +CONFIG_HAVE_DECL_FILENO_UNLOCKED=1 +CONFIG_HAVE_DECL_FPUTC_UNLOCKED=1 +CONFIG_HAVE_DECL_FPUTS_UNLOCKED=1 +CONFIG_HAVE_DECL_FREAD_UNLOCKED=1 +CONFIG_HAVE_DECL_FWRITE_UNLOCKED=1 +CONFIG_HAVE_DECL_GETCHAR_UNLOCKED=1 +CONFIG_HAVE_DECL_GETC_UNLOCKED=1 +CONFIG_HAVE_DECL_GETENV=1 +CONFIG_HAVE_DECL_GETOPT=1 +CONFIG_HAVE_DECL_LDGETNAME=0 +CONFIG_HAVE_DECL_MALLOC=1 +CONFIG_HAVE_DECL_PUTCHAR_UNLOCKED=1 +CONFIG_HAVE_DECL_PUTC_UNLOCKED=1 +CONFIG_HAVE_DECL_REALLOC=1 +CONFIG_HAVE_DECL_SBRK=1 +CONFIG_HAVE_DECL_SNPRINTF=1 +CONFIG_HAVE_DECL_STRSIGNAL=1 +CONFIG_HAVE_DECL_VASPRINTF=1 +CONFIG_HAVE_DECL_VSNPRINTF=1 + +# Misc +CONFIG_STDC_HEADERS=1 +CONFIG_ENABLE_ASSERT_CHECKING=1 +CONFIG__GNU_SOURCE=1 +CONFIG_HAVE_LD_EH_FRAME_HDR=1 +CONFIG_HAVE_GAS_CFI_PERSONALITY_DIRECTIVE=1 +CONFIG_HAVE_GAS_CFI_SECTIONS_DIRECTIVE=1 +CONFIG_HAVE_GAS_HIDDEN=1 diff --git a/examples/gcc/libbacktrace/Tupfile b/examples/gcc/libbacktrace/Tupfile new file mode 100644 index 0000000..f5860bf --- /dev/null +++ b/examples/gcc/libbacktrace/Tupfile @@ -0,0 +1,29 @@ +include_rules + +# ============================================================ +# libbacktrace - stack trace support (GCC 15.2.0) +# ============================================================ + +# --- Phase 1: Generate config.h and backtrace-supported.h --- + +: |> !gen-config |> config.h + +: backtrace-supported.h.in |> ^ GEN %o^ sed \ + -e 's/@BACKTRACE_SUPPORTED@/1/g' \ + -e 's/@BACKTRACE_USES_MALLOC@/0/g' \ + -e 's/@BACKTRACE_SUPPORTS_THREADS@/1/g' \ + -e 's/@BACKTRACE_SUPPORTS_DATA@/1/g' \ + %f > %o |> backtrace-supported.h + +# --- Phase 2: Compile sources --- +# Linux-specific selection: ELF + mmapio + unwind-based backtrace. + +srcs = atomic.c dwarf.c fileline.c +srcs += mmapio.c mmap.c posix.c print.c sort.c state.c +srcs += elf.c backtrace.c simple.c + +: foreach $(srcs) |> !cc |> %B.o + +# --- Phase 3: Archive --- + +: |> ^ AR %o^ $(AR) rcs %o % |> libbacktrace.a $(S)/ diff --git a/examples/gcc/libbacktrace/Tuprules.tup b/examples/gcc/libbacktrace/Tuprules.tup new file mode 100644 index 0000000..fedff50 --- /dev/null +++ b/examples/gcc/libbacktrace/Tuprules.tup @@ -0,0 +1,17 @@ +# libbacktrace build rules (self-contained with ?= defaults) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +AR ?= ar +LIBBACKTRACE_DIR ?= . + +CFLAGS = -O2 -std=gnu11 +CFLAGS += -DHAVE_CONFIG_H +CFLAGS += -I$(B)/$(LIBBACKTRACE_DIR) -I$(S)/$(LIBBACKTRACE_DIR) + +!cc = | $(S)/$(LIBBACKTRACE_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/libbacktrace/tup.config b/examples/gcc/libbacktrace/tup.config new file mode 100644 index 0000000..b57c64c --- /dev/null +++ b/examples/gcc/libbacktrace/tup.config @@ -0,0 +1,53 @@ +# libbacktrace - x86-64 Linux config.h defines +# +# Cross-referenced with libbacktrace/config.h.in from GCC 15.2.0. + +# ELF 64-bit (x86-64 Linux) +CONFIG_BACKTRACE_ELF_SIZE=64 + +# 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_LINK_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 + +# Linux-specific +CONFIG_HAVE_DL_ITERATE_PHDR=1 +CONFIG_HAVE_GETIPINFO=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 +CONFIG__GNU_SOURCE=1 diff --git a/examples/gcc/libcpp/Tupfile b/examples/gcc/libcpp/Tupfile new file mode 100644 index 0000000..6d995c6 --- /dev/null +++ b/examples/gcc/libcpp/Tupfile @@ -0,0 +1,24 @@ +include_rules + +# ============================================================ +# libcpp - C preprocessor library (GCC 15.2.0) +# ============================================================ + +# --- Phase 1: Generate config.h + localedir.h --- + +: |> !gen-config |> config.h + +: |> ^ GEN %o^ echo '#define LOCALEDIR ""' > %o |> localedir.h + +# --- Phase 2: Compile sources --- +# Source list from libcpp/Makefile.in libcpp_a_OBJS. + +srcs = charset.cc directives.cc errors.cc expr.cc files.cc +srcs += identifiers.cc init.cc lex.cc line-map.cc macro.cc +srcs += mkdeps.cc pch.cc symtab.cc traditional.cc + +: foreach $(srcs) |> !cxx |> %B.o + +# --- Phase 3: Archive --- + +: |> ^ AR %o^ $(AR) rcs %o % |> libcpp.a $(S)/ diff --git a/examples/gcc/libcpp/Tuprules.tup b/examples/gcc/libcpp/Tuprules.tup new file mode 100644 index 0000000..8d22888 --- /dev/null +++ b/examples/gcc/libcpp/Tuprules.tup @@ -0,0 +1,19 @@ +# libcpp build rules (self-contained with ?= defaults) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CXX ?= g++ +AR ?= ar +LIBCPP_DIR ?= . +LIBIBERTY_DIR ?= libiberty + +CXXFLAGS = -O2 -std=gnu++14 -fno-exceptions -fno-rtti +CXXFLAGS += -DHAVE_CONFIG_H +CXXFLAGS += -I$(B)/$(LIBCPP_DIR) -I$(S)/$(LIBCPP_DIR) -I$(S)/$(LIBCPP_DIR)/include +CXXFLAGS += -I$(S)/$(LIBCPP_DIR)/../include + +!cxx = | $(S)/$(LIBCPP_DIR)/ |> ^ CXX %b^ $(CXX) $(CXXFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/libcpp/tup.config b/examples/gcc/libcpp/tup.config new file mode 100644 index 0000000..4899740 --- /dev/null +++ b/examples/gcc/libcpp/tup.config @@ -0,0 +1,93 @@ +# libcpp - x86-64 Linux config.h defines +# +# Cross-referenced with libcpp/config.in from GCC 15.2.0. + +# Build options +CONFIG_ENABLE_CANONICAL_SYSTEM_HEADERS=1 + +# Headers +CONFIG_HAVE_ALLOCA_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_LOCALE_H=1 +CONFIG_HAVE_MEMORY_H=1 +CONFIG_HAVE_STDDEF_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_STAT_H=1 +CONFIG_HAVE_SYS_TYPES_H=1 +CONFIG_HAVE_UNISTD_H=1 + +# Functions +CONFIG_HAVE_ALLOCA=1 +CONFIG_HAVE_CLEARERR_UNLOCKED=1 +CONFIG_HAVE_FEOF_UNLOCKED=1 +CONFIG_HAVE_FERROR_UNLOCKED=1 +CONFIG_HAVE_FFLUSH_UNLOCKED=1 +CONFIG_HAVE_FGETC_UNLOCKED=1 +CONFIG_HAVE_FGETS_UNLOCKED=1 +CONFIG_HAVE_FILENO_UNLOCKED=1 +CONFIG_HAVE_FPUTC_UNLOCKED=1 +CONFIG_HAVE_FPUTS_UNLOCKED=1 +CONFIG_HAVE_FREAD_UNLOCKED=1 +CONFIG_HAVE_FWRITE_UNLOCKED=1 +CONFIG_HAVE_GETCHAR_UNLOCKED=1 +CONFIG_HAVE_GETC_UNLOCKED=1 +CONFIG_HAVE_ICONV=1 +CONFIG_HAVE_LANGINFO_CODESET=1 +CONFIG_HAVE_PUTCHAR_UNLOCKED=1 +CONFIG_HAVE_PUTC_UNLOCKED=1 +CONFIG_HAVE_SETLOCALE=1 + +# Declarations +CONFIG_HAVE_DECL_ABORT=1 +CONFIG_HAVE_DECL_ASPRINTF=1 +CONFIG_HAVE_DECL_BASENAME=1 +CONFIG_HAVE_DECL_CLEARERR_UNLOCKED=1 +CONFIG_HAVE_DECL_ERRNO=1 +CONFIG_HAVE_DECL_FEOF_UNLOCKED=1 +CONFIG_HAVE_DECL_FERROR_UNLOCKED=1 +CONFIG_HAVE_DECL_FFLUSH_UNLOCKED=1 +CONFIG_HAVE_DECL_FGETC_UNLOCKED=1 +CONFIG_HAVE_DECL_FGETS_UNLOCKED=1 +CONFIG_HAVE_DECL_FILENO_UNLOCKED=1 +CONFIG_HAVE_DECL_FPRINTF_UNLOCKED=0 +CONFIG_HAVE_DECL_FPUTC_UNLOCKED=1 +CONFIG_HAVE_DECL_FPUTS_UNLOCKED=1 +CONFIG_HAVE_DECL_FREAD_UNLOCKED=1 +CONFIG_HAVE_DECL_FWRITE_UNLOCKED=1 +CONFIG_HAVE_DECL_GETCHAR_UNLOCKED=1 +CONFIG_HAVE_DECL_GETC_UNLOCKED=1 +CONFIG_HAVE_DECL_GETOPT=1 +CONFIG_HAVE_DECL_PUTCHAR_UNLOCKED=1 +CONFIG_HAVE_DECL_PUTC_UNLOCKED=1 +CONFIG_HAVE_DECL_VASPRINTF=1 + +# Types +CONFIG_HAVE_UCHAR=1 +CONFIG_HAVE_UINTPTR_T=1 + +# Sizes +CONFIG_SIZEOF_DEV_T=8 +CONFIG_SIZEOF_INO_T=8 +CONFIG_SIZEOF_INT=4 +CONFIG_SIZEOF_LONG=8 + +# Package +CONFIG_PACKAGE="cpplib" +CONFIG_PACKAGE_BUGREPORT="" +CONFIG_PACKAGE_NAME="cpplib" +CONFIG_PACKAGE_STRING="cpplib 0" +CONFIG_PACKAGE_TARNAME="cpplib" +CONFIG_PACKAGE_URL="" +CONFIG_PACKAGE_VERSION="0" + +# Misc +CONFIG_STDC_HEADERS=1 +CONFIG_STRING_WITH_STRINGS=1 +CONFIG_TIME_WITH_SYS_TIME=1 +CONFIG__GNU_SOURCE=1 diff --git a/examples/gcc/libdecnumber/Tupfile b/examples/gcc/libdecnumber/Tupfile new file mode 100644 index 0000000..918b6c9 --- /dev/null +++ b/examples/gcc/libdecnumber/Tupfile @@ -0,0 +1,25 @@ +include_rules + +# ============================================================ +# libdecnumber - BID decimal floating-point (GCC 15.2.0) +# ============================================================ + +# --- Phase 1: Generate config.h --- +# dconfig.h includes config.h (when not IN_LIBGCC2). +# x86-64 is little-endian so WORDS_BIGENDIAN is not defined. + +: |> !gen-config |> config.h + +# --- Phase 2: Compile sources --- +# BID variant (Binary Integer Decimal) — x86/x86_64 use BID per dfp.m4. + +srcs = decNumber.c decContext.c +srcs += bid/decimal32.c bid/decimal64.c bid/decimal128.c +srcs += bid/bid2dpd_dpd2bid.c bid/host-ieee32.c +srcs += bid/host-ieee64.c bid/host-ieee128.c + +: foreach $(srcs) |> !cc |> %B.o + +# --- Phase 3: Archive --- + +: |> ^ AR %o^ $(AR) rcs %o % |> libdecnumber.a $(S)/ diff --git a/examples/gcc/libdecnumber/Tuprules.tup b/examples/gcc/libdecnumber/Tuprules.tup new file mode 100644 index 0000000..40562b9 --- /dev/null +++ b/examples/gcc/libdecnumber/Tuprules.tup @@ -0,0 +1,17 @@ +# libdecnumber build rules (self-contained with ?= defaults) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +AR ?= ar +LIBDECNUMBER_DIR ?= . + +CFLAGS = -O2 -std=gnu11 +CFLAGS += -DHAVE_CONFIG_H +CFLAGS += -I$(B)/$(LIBDECNUMBER_DIR) -I$(S)/$(LIBDECNUMBER_DIR) + +!cc = | $(S)/$(LIBDECNUMBER_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/libdecnumber/tup.config b/examples/gcc/libdecnumber/tup.config new file mode 100644 index 0000000..45c270d --- /dev/null +++ b/examples/gcc/libdecnumber/tup.config @@ -0,0 +1,8 @@ +# libdecnumber - x86-64 Linux config.h defines +# +# libdecnumber includes "dconfig.h" which, when not IN_LIBGCC2, +# includes "config.h". We only need WORDS_BIGENDIAN (and standard headers). + +CONFIG_STDC_HEADERS=1 +CONFIG_HAVE_STRING_H=1 +CONFIG_HAVE_STDLIB_H=1 diff --git a/examples/gcc/libiberty/Tupfile b/examples/gcc/libiberty/Tupfile new file mode 100644 index 0000000..5f43a97 --- /dev/null +++ b/examples/gcc/libiberty/Tupfile @@ -0,0 +1,41 @@ +include_rules + +# ============================================================ +# libiberty - GCC utility library +# ============================================================ + +# --- Phase 1: Generate config.h --- + +: |> !gen-config |> config.h + +# --- Phase 2: Compile REQUIRED_OFILES --- +# Source list from libiberty/Makefile.in REQUIRED_OFILES. +# @pexecute@ = pex-unix on Linux. + +srcs = regex.c cplus-dem.c cp-demangle.c md5.c sha1.c alloca.c +srcs += argv.c bsearch_r.c +srcs += choose-temp.c concat.c cp-demint.c crc32.c d-demangle.c +srcs += dwarfnames.c dyn-string.c +srcs += fdmatch.c fibheap.c filedescriptor.c filename_cmp.c floatformat.c +srcs += fnmatch.c fopen_unlocked.c +srcs += getopt.c getopt1.c getpwd.c getruntime.c +srcs += hashtab.c hex.c +srcs += lbasename.c ldirname.c lrealpath.c +srcs += make-relative-prefix.c make-temp-file.c +srcs += objalloc.c obstack.c +srcs += partition.c pexecute.c physmem.c pex-common.c pex-one.c pex-unix.c +srcs += vprintf-support.c rust-demangle.c +srcs += safe-ctype.c +srcs += simple-object.c simple-object-coff.c simple-object-elf.c +srcs += simple-object-mach-o.c simple-object-xcoff.c +srcs += sort.c spaces.c splay-tree.c stack-limit.c +srcs += strerror.c strsignal.c +srcs += timeval-utils.c unlink-if-ordinary.c +srcs += xasprintf.c xatexit.c xexit.c xmalloc.c xmemdup.c xstrdup.c +srcs += xstrerror.c xstrndup.c xvasprintf.c + +: foreach $(srcs) |> !cc |> %B.o + +# --- Phase 3: Archive --- + +: |> ^ AR %o^ $(AR) rcs %o % |> libiberty.a $(S)/ diff --git a/examples/gcc/libiberty/Tuprules.tup b/examples/gcc/libiberty/Tuprules.tup new file mode 100644 index 0000000..9f436e5 --- /dev/null +++ b/examples/gcc/libiberty/Tuprules.tup @@ -0,0 +1,21 @@ +# libiberty build rules (self-contained with ?= defaults) +# +# Composed mode: parent sets S, B, CC, AR, HOSTCC, LIBIBERTY_DIR. +# Standalone mode: ?= defaults take effect. + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= gcc +AR ?= ar +HOSTCC ?= gcc +LIBIBERTY_DIR ?= . + +CFLAGS = -O2 -std=gnu11 +CFLAGS += -DHAVE_CONFIG_H +CFLAGS += -I$(B)/$(LIBIBERTY_DIR) -I$(S)/$(LIBIBERTY_DIR)/../include + +!cc = | $(S)/$(LIBIBERTY_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/tup.config > %o |> diff --git a/examples/gcc/libiberty/tup.config b/examples/gcc/libiberty/tup.config new file mode 100644 index 0000000..78a9dff --- /dev/null +++ b/examples/gcc/libiberty/tup.config @@ -0,0 +1,145 @@ +# libiberty - x86-64 Linux config.h defines +# +# Prefix-free: scoped config merging namespaces these under libiberty/. +# Cross-referenced with libiberty/config.in from GCC 15.2.0. + +# Headers +CONFIG_HAVE_ALLOCA_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_MALLOC_H=1 +CONFIG_HAVE_MEMORY_H=1 +CONFIG_HAVE_SPAWN_H=1 +CONFIG_HAVE_STDINT_H=1 +CONFIG_HAVE_STDIO_EXT_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_PRCTL_H=1 +CONFIG_HAVE_SYS_RESOURCE_H=1 +CONFIG_HAVE_SYS_STAT_H=1 +CONFIG_HAVE_SYS_SYSINFO_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_CANONICALIZE_FILE_NAME=1 +CONFIG_HAVE_CLOCK=1 +CONFIG_HAVE_DUP3=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_MEMRCHR=1 +CONFIG_HAVE_MEMSET=1 +CONFIG_HAVE_MKSTEMPS=1 +CONFIG_HAVE_MMAP=1 +CONFIG_HAVE_ON_EXIT=1 +CONFIG_HAVE_PIPE2=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_SIGSETMASK=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_STRVERSCMP=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 +CONFIG_HAVE___FSETLOCKING=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=1 +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=1 +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_STRVERSCMP=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" +CONFIG__GNU_SOURCE=1 From c3083486d958b4842fcc958a638886fed5aa4614 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:55:54 +0800 Subject: [PATCH 03/16] Build genmatch from source, eliminating pre-generated match files genmatch reads match.pd and generates optimized C++ for GIMPLE and GENERIC IR simplification. It was previously requiring users to run ./configure && make on the GCC source tree to produce its outputs. Now genmatch is compiled and linked against libcpp (for tokenization) and run as part of the normal build. Only gengtype outputs remain in pre-generated/. Co-Authored-By: Claude Opus 4.6 --- examples/gcc/README.md | 20 +++++------ examples/gcc/gcc/Tupfile | 74 +++++++++++++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/examples/gcc/README.md b/examples/gcc/README.md index d7b7071..0ecb6db 100644 --- a/examples/gcc/README.md +++ b/examples/gcc/README.md @@ -13,7 +13,7 @@ wget https://gcc.gnu.org/pub/gcc/releases/gcc-15.2.0/gcc-15.2.0.tar.xz tar xf gcc-15.2.0.tar.xz cd gcc-15.2.0 && ./contrib/download_prerequisites && cd .. -# 2. Generate pre-generated files (gengtype/genmatch outputs) +# 2. Generate pre-generated files (gengtype outputs) cd gcc-15.2.0 && mkdir build && cd build ../configure --disable-bootstrap --enable-languages=c && make -j$(nproc) cd ../.. @@ -21,10 +21,8 @@ cd ../.. # 3. Copy pre-generated files into the example cd examples/gcc cp /path/to/gcc-15.2.0/build/gcc/gtype-desc.cc gcc/pre-generated/ -cp /path/to/gcc-15.2.0/build/gcc/gt-*.h gcc/pre-generated/ cp /path/to/gcc-15.2.0/build/gcc/gtype-desc.h gcc/pre-generated/ -cp /path/to/gcc-15.2.0/build/gcc/gimple-match-*.cc gcc/pre-generated/ -cp /path/to/gcc-15.2.0/build/gcc/generic-match-*.cc gcc/pre-generated/ +cp /path/to/gcc-15.2.0/build/gcc/gt-*.h gcc/pre-generated/ # 4. Build cc1 make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc @@ -69,16 +67,16 @@ libcpp ────────────────────→ libcpp.a ## Pre-generated Files -Two GCC generators are too complex to implement initially: +One GCC generator is too complex to implement initially: - **gengtype** scans all source files to produce GC type descriptors (`gtype-desc.cc`, `gtype-desc.h`, `gt-*.h`) -- **genmatch** depends on libcpp and produces pattern matchers - (`gimple-match-*.cc`, `generic-match-*.cc`) These must be copied from a configured GCC build into `gcc/pre-generated/`. -The outputs are target-independent (gengtype) or stable across x86_64 builds -(genmatch), so they only need to be generated once. +The outputs are target-independent, so they only need to be generated once. + +**genmatch** (which produces `gimple-match-*.cc` and `generic-match-*.cc`) +is built and run as part of the normal build, using libcpp for tokenization. ## Per-Component Configuration @@ -203,7 +201,7 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) | `gcc/c-family/Tupfile` | C-family shared objects | | `gcc/analyzer/Tupfile` | Static analyzer objects | | `gcc/config/i386/Tupfile` | x86_64 target-specific objects | -| `gcc/pre-generated/` | gengtype + genmatch outputs | +| `gcc/pre-generated/` | gengtype outputs | ## Build Features Demonstrated @@ -226,4 +224,4 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) - Requires: gcc, g++, m4 (for GMP assembly mode), gawk (for GCC options pipeline) - Target: x86_64-linux native (host == target) -- Pre-generated files must be provided from a configured GCC build (see Quick Start) +- Pre-generated gengtype files must be provided from a configured GCC build (see Quick Start) diff --git a/examples/gcc/gcc/Tupfile b/examples/gcc/gcc/Tupfile index 666d458..206f3ef 100644 --- a/examples/gcc/gcc/Tupfile +++ b/examples/gcc/gcc/Tupfile @@ -11,7 +11,7 @@ include_rules # 4. Backend + common object compilation # 5. cc1 link # -# Pre-generated files (gtype-desc.cc, gimple-match-*, generic-match-*) +# Pre-generated files (gtype-desc.cc, gtype-desc.h, gt-*.h) # must be placed in pre-generated/ from a configured GCC build. SRC = $(S)/$(GCC_DIR) @@ -254,6 +254,42 @@ BUILD_ERRORS = host-errors.o ^ LINK gencfn-macros^ $(HOSTCC) %f -o %o |> gencfn-macros : | gencfn-macros |> ^ GEN %o^ ./gencfn-macros -c > %o \ |> case-cfn-macros.h +: | gencfn-macros |> ^ GEN %o^ ./gencfn-macros -o > %o \ + |> cfn-operators.pd + +# genmatch (reads match.pd via libcpp tokenizer) +: genmatch.cc | $(BUILD_RTL_DEPS) |> ^ HOSTCXX %b^ \ + $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-genmatch.o + +: host-genmatch.o $(BUILD_ERRORS) host-vec.o host-hash-table.o host-sort.o \ + $(LIBCPP_A) $(LIBIBERTY_A) |> \ + ^ LINK genmatch^ $(HOSTCC) %f -o %o |> genmatch + +: $(SRC)/match.pd | genmatch cfn-operators.pd |> ^ GEN gimple-match-*^ \ + ./genmatch --gimple \ + --header=gimple-match-auto.h --include=gimple-match-auto.h \ + %f \ + gimple-match-1.cc gimple-match-2.cc gimple-match-3.cc \ + gimple-match-4.cc gimple-match-5.cc gimple-match-6.cc \ + gimple-match-7.cc gimple-match-8.cc gimple-match-9.cc \ + gimple-match-10.cc \ + |> gimple-match-auto.h gimple-match-1.cc gimple-match-2.cc \ + gimple-match-3.cc gimple-match-4.cc gimple-match-5.cc \ + gimple-match-6.cc gimple-match-7.cc gimple-match-8.cc \ + gimple-match-9.cc gimple-match-10.cc + +: $(SRC)/match.pd | genmatch cfn-operators.pd |> ^ GEN generic-match-*^ \ + ./genmatch --generic \ + --header=generic-match-auto.h --include=generic-match-auto.h \ + %f \ + generic-match-1.cc generic-match-2.cc generic-match-3.cc \ + generic-match-4.cc generic-match-5.cc generic-match-6.cc \ + generic-match-7.cc generic-match-8.cc generic-match-9.cc \ + generic-match-10.cc \ + |> generic-match-auto.h generic-match-1.cc generic-match-2.cc \ + generic-match-3.cc generic-match-4.cc generic-match-5.cc \ + generic-match-6.cc generic-match-7.cc generic-match-8.cc \ + generic-match-9.cc generic-match-10.cc # genconstants (MD input only, no insn-conditions.md) : genconstants.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genconstants.o @@ -422,13 +458,26 @@ gen_srcs += insn-automata.cc insn-extract.cc insn-output.cc insn-peep.cc gen_srcs += insn-preds.cc insn-opinit.cc insn-enums.cc : foreach $(gen_srcs) |> !cxx |> %B.o +# gimple-match split (from genmatch --gimple) +: foreach gimple-match-1.cc gimple-match-2.cc gimple-match-3.cc gimple-match-4.cc \ + gimple-match-5.cc gimple-match-6.cc gimple-match-7.cc gimple-match-8.cc \ + gimple-match-9.cc gimple-match-10.cc |> !cxx |> %B.o + +# generic-match split (from genmatch --generic) +: foreach generic-match-1.cc generic-match-2.cc generic-match-3.cc generic-match-4.cc \ + generic-match-5.cc generic-match-6.cc generic-match-7.cc generic-match-8.cc \ + generic-match-9.cc generic-match-10.cc |> !cxx |> %B.o + +# gimple-match-exports (hand-written API wrapper for generated match code) +: gimple-match-exports.cc |> !cxx |> gimple-match-exports.o + # ============================================================ # Phase 5: Backend objects (OBJS from Makefile.in) # ============================================================ # ~445 source files from gcc/. Excludes: # - analyzer/* (compiled in analyzer/Tupfile) # - config/i386/* (compiled in config/i386/Tupfile) -# - pre-generated gtype-desc.cc, gimple-match-*, generic-match-* +# - pre-generated gtype-desc.cc (gengtype output) # - Generated insn-*.cc and options*.cc (compiled above) objs = ggc-page.cc adjust-alignment.cc alias.cc alloc-pool.cc @@ -650,25 +699,16 @@ common += hooks.cc file-find.cc opt-suggestions.cc : attribs.cc |> !cxx |> attribs.o # ============================================================ -# Phase 7: Pre-generated sources +# Phase 7: Pre-generated sources (gengtype only) # ============================================================ -# gengtype and genmatch outputs must be copied from a configured -# GCC build into pre-generated/ before building. +# gengtype outputs must be copied from a configured GCC build +# into pre-generated/ before building. # -# cp build-gcc/gcc/gtype-desc.cc pre-generated/ -# cp build-gcc/gcc/gimple-match-*.cc pre-generated/ -# cp build-gcc/gcc/gimple-match-auto.h pre-generated/ -# cp build-gcc/gcc/gimple-match-exports.cc pre-generated/ -# cp build-gcc/gcc/generic-match-*.cc pre-generated/ -# cp build-gcc/gcc/generic-match-auto.h pre-generated/ -# cp build-gcc/gcc/gt-*.h pre-generated/ -# cp build-gcc/gcc/gtype-desc.h pre-generated/ +# cp build-gcc/gcc/gtype-desc.cc pre-generated/ +# cp build-gcc/gcc/gtype-desc.h pre-generated/ +# cp build-gcc/gcc/gt-*.h pre-generated/ : pre-generated/gtype-desc.cc |> !cxx |> gtype-desc.o -: pre-generated/gimple-match-exports.cc |> !cxx |> gimple-match-exports.o - -: foreach pre-generated/gimple-match-[0-9]*.cc |> !cxx |> %B.o -: foreach pre-generated/generic-match-[0-9]*.cc |> !cxx |> %B.o # ============================================================ # Phase 8: Link cc1 From 701fb6f7fb7cd6bd5443e94721d017b685b41797 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:53:39 +0800 Subject: [PATCH 04/16] Fix generator paths, config headers, and library builds for 3-tree mode --- examples/gcc/README.md | 34 +-- examples/gcc/gcc/Tupfile | 339 ++++++++++++++++++------- examples/gcc/gcc/Tuprules.tup | 7 +- examples/gcc/gcc/tup.config | 18 +- examples/gcc/gmp/Tuprules.tup | 2 +- examples/gcc/gmp/mpn/tup.config | 13 +- examples/gcc/gmp/tup.config | 4 +- examples/gcc/libbacktrace/Tuprules.tup | 3 +- examples/gcc/libcpp/Tuprules.tup | 2 +- examples/gcc/libcpp/tup.config | 4 +- examples/gcc/libdecnumber/Tupfile | 3 + examples/gcc/libdecnumber/Tuprules.tup | 2 +- examples/gcc/libiberty/Tuprules.tup | 2 +- examples/gcc/libiberty/tup.config | 2 +- examples/gcc/mpc/Tuprules.tup | 2 +- examples/gcc/mpfr/Tupfile | 3 +- examples/gcc/mpfr/Tuprules.tup | 2 +- examples/gcc/mpfr/src/Tupfile | 5 +- src/cli/context.cpp | 1 + test/unit/test_e2e.cpp | 65 +++++ 20 files changed, 353 insertions(+), 160 deletions(-) diff --git a/examples/gcc/README.md b/examples/gcc/README.md index 0ecb6db..3006848 100644 --- a/examples/gcc/README.md +++ b/examples/gcc/README.md @@ -13,18 +13,8 @@ wget https://gcc.gnu.org/pub/gcc/releases/gcc-15.2.0/gcc-15.2.0.tar.xz tar xf gcc-15.2.0.tar.xz cd gcc-15.2.0 && ./contrib/download_prerequisites && cd .. -# 2. Generate pre-generated files (gengtype outputs) -cd gcc-15.2.0 && mkdir build && cd build -../configure --disable-bootstrap --enable-languages=c && make -j$(nproc) -cd ../.. - -# 3. Copy pre-generated files into the example +# 2. Build cc1 cd examples/gcc -cp /path/to/gcc-15.2.0/build/gcc/gtype-desc.cc gcc/pre-generated/ -cp /path/to/gcc-15.2.0/build/gcc/gtype-desc.h gcc/pre-generated/ -cp /path/to/gcc-15.2.0/build/gcc/gt-*.h gcc/pre-generated/ - -# 4. Build cc1 make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc ``` @@ -65,19 +55,6 @@ libbacktrace ──────────────→ libbacktrace.a ── libcpp ────────────────────→ libcpp.a ─────────────────┘ ``` -## Pre-generated Files - -One GCC generator is too complex to implement initially: - -- **gengtype** scans all source files to produce GC type descriptors - (`gtype-desc.cc`, `gtype-desc.h`, `gt-*.h`) - -These must be copied from a configured GCC build into `gcc/pre-generated/`. -The outputs are target-independent, so they only need to be generated once. - -**genmatch** (which produces `gimple-match-*.cc` and `generic-match-*.cc`) -is built and run as part of the normal build, using libcpp for tokenization. - ## Per-Component Configuration Each library has its own `tup.config` with prefix-free entries. The directory scope @@ -155,6 +132,10 @@ genconditions → gencondmd.cc → compile+link gencondmd → insn-conditions.md All other generators (read .md files, produce insn-*.h / insn-*.cc) → genattr, genattrtab, genautomata, gencodes, genconfig, ... → genemit (10 split outputs), genrecog (10 split outputs + header) + +gengtype (GC type descriptors, needs libiberty) + → parses GTY annotations from gtyp-input.list + → gtype-desc.cc, gtype-desc.h, gtype-c.h, gt-*.h (~60 headers) ``` ## Assembly Support @@ -201,12 +182,13 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) | `gcc/c-family/Tupfile` | C-family shared objects | | `gcc/analyzer/Tupfile` | Static analyzer objects | | `gcc/config/i386/Tupfile` | x86_64 target-specific objects | -| `gcc/pre-generated/` | gengtype outputs | +| `gcc/Tupfile` (gtyp section) | gengtype input file list (inline, from GTFILES) | ## Build Features Demonstrated - **Host-tool bootstrapping**: ~25 generator programs compiled and run during the build - **Generated source pipeline**: `.md` → generators → `insn-*.h` / `insn-*.cc` → cc1 +- **GC type descriptor generation**: gengtype parses GTY annotations across all source files, producing `gtype-desc.cc` and ~60 `gt-*.h` headers - **Multi-output generators**: genemit produces 10 split files, genrecog produces 10 + header - **~500-file C++ compilation**: Full GCC backend with analyzer, C frontend, target-specific code - **Cross-directory groups**: Subdirectory objects collected via `../` into parent @@ -224,4 +206,4 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) - Requires: gcc, g++, m4 (for GMP assembly mode), gawk (for GCC options pipeline) - Target: x86_64-linux native (host == target) -- Pre-generated gengtype files must be provided from a configured GCC build (see Quick Start) +- All generators (including gengtype) are built and run as part of the normal build — no `./configure && make` step required diff --git a/examples/gcc/gcc/Tupfile b/examples/gcc/gcc/Tupfile index 206f3ef..522a912 100644 --- a/examples/gcc/gcc/Tupfile +++ b/examples/gcc/gcc/Tupfile @@ -4,15 +4,14 @@ include_rules # GCC 15.2.0 — C compiler backend (x86_64-linux) # ============================================================ # -# Builds cc1 from the GCC source tree via five phases: +# Builds cc1 from the GCC source tree via seven phases: # 1. Config headers + options pipeline # 2. Generator bootstrap (genmodes → BUILD_RTL → generators) -# 3. Machine-description → insn-*.h / insn-*.cc -# 4. Backend + common object compilation -# 5. cc1 link -# -# Pre-generated files (gtype-desc.cc, gtype-desc.h, gt-*.h) -# must be placed in pre-generated/ from a configured GCC build. +# 3. Machine-description generators + gengtype (GC type descriptors) +# 4. Generated source compilation +# 5. Backend + common object compilation +# 6. Common objects +# 7. cc1 link SRC = $(S)/$(GCC_DIR) @@ -27,7 +26,15 @@ MD = common.md config/i386/i386.md : |> !gen-config |> auto-host.h # bconfig.h — build-machine config (generators only) -: |> ^ GEN %o^ echo '#include "auto-host.h"' > %o |> bconfig.h +: |> ^ GEN %o^ ( \ + echo '#ifndef GCC_BCONFIG_H'; \ + echo '#define GCC_BCONFIG_H'; \ + echo '#include "auto-host.h"'; \ + echo '#ifdef IN_GCC'; \ + echo '# include "ansidecl.h"'; \ + echo '#endif'; \ + echo '#endif'; \ + ) > %o |> bconfig.h # config.h — target config (not for generators) : |> ^ GEN %o^ ( \ @@ -106,21 +113,43 @@ OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt echo '#define GCC_TM_P_H'; \ echo '#ifdef IN_GCC'; \ echo '# include "config/i386/i386-protos.h"'; \ + echo '# include "config/linux-protos.h"'; \ + echo '# include "tm-preds.h"'; \ echo '#endif'; \ echo '#endif'; \ ) > %o |> tm_p.h # tm.h — target machine description for x86_64-linux-gnu -# Includes options.h and the i386 target header chain. +# Matches the real configure-generated tm.h layout. : |> ^ GEN %o^ ( \ echo '#ifndef GCC_TM_H'; \ echo '#define GCC_TM_H'; \ - echo '#define LIBC_GLIBC 1'; \ - echo '#define LIBC_UCLIBC 2'; \ - echo '#define LIBC_BIONIC 3'; \ - echo '#define LIBC_MUSL 4'; \ + echo '#ifndef LIBC_GLIBC'; \ + echo '# define LIBC_GLIBC 1'; \ + echo '#endif'; \ + echo '#ifndef LIBC_UCLIBC'; \ + echo '# define LIBC_UCLIBC 2'; \ + echo '#endif'; \ + echo '#ifndef LIBC_BIONIC'; \ + echo '# define LIBC_BIONIC 3'; \ + echo '#endif'; \ + echo '#ifndef LIBC_MUSL'; \ + echo '# define LIBC_MUSL 4'; \ + echo '#endif'; \ + echo '#ifndef DEFAULT_LIBC'; \ + echo '# define DEFAULT_LIBC LIBC_GLIBC'; \ + echo '#endif'; \ + echo '#ifndef ANDROID_DEFAULT'; \ + echo '# define ANDROID_DEFAULT 0'; \ + echo '#endif'; \ + echo '#ifndef HEAP_TRAMPOLINES_INIT'; \ + echo '# define HEAP_TRAMPOLINES_INIT 0'; \ + echo '#endif'; \ echo '#ifdef IN_GCC'; \ echo '# include "options.h"'; \ + echo '# include "insn-constants.h"'; \ + echo '# include "config/vxworks-dummy.h"'; \ + echo '# include "config/i386/biarch64.h"'; \ echo '# include "config/i386/i386.h"'; \ echo '# include "config/i386/unix.h"'; \ echo '# include "config/i386/att.h"'; \ @@ -137,13 +166,12 @@ OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt echo '# include "config/initfini-array.h"'; \ echo '#endif'; \ echo '#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET'; \ - echo '# include "insn-constants.h"'; \ echo '# include "insn-flags.h"'; \ echo '#endif'; \ echo '#if defined IN_GCC && !defined GENERATOR_FILE'; \ echo '# include "insn-modes.h"'; \ echo '#endif'; \ - echo '#include "defaults.h"'; \ + echo '# include "defaults.h"'; \ echo '#endif'; \ ) > %o |> tm.h @@ -158,6 +186,7 @@ OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt # insn-conditions.md → all RTL generators # Host support objects (prefixed to avoid collision with target objects) +BUILD_ERRORS = host-errors.o : errors.cc |> !hostcxx |> host-errors.o # genmodes needs EXTRA_MODES_FILE for i386 @@ -165,19 +194,30 @@ OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt -DEXTRA_MODES_FILE=\"config/i386/i386-modes.def\" -c %f -o %o \ |> host-genmodes.o -: host-genmodes.o host-errors.o |> ^ LINK genmodes^ $(HOSTCC) %f -o %o |> genmodes +: host-genmodes.o host-errors.o $(LIBIBERTY_A) |> ^ LINK genmodes^ $(HOSTCC) %f -o %o |> genmodes -: | genmodes |> ^ GEN %o^ ./genmodes -h > %o |> insn-modes.h -: | genmodes |> ^ GEN %o^ ./genmodes -i > %o |> insn-modes-inline.h -: | genmodes |> ^ GEN %o^ ./genmodes > %o |> insn-modes.cc -: | genmodes |> ^ GEN %o^ ./genmodes -m > %o |> min-insn-modes.cc +: | genmodes |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genmodes -h > %o |> insn-modes.h +: | genmodes |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genmodes -i > %o |> insn-modes-inline.h +: | genmodes |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genmodes > %o |> insn-modes.cc +: | genmodes |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genmodes -m > %o |> min-insn-modes.cc # min-insn-modes.o (host, from generated source) -: min-insn-modes.cc | |> \ - ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-min-insn-modes.o +: min-insn-modes.cc |> !hostcxx |> host-min-insn-modes.o -# BUILD_RTL objects (need insn-modes.h + insn-modes-inline.h) -BUILD_RTL_DEPS = insn-modes.h insn-modes-inline.h +# BUILD_MD (no tm.h → no insn-constants.h needed) +EARLY_GEN_DEPS = insn-modes.h insn-modes-inline.h +: read-md.cc | $(EARLY_GEN_DEPS) |> !hostcxx |> host-read-md.o + +# genconstants (MD input only — early because tm.h includes insn-constants.h) +: genconstants.cc | $(EARLY_GEN_DEPS) |> !hostcxx |> host-genconstants.o +: host-genconstants.o host-read-md.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK genconstants^ $(HOSTCC) %f -o %o |> genconstants +: $(MD) | genconstants |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genconstants %f > %o \ + |> insn-constants.h + +# BUILD_RTL objects +# IN_GCC → tm.h → insn-constants.h; GENERATOR_FILE → rtl.h → ggc.h → gtype-desc.h +BUILD_RTL_DEPS = insn-modes.h insn-modes-inline.h insn-constants.h gtype-desc.h : rtl.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-rtl.o : read-rtl.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-read-rtl.o @@ -189,14 +229,10 @@ BUILD_RTL_DEPS = insn-modes.h insn-modes-inline.h : sort.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-sort.o : inchash.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-inchash.o -# BUILD_MD -: read-md.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-read-md.o - BUILD_RTL = host-rtl.o host-read-rtl.o host-ggc-none.o host-vec.o BUILD_RTL += host-min-insn-modes.o host-gensupport.o host-print-rtl.o BUILD_RTL += host-hash-table.o host-sort.o BUILD_MD = host-read-md.o -BUILD_ERRORS = host-errors.o # --- genconditions → gencondmd bootstrap --- @@ -205,15 +241,15 @@ BUILD_ERRORS = host-errors.o : host-genconditions.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) \ $(LIBIBERTY_A) |> ^ LINK genconditions^ $(HOSTCC) %f -o %o |> genconditions -: $(MD) | genconditions |> ^ GEN %o^ ./genconditions %f > %o |> gencondmd.cc +: $(MD) | genconditions |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genconditions %f > %o |> gencondmd.cc -: gencondmd.cc | |> \ - ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-gencondmd.o +: gencondmd.cc | |> ^ HOSTCXX %b^ \ + $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-gencondmd.o : host-gencondmd.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK gencondmd^ $(HOSTCC) %f -o %o |> gencondmd -: | gencondmd |> ^ GEN %o^ ./gencondmd > %o |> insn-conditions.md +: | gencondmd |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gencondmd > %o |> insn-conditions.md # ============================================================ # Phase 3: Generators @@ -230,21 +266,27 @@ BUILD_ERRORS = host-errors.o : gengenrtl.cc |> !hostcxx |> host-gengenrtl.o : host-gengenrtl.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK gengenrtl^ $(HOSTCC) %f -o %o |> gengenrtl -: | gengenrtl |> ^ GEN %o^ ./gengenrtl > %o |> genrtl.h +: | gengenrtl |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gengenrtl > %o |> genrtl.h -# gencheck (no MD input, uses tree.def) -: gencheck.cc |> !hostcxx |> host-gencheck.o -: host-gencheck.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ - ^ LINK gencheck^ $(HOSTCC) %f -o %o |> gencheck -: | gencheck |> ^ GEN %o^ ./gencheck > %o |> tree-check.h +# all-tree.def — aggregates tree.def + language-specific defs (C only) +: |> ^ GEN %o^ ( \ + echo '#include "tree.def"'; \ + echo 'END_OF_BASE_TREE_CODES'; \ + echo '#include "c-family/c-common.def"'; \ + ) > %o |> all-tree.def + +# gencheck (uses all-tree.def + insn-modes.h via coretypes.h → tm.h) +: gencheck.cc | $(BUILD_RTL_DEPS) all-tree.def |> !hostcxx |> host-gencheck.o +: host-gencheck.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> ^ LINK gencheck^ $(HOSTCC) %f -o %o |> gencheck +: | gencheck |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gencheck > %o |> tree-check.h # genhooks (no MD input, produces multiple hook headers) : genhooks.cc |> !hostcxx |> host-genhooks.o : host-genhooks.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genhooks^ $(HOSTCC) %f -o %o |> genhooks -: | genhooks |> ^ GEN %o^ ./genhooks "Target Hook" > %o \ +: | genhooks |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genhooks "Target Hook" > %o \ |> target-hooks-def.h -: | genhooks |> ^ GEN %o^ ./genhooks "Common Target Hook" > %o \ +: | genhooks |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genhooks "Common Target Hook" > %o \ |> common-target-hooks-def.h # gencfn-macros (no MD input) @@ -252,13 +294,13 @@ BUILD_ERRORS = host-errors.o : host-gencfn-macros.o $(BUILD_ERRORS) host-hash-table.o host-vec.o \ host-ggc-none.o host-sort.o $(LIBIBERTY_A) |> \ ^ LINK gencfn-macros^ $(HOSTCC) %f -o %o |> gencfn-macros -: | gencfn-macros |> ^ GEN %o^ ./gencfn-macros -c > %o \ +: | gencfn-macros |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gencfn-macros -c > %o \ |> case-cfn-macros.h -: | gencfn-macros |> ^ GEN %o^ ./gencfn-macros -o > %o \ +: | gencfn-macros |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gencfn-macros -o > %o \ |> cfn-operators.pd # genmatch (reads match.pd via libcpp tokenizer) -: genmatch.cc | $(BUILD_RTL_DEPS) |> ^ HOSTCXX %b^ \ +: genmatch.cc | $(BUILD_RTL_DEPS) case-cfn-macros.h |> ^ HOSTCXX %b^ \ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-genmatch.o : host-genmatch.o $(BUILD_ERRORS) host-vec.o host-hash-table.o host-sort.o \ @@ -266,9 +308,9 @@ BUILD_ERRORS = host-errors.o ^ LINK genmatch^ $(HOSTCC) %f -o %o |> genmatch : $(SRC)/match.pd | genmatch cfn-operators.pd |> ^ GEN gimple-match-*^ \ - ./genmatch --gimple \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genmatch --gimple \ --header=gimple-match-auto.h --include=gimple-match-auto.h \ - %f \ + $SRCDIR/match.pd \ gimple-match-1.cc gimple-match-2.cc gimple-match-3.cc \ gimple-match-4.cc gimple-match-5.cc gimple-match-6.cc \ gimple-match-7.cc gimple-match-8.cc gimple-match-9.cc \ @@ -279,9 +321,9 @@ BUILD_ERRORS = host-errors.o gimple-match-9.cc gimple-match-10.cc : $(SRC)/match.pd | genmatch cfn-operators.pd |> ^ GEN generic-match-*^ \ - ./genmatch --generic \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genmatch --generic \ --header=generic-match-auto.h --include=generic-match-auto.h \ - %f \ + $SRCDIR/match.pd \ generic-match-1.cc generic-match-2.cc generic-match-3.cc \ generic-match-4.cc generic-match-5.cc generic-match-6.cc \ generic-match-7.cc generic-match-8.cc generic-match-9.cc \ @@ -291,55 +333,48 @@ BUILD_ERRORS = host-errors.o generic-match-6.cc generic-match-7.cc generic-match-8.cc \ generic-match-9.cc generic-match-10.cc -# genconstants (MD input only, no insn-conditions.md) -: genconstants.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genconstants.o -: host-genconstants.o $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ - ^ LINK genconstants^ $(HOSTCC) %f -o %o |> genconstants -: $(MD) | genconstants |> ^ GEN %o^ ./genconstants %f > %o \ - |> insn-constants.h - # genenums (MD input only) : genenums.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genenums.o : host-genenums.o $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genenums^ $(HOSTCC) %f -o %o |> genenums -: $(MD) | genenums |> ^ GEN %o^ ./genenums %f > %o |> insn-enums.cc +: $(MD) | genenums |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genenums %f > %o |> insn-enums.cc # --- Simple RTL generators (MD + insn-conditions.md → header output) --- : genattr.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattr.o : host-genattr.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genattr^ $(HOSTCC) %f -o %o |> genattr -: $(MD) insn-conditions.md | genattr |> ^ GEN %o^ ./genattr %f > %o \ +: $(MD) insn-conditions.md | genattr |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genattr%f > %o \ |> insn-attr.h : genattr-common.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattr-common.o : host-genattr-common.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genattr-common^ $(HOSTCC) %f -o %o |> genattr-common -: $(MD) insn-conditions.md | genattr-common |> ^ GEN %o^ ./genattr-common %f > %o \ +: $(MD) insn-conditions.md | genattr-common |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genattr-common %f > %o \ |> insn-attr-common.h : gencodes.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gencodes.o : host-gencodes.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK gencodes^ $(HOSTCC) %f -o %o |> gencodes -: $(MD) insn-conditions.md | gencodes |> ^ GEN %o^ ./gencodes %f > %o \ +: $(MD) insn-conditions.md | gencodes |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gencodes %f > %o \ |> insn-codes.h : genconfig.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genconfig.o : host-genconfig.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genconfig^ $(HOSTCC) %f -o %o |> genconfig -: $(MD) insn-conditions.md | genconfig |> ^ GEN %o^ ./genconfig %f > %o \ +: $(MD) insn-conditions.md | genconfig |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genconfig %f > %o \ |> insn-config.h : genflags.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genflags.o : host-genflags.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genflags^ $(HOSTCC) %f -o %o |> genflags -: $(MD) insn-conditions.md | genflags |> ^ GEN %o^ ./genflags %f > %o \ +: $(MD) insn-conditions.md | genflags |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genflags %f > %o \ |> insn-flags.h : gentarget-def.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gentarget-def.o : host-gentarget-def.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK gentarget-def^ $(HOSTCC) %f -o %o |> gentarget-def -: $(MD) insn-conditions.md | gentarget-def |> ^ GEN %o^ ./gentarget-def %f > %o \ +: $(MD) insn-conditions.md | gentarget-def |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gentarget-def %f > %o \ |> insn-target-def.h # --- Simple RTL generators (MD + insn-conditions.md → source output) --- @@ -347,25 +382,25 @@ BUILD_ERRORS = host-errors.o : genautomata.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genautomata.o : host-genautomata.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genautomata^ $(HOSTCC) %f -o %o -lm |> genautomata -: $(MD) insn-conditions.md | genautomata |> ^ GEN %o^ ./genautomata %f > %o \ +: $(MD) insn-conditions.md | genautomata |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genautomata %f > %o \ |> insn-automata.cc : genextract.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genextract.o : host-genextract.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genextract^ $(HOSTCC) %f -o %o |> genextract -: $(MD) insn-conditions.md | genextract |> ^ GEN %o^ ./genextract %f > %o \ +: $(MD) insn-conditions.md | genextract |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genextract %f > %o \ |> insn-extract.cc : genoutput.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genoutput.o : host-genoutput.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genoutput^ $(HOSTCC) %f -o %o |> genoutput -: $(MD) insn-conditions.md | genoutput |> ^ GEN %o^ ./genoutput %f > %o \ +: $(MD) insn-conditions.md | genoutput |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genoutput %f > %o \ |> insn-output.cc : genpeep.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genpeep.o : host-genpeep.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genpeep^ $(HOSTCC) %f -o %o |> genpeep -: $(MD) insn-conditions.md | genpeep |> ^ GEN %o^ ./genpeep %f > %o \ +: $(MD) insn-conditions.md | genpeep |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genpeep %f > %o \ |> insn-peep.cc # --- Multi-output RTL generators --- @@ -375,7 +410,9 @@ BUILD_ERRORS = host-errors.o : host-genattrtab.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genattrtab^ $(HOSTCC) %f -o %o |> genattrtab : $(MD) insn-conditions.md | genattrtab |> ^ GEN insn-attrtab^ \ - ./genattrtab %f -Ainsn-attrtab.cc -Dinsn-dfatab.cc -Linsn-latencytab.cc \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genattrtab \ + $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + -Ainsn-attrtab.cc -Dinsn-dfatab.cc -Linsn-latencytab.cc \ |> insn-attrtab.cc insn-dfatab.cc insn-latencytab.cc # genopinit → 2 files @@ -383,23 +420,26 @@ BUILD_ERRORS = host-errors.o : host-genopinit.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genopinit^ $(HOSTCC) %f -o %o |> genopinit : $(MD) insn-conditions.md | genopinit |> ^ GEN insn-opinit^ \ - ./genopinit %f -hinsn-opinit.h -cinsn-opinit.cc \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genopinit \ + $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + -hinsn-opinit.h -cinsn-opinit.cc \ |> insn-opinit.h insn-opinit.cc # genpreds → 3 files (separate invocations) : genpreds.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genpreds.o : host-genpreds.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genpreds^ $(HOSTCC) %f -o %o |> genpreds -: $(MD) | genpreds |> ^ GEN %o^ ./genpreds %f > %o |> insn-preds.cc -: $(MD) | genpreds |> ^ GEN %o^ ./genpreds -h %f > %o |> tm-preds.h -: $(MD) | genpreds |> ^ GEN %o^ ./genpreds -c %f > %o |> tm-constrs.h +: $(MD) | genpreds |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genpreds %f > %o |> insn-preds.cc +: $(MD) | genpreds |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genpreds -h %f > %o |> tm-preds.h +: $(MD) | genpreds |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genpreds -c %f > %o |> tm-constrs.h # genemit → 10 split files : genemit.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genemit.o : host-genemit.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genemit^ $(HOSTCC) %f -o %o |> genemit : $(MD) insn-conditions.md | genemit |> ^ GEN insn-emit-*^ \ - ./genemit %f \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genemit \ + $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ -O insn-emit-1.cc -O insn-emit-2.cc -O insn-emit-3.cc \ -O insn-emit-4.cc -O insn-emit-5.cc -O insn-emit-6.cc \ -O insn-emit-7.cc -O insn-emit-8.cc -O insn-emit-9.cc \ @@ -411,10 +451,12 @@ BUILD_ERRORS = host-errors.o # genrecog → 10 split files + header : genrecog.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genrecog.o : host-genrecog.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) \ - host-hash-table.o host-inchash.o $(LIBIBERTY_A) |> \ + host-inchash.o $(LIBIBERTY_A) |> \ ^ LINK genrecog^ $(HOSTCC) %f -o %o |> genrecog : $(MD) insn-conditions.md | genrecog |> ^ GEN insn-recog-*^ \ - ./genrecog %f -Hinsn-recog.h \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genrecog \ + $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + -Hinsn-recog.h \ -O insn-recog-1.cc -O insn-recog-2.cc -O insn-recog-3.cc \ -O insn-recog-4.cc -O insn-recog-5.cc -O insn-recog-6.cc \ -O insn-recog-7.cc -O insn-recog-8.cc -O insn-recog-9.cc \ @@ -430,6 +472,125 @@ BUILD_ERRORS = host-errors.o awk -f $(SRC)/gen-pass-instances.awk %f > %o \ |> pass-instances.def +# --- gengtype (GC type descriptor generator) --- +# +# gengtype scans GTY-annotated source files and generates GC marking code. +# Two passes: -w writes gtype.state, -r reads it and generates output files. +# Uses -DHOST_GENERATOR_FILE (not -DGENERATOR_FILE) because gengtype needs +# full host header access for file I/O, state serialization, and regex. + +GENGTYPE_SRCS = gengtype.cc gengtype-parse.cc gengtype-state.cc gengtype-lex.cc + +: foreach $(GENGTYPE_SRCS) | |> ^ HOSTCXX %b^ \ + $(HOSTCC) -O0 -std=gnu++14 -DHOST_GENERATOR_FILE -DHAVE_CONFIG_H \ + $(GCC_INCLUDES) -c %f -o %o |> host-%B.o + +: host-gengtype.o host-gengtype-parse.o host-gengtype-state.o \ + host-gengtype-lex.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ + ^ LINK gengtype^ $(HOSTCC) %f -o %o |> gengtype + +# gtyp-input.list — generated inline (template files can't be inputs in 3-tree mode) +# Derived from GTFILES in gcc/Makefile.in for x86_64-pc-linux-gnu, C only. +# $(SRC) is expanded at parse time, producing the correct relative paths. + +gtyp_parent = libcpp/include/line-map.h libcpp/include/rich-location.h +gtyp_parent += libcpp/include/label-text.h libcpp/include/cpplib.h +gtyp_parent += include/hashtab.h include/splay-tree.h +gtyp_parent += libcpp/include/symtab.h include/obstack.h + +gtyp_src = input.h coretypes.h +gtyp_src += config/i386/i386.h config/i386/unix.h config/i386/att.h +gtyp_src += config/elfos.h config/gnu-user.h config/glibc-stdint.h +gtyp_src += config/i386/x86-64.h config/i386/gnu-user-common.h config/i386/gnu-user64.h +gtyp_src += config/linux.h config/linux-android.h config/i386/linux-common.h +gtyp_src += config/i386/linux64.h config/initfini-array.h +gtyp_src += bitmap.h wide-int.h alias.h coverage.cc rtl.h optabs.h +gtyp_src += tree.h tree-core.h libfuncs.h +gtyp_src += real.h function.h insn-addr.h hwint.h fixed-value.h function-abi.h +gtyp_src += output.h cfgloop.h cfg.h profile-count.h cselib.h basic-block.h +gtyp_src += ipa-ref.h cgraph.h symtab-thunks.h symtab-thunks.cc symtab-clones.h +gtyp_src += reload.h caller-save.cc symtab.cc alias.cc attribs.cc +gtyp_src += bitmap.cc cselib.cc cgraph.cc ipa-prop.cc ipa-cp.cc +gtyp_src += ipa-utils.h ipa-param-manipulation.h ipa-sra.cc +gtyp_src += ipa-modref.h ipa-modref.cc ipa-modref-tree.h ipa-locality-cloning.cc +gtyp_src += signop.h diagnostic-spec.h diagnostic-spec.cc +gtyp_src += dwarf2out.h dwarf2asm.cc dwarf2cfi.cc dwarf2codeview.cc dwarf2ctf.cc dwarf2out.cc +gtyp_src += ctfc.h ctfout.cc btfout.cc +gtyp_src += tree-vect-generic.cc gimple-isel.cc dojump.cc +gtyp_src += emit-rtl.h emit-rtl.cc except.h explow.cc expr.cc expr.h +gtyp_src += function.cc except.cc ggc-tests.cc gcse.cc godump.cc +gtyp_src += lists.cc optabs-libfuncs.cc profile.cc mcf.cc reg-stack.cc +gtyp_src += cfgrtl.cc stor-layout.cc stringpool.cc tree.cc varasm.cc +gtyp_src += gimple.h gimple-ssa.h tree-ssanames.cc tree-eh.cc +gtyp_src += tree-ssa-address.cc tree-cfg.cc tree-ssa-loop-ivopts.cc +gtyp_src += tree-dfa.cc tree-iterator.cc gimple-expr.cc tree-chrec.h +gtyp_src += tree-scalar-evolution.cc tree-ssa-operands.h +gtyp_src += tree-profile.cc tree-nested.cc path-coverage.cc prime-paths.cc +gtyp_src += omp-offload.h omp-general.h omp-general.cc omp-low.cc +gtyp_src += targhooks.cc config/i386/i386.cc passes.cc cgraphclones.cc +gtyp_src += tree-phinodes.cc tree-ssa-alias.h tree-ssanames.h +gtyp_src += tree-vrp.h value-range.h value-range-storage.h ipa-prop.h +gtyp_src += trans-mem.cc lto-streamer.h target-globals.h +gtyp_src += ipa-predicate.h ipa-fnsummary.h vtable-verify.cc +gtyp_src += asan.cc ubsan.cc tsan.cc sanopt.cc sancov.cc +gtyp_src += ipa-devirt.cc ipa-strub.cc internal-fn.h calls.cc +gtyp_src += analyzer/analyzer-language.cc +gtyp_src += config/i386/i386-builtins.cc config/i386/i386-expand.cc config/i386/i386-options.cc + +gtyp_c = c/c-lang.cc c/c-tree.h c/c-decl.cc +gtyp_c += c-family/c-common.cc c-family/c-common.h c-family/c-objc.h +gtyp_c += c-family/c-cppbuiltin.cc c-family/c-pragma.h c-family/c-pragma.cc +gtyp_c += c-family/c-format.cc c/c-objc-common.cc +gtyp_c += c/c-parser.h c/c-parser.cc c/c-lang.h + +: |> ^ GEN %o^ { \ + for f in $(gtyp_parent); do printf '%s\n' "$(SRC)/../$f"; done; \ + for f in $(gtyp_src); do printf '%s\n' "$(SRC)/$f"; done; \ + printf '%s\n' $(TUP_VARIANT_OUTPUTDIR)/options.h; \ + echo '[c]'; \ + for f in $(gtyp_c); do printf '%s\n' "$(SRC)/$f"; done; \ + } > %o |> gtyp-input.list + +# gengtype outputs: gtype-desc.cc/h, gtype-c.h, gt-*.h +GT_H = gtype-desc.h gtype-c.h +GT_H += gt-alias.h gt-asan.h gt-attribs.h gt-bitmap.h gt-btfout.h +GT_H += gt-caller-save.h gt-calls.h gt-cfgrtl.h gt-cgraph.h gt-cgraphclones.h +GT_H += gt-coverage.h gt-cselib.h gt-ctfout.h +GT_H += gt-diagnostic-spec.h gt-dojump.h +GT_H += gt-dwarf2asm.h gt-dwarf2cfi.h gt-dwarf2codeview.h gt-dwarf2ctf.h gt-dwarf2out.h +GT_H += gt-emit-rtl.h gt-except.h gt-explow.h gt-expr.h +GT_H += gt-function.h +GT_H += gt-gcse.h gt-ggc-tests.h gt-gimple-expr.h gt-gimple-isel.h gt-godump.h +GT_H += gt-ipa-cp.h gt-ipa-devirt.h gt-ipa-locality-cloning.h +GT_H += gt-ipa-modref.h gt-ipa-prop.h gt-ipa-sra.h gt-ipa-strub.h +GT_H += gt-lists.h +GT_H += gt-mcf.h +GT_H += gt-omp-general.h gt-omp-low.h gt-optabs-libfuncs.h +GT_H += gt-passes.h gt-path-coverage.h gt-prime-paths.h gt-profile.h +GT_H += gt-reg-stack.h +GT_H += gt-sancov.h gt-sanopt.h gt-stor-layout.h gt-stringpool.h +GT_H += gt-symtab.h gt-symtab-thunks.h +GT_H += gt-targhooks.h gt-trans-mem.h gt-tree.h +GT_H += gt-tree-cfg.h gt-tree-dfa.h gt-tree-eh.h gt-tree-iterator.h +GT_H += gt-tree-nested.h gt-tree-phinodes.h gt-tree-profile.h +GT_H += gt-tree-scalar-evolution.h gt-tree-ssa-address.h +GT_H += gt-tree-ssa-loop-ivopts.h gt-tree-ssanames.h +GT_H += gt-tree-vect-generic.h gt-tsan.h gt-ubsan.h +GT_H += gt-varasm.h gt-vtable-verify.h +GT_H += gt-i386.h gt-i386-builtins.h gt-i386-expand.h gt-i386-options.h +GT_H += gt-analyzer-language.h +GT_H += gt-c-c-decl.h gt-c-c-lang.h gt-c-c-objc-common.h gt-c-c-parser.h +GT_H += gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h +GT_H += gt-c-family-c-format.h gt-c-family-c-objc.h gt-c-family-c-pragma.h + +: gtyp-input.list | gengtype |> ^ GEN gtype-desc^ \ + $(TUP_VARIANT_OUTPUTDIR)/gengtype -S $(SRC) \ + -I $(TUP_VARIANT_OUTPUTDIR)/gtyp-input.list \ + -w $(TUP_VARIANT_OUTPUTDIR)/gtype.state && \ + cd $(TUP_VARIANT_OUTPUTDIR) && \ + ./gengtype -r gtype.state \ + |> gtype-desc.cc $(GT_H) + # ============================================================ # Phase 4: Generated source compilation → # ============================================================ @@ -471,14 +632,16 @@ gen_srcs += insn-preds.cc insn-opinit.cc insn-enums.cc # gimple-match-exports (hand-written API wrapper for generated match code) : gimple-match-exports.cc |> !cxx |> gimple-match-exports.o +# gtype-desc (from gengtype) +: gtype-desc.cc |> !cxx |> gtype-desc.o + # ============================================================ # Phase 5: Backend objects (OBJS from Makefile.in) # ============================================================ # ~445 source files from gcc/. Excludes: # - analyzer/* (compiled in analyzer/Tupfile) # - config/i386/* (compiled in config/i386/Tupfile) -# - pre-generated gtype-desc.cc (gengtype output) -# - Generated insn-*.cc and options*.cc (compiled above) +# - Generated insn-*.cc, options*.cc, gtype-desc.cc (compiled above) objs = ggc-page.cc adjust-alignment.cc alias.cc alloc-pool.cc objs += auto-inc-dec.cc auto-profile.cc @@ -627,23 +790,23 @@ objs += vr-values.cc vtable-verify.cc warning-control.cc web.cc objs += wide-int.cc wide-int-print.cc # Special -D flags for a few objects -: toplev.cc | |> ^ CXX %b^ \ +: toplev.cc | |> ^ CXX %b^ \ $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ |> toplev.o -: lto-streamer-in.cc | |> ^ CXX %b^ \ +: lto-streamer-in.cc | |> ^ CXX %b^ \ $(CXX) $(TARGET_CXXFLAGS) -DTARGET_MACHINE=\"x86_64-pc-linux-gnu\" -c %f -o %o \ |> lto-streamer-in.o -: optinfo-emit-json.cc | |> ^ CXX %b^ \ +: optinfo-emit-json.cc | |> ^ CXX %b^ \ $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ |> optinfo-emit-json.o -: tree-diagnostic-client-data-hooks.cc | |> ^ CXX %b^ \ +: tree-diagnostic-client-data-hooks.cc | |> ^ CXX %b^ \ $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ |> tree-diagnostic-client-data-hooks.o -: cppbuiltin.cc | |> ^ CXX %b^ \ +: cppbuiltin.cc | |> ^ CXX %b^ \ $(CXX) $(TARGET_CXXFLAGS) -DBASEVER=\"15.2.0\" -c %f -o %o \ |> cppbuiltin.o @@ -676,7 +839,7 @@ common += hooks.cc file-find.cc opt-suggestions.cc : foreach $(common) |> !cxx |> %B.o -: prefix.cc | |> ^ CXX %b^ \ +: prefix.cc | |> ^ CXX %b^ \ $(CXX) $(TARGET_CXXFLAGS) -DPREFIX=\"/usr/local\" -DBASEVER=\"15.2.0\" -c %f -o %o \ |> prefix.o @@ -699,19 +862,7 @@ common += hooks.cc file-find.cc opt-suggestions.cc : attribs.cc |> !cxx |> attribs.o # ============================================================ -# Phase 7: Pre-generated sources (gengtype only) -# ============================================================ -# gengtype outputs must be copied from a configured GCC build -# into pre-generated/ before building. -# -# cp build-gcc/gcc/gtype-desc.cc pre-generated/ -# cp build-gcc/gcc/gtype-desc.h pre-generated/ -# cp build-gcc/gcc/gt-*.h pre-generated/ - -: pre-generated/gtype-desc.cc |> !cxx |> gtype-desc.o - -# ============================================================ -# Phase 8: Link cc1 +# Phase 7: Link cc1 # ============================================================ # Collects objects from this directory and subdirectories: # gcc/c/ → ../ (C frontend) diff --git a/examples/gcc/gcc/Tuprules.tup b/examples/gcc/gcc/Tuprules.tup index 99e1859..4cd15c9 100644 --- a/examples/gcc/gcc/Tuprules.tup +++ b/examples/gcc/gcc/Tuprules.tup @@ -41,7 +41,7 @@ GCC_INCLUDES += -I$(B)/$(MPC_DIR)/src -I$(S)/$(MPC_DIR)/src # --- HOST compilation (generators) --- HOST_CXXFLAGS = -O0 -std=gnu++14 -HOST_CXXFLAGS += -DGENERATOR_FILE -DHAVE_CONFIG_H +HOST_CXXFLAGS += -DIN_GCC -DGENERATOR_FILE -DHAVE_CONFIG_H HOST_CXXFLAGS += $(GCC_INCLUDES) !hostcxx = | $(S)/$(GCC_DIR)/ |> \ @@ -53,9 +53,10 @@ TARGET_CXXFLAGS = -O2 -std=gnu++14 TARGET_CXXFLAGS += -DIN_GCC -DHAVE_CONFIG_H TARGET_CXXFLAGS += $(GCC_INCLUDES) -!cxx = | $(S)/$(GCC_DIR)/ $(S)/$(GCC_DIR)/ |> \ +!cxx = | $(S)/$(GCC_DIR)/ $(S)/$(GCC_DIR)/ \ + $(S)/$(GCC_DIR)/ |> \ ^ CXX %b^ $(CXX) $(TARGET_CXXFLAGS) -c %f -o %o |> !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(GCC_DIR)/tup.config > %o |> diff --git a/examples/gcc/gcc/tup.config b/examples/gcc/gcc/tup.config index 6ce176e..7ccb184 100644 --- a/examples/gcc/gcc/tup.config +++ b/examples/gcc/gcc/tup.config @@ -3,20 +3,14 @@ # These generate auto-host.h via !gen-config. # Cross-referenced with gcc/configure.ac output for x86_64-pc-linux-gnu. -# Host word sizes -CONFIG_HOST_BITS_PER_CHAR=8 -CONFIG_HOST_BITS_PER_SHORT=16 -CONFIG_HOST_BITS_PER_INT=32 -CONFIG_HOST_BITS_PER_LONG=64 -CONFIG_HOST_BITS_PER_LONGLONG=64 - -# Type sizes +# Type sizes (HOST_BITS_PER_* derived from these by hwint.h) CONFIG_SIZEOF_SHORT=2 CONFIG_SIZEOF_INT=4 CONFIG_SIZEOF_LONG=8 CONFIG_SIZEOF_LONG_LONG=8 CONFIG_SIZEOF_VOID_P=8 CONFIG_SIZEOF__BOOL=1 +CONFIG_INT64_T_IS_LONG=1 # Headers CONFIG_HAVE_ALLOCA_H=1 @@ -80,9 +74,9 @@ CONFIG_HAVE_PUTC_UNLOCKED=1 CONFIG_HAVE_SETLOCALE=1 CONFIG_HAVE_SETRLIMIT=1 CONFIG_HAVE_SIGACTION=1 +CONFIG_HAVE_STRSIGNAL=1 CONFIG_HAVE_SYSCONF=1 CONFIG_HAVE_TIMES=1 -CONFIG_HAVE_UCHAR=1 CONFIG_HAVE_VFORK=1 CONFIG_HAVE_WORKING_FORK=1 CONFIG_HAVE_WORKING_VFORK=1 @@ -90,7 +84,7 @@ CONFIG_HAVE_WORKING_VFORK=1 # Declarations CONFIG_HAVE_DECL_ABORT=1 CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_BASENAME=1 CONFIG_HAVE_DECL_CLEARERR_UNLOCKED=1 CONFIG_HAVE_DECL_ERRNO=1 CONFIG_HAVE_DECL_FEOF_UNLOCKED=1 @@ -117,6 +111,10 @@ CONFIG_HAVE_DECL_STRSIGNAL=1 CONFIG_HAVE_DECL_VASPRINTF=1 CONFIG_HAVE_DECL_VSNPRINTF=1 +# Build options +CONFIG_GATHER_STATISTICS=0 +CONFIG_CHECKING_P=1 + # Misc CONFIG_STDC_HEADERS=1 CONFIG_ENABLE_ASSERT_CHECKING=1 diff --git a/examples/gcc/gmp/Tuprules.tup b/examples/gcc/gmp/Tuprules.tup index 83ab46b..c49acfe 100644 --- a/examples/gcc/gmp/Tuprules.tup +++ b/examples/gcc/gmp/Tuprules.tup @@ -29,4 +29,4 @@ CFLAGS += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(GMP_DIR)/tup.config > %o |> diff --git a/examples/gcc/gmp/mpn/tup.config b/examples/gcc/gmp/mpn/tup.config index 5dbb28e..a42fbad 100644 --- a/examples/gcc/gmp/mpn/tup.config +++ b/examples/gcc/gmp/mpn/tup.config @@ -1,18 +1,7 @@ -# GMP mpn source resolution — generic C mode (no assembly) -# -# Generated by: scripts/resolve-mpn.sh generic -# Regenerate for assembly: scripts/resolve-mpn.sh x86_64 > gmp/mpn/tup.config - CONFIG_MPN_ARCH=generic CONFIG_MPN_SUBDIR=generic - -# Single-function sources (foreach-compatible — one .c per .o) -CONFIG_C_SOURCES=generic/add.c generic/add_1.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/add_n.c generic/add_n_sub_n.c generic/addmul_1.c generic/bdiv_dbm1c.c generic/bdiv_q.c generic/bdiv_q_1.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/com.c generic/comb_tables.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dcpi1_divappr_q.c generic/div_q.c generic/div_qr_1.c generic/div_qr_1n_pi1.c generic/div_qr_2.c generic/div_qr_2n_pi1.c generic/div_qr_2u_pi1.c generic/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/divrem.c generic/divrem_1.c generic/divrem_2.c generic/dump.c generic/fib2_ui.c generic/fib2m.c generic/gcd.c generic/gcd_1.c generic/gcd_11.c generic/gcd_22.c generic/gcd_subdiv_step.c generic/gcdext.c generic/gcdext_1.c generic/gcdext_lehmer.c generic/get_d.c generic/get_str.c generic/hgcd.c generic/hgcd2.c generic/hgcd2_jacobi.c generic/hgcd_appr.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/invert.c generic/invertappr.c generic/jacbase.c generic/jacobi.c generic/jacobi_2.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul.c generic/matrix22_mul1_inverse_vector.c generic/mod_1.c generic/mod_1_1.c generic/mod_1_2.c generic/mod_1_3.c generic/mod_1_4.c generic/mod_34lsub1.c generic/mode1o.c generic/mu_bdiv_q.c generic/mu_bdiv_qr.c generic/mu_div_q.c generic/mu_div_qr.c generic/mu_divappr_q.c generic/mul.c generic/mul_1.c generic/mul_basecase.c generic/mul_fft.c generic/mul_n.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid.c generic/mulmid_basecase.c generic/mulmid_n.c generic/mulmod_bnm1.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/random.c generic/random2.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_div_q.c generic/sbpi1_div_qr.c generic/sbpi1_divappr_q.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.c generic/sqr_basecase.c generic/sqrlo.c generic/sqrlo_basecase.c generic/sqrmod_bnm1.c generic/sqrtrem.c generic/strongfibo.c generic/sub.c generic/sub_1.c generic/sub_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/sub_n.c generic/submul_1.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/toom6_sqr.c generic/toom6h_mul.c generic/toom8_sqr.c generic/toom8h_mul.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 - -# Single-function assembly sources (empty in generic mode) +CONFIG_C_SOURCES=generic/add.c generic/add_1.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/add_n.c generic/add_n_sub_n.c generic/addmul_1.c generic/bdiv_dbm1c.c generic/bdiv_q.c generic/bdiv_q_1.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/com.c generic/comb_tables.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dcpi1_divappr_q.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/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/divrem.c generic/divrem_1.c generic/divrem_2.c generic/dump.c generic/fib2_ui.c generic/fib2m.c generic/gcd.c generic/gcd_1.c generic/gcd_11.c generic/gcd_22.c generic/gcd_subdiv_step.c generic/gcdext.c generic/gcdext_1.c generic/gcdext_lehmer.c generic/get_d.c generic/get_str.c generic/hgcd.c generic/hgcd2.c generic/hgcd2_jacobi.c generic/hgcd_appr.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/invert.c generic/invertappr.c generic/jacbase.c generic/jacobi.c generic/jacobi_2.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul.c generic/matrix22_mul1_inverse_vector.c generic/mod_1.c generic/mod_1_1.c generic/mod_1_2.c generic/mod_1_3.c generic/mod_1_4.c generic/mod_34lsub1.c generic/mode1o.c generic/mu_bdiv_q.c generic/mu_bdiv_qr.c generic/mu_div_q.c generic/mu_div_qr.c generic/mu_divappr_q.c generic/mul.c generic/mul_1.c generic/mul_basecase.c generic/mul_fft.c generic/mul_n.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid.c generic/mulmid_basecase.c generic/mulmid_n.c generic/mulmod_bnm1.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/random.c generic/random2.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_div_q.c generic/sbpi1_div_qr.c generic/sbpi1_divappr_q.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.c generic/sqr_basecase.c generic/sqrlo.c generic/sqrlo_basecase.c generic/sqrmod_bnm1.c generic/sqrtrem.c generic/strongfibo.c generic/sub.c generic/sub_1.c generic/sub_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/sub_n.c generic/submul_1.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/toom6_sqr.c generic/toom6h_mul.c generic/toom8_sqr.c generic/toom8h_mul.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= - -# Template C toggles — all enabled in generic mode (no assembly replacements) CONFIG_C_and_n=y CONFIG_C_andn_n=y CONFIG_C_ior_n=y diff --git a/examples/gcc/gmp/tup.config b/examples/gcc/gmp/tup.config index d97795b..22334ea 100644 --- a/examples/gcc/gmp/tup.config +++ b/examples/gcc/gmp/tup.config @@ -10,7 +10,6 @@ CONFIG_NAIL_BITS=0 # MPN CPU target: "generic" for pure C, or a CPU path like "x86_64" or "x86_64/core2" CONFIG_MPN_CPU=generic -CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h # Feature detection CONFIG_HAVE_ALARM=1 @@ -86,7 +85,6 @@ CONFIG_HAVE_UINT_LEAST32_T=1 CONFIG_HAVE_UNISTD_H=1 CONFIG_HAVE_VSNPRINTF=1 CONFIG_LSYM_PREFIX="" -CONFIG_NO_ASM=1 CONFIG_RETSIGTYPE=void CONFIG_SIZEOF_UNSIGNED=4 CONFIG_SIZEOF_UNSIGNED_SHORT=2 @@ -106,3 +104,5 @@ 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/gcc/libbacktrace/Tuprules.tup b/examples/gcc/libbacktrace/Tuprules.tup index fedff50..3ba259b 100644 --- a/examples/gcc/libbacktrace/Tuprules.tup +++ b/examples/gcc/libbacktrace/Tuprules.tup @@ -9,9 +9,10 @@ LIBBACKTRACE_DIR ?= . CFLAGS = -O2 -std=gnu11 CFLAGS += -DHAVE_CONFIG_H CFLAGS += -I$(B)/$(LIBBACKTRACE_DIR) -I$(S)/$(LIBBACKTRACE_DIR) +CFLAGS += -I$(S)/$(LIBBACKTRACE_DIR)/../include !cc = | $(S)/$(LIBBACKTRACE_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> %B.o !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(LIBBACKTRACE_DIR)/tup.config > %o |> diff --git a/examples/gcc/libcpp/Tuprules.tup b/examples/gcc/libcpp/Tuprules.tup index 8d22888..d570df7 100644 --- a/examples/gcc/libcpp/Tuprules.tup +++ b/examples/gcc/libcpp/Tuprules.tup @@ -16,4 +16,4 @@ CXXFLAGS += -I$(S)/$(LIBCPP_DIR)/../include !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(LIBCPP_DIR)/tup.config > %o |> diff --git a/examples/gcc/libcpp/tup.config b/examples/gcc/libcpp/tup.config index 4899740..68842b8 100644 --- a/examples/gcc/libcpp/tup.config +++ b/examples/gcc/libcpp/tup.config @@ -68,7 +68,6 @@ CONFIG_HAVE_DECL_PUTC_UNLOCKED=1 CONFIG_HAVE_DECL_VASPRINTF=1 # Types -CONFIG_HAVE_UCHAR=1 CONFIG_HAVE_UINTPTR_T=1 # Sizes @@ -86,6 +85,9 @@ CONFIG_PACKAGE_TARNAME="cpplib" CONFIG_PACKAGE_URL="" CONFIG_PACKAGE_VERSION="0" +# iconv (glibc takes non-const; define as empty) +CONFIG_ICONV_CONST= + # Misc CONFIG_STDC_HEADERS=1 CONFIG_STRING_WITH_STRINGS=1 diff --git a/examples/gcc/libdecnumber/Tupfile b/examples/gcc/libdecnumber/Tupfile index 918b6c9..ff74081 100644 --- a/examples/gcc/libdecnumber/Tupfile +++ b/examples/gcc/libdecnumber/Tupfile @@ -10,6 +10,9 @@ include_rules : |> !gen-config |> config.h +# gstdint.h — configure-generated wrapper around system +: |> ^ GEN %o^ echo '#include ' > %o |> gstdint.h + # --- Phase 2: Compile sources --- # BID variant (Binary Integer Decimal) — x86/x86_64 use BID per dfp.m4. diff --git a/examples/gcc/libdecnumber/Tuprules.tup b/examples/gcc/libdecnumber/Tuprules.tup index 40562b9..877e17d 100644 --- a/examples/gcc/libdecnumber/Tuprules.tup +++ b/examples/gcc/libdecnumber/Tuprules.tup @@ -14,4 +14,4 @@ CFLAGS += -I$(B)/$(LIBDECNUMBER_DIR) -I$(S)/$(LIBDECNUMBER_DIR) !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(LIBDECNUMBER_DIR)/tup.config > %o |> diff --git a/examples/gcc/libiberty/Tuprules.tup b/examples/gcc/libiberty/Tuprules.tup index 9f436e5..fcff533 100644 --- a/examples/gcc/libiberty/Tuprules.tup +++ b/examples/gcc/libiberty/Tuprules.tup @@ -18,4 +18,4 @@ CFLAGS += -I$(B)/$(LIBIBERTY_DIR) -I$(S)/$(LIBIBERTY_DIR)/../include !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(LIBIBERTY_DIR)/tup.config > %o |> diff --git a/examples/gcc/libiberty/tup.config b/examples/gcc/libiberty/tup.config index 78a9dff..781ad5e 100644 --- a/examples/gcc/libiberty/tup.config +++ b/examples/gcc/libiberty/tup.config @@ -141,5 +141,5 @@ CONFIG_SIZEOF_SIZE_T=8 # Misc CONFIG_STDC_HEADERS=1 CONFIG_TIME_WITH_SYS_TIME=1 -CONFIG_UNSIGNED_64BIT_TYPE="unsigned long" +CONFIG_UNSIGNED_64BIT_TYPE=unsigned long CONFIG__GNU_SOURCE=1 diff --git a/examples/gcc/mpc/Tuprules.tup b/examples/gcc/mpc/Tuprules.tup index 43575ae..6bcb51a 100644 --- a/examples/gcc/mpc/Tuprules.tup +++ b/examples/gcc/mpc/Tuprules.tup @@ -17,4 +17,4 @@ CFLAGS += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(MPC_DIR)/tup.config > %o |> diff --git a/examples/gcc/mpfr/Tupfile b/examples/gcc/mpfr/Tupfile index 27d9bc1..60db22c 100644 --- a/examples/gcc/mpfr/Tupfile +++ b/examples/gcc/mpfr/Tupfile @@ -7,5 +7,4 @@ include_rules # mparam.h - architecture-specific tuning (auto-selects via compiler macros) : src/mparam_h.in |> ^ GEN %o^ cp %f %o |> src/mparam.h -# get_patches.c - empty patch list -: |> ^ GEN %o^ printf '#include \nconst char * const mpfr_patches[] = { NULL };\n' > %o |> src/get_patches.c +# get_patches.c is generated in src/Tupfile (same directory as compilation) diff --git a/examples/gcc/mpfr/Tuprules.tup b/examples/gcc/mpfr/Tuprules.tup index 35f792a..b7d15f4 100644 --- a/examples/gcc/mpfr/Tuprules.tup +++ b/examples/gcc/mpfr/Tuprules.tup @@ -15,4 +15,4 @@ CFLAGS += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ - $(B)/tup.config > %o |> + $(B)/$(MPFR_DIR)/tup.config > %o |> diff --git a/examples/gcc/mpfr/src/Tupfile b/examples/gcc/mpfr/src/Tupfile index c2c200b..88b2c2c 100644 --- a/examples/gcc/mpfr/src/Tupfile +++ b/examples/gcc/mpfr/src/Tupfile @@ -47,8 +47,9 @@ srcs += ui_div.c ui_pow.c ui_pow_ui.c ui_sub.c srcs += urandom.c urandomb.c vasprintf.c version.c volatile.c srcs += yn.c zeta.c zeta_ui.c -# Generated source -srcs += get_patches.c +# get_patches.c - empty patch list (generated here, not from source tree) +: |> ^ GEN %o^ printf '#include \nconst char * const mpfr_patches[] = { NULL };\n' > %o |> get_patches.c +: get_patches.c |> !cc |> : foreach $(srcs) |> !cc |> diff --git a/src/cli/context.cpp b/src/cli/context.cpp index 6c915fe..e025835 100644 --- a/src/cli/context.cpp +++ b/src/cli/context.cpp @@ -686,6 +686,7 @@ auto build_context( .output_root = ctx.impl_->layout.output_root, .config_path = config_path, .expand_globs = true, + .verbose = ctx_opts.verbose, .scanner_registry = ctx_opts.scanner_registry, .pattern_registry = ctx_opts.pattern_registry, .cached_env_vars = std::move(cached_env_vars), diff --git a/test/unit/test_e2e.cpp b/test/unit/test_e2e.cpp index b5bf814..3e4a46d 100644 --- a/test/unit/test_e2e.cpp +++ b/test/unit/test_e2e.cpp @@ -4180,6 +4180,71 @@ SCENARIO("Out-of-tree configuration with separate source/config/build trees", "[ } } +SCENARIO("Cross-directory groups in 3-tree builds", "[e2e][out-of-tree-config][groups]") +{ + GIVEN("a 3-tree project with cross-directory group references via variables") + { + // Mirrors the GCC example pattern: + // root Tuprules.tup: S = $(TUP_CWD); LIB_DIR = gcc + // gcc/Tuprules.tup: S ?= ...; LIB_DIR ?= .; macros use $(S)/$(LIB_DIR)/ + // gcc/Tupfile: produces , consumes via macros + auto f = E2EFixture { "groups_cross_dir_3tree" }; + auto source_dir = f.workdir() / "source"; + auto config_dir = f.workdir() / "config"; + auto build_dir = f.workdir() / "build"; + + f.mkdir("build"); + f.write_file("build/tup.config", ""); + + WHEN("parsing with -S, -C, and -B options") + { + auto result = f.pup({ + "parse", + "-S", source_dir.string(), + "-C", config_dir.string(), + "-B", build_dir.string(), + "-v" + }); + + THEN("parse succeeds without group warnings") + { + INFO("stdout:\n" << result.stdout_output); + INFO("stderr:\n" << result.stderr_output); + REQUIRE(result.success()); + REQUIRE(result.stdout_output.find("has no members") == std::string::npos); + } + } + + WHEN("building with -S, -C, and -B options") + { + auto result = f.pup({ + "-S", source_dir.string(), + "-C", config_dir.string(), + "-B", build_dir.string(), + "-j1" + }); + + THEN("build succeeds without group warnings") + { + INFO("stdout:\n" << result.stdout_output); + INFO("stderr:\n" << result.stderr_output); + REQUIRE(result.success()); + REQUIRE(result.stdout_output.find("has no members") == std::string::npos); + } + + THEN("generated header exists in build directory") + { + REQUIRE(f.exists("build/gcc/config.h")); + } + + THEN("output files are created from source globs") + { + REQUIRE(f.exists("build/gcc/hello.out")); + } + } + } +} + SCENARIO("Out-of-tree configuration with TUP_SRCDIR and TUP_OUTDIR variables", "[e2e][out-of-tree-config]") { GIVEN("a project using TUP_SRCDIR and TUP_OUTDIR in Tupfiles") From 712396115e6dd90f80c04457153330edca4ededd Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:54:46 +0800 Subject: [PATCH 05/16] Add project skills for Tupfile patterns and GCC example Co-Authored-By: Claude Opus 4.6 --- .claude/skills/gcc-example/SKILL.md | 177 +++++++++++++++++++ .claude/skills/tupfile-patterns/SKILL.md | 210 +++++++++++++++++++++++ 2 files changed, 387 insertions(+) create mode 100644 .claude/skills/gcc-example/SKILL.md create mode 100644 .claude/skills/tupfile-patterns/SKILL.md diff --git a/.claude/skills/gcc-example/SKILL.md b/.claude/skills/gcc-example/SKILL.md new file mode 100644 index 0000000..c5150a8 --- /dev/null +++ b/.claude/skills/gcc-example/SKILL.md @@ -0,0 +1,177 @@ +--- +name: gcc-example +description: Building GCC with putup. Use when working on the examples/gcc/ directory, debugging GCC build failures, adding new GCC source files to the build, fixing generator issues, or extending the cc1 build. Covers 3-tree mode workflow, generator patterns, config headers, and accumulated fixes. +--- + +# GCC Example Build + +The `examples/gcc/` directory builds GCC's cc1 C compiler from source using putup in 3-tree mode. This skill captures the architecture and hard-won knowledge from iterative debugging. + +## Build Command + +```bash +cd /path/to/pup/examples/gcc && \ + PUP_IMPLICIT_DEPS=0 putup -C . -S /path/to/gcc-15.2.0 -B ../../build-gcc -j$(nproc) +``` + +- `-C .` — config tree (our Tupfiles, tup.config, Tuprules.tup) +- `-S /path/to/gcc-15.2.0` — GCC source tree (read-only) +- `-B ../../build-gcc` — build output directory +- `PUP_IMPLICIT_DEPS=0` — workaround for 3-tree groups bug + +After editing any `tup.config`, re-run `putup configure` to propagate to the build dir. + +## Architecture + +Seven build phases in `gcc/Tupfile`: + +1. **Config headers** (``) — auto-host.h, bconfig.h, config.h, tm.h, tm_p.h, options.h, etc. +2. **Generator bootstrap** — genmodes → insn-modes.h → BUILD_RTL → genconditions → insn-conditions.md +3. **RTL generators** — 20+ generators producing insn-*.h/cc files (``) +4. **Generated source compilation** — compile all generated .cc into `` +5. **Backend objects** — ~445 source files from gcc/ +6. **Common objects** — from gcc/c/, gcc/c-family/, gcc/analyzer/, gcc/config/i386/ +7. **cc1 link** — link everything with library archives + +### Group Dependencies + +| Group | Purpose | Producers | +|-------|---------|-----------| +| `` | Config/target headers | Phase 1 (auto-host.h, tm.h, options.h, etc.) | +| `` | Generated insn headers | Phase 3 generators | +| `` | GC type descriptors | gengtype | +| `` | All object files | Phases 4-6 | + +### Two Compilation Modes + +**HOST** (generators) — runs on build machine: +``` +HOST_CXXFLAGS = -O0 -std=gnu++14 -DIN_GCC -DGENERATOR_FILE -DHAVE_CONFIG_H +``` + +**TARGET** (cc1 objects) — runs on target: +``` +TARGET_CXXFLAGS = -O2 -std=gnu++14 -DIN_GCC -DHAVE_CONFIG_H +``` + +`-DGENERATOR_FILE` is the key difference. It gates which headers generators see (they skip insn-flags.h, insn-modes.h via guards in tm.h). + +## Generator Patterns + +### Stdout Generators (simple — just redirect) + +```tup +: $(MD) insn-conditions.md | gen-foo |> ^ GEN %o^ \ + $(TUP_VARIANT_OUTPUTDIR)/gen-foo %f > %o |> insn-foo.h +``` + +### File-Output Generators (need cd to build dir) + +Generators with `-O`, `-H`, `-A`, `-D`, `-L`, `-h`, `-c` flags write files relative to CWD. In 3-tree mode CWD is the read-only source dir, so cd first: + +```tup +: $(MD) insn-conditions.md | generator |> ^ GEN outputs^ \ + cd $(TUP_VARIANT_OUTPUTDIR) && ./generator %f \ + -O output-1.cc -O output-2.cc \ + |> output-1.cc output-2.cc +``` + +If `%f` produces relative paths that break after cd, capture CWD first: + +```tup +: $(MD) insn-conditions.md | generator |> ^ GEN outputs^ \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && \ + ./generator $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + -O output-1.cc -O output-2.cc \ + |> output-1.cc output-2.cc +``` + +Note: `$SRCDIR` and `$PWD` are shell variables (bare `$` passes through putup to shell). + +### genmatch (special case) + +genmatch uses libcpp's `getpwd()` as include search path. `match.pd` includes `cfn-operators.pd` which lives in the build dir. Must cd to build dir AND pass source-relative match.pd path: + +```tup +: $(SRC)/match.pd | genmatch cfn-operators.pd |> ^ GEN gimple-match-*^ \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genmatch --gimple \ + --header=gimple-match-auto.h --include=gimple-match-auto.h \ + $SRCDIR/match.pd \ + gimple-match-1.cc ... gimple-match-10.cc \ + |> gimple-match-auto.h gimple-match-1.cc ... gimple-match-10.cc +``` + +### gengtype (two-pass) + +gengtype scans GTY-annotated source files. Uses `-DHOST_GENERATOR_FILE` (NOT `-DGENERATOR_FILE`) because it needs full host header access: + +```tup +# Pass 1: write state file +gengtype -S $(SRC) -I gtyp-input.list -w gtype.state +# Pass 2: generate from state +cd $(TUP_VARIANT_OUTPUTDIR) && ./gengtype -r gtype.state +``` + +## Config Headers + +### auto-host.h (from tup.config via !gen-config) + +`CONFIG_FOO=value` in `tup.config` → `#define FOO value` in auto-host.h. + +Key gotchas: +- **Do NOT set `CONFIG_HAVE_UCHAR=1`** — modern Linux doesn't provide `uchar`. GCC's coretypes.h typedefs it when `HAVE_UCHAR` is NOT defined. +- Cross-reference with real `./configure` output for your platform. + +### tm.h (target machine) + +Must match the real configure-generated layout exactly. Key structure: +- LIBC defines (GLIBC, UCLIBC, etc.) outside `#ifdef IN_GCC` +- Target headers inside `#ifdef IN_GCC` +- `insn-flags.h` guarded with `!defined GENERATOR_FILE && !defined USED_FOR_TARGET` +- `insn-modes.h` guarded with `!defined GENERATOR_FILE` +- `defaults.h` at the end + +### tm_p.h (target machine prototypes) + +Must include exactly three headers: +```c +#include "config/i386/i386-protos.h" +#include "config/linux-protos.h" +#include "tm-preds.h" +``` + +The `tm-preds.h` is generated by `genpreds -h` and declares predicate functions like `register_operand`. Missing this causes "undeclared" errors in many files. + +### bconfig.h vs config.h + +- `bconfig.h` — for generators: includes `auto-host.h` + `ansidecl.h` +- `config.h` — for target objects: includes `auto-host.h`, errors if `GENERATOR_FILE` defined + +## Self-Contained Library Convention + +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 `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. + +## Debugging Workflow + +1. Run the build command +2. Read the **first** error (ignore cascading failures) +3. Diagnose: missing header? → check group deps. Undeclared symbol? → check which generated header provides it. Read-only filesystem? → generator needs cd to build dir. +4. Fix the Tupfile or tup.config +5. If tup.config changed, run `putup configure` to propagate +6. Rebuild and repeat + +## Common Error Patterns + +| Error | Likely Cause | Fix | +|-------|-------------|-----| +| `Read-only file system` | Generator writes to CWD (source dir) | cd to build dir before running | +| `No such file or directory` (generator output) | Same as above | cd to build dir | +| `undeclared` symbol from generated header | Missing group dependency or header include | Check which generator produces it | +| `/bin/sh: ^: not found` | Display text on continuation line | Move `^ ... ^` to same line as `|>` | +| `uchar not declared` | `HAVE_UCHAR` wrongly defined | Remove `CONFIG_HAVE_UCHAR` from tup.config | +| `register_operand undeclared` | `tm_p.h` missing `tm-preds.h` | Add `#include "tm-preds.h"` to tm_p.h generation | diff --git a/.claude/skills/tupfile-patterns/SKILL.md b/.claude/skills/tupfile-patterns/SKILL.md new file mode 100644 index 0000000..f1791f0 --- /dev/null +++ b/.claude/skills/tupfile-patterns/SKILL.md @@ -0,0 +1,210 @@ +--- +name: tupfile-patterns +description: Patterns and gotchas for writing Tupfiles with putup. Use when authoring Tupfiles, debugging build failures, working with 3-tree builds (-C/-S/-B), cross-directory dependencies, order-only groups, bang macros, generator programs, or multi-library projects. Covers Tup syntax that putup supports. +--- + +# Tupfile Patterns + +Reference for writing Tupfiles with putup. See [docs/reference.md](../../../docs/reference.md) for the full manual. + +## Rule Syntax + +```tup +: [foreach] [inputs] [| order-only] |> command |> [outputs] [| extra-outputs] [{group}] [] +``` + +- `%f` — all inputs, `%o` — all outputs, `%b` — input basename, `%B` — basename without extension +- `%d` — input directory, `%e` — extension, `%%` — literal `%` +- Display text: `^ TEXT ^` right after `|>` on the **same line** (never on a continuation line) + +## Variable Expansion vs Shell Variables + +putup expands `$(VAR)` as a Tup variable. Bare `$VAR` passes through to the shell unchanged. + +```tup +# $(CC) expanded by putup at parse time +# $PWD passed through to /bin/sh at execution time +: |> $(CC) -DPREFIX=$PWD -c %f -o %o |> output.o +``` + +This is useful for shell tricks like capturing CWD before `cd`: + +```tup +: |> SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./tool $SRCDIR/input |> output +``` + +## Display Text Gotcha + +Display text `^ ... ^` **must** appear on the same line as the opening `|>`. If placed on a continuation line, it becomes part of the shell command. + +```tup +# CORRECT +: input |> ^ CC %b^ $(CC) -c %f -o %o |> output.o + +# CORRECT (continuation after display text) +: input |> ^ CC %b^ \ + $(CC) -c %f -o %o |> output.o + +# WRONG — ^ becomes a shell command +: input |> \ + ^ CC %b^ $(CC) -c %f -o %o |> output.o +``` + +## 3-Tree Builds (-C / -S / -B) + +```bash +putup -C config_dir -S source_dir -B build_dir +``` + +- `-C` — config tree (Tupfiles, tup.config, Tuprules.tup) +- `-S` — source tree (read-only source code) +- `-B` — build tree (output directory) + +Commands run with CWD = source directory. The source tree is **read-only**. + +### Key Variables in 3-Tree Mode + +| Variable | Meaning | +|----------|---------| +| `$(TUP_CWD)` | Config-relative directory of current Tupfile | +| `$(TUP_VARIANT_OUTPUTDIR)` | Absolute path to the build directory | +| `$(S)` (convention) | Usually set to `$(TUP_CWD)` in root Tuprules.tup | +| `$(B)` (convention) | Usually set to `$(TUP_VARIANT_OUTPUTDIR)/$(S)` | + +### Generator Programs in 3-Tree Mode + +Generators that write output files via flags (not stdout) write relative to CWD, which is the read-only source dir. Two approaches: + +**Approach 1: cd to build dir** (preferred for programs that write many files by name) + +```tup +: $(MD) | generator |> ^ GEN outputs^ \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && \ + ./generator $SRCDIR/input1.md $SRCDIR/input2.md \ + -O output-1.cc -O output-2.cc \ + |> output-1.cc output-2.cc +``` + +Note: inputs that are already in the build dir (previously generated) don't need `$SRCDIR/`. + +**Approach 2: stdout redirect** (preferred for single-output generators) + +```tup +: input.md | generator |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/generator %f > %o |> output.h +``` + +## Order-Only Groups + +Groups create ordering dependencies without file-level dependencies. + +```tup +# Producer: outputs go into group +: |> gen-header > %o |> config.h +: |> gen-header > %o |> types.h + +# Consumer: waits for all members before starting +: src.c | |> $(CC) -c %f -o %o |> src.o +``` + +Cross-directory groups use the `$(S)/dir/` prefix: + +```tup +# In lib/Tupfile: produce into group +: |> generate > %o |> header.h + +# In app/Tupfile: consume from lib's group +: src.c | $(S)/lib/ |> $(CC) -c %f -o %o |> src.o +``` + +## Bang Macros + +Define reusable command templates in `Tuprules.tup`: + +```tup +!cc = |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> + +# With order-only deps (consumers auto-wait) +!cc = | |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> +``` + +Usage in Tupfile: + +```tup +: foreach *.c |> !cc |> %B.o +``` + +## Self-Contained Library Convention + +For multi-library projects (like GCC with GMP, MPFR, MPC): + +**Root `Tuprules.tup`** — sets layout variables: + +```tup +S = $(TUP_CWD) +B = $(TUP_VARIANT_OUTPUTDIR)/$(S) +GMP_DIR = gmp +MPFR_DIR = mpfr +``` + +**Each library's `Tuprules.tup`** — uses `?=` defaults for standalone builds: + +```tup +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +GMP_DIR ?= . +CFLAGS = -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) +!cc = |> ^ CC %b^ $(CC) $(CFLAGS) -c %f -o %o |> +``` + +`?=` means "set only if undefined". When built as part of the larger project, the root Tuprules.tup values win. When built standalone, the `?=` defaults apply. + +Prefixed DIR vars (`GMP_DIR`, `MPFR_DIR`) are needed because `include_rules` merges ALL `Tuprules.tup` from root to leaf — a single `DIR` variable would collide. + +## Scoped tup.config + +Each subdirectory can have its own `tup.config` for `@(VAR)` config variables: + +``` +project/ + tup.config # Global: CC=gcc, AR=ar + gmp/tup.config # GMP-specific: HAVE_ALLOCA=1 + mpfr/tup.config # MPFR-specific: HAVE_LOCALE=1 +``` + +Run `putup configure` to propagate config files into the build directory. Parent config values override child values (parent wins on conflict). + +## `!gen-config` Pattern + +Convert `tup.config` variables into C `#define` headers: + +```tup +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2); \ + if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/$(GCC_DIR)/tup.config > %o |> +``` + +`CONFIG_HAVE_MMAP=1` becomes `#define HAVE_MMAP 1`. `CONFIG_HAVE_UCHAR=n` is suppressed. + +## Line Continuation + +Use `\` at end of line. Works in rules and variable assignments: + +```tup +SRCS = file1.c +SRCS += file2.c \ + file3.c \ + file4.c +``` + +## Conditional Compilation + +```tup +ifdef CC + CFLAGS += -Wall +endif + +ifeq ($(TARGET),arm) + CFLAGS += -marm +endif +``` From b5eab6e78a37cf84fc77012f4fdb7c1404f97961 Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Sat, 14 Feb 2026 19:17:40 +0800 Subject: [PATCH 06/16] Build full GCC cross-compiler toolchain --- examples/gcc/Makefile.pup | 37 +- examples/gcc/README.md | 62 ++- examples/gcc/Tuprules.tup | 1 + examples/gcc/configs/aarch64-linux.config | 7 + .../gcc/configs/darwin-x86_64-linux.config | 20 + examples/gcc/configs/host-darwin/gcc.config | 87 ++++ examples/gcc/configs/host-darwin/gmp.config | 101 ++++ .../configs/host-darwin/libbacktrace.config | 48 ++ .../gcc/configs/host-darwin/libcpp.config | 64 +++ .../configs/host-darwin/libdecnumber.config | 7 + .../gcc/configs/host-darwin/libiberty.config | 132 +++++ examples/gcc/configs/host-darwin/mpc.config | 24 + examples/gcc/configs/host-darwin/mpfr.config | 31 ++ examples/gcc/configs/x86_64-linux.config | 9 +- examples/gcc/gcc/Tupfile | 457 ++++++++++++------ examples/gcc/gcc/Tuprules.tup | 17 + examples/gcc/gcc/cp/Tupfile | 23 + .../gcc/gcc/targets/x86_64-pc-linux-gnu.tup | 122 +++++ examples/gcc/gcc/tup.config | 96 ++-- examples/gcc/gmp/Tupfile | 8 +- examples/gcc/gmp/mpf/Tupfile | 2 +- examples/gcc/gmp/mpn/Tupfile | 80 +-- examples/gcc/gmp/mpn/tup.config | 2 +- examples/gcc/gmp/mpq/Tupfile | 2 +- examples/gcc/gmp/mpz/Tupfile | 2 +- examples/gcc/gmp/printf/Tupfile | 2 +- examples/gcc/gmp/rand/Tupfile | 2 +- examples/gcc/gmp/scanf/Tupfile | 2 +- examples/gcc/gmp/tup.config | 17 +- examples/gcc/libbacktrace/Tupfile | 4 +- examples/gcc/libbacktrace/tup.config | 15 +- examples/gcc/libcody/Tupfile | 21 + examples/gcc/libcody/Tuprules.tup | 18 + examples/gcc/libcody/tup.config | 11 + examples/gcc/libcpp/tup.config | 43 +- examples/gcc/libdecnumber/tup.config | 5 +- examples/gcc/libiberty/Tupfile | 2 +- examples/gcc/libiberty/tup.config | 25 +- examples/gcc/mpc/tup.config | 4 +- examples/gcc/mpfr/tup.config | 4 +- examples/gcc/scripts/resolve-mpn.sh | 8 + src/graph/scanners/gcc.cpp | 4 +- 42 files changed, 1279 insertions(+), 349 deletions(-) create mode 100644 examples/gcc/configs/darwin-x86_64-linux.config create mode 100644 examples/gcc/configs/host-darwin/gcc.config create mode 100644 examples/gcc/configs/host-darwin/gmp.config create mode 100644 examples/gcc/configs/host-darwin/libbacktrace.config create mode 100644 examples/gcc/configs/host-darwin/libcpp.config create mode 100644 examples/gcc/configs/host-darwin/libdecnumber.config create mode 100644 examples/gcc/configs/host-darwin/libiberty.config create mode 100644 examples/gcc/configs/host-darwin/mpc.config create mode 100644 examples/gcc/configs/host-darwin/mpfr.config create mode 100644 examples/gcc/gcc/cp/Tupfile create mode 100644 examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup create mode 100644 examples/gcc/libcody/Tupfile create mode 100644 examples/gcc/libcody/Tuprules.tup create mode 100644 examples/gcc/libcody/tup.config diff --git a/examples/gcc/Makefile.pup b/examples/gcc/Makefile.pup index f599f64..73e7023 100644 --- a/examples/gcc/Makefile.pup +++ b/examples/gcc/Makefile.pup @@ -1,7 +1,7 @@ -# Makefile.pup - Build GCC's cc1 C compiler with putup +# Makefile.pup - Build GCC cross-compiler toolchain with putup # # Usage: -# make -f Makefile.pup # Build cc1 (all libraries + compiler) +# make -f Makefile.pup # Build toolchain (libraries + compilers + tools) # make -f Makefile.pup clean # Clean build artifacts # make -f Makefile.pup distclean # Full clean # @@ -10,14 +10,18 @@ # 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 . Tupfiles live here (examples/gcc/) # -S $(SRCDIR) GCC source tree (read-only) # -B $(BUILD) Build output directory -.PHONY: all build configure resolve-mpn clean distclean +.PHONY: all build configure resolve-mpn setup-host-configs clean distclean download-source PLATFORM ?= x86_64-linux +HOST ?= linux SRCDIR ?= ../gcc-15.2.0 BUILD ?= ../build-gcc MPN_CPU ?= generic @@ -25,13 +29,25 @@ TREES = -C . -S $(SRCDIR) -B $(BUILD) all: build -build: resolve-mpn +build: resolve-mpn setup-host-configs putup configure --config configs/$(PLATFORM).config $(TREES) putup $(TREES) -j$$(nproc) -configure: resolve-mpn +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 -- */tup.config +setup-host-configs: + @if [ "$(HOST)" != "linux" ] && [ -d configs/host-$(HOST) ]; then \ + for cfg in configs/host-$(HOST)/*.config; do \ + lib=$$(basename "$$cfg" .config); \ + echo " COPY $$lib/tup.config (host-$(HOST))"; \ + cp "$$cfg" "$$lib/tup.config"; \ + done; \ + fi + # Resolve mpn sources for the selected CPU target. # - gmp/mpn/tup.config: source lists and per-function toggles (child scope) # - gmp/tup.config: GMP_MPARAM and ASM_ENABLED (parent scope, visible to gmp/Tupfile) @@ -60,6 +76,17 @@ multi: done putup $(foreach p,$(PLATFORMS),-B $(BUILD)-$(p)) -C . -S $(SRCDIR) -j$$(nproc) +# Download GCC source for reference/building +GCC_VERSION ?= 15.2.0 +download-source: + @if [ ! -d "$(SRCDIR)" ]; then \ + echo "Downloading GCC $(GCC_VERSION)..."; \ + curl -L "https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.xz" \ + | tar xJ -C $$(dirname $(SRCDIR)); \ + else \ + echo "$(SRCDIR) already exists"; \ + fi + clean: putup clean $(TREES) diff --git a/examples/gcc/README.md b/examples/gcc/README.md index 3006848..362589f 100644 --- a/examples/gcc/README.md +++ b/examples/gcc/README.md @@ -1,8 +1,9 @@ -# GCC cc1 — C Compiler from Source +# GCC Cross-Compiler Toolchain from Source -Build GCC's `cc1` C compiler from the GCC 15.2.0 source tree using putup. +Build a complete GCC 15.2.0 cross-compiler toolchain using putup. This builds everything from source: prerequisite math libraries, compiler support -libraries, ~25 host generator programs, and the ~500-file cc1 backend. +libraries, ~25 host generator programs, the ~500-file compiler backend, C/C++ +frontends, driver programs, and developer tools — 3500+ build commands in ~130s. ## Quick Start @@ -21,7 +22,7 @@ make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc ## What Gets Built ``` -Phase 1-4 (independent libraries, parallel): +Libraries (parallel): gmp/ → libgmp.a Math library mpfr/ → libmpfr.a Multi-precision floats (needs GMP) mpc/ → libmpc.a Complex arithmetic (needs GMP + MPFR) @@ -29,13 +30,27 @@ Phase 1-4 (independent libraries, parallel): libdecnumber/ → libdecnumber.a Decimal floating-point (DPD variant) libbacktrace/ → libbacktrace.a Stack unwinding (ELF/mmap) libcpp/ → libcpp.a C preprocessor + libcody/ → libcody.a C++ modules protocol -Phase 5 (generators, need libiberty): +Generators (need libiberty): gcc/ → genmodes, genattr, genemit, genrecog, ... (~25 host programs) → insn-*.h, insn-*.cc (generated machine descriptions) - -Phase 6 (cc1, needs everything): - gcc/ → cc1 C compiler (~500 objects) + → gtype-desc.cc, gt-*.h (~60 GC type descriptor headers) + +Compilers: + gcc/ → cc1 C compiler backend (~500 objects) + gcc/ → cc1plus C++ compiler backend (+ 40 cp/ objects) + +Drivers: + gcc/ → xgcc C compiler driver + gcc/ → xg++ C++ compiler driver + gcc/ → cpp C preprocessor driver + +Tools: + gcc/ → collect2 Linker wrapper (C++ ctor/dtor collection) + gcc/ → lto-wrapper LTO linker plugin interface + gcc/ → gcov Code coverage analysis + gcc/ → gcov-dump Coverage data inspector ``` ## Dependency Chain @@ -95,6 +110,28 @@ When composed under the root project, the root `Tuprules.tup` sets toolchain var that override each library's `?=` defaults. The same `tup.config` file serves as the root config in standalone mode and as a scoped subdir config in composed mode. +### Multi-Platform Support + +The build uses config-variable substitution for platform selection. Target-specific +rules (tm.h, tm_p.h, MD files, gtyp entries) live in `gcc/targets/@(TARGET).tup`: + +``` +configs/x86_64-linux.config → Native Linux x86-64 +configs/darwin-x86_64-linux.config → macOS host, Linux x86-64 target +configs/host-darwin/ → macOS-specific library configs +gcc/targets/x86_64-pc-linux-gnu.tup → x86_64-linux target rules +``` + +**Cross-compiler (macOS host → x86-64 Linux target):** + +```bash +make -f Makefile.pup PLATFORM=darwin-x86_64-linux HOST=darwin +``` + +This builds cc1 using Apple Clang on macOS, producing a compiler that generates +x86_64 Linux code. The `HOST=darwin` flag copies macOS-specific library configs +(feature detection for macOS: no `-ldl`, Mach-O libbacktrace, different iconv, etc.) + ### Multi-Variant Builds Build multiple platforms in parallel with a single putup invocation: @@ -176,13 +213,16 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) | `libbacktrace/{Tuprules.tup,tup.config,Tupfile}` | Backtrace library | | **libcpp** | | | `libcpp/{Tuprules.tup,tup.config,Tupfile}` | C preprocessor library | -| **GCC (cc1)** | | -| `gcc/{Tuprules.tup,tup.config,Tupfile}` | Config headers, generators, backend | +| **libcody** | | +| `libcody/{Tuprules.tup,tup.config,Tupfile}` | C++ modules protocol library | +| **GCC (compilers + tools)** | | +| `gcc/{Tuprules.tup,tup.config,Tupfile}` | Config headers, generators, backend, tools | | `gcc/c/Tupfile` | C frontend objects | +| `gcc/cp/Tupfile` | C++ frontend objects | | `gcc/c-family/Tupfile` | C-family shared objects | | `gcc/analyzer/Tupfile` | Static analyzer objects | | `gcc/config/i386/Tupfile` | x86_64 target-specific objects | -| `gcc/Tupfile` (gtyp section) | gengtype input file list (inline, from GTFILES) | +| `gcc/targets/x86_64-pc-linux-gnu.tup` | Target-specific machine description rules | ## Build Features Demonstrated diff --git a/examples/gcc/Tuprules.tup b/examples/gcc/Tuprules.tup index 415b520..2b5feea 100644 --- a/examples/gcc/Tuprules.tup +++ b/examples/gcc/Tuprules.tup @@ -19,4 +19,5 @@ LIBIBERTY_DIR = libiberty LIBCPP_DIR = libcpp LIBDECNUMBER_DIR = libdecnumber LIBBACKTRACE_DIR = libbacktrace +LIBCODY_DIR = libcody GCC_DIR = gcc diff --git a/examples/gcc/configs/aarch64-linux.config b/examples/gcc/configs/aarch64-linux.config index d925ae5..58510e3 100644 --- a/examples/gcc/configs/aarch64-linux.config +++ b/examples/gcc/configs/aarch64-linux.config @@ -6,7 +6,14 @@ # Per-library configs live in gmp/tup.config, mpfr/tup.config, mpc/tup.config. # Scoped config merging combines these with the toolchain vars below. +# Toolchain (cross-compiler) CONFIG_CC=aarch64-linux-gnu-gcc CONFIG_CXX=aarch64-linux-gnu-g++ CONFIG_AR=aarch64-linux-gnu-ar CONFIG_HOSTCC=g++ + +# Platform selection (same x86_64 target, cross-compiled from Linux host) +CONFIG_TARGET=x86_64-pc-linux-gnu +CONFIG_HOST_OS=linux +CONFIG_PLATFORM_LDFLAGS=-lm -ldl -lpthread -lz +CONFIG_EXTRA_MODES_FILE=config/i386/i386-modes.def diff --git a/examples/gcc/configs/darwin-x86_64-linux.config b/examples/gcc/configs/darwin-x86_64-linux.config new file mode 100644 index 0000000..bf3c1c4 --- /dev/null +++ b/examples/gcc/configs/darwin-x86_64-linux.config @@ -0,0 +1,20 @@ +# GCC Libraries - macOS host, x86-64 Linux target (cross-compiler) +# +# Usage: +# make -f Makefile.pup PLATFORM=darwin-x86_64-linux HOST=darwin +# +# 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 diff --git a/examples/gcc/configs/host-darwin/gcc.config b/examples/gcc/configs/host-darwin/gcc.config new file mode 100644 index 0000000..ab0517d --- /dev/null +++ b/examples/gcc/configs/host-darwin/gcc.config @@ -0,0 +1,87 @@ +# gcc/ - macOS (aarch64-apple-darwin) auto-host.h defines +# +# Cross-referenced with gcc/configure.ac output for macOS host. +# Differences from Linux: no mallinfo, no posix_fallocate, no *_unlocked, +# no _GNU_SOURCE, different ld/gas features. + +# Type sizes (same as Linux on 64-bit) +CONFIG_SIZEOF_SHORT=2 +CONFIG_SIZEOF_INT=4 +CONFIG_SIZEOF_LONG=8 +CONFIG_SIZEOF_LONG_LONG=8 +CONFIG_SIZEOF_VOID_P=8 +CONFIG_SIZEOF__BOOL=1 +CONFIG_INT64_T_IS_LONG=1 + +# Headers +CONFIG_HAVE_ALLOCA_H=1 +CONFIG_HAVE_DLFCN_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_FTW_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_LANGINFO_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_LOCALE_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_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_TIMES_H=1 +CONFIG_HAVE_SYS_TIME_H=1 +CONFIG_HAVE_SYS_TYPES_H=1 +CONFIG_HAVE_SYS_WAIT_H=1 +CONFIG_HAVE_UNISTD_H=1 + +# Functions (macOS has most POSIX, but not Linux-specific ones) +CONFIG_HAVE_ALLOCA=1 +CONFIG_HAVE_CLOCK=1 +CONFIG_HAVE_CLOCK_GETTIME=1 +CONFIG_HAVE_GETRLIMIT=1 +CONFIG_HAVE_GETRUSAGE=1 +CONFIG_HAVE_GETTIMEOFDAY=1 +CONFIG_HAVE_ICONV=1 +CONFIG_HAVE_LANGINFO_CODESET=1 +CONFIG_HAVE_LSTAT=1 +CONFIG_HAVE_MADVISE=1 +CONFIG_HAVE_MMAP=1 +CONFIG_HAVE_MMAP_ANON=1 +CONFIG_HAVE_MMAP_FILE=1 +CONFIG_HAVE_SETLOCALE=1 +CONFIG_HAVE_SETRLIMIT=1 +CONFIG_HAVE_SIGACTION=1 +CONFIG_HAVE_STRSIGNAL=1 +CONFIG_HAVE_SYSCONF=1 +CONFIG_HAVE_TIMES=1 +CONFIG_HAVE_VFORK=1 +CONFIG_HAVE_WORKING_FORK=1 +CONFIG_HAVE_WORKING_VFORK=1 + +# Declarations +CONFIG_HAVE_DECL_ABORT=1 +CONFIG_HAVE_DECL_ASPRINTF=1 +CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_ERRNO=1 +CONFIG_HAVE_DECL_GETENV=1 +CONFIG_HAVE_DECL_GETOPT=1 +CONFIG_HAVE_DECL_LDGETNAME=0 +CONFIG_HAVE_DECL_MALLOC=1 +CONFIG_HAVE_DECL_REALLOC=1 +CONFIG_HAVE_DECL_SBRK=0 +CONFIG_HAVE_DECL_SNPRINTF=1 +CONFIG_HAVE_DECL_STRSIGNAL=1 +CONFIG_HAVE_DECL_VASPRINTF=1 +CONFIG_HAVE_DECL_VSNPRINTF=1 + +# Build options +CONFIG_GATHER_STATISTICS=0 +CONFIG_CHECKING_P=1 + +# Misc +CONFIG_STDC_HEADERS=1 +CONFIG_ENABLE_ASSERT_CHECKING=1 diff --git a/examples/gcc/configs/host-darwin/gmp.config b/examples/gcc/configs/host-darwin/gmp.config new file mode 100644 index 0000000..a280c8c --- /dev/null +++ b/examples/gcc/configs/host-darwin/gmp.config @@ -0,0 +1,101 @@ +# 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/gcc/configs/host-darwin/libbacktrace.config b/examples/gcc/configs/host-darwin/libbacktrace.config new file mode 100644 index 0000000..645b8cb --- /dev/null +++ b/examples/gcc/configs/host-darwin/libbacktrace.config @@ -0,0 +1,48 @@ +# 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/gcc/configs/host-darwin/libcpp.config b/examples/gcc/configs/host-darwin/libcpp.config new file mode 100644 index 0000000..771437b --- /dev/null +++ b/examples/gcc/configs/host-darwin/libcpp.config @@ -0,0 +1,64 @@ +# libcpp - macOS (aarch64-apple-darwin) config.h defines +# +# Key differences from Linux: no *_unlocked functions (glibc-specific). + +# Build options +CONFIG_ENABLE_CANONICAL_SYSTEM_HEADERS=1 + +# Headers +CONFIG_HAVE_ALLOCA_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_LOCALE_H=1 +CONFIG_HAVE_MEMORY_H=1 +CONFIG_HAVE_STDDEF_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_STAT_H=1 +CONFIG_HAVE_SYS_TYPES_H=1 +CONFIG_HAVE_UNISTD_H=1 + +# Functions (macOS lacks glibc *_unlocked variants) +CONFIG_HAVE_ALLOCA=1 +CONFIG_HAVE_ICONV=1 +CONFIG_HAVE_LANGINFO_CODESET=1 +CONFIG_HAVE_SETLOCALE=1 + +# Declarations +CONFIG_HAVE_DECL_ABORT=1 +CONFIG_HAVE_DECL_ASPRINTF=1 +CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_ERRNO=1 +CONFIG_HAVE_DECL_FPRINTF_UNLOCKED=0 +CONFIG_HAVE_DECL_GETOPT=1 +CONFIG_HAVE_DECL_VASPRINTF=1 + +# Types +CONFIG_HAVE_UINTPTR_T=1 + +# Sizes +CONFIG_SIZEOF_DEV_T=4 +CONFIG_SIZEOF_INO_T=8 +CONFIG_SIZEOF_INT=4 +CONFIG_SIZEOF_LONG=8 + +# Package +CONFIG_PACKAGE="cpplib" +CONFIG_PACKAGE_BUGREPORT="" +CONFIG_PACKAGE_NAME="cpplib" +CONFIG_PACKAGE_STRING="cpplib 0" +CONFIG_PACKAGE_TARNAME="cpplib" +CONFIG_PACKAGE_URL="" +CONFIG_PACKAGE_VERSION="0" + +# iconv (macOS libc uses char**, same as glibc — ICONV_CONST is empty) +CONFIG_ICONV_CONST= + +# Misc +CONFIG_STDC_HEADERS=1 +CONFIG_STRING_WITH_STRINGS=1 +CONFIG_TIME_WITH_SYS_TIME=1 diff --git a/examples/gcc/configs/host-darwin/libdecnumber.config b/examples/gcc/configs/host-darwin/libdecnumber.config new file mode 100644 index 0000000..de25363 --- /dev/null +++ b/examples/gcc/configs/host-darwin/libdecnumber.config @@ -0,0 +1,7 @@ +# 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/gcc/configs/host-darwin/libiberty.config b/examples/gcc/configs/host-darwin/libiberty.config new file mode 100644 index 0000000..4fb2d0a --- /dev/null +++ b/examples/gcc/configs/host-darwin/libiberty.config @@ -0,0 +1,132 @@ +# 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/gcc/configs/host-darwin/mpc.config b/examples/gcc/configs/host-darwin/mpc.config new file mode 100644 index 0000000..d4568ae --- /dev/null +++ b/examples/gcc/configs/host-darwin/mpc.config @@ -0,0 +1,24 @@ +# 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/gcc/configs/host-darwin/mpfr.config b/examples/gcc/configs/host-darwin/mpfr.config new file mode 100644 index 0000000..f92072b --- /dev/null +++ b/examples/gcc/configs/host-darwin/mpfr.config @@ -0,0 +1,31 @@ +# 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/gcc/configs/x86_64-linux.config b/examples/gcc/configs/x86_64-linux.config index a91299a..44f92ab 100644 --- a/examples/gcc/configs/x86_64-linux.config +++ b/examples/gcc/configs/x86_64-linux.config @@ -1,4 +1,4 @@ -# GCC Libraries - x86-64 Linux toolchain +# GCC Libraries - x86-64 Linux toolchain (native) # # Usage: # putup configure --config configs/x86_64-linux.config -S ../gcc-15.2.0 -B ../build-gcc @@ -6,7 +6,14 @@ # Per-library configs live in gmp/tup.config, mpfr/tup.config, mpc/tup.config. # Scoped config merging combines these with the toolchain vars below. +# Toolchain CONFIG_CC=gcc CONFIG_CXX=g++ CONFIG_AR=ar CONFIG_HOSTCC=g++ + +# Platform selection +CONFIG_TARGET=x86_64-pc-linux-gnu +CONFIG_HOST_OS=linux +CONFIG_PLATFORM_LDFLAGS=-lm -ldl -lpthread -lz +CONFIG_EXTRA_MODES_FILE=config/i386/i386-modes.def diff --git a/examples/gcc/gcc/Tupfile b/examples/gcc/gcc/Tupfile index 522a912..9e7d3a6 100644 --- a/examples/gcc/gcc/Tupfile +++ b/examples/gcc/gcc/Tupfile @@ -1,7 +1,7 @@ include_rules # ============================================================ -# GCC 15.2.0 — C compiler backend (x86_64-linux) +# GCC 15.2.0 — C compiler backend # ============================================================ # # Builds cc1 from the GCC source tree via seven phases: @@ -12,12 +12,18 @@ include_rules # 5. Backend + common object compilation # 6. Common objects # 7. cc1 link +# +# Platform selection (from root tup.config): +# @(TARGET) — target triple (e.g. x86_64-pc-linux-gnu) +# @(HOST_OS) — host OS for source selection (linux, darwin) +# @(EXTRA_MODES_FILE) — target modes definition file +# @(PLATFORM_LDFLAGS) — platform-specific link flags +# +# Target-specific rules (tm.h, tm_p.h, MD, gtyp entries): +# targets/@(TARGET).tup SRC = $(S)/$(GCC_DIR) -# Machine description inputs (x86_64-linux) -MD = common.md config/i386/i386.md - # ============================================================ # Phase 1: Config headers → # ============================================================ @@ -69,16 +75,30 @@ MD = common.md config/i386/i386.md # configargs.h — configure arguments (stub for tup build) : |> ^ GEN %o^ ( \ - echo 'static const char configuration_arguments[] = "tup-build x86_64-pc-linux-gnu";'; \ + echo 'static const char configuration_arguments[] = "tup-build @(TARGET)";'; \ echo 'static const char thread_model[] = "posix";'; \ echo 'static const struct { const char *name, *value; } configure_default_options[] = { { NULL, NULL } };'; \ ) > %o |> configargs.h +# omp-device-properties.h — offload device properties (no GPU offloading) +: |> ^ GEN %o^ ( \ + echo 'const char omp_offload_device_kind[] = "";'; \ + echo 'const char omp_offload_device_arch[] = "";'; \ + echo 'const char omp_offload_device_isa[] = "";'; \ + ) > %o |> omp-device-properties.h + +# --- Target-specific headers and configuration --- +# Sets: MD, TARGET_OPT_FILES, target_gtyp_src, target_GT_H +# Generates: tm.h, tm_p.h → +# Compiles: target-specific common objects → +include targets/@(TARGET).tup + # --- Options pipeline --- # .opt files → optionlist → options.h, options.cc, options-save.cc, options-urls.cc OPT_FILES = c-family/c.opt common.opt params.opt analyzer/analyzer.opt -OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt +OPT_FILES += lto/lang.opt +OPT_FILES += $(TARGET_OPT_FILES) : $(OPT_FILES) |> ^ GEN optionlist^ \ LC_ALL=C awk -f $(SRC)/opt-gather.awk %f > %o \ @@ -107,74 +127,6 @@ OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt -v header_name="config.h system.h coretypes.h tm.h" < %f > %o \ |> options-urls.cc -# tm_p.h — target machine prototypes for x86_64-linux-gnu -: |> ^ GEN %o^ ( \ - echo '#ifndef GCC_TM_P_H'; \ - echo '#define GCC_TM_P_H'; \ - echo '#ifdef IN_GCC'; \ - echo '# include "config/i386/i386-protos.h"'; \ - echo '# include "config/linux-protos.h"'; \ - echo '# include "tm-preds.h"'; \ - echo '#endif'; \ - echo '#endif'; \ - ) > %o |> tm_p.h - -# tm.h — target machine description for x86_64-linux-gnu -# Matches the real configure-generated tm.h layout. -: |> ^ GEN %o^ ( \ - echo '#ifndef GCC_TM_H'; \ - echo '#define GCC_TM_H'; \ - echo '#ifndef LIBC_GLIBC'; \ - echo '# define LIBC_GLIBC 1'; \ - echo '#endif'; \ - echo '#ifndef LIBC_UCLIBC'; \ - echo '# define LIBC_UCLIBC 2'; \ - echo '#endif'; \ - echo '#ifndef LIBC_BIONIC'; \ - echo '# define LIBC_BIONIC 3'; \ - echo '#endif'; \ - echo '#ifndef LIBC_MUSL'; \ - echo '# define LIBC_MUSL 4'; \ - echo '#endif'; \ - echo '#ifndef DEFAULT_LIBC'; \ - echo '# define DEFAULT_LIBC LIBC_GLIBC'; \ - echo '#endif'; \ - echo '#ifndef ANDROID_DEFAULT'; \ - echo '# define ANDROID_DEFAULT 0'; \ - echo '#endif'; \ - echo '#ifndef HEAP_TRAMPOLINES_INIT'; \ - echo '# define HEAP_TRAMPOLINES_INIT 0'; \ - echo '#endif'; \ - echo '#ifdef IN_GCC'; \ - echo '# include "options.h"'; \ - echo '# include "insn-constants.h"'; \ - echo '# include "config/vxworks-dummy.h"'; \ - echo '# include "config/i386/biarch64.h"'; \ - echo '# include "config/i386/i386.h"'; \ - echo '# include "config/i386/unix.h"'; \ - echo '# include "config/i386/att.h"'; \ - echo '# include "config/elfos.h"'; \ - echo '# include "config/gnu-user.h"'; \ - echo '# include "config/glibc-stdint.h"'; \ - echo '# include "config/i386/x86-64.h"'; \ - echo '# include "config/i386/gnu-user-common.h"'; \ - echo '# include "config/i386/gnu-user64.h"'; \ - echo '# include "config/linux.h"'; \ - echo '# include "config/linux-android.h"'; \ - echo '# include "config/i386/linux-common.h"'; \ - echo '# include "config/i386/linux64.h"'; \ - echo '# include "config/initfini-array.h"'; \ - echo '#endif'; \ - echo '#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET'; \ - echo '# include "insn-flags.h"'; \ - echo '#endif'; \ - echo '#if defined IN_GCC && !defined GENERATOR_FILE'; \ - echo '# include "insn-modes.h"'; \ - echo '#endif'; \ - echo '# include "defaults.h"'; \ - echo '#endif'; \ - ) > %o |> tm.h - # ============================================================ # Phase 2: Generator bootstrap # ============================================================ @@ -189,9 +141,9 @@ OPT_FILES += config/i386/i386.opt config/fused-madd.opt config/linux-android.opt BUILD_ERRORS = host-errors.o : errors.cc |> !hostcxx |> host-errors.o -# genmodes needs EXTRA_MODES_FILE for i386 +# genmodes needs EXTRA_MODES_FILE for the target architecture : genmodes.cc |> ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) \ - -DEXTRA_MODES_FILE=\"config/i386/i386-modes.def\" -c %f -o %o \ + -DEXTRA_MODES_FILE=\"@(EXTRA_MODES_FILE)\" -c %f -o %o \ |> host-genmodes.o : host-genmodes.o host-errors.o $(LIBIBERTY_A) |> ^ LINK genmodes^ $(HOSTCC) %f -o %o |> genmodes @@ -243,8 +195,7 @@ BUILD_MD = host-read-md.o : $(MD) | genconditions |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genconditions %f > %o |> gencondmd.cc -: gencondmd.cc | |> ^ HOSTCXX %b^ \ - $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-gencondmd.o +: gencondmd.cc |> !hostcxx |> host-gencondmd.o : host-gencondmd.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK gencondmd^ $(HOSTCC) %f -o %o |> gencondmd @@ -268,11 +219,14 @@ BUILD_MD = host-read-md.o ^ LINK gengenrtl^ $(HOSTCC) %f -o %o |> gengenrtl : | gengenrtl |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/gengenrtl > %o |> genrtl.h -# all-tree.def — aggregates tree.def + language-specific defs (C only) +# all-tree.def — aggregates tree.def + language-specific defs +# Includes cp/cp-tree.def because c-family/ shared code references C++ tree codes. : |> ^ GEN %o^ ( \ echo '#include "tree.def"'; \ echo 'END_OF_BASE_TREE_CODES'; \ echo '#include "c-family/c-common.def"'; \ + echo '#include "c/c-tree.def"'; \ + echo '#include "cp/cp-tree.def"'; \ ) > %o |> all-tree.def # gencheck (uses all-tree.def + insn-modes.h via coretypes.h → tm.h) @@ -287,7 +241,7 @@ BUILD_MD = host-read-md.o : | genhooks |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genhooks "Target Hook" > %o \ |> target-hooks-def.h : | genhooks |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genhooks "Common Target Hook" > %o \ - |> common-target-hooks-def.h + |> common/common-target-hooks-def.h # gencfn-macros (no MD input) : gencfn-macros.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-gencfn-macros.o @@ -300,12 +254,11 @@ BUILD_MD = host-read-md.o |> cfn-operators.pd # genmatch (reads match.pd via libcpp tokenizer) -: genmatch.cc | $(BUILD_RTL_DEPS) case-cfn-macros.h |> ^ HOSTCXX %b^ \ - $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> host-genmatch.o +: genmatch.cc | $(BUILD_RTL_DEPS) case-cfn-macros.h |> !hostcxx |> host-genmatch.o : host-genmatch.o $(BUILD_ERRORS) host-vec.o host-hash-table.o host-sort.o \ $(LIBCPP_A) $(LIBIBERTY_A) |> \ - ^ LINK genmatch^ $(HOSTCC) %f -o %o |> genmatch + ^ LINK genmatch^ $(HOSTCC) %f @(PLATFORM_LDFLAGS) -o %o |> genmatch : $(SRC)/match.pd | genmatch cfn-operators.pd |> ^ GEN gimple-match-*^ \ SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genmatch --gimple \ @@ -344,7 +297,7 @@ BUILD_MD = host-read-md.o : genattr.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattr.o : host-genattr.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genattr^ $(HOSTCC) %f -o %o |> genattr -: $(MD) insn-conditions.md | genattr |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genattr%f > %o \ +: $(MD) insn-conditions.md | genattr |> ^ GEN %o^ $(TUP_VARIANT_OUTPUTDIR)/genattr %f > %o \ |> insn-attr.h : genattr-common.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattr-common.o @@ -404,14 +357,16 @@ BUILD_MD = host-read-md.o |> insn-peep.cc # --- Multi-output RTL generators --- +# These cd to the output dir for writing; MD paths are prefixed with $SRCDIR. # genattrtab → 3 files : genattrtab.cc | $(BUILD_RTL_DEPS) |> !hostcxx |> host-genattrtab.o : host-genattrtab.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genattrtab^ $(HOSTCC) %f -o %o |> genattrtab : $(MD) insn-conditions.md | genattrtab |> ^ GEN insn-attrtab^ \ - SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genattrtab \ - $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && \ + MD_ARGS=""; for m in $(MD); do MD_ARGS="$MD_ARGS $SRCDIR/$m"; done && \ + ./genattrtab $MD_ARGS insn-conditions.md \ -Ainsn-attrtab.cc -Dinsn-dfatab.cc -Linsn-latencytab.cc \ |> insn-attrtab.cc insn-dfatab.cc insn-latencytab.cc @@ -420,8 +375,9 @@ BUILD_MD = host-read-md.o : host-genopinit.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genopinit^ $(HOSTCC) %f -o %o |> genopinit : $(MD) insn-conditions.md | genopinit |> ^ GEN insn-opinit^ \ - SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genopinit \ - $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && \ + MD_ARGS=""; for m in $(MD); do MD_ARGS="$MD_ARGS $SRCDIR/$m"; done && \ + ./genopinit $MD_ARGS insn-conditions.md \ -hinsn-opinit.h -cinsn-opinit.cc \ |> insn-opinit.h insn-opinit.cc @@ -438,12 +394,13 @@ BUILD_MD = host-read-md.o : host-genemit.o $(BUILD_RTL) $(BUILD_MD) $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK genemit^ $(HOSTCC) %f -o %o |> genemit : $(MD) insn-conditions.md | genemit |> ^ GEN insn-emit-*^ \ - SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genemit \ - $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ - -O insn-emit-1.cc -O insn-emit-2.cc -O insn-emit-3.cc \ - -O insn-emit-4.cc -O insn-emit-5.cc -O insn-emit-6.cc \ - -O insn-emit-7.cc -O insn-emit-8.cc -O insn-emit-9.cc \ - -O insn-emit-10.cc \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && \ + MD_ARGS=""; for m in $(MD); do MD_ARGS="$MD_ARGS $SRCDIR/$m"; done && \ + ./genemit $MD_ARGS insn-conditions.md \ + -Oinsn-emit-1.cc -Oinsn-emit-2.cc -Oinsn-emit-3.cc \ + -Oinsn-emit-4.cc -Oinsn-emit-5.cc -Oinsn-emit-6.cc \ + -Oinsn-emit-7.cc -Oinsn-emit-8.cc -Oinsn-emit-9.cc \ + -Oinsn-emit-10.cc \ |> insn-emit-1.cc insn-emit-2.cc insn-emit-3.cc insn-emit-4.cc \ insn-emit-5.cc insn-emit-6.cc insn-emit-7.cc insn-emit-8.cc \ insn-emit-9.cc insn-emit-10.cc @@ -454,13 +411,14 @@ BUILD_MD = host-read-md.o host-inchash.o $(LIBIBERTY_A) |> \ ^ LINK genrecog^ $(HOSTCC) %f -o %o |> genrecog : $(MD) insn-conditions.md | genrecog |> ^ GEN insn-recog-*^ \ - SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && ./genrecog \ - $SRCDIR/common.md $SRCDIR/config/i386/i386.md insn-conditions.md \ + SRCDIR=$PWD && cd $(TUP_VARIANT_OUTPUTDIR) && \ + MD_ARGS=""; for m in $(MD); do MD_ARGS="$MD_ARGS $SRCDIR/$m"; done && \ + ./genrecog $MD_ARGS insn-conditions.md \ -Hinsn-recog.h \ - -O insn-recog-1.cc -O insn-recog-2.cc -O insn-recog-3.cc \ - -O insn-recog-4.cc -O insn-recog-5.cc -O insn-recog-6.cc \ - -O insn-recog-7.cc -O insn-recog-8.cc -O insn-recog-9.cc \ - -O insn-recog-10.cc \ + -Oinsn-recog-1.cc -Oinsn-recog-2.cc -Oinsn-recog-3.cc \ + -Oinsn-recog-4.cc -Oinsn-recog-5.cc -Oinsn-recog-6.cc \ + -Oinsn-recog-7.cc -Oinsn-recog-8.cc -Oinsn-recog-9.cc \ + -Oinsn-recog-10.cc \ |> insn-recog.h insn-recog-1.cc insn-recog-2.cc insn-recog-3.cc \ insn-recog-4.cc insn-recog-5.cc insn-recog-6.cc insn-recog-7.cc \ insn-recog-8.cc insn-recog-9.cc insn-recog-10.cc @@ -481,17 +439,16 @@ BUILD_MD = host-read-md.o GENGTYPE_SRCS = gengtype.cc gengtype-parse.cc gengtype-state.cc gengtype-lex.cc -: foreach $(GENGTYPE_SRCS) | |> ^ HOSTCXX %b^ \ - $(HOSTCC) -O0 -std=gnu++14 -DHOST_GENERATOR_FILE -DHAVE_CONFIG_H \ - $(GCC_INCLUDES) -c %f -o %o |> host-%B.o +: foreach $(GENGTYPE_SRCS) |> !hostcxx-gengtype |> : host-gengtype.o host-gengtype-parse.o host-gengtype-state.o \ host-gengtype-lex.o $(BUILD_ERRORS) $(LIBIBERTY_A) |> \ ^ LINK gengtype^ $(HOSTCC) %f -o %o |> gengtype # gtyp-input.list — generated inline (template files can't be inputs in 3-tree mode) -# Derived from GTFILES in gcc/Makefile.in for x86_64-pc-linux-gnu, C only. +# Derived from GTFILES in gcc/Makefile.in, C only. # $(SRC) is expanded at parse time, producing the correct relative paths. +# Target-specific entries come from $(target_gtyp_src) set by the target include. gtyp_parent = libcpp/include/line-map.h libcpp/include/rich-location.h gtyp_parent += libcpp/include/label-text.h libcpp/include/cpplib.h @@ -499,11 +456,6 @@ gtyp_parent += include/hashtab.h include/splay-tree.h gtyp_parent += libcpp/include/symtab.h include/obstack.h gtyp_src = input.h coretypes.h -gtyp_src += config/i386/i386.h config/i386/unix.h config/i386/att.h -gtyp_src += config/elfos.h config/gnu-user.h config/glibc-stdint.h -gtyp_src += config/i386/x86-64.h config/i386/gnu-user-common.h config/i386/gnu-user64.h -gtyp_src += config/linux.h config/linux-android.h config/i386/linux-common.h -gtyp_src += config/i386/linux64.h config/initfini-array.h gtyp_src += bitmap.h wide-int.h alias.h coverage.cc rtl.h optabs.h gtyp_src += tree.h tree-core.h libfuncs.h gtyp_src += real.h function.h insn-addr.h hwint.h fixed-value.h function-abi.h @@ -527,7 +479,7 @@ gtyp_src += tree-dfa.cc tree-iterator.cc gimple-expr.cc tree-chrec.h gtyp_src += tree-scalar-evolution.cc tree-ssa-operands.h gtyp_src += tree-profile.cc tree-nested.cc path-coverage.cc prime-paths.cc gtyp_src += omp-offload.h omp-general.h omp-general.cc omp-low.cc -gtyp_src += targhooks.cc config/i386/i386.cc passes.cc cgraphclones.cc +gtyp_src += targhooks.cc passes.cc cgraphclones.cc gtyp_src += tree-phinodes.cc tree-ssa-alias.h tree-ssanames.h gtyp_src += tree-vrp.h value-range.h value-range-storage.h ipa-prop.h gtyp_src += trans-mem.cc lto-streamer.h target-globals.h @@ -535,7 +487,7 @@ gtyp_src += ipa-predicate.h ipa-fnsummary.h vtable-verify.cc gtyp_src += asan.cc ubsan.cc tsan.cc sanopt.cc sancov.cc gtyp_src += ipa-devirt.cc ipa-strub.cc internal-fn.h calls.cc gtyp_src += analyzer/analyzer-language.cc -gtyp_src += config/i386/i386-builtins.cc config/i386/i386-expand.cc config/i386/i386-options.cc +gtyp_src += $(target_gtyp_src) gtyp_c = c/c-lang.cc c/c-tree.h c/c-decl.cc gtyp_c += c-family/c-common.cc c-family/c-common.h c-family/c-objc.h @@ -543,12 +495,24 @@ gtyp_c += c-family/c-cppbuiltin.cc c-family/c-pragma.h c-family/c-pragma.cc gtyp_c += c-family/c-format.cc c/c-objc-common.cc gtyp_c += c/c-parser.h c/c-parser.cc c/c-lang.h +gtyp_cp = cp/name-lookup.h cp/cp-tree.h cp/decl.h cp/parser.h +gtyp_cp += c-family/c-common.h c-family/c-objc.h c-family/c-pragma.h +gtyp_cp += c-family/c-common.cc c-family/c-format.cc c-family/c-cppbuiltin.cc c-family/c-pragma.cc +gtyp_cp += cp/call.cc cp/class.cc cp/constexpr.cc cp/contracts.cc cp/constraint.cc +gtyp_cp += cp/coroutines.cc cp/cp-gimplify.cc cp/cp-lang.cc cp/cp-objcp-common.cc +gtyp_cp += cp/decl.cc cp/decl2.cc cp/except.cc cp/friend.cc cp/init.cc +gtyp_cp += cp/lambda.cc cp/lex.cc cp/logic.cc cp/mangle.cc cp/method.cc cp/module.cc +gtyp_cp += cp/name-lookup.cc cp/parser.cc cp/pt.cc cp/rtti.cc +gtyp_cp += cp/semantics.cc cp/tree.cc cp/typeck2.cc cp/vtable-class-hierarchy.cc + : |> ^ GEN %o^ { \ for f in $(gtyp_parent); do printf '%s\n' "$(SRC)/../$f"; done; \ for f in $(gtyp_src); do printf '%s\n' "$(SRC)/$f"; done; \ printf '%s\n' $(TUP_VARIANT_OUTPUTDIR)/options.h; \ echo '[c]'; \ for f in $(gtyp_c); do printf '%s\n' "$(SRC)/$f"; done; \ + echo '[cp]'; \ + for f in $(gtyp_cp); do printf '%s\n' "$(SRC)/$f"; done; \ } > %o |> gtyp-input.list # gengtype outputs: gtype-desc.cc/h, gtype-c.h, gt-*.h @@ -577,11 +541,20 @@ GT_H += gt-tree-scalar-evolution.h gt-tree-ssa-address.h GT_H += gt-tree-ssa-loop-ivopts.h gt-tree-ssanames.h GT_H += gt-tree-vect-generic.h gt-tsan.h gt-ubsan.h GT_H += gt-varasm.h gt-vtable-verify.h -GT_H += gt-i386.h gt-i386-builtins.h gt-i386-expand.h gt-i386-options.h +GT_H += $(target_GT_H) GT_H += gt-analyzer-language.h GT_H += gt-c-c-decl.h gt-c-c-lang.h gt-c-c-objc-common.h gt-c-c-parser.h GT_H += gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h GT_H += gt-c-family-c-format.h gt-c-family-c-objc.h gt-c-family-c-pragma.h +GT_H += gtype-cp.h +GT_H += gt-cp-call.h gt-cp-class.h gt-cp-constexpr.h gt-cp-constraint.h +GT_H += gt-cp-contracts.h gt-cp-coroutines.h gt-cp-cp-gimplify.h +GT_H += gt-cp-cp-lang.h gt-cp-cp-objcp-common.h gt-cp-decl.h gt-cp-decl2.h +GT_H += gt-cp-except.h gt-cp-friend.h gt-cp-init.h gt-cp-lambda.h +GT_H += gt-cp-lex.h gt-cp-logic.h gt-cp-mangle.h gt-cp-method.h +GT_H += gt-cp-module.h gt-cp-name-lookup.h gt-cp-parser.h gt-cp-pt.h +GT_H += gt-cp-rtti.h gt-cp-semantics.h gt-cp-tree.h gt-cp-typeck2.h +GT_H += gt-cp-vtable-class-hierarchy.h : gtyp-input.list | gengtype |> ^ GEN gtype-desc^ \ $(TUP_VARIANT_OUTPUTDIR)/gengtype -S $(SRC) \ @@ -640,7 +613,7 @@ gen_srcs += insn-preds.cc insn-opinit.cc insn-enums.cc # ============================================================ # ~445 source files from gcc/. Excludes: # - analyzer/* (compiled in analyzer/Tupfile) -# - config/i386/* (compiled in config/i386/Tupfile) +# - config/* (compiled in config/*/Tupfile) # - Generated insn-*.cc, options*.cc, gtype-desc.cc (compiled above) objs = ggc-page.cc adjust-alignment.cc alias.cc alloc-pool.cc @@ -654,7 +627,7 @@ objs += symtab.cc symtab-thunks.cc symtab-clones.cc objs += cgraph.cc cgraphbuild.cc cgraphunit.cc cgraphclones.cc objs += combine.cc combine-stack-adj.cc compare-elim.cc context.cc objs += convert.cc coroutine-passes.cc coverage.cc -objs += cppdefault.cc cprop.cc cse.cc cselib.cc +objs += cprop.cc cse.cc cselib.cc objs += data-streamer.cc data-streamer-in.cc data-streamer-out.cc objs += dbgcnt.cc dce.cc ddg.cc debug.cc objs += df-core.cc df-problems.cc df-scan.cc dfp.cc digraph.cc @@ -789,26 +762,40 @@ objs += varasm.cc varpool.cc vec-perm-indices.cc vmsdbgout.cc objs += vr-values.cc vtable-verify.cc warning-control.cc web.cc objs += wide-int.cc wide-int-print.cc -# Special -D flags for a few objects -: toplev.cc | |> ^ CXX %b^ \ - $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ - |> toplev.o - -: lto-streamer-in.cc | |> ^ CXX %b^ \ - $(CXX) $(TARGET_CXXFLAGS) -DTARGET_MACHINE=\"x86_64-pc-linux-gnu\" -c %f -o %o \ - |> lto-streamer-in.o - -: optinfo-emit-json.cc | |> ^ CXX %b^ \ - $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ - |> optinfo-emit-json.o - -: tree-diagnostic-client-data-hooks.cc | |> ^ CXX %b^ \ - $(CXX) $(TARGET_CXXFLAGS) -DTARGET_NAME=\"x86_64-pc-linux-gnu\" -c %f -o %o \ - |> tree-diagnostic-client-data-hooks.o - -: cppbuiltin.cc | |> ^ CXX %b^ \ - $(CXX) $(TARGET_CXXFLAGS) -DBASEVER=\"15.2.0\" -c %f -o %o \ - |> cppbuiltin.o +# Special -D flags for a few objects (use !cxx-defs with EXTRA_DEFS) +EXTRA_DEFS = -DTARGET_NAME=\"@(TARGET)\" +: toplev.cc |> !cxx-defs |> toplev.o + +EXTRA_DEFS = -DTARGET_MACHINE=\"@(TARGET)\" +: lto-streamer-in.cc |> !cxx-defs |> lto-streamer-in.o + +EXTRA_DEFS = -DTARGET_NAME=\"@(TARGET)\" +: optinfo-emit-json.cc |> !cxx-defs |> optinfo-emit-json.o + +EXTRA_DEFS = -DTARGET_NAME=\"@(TARGET)\" +: tree-diagnostic-client-data-hooks.cc |> !cxx-defs |> tree-diagnostic-client-data-hooks.o + +# Preprocessor search path defines (PREPROCESSOR_DEFINES in Makefile.in) +PP_DEFS = -DPREFIX=\"/usr/local/\" +PP_DEFS += -DSTANDARD_EXEC_PREFIX=\"/usr/local/lib/gcc/\" +PP_DEFS += -DGCC_INCLUDE_DIR=\"/usr/local/lib/gcc/@(TARGET)/15.2.0/include\" +PP_DEFS += -DFIXED_INCLUDE_DIR=\"/usr/local/lib/gcc/@(TARGET)/15.2.0/include-fixed\" +PP_DEFS += -DGPLUSPLUS_INCLUDE_DIR=\"/usr/local/include/c++/15.2.0\" +PP_DEFS += -DGPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT=0 +PP_DEFS += -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"/usr/local/include/c++/15.2.0/@(TARGET)\" +PP_DEFS += -DGPLUSPLUS_BACKWARD_INCLUDE_DIR=\"/usr/local/include/c++/15.2.0/backward\" +PP_DEFS += -DGPLUSPLUS_LIBCXX_INCLUDE_DIR=\"\" +PP_DEFS += -DGPLUSPLUS_LIBCXX_INCLUDE_DIR_ADD_SYSROOT=0 +PP_DEFS += -DLOCAL_INCLUDE_DIR=\"/usr/local/include\" +PP_DEFS += -DCROSS_INCLUDE_DIR=\"/usr/include\" +PP_DEFS += -DTOOL_INCLUDE_DIR=\"/usr/local/@(TARGET)/include\" +PP_DEFS += -DNATIVE_SYSTEM_HEADER_DIR=\"/usr/include\" + +EXTRA_DEFS = $(PP_DEFS) -DBASEVER=\"15.2.0\" +: cppbuiltin.cc |> !cxx-defs |> cppbuiltin.o + +EXTRA_DEFS = $(PP_DEFS) +: cppdefault.cc |> !cxx-defs |> cppdefault.o : foreach $(objs) |> !cxx |> %B.o @@ -839,22 +826,21 @@ common += hooks.cc file-find.cc opt-suggestions.cc : foreach $(common) |> !cxx |> %B.o -: prefix.cc | |> ^ CXX %b^ \ - $(CXX) $(TARGET_CXXFLAGS) -DPREFIX=\"/usr/local\" -DBASEVER=\"15.2.0\" -c %f -o %o \ - |> prefix.o +EXTRA_DEFS = -DPREFIX=\"/usr/local\" -DBASEVER=\"15.2.0\" +: prefix.cc |> !cxx-defs |> prefix.o # Target-specific common objects (from subdirectories) : common/common-targhooks.cc |> !cxx |> common-targhooks.o -: common/config/i386/i386-common.cc |> !cxx |> i386-common.o -# Host hooks (Linux host) -: config/host-linux.cc |> !cxx |> host-linux.o +# Host hooks (default host hooks + platform-specific PCH helpers) +: host-default.cc |> !cxx |> host-default.o +: config/host-@(HOST_OS).cc |> !cxx |> host-@(HOST_OS).o # main.o : main.cc |> !cxx |> main.o # cc1-checksum.o (stub — real GCC uses genchecksum to embed a binary hash) -: |> ^ GEN %o^ echo 'const unsigned char executable_checksum[16] = {0};' > %o \ +: |> ^ GEN %o^ echo 'extern const unsigned char executable_checksum[16] = {0};' > %o \ |> cc1-checksum.cc : cc1-checksum.cc |> !cxx |> cc1-checksum.o @@ -865,14 +851,189 @@ common += hooks.cc file-find.cc opt-suggestions.cc # Phase 7: Link cc1 # ============================================================ # Collects objects from this directory and subdirectories: -# gcc/c/ → ../ (C frontend) -# gcc/c-family/ → ../ (C-family shared code) -# gcc/analyzer/ → ../ (static analyzer) -# gcc/config/i386/ → ../../ (x86_64 target) +# gcc/c/ → ../ (C frontend) +# gcc/c-family/ → ../ (C-family shared code) +# gcc/analyzer/ → ../ (static analyzer) +# gcc/config/*/ → ../../ (target-specific objects) : $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) \ - $(LIBIBERTY_A) $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) |> \ - ^ LINK cc1^ $(CXX) % \ + $(LIBIBERTY_A) $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) \ + | c/ c-family/ analyzer/ |> \ + ^ LINK cc1^ sh -c '$(CXX) % \ + $(TUP_VARIANT_OUTPUTDIR)/c/*.o \ + $(TUP_VARIANT_OUTPUTDIR)/c-family/*.o \ + $(TUP_VARIANT_OUTPUTDIR)/analyzer/*.o \ $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) $(LIBIBERTY_A) \ $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) \ - -lm -ldl -lpthread -lz -o %o |> cc1 + @(PLATFORM_LDFLAGS) -o %o' |> cc1 + +# ============================================================ +# Phase 8: xgcc driver +# ============================================================ +# The `gcc` command that users invoke. Dispatches to cc1/cc1plus/as/ld +# based on file extensions and flags. Links against shared utility +# objects (already compiled for cc1) + its own driver-specific objects. + +# multilib.h — multilib configuration (no multilib for cross-compiler) +: |> ^ GEN %o^ sh $(SRC)/genmultilib '' '' '' '' '' '' '' '' '' '' no > %o \ + |> multilib.h + +# specs.h — additional language spec entries for default_compilers[] +# C specs are built into gcc.cc; other languages add via this header. +# Includes cp/lang-specs.h for C++ file extension recognition. +: |> ^ GEN %o^ echo '#include "cp/lang-specs.h"' > %o |> specs.h + +# Driver path defines (embedded installation paths) +DRIVER_DEFS = -DSTANDARD_STARTFILE_PREFIX=\"../lib/\" +DRIVER_DEFS += -DSTANDARD_EXEC_PREFIX=\"/usr/local/lib/gcc/\" +DRIVER_DEFS += -DSTANDARD_LIBEXEC_PREFIX=\"/usr/local/libexec/gcc/\" +DRIVER_DEFS += -DDEFAULT_TARGET_VERSION=\"15.2.0\" +DRIVER_DEFS += -DDEFAULT_REAL_TARGET_MACHINE=\"@(TARGET)\" +DRIVER_DEFS += -DDEFAULT_TARGET_MACHINE=\"@(TARGET)\" +DRIVER_DEFS += -DSTANDARD_BINDIR_PREFIX=\"/usr/local/bin/\" +DRIVER_DEFS += -DTOOLDIR_BASE_PREFIX=\"../../\" +DRIVER_DEFS += -DACCEL_DIR_SUFFIX=\"\" +DRIVER_DEFS += -DCONFIGURE_SPECS=\"\" +DRIVER_DEFS += -DTOOL_INCLUDE_DIR=\"/usr/local/@(TARGET)/include\" +DRIVER_DEFS += -DNATIVE_SYSTEM_HEADER_DIR=\"/usr/include\" +DRIVER_DEFS += -DOFFLOAD_TARGETS=\"\" + +EXTRA_DEFS = $(DRIVER_DEFS) -DBASEVER=\"15.2.0\" +: gcc.cc | specs.h |> !cxx-defs |> gcc-driver.o + +EXTRA_DEFS = +: gcc-main.cc |> !cxx |> gcc-main-driver.o +: ggc-none.cc |> !cxx |> xgcc-ggc-none.o +: c/gccspec.cc |> !cxx |> gccspec.o + +# Shared objects for driver-like binaries (xgcc, collect2, g++). +# Equivalent to libcommon.a + libcommon-target.a in the autotools build. +D = $(TUP_VARIANT_OUTPUTDIR) +LIBCOMMON_OBJS = $(D)/diagnostic-spec.o $(D)/diagnostic.o $(D)/diagnostic-color.o +LIBCOMMON_OBJS += $(D)/diagnostic-format-json.o $(D)/diagnostic-format-sarif.o +LIBCOMMON_OBJS += $(D)/diagnostic-format-text.o $(D)/diagnostic-global-context.o +LIBCOMMON_OBJS += $(D)/diagnostic-macro-unwinding.o $(D)/diagnostic-path.o +LIBCOMMON_OBJS += $(D)/diagnostic-show-locus.o $(D)/edit-context.o $(D)/pretty-print.o +LIBCOMMON_OBJS += $(D)/intl.o $(D)/json.o $(D)/json-parsing.o $(D)/sbitmap.o +LIBCOMMON_OBJS += $(D)/vec.o $(D)/input.o $(D)/hash-table.o $(D)/memory-block.o +LIBCOMMON_OBJS += $(D)/selftest.o $(D)/selftest-diagnostic.o $(D)/sort.o +LIBCOMMON_OBJS += $(D)/selftest-diagnostic-path.o $(D)/selftest-json.o +LIBCOMMON_OBJS += $(D)/selftest-logical-location.o +LIBCOMMON_OBJS += $(D)/box-drawing.o $(D)/canvas.o $(D)/ruler.o $(D)/selftests.o +LIBCOMMON_OBJS += $(D)/style.o $(D)/styled-string.o $(D)/table.o $(D)/theme.o +LIBCOMMON_OBJS += $(D)/tree-widget.o $(D)/widget.o +LIBCOMMON_OBJS += $(D)/i386-common.o $(D)/prefix.o $(D)/opts.o $(D)/opts-common.o +LIBCOMMON_OBJS += $(D)/opts-diagnostic.o $(D)/options.o $(D)/hooks.o +LIBCOMMON_OBJS += $(D)/common-targhooks.o $(D)/file-find.o $(D)/spellcheck.o +LIBCOMMON_OBJS += $(D)/opt-suggestions.o $(D)/options-urls.o $(D)/gcc-urlifier.o + +DRIVER_LIBS = $(LIBIBERTY_A) $(LIBCPP_A) $(LIBBACKTRACE_A) $(LIBDECNUMBER_A) + +# Link xgcc +: $(DRIVER_LIBS) \ + | |> ^ LINK xgcc^ sh -c '$(CXX) % \ + $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + @(PLATFORM_LDFLAGS) -o %o' |> xgcc + +# ============================================================ +# Phase 9: cc1plus (C++ compiler) +# ============================================================ +# Same backend as cc1, swapping C frontend (c/) for C++ frontend (cp/). +# Adds libcody for C++ modules protocol support. + +# Link cc1plus — backend + C++ frontend + shared frontends + libraries. +# Uses for the shared backend (includes main.o, cc1-checksum.o). +# The checksum stub is identical for both compilers. +: $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) \ + $(LIBIBERTY_A) $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) $(LIBCODY_A) \ + | cp/ c-family/ analyzer/ |> \ + ^ LINK cc1plus^ sh -c '$(CXX) % \ + $(TUP_VARIANT_OUTPUTDIR)/cp/*.o \ + $(TUP_VARIANT_OUTPUTDIR)/c-family/*.o \ + $(TUP_VARIANT_OUTPUTDIR)/analyzer/*.o \ + $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) $(LIBIBERTY_A) \ + $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) $(LIBCODY_A) \ + @(PLATFORM_LDFLAGS) -o %o' |> cc1plus + +# ============================================================ +# Phase 10: collect2 (linker wrapper) +# ============================================================ +# Intercepts linker invocations to collect C++ static constructors/destructors. +# Standalone binary with its own main() — not a driver variant. + +EXTRA_DEFS = -DTARGET_MACHINE=\"@(TARGET)\" +: collect2.cc |> !cxx-defs |> collect2-main.o + +EXTRA_DEFS = +: collect2-aix.cc |> !cxx |> collect2-aix.o +: collect-utils.cc |> !cxx |> collect-utils.o +: ggc-none.cc |> !cxx |> collect2-ggc-none.o + +: $(DRIVER_LIBS) \ + | |> ^ LINK collect2^ sh -c '$(CXX) % \ + $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + @(PLATFORM_LDFLAGS) -o %o' |> collect2 + +# ============================================================ +# Phase 11: g++ driver (xg++) +# ============================================================ +# C++ driver — same as xgcc but links g++spec.o instead of gccspec.o. +# Defaults to C++ mode, adds -lstdc++ and C++ library paths. + +EXTRA_DEFS = $(DRIVER_DEFS) +: cp/g++spec.cc |> !cxx-defs |> g++spec.o + +EXTRA_DEFS = +: $(DRIVER_LIBS) \ + | |> ^ LINK xg++^ sh -c '$(CXX) \ + $(D)/gcc-driver.o $(D)/gcc-main-driver.o $(D)/xgcc-ggc-none.o % \ + $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + @(PLATFORM_LDFLAGS) -o %o' |> xg++ + +# ============================================================ +# Phase 12: cpp (C preprocessor) +# ============================================================ +# Same as xgcc but with cppspec.o — invokes cc1 with -E flag. + +EXTRA_DEFS = $(DRIVER_DEFS) +: c-family/cppspec.cc |> !cxx-defs |> cppspec.o + +EXTRA_DEFS = +: $(DRIVER_LIBS) \ + | |> ^ LINK cpp^ sh -c '$(CXX) \ + $(D)/gcc-driver.o $(D)/gcc-main-driver.o $(D)/xgcc-ggc-none.o % \ + $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + @(PLATFORM_LDFLAGS) -o %o' |> cpp + +# ============================================================ +# Phase 13: lto-wrapper (LTO linker plugin interface) +# ============================================================ + +: lto-wrapper.cc |> !cxx |> lto-wrapper.o +: lockfile.cc |> !cxx |> lockfile.o +: lto-ltrans-cache.cc |> !cxx |> lto-ltrans-cache.o + +: $(DRIVER_LIBS) \ + | |> ^ LINK lto-wrapper^ sh -c '$(CXX) % \ + $(D)/collect-utils.o $(D)/collect2-ggc-none.o \ + $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + @(PLATFORM_LDFLAGS) -o %o' |> lto-wrapper + +# ============================================================ +# Phase 14: gcov + gcov-dump (code coverage analysis) +# ============================================================ + +: gcov.cc |> !cxx |> gcov.o + +: $(DRIVER_LIBS) \ + | |> ^ LINK gcov^ sh -c '$(CXX) % \ + $(D)/graphds.o $(D)/prime-paths.o $(D)/bitmap.o \ + $(D)/xgcc-ggc-none.o $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + -lz @(PLATFORM_LDFLAGS) -o %o' |> gcov + +: gcov-dump.cc |> !cxx |> gcov-dump.o + +: $(DRIVER_LIBS) \ + | |> ^ LINK gcov-dump^ sh -c '$(CXX) % \ + $(D)/xgcc-ggc-none.o $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ + @(PLATFORM_LDFLAGS) -o %o' |> gcov-dump diff --git a/examples/gcc/gcc/Tuprules.tup b/examples/gcc/gcc/Tuprules.tup index 4cd15c9..5202954 100644 --- a/examples/gcc/gcc/Tuprules.tup +++ b/examples/gcc/gcc/Tuprules.tup @@ -18,6 +18,7 @@ LIBIBERTY_DIR ?= libiberty LIBCPP_DIR ?= libcpp LIBDECNUMBER_DIR ?= libdecnumber LIBBACKTRACE_DIR ?= libbacktrace +LIBCODY_DIR ?= libcody # Resolved library paths LIBIBERTY_A = $(B)/$(LIBIBERTY_DIR)/libiberty.a @@ -27,16 +28,19 @@ LIBBACKTRACE_A = $(B)/$(LIBBACKTRACE_DIR)/libbacktrace.a LIBGMP_A = $(B)/$(GMP_DIR)/libgmp.a LIBMPFR_A = $(B)/$(MPFR_DIR)/src/libmpfr.a LIBMPC_A = $(B)/$(MPC_DIR)/src/libmpc.a +LIBCODY_A = $(B)/$(LIBCODY_DIR)/libcody.a # Common include paths GCC_INCLUDES = -I$(B)/$(GCC_DIR) -I$(S)/$(GCC_DIR) GCC_INCLUDES += -I$(S)/$(GCC_DIR)/../include GCC_INCLUDES += -I$(S)/$(LIBCPP_DIR)/include GCC_INCLUDES += -I$(B)/$(LIBDECNUMBER_DIR) -I$(S)/$(LIBDECNUMBER_DIR) +GCC_INCLUDES += -I$(S)/$(LIBDECNUMBER_DIR)/@(DECIMAL_FORMAT) GCC_INCLUDES += -I$(B)/$(LIBBACKTRACE_DIR) -I$(S)/$(LIBBACKTRACE_DIR) GCC_INCLUDES += -I$(B)/$(GMP_DIR) -I$(S)/$(GMP_DIR) GCC_INCLUDES += -I$(B)/$(MPFR_DIR)/src -I$(S)/$(MPFR_DIR)/src GCC_INCLUDES += -I$(B)/$(MPC_DIR)/src -I$(S)/$(MPC_DIR)/src +GCC_INCLUDES += -I$(S)/$(LIBCODY_DIR) # --- HOST compilation (generators) --- @@ -47,6 +51,14 @@ HOST_CXXFLAGS += $(GCC_INCLUDES) !hostcxx = | $(S)/$(GCC_DIR)/ |> \ ^ HOSTCXX %b^ $(HOSTCC) $(HOST_CXXFLAGS) -c %f -o %o |> %B.o +# gengtype uses -DHOST_GENERATOR_FILE (not -DGENERATOR_FILE) for full host header access +GENGTYPE_CXXFLAGS = -O0 -std=gnu++14 +GENGTYPE_CXXFLAGS += -DIN_GCC -DHOST_GENERATOR_FILE -DHAVE_CONFIG_H +GENGTYPE_CXXFLAGS += $(GCC_INCLUDES) + +!hostcxx-gengtype = | $(S)/$(GCC_DIR)/ |> \ + ^ HOSTCXX %b^ $(HOSTCC) $(GENGTYPE_CXXFLAGS) -c %f -o %o |> host-%B.o + # --- TARGET compilation (cc1 objects) --- TARGET_CXXFLAGS = -O2 -std=gnu++14 @@ -57,6 +69,11 @@ TARGET_CXXFLAGS += $(GCC_INCLUDES) $(S)/$(GCC_DIR)/ |> \ ^ CXX %b^ $(CXX) $(TARGET_CXXFLAGS) -c %f -o %o |> +# Like !cxx but with $(EXTRA_DEFS) for per-file -D flags +!cxx-defs = | $(S)/$(GCC_DIR)/ $(S)/$(GCC_DIR)/ \ + $(S)/$(GCC_DIR)/ |> \ + ^ CXX %b^ $(CXX) $(TARGET_CXXFLAGS) $(EXTRA_DEFS) -c %f -o %o |> + !gen-config = |> ^ GEN %o^ awk -F= \ '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ $(B)/$(GCC_DIR)/tup.config > %o |> diff --git a/examples/gcc/gcc/cp/Tupfile b/examples/gcc/gcc/cp/Tupfile new file mode 100644 index 0000000..cbfb46e --- /dev/null +++ b/examples/gcc/gcc/cp/Tupfile @@ -0,0 +1,23 @@ +include_rules + +# ============================================================ +# gcc/cp/ -- C++ language frontend (GCC 15.2.0) +# ============================================================ +# Objects contribute to ../ for the cc1plus link. +# Source list from CXX_AND_OBJCXX_OBJS + cp-lang.cc in cp/Make-lang.in. + +srcs = cp-lang.cc +srcs += call.cc class.cc constexpr.cc constraint.cc contracts.cc +srcs += coroutines.cc cp-gimplify.cc cp-objcp-common.cc cp-ubsan.cc cvt.cc +srcs += cxx-pretty-print.cc decl.cc decl2.cc dump.cc error.cc except.cc +srcs += expr.cc friend.cc init.cc lambda.cc lex.cc logic.cc mangle.cc +srcs += mapper-client.cc mapper-resolver.cc method.cc +srcs += name-lookup.cc optimize.cc parser.cc pt.cc ptree.cc +srcs += rtti.cc search.cc semantics.cc tree.cc typeck.cc typeck2.cc +srcs += vtable-class-hierarchy.cc + +: foreach $(srcs) |> !cxx |> %B.o ../ + +# module.cc needs special defines for C++ modules support +EXTRA_DEFS = -DHOST_MACHINE=\"aarch64-apple-darwin\" -DTARGET_MACHINE=\"@(TARGET)\" +: module.cc |> !cxx-defs |> module.o ../ diff --git a/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup b/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup new file mode 100644 index 0000000..2d60c1d --- /dev/null +++ b/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup @@ -0,0 +1,122 @@ +# targets/x86_64-pc-linux-gnu.tup — x86_64 Linux with glibc +# +# Target-specific configuration for the cc1 build. +# Included by gcc/Tupfile via: include targets/@(TARGET).tup +# +# Provides: +# MD — machine description inputs +# TARGET_OPT_FILES — target-specific .opt files +# target_gtyp_src — gengtype source entries for this target +# target_GT_H — gengtype output headers for this target +# Generates: +# tm.h, tm_p.h — target machine headers → +# Compiles: +# i386-common.cc — target-specific common object → + +# Machine description inputs +MD = common.md config/i386/i386.md + +# Target-specific .opt files +TARGET_OPT_FILES = config/i386/i386.opt config/fused-madd.opt config/linux.opt config/linux-android.opt + +# tm_p.h — target machine prototypes +: |> ^ GEN %o^ ( \ + echo '#ifndef GCC_TM_P_H'; \ + echo '#define GCC_TM_P_H'; \ + echo '#ifdef IN_GCC'; \ + echo '# include "config/i386/i386-protos.h"'; \ + echo '# include "config/linux-protos.h"'; \ + echo '# include "tm-preds.h"'; \ + echo '#endif'; \ + echo '#endif'; \ + ) > %o |> tm_p.h + +# tm.h — target machine description +# Matches the real configure-generated tm.h layout. +: |> ^ GEN %o^ ( \ + echo '#ifndef GCC_TM_H'; \ + echo '#define GCC_TM_H'; \ + echo '#ifndef LIBC_GLIBC'; \ + echo '# define LIBC_GLIBC 1'; \ + echo '#endif'; \ + echo '#ifndef LIBC_UCLIBC'; \ + echo '# define LIBC_UCLIBC 2'; \ + echo '#endif'; \ + echo '#ifndef LIBC_BIONIC'; \ + echo '# define LIBC_BIONIC 3'; \ + echo '#endif'; \ + echo '#ifndef LIBC_MUSL'; \ + echo '# define LIBC_MUSL 4'; \ + echo '#endif'; \ + echo '#ifndef DEFAULT_LIBC'; \ + echo '# define DEFAULT_LIBC LIBC_GLIBC'; \ + echo '#endif'; \ + echo '#ifndef ANDROID_DEFAULT'; \ + echo '# define ANDROID_DEFAULT 0'; \ + echo '#endif'; \ + echo '#ifndef HEAP_TRAMPOLINES_INIT'; \ + echo '# define HEAP_TRAMPOLINES_INIT 0'; \ + echo '#endif'; \ + echo '#ifdef IN_GCC'; \ + echo '# include "options.h"'; \ + echo '# include "insn-constants.h"'; \ + echo '# include "config/vxworks-dummy.h"'; \ + echo '# include "config/i386/biarch64.h"'; \ + echo '# include "config/i386/i386.h"'; \ + echo '# include "config/i386/unix.h"'; \ + echo '# include "config/i386/att.h"'; \ + echo '# include "config/elfos.h"'; \ + echo '# include "config/gnu-user.h"'; \ + echo '# include "config/glibc-stdint.h"'; \ + echo '# include "config/i386/x86-64.h"'; \ + echo '# include "config/i386/gnu-user-common.h"'; \ + echo '# include "config/i386/gnu-user64.h"'; \ + echo '# include "config/linux.h"'; \ + echo '# include "config/linux-android.h"'; \ + echo '# include "config/i386/linux-common.h"'; \ + echo '# include "config/i386/linux64.h"'; \ + echo '# include "config/initfini-array.h"'; \ + echo '#endif'; \ + echo '#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET'; \ + echo '# include "insn-flags.h"'; \ + echo '#endif'; \ + echo '#if defined IN_GCC && !defined GENERATOR_FILE'; \ + echo '# include "insn-modes.h"'; \ + echo '#endif'; \ + echo '# include "defaults.h"'; \ + echo '#endif'; \ + ) > %o |> tm.h + +# Target-specific gtyp_src entries (appended by main Tupfile) +target_gtyp_src = config/i386/i386.h config/i386/unix.h config/i386/att.h +target_gtyp_src += config/elfos.h config/gnu-user.h config/glibc-stdint.h +target_gtyp_src += config/i386/x86-64.h config/i386/gnu-user-common.h config/i386/gnu-user64.h +target_gtyp_src += config/linux.h config/linux-android.h config/i386/linux-common.h +target_gtyp_src += config/i386/linux64.h config/initfini-array.h +target_gtyp_src += config/i386/i386.cc +target_gtyp_src += config/i386/i386-builtins.cc config/i386/i386-expand.cc config/i386/i386-options.cc + +# Target-specific GT_H entries +target_GT_H = gt-i386.h gt-i386-builtins.h gt-i386-expand.h gt-i386-options.h + +# i386-builtin-types.inc — generated from .def via AWK +: $(SRC)/config/i386/i386-builtin-types.def |> ^ GEN %o^ \ + awk -f $(SRC)/config/i386/i386-builtin-types.awk %f > %o \ + |> i386-builtin-types.inc + +# Target-specific common object (config.gcc: i386_common_objs) +: common/config/i386/i386-common.cc |> !cxx |> i386-common.o + +# i386 backend objects (config.gcc: out_file + extra_objs + c_target_objs) +target_srcs = config/i386/i386.cc +target_srcs += config/i386/i386-c.cc config/i386/i386-options.cc +target_srcs += config/i386/i386-builtins.cc config/i386/i386-expand.cc +target_srcs += config/i386/i386-features.cc +target_srcs += config/i386/x86-tune-sched.cc config/i386/x86-tune-sched-bd.cc +target_srcs += config/i386/x86-tune-sched-atom.cc config/i386/x86-tune-sched-core.cc +target_srcs += config/i386/gnu-property.cc + +target_srcs += config/linux.cc +target_srcs += config/glibc-c.cc + +: foreach $(target_srcs) |> !cxx |> %B.o diff --git a/examples/gcc/gcc/tup.config b/examples/gcc/gcc/tup.config index 7ccb184..bfe2ff7 100644 --- a/examples/gcc/gcc/tup.config +++ b/examples/gcc/gcc/tup.config @@ -1,9 +1,10 @@ -# gcc/ - x86-64 Linux auto-host.h defines +# gcc/ - macOS (aarch64-apple-darwin) auto-host.h defines # -# These generate auto-host.h via !gen-config. -# Cross-referenced with gcc/configure.ac output for x86_64-pc-linux-gnu. +# Cross-referenced with gcc/configure.ac output for macOS host. +# Differences from Linux: no mallinfo, no posix_fallocate, no *_unlocked, +# no _GNU_SOURCE, different ld/gas features. -# Type sizes (HOST_BITS_PER_* derived from these by hwint.h) +# Type sizes (same as Linux on 64-bit) CONFIG_SIZEOF_SHORT=2 CONFIG_SIZEOF_INT=4 CONFIG_SIZEOF_LONG=8 @@ -37,24 +38,10 @@ CONFIG_HAVE_SYS_TYPES_H=1 CONFIG_HAVE_SYS_WAIT_H=1 CONFIG_HAVE_UNISTD_H=1 -# Functions +# Functions (macOS has most POSIX, but not Linux-specific ones) CONFIG_HAVE_ALLOCA=1 -CONFIG_HAVE_ATOQ=1 -CONFIG_HAVE_CLEARERR_UNLOCKED=1 CONFIG_HAVE_CLOCK=1 CONFIG_HAVE_CLOCK_GETTIME=1 -CONFIG_HAVE_FEOF_UNLOCKED=1 -CONFIG_HAVE_FERROR_UNLOCKED=1 -CONFIG_HAVE_FFLUSH_UNLOCKED=1 -CONFIG_HAVE_FGETC_UNLOCKED=1 -CONFIG_HAVE_FILENO_UNLOCKED=1 -CONFIG_HAVE_FOPEN_UNLOCKED=1 -CONFIG_HAVE_FPUTC_UNLOCKED=1 -CONFIG_HAVE_FPUTS_UNLOCKED=1 -CONFIG_HAVE_FREAD_UNLOCKED=1 -CONFIG_HAVE_FWRITE_UNLOCKED=1 -CONFIG_HAVE_GETCHAR_UNLOCKED=1 -CONFIG_HAVE_GETC_UNLOCKED=1 CONFIG_HAVE_GETRLIMIT=1 CONFIG_HAVE_GETRUSAGE=1 CONFIG_HAVE_GETTIMEOFDAY=1 @@ -62,15 +49,9 @@ CONFIG_HAVE_ICONV=1 CONFIG_HAVE_LANGINFO_CODESET=1 CONFIG_HAVE_LSTAT=1 CONFIG_HAVE_MADVISE=1 -CONFIG_HAVE_MALLINFO=1 -CONFIG_HAVE_MALLINFO2=1 CONFIG_HAVE_MMAP=1 CONFIG_HAVE_MMAP_ANON=1 -CONFIG_HAVE_MMAP_DEV_ZERO=1 CONFIG_HAVE_MMAP_FILE=1 -CONFIG_HAVE_POSIX_FALLOCATE=1 -CONFIG_HAVE_PUTCHAR_UNLOCKED=1 -CONFIG_HAVE_PUTC_UNLOCKED=1 CONFIG_HAVE_SETLOCALE=1 CONFIG_HAVE_SETRLIMIT=1 CONFIG_HAVE_SIGACTION=1 @@ -84,42 +65,65 @@ CONFIG_HAVE_WORKING_VFORK=1 # Declarations CONFIG_HAVE_DECL_ABORT=1 CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=1 -CONFIG_HAVE_DECL_CLEARERR_UNLOCKED=1 +CONFIG_HAVE_DECL_BASENAME=0 CONFIG_HAVE_DECL_ERRNO=1 -CONFIG_HAVE_DECL_FEOF_UNLOCKED=1 -CONFIG_HAVE_DECL_FERROR_UNLOCKED=1 -CONFIG_HAVE_DECL_FFLUSH_UNLOCKED=1 -CONFIG_HAVE_DECL_FGETC_UNLOCKED=1 -CONFIG_HAVE_DECL_FILENO_UNLOCKED=1 -CONFIG_HAVE_DECL_FPUTC_UNLOCKED=1 -CONFIG_HAVE_DECL_FPUTS_UNLOCKED=1 -CONFIG_HAVE_DECL_FREAD_UNLOCKED=1 -CONFIG_HAVE_DECL_FWRITE_UNLOCKED=1 -CONFIG_HAVE_DECL_GETCHAR_UNLOCKED=1 -CONFIG_HAVE_DECL_GETC_UNLOCKED=1 CONFIG_HAVE_DECL_GETENV=1 CONFIG_HAVE_DECL_GETOPT=1 CONFIG_HAVE_DECL_LDGETNAME=0 CONFIG_HAVE_DECL_MALLOC=1 -CONFIG_HAVE_DECL_PUTCHAR_UNLOCKED=1 -CONFIG_HAVE_DECL_PUTC_UNLOCKED=1 CONFIG_HAVE_DECL_REALLOC=1 -CONFIG_HAVE_DECL_SBRK=1 +CONFIG_HAVE_DECL_SBRK=0 CONFIG_HAVE_DECL_SNPRINTF=1 CONFIG_HAVE_DECL_STRSIGNAL=1 CONFIG_HAVE_DECL_VASPRINTF=1 CONFIG_HAVE_DECL_VSNPRINTF=1 +CONFIG_HAVE_DECL_STRVERSCMP=0 # Build options CONFIG_GATHER_STATISTICS=0 CONFIG_CHECKING_P=1 +CONFIG_ENABLE_ANALYZER=1 +CONFIG_ENABLE_OFFLOADING=0 +CONFIG_ENABLE_DECIMAL_FLOAT=1 +CONFIG_ENABLE_DECIMAL_BID_FORMAT=1 + +# Target toolchain +CONFIG_HAVE_GNU_AS=1 +CONFIG_HAVE_GNU_LD=1 +CONFIG_PLUGIN_LD_SUFFIX="ld" + +# Target assembler/linker features (GNU binutils for x86_64-linux) +CONFIG_HAVE_COMDAT_GROUP=1 +CONFIG_HAVE_AS_GOTOFF_IN_DATA=1 +CONFIG_HAVE_AS_IX86_GOT32X=1 +CONFIG_HAVE_AS_IX86_INTERUNIT_MOVQ=1 +CONFIG_HAVE_AS_IX86_TLSLDM=1 +CONFIG_HAVE_AS_IX86_TLSLDMPLT=1 +CONFIG_HAVE_AS_IX86_TLS_GET_ADDR_GOT=1 +CONFIG_HAVE_AS_R_X86_64_CODE_6_GOTTPOFF=0 +CONFIG_HAVE_LD_NOW_SUPPORT=1 +CONFIG_HAVE_LD_PIE_COPYRELOC=1 +CONFIG_HAVE_LD_RELRO_SUPPORT=1 +CONFIG_HAVE_GAS_SHF_MERGE=1 +CONFIG_HAVE_GAS_SECTION_LINK_ORDER=1 +CONFIG_HAVE_GNU_INDIRECT_FUNCTION=1 +CONFIG_ENABLE_FIXED_POINT=0 +CONFIG_HAVE_AS_LEB128=1 +CONFIG_HAVE_GAS_CFI_PERSONALITY_DIRECTIVE=1 +CONFIG_HAVE_GAS_CFI_SECTIONS_DIRECTIVE=1 +CONFIG_HAVE_FHARDENED_SUPPORT=0 +CONFIG_ENABLE_EXTRA_CHECKING=0 +CONFIG_HAVE_GAS_CFI_DIRECTIVE=1 +CONFIG_HAVE_LTO_PLUGIN=0 +CONFIG_CHANGES_ROOT_URL="https://gcc.gnu.org/changes.html" +CONFIG_DOCUMENTATION_ROOT_URL="https://gcc.gnu.org/onlinedocs/" + +# Target glibc version (x86_64-linux with modern glibc) +CONFIG_TARGET_GLIBC_MAJOR=2 +CONFIG_TARGET_GLIBC_MINOR=35 # Misc CONFIG_STDC_HEADERS=1 CONFIG_ENABLE_ASSERT_CHECKING=1 -CONFIG__GNU_SOURCE=1 -CONFIG_HAVE_LD_EH_FRAME_HDR=1 -CONFIG_HAVE_GAS_CFI_PERSONALITY_DIRECTIVE=1 -CONFIG_HAVE_GAS_CFI_SECTIONS_DIRECTIVE=1 -CONFIG_HAVE_GAS_HIDDEN=1 +CONFIG_DIAGNOSTICS_COLOR_DEFAULT=DIAGNOSTICS_COLOR_AUTO +CONFIG_DIAGNOSTICS_URLS_DEFAULT=DIAGNOSTICS_URL_AUTO diff --git a/examples/gcc/gmp/Tupfile b/examples/gcc/gmp/Tupfile index c99d077..110756b 100644 --- a/examples/gcc/gmp/Tupfile +++ b/examples/gcc/gmp/Tupfile @@ -61,6 +61,10 @@ srcs += tal-reent.c : foreach $(srcs) |> !cc |> %B.o # --- Phase 5: Archive all GMP objects into libgmp.a --- -# All subdirectories contribute objects to via ../. +# Use shell glob to collect objects from all subdirectories. +# Order-only deps on subdirectory groups ensure correct build order. -: |> ^ AR %o^ $(AR) rcs %o % |> libgmp.a $(S)/ +: | mpn/ mpz/ mpq/ mpf/ \ + printf/ scanf/ rand/ |> \ + ^ AR %o^ sh -c '$(AR) rcs %o % $(TUP_VARIANT_OUTPUTDIR)/mpn/*.o $(TUP_VARIANT_OUTPUTDIR)/mpz/*.o $(TUP_VARIANT_OUTPUTDIR)/mpq/*.o $(TUP_VARIANT_OUTPUTDIR)/mpf/*.o $(TUP_VARIANT_OUTPUTDIR)/printf/*.o $(TUP_VARIANT_OUTPUTDIR)/scanf/*.o $(TUP_VARIANT_OUTPUTDIR)/rand/*.o' \ + |> libgmp.a $(S)/ diff --git a/examples/gcc/gmp/mpf/Tupfile b/examples/gcc/gmp/mpf/Tupfile index bf8bb49..5936c8e 100644 --- a/examples/gcc/gmp/mpf/Tupfile +++ b/examples/gcc/gmp/mpf/Tupfile @@ -17,4 +17,4 @@ srcs += set_q.c set_si.c set_str.c set_ui.c set_z.c srcs += size.c sqrt.c sqrt_ui.c sub.c sub_ui.c swap.c trunc.c srcs += ui_div.c ui_sub.c urandomb.c -: foreach $(srcs) |> !cc |> %B.o ../ +: foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/gmp/mpn/Tupfile b/examples/gcc/gmp/mpn/Tupfile index 27ab8bc..a5f0d83 100644 --- a/examples/gcc/gmp/mpn/Tupfile +++ b/examples/gcc/gmp/mpn/Tupfile @@ -9,12 +9,12 @@ include_rules # --- Bang macros --- -!cc-op = | $(S)/$(GMP_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -DOPERATION_%B -c %f -o %o |> %B.o ../ +!cc-op = | $(S)/$(GMP_DIR)/ |> ^ CC %b^ $(CC) $(CFLAGS) -DOPERATION_%B -c %f -o %o |> %B.o # --- Bulk sources (foreach over config lists) --- : foreach @(C_SOURCES) |> !cc-op |> -: foreach @(ASM_SOURCES) |> !m4asm |> %B.o ../ +: foreach @(ASM_SOURCES) |> !m4asm |> %B.o # ===================================================================== # Multi-function assembly (foo-y pattern) @@ -32,12 +32,12 @@ aors_sub_n-@(ASM_sub_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_n.asm : foreach $(aors_add_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_n^ \ m4 -DPIC -DOPERATION_add_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> add_n.o ../ + | $(CC) -c -x assembler - -o %o |> add_n.o : foreach $(aors_sub_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_n^ \ m4 -DPIC -DOPERATION_sub_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> sub_n.o ../ + | $(CC) -c -x assembler - -o %o |> sub_n.o # aorsmul_1.asm → addmul_1, submul_1 aorsmul_addmul_1-@(ASM_addmul_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/aorsmul_1.asm @@ -46,12 +46,12 @@ aorsmul_submul_1-@(ASM_submul_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/aorsmul_1.asm : foreach $(aorsmul_addmul_1-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM addmul_1^ \ m4 -DPIC -DOPERATION_addmul_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> addmul_1.o ../ + | $(CC) -c -x assembler - -o %o |> addmul_1.o : foreach $(aorsmul_submul_1-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM submul_1^ \ m4 -DPIC -DOPERATION_submul_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> submul_1.o ../ + | $(CC) -c -x assembler - -o %o |> submul_1.o # aors_err1_n.asm → add_err1_n, sub_err1_n aors_err1_add-@(ASM_add_err1_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err1_n.asm @@ -60,12 +60,12 @@ aors_err1_sub-@(ASM_sub_err1_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err1_n.asm : foreach $(aors_err1_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_err1_n^ \ m4 -DPIC -DOPERATION_add_err1_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> add_err1_n.o ../ + | $(CC) -c -x assembler - -o %o |> add_err1_n.o : foreach $(aors_err1_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_err1_n^ \ m4 -DPIC -DOPERATION_sub_err1_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> sub_err1_n.o ../ + | $(CC) -c -x assembler - -o %o |> sub_err1_n.o # aors_err2_n.asm → add_err2_n, sub_err2_n aors_err2_add-@(ASM_add_err2_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err2_n.asm @@ -74,12 +74,12 @@ aors_err2_sub-@(ASM_sub_err2_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err2_n.asm : foreach $(aors_err2_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_err2_n^ \ m4 -DPIC -DOPERATION_add_err2_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> add_err2_n.o ../ + | $(CC) -c -x assembler - -o %o |> add_err2_n.o : foreach $(aors_err2_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_err2_n^ \ m4 -DPIC -DOPERATION_sub_err2_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> sub_err2_n.o ../ + | $(CC) -c -x assembler - -o %o |> sub_err2_n.o # aors_err3_n.asm → add_err3_n, sub_err3_n aors_err3_add-@(ASM_add_err3_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err3_n.asm @@ -88,12 +88,12 @@ aors_err3_sub-@(ASM_sub_err3_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/aors_err3_n.asm : foreach $(aors_err3_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM add_err3_n^ \ m4 -DPIC -DOPERATION_add_err3_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> add_err3_n.o ../ + | $(CC) -c -x assembler - -o %o |> add_err3_n.o : foreach $(aors_err3_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sub_err3_n^ \ m4 -DPIC -DOPERATION_sub_err3_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> sub_err3_n.o ../ + | $(CC) -c -x assembler - -o %o |> sub_err3_n.o # logops_n.asm → and_n, andn_n, ior_n, iorn_n, nand_n, nior_n, xnor_n, xor_n logops_asm_and_n-@(ASM_and_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm @@ -108,42 +108,42 @@ logops_asm_xor_n-@(ASM_xor_n) = @(MPN_ARCH)/@(MPN_SUBDIR)/logops_n.asm : foreach $(logops_asm_and_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM and_n^ \ m4 -DPIC -DOPERATION_and_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> and_n.o ../ + | $(CC) -c -x assembler - -o %o |> and_n.o : foreach $(logops_asm_andn_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM andn_n^ \ m4 -DPIC -DOPERATION_andn_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> andn_n.o ../ + | $(CC) -c -x assembler - -o %o |> andn_n.o : foreach $(logops_asm_ior_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM ior_n^ \ m4 -DPIC -DOPERATION_ior_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> ior_n.o ../ + | $(CC) -c -x assembler - -o %o |> ior_n.o : foreach $(logops_asm_iorn_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM iorn_n^ \ m4 -DPIC -DOPERATION_iorn_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> iorn_n.o ../ + | $(CC) -c -x assembler - -o %o |> iorn_n.o : foreach $(logops_asm_nand_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM nand_n^ \ m4 -DPIC -DOPERATION_nand_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> nand_n.o ../ + | $(CC) -c -x assembler - -o %o |> nand_n.o : foreach $(logops_asm_nior_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM nior_n^ \ m4 -DPIC -DOPERATION_nior_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> nior_n.o ../ + | $(CC) -c -x assembler - -o %o |> nior_n.o : foreach $(logops_asm_xnor_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM xnor_n^ \ m4 -DPIC -DOPERATION_xnor_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> xnor_n.o ../ + | $(CC) -c -x assembler - -o %o |> xnor_n.o : foreach $(logops_asm_xor_n-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM xor_n^ \ m4 -DPIC -DOPERATION_xor_n -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> xor_n.o ../ + | $(CC) -c -x assembler - -o %o |> xor_n.o # popham.asm → popcount, hamdist popham_asm_popcount-@(ASM_popcount) = @(MPN_ARCH)/@(MPN_SUBDIR)/popham.asm @@ -152,12 +152,12 @@ popham_asm_hamdist-@(ASM_hamdist) = @(MPN_ARCH)/@(MPN_SUBDIR)/popham.asm : foreach $(popham_asm_popcount-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM popcount^ \ m4 -DPIC -DOPERATION_popcount -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> popcount.o ../ + | $(CC) -c -x assembler - -o %o |> popcount.o : foreach $(popham_asm_hamdist-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM hamdist^ \ m4 -DPIC -DOPERATION_hamdist -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> hamdist.o ../ + | $(CC) -c -x assembler - -o %o |> hamdist.o # sec_aors_1.asm → sec_add_1, sec_sub_1 sec_aors_1_asm_add-@(ASM_sec_add_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/sec_aors_1.asm @@ -166,12 +166,12 @@ sec_aors_1_asm_sub-@(ASM_sec_sub_1) = @(MPN_ARCH)/@(MPN_SUBDIR)/sec_aors_1.asm : foreach $(sec_aors_1_asm_add-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sec_add_1^ \ m4 -DPIC -DOPERATION_sec_add_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> sec_add_1.o ../ + | $(CC) -c -x assembler - -o %o |> sec_add_1.o : foreach $(sec_aors_1_asm_sub-y) | $(S)/$(GMP_DIR)/ |> ^ M4ASM sec_sub_1^ \ m4 -DPIC -DOPERATION_sec_sub_1 -I$(S)/$(GMP_DIR)/mpn -I$(S)/$(GMP_DIR)/mpn/@(MPN_ARCH) \ $(B)/$(GMP_DIR)/config.m4 $(S)/$(GMP_DIR)/mpn/asm-defs.m4 %f \ - | $(CC) -c -x assembler - -o %o |> sec_sub_1.o ../ + | $(CC) -c -x assembler - -o %o |> sec_sub_1.o # ===================================================================== # Template C rules (foo-y pattern) @@ -191,42 +191,42 @@ logops_nior_n-@(C_nior_n) = generic/logops_n.c logops_xnor_n-@(C_xnor_n) = generic/logops_n.c logops_xor_n-@(C_xor_n) = generic/logops_n.c -: foreach $(logops_and_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC and_n^ $(CC) $(CFLAGS) -DOPERATION_and_n -c %f -o %o |> and_n.o ../ -: foreach $(logops_andn_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC andn_n^ $(CC) $(CFLAGS) -DOPERATION_andn_n -c %f -o %o |> andn_n.o ../ -: foreach $(logops_ior_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC ior_n^ $(CC) $(CFLAGS) -DOPERATION_ior_n -c %f -o %o |> ior_n.o ../ -: foreach $(logops_iorn_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC iorn_n^ $(CC) $(CFLAGS) -DOPERATION_iorn_n -c %f -o %o |> iorn_n.o ../ -: foreach $(logops_nand_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC nand_n^ $(CC) $(CFLAGS) -DOPERATION_nand_n -c %f -o %o |> nand_n.o ../ -: foreach $(logops_nior_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC nior_n^ $(CC) $(CFLAGS) -DOPERATION_nior_n -c %f -o %o |> nior_n.o ../ -: foreach $(logops_xnor_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC xnor_n^ $(CC) $(CFLAGS) -DOPERATION_xnor_n -c %f -o %o |> xnor_n.o ../ -: foreach $(logops_xor_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC xor_n^ $(CC) $(CFLAGS) -DOPERATION_xor_n -c %f -o %o |> xor_n.o ../ +: foreach $(logops_and_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC and_n^ $(CC) $(CFLAGS) -DOPERATION_and_n -c %f -o %o |> and_n.o +: foreach $(logops_andn_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC andn_n^ $(CC) $(CFLAGS) -DOPERATION_andn_n -c %f -o %o |> andn_n.o +: foreach $(logops_ior_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC ior_n^ $(CC) $(CFLAGS) -DOPERATION_ior_n -c %f -o %o |> ior_n.o +: foreach $(logops_iorn_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC iorn_n^ $(CC) $(CFLAGS) -DOPERATION_iorn_n -c %f -o %o |> iorn_n.o +: foreach $(logops_nand_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC nand_n^ $(CC) $(CFLAGS) -DOPERATION_nand_n -c %f -o %o |> nand_n.o +: foreach $(logops_nior_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC nior_n^ $(CC) $(CFLAGS) -DOPERATION_nior_n -c %f -o %o |> nior_n.o +: foreach $(logops_xnor_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC xnor_n^ $(CC) $(CFLAGS) -DOPERATION_xnor_n -c %f -o %o |> xnor_n.o +: foreach $(logops_xor_n-y) | $(S)/$(GMP_DIR)/ |> ^ CC xor_n^ $(CC) $(CFLAGS) -DOPERATION_xor_n -c %f -o %o |> xor_n.o # popham.c → popcount, hamdist popham_popcount-@(C_popcount) = generic/popham.c popham_hamdist-@(C_hamdist) = generic/popham.c -: foreach $(popham_popcount-y) | $(S)/$(GMP_DIR)/ |> ^ CC popcount^ $(CC) $(CFLAGS) -DOPERATION_popcount -c %f -o %o |> popcount.o ../ -: foreach $(popham_hamdist-y) | $(S)/$(GMP_DIR)/ |> ^ CC hamdist^ $(CC) $(CFLAGS) -DOPERATION_hamdist -c %f -o %o |> hamdist.o ../ +: foreach $(popham_popcount-y) | $(S)/$(GMP_DIR)/ |> ^ CC popcount^ $(CC) $(CFLAGS) -DOPERATION_popcount -c %f -o %o |> popcount.o +: foreach $(popham_hamdist-y) | $(S)/$(GMP_DIR)/ |> ^ CC hamdist^ $(CC) $(CFLAGS) -DOPERATION_hamdist -c %f -o %o |> hamdist.o # sec_aors_1.c → sec_add_1, sec_sub_1 sec_aors_1_add-@(C_sec_add_1) = generic/sec_aors_1.c sec_aors_1_sub-@(C_sec_sub_1) = generic/sec_aors_1.c -: foreach $(sec_aors_1_add-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_add_1^ $(CC) $(CFLAGS) -DOPERATION_sec_add_1 -c %f -o %o |> sec_add_1.o ../ -: foreach $(sec_aors_1_sub-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_sub_1^ $(CC) $(CFLAGS) -DOPERATION_sec_sub_1 -c %f -o %o |> sec_sub_1.o ../ +: foreach $(sec_aors_1_add-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_add_1^ $(CC) $(CFLAGS) -DOPERATION_sec_add_1 -c %f -o %o |> sec_add_1.o +: foreach $(sec_aors_1_sub-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_sub_1^ $(CC) $(CFLAGS) -DOPERATION_sec_sub_1 -c %f -o %o |> sec_sub_1.o # sec_div.c → sec_div_qr, sec_div_r (always C, no asm variant) sec_div_qr-@(C_sec_div_qr) = generic/sec_div.c sec_div_r-@(C_sec_div_r) = generic/sec_div.c -: foreach $(sec_div_qr-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_div_qr^ $(CC) $(CFLAGS) -DOPERATION_sec_div_qr -c %f -o %o |> sec_div_qr.o ../ -: foreach $(sec_div_r-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_div_r^ $(CC) $(CFLAGS) -DOPERATION_sec_div_r -c %f -o %o |> sec_div_r.o ../ +: foreach $(sec_div_qr-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_div_qr^ $(CC) $(CFLAGS) -DOPERATION_sec_div_qr -c %f -o %o |> sec_div_qr.o +: foreach $(sec_div_r-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_div_r^ $(CC) $(CFLAGS) -DOPERATION_sec_div_r -c %f -o %o |> sec_div_r.o # sec_pi1_div.c → sec_pi1_div_qr, sec_pi1_div_r (always C, no asm variant) sec_pi1_div_qr-@(C_sec_pi1_div_qr) = generic/sec_pi1_div.c sec_pi1_div_r-@(C_sec_pi1_div_r) = generic/sec_pi1_div.c -: foreach $(sec_pi1_div_qr-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_pi1_div_qr^ $(CC) $(CFLAGS) -DOPERATION_sec_pi1_div_qr -c %f -o %o |> sec_pi1_div_qr.o ../ -: foreach $(sec_pi1_div_r-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_pi1_div_r^ $(CC) $(CFLAGS) -DOPERATION_sec_pi1_div_r -c %f -o %o |> sec_pi1_div_r.o ../ +: foreach $(sec_pi1_div_qr-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_pi1_div_qr^ $(CC) $(CFLAGS) -DOPERATION_sec_pi1_div_qr -c %f -o %o |> sec_pi1_div_qr.o +: foreach $(sec_pi1_div_r-y) | $(S)/$(GMP_DIR)/ |> ^ CC sec_pi1_div_r^ $(CC) $(CFLAGS) -DOPERATION_sec_pi1_div_r -c %f -o %o |> sec_pi1_div_r.o # --- Generated table sources (produced by gmp/Tupfile generators) --- : foreach fib_table.c mp_bases.c |> !cc-op |> diff --git a/examples/gcc/gmp/mpn/tup.config b/examples/gcc/gmp/mpn/tup.config index a42fbad..834183c 100644 --- a/examples/gcc/gmp/mpn/tup.config +++ b/examples/gcc/gmp/mpn/tup.config @@ -1,6 +1,6 @@ CONFIG_MPN_ARCH=generic CONFIG_MPN_SUBDIR=generic -CONFIG_C_SOURCES=generic/add.c generic/add_1.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/add_n.c generic/add_n_sub_n.c generic/addmul_1.c generic/bdiv_dbm1c.c generic/bdiv_q.c generic/bdiv_q_1.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/com.c generic/comb_tables.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dcpi1_divappr_q.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/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/divrem.c generic/divrem_1.c generic/divrem_2.c generic/dump.c generic/fib2_ui.c generic/fib2m.c generic/gcd.c generic/gcd_1.c generic/gcd_11.c generic/gcd_22.c generic/gcd_subdiv_step.c generic/gcdext.c generic/gcdext_1.c generic/gcdext_lehmer.c generic/get_d.c generic/get_str.c generic/hgcd.c generic/hgcd2.c generic/hgcd2_jacobi.c generic/hgcd_appr.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/invert.c generic/invertappr.c generic/jacbase.c generic/jacobi.c generic/jacobi_2.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul.c generic/matrix22_mul1_inverse_vector.c generic/mod_1.c generic/mod_1_1.c generic/mod_1_2.c generic/mod_1_3.c generic/mod_1_4.c generic/mod_34lsub1.c generic/mode1o.c generic/mu_bdiv_q.c generic/mu_bdiv_qr.c generic/mu_div_q.c generic/mu_div_qr.c generic/mu_divappr_q.c generic/mul.c generic/mul_1.c generic/mul_basecase.c generic/mul_fft.c generic/mul_n.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid.c generic/mulmid_basecase.c generic/mulmid_n.c generic/mulmod_bnm1.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/random.c generic/random2.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_div_q.c generic/sbpi1_div_qr.c generic/sbpi1_divappr_q.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.c generic/sqr_basecase.c generic/sqrlo.c generic/sqrlo_basecase.c generic/sqrmod_bnm1.c generic/sqrtrem.c generic/strongfibo.c generic/sub.c generic/sub_1.c generic/sub_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/sub_n.c generic/submul_1.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/toom6_sqr.c generic/toom6h_mul.c generic/toom8_sqr.c generic/toom8h_mul.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_C_SOURCES=generic/add_1.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/add_n_sub_n.c generic/add_n.c generic/add.c generic/addmul_1.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/com.c generic/comb_tables.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dcpi1_divappr_q.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/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/divrem_1.c generic/divrem_2.c generic/divrem.c generic/dump.c generic/fib2_ui.c generic/fib2m.c generic/gcd_1.c generic/gcd_11.c generic/gcd_22.c generic/gcd_subdiv_step.c generic/gcd.c generic/gcdext_1.c generic/gcdext_lehmer.c generic/gcdext.c generic/get_d.c generic/get_str.c generic/hgcd_appr.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/hgcd.c generic/hgcd2_jacobi.c generic/hgcd2.c generic/invert.c generic/invertappr.c generic/jacbase.c generic/jacobi_2.c generic/jacobi.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul.c generic/matrix22_mul1_inverse_vector.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_div_q.c generic/mu_div_qr.c generic/mu_divappr_q.c generic/mul_1.c generic/mul_basecase.c generic/mul_fft.c generic/mul_n.c generic/mul.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid_basecase.c generic/mulmid_n.c generic/mulmid.c generic/mulmod_bnm1.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/random.c generic/random2.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_div_q.c generic/sbpi1_div_qr.c generic/sbpi1_divappr_q.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_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/sub_n.c generic/sub.c generic/submul_1.c generic/tdiv_qr.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/toom2_sqr.c generic/toom22_mul.c generic/toom3_sqr.c generic/toom32_mul.c generic/toom33_mul.c generic/toom4_sqr.c generic/toom42_mul.c generic/toom42_mulmid.c generic/toom43_mul.c generic/toom44_mul.c generic/toom52_mul.c generic/toom53_mul.c generic/toom54_mul.c generic/toom6_sqr.c generic/toom62_mul.c generic/toom63_mul.c generic/toom6h_mul.c generic/toom8_sqr.c generic/toom8h_mul.c generic/trialdiv.c generic/zero_p.c generic/zero.c CONFIG_ASM_SOURCES= CONFIG_C_and_n=y CONFIG_C_andn_n=y diff --git a/examples/gcc/gmp/mpq/Tupfile b/examples/gcc/gmp/mpq/Tupfile index 49727d9..8fd3c7b 100644 --- a/examples/gcc/gmp/mpq/Tupfile +++ b/examples/gcc/gmp/mpq/Tupfile @@ -9,4 +9,4 @@ srcs += init.c inits.c inp_str.c inv.c md_2exp.c mul.c neg.c out_str.c srcs += set.c set_d.c set_den.c set_f.c set_num.c srcs += set_si.c set_str.c set_ui.c set_z.c swap.c -: foreach $(srcs) |> !cc |> %B.o ../ +: foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/gmp/mpz/Tupfile b/examples/gcc/gmp/mpz/Tupfile index 6a22fe3..9bf276c 100644 --- a/examples/gcc/gmp/mpz/Tupfile +++ b/examples/gcc/gmp/mpz/Tupfile @@ -42,4 +42,4 @@ srcs += tdiv_qr.c tdiv_qr_ui.c srcs += tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tdiv_ui.c srcs += tstbit.c ui_pow_ui.c ui_sub.c urandomb.c urandomm.c xor.c -: foreach $(srcs) |> !cc |> %B.o ../ +: foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/gmp/printf/Tupfile b/examples/gcc/gmp/printf/Tupfile index 00802c9..ada4013 100644 --- a/examples/gcc/gmp/printf/Tupfile +++ b/examples/gcc/gmp/printf/Tupfile @@ -8,4 +8,4 @@ srcs += printf.c printffuns.c repl-vsnprintf.c srcs += snprintf.c snprntffuns.c sprintf.c sprintffuns.c srcs += vasprintf.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c -: foreach $(srcs) |> !cc |> %B.o ../ +: foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/gmp/rand/Tupfile b/examples/gcc/gmp/rand/Tupfile index 7f4e91c..e508739 100644 --- a/examples/gcc/gmp/rand/Tupfile +++ b/examples/gcc/gmp/rand/Tupfile @@ -6,4 +6,4 @@ srcs = rand.c randbui.c randclr.c randdef.c randiset.c srcs += randlc2s.c randlc2x.c randmt.c randmts.c randmui.c srcs += rands.c randsd.c randsdui.c -: foreach $(srcs) |> !cc |> %B.o ../ +: foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/gmp/scanf/Tupfile b/examples/gcc/gmp/scanf/Tupfile index 1708638..eb6ec36 100644 --- a/examples/gcc/gmp/scanf/Tupfile +++ b/examples/gcc/gmp/scanf/Tupfile @@ -5,4 +5,4 @@ include_rules srcs = doscan.c fscanf.c fscanffuns.c scanf.c sscanf.c sscanffuns.c srcs += vfscanf.c vscanf.c vsscanf.c -: foreach $(srcs) |> !cc |> %B.o ../ +: foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/gmp/tup.config b/examples/gcc/gmp/tup.config index 22334ea..a280c8c 100644 --- a/examples/gcc/gmp/tup.config +++ b/examples/gcc/gmp/tup.config @@ -1,14 +1,13 @@ -# GMP 6.2.1 - x86-64 Linux config.h defines +# GMP 6.2.1 - macOS (aarch64-apple-darwin) config.h defines # -# Prefix-free: scoped config merging namespaces these under gmp/. -# @(HAVE_ALLOCA) in gmp/ resolves from this file. -# @(CC) in gmp/ resolves from the root tup.config. +# 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: "generic" for pure C, or a CPU path like "x86_64" or "x86_64/core2" +# MPN CPU target CONFIG_MPN_CPU=generic # Feature detection @@ -35,8 +34,6 @@ CONFIG_HAVE_FLOAT_H=1 CONFIG_HAVE_GETPAGESIZE=1 CONFIG_HAVE_GETRUSAGE=1 CONFIG_HAVE_GETTIMEOFDAY=1 -CONFIG_HAVE_HIDDEN_ALIAS=1 -CONFIG_HAVE_HOST_CPU_FAMILY_x86_64=1 CONFIG_HAVE_INTMAX_T=1 CONFIG_HAVE_INTPTR_T=1 CONFIG_HAVE_INTTYPES_H=1 @@ -52,15 +49,12 @@ CONFIG_HAVE_MMAP=1 CONFIG_HAVE_MPROTECT=1 CONFIG_HAVE_NL_LANGINFO=1 CONFIG_HAVE_NL_TYPES_H=1 -CONFIG_HAVE_OBSTACK_VPRINTF=1 CONFIG_HAVE_POPEN=1 CONFIG_HAVE_PTRDIFF_T=1 -CONFIG_HAVE_QUAD_T=1 CONFIG_HAVE_RAISE=1 CONFIG_HAVE_SIGACTION=1 CONFIG_HAVE_SIGALTSTACK=1 CONFIG_HAVE_SIGNAL_H=1 -CONFIG_HAVE_SIGSTACK=1 CONFIG_HAVE_STACK_T=1 CONFIG_HAVE_STDINT_H=1 CONFIG_HAVE_STDLIB_H=1 @@ -76,7 +70,6 @@ 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_SYSINFO_H=1 CONFIG_HAVE_SYS_TIME_H=1 CONFIG_HAVE_SYS_TIMES_H=1 CONFIG_HAVE_SYS_TYPES_H=1 @@ -84,7 +77,7 @@ CONFIG_HAVE_TIMES=1 CONFIG_HAVE_UINT_LEAST32_T=1 CONFIG_HAVE_UNISTD_H=1 CONFIG_HAVE_VSNPRINTF=1 -CONFIG_LSYM_PREFIX="" +CONFIG_LSYM_PREFIX="_" CONFIG_RETSIGTYPE=void CONFIG_SIZEOF_UNSIGNED=4 CONFIG_SIZEOF_UNSIGNED_SHORT=2 diff --git a/examples/gcc/libbacktrace/Tupfile b/examples/gcc/libbacktrace/Tupfile index f5860bf..2a4e143 100644 --- a/examples/gcc/libbacktrace/Tupfile +++ b/examples/gcc/libbacktrace/Tupfile @@ -16,11 +16,11 @@ include_rules %f > %o |> backtrace-supported.h # --- Phase 2: Compile sources --- -# Linux-specific selection: ELF + mmapio + unwind-based backtrace. +# Format selection: @(BACKTRACE_FORMAT) = elf (Linux) or macho (macOS) srcs = atomic.c dwarf.c fileline.c srcs += mmapio.c mmap.c posix.c print.c sort.c state.c -srcs += elf.c backtrace.c simple.c +srcs += @(BACKTRACE_FORMAT).c backtrace.c simple.c : foreach $(srcs) |> !cc |> %B.o diff --git a/examples/gcc/libbacktrace/tup.config b/examples/gcc/libbacktrace/tup.config index b57c64c..645b8cb 100644 --- a/examples/gcc/libbacktrace/tup.config +++ b/examples/gcc/libbacktrace/tup.config @@ -1,9 +1,10 @@ -# libbacktrace - x86-64 Linux config.h defines +# libbacktrace - macOS (aarch64-apple-darwin) config.h defines # -# Cross-referenced with libbacktrace/config.h.in from GCC 15.2.0. +# Key differences from Linux: Mach-O format (not ELF), no dl_iterate_phdr, +# no link.h, no _GNU_SOURCE. -# ELF 64-bit (x86-64 Linux) -CONFIG_BACKTRACE_ELF_SIZE=64 +# Object format: macho (macOS) instead of elf (Linux) +CONFIG_BACKTRACE_FORMAT=macho # Atomics CONFIG_HAVE_ATOMIC_FUNCTIONS=1 @@ -23,7 +24,6 @@ CONFIG_HAVE_DECL__PGMPTR=0 # Headers CONFIG_HAVE_DLFCN_H=1 CONFIG_HAVE_INTTYPES_H=1 -CONFIG_HAVE_LINK_H=1 CONFIG_HAVE_MEMORY_H=1 CONFIG_HAVE_STDINT_H=1 CONFIG_HAVE_STDLIB_H=1 @@ -34,10 +34,6 @@ CONFIG_HAVE_SYS_STAT_H=1 CONFIG_HAVE_SYS_TYPES_H=1 CONFIG_HAVE_UNISTD_H=1 -# Linux-specific -CONFIG_HAVE_DL_ITERATE_PHDR=1 -CONFIG_HAVE_GETIPINFO=1 - # Compression (optional, can link -lz) CONFIG_HAVE_ZLIB=1 @@ -50,4 +46,3 @@ CONFIG_SIZEOF_VOID_P=8 # Misc CONFIG_STDC_HEADERS=1 -CONFIG__GNU_SOURCE=1 diff --git a/examples/gcc/libcody/Tupfile b/examples/gcc/libcody/Tupfile new file mode 100644 index 0000000..68488f0 --- /dev/null +++ b/examples/gcc/libcody/Tupfile @@ -0,0 +1,21 @@ +include_rules + +# ============================================================ +# libcody - C++ modules protocol library +# ============================================================ + +# --- Phase 1: Generate config.h --- + +: |> !gen-config |> config.h + +# --- Phase 2: Compile sources --- + +srcs = buffer.cc client.cc fatal.cc +srcs += netclient.cc netserver.cc packet.cc +srcs += resolver.cc server.cc + +: foreach $(srcs) |> !cxx |> %B.o + +# --- Phase 3: Archive --- + +: |> ^ AR %o^ $(AR) rcs %o % |> libcody.a $(S)/ diff --git a/examples/gcc/libcody/Tuprules.tup b/examples/gcc/libcody/Tuprules.tup new file mode 100644 index 0000000..a175d26 --- /dev/null +++ b/examples/gcc/libcody/Tuprules.tup @@ -0,0 +1,18 @@ +# libcody build rules (self-contained with ?= defaults) + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CXX ?= g++ +AR ?= ar +LIBCODY_DIR ?= . + +CXXFLAGS = -O2 -std=gnu++14 -fno-exceptions +CXXFLAGS += -include $(B)/$(LIBCODY_DIR)/config.h +CXXFLAGS += -I$(S)/$(LIBCODY_DIR) +CXXFLAGS += -DSRCDIR=\"\" + +!cxx = | $(S)/$(LIBCODY_DIR)/ |> ^ CXX %b^ $(CXX) $(CXXFLAGS) -c %f -o %o |> %B.o + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/$(LIBCODY_DIR)/tup.config > %o |> diff --git a/examples/gcc/libcody/tup.config b/examples/gcc/libcody/tup.config new file mode 100644 index 0000000..b4578e4 --- /dev/null +++ b/examples/gcc/libcody/tup.config @@ -0,0 +1,11 @@ +# libcody - C++ modules protocol library (minimal config) +# +# libcody's config.h.in defines _GNU_SOURCE unconditionally. +# No other significant configure-time detection needed. + +CONFIG_PACKAGE_NAME="libcody" +CONFIG_PACKAGE_VERSION="0.1" +CONFIG_PACKAGE_STRING="libcody 0.1" +CONFIG_PACKAGE_BUGREPORT="" +CONFIG_PACKAGE_TARNAME="libcody" +CONFIG_PACKAGE_URL="" diff --git a/examples/gcc/libcpp/tup.config b/examples/gcc/libcpp/tup.config index 68842b8..771437b 100644 --- a/examples/gcc/libcpp/tup.config +++ b/examples/gcc/libcpp/tup.config @@ -1,6 +1,6 @@ -# libcpp - x86-64 Linux config.h defines +# libcpp - macOS (aarch64-apple-darwin) config.h defines # -# Cross-referenced with libcpp/config.in from GCC 15.2.0. +# Key differences from Linux: no *_unlocked functions (glibc-specific). # Build options CONFIG_ENABLE_CANONICAL_SYSTEM_HEADERS=1 @@ -22,56 +22,26 @@ CONFIG_HAVE_SYS_STAT_H=1 CONFIG_HAVE_SYS_TYPES_H=1 CONFIG_HAVE_UNISTD_H=1 -# Functions +# Functions (macOS lacks glibc *_unlocked variants) CONFIG_HAVE_ALLOCA=1 -CONFIG_HAVE_CLEARERR_UNLOCKED=1 -CONFIG_HAVE_FEOF_UNLOCKED=1 -CONFIG_HAVE_FERROR_UNLOCKED=1 -CONFIG_HAVE_FFLUSH_UNLOCKED=1 -CONFIG_HAVE_FGETC_UNLOCKED=1 -CONFIG_HAVE_FGETS_UNLOCKED=1 -CONFIG_HAVE_FILENO_UNLOCKED=1 -CONFIG_HAVE_FPUTC_UNLOCKED=1 -CONFIG_HAVE_FPUTS_UNLOCKED=1 -CONFIG_HAVE_FREAD_UNLOCKED=1 -CONFIG_HAVE_FWRITE_UNLOCKED=1 -CONFIG_HAVE_GETCHAR_UNLOCKED=1 -CONFIG_HAVE_GETC_UNLOCKED=1 CONFIG_HAVE_ICONV=1 CONFIG_HAVE_LANGINFO_CODESET=1 -CONFIG_HAVE_PUTCHAR_UNLOCKED=1 -CONFIG_HAVE_PUTC_UNLOCKED=1 CONFIG_HAVE_SETLOCALE=1 # Declarations CONFIG_HAVE_DECL_ABORT=1 CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=1 -CONFIG_HAVE_DECL_CLEARERR_UNLOCKED=1 +CONFIG_HAVE_DECL_BASENAME=0 CONFIG_HAVE_DECL_ERRNO=1 -CONFIG_HAVE_DECL_FEOF_UNLOCKED=1 -CONFIG_HAVE_DECL_FERROR_UNLOCKED=1 -CONFIG_HAVE_DECL_FFLUSH_UNLOCKED=1 -CONFIG_HAVE_DECL_FGETC_UNLOCKED=1 -CONFIG_HAVE_DECL_FGETS_UNLOCKED=1 -CONFIG_HAVE_DECL_FILENO_UNLOCKED=1 CONFIG_HAVE_DECL_FPRINTF_UNLOCKED=0 -CONFIG_HAVE_DECL_FPUTC_UNLOCKED=1 -CONFIG_HAVE_DECL_FPUTS_UNLOCKED=1 -CONFIG_HAVE_DECL_FREAD_UNLOCKED=1 -CONFIG_HAVE_DECL_FWRITE_UNLOCKED=1 -CONFIG_HAVE_DECL_GETCHAR_UNLOCKED=1 -CONFIG_HAVE_DECL_GETC_UNLOCKED=1 CONFIG_HAVE_DECL_GETOPT=1 -CONFIG_HAVE_DECL_PUTCHAR_UNLOCKED=1 -CONFIG_HAVE_DECL_PUTC_UNLOCKED=1 CONFIG_HAVE_DECL_VASPRINTF=1 # Types CONFIG_HAVE_UINTPTR_T=1 # Sizes -CONFIG_SIZEOF_DEV_T=8 +CONFIG_SIZEOF_DEV_T=4 CONFIG_SIZEOF_INO_T=8 CONFIG_SIZEOF_INT=4 CONFIG_SIZEOF_LONG=8 @@ -85,11 +55,10 @@ CONFIG_PACKAGE_TARNAME="cpplib" CONFIG_PACKAGE_URL="" CONFIG_PACKAGE_VERSION="0" -# iconv (glibc takes non-const; define as empty) +# iconv (macOS libc uses char**, same as glibc — ICONV_CONST is empty) CONFIG_ICONV_CONST= # Misc CONFIG_STDC_HEADERS=1 CONFIG_STRING_WITH_STRINGS=1 CONFIG_TIME_WITH_SYS_TIME=1 -CONFIG__GNU_SOURCE=1 diff --git a/examples/gcc/libdecnumber/tup.config b/examples/gcc/libdecnumber/tup.config index 45c270d..de25363 100644 --- a/examples/gcc/libdecnumber/tup.config +++ b/examples/gcc/libdecnumber/tup.config @@ -1,7 +1,6 @@ -# libdecnumber - x86-64 Linux config.h defines +# libdecnumber - macOS (aarch64-apple-darwin) config.h defines # -# libdecnumber includes "dconfig.h" which, when not IN_LIBGCC2, -# includes "config.h". We only need WORDS_BIGENDIAN (and standard headers). +# Identical to Linux — libdecnumber only needs endianness and standard headers. CONFIG_STDC_HEADERS=1 CONFIG_HAVE_STRING_H=1 diff --git a/examples/gcc/libiberty/Tupfile b/examples/gcc/libiberty/Tupfile index 5f43a97..18ae4a3 100644 --- a/examples/gcc/libiberty/Tupfile +++ b/examples/gcc/libiberty/Tupfile @@ -29,7 +29,7 @@ srcs += safe-ctype.c srcs += simple-object.c simple-object-coff.c simple-object-elf.c srcs += simple-object-mach-o.c simple-object-xcoff.c srcs += sort.c spaces.c splay-tree.c stack-limit.c -srcs += strerror.c strsignal.c +srcs += strerror.c strsignal.c strverscmp.c srcs += timeval-utils.c unlink-if-ordinary.c srcs += xasprintf.c xatexit.c xexit.c xmalloc.c xmemdup.c xstrdup.c srcs += xstrerror.c xstrndup.c xvasprintf.c diff --git a/examples/gcc/libiberty/tup.config b/examples/gcc/libiberty/tup.config index 781ad5e..4fb2d0a 100644 --- a/examples/gcc/libiberty/tup.config +++ b/examples/gcc/libiberty/tup.config @@ -1,28 +1,25 @@ -# libiberty - x86-64 Linux config.h defines +# libiberty - macOS (aarch64-apple-darwin) config.h defines # -# Prefix-free: scoped config merging namespaces these under libiberty/. -# Cross-referenced with libiberty/config.in from GCC 15.2.0. +# 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_MALLOC_H=1 CONFIG_HAVE_MEMORY_H=1 CONFIG_HAVE_SPAWN_H=1 CONFIG_HAVE_STDINT_H=1 -CONFIG_HAVE_STDIO_EXT_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_PRCTL_H=1 CONFIG_HAVE_SYS_RESOURCE_H=1 CONFIG_HAVE_SYS_STAT_H=1 -CONFIG_HAVE_SYS_SYSINFO_H=1 CONFIG_HAVE_SYS_TIME_H=1 CONFIG_HAVE_SYS_TYPES_H=1 CONFIG_HAVE_SYS_WAIT_H=1 @@ -38,9 +35,7 @@ CONFIG_HAVE_BCOPY=1 CONFIG_HAVE_BSEARCH=1 CONFIG_HAVE_BZERO=1 CONFIG_HAVE_CALLOC=1 -CONFIG_HAVE_CANONICALIZE_FILE_NAME=1 CONFIG_HAVE_CLOCK=1 -CONFIG_HAVE_DUP3=1 CONFIG_HAVE_FFS=1 CONFIG_HAVE_FORK=1 CONFIG_HAVE_GETCWD=1 @@ -55,12 +50,9 @@ CONFIG_HAVE_MEMCMP=1 CONFIG_HAVE_MEMCPY=1 CONFIG_HAVE_MEMMEM=1 CONFIG_HAVE_MEMMOVE=1 -CONFIG_HAVE_MEMRCHR=1 CONFIG_HAVE_MEMSET=1 CONFIG_HAVE_MKSTEMPS=1 CONFIG_HAVE_MMAP=1 -CONFIG_HAVE_ON_EXIT=1 -CONFIG_HAVE_PIPE2=1 CONFIG_HAVE_POSIX_SPAWN=1 CONFIG_HAVE_POSIX_SPAWNP=1 CONFIG_HAVE_PSIGNAL=1 @@ -72,7 +64,6 @@ CONFIG_HAVE_RINDEX=1 CONFIG_HAVE_SBRK=1 CONFIG_HAVE_SETENV=1 CONFIG_HAVE_SETRLIMIT=1 -CONFIG_HAVE_SIGSETMASK=1 CONFIG_HAVE_SNPRINTF=1 CONFIG_HAVE_STPCPY=1 CONFIG_HAVE_STPNCPY=1 @@ -91,7 +82,6 @@ CONFIG_HAVE_STRTOL=1 CONFIG_HAVE_STRTOLL=1 CONFIG_HAVE_STRTOUL=1 CONFIG_HAVE_STRTOULL=1 -CONFIG_HAVE_STRVERSCMP=1 CONFIG_HAVE_SYSCONF=1 CONFIG_HAVE_TIMES=1 CONFIG_HAVE_TMPNAM=1 @@ -105,7 +95,6 @@ CONFIG_HAVE_WAIT4=1 CONFIG_HAVE_WAITPID=1 CONFIG_HAVE_WORKING_FORK=1 CONFIG_HAVE_WORKING_VFORK=1 -CONFIG_HAVE___FSETLOCKING=1 # Types CONFIG_HAVE_INTPTR_T=1 @@ -114,21 +103,20 @@ CONFIG_HAVE_LONG_LONG=1 # Declarations CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=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=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_STRVERSCMP=1 CONFIG_HAVE_DECL_VASPRINTF=1 CONFIG_HAVE_DECL_VSNPRINTF=1 @@ -142,4 +130,3 @@ CONFIG_SIZEOF_SIZE_T=8 CONFIG_STDC_HEADERS=1 CONFIG_TIME_WITH_SYS_TIME=1 CONFIG_UNSIGNED_64BIT_TYPE=unsigned long -CONFIG__GNU_SOURCE=1 diff --git a/examples/gcc/mpc/tup.config b/examples/gcc/mpc/tup.config index 89aa987..d4568ae 100644 --- a/examples/gcc/mpc/tup.config +++ b/examples/gcc/mpc/tup.config @@ -1,6 +1,6 @@ -# MPC 1.2.1 - x86-64 Linux config.h defines +# MPC 1.2.1 - macOS (aarch64-apple-darwin) config.h defines # -# Prefix-free: scoped config merging namespaces these under mpc/. +# Identical to Linux — MPC is pure C with no platform-specific features. CONFIG_HAVE_INTTYPES_H=1 CONFIG_HAVE_LOCALE_H=1 diff --git a/examples/gcc/mpfr/tup.config b/examples/gcc/mpfr/tup.config index 96a7432..f92072b 100644 --- a/examples/gcc/mpfr/tup.config +++ b/examples/gcc/mpfr/tup.config @@ -1,6 +1,6 @@ -# MPFR 4.1.0 - x86-64 Linux config.h defines +# MPFR 4.1.0 - macOS (aarch64-apple-darwin) config.h defines # -# Prefix-free: scoped config merging namespaces these under mpfr/. +# Nearly identical to Linux. Only endianness representation differs slightly. CONFIG_HAVE_ALLOCA=1 CONFIG_HAVE_ALLOCA_H=1 diff --git a/examples/gcc/scripts/resolve-mpn.sh b/examples/gcc/scripts/resolve-mpn.sh index 4df0079..ec0d2ed 100755 --- a/examples/gcc/scripts/resolve-mpn.sh +++ b/examples/gcc/scripts/resolve-mpn.sh @@ -55,12 +55,20 @@ popcount hamdist sec_add_1 sec_sub_1 sec_div_qr sec_div_r sec_pi1_div_qr sec_pi1 # --- Generic mode --- +is_arch_specific() { + case "$1" in + udiv_w_sdiv) return 0 ;; # requires sdiv_qrnnd (68k/PowerPC only) + *) return 1 ;; + esac +} + if [ "$cpu" = "generic" ]; then c_files="" for f in "$mpn_src"/generic/*.c; do [ -f "$f" ] || continue func=$(basename "$f" .c) is_template_file "$func" && continue + is_arch_specific "$func" && continue c_files="${c_files:+$c_files }generic/$(basename "$f")" done diff --git a/src/graph/scanners/gcc.cpp b/src/graph/scanners/gcc.cpp index 17ef59d..457f314 100644 --- a/src/graph/scanners/gcc.cpp +++ b/src/graph/scanners/gcc.cpp @@ -155,9 +155,11 @@ auto is_source_file(std::string const& word) -> bool } /// Regex to match GCC/Clang compile commands +/// Requires compiler name followed by whitespace (not /) to avoid matching +/// directory names like "build-gcc/gcc/genpreds" auto gcc_pattern() -> std::regex const& { - static auto const pattern = std::regex { R"((gcc|g\+\+|clang|clang\+\+|cc|c\+\+).*\s-c\s)" }; + static auto const pattern = std::regex { R"((?:^|/)(gcc|g\+\+|clang|clang\+\+|cc|c\+\+)\s.*\s-c\s)" }; return pattern; } From 39f53d81848b5524a74eddb30bba12652d4a139e Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Thu, 19 Feb 2026 19:06:49 +0800 Subject: [PATCH 07/16] Support $$ escape and config-tree overlay for external packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add $$ → $ de-escaping in the evaluator so shell variable references survive Tupfile expansion (e.g., for f in $(names); do ... $$f). In 3-tree builds (-C/-S/-B), the scheduler now creates source subdirs that exist in the config tree but not the source tree, enabling packages whose actual source lives in a separate tree (referenced via config variables rather than the -S tree). Co-Authored-By: Claude Opus 4.6 --- include/pup/exec/scheduler.hpp | 1 + src/cli/cmd_build.cpp | 1 + src/cli/cmd_configure.cpp | 1 + src/exec/scheduler.cpp | 11 +++++++++++ src/parser/eval.cpp | 7 +++++++ test/e2e/fixtures/dollar_escape/Tupfile | 1 + test/unit/test_e2e.cpp | 20 ++++++++++++++++++++ 7 files changed, 42 insertions(+) create mode 100644 test/e2e/fixtures/dollar_escape/Tupfile diff --git a/include/pup/exec/scheduler.hpp b/include/pup/exec/scheduler.hpp index c5de101..ac91dee 100644 --- a/include/pup/exec/scheduler.hpp +++ b/include/pup/exec/scheduler.hpp @@ -67,6 +67,7 @@ struct SchedulerOptions { bool dry_run = false; ///< Print commands without executing bool verbose = false; ///< Print commands as they run std::filesystem::path source_root = {}; ///< Source tree root (where Tupfile.ini lives) + std::filesystem::path config_root = {}; ///< Config tree root (fallback when source subdir missing) std::filesystem::path output_root = {}; ///< Output tree root (where outputs/.pup go) std::optional timeout = {}; ///< Per-command timeout }; diff --git a/src/cli/cmd_build.cpp b/src/cli/cmd_build.cpp index 8abce74..95c4eb4 100644 --- a/src/cli/cmd_build.cpp +++ b/src/cli/cmd_build.cpp @@ -1076,6 +1076,7 @@ auto build_single_variant( .dry_run = opts.dry_run, .verbose = opts.verbose, .source_root = ctx.layout().source_root, + .config_root = ctx.layout().config_root, .output_root = ctx.layout().output_root, }; diff --git a/src/cli/cmd_configure.cpp b/src/cli/cmd_configure.cpp index 8eee485..71306f6 100644 --- a/src/cli/cmd_configure.cpp +++ b/src/cli/cmd_configure.cpp @@ -187,6 +187,7 @@ auto configure_single_variant( .dry_run = opts.dry_run, .verbose = opts.verbose, .source_root = ctx.layout().source_root, + .config_root = ctx.layout().config_root, .output_root = ctx.layout().output_root, }; diff --git a/src/exec/scheduler.cpp b/src/exec/scheduler.cpp index 9a7ab0e..6969fa5 100644 --- a/src/exec/scheduler.cpp +++ b/src/exec/scheduler.cpp @@ -806,6 +806,17 @@ auto Scheduler::build_job_list( if (!source_dir.empty()) { working_dir /= source_dir; } + // In overlay mode (3-tree builds), config-tree directories are projected + // onto the source tree. If this subdir exists in the config tree but not + // the source tree, create it so commands can run from it. + if (!std::filesystem::is_directory(working_dir) + && !impl_->options.config_root.empty() + && !source_dir.empty()) { + auto config_dir = impl_->options.config_root / source_dir; + if (std::filesystem::is_directory(config_dir)) { + std::filesystem::create_directories(working_dir); + } + } // Check if this is a generated rule that captures stdout auto capture_stdout = false; diff --git a/src/parser/eval.cpp b/src/parser/eval.cpp index 74eabdd..6ec11b1 100644 --- a/src/parser/eval.cpp +++ b/src/parser/eval.cpp @@ -274,6 +274,13 @@ auto expand(EvalContext& ctx, std::string_view text) -> Result // Add text before the variable result += text.substr(pos, next - pos); + // Handle $$ escape → literal $ for shell commands + if (text[next] == '$' && next + 1 < text.size() && text[next + 1] == '$') { + result += '$'; + pos = next + 2; + continue; + } + // Check for variable reference pattern: X(name) if (next + 1 < text.size() && text[next + 1] == '(') { auto close = text.find(')', next + 2); diff --git a/test/e2e/fixtures/dollar_escape/Tupfile b/test/e2e/fixtures/dollar_escape/Tupfile new file mode 100644 index 0000000..1a94a84 --- /dev/null +++ b/test/e2e/fixtures/dollar_escape/Tupfile @@ -0,0 +1 @@ +: |> VAR=hello; echo $$VAR > %o |> output.txt diff --git a/test/unit/test_e2e.cpp b/test/unit/test_e2e.cpp index 3e4a46d..6438d4d 100644 --- a/test/unit/test_e2e.cpp +++ b/test/unit/test_e2e.cpp @@ -510,6 +510,26 @@ SCENARIO("Build fails when command fails", "[e2e][build]") } } +SCENARIO("Dollar-dollar escapes to literal dollar in shell commands", "[e2e][build]") +{ + GIVEN("a project with $$ in a command") + { + auto f = E2EFixture { "dollar_escape" }; + REQUIRE(f.init().success()); + + WHEN("the project is built") + { + auto result = f.build(); + + THEN("build succeeds and $$ becomes $ for the shell") + { + REQUIRE(result.success()); + REQUIRE(f.read_file("output.txt") == "hello\n"); + } + } + } +} + // ============================================================================= // Incremental Build Tests // ============================================================================= From 869c7f7e39c4a807055c12356fa39938460feae1 Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Thu, 19 Feb 2026 19:07:00 +0800 Subject: [PATCH 08/16] Add cross-binutils (as + ar) as first external package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build GNU binutils 2.44 cross-assembler and cross-archiver targeting x86_64-linux from a separate source tree via @(BINUTILS_SRC). This is the first package to use an explicit source variable rather than the implicit -S tree, establishing the pattern for future packages. Single Tupfile builds BFD (38 files), libsframe (2), opcodes (4), gas (39), and ar (11) — producing working as and ar binaries that integrate with the existing xgcc/cc1 toolchain. Co-Authored-By: Claude Opus 4.6 --- examples/gcc/Makefile.pup | 35 +++++- examples/gcc/README.md | 20 +++- examples/gcc/Tuprules.tup | 1 + examples/gcc/binutils/Tupfile | 181 +++++++++++++++++++++++++++++ examples/gcc/binutils/Tuprules.tup | 37 ++++++ examples/gcc/binutils/tup.config | 112 ++++++++++++++++++ 6 files changed, 379 insertions(+), 7 deletions(-) create mode 100644 examples/gcc/binutils/Tupfile create mode 100644 examples/gcc/binutils/Tuprules.tup create mode 100644 examples/gcc/binutils/tup.config diff --git a/examples/gcc/Makefile.pup b/examples/gcc/Makefile.pup index 73e7023..de57ae3 100644 --- a/examples/gcc/Makefile.pup +++ b/examples/gcc/Makefile.pup @@ -18,7 +18,8 @@ # -S $(SRCDIR) GCC source tree (read-only) # -B $(BUILD) Build output directory -.PHONY: all build configure resolve-mpn setup-host-configs clean distclean download-source +.PHONY: all build configure resolve-mpn resolve-binutils-src setup-host-configs \ + clean distclean download-source download-binutils PLATFORM ?= x86_64-linux HOST ?= linux @@ -29,11 +30,11 @@ TREES = -C . -S $(SRCDIR) -B $(BUILD) all: build -build: resolve-mpn setup-host-configs +build: resolve-mpn setup-host-configs resolve-binutils-src putup configure --config configs/$(PLATFORM).config $(TREES) putup $(TREES) -j$$(nproc) -configure: resolve-mpn setup-host-configs +configure: resolve-mpn setup-host-configs resolve-binutils-src putup configure --config configs/$(PLATFORM).config $(TREES) # Copy host-specific library configs when building for non-Linux hosts. @@ -53,7 +54,7 @@ setup-host-configs: # - gmp/tup.config: GMP_MPARAM and ASM_ENABLED (parent scope, visible to gmp/Tupfile) resolve-mpn: @scripts/resolve-mpn.sh $(MPN_CPU) $(SRCDIR)/gmp/mpn > gmp/mpn/tup.config - @sed -i '/^CONFIG_GMP_MPARAM=/d;/^CONFIG_ASM_ENABLED=/d;/^CONFIG_NO_ASM=/d' gmp/tup.config + @grep -v '^CONFIG_GMP_MPARAM=\|^CONFIG_ASM_ENABLED=\|^CONFIG_NO_ASM=' gmp/tup.config > gmp/tup.config.tmp && mv gmp/tup.config.tmp gmp/tup.config @if [ "$(MPN_CPU)" != "generic" ]; then \ arch=$${MPN_CPU%%/*}; \ if [ -f "$(SRCDIR)/gmp/mpn/$$arch/gmp-mparam.h" ]; then \ @@ -67,6 +68,18 @@ resolve-mpn: echo "CONFIG_NO_ASM=1" >> gmp/tup.config; \ fi +# Resolve binutils source to an absolute path. +# Commands run from the config tree (putup falls back when the source +# subdir doesn't exist in the -S tree), so absolute paths ensure the +# compiler can always find binutils sources regardless of working directory. +resolve-binutils-src: + @if [ -d "$(BINUTILS_DIR)" ]; then \ + abs=$$(cd "$(BINUTILS_DIR)" && pwd); \ + grep -v '^CONFIG_BINUTILS_SRC=' binutils/tup.config > binutils/tup.config.tmp; \ + echo "CONFIG_BINUTILS_SRC=$$abs" >> binutils/tup.config.tmp; \ + mv binutils/tup.config.tmp binutils/tup.config; \ + fi + # Multi-variant: build for multiple platforms in parallel # make -f Makefile.pup multi SRCDIR=../gcc-15.2.0 PLATFORMS ?= x86_64-linux aarch64-linux @@ -78,7 +91,10 @@ multi: # Download GCC source for reference/building GCC_VERSION ?= 15.2.0 -download-source: +BINUTILS_VERSION ?= 2.44 +BINUTILS_DIR ?= ../binutils-$(BINUTILS_VERSION) + +download-source: download-binutils @if [ ! -d "$(SRCDIR)" ]; then \ echo "Downloading GCC $(GCC_VERSION)..."; \ curl -L "https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.xz" \ @@ -87,6 +103,15 @@ download-source: echo "$(SRCDIR) already exists"; \ fi +download-binutils: + @if [ ! -d "$(BINUTILS_DIR)" ]; then \ + echo "Downloading binutils $(BINUTILS_VERSION)..."; \ + curl -L "https://ftp.gnu.org/gnu/binutils/binutils-$(BINUTILS_VERSION).tar.xz" \ + | tar xJ -C $$(dirname $(BINUTILS_DIR)); \ + else \ + echo "$(BINUTILS_DIR) already exists"; \ + fi + clean: putup clean $(TREES) diff --git a/examples/gcc/README.md b/examples/gcc/README.md index 362589f..fa5f317 100644 --- a/examples/gcc/README.md +++ b/examples/gcc/README.md @@ -3,7 +3,8 @@ Build a complete GCC 15.2.0 cross-compiler toolchain using putup. This builds everything from source: prerequisite math libraries, compiler support libraries, ~25 host generator programs, the ~500-file compiler backend, C/C++ -frontends, driver programs, and developer tools — 3500+ build commands in ~130s. +frontends, driver programs, developer tools, and GNU binutils (assembler + archiver) +— 3600+ build commands in ~140s. ## Quick Start @@ -14,8 +15,11 @@ wget https://gcc.gnu.org/pub/gcc/releases/gcc-15.2.0/gcc-15.2.0.tar.xz tar xf gcc-15.2.0.tar.xz cd gcc-15.2.0 && ./contrib/download_prerequisites && cd .. -# 2. Build cc1 +# 2. Download binutils (assembler + archiver) cd examples/gcc +make -f Makefile.pup download-binutils + +# 3. Build toolchain make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc ``` @@ -51,6 +55,10 @@ Tools: gcc/ → lto-wrapper LTO linker plugin interface gcc/ → gcov Code coverage analysis gcc/ → gcov-dump Coverage data inspector + +Binutils (separate source tree): + binutils/ → as Cross-assembler (x86_64 ELF) + binutils/ → ar Cross-archiver ``` ## Dependency Chain @@ -68,6 +76,10 @@ libdecnumber ──────────────→ libdecnumber.a ┘ libbacktrace ──────────────→ libbacktrace.a ───────────┘ ↑ libcpp ────────────────────→ libcpp.a ─────────────────┘ + +binutils (separate source): + libiberty.a ──→ bfd + opcodes + gas ──→ as + libiberty.a ──→ bfd + ar objects ─────→ ar ``` ## Per-Component Configuration @@ -85,6 +97,7 @@ libdecnumber/tup.config → libdecnumber: endianness, float format libbacktrace/tup.config → libbacktrace: BACKTRACE_ELF_SIZE, HAVE_DL_ITERATE_PHDR, ... libcpp/tup.config → libcpp: HAVE_ICONV, ENABLE_NLS, ... gcc/tup.config → GCC: HOST_BITS_PER_*, SIZEOF_*, HAVE_*, ... +binutils/tup.config → binutils: BFD64, target arch, host capabilities ``` `putup configure --config` installs the root config and copies subdir configs to the @@ -223,6 +236,8 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) | `gcc/analyzer/Tupfile` | Static analyzer objects | | `gcc/config/i386/Tupfile` | x86_64 target-specific objects | | `gcc/targets/x86_64-pc-linux-gnu.tup` | Target-specific machine description rules | +| **binutils** (separate source tree) | | +| `binutils/{Tuprules.tup,tup.config,Tupfile}` | Cross-assembler + cross-archiver | ## Build Features Demonstrated @@ -241,6 +256,7 @@ make -f Makefile.pup MPN_CPU=generic # Pure C (default) - **Self-contained libraries**: Each library has its own `Tuprules.tup` with `?=` defaults; buildable alone or composed - **Nested `include_rules`**: Root `Tuprules.tup` sets toolchain, per-library `Tuprules.tup` adds flags and bang macros - **Inter-library dependencies**: Order-only groups ensure correct build ordering +- **Multi-source-tree packages**: binutils uses `@(BINUTILS_SRC)` for its own source tree, separate from GCC's `-S` ## Notes diff --git a/examples/gcc/Tuprules.tup b/examples/gcc/Tuprules.tup index 2b5feea..dd25173 100644 --- a/examples/gcc/Tuprules.tup +++ b/examples/gcc/Tuprules.tup @@ -21,3 +21,4 @@ LIBDECNUMBER_DIR = libdecnumber LIBBACKTRACE_DIR = libbacktrace LIBCODY_DIR = libcody GCC_DIR = gcc +BINUTILS_DIR = binutils diff --git a/examples/gcc/binutils/Tupfile b/examples/gcc/binutils/Tupfile new file mode 100644 index 0000000..61d6f5f --- /dev/null +++ b/examples/gcc/binutils/Tupfile @@ -0,0 +1,181 @@ +include_rules + +# ============================================================ +# binutils — cross-assembler (as) + cross-archiver (ar) +# +# First external package: source via @(BINUTILS_SRC), not -S. +# Single Tupfile avoids cross-directory group issues in 3-tree mode. +# +# Source paths use $(BFD)/, $(GAS)/, $(OPC)/, $(BIN)/ prefixes. +# Because the binutils source tree is outside the -S tree, sources +# are referenced only in command strings, not as tup inputs. +# putup falls back to the config tree as working directory when +# the source subdir doesn't exist in -S. +# ============================================================ + +BFD = $(BU)/bfd +GAS = $(BU)/gas +OPC = $(BU)/opcodes +BIN = $(BU)/binutils +OUT = $(B)/$(BINUTILS_DIR) + +# --- Phase 1: Generated headers --- + +# config.h from tup.config +: |> !gen-config |> config.h + +# bfd.h — substitute autoconf placeholders in bfd-in2.h +: |> ^ GEN %o^ sed \ + -e 's/@wordsize@/64/g' \ + -e 's/@bfd_default_target_size@/64/g' \ + -e 's/@BFD_DEFAULT_TARGET_SIZE@/64/g' \ + -e 's/@BFD64@/#define BFD64 1/g' \ + -e 's/@BFD_HOST_64BIT_LONG@/1/g' \ + -e 's/@BFD_HOST_LONG_LONG@/1/g' \ + -e 's/@BFD_HOST_64_BIT@/long/g' \ + -e 's/@BFD_HOST_U_64_BIT@/unsigned long/g' \ + -e 's/@bfd_file_ptr@/long/g' \ + -e 's/@bfd_ufile_ptr@/unsigned long/g' \ + -e 's/@supports_plugins@/0/g' \ + $(BFD)/bfd-in2.h > %o |> bfd.h + +# bfd_stdint.h — trivial wrapper (modern systems have stdint.h) +: |> ^ GEN %o^ printf '%s\n' '#include ' > %o |> bfd_stdint.h + +# targmatch.h — target matching table for x86_64 ELF targets +: |> ^ GEN %o^ printf '%s\n' \ + '/* Generated — x86_64-pc-linux-gnu target */' \ + '{ "x86_64-*-linux*", &x86_64_elf64_vec },' \ + '{ "x86_64-*-elf*", &x86_64_elf64_vec },' \ + '{ "i[3-7]86-*-linux*", &i386_elf32_vec },' > %o |> targmatch.h + +# bfdver.h — substitute version placeholders in version.h +: |> ^ GEN %o^ sed \ + -e 's/@bfd_version@/244000000/g' \ + -e 's/@bfd_version_string@/"2.44"/g' \ + -e 's/@bfd_version_package@/"(GNU Binutils)"/g' \ + -e 's/@report_bugs_to@/""/g' \ + $(BFD)/version.h > %o |> bfdver.h + +# gas target headers — redirect to concrete config files for x86_64-linux-elf +: |> ^ GEN %o^ echo '#include "tc-i386.h"' > %o |> targ-cpu.h +: |> ^ GEN %o^ echo '#include "obj-elf.h"' > %o |> obj-format.h +: |> ^ GEN %o^ echo '#include "te-linux.h"' > %o |> targ-env.h + +# elf32-target.h / elf64-target.h — elfxx-target.h with NN substitution +: |> ^ GEN %o^ sed 's/elfNN/elf32/g;s/ELFNN/ELF32/g' $(BFD)/elfxx-target.h > %o |> elf32-target.h +: |> ^ GEN %o^ sed 's/elfNN/elf64/g;s/ELFNN/ELF64/g' $(BFD)/elfxx-target.h > %o |> elf64-target.h + +# --- Phase 2: BFD objects --- +# Core BFD library + ELF x86_64 backend. +# Batch compile: sources are outside the project tree, so we reference +# them only in the command (not as tup inputs). Output prefix bfd- +# avoids collisions with gas (both have hash.c, stabs.c). + +bfd_names = archive archures bfd bfdio cache +bfd_names += coffgen compress corefile format hash +bfd_names += init libbfd linker merge opncls +bfd_names += reloc section simple stab-syms stabs +bfd_names += syms targets +bfd_names += elf elf-properties elf-strtab elflink +bfd_names += elf-eh-frame elf-ifunc elf-vxworks elf-attrs elf-sframe +bfd_names += dwarf1 dwarf2 archive64 +bfd_names += elf64 elf64-x86-64 elfxx-x86 cpu-i386 +bfd_names += elf64-gen elf32-gen elf32 elf32-i386 +bfd_names += binary ihex srec tekhex verilog + +: | |> ^ CC-BFD (38 files)^ for f in $(bfd_names); do \ + $(CC) $(CFLAGS) $(BFD_INCLUDES) -c $(BFD)/$$f.c -o $(OUT)/bfd-$$f.o || exit 1; \ + done |> \ + bfd-archive.o bfd-archures.o bfd-bfd.o bfd-bfdio.o bfd-cache.o \ + bfd-coffgen.o bfd-compress.o bfd-corefile.o bfd-format.o bfd-hash.o \ + bfd-init.o bfd-libbfd.o bfd-linker.o bfd-merge.o bfd-opncls.o \ + bfd-reloc.o bfd-section.o bfd-simple.o bfd-stab-syms.o bfd-stabs.o \ + bfd-syms.o bfd-targets.o \ + bfd-elf.o bfd-elf-properties.o bfd-elf-strtab.o bfd-elflink.o \ + bfd-elf-eh-frame.o bfd-elf-ifunc.o bfd-elf-vxworks.o bfd-elf-attrs.o bfd-elf-sframe.o \ + bfd-dwarf1.o bfd-dwarf2.o bfd-archive64.o \ + bfd-elf64.o bfd-elf64-x86-64.o bfd-elfxx-x86.o bfd-cpu-i386.o \ + bfd-elf64-gen.o bfd-elf32-gen.o bfd-elf32.o bfd-elf32-i386.o \ + bfd-binary.o bfd-ihex.o bfd-srec.o bfd-tekhex.o bfd-verilog.o \ + + +# --- Phase 2b: libsframe objects --- +# SFrame stack-trace format library, needed by elf-sframe.c in BFD. + +SFRAME = $(BU)/libsframe +SFRAME_INCLUDES = -I$(B)/$(BINUTILS_DIR) -I$(SFRAME) -I$(BU)/libctf -I$(BU)/include + +sframe_names = sframe sframe-error + +: | |> ^ CC-SFRAME (2 files)^ for f in $(sframe_names); do \ + $(CC) $(CFLAGS) $(SFRAME_INCLUDES) -c $(SFRAME)/$$f.c -o $(OUT)/sframe-$$f.o || exit 1; \ + done |> \ + sframe-sframe.o sframe-sframe-error.o \ + + +# --- Phase 3: Opcodes objects --- +# x86 instruction decode/encode tables + +opc_names = dis-init disassemble dis-buf i386-dis + +: | |> ^ CC-OPC (4 files)^ for f in $(opc_names); do \ + $(CC) $(CFLAGS) $(BFD_INCLUDES) -I$(OPC) -c $(OPC)/$$f.c -o $(OUT)/opc-$$f.o || exit 1; \ + done |> \ + opc-dis-init.o opc-disassemble.o opc-dis-buf.o opc-i386-dis.o \ + + +# --- Phase 4: Gas (assembler) objects --- +# Output prefix gas- avoids collisions with bfd (hash.c, stabs.c). + +gas_names = app as atof-generic compress-debug cond +gas_names += depend dwarf2dbg dw2gencfi ecoff ehopt +gas_names += expr flonum-copy flonum-konst flonum-mult +gas_names += frags hash input-file input-scrub listing +gas_names += literal macro messages output-file read +gas_names += remap sb stabs subsegs symbols write +gas_names += ginsn scfi scfidw2gen gen-sframe sframe-opt codeview + +gas_target_names = tc-i386 obj-elf atof-ieee + +: | |> ^ CC-GAS (39 files)^ \ + for f in $(gas_names); do \ + $(CC) $(CFLAGS) $(GAS_INCLUDES) $(BFD_INCLUDES) -c $(GAS)/$$f.c -o $(OUT)/gas-$$f.o || exit 1; \ + done; \ + for f in $(gas_target_names); do \ + $(CC) $(CFLAGS) $(GAS_INCLUDES) $(BFD_INCLUDES) -c $(GAS)/config/$$f.c -o $(OUT)/gas-$$f.o || exit 1; \ + done |> \ + gas-app.o gas-as.o gas-atof-generic.o gas-compress-debug.o gas-cond.o \ + gas-depend.o gas-dwarf2dbg.o gas-dw2gencfi.o gas-ecoff.o gas-ehopt.o \ + gas-expr.o gas-flonum-copy.o gas-flonum-konst.o gas-flonum-mult.o \ + gas-frags.o gas-hash.o gas-input-file.o gas-input-scrub.o gas-listing.o \ + gas-literal.o gas-macro.o gas-messages.o gas-output-file.o gas-read.o \ + gas-remap.o gas-sb.o gas-stabs.o gas-subsegs.o gas-symbols.o gas-write.o \ + gas-ginsn.o gas-scfi.o gas-scfidw2gen.o gas-gen-sframe.o gas-sframe-opt.o gas-codeview.o \ + gas-tc-i386.o gas-obj-elf.o gas-atof-ieee.o \ + + +# --- Phase 5: Link as (cross-assembler) --- + +: $(LIBIBERTY_A) |> ^ LINK as^ \ + $(CC) % % % % $(LIBIBERTY_A) \ + -lz @(PLATFORM_LDFLAGS) -o %o |> as + +# --- Phase 6: ar (cross-archiver) objects --- + +ar_names = ar arsup not-ranlib bucomm rename binemul emul_vanilla version filemode arparse arlex + +: | |> ^ CC-BU (11 files)^ for f in $(ar_names); do \ + $(CC) $(CFLAGS) $(BINUTILS_INCLUDES) $(BFD_INCLUDES) \ + -Dbin_dummy_emulation=bin_vanilla_emulation \ + -c $(BIN)/$$f.c -o $(OUT)/$$f.o || exit 1; \ + done |> \ + ar.o arsup.o not-ranlib.o bucomm.o rename.o binemul.o emul_vanilla.o \ + version.o filemode.o arparse.o arlex.o \ + + +# --- Phase 7: Link ar (cross-archiver) --- + +: $(LIBIBERTY_A) |> ^ LINK ar^ \ + $(CC) % % % $(LIBIBERTY_A) \ + -lz @(PLATFORM_LDFLAGS) -o %o |> ar diff --git a/examples/gcc/binutils/Tuprules.tup b/examples/gcc/binutils/Tuprules.tup new file mode 100644 index 0000000..f6254c1 --- /dev/null +++ b/examples/gcc/binutils/Tuprules.tup @@ -0,0 +1,37 @@ +# binutils build rules (self-contained with ?= defaults) +# +# Composed mode: parent sets S, B, CC, AR, LIBIBERTY_DIR, BINUTILS_DIR. +# Standalone mode: ?= defaults take effect. +# +# Source is a separate tree from GCC, referenced via @(BINUTILS_SRC). + +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) +CC ?= clang +AR_CMD ?= ar +LIBIBERTY_DIR ?= libiberty +BINUTILS_DIR ?= . + +# Binutils source root (separate from GCC -S tree). +# Resolved to an absolute path by Makefile.pup (resolve-binutils-src) +# so commands work from the build variant directory. +BU = @(BINUTILS_SRC) + +# Resolved library paths +LIBIBERTY_A = $(B)/$(LIBIBERTY_DIR)/libiberty.a + +# Include paths +BFD_INCLUDES = -I$(B)/$(BINUTILS_DIR) -I$(BU)/bfd -I$(BU)/include +GAS_INCLUDES = -I$(B)/$(BINUTILS_DIR) -I$(BU)/gas -I$(BU)/gas/config -I$(BU)/include -I$(BU)/bfd -I$(BU) +BINUTILS_INCLUDES = -I$(B)/$(BINUTILS_DIR) -I$(BU)/binutils -I$(BU)/include -I$(BU)/bfd + +CFLAGS = -O2 -DHAVE_CONFIG_H + +!cc-bfd = | $(S)/$(BINUTILS_DIR)/ |> ^ CC-BFD %b^ $(CC) $(CFLAGS) $(BFD_INCLUDES) -c %f -o %o |> +!cc-opcodes = | $(S)/$(BINUTILS_DIR)/ |> ^ CC-OPC %b^ $(CC) $(CFLAGS) $(BFD_INCLUDES) -I$(BU)/opcodes -c %f -o %o |> +!cc-gas = | $(S)/$(BINUTILS_DIR)/ |> ^ CC-GAS %b^ $(CC) $(CFLAGS) $(GAS_INCLUDES) $(BFD_INCLUDES) -c %f -o %o |> +!cc-binutils = | $(S)/$(BINUTILS_DIR)/ |> ^ CC-BU %b^ $(CC) $(CFLAGS) $(BINUTILS_INCLUDES) $(BFD_INCLUDES) -c %f -o %o |> + +!gen-config = |> ^ GEN %o^ awk -F= \ + '/^CONFIG_/{k=substr($1,8);v=substr($0,length($1)+2);if(v!="n")print "#define " k " " (v=="y"?1:v)}' \ + $(B)/$(BINUTILS_DIR)/tup.config > %o |> diff --git a/examples/gcc/binutils/tup.config b/examples/gcc/binutils/tup.config new file mode 100644 index 0000000..de8d612 --- /dev/null +++ b/examples/gcc/binutils/tup.config @@ -0,0 +1,112 @@ +# binutils - macOS (aarch64-apple-darwin) host, x86_64-linux target +# +# BFD, opcodes, and gas share this config.h. +# Key: BFD64 for 64-bit targets, ELF backend, macOS host capabilities. + +# Package identity +CONFIG_PACKAGE="binutils" +CONFIG_PACKAGE_VERSION="2.44" + +# BFD64 required for x86_64 targets +CONFIG_BFD64=1 + +# Target selection +CONFIG_TARGET="x86_64-pc-linux-gnu" +CONFIG_TARGET_CPU="i386" +CONFIG_DEFAULT_BFD_ARCH=bfd_i386_arch +CONFIG_DEFAULT_BFD_VEC=x86_64_elf64_vec +CONFIG_SELECT_ARCHITECTURES=&bfd_i386_arch +CONFIG_TARG_ARCHS=&bfd_i386_arch +CONFIG_SELECT_VECS=&x86_64_elf64_vec,&i386_elf32_vec,&x86_64_elf32_vec + +# Host capabilities (macOS/Darwin aarch64) +CONFIG_HAVE_MMAP=1 +CONFIG_HAVE_MPROTECT=1 +CONFIG_HAVE_FCNTL=1 +CONFIG_HAVE_GETPAGESIZE=1 +CONFIG_HAVE_FOPEN64=n +CONFIG_HAVE_FSEEKO64=n +CONFIG_HAVE_FSEEKO=1 + +# Standard headers +CONFIG_HAVE_STDINT_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_STDLIB_H=1 +CONFIG_HAVE_STRING_H=1 +CONFIG_HAVE_STRINGS_H=1 +CONFIG_HAVE_UNISTD_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_SYS_FILE_H=1 +CONFIG_HAVE_SYS_MMAN_H=1 +CONFIG_HAVE_SYS_PARAM_H=1 +CONFIG_HAVE_SYS_STAT_H=1 +CONFIG_HAVE_SYS_TYPES_H=1 +CONFIG_HAVE_SYS_TIME_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_DLFCN_H=1 +CONFIG_HAVE_ERRNO_H=1 +CONFIG_HAVE_ALLOCA_H=n +CONFIG_HAVE_ZLIB_H=1 + +# Type sizes (LP64) +CONFIG_SIZEOF_VOID_P=8 +CONFIG_SIZEOF_LONG=8 +CONFIG_SIZEOF_LONG_LONG=8 +CONFIG_SIZEOF_OFF_T=8 + +# Declarations +CONFIG_HAVE_DECL_ASPRINTF=1 +CONFIG_HAVE_DECL_VASPRINTF=1 +CONFIG_HAVE_DECL_SNPRINTF=1 +CONFIG_HAVE_DECL_VSNPRINTF=1 +CONFIG_HAVE_DECL_STPCPY=1 +CONFIG_HAVE_DECL_STRNLEN=1 +CONFIG_HAVE_DECL_FFS=1 +CONFIG_HAVE_DECL_GETENV=1 +CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_MALLOC=1 +CONFIG_HAVE_DECL_REALLOC=1 +CONFIG_HAVE_DECL_SBRK=0 +CONFIG_HAVE_DECL_ENVIRON=0 +CONFIG_HAVE_DECL_STRSTR=1 + +# Functions +CONFIG_HAVE_ASPRINTF=1 +CONFIG_HAVE_VASPRINTF=1 +CONFIG_HAVE_REALPATH=1 +CONFIG_HAVE_MKDTEMP=1 +CONFIG_HAVE_MKSTEMP=1 +CONFIG_HAVE_SETLOCALE=1 +CONFIG_HAVE_SBRK=1 +CONFIG_HAVE_GETRLIMIT=1 + +# C standard +CONFIG_STDC_HEADERS=1 + +# Misc +CONFIG_USE_BINARY_FOPEN=n +CONFIG_NEED_DECLARATION_ENVIRON=1 +CONFIG_NEED_DECLARATION_FFS=n +CONFIG_DEFAULT_AR_DETERMINISTIC=1 +CONFIG_HAVE_UTIMES=1 + +# Gas target identity +CONFIG_TARGET_ALIAS="x86_64-pc-linux-gnu" +CONFIG_TARGET_CANONICAL="x86_64-pc-linux-gnu" +CONFIG_VERSION="2.44" + +# Gas defaults +CONFIG_DEFAULT_GENERATE_ELF_STT_COMMON=0 +CONFIG_DEFAULT_GENERATE_BUILD_NOTES=0 +CONFIG_DEFAULT_COMPRESSED_DEBUG_ALGORITHM=0 +CONFIG_HAVE_STRSIGNAL=1 +CONFIG_DEFAULT_X86_USED_NOTE=0 +CONFIG_DEFAULT_GENERATE_X86_RELAX_RELOCATIONS=1 +CONFIG_DEFAULT_X86_TLS_CHECK=0 + +# Thread-local storage keyword +CONFIG_TLS=__thread + +# Debug info directory +CONFIG_DEBUGDIR="/usr/lib/debug" +CONFIG_BINUTILS_SRC=/Users/mural/Developer/pup/examples/binutils-2.44 From 37c125cc5dbf69d2a1d53b8cd05358e2af1c4e29 Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:49:14 +0800 Subject: [PATCH 09/16] Fix GCC dep scanner regex to match -c as first argument The pattern required at least one token between the compiler name and -c, so commands like `gcc -c foo.c -o foo.o` never matched. Also add \s as an anchor alternative so compiler wrappers like `ccache gcc` are recognized. Co-Authored-By: Claude Opus 4.6 --- src/graph/scanners/gcc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graph/scanners/gcc.cpp b/src/graph/scanners/gcc.cpp index 457f314..b10b14d 100644 --- a/src/graph/scanners/gcc.cpp +++ b/src/graph/scanners/gcc.cpp @@ -159,7 +159,7 @@ auto is_source_file(std::string const& word) -> bool /// directory names like "build-gcc/gcc/genpreds" auto gcc_pattern() -> std::regex const& { - static auto const pattern = std::regex { R"((?:^|/)(gcc|g\+\+|clang|clang\+\+|cc|c\+\+)\s.*\s-c\s)" }; + static auto const pattern = std::regex { R"((?:^|/|\s)(gcc|g\+\+|clang|clang\+\+|cc|c\+\+)\s(?:.*\s)?-c(?:\s|$))" }; return pattern; } From 011bf31f1d59bdf318db9d48ba3beb93e831bb10 Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Sat, 21 Feb 2026 19:06:43 +0800 Subject: [PATCH 10/16] Add groups_cross_dir_3tree fixture for 3-tree cross-directory group test Co-Authored-By: Claude Opus 4.6 --- test/e2e/fixtures/groups_cross_dir_3tree/config/Tupfile.ini | 0 test/e2e/fixtures/groups_cross_dir_3tree/config/Tuprules.tup | 2 ++ test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tupfile | 5 +++++ .../fixtures/groups_cross_dir_3tree/config/gcc/Tuprules.tup | 5 +++++ test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/hello.c | 1 + test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/main.c | 4 ++++ 6 files changed, 17 insertions(+) create mode 100644 test/e2e/fixtures/groups_cross_dir_3tree/config/Tupfile.ini create mode 100644 test/e2e/fixtures/groups_cross_dir_3tree/config/Tuprules.tup create mode 100644 test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tupfile create mode 100644 test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tuprules.tup create mode 100644 test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/hello.c create mode 100644 test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/main.c diff --git a/test/e2e/fixtures/groups_cross_dir_3tree/config/Tupfile.ini b/test/e2e/fixtures/groups_cross_dir_3tree/config/Tupfile.ini new file mode 100644 index 0000000..e69de29 diff --git a/test/e2e/fixtures/groups_cross_dir_3tree/config/Tuprules.tup b/test/e2e/fixtures/groups_cross_dir_3tree/config/Tuprules.tup new file mode 100644 index 0000000..925a536 --- /dev/null +++ b/test/e2e/fixtures/groups_cross_dir_3tree/config/Tuprules.tup @@ -0,0 +1,2 @@ +S = $(TUP_CWD) +LIB_DIR = gcc diff --git a/test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tupfile b/test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tupfile new file mode 100644 index 0000000..4bab9d0 --- /dev/null +++ b/test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tupfile @@ -0,0 +1,5 @@ +include_rules + +: |> ^ GEN config.h^ echo '#define HAVE_CONFIG 1' > %o |> config.h +: foreach *.c |> !cc |> +: *.o |> ^ LINK %o^ cc %f -o %o |> hello.out diff --git a/test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tuprules.tup b/test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tuprules.tup new file mode 100644 index 0000000..d843141 --- /dev/null +++ b/test/e2e/fixtures/groups_cross_dir_3tree/config/gcc/Tuprules.tup @@ -0,0 +1,5 @@ +S ?= .. +LIB_DIR ?= . +include_rules + +!cc = | $(S)/$(LIB_DIR)/ |> ^ CC %o^ cc -c %f -o %o |> %B.o diff --git a/test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/hello.c b/test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/hello.c new file mode 100644 index 0000000..3665a6d --- /dev/null +++ b/test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/hello.c @@ -0,0 +1 @@ +int hello(void) { return 42; } diff --git a/test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/main.c b/test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/main.c new file mode 100644 index 0000000..58fe692 --- /dev/null +++ b/test/e2e/fixtures/groups_cross_dir_3tree/source/gcc/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} From 609f01faa0d8e6eec7d5da3758ab1b134e000a1d Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:42:44 +0800 Subject: [PATCH 11/16] Remove scheduler workaround for missing source directories in 3-tree mode The scheduler auto-created source-tree directories when a config-tree directory had no counterpart. This papered over a user setup issue rather than honoring the 3-tree model: config tree mirrors source tree. Makefile.pup now creates the binutils/ directory in the source tree as an explicit setup step. Co-Authored-By: Claude Opus 4.6 --- examples/gcc/Makefile.pup | 5 ++--- examples/gcc/binutils/Tupfile | 5 ++--- include/pup/exec/scheduler.hpp | 1 - src/cli/cmd_build.cpp | 1 - src/cli/cmd_configure.cpp | 1 - src/exec/scheduler.cpp | 11 ----------- 6 files changed, 4 insertions(+), 20 deletions(-) diff --git a/examples/gcc/Makefile.pup b/examples/gcc/Makefile.pup index de57ae3..9fd30a9 100644 --- a/examples/gcc/Makefile.pup +++ b/examples/gcc/Makefile.pup @@ -69,9 +69,8 @@ resolve-mpn: fi # Resolve binutils source to an absolute path. -# Commands run from the config tree (putup falls back when the source -# subdir doesn't exist in the -S tree), so absolute paths ensure the -# compiler can always find binutils sources regardless of working directory. +# The source tree must have a binutils/ directory — created by the user +# when setting up their source tree (e.g., symlink, download script). resolve-binutils-src: @if [ -d "$(BINUTILS_DIR)" ]; then \ abs=$$(cd "$(BINUTILS_DIR)" && pwd); \ diff --git a/examples/gcc/binutils/Tupfile b/examples/gcc/binutils/Tupfile index 61d6f5f..8502730 100644 --- a/examples/gcc/binutils/Tupfile +++ b/examples/gcc/binutils/Tupfile @@ -3,14 +3,13 @@ include_rules # ============================================================ # binutils — cross-assembler (as) + cross-archiver (ar) # -# First external package: source via @(BINUTILS_SRC), not -S. +# External package: source via @(BINUTILS_SRC), not -S. # Single Tupfile avoids cross-directory group issues in 3-tree mode. # # Source paths use $(BFD)/, $(GAS)/, $(OPC)/, $(BIN)/ prefixes. # Because the binutils source tree is outside the -S tree, sources # are referenced only in command strings, not as tup inputs. -# putup falls back to the config tree as working directory when -# the source subdir doesn't exist in -S. +# The source tree must have a binutils/ directory (Makefile.pup creates it). # ============================================================ BFD = $(BU)/bfd diff --git a/include/pup/exec/scheduler.hpp b/include/pup/exec/scheduler.hpp index ac91dee..c5de101 100644 --- a/include/pup/exec/scheduler.hpp +++ b/include/pup/exec/scheduler.hpp @@ -67,7 +67,6 @@ struct SchedulerOptions { bool dry_run = false; ///< Print commands without executing bool verbose = false; ///< Print commands as they run std::filesystem::path source_root = {}; ///< Source tree root (where Tupfile.ini lives) - std::filesystem::path config_root = {}; ///< Config tree root (fallback when source subdir missing) std::filesystem::path output_root = {}; ///< Output tree root (where outputs/.pup go) std::optional timeout = {}; ///< Per-command timeout }; diff --git a/src/cli/cmd_build.cpp b/src/cli/cmd_build.cpp index 95c4eb4..8abce74 100644 --- a/src/cli/cmd_build.cpp +++ b/src/cli/cmd_build.cpp @@ -1076,7 +1076,6 @@ auto build_single_variant( .dry_run = opts.dry_run, .verbose = opts.verbose, .source_root = ctx.layout().source_root, - .config_root = ctx.layout().config_root, .output_root = ctx.layout().output_root, }; diff --git a/src/cli/cmd_configure.cpp b/src/cli/cmd_configure.cpp index 71306f6..8eee485 100644 --- a/src/cli/cmd_configure.cpp +++ b/src/cli/cmd_configure.cpp @@ -187,7 +187,6 @@ auto configure_single_variant( .dry_run = opts.dry_run, .verbose = opts.verbose, .source_root = ctx.layout().source_root, - .config_root = ctx.layout().config_root, .output_root = ctx.layout().output_root, }; diff --git a/src/exec/scheduler.cpp b/src/exec/scheduler.cpp index 6969fa5..9a7ab0e 100644 --- a/src/exec/scheduler.cpp +++ b/src/exec/scheduler.cpp @@ -806,17 +806,6 @@ auto Scheduler::build_job_list( if (!source_dir.empty()) { working_dir /= source_dir; } - // In overlay mode (3-tree builds), config-tree directories are projected - // onto the source tree. If this subdir exists in the config tree but not - // the source tree, create it so commands can run from it. - if (!std::filesystem::is_directory(working_dir) - && !impl_->options.config_root.empty() - && !source_dir.empty()) { - auto config_dir = impl_->options.config_root / source_dir; - if (std::filesystem::is_directory(config_dir)) { - std::filesystem::create_directories(working_dir); - } - } // Check if this is a generated rule that captures stdout auto capture_stdout = false; From 43b1d0c66a186040a8c34d5045a2d214045e071c Mon Sep 17 00:00:00 2001 From: Mural <2606021+typeless@users.noreply.github.com> Date: Sun, 22 Feb 2026 15:27:32 +0800 Subject: [PATCH 12/16] Flatten examples/ into a BSP with gcc/ and binutils/ tarball groups The examples/ directory becomes the BSP root (-C tree). Infrastructure (Tupfile.ini, Tuprules.tup, Makefile.pup, configs/, scripts/) moves up from examples/gcc/. Binutils moves to examples/binutils/ as a peer tarball group. GCC-internal packages stay under examples/gcc/ with a new group Tuprules.tup providing ?= defaults for standalone use. Key changes: - Root Tuprules.tup uses gcc/ prefix for all GCC-tarball DIR variables - Binutils uses $(S)/$(BINUTILS_DIR) instead of @(BINUTILS_SRC) - Nested Tupfile.ini markers removed from busybox/ and helloworld/ - Source assembly model: one source-root/ subdir per extracted tarball Co-Authored-By: Claude Opus 4.6 --- examples/{gcc => }/Makefile.pup | 70 ++--- examples/README.md | 113 +++++++- examples/Tupfile | 23 ++ examples/Tupfile.ini | 1 + examples/Tuprules.tup | 27 ++ examples/{gcc => }/binutils/Tupfile | 11 +- examples/{gcc => }/binutils/Tuprules.tup | 8 +- examples/{gcc => }/binutils/tup.config | 1 - examples/busybox/Tupfile.ini | 1 - .../{gcc => }/configs/aarch64-linux.config | 0 .../configs/darwin-x86_64-linux.config | 0 .../{gcc => }/configs/host-darwin/gcc.config | 0 .../{gcc => }/configs/host-darwin/gmp.config | 0 .../configs/host-darwin/libbacktrace.config | 0 .../configs/host-darwin/libcpp.config | 0 .../configs/host-darwin/libdecnumber.config | 0 .../configs/host-darwin/libiberty.config | 0 .../{gcc => }/configs/host-darwin/mpc.config | 0 .../{gcc => }/configs/host-darwin/mpfr.config | 0 .../{gcc => }/configs/x86_64-linux.config | 0 examples/gcc/README.md | 265 ------------------ examples/gcc/Tupfile | 22 -- examples/gcc/Tupfile.ini | 2 +- examples/gcc/Tuprules.tup | 38 ++- examples/helloworld/Tupfile.ini | 0 examples/{gcc => }/scripts/resolve-mpn.sh | 0 26 files changed, 213 insertions(+), 369 deletions(-) rename examples/{gcc => }/Makefile.pup (53%) create mode 100644 examples/Tupfile create mode 100644 examples/Tupfile.ini create mode 100644 examples/Tuprules.tup rename examples/{gcc => }/binutils/Tupfile (94%) rename examples/{gcc => }/binutils/Tuprules.tup (83%) rename examples/{gcc => }/binutils/tup.config (97%) delete mode 100644 examples/busybox/Tupfile.ini rename examples/{gcc => }/configs/aarch64-linux.config (100%) rename examples/{gcc => }/configs/darwin-x86_64-linux.config (100%) rename examples/{gcc => }/configs/host-darwin/gcc.config (100%) rename examples/{gcc => }/configs/host-darwin/gmp.config (100%) rename examples/{gcc => }/configs/host-darwin/libbacktrace.config (100%) rename examples/{gcc => }/configs/host-darwin/libcpp.config (100%) rename examples/{gcc => }/configs/host-darwin/libdecnumber.config (100%) rename examples/{gcc => }/configs/host-darwin/libiberty.config (100%) rename examples/{gcc => }/configs/host-darwin/mpc.config (100%) rename examples/{gcc => }/configs/host-darwin/mpfr.config (100%) rename examples/{gcc => }/configs/x86_64-linux.config (100%) delete mode 100644 examples/gcc/README.md delete mode 100644 examples/gcc/Tupfile delete mode 100644 examples/helloworld/Tupfile.ini rename examples/{gcc => }/scripts/resolve-mpn.sh (100%) diff --git a/examples/gcc/Makefile.pup b/examples/Makefile.pup similarity index 53% rename from examples/gcc/Makefile.pup rename to examples/Makefile.pup index 9fd30a9..4f8b23f 100644 --- a/examples/gcc/Makefile.pup +++ b/examples/Makefile.pup @@ -14,73 +14,62 @@ # make -f Makefile.pup PLATFORM=darwin-x86_64-linux HOST=darwin # # 3-tree layout: -# -C . Tupfiles live here (examples/gcc/) -# -S $(SRCDIR) GCC source tree (read-only) +# -C . BSP root (examples/) +# -S $(SRCDIR) Assembled source tree (gcc/, binutils/ subdirs) # -B $(BUILD) Build output directory -.PHONY: all build configure resolve-mpn resolve-binutils-src setup-host-configs \ +.PHONY: all build configure resolve-mpn setup-host-configs \ clean distclean download-source download-binutils PLATFORM ?= x86_64-linux HOST ?= linux -SRCDIR ?= ../gcc-15.2.0 +SRCDIR ?= ../source-root BUILD ?= ../build-gcc MPN_CPU ?= generic TREES = -C . -S $(SRCDIR) -B $(BUILD) all: build -build: resolve-mpn setup-host-configs resolve-binutils-src +build: resolve-mpn setup-host-configs putup configure --config configs/$(PLATFORM).config $(TREES) putup $(TREES) -j$$(nproc) -configure: resolve-mpn setup-host-configs resolve-binutils-src +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 -- */tup.config +# To restore Linux defaults: git checkout -- gcc/*/tup.config setup-host-configs: @if [ "$(HOST)" != "linux" ] && [ -d configs/host-$(HOST) ]; then \ for cfg in configs/host-$(HOST)/*.config; do \ lib=$$(basename "$$cfg" .config); \ - echo " COPY $$lib/tup.config (host-$(HOST))"; \ - cp "$$cfg" "$$lib/tup.config"; \ + echo " COPY gcc/$$lib/tup.config (host-$(HOST))"; \ + cp "$$cfg" "gcc/$$lib/tup.config"; \ done; \ fi # Resolve mpn sources for the selected CPU target. -# - gmp/mpn/tup.config: source lists and per-function toggles (child scope) -# - gmp/tup.config: GMP_MPARAM and ASM_ENABLED (parent scope, visible to gmp/Tupfile) +# - gcc/gmp/mpn/tup.config: source lists and per-function toggles (child scope) +# - gcc/gmp/tup.config: GMP_MPARAM and ASM_ENABLED (parent scope, visible to gmp/Tupfile) resolve-mpn: - @scripts/resolve-mpn.sh $(MPN_CPU) $(SRCDIR)/gmp/mpn > gmp/mpn/tup.config - @grep -v '^CONFIG_GMP_MPARAM=\|^CONFIG_ASM_ENABLED=\|^CONFIG_NO_ASM=' gmp/tup.config > gmp/tup.config.tmp && mv gmp/tup.config.tmp gmp/tup.config + @scripts/resolve-mpn.sh $(MPN_CPU) $(SRCDIR)/gcc/gmp/mpn > gcc/gmp/mpn/tup.config + @grep -v '^CONFIG_GMP_MPARAM=\|^CONFIG_ASM_ENABLED=\|^CONFIG_NO_ASM=' gcc/gmp/tup.config > gcc/gmp/tup.config.tmp && mv gcc/gmp/tup.config.tmp gcc/gmp/tup.config @if [ "$(MPN_CPU)" != "generic" ]; then \ arch=$${MPN_CPU%%/*}; \ - if [ -f "$(SRCDIR)/gmp/mpn/$$arch/gmp-mparam.h" ]; then \ - echo "CONFIG_GMP_MPARAM=mpn/$$arch/gmp-mparam.h" >> gmp/tup.config; \ + if [ -f "$(SRCDIR)/gcc/gmp/mpn/$$arch/gmp-mparam.h" ]; then \ + echo "CONFIG_GMP_MPARAM=mpn/$$arch/gmp-mparam.h" >> gcc/gmp/tup.config; \ else \ - echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gmp/tup.config; \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gcc/gmp/tup.config; \ fi; \ - echo "CONFIG_ASM_ENABLED=y" >> gmp/tup.config; \ + echo "CONFIG_ASM_ENABLED=y" >> gcc/gmp/tup.config; \ else \ - echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gmp/tup.config; \ - echo "CONFIG_NO_ASM=1" >> gmp/tup.config; \ - fi - -# Resolve binutils source to an absolute path. -# The source tree must have a binutils/ directory — created by the user -# when setting up their source tree (e.g., symlink, download script). -resolve-binutils-src: - @if [ -d "$(BINUTILS_DIR)" ]; then \ - abs=$$(cd "$(BINUTILS_DIR)" && pwd); \ - grep -v '^CONFIG_BINUTILS_SRC=' binutils/tup.config > binutils/tup.config.tmp; \ - echo "CONFIG_BINUTILS_SRC=$$abs" >> binutils/tup.config.tmp; \ - mv binutils/tup.config.tmp binutils/tup.config; \ + echo "CONFIG_GMP_MPARAM=mpn/generic/gmp-mparam.h" >> gcc/gmp/tup.config; \ + echo "CONFIG_NO_ASM=1" >> gcc/gmp/tup.config; \ fi # Multi-variant: build for multiple platforms in parallel -# make -f Makefile.pup multi SRCDIR=../gcc-15.2.0 +# make -f Makefile.pup multi SRCDIR=../source-root PLATFORMS ?= x86_64-linux aarch64-linux multi: @for p in $(PLATFORMS); do \ @@ -88,27 +77,30 @@ multi: done putup $(foreach p,$(PLATFORMS),-B $(BUILD)-$(p)) -C . -S $(SRCDIR) -j$$(nproc) -# Download GCC source for reference/building +# Download and assemble source tree. +# Source assembly: extract each tarball, rename into $(SRCDIR)/. GCC_VERSION ?= 15.2.0 BINUTILS_VERSION ?= 2.44 -BINUTILS_DIR ?= ../binutils-$(BINUTILS_VERSION) download-source: download-binutils - @if [ ! -d "$(SRCDIR)" ]; then \ + @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 -C $$(dirname $(SRCDIR)); \ + | tar xJ --strip-components=1 -C $(SRCDIR)/gcc; \ + cd $(SRCDIR)/gcc && ./contrib/download_prerequisites; \ else \ - echo "$(SRCDIR) already exists"; \ + echo "$(SRCDIR)/gcc already exists"; \ fi download-binutils: - @if [ ! -d "$(BINUTILS_DIR)" ]; then \ + @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 -C $$(dirname $(BINUTILS_DIR)); \ + | tar xJ --strip-components=1 -C $(SRCDIR)/binutils; \ else \ - echo "$(BINUTILS_DIR) already exists"; \ + echo "$(SRCDIR)/binutils already exists"; \ fi clean: diff --git a/examples/README.md b/examples/README.md index 2843ffc..4607ede 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,109 @@ -# Putup Examples +# BSP — Board Support Package Example -| Example | Description | -|---------|-------------| -| [helloworld](helloworld/) | Minimal single-file C project | -| [busybox](busybox/) | Cross-compile Busybox (33 Tupfiles, 403 applets) | +A complete cross-compiler toolchain built from source using putup. +Demonstrates multi-tarball, multi-package builds with 3-tree mode (`-C`, `-S`, `-B`). + +## Packages + +``` +gcc/ GCC tarball group (gcc-15.2.0) + gcc/ Compiler: cc1, cc1plus, xgcc, xg++, cpp, collect2, ... + gmp/ Math library: libgmp.a + mpfr/ Multi-precision floats: libmpfr.a + mpc/ Complex arithmetic: libmpc.a + libiberty/ Utility library: libiberty.a + libcpp/ C preprocessor: libcpp.a + libdecnumber/ Decimal floating-point: libdecnumber.a + libbacktrace/ Stack unwinding: libbacktrace.a + libcody/ C++ modules protocol: libcody.a + +binutils/ binutils tarball group (binutils-2.44) + Cross-assembler (as) + cross-archiver (ar) + +busybox/ busybox (deferred — not yet BSP-integrated) +helloworld/ test package (deferred — not yet BSP-integrated) +``` + +## Source Tree Assembly + +Each top-level config directory maps to one extracted tarball. +Assemble the source tree by extracting and renaming: + +```bash +mkdir -p source-root +# GCC (includes GMP, MPFR, MPC via download_prerequisites) +tar xf gcc-15.2.0.tar.xz +mv gcc-15.2.0 source-root/gcc +cd source-root/gcc && ./contrib/download_prerequisites && cd ../.. + +# binutils +tar xf binutils-2.44.tar.xz +mv binutils-2.44 source-root/binutils +``` + +The config tree (`-C examples/`) mirrors the source tree (`-S source-root/`): + +``` +examples/ (config tree) source-root/ (source tree) +├── gcc/ ├── gcc/ +│ ├── gcc/ │ ├── gcc/ +│ ├── gmp/ │ ├── gmp/ +│ └── ... │ └── ... +└── binutils/ └── binutils/ +``` + +## Quick Start + +```bash +cd examples + +# Assemble source tree (or use: make -f Makefile.pup download-source) +# ... see above ... + +# Build (macOS host → x86-64 Linux target) +make -f Makefile.pup SRCDIR=../source-root PLATFORM=darwin-x86_64-linux HOST=darwin + +# Or directly with putup: +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 +``` + +## Scoped Builds + +Build individual packages without rebuilding everything: + +```bash +# Just binutils +putup -C . -S ../source-root -B ../build-gcc binutils/ + +# Just the GCC compiler (assuming libraries are already built) +putup -C . -S ../source-root -B ../build-gcc gcc/gcc/ + +# Just GMP +putup -C . -S ../source-root -B ../build-gcc gcc/gmp/ +``` + +## Standalone Mode + +Each package group is independently buildable. The `?=` defaults in each +package's `Tuprules.tup` provide flat paths when there's no BSP root above: + +```bash +# Build just the GCC group (standalone) +cd gcc +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 +``` + +## Architecture + +- **Root `Tuprules.tup`** uses `=` (force-set) for all DIR variables with `gcc/` prefix +- **Group `Tuprules.tup`** uses `?=` (default) — overridden in BSP mode, effective standalone +- **Package `Tuprules.tup`** uses `?=` for toolchain vars — overridden by both root and group +- `include_rules` processes root-first; BSP root wins over group defaults + +## Known Limitations + +- putup `create_directories` crashes on symlinks in source tree +- busybox and helloworld are not yet integrated into the BSP (use `$(CC)` from root config) diff --git a/examples/Tupfile b/examples/Tupfile new file mode 100644 index 0000000..f3c63c0 --- /dev/null +++ b/examples/Tupfile @@ -0,0 +1,23 @@ +include_rules + +# Root Tupfile - nothing to do here +# Packages are built by their respective Tupfiles: +# +# GCC tarball (gcc/): +# gcc/gmp/Tupfile → libgmp.a +# gcc/mpfr/src/Tupfile → libmpfr.a +# gcc/mpc/src/Tupfile → libmpc.a +# gcc/libiberty/Tupfile → libiberty.a +# gcc/libdecnumber/Tupfile → libdecnumber.a +# gcc/libbacktrace/Tupfile → libbacktrace.a +# gcc/libcpp/Tupfile → libcpp.a +# gcc/libcody/Tupfile → libcody.a +# gcc/gcc/Tupfile → cc1, cc1plus, xgcc, xg++, cpp, collect2, ... +# gcc/gcc/c/Tupfile → C frontend objects +# gcc/gcc/cp/Tupfile → C++ frontend objects +# gcc/gcc/c-family/Tupfile → C-family shared objects +# gcc/gcc/analyzer/Tupfile → Static analyzer objects +# gcc/gcc/config/i386/Tupfile → x86_64 target-specific objects +# +# binutils tarball (binutils/): +# binutils/Tupfile → as (cross-assembler), ar (cross-archiver) diff --git a/examples/Tupfile.ini b/examples/Tupfile.ini new file mode 100644 index 0000000..10c3ed8 --- /dev/null +++ b/examples/Tupfile.ini @@ -0,0 +1 @@ +# BSP - pup build configuration diff --git a/examples/Tuprules.tup b/examples/Tuprules.tup new file mode 100644 index 0000000..4111dca --- /dev/null +++ b/examples/Tuprules.tup @@ -0,0 +1,27 @@ +# Tuprules.tup - BSP root rules +# +# Sets project-wide variables from tup.config. +# Per-package rules live in each package's own Tuprules.tup. +# Uses = (force-set) so these override ?= defaults in group/package rules. + +S = $(TUP_CWD) +B = $(TUP_VARIANT_OUTPUTDIR)/$(S) + +CC = @(CC) +CXX = @(CXX) +AR = @(AR) +HOSTCC = @(HOSTCC) + +# GCC tarball group +GCC_DIR = gcc/gcc +GMP_DIR = gcc/gmp +MPFR_DIR = gcc/mpfr +MPC_DIR = gcc/mpc +LIBIBERTY_DIR = gcc/libiberty +LIBCPP_DIR = gcc/libcpp +LIBDECNUMBER_DIR = gcc/libdecnumber +LIBBACKTRACE_DIR = gcc/libbacktrace +LIBCODY_DIR = gcc/libcody + +# binutils tarball group +BINUTILS_DIR = binutils diff --git a/examples/gcc/binutils/Tupfile b/examples/binutils/Tupfile similarity index 94% rename from examples/gcc/binutils/Tupfile rename to examples/binutils/Tupfile index 8502730..fba2135 100644 --- a/examples/gcc/binutils/Tupfile +++ b/examples/binutils/Tupfile @@ -3,19 +3,14 @@ include_rules # ============================================================ # binutils — cross-assembler (as) + cross-archiver (ar) # -# External package: source via @(BINUTILS_SRC), not -S. # Single Tupfile avoids cross-directory group issues in 3-tree mode. -# -# Source paths use $(BFD)/, $(GAS)/, $(OPC)/, $(BIN)/ prefixes. -# Because the binutils source tree is outside the -S tree, sources -# are referenced only in command strings, not as tup inputs. -# The source tree must have a binutils/ directory (Makefile.pup creates it). +# Source paths use $(BFD)/, $(GAS)/, $(OPC)/, $(BU_BIN)/ prefixes. # ============================================================ BFD = $(BU)/bfd GAS = $(BU)/gas OPC = $(BU)/opcodes -BIN = $(BU)/binutils +BU_BIN = $(BU)/binutils OUT = $(B)/$(BINUTILS_DIR) # --- Phase 1: Generated headers --- @@ -167,7 +162,7 @@ ar_names = ar arsup not-ranlib bucomm rename binemul emul_vanilla version filemo : | |> ^ CC-BU (11 files)^ for f in $(ar_names); do \ $(CC) $(CFLAGS) $(BINUTILS_INCLUDES) $(BFD_INCLUDES) \ -Dbin_dummy_emulation=bin_vanilla_emulation \ - -c $(BIN)/$$f.c -o $(OUT)/$$f.o || exit 1; \ + -c $(BU_BIN)/$$f.c -o $(OUT)/$$f.o || exit 1; \ done |> \ ar.o arsup.o not-ranlib.o bucomm.o rename.o binemul.o emul_vanilla.o \ version.o filemode.o arparse.o arlex.o \ diff --git a/examples/gcc/binutils/Tuprules.tup b/examples/binutils/Tuprules.tup similarity index 83% rename from examples/gcc/binutils/Tuprules.tup rename to examples/binutils/Tuprules.tup index f6254c1..edada26 100644 --- a/examples/gcc/binutils/Tuprules.tup +++ b/examples/binutils/Tuprules.tup @@ -2,8 +2,6 @@ # # Composed mode: parent sets S, B, CC, AR, LIBIBERTY_DIR, BINUTILS_DIR. # Standalone mode: ?= defaults take effect. -# -# Source is a separate tree from GCC, referenced via @(BINUTILS_SRC). S ?= $(TUP_CWD) B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) @@ -12,10 +10,8 @@ AR_CMD ?= ar LIBIBERTY_DIR ?= libiberty BINUTILS_DIR ?= . -# Binutils source root (separate from GCC -S tree). -# Resolved to an absolute path by Makefile.pup (resolve-binutils-src) -# so commands work from the build variant directory. -BU = @(BINUTILS_SRC) +# Binutils source root — resolved via $(S)/$(BINUTILS_DIR) +BU = $(S)/$(BINUTILS_DIR) # Resolved library paths LIBIBERTY_A = $(B)/$(LIBIBERTY_DIR)/libiberty.a diff --git a/examples/gcc/binutils/tup.config b/examples/binutils/tup.config similarity index 97% rename from examples/gcc/binutils/tup.config rename to examples/binutils/tup.config index de8d612..246437e 100644 --- a/examples/gcc/binutils/tup.config +++ b/examples/binutils/tup.config @@ -109,4 +109,3 @@ CONFIG_TLS=__thread # Debug info directory CONFIG_DEBUGDIR="/usr/lib/debug" -CONFIG_BINUTILS_SRC=/Users/mural/Developer/pup/examples/binutils-2.44 diff --git a/examples/busybox/Tupfile.ini b/examples/busybox/Tupfile.ini deleted file mode 100644 index 2b3d4f6..0000000 --- a/examples/busybox/Tupfile.ini +++ /dev/null @@ -1 +0,0 @@ -# Busybox - pup build configuration diff --git a/examples/gcc/configs/aarch64-linux.config b/examples/configs/aarch64-linux.config similarity index 100% rename from examples/gcc/configs/aarch64-linux.config rename to examples/configs/aarch64-linux.config diff --git a/examples/gcc/configs/darwin-x86_64-linux.config b/examples/configs/darwin-x86_64-linux.config similarity index 100% rename from examples/gcc/configs/darwin-x86_64-linux.config rename to examples/configs/darwin-x86_64-linux.config diff --git a/examples/gcc/configs/host-darwin/gcc.config b/examples/configs/host-darwin/gcc.config similarity index 100% rename from examples/gcc/configs/host-darwin/gcc.config rename to examples/configs/host-darwin/gcc.config diff --git a/examples/gcc/configs/host-darwin/gmp.config b/examples/configs/host-darwin/gmp.config similarity index 100% rename from examples/gcc/configs/host-darwin/gmp.config rename to examples/configs/host-darwin/gmp.config diff --git a/examples/gcc/configs/host-darwin/libbacktrace.config b/examples/configs/host-darwin/libbacktrace.config similarity index 100% rename from examples/gcc/configs/host-darwin/libbacktrace.config rename to examples/configs/host-darwin/libbacktrace.config diff --git a/examples/gcc/configs/host-darwin/libcpp.config b/examples/configs/host-darwin/libcpp.config similarity index 100% rename from examples/gcc/configs/host-darwin/libcpp.config rename to examples/configs/host-darwin/libcpp.config diff --git a/examples/gcc/configs/host-darwin/libdecnumber.config b/examples/configs/host-darwin/libdecnumber.config similarity index 100% rename from examples/gcc/configs/host-darwin/libdecnumber.config rename to examples/configs/host-darwin/libdecnumber.config diff --git a/examples/gcc/configs/host-darwin/libiberty.config b/examples/configs/host-darwin/libiberty.config similarity index 100% rename from examples/gcc/configs/host-darwin/libiberty.config rename to examples/configs/host-darwin/libiberty.config diff --git a/examples/gcc/configs/host-darwin/mpc.config b/examples/configs/host-darwin/mpc.config similarity index 100% rename from examples/gcc/configs/host-darwin/mpc.config rename to examples/configs/host-darwin/mpc.config diff --git a/examples/gcc/configs/host-darwin/mpfr.config b/examples/configs/host-darwin/mpfr.config similarity index 100% rename from examples/gcc/configs/host-darwin/mpfr.config rename to examples/configs/host-darwin/mpfr.config diff --git a/examples/gcc/configs/x86_64-linux.config b/examples/configs/x86_64-linux.config similarity index 100% rename from examples/gcc/configs/x86_64-linux.config rename to examples/configs/x86_64-linux.config diff --git a/examples/gcc/README.md b/examples/gcc/README.md deleted file mode 100644 index fa5f317..0000000 --- a/examples/gcc/README.md +++ /dev/null @@ -1,265 +0,0 @@ -# GCC Cross-Compiler Toolchain from Source - -Build a complete GCC 15.2.0 cross-compiler toolchain using putup. -This builds everything from source: prerequisite math libraries, compiler support -libraries, ~25 host generator programs, the ~500-file compiler backend, C/C++ -frontends, driver programs, developer tools, and GNU binutils (assembler + archiver) -— 3600+ build commands in ~140s. - -## Quick Start - -```bash -# 1. Download and extract GCC (includes GMP, MPFR, MPC) -cd /path/to -wget https://gcc.gnu.org/pub/gcc/releases/gcc-15.2.0/gcc-15.2.0.tar.xz -tar xf gcc-15.2.0.tar.xz -cd gcc-15.2.0 && ./contrib/download_prerequisites && cd .. - -# 2. Download binutils (assembler + archiver) -cd examples/gcc -make -f Makefile.pup download-binutils - -# 3. Build toolchain -make -f Makefile.pup SRCDIR=/path/to/gcc-15.2.0 BUILD=../build-gcc -``` - -## What Gets Built - -``` -Libraries (parallel): - gmp/ → libgmp.a Math library - mpfr/ → libmpfr.a Multi-precision floats (needs GMP) - mpc/ → libmpc.a Complex arithmetic (needs GMP + MPFR) - libiberty/ → libiberty.a Utility library - libdecnumber/ → libdecnumber.a Decimal floating-point (DPD variant) - libbacktrace/ → libbacktrace.a Stack unwinding (ELF/mmap) - libcpp/ → libcpp.a C preprocessor - libcody/ → libcody.a C++ modules protocol - -Generators (need libiberty): - gcc/ → genmodes, genattr, genemit, genrecog, ... (~25 host programs) - → insn-*.h, insn-*.cc (generated machine descriptions) - → gtype-desc.cc, gt-*.h (~60 GC type descriptor headers) - -Compilers: - gcc/ → cc1 C compiler backend (~500 objects) - gcc/ → cc1plus C++ compiler backend (+ 40 cp/ objects) - -Drivers: - gcc/ → xgcc C compiler driver - gcc/ → xg++ C++ compiler driver - gcc/ → cpp C preprocessor driver - -Tools: - gcc/ → collect2 Linker wrapper (C++ ctor/dtor collection) - gcc/ → lto-wrapper LTO linker plugin interface - gcc/ → gcov Code coverage analysis - gcc/ → gcov-dump Coverage data inspector - -Binutils (separate source tree): - binutils/ → as Cross-assembler (x86_64 ELF) - binutils/ → ar Cross-archiver -``` - -## Dependency Chain - -``` -GMP ──────────────────────────────────→ libgmp.a ──→ cc1 - ↓ ↑ -MPFR (needs GMP) ─────────────────→ libmpfr.a ────────┘ - ↓ ↑ -MPC (needs GMP + MPFR) ──────────→ libmpc.a ──────────┘ - ↑ -libiberty ─→ libiberty.a ─→ generators ─→ insn-*.h ───┘ - ↓ ↑ ↑ -libdecnumber ──────────────→ libdecnumber.a ┘ │ -libbacktrace ──────────────→ libbacktrace.a ───────────┘ - ↑ -libcpp ────────────────────→ libcpp.a ─────────────────┘ - -binutils (separate source): - libiberty.a ──→ bfd + opcodes + gas ──→ as - libiberty.a ──→ bfd + ar objects ─────→ ar -``` - -## Per-Component Configuration - -Each library has its own `tup.config` with prefix-free entries. The directory scope -provides the namespace via scoped config merging: - -``` -configs/x86_64-linux.config → Root: CC, CXX, AR, HOSTCC (toolchain) -gmp/tup.config → GMP: HAVE_ALLOCA, SIZEOF_UNSIGNED_LONG, ... -mpfr/tup.config → MPFR: HAVE_ALLOCA, HAVE_VA_COPY, ... -mpc/tup.config → MPC: HAVE_INTTYPES_H, HAVE_LOCALECONV, ... -libiberty/tup.config → libiberty: HAVE_SBRK, HAVE_MMAP, ... -libdecnumber/tup.config → libdecnumber: endianness, float format -libbacktrace/tup.config → libbacktrace: BACKTRACE_ELF_SIZE, HAVE_DL_ITERATE_PHDR, ... -libcpp/tup.config → libcpp: HAVE_ICONV, ENABLE_NLS, ... -gcc/tup.config → GCC: HOST_BITS_PER_*, SIZEOF_*, HAVE_*, ... -binutils/tup.config → binutils: BFD64, target arch, host capabilities -``` - -`putup configure --config` installs the root config and copies subdir configs to the -build tree in a single invocation. Scoped config merging then combines them: - -- `@(CC)` in gmp/ resolves to `gcc` (from root tup.config) -- `@(HAVE_ALLOCA)` in gmp/ resolves to `1` (from gmp/tup.config) -- `@(HAVE_ALLOCA)` in mpfr/ resolves to `1` (from mpfr/tup.config) - -Each library's `!gen-config` reads the raw `$(B)/tup.config` to generate `config.h`, -stripping the 7-char `CONFIG_` prefix from each entry. - -### Standalone vs Composed - -Each library is self-contained and can be built independently: - -```bash -# Standalone: build just GMP -cd gmp && putup configure && putup -``` - -When composed under the root project, the root `Tuprules.tup` sets toolchain variables -that override each library's `?=` defaults. The same `tup.config` file serves as the -root config in standalone mode and as a scoped subdir config in composed mode. - -### Multi-Platform Support - -The build uses config-variable substitution for platform selection. Target-specific -rules (tm.h, tm_p.h, MD files, gtyp entries) live in `gcc/targets/@(TARGET).tup`: - -``` -configs/x86_64-linux.config → Native Linux x86-64 -configs/darwin-x86_64-linux.config → macOS host, Linux x86-64 target -configs/host-darwin/ → macOS-specific library configs -gcc/targets/x86_64-pc-linux-gnu.tup → x86_64-linux target rules -``` - -**Cross-compiler (macOS host → x86-64 Linux target):** - -```bash -make -f Makefile.pup PLATFORM=darwin-x86_64-linux HOST=darwin -``` - -This builds cc1 using Apple Clang on macOS, producing a compiler that generates -x86_64 Linux code. The `HOST=darwin` flag copies macOS-specific library configs -(feature detection for macOS: no `-ldl`, Mach-O libbacktrace, different iconv, etc.) - -### Multi-Variant Builds - -Build multiple platforms in parallel with a single putup invocation: - -```bash -# Configure each variant (different toolchain per variant) -putup configure --config configs/x86_64-linux.config -C . -S ../gcc-15.2.0 -B ../build-gcc-x86_64-linux -putup configure --config configs/aarch64-linux.config -C . -S ../gcc-15.2.0 -B ../build-gcc-aarch64-linux - -# Build both variants in parallel -putup -C . -S ../gcc-15.2.0 -B ../build-gcc-x86_64-linux -B ../build-gcc-aarch64-linux -j$(nproc) -``` - -Or via the Makefile: - -```bash -make -f Makefile.pup multi SRCDIR=../gcc-15.2.0 -``` - -## Generator Bootstrap - -GCC generates machine-specific code from `.md` (machine description) files. -The generators form a bootstrap chain: - -``` -genmodes (no RTL deps) - → insn-modes.h, insn-modes-inline.h, min-insn-modes.cc - → compile min-insn-modes.o - -BUILD_RTL objects (need min-insn-modes.o) - → rtl.o, read-md.o, read-rtl.o, gensupport.o, ... - -genconditions → gencondmd.cc → compile+link gencondmd → insn-conditions.md - -All other generators (read .md files, produce insn-*.h / insn-*.cc) - → genattr, genattrtab, genautomata, gencodes, genconfig, ... - → genemit (10 split outputs), genrecog (10 split outputs + header) - -gengtype (GC type descriptors, needs libiberty) - → parses GTY annotations from gtyp-input.list - → gtype-desc.cc, gtype-desc.h, gtype-c.h, gt-*.h (~60 headers) -``` - -## Assembly Support - -By default, GMP builds in generic C mode (equivalent to `--disable-assembly`). -For CPU-specific assembly, pass `MPN_CPU`: - -```bash -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) -``` - -## Files - -| File | Purpose | -|------|---------| -| `Makefile.pup` | Make wrapper for putup commands | -| `scripts/resolve-mpn.sh` | Resolve mpn sources for a CPU target | -| `Tupfile.ini` | Project root marker | -| `Tuprules.tup` | Toolchain vars (CC, CXX, AR, HOSTCC), directory names | -| `configs/x86_64-linux.config` | Toolchain config (x86-64 Linux, native) | -| `configs/aarch64-linux.config` | Toolchain config (AArch64 Linux, cross) | -| **GMP** | | -| `gmp/{Tuprules.tup,tup.config,Tupfile}` | Config, rules, top-level sources | -| `gmp/{mpn,mpz,mpq,mpf,printf,scanf,rand}/Tupfile` | Per-directory compilation | -| **MPFR** | | -| `mpfr/{Tuprules.tup,tup.config,Tupfile}` | Config generation | -| `mpfr/src/Tupfile` | Source compilation + archive | -| **MPC** | | -| `mpc/{Tuprules.tup,tup.config,Tupfile}` | Config generation | -| `mpc/src/Tupfile` | Source compilation + archive | -| **libiberty** | | -| `libiberty/{Tuprules.tup,tup.config,Tupfile}` | Utility library | -| **libdecnumber** | | -| `libdecnumber/{Tuprules.tup,tup.config,Tupfile}` | Decimal number library | -| **libbacktrace** | | -| `libbacktrace/{Tuprules.tup,tup.config,Tupfile}` | Backtrace library | -| **libcpp** | | -| `libcpp/{Tuprules.tup,tup.config,Tupfile}` | C preprocessor library | -| **libcody** | | -| `libcody/{Tuprules.tup,tup.config,Tupfile}` | C++ modules protocol library | -| **GCC (compilers + tools)** | | -| `gcc/{Tuprules.tup,tup.config,Tupfile}` | Config headers, generators, backend, tools | -| `gcc/c/Tupfile` | C frontend objects | -| `gcc/cp/Tupfile` | C++ frontend objects | -| `gcc/c-family/Tupfile` | C-family shared objects | -| `gcc/analyzer/Tupfile` | Static analyzer objects | -| `gcc/config/i386/Tupfile` | x86_64 target-specific objects | -| `gcc/targets/x86_64-pc-linux-gnu.tup` | Target-specific machine description rules | -| **binutils** (separate source tree) | | -| `binutils/{Tuprules.tup,tup.config,Tupfile}` | Cross-assembler + cross-archiver | - -## Build Features Demonstrated - -- **Host-tool bootstrapping**: ~25 generator programs compiled and run during the build -- **Generated source pipeline**: `.md` → generators → `insn-*.h` / `insn-*.cc` → cc1 -- **GC type descriptor generation**: gengtype parses GTY annotations across all source files, producing `gtype-desc.cc` and ~60 `gt-*.h` headers -- **Multi-output generators**: genemit produces 10 split files, genrecog produces 10 + header -- **~500-file C++ compilation**: Full GCC backend with analyzer, C frontend, target-specific code -- **Cross-directory groups**: Subdirectory objects collected via `../` into parent -- **Assembly support**: CPU-specific `.asm → m4 → assembler` pipeline with config-driven source selection -- **foo-y conditional compilation**: Kbuild-inspired pattern for toggling multi-function sources without `ifeq` -- **Multi-variant parallel builds**: Multiple `-B` directories built simultaneously with different toolchain configs -- **Per-component scoped configs**: Each library has its own `tup.config`, merged with root via scoped config merging -- **Multi-directory builds**: 15+ subdirectories, each with its own Tupfile -- **3-tree builds**: Tupfiles, GCC sources, and build output in separate directories (`-C`, `-S`, `-B`) -- **Self-contained libraries**: Each library has its own `Tuprules.tup` with `?=` defaults; buildable alone or composed -- **Nested `include_rules`**: Root `Tuprules.tup` sets toolchain, per-library `Tuprules.tup` adds flags and bang macros -- **Inter-library dependencies**: Order-only groups ensure correct build ordering -- **Multi-source-tree packages**: binutils uses `@(BINUTILS_SRC)` for its own source tree, separate from GCC's `-S` - -## Notes - -- Requires: gcc, g++, m4 (for GMP assembly mode), gawk (for GCC options pipeline) -- Target: x86_64-linux native (host == target) -- All generators (including gengtype) are built and run as part of the normal build — no `./configure && make` step required diff --git a/examples/gcc/Tupfile b/examples/gcc/Tupfile deleted file mode 100644 index 5ebc6c9..0000000 --- a/examples/gcc/Tupfile +++ /dev/null @@ -1,22 +0,0 @@ -include_rules - -# Root Tupfile - nothing to do here -# Components are built by their respective Tupfiles: -# -# Prerequisite libraries: -# gmp/Tupfile → libgmp.a -# mpfr/src/Tupfile → libmpfr.a -# mpc/src/Tupfile → libmpc.a -# -# Compiler support libraries: -# libiberty/Tupfile → libiberty.a -# libdecnumber/Tupfile → libdecnumber.a -# libbacktrace/Tupfile → libbacktrace.a -# libcpp/Tupfile → libcpp.a -# -# C compiler: -# gcc/Tupfile → cc1 (config headers, generators, backend) -# gcc/c/Tupfile → C frontend objects -# gcc/c-family/Tupfile → C-family shared objects -# gcc/analyzer/Tupfile → Static analyzer objects -# gcc/config/i386/Tupfile → x86_64 target-specific objects diff --git a/examples/gcc/Tupfile.ini b/examples/gcc/Tupfile.ini index e9839ba..3a94e71 100644 --- a/examples/gcc/Tupfile.ini +++ b/examples/gcc/Tupfile.ini @@ -1 +1 @@ -# GCC Libraries - pup build configuration +# GCC tarball group diff --git a/examples/gcc/Tuprules.tup b/examples/gcc/Tuprules.tup index dd25173..71b890d 100644 --- a/examples/gcc/Tuprules.tup +++ b/examples/gcc/Tuprules.tup @@ -1,24 +1,20 @@ -# Tuprules.tup - GCC in-tree build (root rules) -# -# Sets project-wide variables from tup.config. -# Per-library CFLAGS, !cc, and !gen-config live in each -# library's own Tuprules.tup (gmp/, mpfr/, mpc/, libiberty/, etc.). +# gcc group rules — ?= defaults for standalone use. +# In BSP mode, root Tuprules.tup overrides these with gcc/ prefix. -S = $(TUP_CWD) -B = $(TUP_VARIANT_OUTPUTDIR)/$(S) +S ?= $(TUP_CWD) +B ?= $(TUP_VARIANT_OUTPUTDIR)/$(S) -CC = @(CC) -CXX = @(CXX) -AR = @(AR) -HOSTCC = @(HOSTCC) +CC ?= @(CC) +CXX ?= @(CXX) +AR ?= @(AR) +HOSTCC ?= @(HOSTCC) -GMP_DIR = gmp -MPFR_DIR = mpfr -MPC_DIR = mpc -LIBIBERTY_DIR = libiberty -LIBCPP_DIR = libcpp -LIBDECNUMBER_DIR = libdecnumber -LIBBACKTRACE_DIR = libbacktrace -LIBCODY_DIR = libcody -GCC_DIR = gcc -BINUTILS_DIR = binutils +GCC_DIR ?= gcc +GMP_DIR ?= gmp +MPFR_DIR ?= mpfr +MPC_DIR ?= mpc +LIBIBERTY_DIR ?= libiberty +LIBCPP_DIR ?= libcpp +LIBDECNUMBER_DIR ?= libdecnumber +LIBBACKTRACE_DIR ?= libbacktrace +LIBCODY_DIR ?= libcody diff --git a/examples/helloworld/Tupfile.ini b/examples/helloworld/Tupfile.ini deleted file mode 100644 index e69de29..0000000 diff --git a/examples/gcc/scripts/resolve-mpn.sh b/examples/scripts/resolve-mpn.sh similarity index 100% rename from examples/gcc/scripts/resolve-mpn.sh rename to examples/scripts/resolve-mpn.sh From 37cbdc587eed3cbd2af961011d0d387e1e09cae9 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:23:42 +0800 Subject: [PATCH 13/16] Fix 3-tree build issues and clean up GCC example for Linux host Core fixes for symlink-safe path resolution in 3-tree mode: canonicalize source/output paths in builder, scheduler, and dag expansion so ../ components resolve correctly from physical CWD. Add parse_scopes to limit Tupfile scanning to requested targets. Add $$ escape for literal dollar signs in shell commands. GCC example cleanup after end-to-end build validation (3511 commands, 0 failures, cc1/cc1plus/xgcc/xg++/cpp all link and run): - Delete dead config/i386/Tupfile (targets/ file compiles same sources) - Fix stale aarch64-apple-darwin HOST_MACHINE in cp/Tupfile - Move driver-i386 compilation to target file, parameterize via TARGET_DRIVER_LINK so non-x86 targets can leave it empty - Rewrite tup.configs for Linux host (basename, sbrk, *_unlocked, etc.) - Add missing BACKTRACE/DECIMAL_FORMAT to aarch64-linux.config - Rewrite binutils/tup.config for Linux, add darwin overlay - Fix Makefile.pup setup-host-configs to handle binutils path --- examples/Makefile.pup | 11 +- examples/binutils/tup.config | 20 ++-- examples/configs/aarch64-linux.config | 3 + examples/configs/host-darwin/binutils.config | 111 ++++++++++++++++++ examples/configs/x86_64-linux.config | 4 + examples/gcc/gcc/Tupfile | 27 ++--- examples/gcc/gcc/analyzer/Tupfile | 5 +- examples/gcc/gcc/c-family/Tupfile | 5 +- examples/gcc/gcc/c/Tupfile | 5 +- examples/gcc/gcc/config/i386/Tupfile | 24 ---- examples/gcc/gcc/cp/Tupfile | 9 +- .../gcc/gcc/targets/x86_64-pc-linux-gnu.tup | 4 + examples/gcc/gcc/tup.config | 25 ++-- examples/gcc/gmp/mpn/tup.config | 2 +- examples/gcc/libbacktrace/tup.config | 11 +- examples/gcc/libcpp/tup.config | 16 +-- include/pup/cli/context.hpp | 1 + include/pup/graph/dag.hpp | 12 ++ src/cli/cmd_build.cpp | 14 ++- src/cli/cmd_configure.cpp | 3 +- src/cli/cmd_parse.cpp | 10 +- src/cli/context.cpp | 14 ++- src/core/path_utils.cpp | 9 ++ src/exec/scheduler.cpp | 3 +- src/graph/builder.cpp | 47 ++++++-- src/graph/dag.cpp | 57 +++++++-- .../groups_in_inputs/modules/Tupfile.fixture | 6 +- .../groups_in_inputs/output/Tupfile.fixture | 2 +- 28 files changed, 347 insertions(+), 113 deletions(-) create mode 100644 examples/configs/host-darwin/binutils.config delete mode 100644 examples/gcc/gcc/config/i386/Tupfile diff --git a/examples/Makefile.pup b/examples/Makefile.pup index 4f8b23f..78c86cc 100644 --- a/examples/Makefile.pup +++ b/examples/Makefile.pup @@ -39,13 +39,18 @@ configure: resolve-mpn setup-host-configs # 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/*/tup.config +# To restore Linux defaults: git checkout -- gcc/*/tup.config binutils/tup.config setup-host-configs: @if [ "$(HOST)" != "linux" ] && [ -d configs/host-$(HOST) ]; then \ for cfg in configs/host-$(HOST)/*.config; do \ lib=$$(basename "$$cfg" .config); \ - echo " COPY gcc/$$lib/tup.config (host-$(HOST))"; \ - cp "$$cfg" "gcc/$$lib/tup.config"; \ + if [ -f "$$lib/tup.config" ]; then \ + echo " COPY $$lib/tup.config (host-$(HOST))"; \ + cp "$$cfg" "$$lib/tup.config"; \ + elif [ -f "gcc/$$lib/tup.config" ]; then \ + echo " COPY gcc/$$lib/tup.config (host-$(HOST))"; \ + cp "$$cfg" "gcc/$$lib/tup.config"; \ + fi; \ done; \ fi diff --git a/examples/binutils/tup.config b/examples/binutils/tup.config index 246437e..2c292bb 100644 --- a/examples/binutils/tup.config +++ b/examples/binutils/tup.config @@ -1,7 +1,7 @@ -# binutils - macOS (aarch64-apple-darwin) host, x86_64-linux target +# binutils - x86_64 Linux host, x86_64-linux target # # BFD, opcodes, and gas share this config.h. -# Key: BFD64 for 64-bit targets, ELF backend, macOS host capabilities. +# Key: BFD64 for 64-bit targets, ELF backend, Linux/glibc host capabilities. # Package identity CONFIG_PACKAGE="binutils" @@ -19,13 +19,13 @@ CONFIG_SELECT_ARCHITECTURES=&bfd_i386_arch CONFIG_TARG_ARCHS=&bfd_i386_arch CONFIG_SELECT_VECS=&x86_64_elf64_vec,&i386_elf32_vec,&x86_64_elf32_vec -# Host capabilities (macOS/Darwin aarch64) +# Host capabilities (Linux/glibc x86_64) CONFIG_HAVE_MMAP=1 CONFIG_HAVE_MPROTECT=1 CONFIG_HAVE_FCNTL=1 CONFIG_HAVE_GETPAGESIZE=1 -CONFIG_HAVE_FOPEN64=n -CONFIG_HAVE_FSEEKO64=n +CONFIG_HAVE_FOPEN64=1 +CONFIG_HAVE_FSEEKO64=1 CONFIG_HAVE_FSEEKO=1 # Standard headers @@ -45,7 +45,7 @@ CONFIG_HAVE_SYS_TIME_H=1 CONFIG_HAVE_LIMITS_H=1 CONFIG_HAVE_DLFCN_H=1 CONFIG_HAVE_ERRNO_H=1 -CONFIG_HAVE_ALLOCA_H=n +CONFIG_HAVE_ALLOCA_H=1 CONFIG_HAVE_ZLIB_H=1 # Type sizes (LP64) @@ -63,11 +63,11 @@ CONFIG_HAVE_DECL_STPCPY=1 CONFIG_HAVE_DECL_STRNLEN=1 CONFIG_HAVE_DECL_FFS=1 CONFIG_HAVE_DECL_GETENV=1 -CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_BASENAME=1 CONFIG_HAVE_DECL_MALLOC=1 CONFIG_HAVE_DECL_REALLOC=1 -CONFIG_HAVE_DECL_SBRK=0 -CONFIG_HAVE_DECL_ENVIRON=0 +CONFIG_HAVE_DECL_SBRK=1 +CONFIG_HAVE_DECL_ENVIRON=1 CONFIG_HAVE_DECL_STRSTR=1 # Functions @@ -85,7 +85,7 @@ CONFIG_STDC_HEADERS=1 # Misc CONFIG_USE_BINARY_FOPEN=n -CONFIG_NEED_DECLARATION_ENVIRON=1 +CONFIG_NEED_DECLARATION_ENVIRON=0 CONFIG_NEED_DECLARATION_FFS=n CONFIG_DEFAULT_AR_DETERMINISTIC=1 CONFIG_HAVE_UTIMES=1 diff --git a/examples/configs/aarch64-linux.config b/examples/configs/aarch64-linux.config index 58510e3..fd73b97 100644 --- a/examples/configs/aarch64-linux.config +++ b/examples/configs/aarch64-linux.config @@ -17,3 +17,6 @@ CONFIG_TARGET=x86_64-pc-linux-gnu CONFIG_HOST_OS=linux CONFIG_PLATFORM_LDFLAGS=-lm -ldl -lpthread -lz CONFIG_EXTRA_MODES_FILE=config/i386/i386-modes.def +CONFIG_DECIMAL_FORMAT=bid +CONFIG_BACKTRACE_FORMAT=elf +CONFIG_BACKTRACE_ELF_SIZE=64 diff --git a/examples/configs/host-darwin/binutils.config b/examples/configs/host-darwin/binutils.config new file mode 100644 index 0000000..246437e --- /dev/null +++ b/examples/configs/host-darwin/binutils.config @@ -0,0 +1,111 @@ +# binutils - macOS (aarch64-apple-darwin) host, x86_64-linux target +# +# BFD, opcodes, and gas share this config.h. +# Key: BFD64 for 64-bit targets, ELF backend, macOS host capabilities. + +# Package identity +CONFIG_PACKAGE="binutils" +CONFIG_PACKAGE_VERSION="2.44" + +# BFD64 required for x86_64 targets +CONFIG_BFD64=1 + +# Target selection +CONFIG_TARGET="x86_64-pc-linux-gnu" +CONFIG_TARGET_CPU="i386" +CONFIG_DEFAULT_BFD_ARCH=bfd_i386_arch +CONFIG_DEFAULT_BFD_VEC=x86_64_elf64_vec +CONFIG_SELECT_ARCHITECTURES=&bfd_i386_arch +CONFIG_TARG_ARCHS=&bfd_i386_arch +CONFIG_SELECT_VECS=&x86_64_elf64_vec,&i386_elf32_vec,&x86_64_elf32_vec + +# Host capabilities (macOS/Darwin aarch64) +CONFIG_HAVE_MMAP=1 +CONFIG_HAVE_MPROTECT=1 +CONFIG_HAVE_FCNTL=1 +CONFIG_HAVE_GETPAGESIZE=1 +CONFIG_HAVE_FOPEN64=n +CONFIG_HAVE_FSEEKO64=n +CONFIG_HAVE_FSEEKO=1 + +# Standard headers +CONFIG_HAVE_STDINT_H=1 +CONFIG_HAVE_INTTYPES_H=1 +CONFIG_HAVE_STDLIB_H=1 +CONFIG_HAVE_STRING_H=1 +CONFIG_HAVE_STRINGS_H=1 +CONFIG_HAVE_UNISTD_H=1 +CONFIG_HAVE_FCNTL_H=1 +CONFIG_HAVE_SYS_FILE_H=1 +CONFIG_HAVE_SYS_MMAN_H=1 +CONFIG_HAVE_SYS_PARAM_H=1 +CONFIG_HAVE_SYS_STAT_H=1 +CONFIG_HAVE_SYS_TYPES_H=1 +CONFIG_HAVE_SYS_TIME_H=1 +CONFIG_HAVE_LIMITS_H=1 +CONFIG_HAVE_DLFCN_H=1 +CONFIG_HAVE_ERRNO_H=1 +CONFIG_HAVE_ALLOCA_H=n +CONFIG_HAVE_ZLIB_H=1 + +# Type sizes (LP64) +CONFIG_SIZEOF_VOID_P=8 +CONFIG_SIZEOF_LONG=8 +CONFIG_SIZEOF_LONG_LONG=8 +CONFIG_SIZEOF_OFF_T=8 + +# Declarations +CONFIG_HAVE_DECL_ASPRINTF=1 +CONFIG_HAVE_DECL_VASPRINTF=1 +CONFIG_HAVE_DECL_SNPRINTF=1 +CONFIG_HAVE_DECL_VSNPRINTF=1 +CONFIG_HAVE_DECL_STPCPY=1 +CONFIG_HAVE_DECL_STRNLEN=1 +CONFIG_HAVE_DECL_FFS=1 +CONFIG_HAVE_DECL_GETENV=1 +CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_MALLOC=1 +CONFIG_HAVE_DECL_REALLOC=1 +CONFIG_HAVE_DECL_SBRK=0 +CONFIG_HAVE_DECL_ENVIRON=0 +CONFIG_HAVE_DECL_STRSTR=1 + +# Functions +CONFIG_HAVE_ASPRINTF=1 +CONFIG_HAVE_VASPRINTF=1 +CONFIG_HAVE_REALPATH=1 +CONFIG_HAVE_MKDTEMP=1 +CONFIG_HAVE_MKSTEMP=1 +CONFIG_HAVE_SETLOCALE=1 +CONFIG_HAVE_SBRK=1 +CONFIG_HAVE_GETRLIMIT=1 + +# C standard +CONFIG_STDC_HEADERS=1 + +# Misc +CONFIG_USE_BINARY_FOPEN=n +CONFIG_NEED_DECLARATION_ENVIRON=1 +CONFIG_NEED_DECLARATION_FFS=n +CONFIG_DEFAULT_AR_DETERMINISTIC=1 +CONFIG_HAVE_UTIMES=1 + +# Gas target identity +CONFIG_TARGET_ALIAS="x86_64-pc-linux-gnu" +CONFIG_TARGET_CANONICAL="x86_64-pc-linux-gnu" +CONFIG_VERSION="2.44" + +# Gas defaults +CONFIG_DEFAULT_GENERATE_ELF_STT_COMMON=0 +CONFIG_DEFAULT_GENERATE_BUILD_NOTES=0 +CONFIG_DEFAULT_COMPRESSED_DEBUG_ALGORITHM=0 +CONFIG_HAVE_STRSIGNAL=1 +CONFIG_DEFAULT_X86_USED_NOTE=0 +CONFIG_DEFAULT_GENERATE_X86_RELAX_RELOCATIONS=1 +CONFIG_DEFAULT_X86_TLS_CHECK=0 + +# Thread-local storage keyword +CONFIG_TLS=__thread + +# Debug info directory +CONFIG_DEBUGDIR="/usr/lib/debug" diff --git a/examples/configs/x86_64-linux.config b/examples/configs/x86_64-linux.config index 44f92ab..7433a5b 100644 --- a/examples/configs/x86_64-linux.config +++ b/examples/configs/x86_64-linux.config @@ -17,3 +17,7 @@ CONFIG_TARGET=x86_64-pc-linux-gnu CONFIG_HOST_OS=linux CONFIG_PLATFORM_LDFLAGS=-lm -ldl -lpthread -lz 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 diff --git a/examples/gcc/gcc/Tupfile b/examples/gcc/gcc/Tupfile index 9e7d3a6..73d5328 100644 --- a/examples/gcc/gcc/Tupfile +++ b/examples/gcc/gcc/Tupfile @@ -88,9 +88,10 @@ SRC = $(S)/$(GCC_DIR) ) > %o |> omp-device-properties.h # --- Target-specific headers and configuration --- -# Sets: MD, TARGET_OPT_FILES, target_gtyp_src, target_GT_H +# Sets: MD, TARGET_OPT_FILES, target_gtyp_src, target_GT_H, TARGET_DRIVER_LINK # Generates: tm.h, tm_p.h → -# Compiles: target-specific common objects → +# Compiles: target-specific backend + driver objects → , +TARGET_DRIVER_LINK = include targets/@(TARGET).tup # --- Options pipeline --- @@ -832,8 +833,7 @@ EXTRA_DEFS = -DPREFIX=\"/usr/local\" -DBASEVER=\"15.2.0\" # Target-specific common objects (from subdirectories) : common/common-targhooks.cc |> !cxx |> common-targhooks.o -# Host hooks (default host hooks + platform-specific PCH helpers) -: host-default.cc |> !cxx |> host-default.o +# Host hooks (platform-specific replaces default when available) : config/host-@(HOST_OS).cc |> !cxx |> host-@(HOST_OS).o # main.o @@ -860,11 +860,8 @@ EXTRA_DEFS = -DPREFIX=\"/usr/local\" -DBASEVER=\"15.2.0\" $(LIBIBERTY_A) $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) \ | c/ c-family/ analyzer/ |> \ ^ LINK cc1^ sh -c '$(CXX) % \ - $(TUP_VARIANT_OUTPUTDIR)/c/*.o \ - $(TUP_VARIANT_OUTPUTDIR)/c-family/*.o \ - $(TUP_VARIANT_OUTPUTDIR)/analyzer/*.o \ - $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) $(LIBIBERTY_A) \ - $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) \ + $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) \ + $(LIBMPC_A) $(LIBMPFR_A) $(LIBGMP_A) $(LIBIBERTY_A) \ @(PLATFORM_LDFLAGS) -o %o' |> cc1 # ============================================================ @@ -927,7 +924,7 @@ LIBCOMMON_OBJS += $(D)/opts-diagnostic.o $(D)/options.o $(D)/hooks.o LIBCOMMON_OBJS += $(D)/common-targhooks.o $(D)/file-find.o $(D)/spellcheck.o LIBCOMMON_OBJS += $(D)/opt-suggestions.o $(D)/options-urls.o $(D)/gcc-urlifier.o -DRIVER_LIBS = $(LIBIBERTY_A) $(LIBCPP_A) $(LIBBACKTRACE_A) $(LIBDECNUMBER_A) +DRIVER_LIBS = $(LIBCPP_A) $(LIBBACKTRACE_A) $(LIBDECNUMBER_A) $(LIBIBERTY_A) # Link xgcc : $(DRIVER_LIBS) \ @@ -949,10 +946,8 @@ DRIVER_LIBS = $(LIBIBERTY_A) $(LIBCPP_A) $(LIBBACKTRACE_A) $(LIBDECNUMBER_A) | cp/ c-family/ analyzer/ |> \ ^ LINK cc1plus^ sh -c '$(CXX) % \ $(TUP_VARIANT_OUTPUTDIR)/cp/*.o \ - $(TUP_VARIANT_OUTPUTDIR)/c-family/*.o \ - $(TUP_VARIANT_OUTPUTDIR)/analyzer/*.o \ - $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) $(LIBIBERTY_A) \ - $(LIBGMP_A) $(LIBMPFR_A) $(LIBMPC_A) $(LIBCODY_A) \ + $(LIBCPP_A) $(LIBDECNUMBER_A) $(LIBBACKTRACE_A) \ + $(LIBMPC_A) $(LIBMPFR_A) $(LIBGMP_A) $(LIBCODY_A) $(LIBIBERTY_A) \ @(PLATFORM_LDFLAGS) -o %o' |> cc1plus # ============================================================ @@ -986,7 +981,7 @@ EXTRA_DEFS = $(DRIVER_DEFS) EXTRA_DEFS = : $(DRIVER_LIBS) \ | |> ^ LINK xg++^ sh -c '$(CXX) \ - $(D)/gcc-driver.o $(D)/gcc-main-driver.o $(D)/xgcc-ggc-none.o % \ + $(D)/gcc-driver.o $(D)/gcc-main-driver.o $(D)/xgcc-ggc-none.o $(TARGET_DRIVER_LINK) % \ $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ @(PLATFORM_LDFLAGS) -o %o' |> xg++ @@ -1001,7 +996,7 @@ EXTRA_DEFS = $(DRIVER_DEFS) EXTRA_DEFS = : $(DRIVER_LIBS) \ | |> ^ LINK cpp^ sh -c '$(CXX) \ - $(D)/gcc-driver.o $(D)/gcc-main-driver.o $(D)/xgcc-ggc-none.o % \ + $(D)/gcc-driver.o $(D)/gcc-main-driver.o $(D)/xgcc-ggc-none.o $(TARGET_DRIVER_LINK) % \ $(LIBCOMMON_OBJS) $(DRIVER_LIBS) \ @(PLATFORM_LDFLAGS) -o %o' |> cpp diff --git a/examples/gcc/gcc/analyzer/Tupfile b/examples/gcc/gcc/analyzer/Tupfile index 6257584..ec845af 100644 --- a/examples/gcc/gcc/analyzer/Tupfile +++ b/examples/gcc/gcc/analyzer/Tupfile @@ -3,7 +3,8 @@ include_rules # ============================================================ # gcc/analyzer/ — Static analyzer (GCC 15.2.0) # ============================================================ -# Objects contribute to ../ for the cc1 link. +# Objects contribute to for the cc1 link. +# Parent references this group as analyzer/ in order-only deps. # Source list from ANALYZER_OBJS in Makefile.in. srcs = access-diagram.cc analysis-plan.cc analyzer.cc @@ -25,4 +26,4 @@ srcs += sm-pattern-test.cc sm-sensitive.cc sm-signal.cc sm-taint.cc srcs += state-purge.cc store.cc supergraph.cc srcs += svalue.cc symbol.cc trimmed-graph.cc varargs.cc -: foreach $(srcs) |> !cxx |> %B.o ../ +: foreach $(srcs) |> !cxx |> %B.o diff --git a/examples/gcc/gcc/c-family/Tupfile b/examples/gcc/gcc/c-family/Tupfile index c241ba1..3cde7a4 100644 --- a/examples/gcc/gcc/c-family/Tupfile +++ b/examples/gcc/gcc/c-family/Tupfile @@ -3,7 +3,8 @@ include_rules # ============================================================ # gcc/c-family/ — C language family shared code (GCC 15.2.0) # ============================================================ -# Objects contribute to ../ for the cc1 link. +# Objects contribute to for the cc1 link. +# Parent references this group as c-family/ in order-only deps. # Source list from C_COMMON_OBJS + stub-objc. srcs = stub-objc.cc @@ -14,7 +15,7 @@ srcs += c-pretty-print.cc c-semantics.cc c-ada-spec.cc c-ubsan.cc srcs += known-headers.cc c-attribs.cc c-warn.cc c-spellcheck.cc srcs += c-type-mismatch.cc -: foreach $(srcs) |> !cxx |> %B.o ../ +: foreach $(srcs) |> !cxx |> %B.o # c-target-hooks-def.h (generated by genhooks in parent dir) : | $(S)/$(GCC_DIR)/ |> ^ GEN %o^ \ diff --git a/examples/gcc/gcc/c/Tupfile b/examples/gcc/gcc/c/Tupfile index 48252c1..f5ffcd7 100644 --- a/examples/gcc/gcc/c/Tupfile +++ b/examples/gcc/gcc/c/Tupfile @@ -3,10 +3,11 @@ include_rules # ============================================================ # gcc/c/ — C language frontend (GCC 15.2.0) # ============================================================ -# Objects contribute to ../ for the cc1 link. +# Objects contribute to for the cc1 link. +# Parent references this group as c/ in order-only deps. srcs = c-lang.cc c-errors.cc c-decl.cc c-typeck.cc srcs += c-convert.cc c-aux-info.cc c-objc-common.cc srcs += c-parser.cc c-fold.cc gimple-parser.cc -: foreach $(srcs) |> !cxx |> %B.o ../ +: foreach $(srcs) |> !cxx |> %B.o diff --git a/examples/gcc/gcc/config/i386/Tupfile b/examples/gcc/gcc/config/i386/Tupfile deleted file mode 100644 index d0d9608..0000000 --- a/examples/gcc/gcc/config/i386/Tupfile +++ /dev/null @@ -1,24 +0,0 @@ -include_rules - -# ============================================================ -# gcc/config/i386/ — x86_64 target-specific code (GCC 15.2.0) -# ============================================================ -# Objects contribute to ../../ for the cc1 link. -# Source list from out_object_file, extra_objs, c_target_objs in config.gcc. - -# Main target description (out_object_file = i386.o) -: i386.cc |> !cxx |> i386.o ../../ - -# C frontend target hooks (c_target_objs) -: i386-c.cc |> !cxx |> i386-c.o ../../ - -# extra_objs for i386 -srcs = x86-tune-sched.cc x86-tune-sched-bd.cc -srcs += x86-tune-sched-atom.cc x86-tune-sched-core.cc -srcs += i386-options.cc i386-builtins.cc -srcs += i386-expand.cc i386-features.cc - -: foreach $(srcs) |> !cxx |> %B.o ../../ - -# x86_64-linux extra (config.gcc line 5928) -: gnu-property.cc |> !cxx |> gnu-property.o ../../ diff --git a/examples/gcc/gcc/cp/Tupfile b/examples/gcc/gcc/cp/Tupfile index cbfb46e..9dc99a6 100644 --- a/examples/gcc/gcc/cp/Tupfile +++ b/examples/gcc/gcc/cp/Tupfile @@ -3,7 +3,8 @@ include_rules # ============================================================ # gcc/cp/ -- C++ language frontend (GCC 15.2.0) # ============================================================ -# Objects contribute to ../ for the cc1plus link. +# Objects contribute to for the cc1plus link. +# Parent references this group as cp/ in order-only deps. # Source list from CXX_AND_OBJCXX_OBJS + cp-lang.cc in cp/Make-lang.in. srcs = cp-lang.cc @@ -16,8 +17,8 @@ srcs += name-lookup.cc optimize.cc parser.cc pt.cc ptree.cc srcs += rtti.cc search.cc semantics.cc tree.cc typeck.cc typeck2.cc srcs += vtable-class-hierarchy.cc -: foreach $(srcs) |> !cxx |> %B.o ../ +: foreach $(srcs) |> !cxx |> %B.o # module.cc needs special defines for C++ modules support -EXTRA_DEFS = -DHOST_MACHINE=\"aarch64-apple-darwin\" -DTARGET_MACHINE=\"@(TARGET)\" -: module.cc |> !cxx-defs |> module.o ../ +EXTRA_DEFS = -DHOST_MACHINE=\"@(TARGET)\" -DTARGET_MACHINE=\"@(TARGET)\" +: module.cc |> !cxx-defs |> module.o diff --git a/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup b/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup index 2d60c1d..0f7d60f 100644 --- a/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup +++ b/examples/gcc/gcc/targets/x86_64-pc-linux-gnu.tup @@ -120,3 +120,7 @@ target_srcs += config/linux.cc target_srcs += config/glibc-c.cc : foreach $(target_srcs) |> !cxx |> %B.o + +# x86_64 host CPU detection for the driver (gcc.cc references host_detect_local_cpu) +: config/i386/driver-i386.cc |> !cxx |> driver-i386.o +TARGET_DRIVER_LINK = $(TUP_VARIANT_OUTPUTDIR)/driver-i386.o diff --git a/examples/gcc/gcc/tup.config b/examples/gcc/gcc/tup.config index bfe2ff7..2a7159f 100644 --- a/examples/gcc/gcc/tup.config +++ b/examples/gcc/gcc/tup.config @@ -1,10 +1,10 @@ -# gcc/ - macOS (aarch64-apple-darwin) auto-host.h defines -# -# Cross-referenced with gcc/configure.ac output for macOS host. -# Differences from Linux: no mallinfo, no posix_fallocate, no *_unlocked, -# no _GNU_SOURCE, different ld/gas features. +# gcc/ - x86_64-linux auto-host.h defines -# Type sizes (same as Linux on 64-bit) +# Platform (shared with root config) +CONFIG_HOST_OS=linux +CONFIG_DECIMAL_FORMAT=bid + +# Type sizes CONFIG_SIZEOF_SHORT=2 CONFIG_SIZEOF_INT=4 CONFIG_SIZEOF_LONG=8 @@ -38,7 +38,7 @@ CONFIG_HAVE_SYS_TYPES_H=1 CONFIG_HAVE_SYS_WAIT_H=1 CONFIG_HAVE_UNISTD_H=1 -# Functions (macOS has most POSIX, but not Linux-specific ones) +# Functions (Linux/glibc — has mallinfo, posix_fallocate, etc.) CONFIG_HAVE_ALLOCA=1 CONFIG_HAVE_CLOCK=1 CONFIG_HAVE_CLOCK_GETTIME=1 @@ -49,9 +49,12 @@ CONFIG_HAVE_ICONV=1 CONFIG_HAVE_LANGINFO_CODESET=1 CONFIG_HAVE_LSTAT=1 CONFIG_HAVE_MADVISE=1 +CONFIG_HAVE_MALLINFO=1 +CONFIG_HAVE_MALLINFO2=1 CONFIG_HAVE_MMAP=1 CONFIG_HAVE_MMAP_ANON=1 CONFIG_HAVE_MMAP_FILE=1 +CONFIG_HAVE_POSIX_FALLOCATE=1 CONFIG_HAVE_SETLOCALE=1 CONFIG_HAVE_SETRLIMIT=1 CONFIG_HAVE_SIGACTION=1 @@ -62,22 +65,22 @@ CONFIG_HAVE_VFORK=1 CONFIG_HAVE_WORKING_FORK=1 CONFIG_HAVE_WORKING_VFORK=1 -# Declarations +# Declarations (Linux/glibc — basename and sbrk are declared) CONFIG_HAVE_DECL_ABORT=1 CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_BASENAME=1 CONFIG_HAVE_DECL_ERRNO=1 CONFIG_HAVE_DECL_GETENV=1 CONFIG_HAVE_DECL_GETOPT=1 CONFIG_HAVE_DECL_LDGETNAME=0 CONFIG_HAVE_DECL_MALLOC=1 CONFIG_HAVE_DECL_REALLOC=1 -CONFIG_HAVE_DECL_SBRK=0 +CONFIG_HAVE_DECL_SBRK=1 CONFIG_HAVE_DECL_SNPRINTF=1 CONFIG_HAVE_DECL_STRSIGNAL=1 CONFIG_HAVE_DECL_VASPRINTF=1 CONFIG_HAVE_DECL_VSNPRINTF=1 -CONFIG_HAVE_DECL_STRVERSCMP=0 +CONFIG_HAVE_DECL_STRVERSCMP=1 # Build options CONFIG_GATHER_STATISTICS=0 diff --git a/examples/gcc/gmp/mpn/tup.config b/examples/gcc/gmp/mpn/tup.config index 834183c..d8a5628 100644 --- a/examples/gcc/gmp/mpn/tup.config +++ b/examples/gcc/gmp/mpn/tup.config @@ -1,6 +1,6 @@ CONFIG_MPN_ARCH=generic CONFIG_MPN_SUBDIR=generic -CONFIG_C_SOURCES=generic/add_1.c generic/add_err1_n.c generic/add_err2_n.c generic/add_err3_n.c generic/add_n_sub_n.c generic/add_n.c generic/add.c generic/addmul_1.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/com.c generic/comb_tables.c generic/compute_powtab.c generic/copyd.c generic/copyi.c generic/dcpi1_bdiv_q.c generic/dcpi1_bdiv_qr.c generic/dcpi1_div_q.c generic/dcpi1_div_qr.c generic/dcpi1_divappr_q.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/dive_1.c generic/diveby3.c generic/divexact.c generic/divis.c generic/divrem_1.c generic/divrem_2.c generic/divrem.c generic/dump.c generic/fib2_ui.c generic/fib2m.c generic/gcd_1.c generic/gcd_11.c generic/gcd_22.c generic/gcd_subdiv_step.c generic/gcd.c generic/gcdext_1.c generic/gcdext_lehmer.c generic/gcdext.c generic/get_d.c generic/get_str.c generic/hgcd_appr.c generic/hgcd_jacobi.c generic/hgcd_matrix.c generic/hgcd_reduce.c generic/hgcd_step.c generic/hgcd.c generic/hgcd2_jacobi.c generic/hgcd2.c generic/invert.c generic/invertappr.c generic/jacbase.c generic/jacobi_2.c generic/jacobi.c generic/lshift.c generic/lshiftc.c generic/matrix22_mul.c generic/matrix22_mul1_inverse_vector.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_div_q.c generic/mu_div_qr.c generic/mu_divappr_q.c generic/mul_1.c generic/mul_basecase.c generic/mul_fft.c generic/mul_n.c generic/mul.c generic/mullo_basecase.c generic/mullo_n.c generic/mulmid_basecase.c generic/mulmid_n.c generic/mulmid.c generic/mulmod_bnm1.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/random.c generic/random2.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_div_q.c generic/sbpi1_div_qr.c generic/sbpi1_divappr_q.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_err1_n.c generic/sub_err2_n.c generic/sub_err3_n.c generic/sub_n.c generic/sub.c generic/submul_1.c generic/tdiv_qr.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/toom2_sqr.c generic/toom22_mul.c generic/toom3_sqr.c generic/toom32_mul.c generic/toom33_mul.c generic/toom4_sqr.c generic/toom42_mul.c generic/toom42_mulmid.c generic/toom43_mul.c generic/toom44_mul.c generic/toom52_mul.c generic/toom53_mul.c generic/toom54_mul.c generic/toom6_sqr.c generic/toom62_mul.c generic/toom63_mul.c generic/toom6h_mul.c generic/toom8_sqr.c generic/toom8h_mul.c generic/trialdiv.c generic/zero_p.c generic/zero.c +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 diff --git a/examples/gcc/libbacktrace/tup.config b/examples/gcc/libbacktrace/tup.config index 645b8cb..9adf7c8 100644 --- a/examples/gcc/libbacktrace/tup.config +++ b/examples/gcc/libbacktrace/tup.config @@ -1,10 +1,9 @@ -# 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. +# libbacktrace config.h defines +# Object format selected by platform config (elf on Linux, macho on macOS) -# Object format: macho (macOS) instead of elf (Linux) -CONFIG_BACKTRACE_FORMAT=macho +# Object format: elf (Linux default), overridden by platform config +CONFIG_BACKTRACE_FORMAT=elf +CONFIG_BACKTRACE_ELF_SIZE=64 # Atomics CONFIG_HAVE_ATOMIC_FUNCTIONS=1 diff --git a/examples/gcc/libcpp/tup.config b/examples/gcc/libcpp/tup.config index 771437b..29d9180 100644 --- a/examples/gcc/libcpp/tup.config +++ b/examples/gcc/libcpp/tup.config @@ -1,6 +1,4 @@ -# libcpp - macOS (aarch64-apple-darwin) config.h defines -# -# Key differences from Linux: no *_unlocked functions (glibc-specific). +# libcpp - x86_64-linux config.h defines # Build options CONFIG_ENABLE_CANONICAL_SYSTEM_HEADERS=1 @@ -22,16 +20,20 @@ CONFIG_HAVE_SYS_STAT_H=1 CONFIG_HAVE_SYS_TYPES_H=1 CONFIG_HAVE_UNISTD_H=1 -# Functions (macOS lacks glibc *_unlocked variants) +# Functions (glibc has *_unlocked variants) CONFIG_HAVE_ALLOCA=1 CONFIG_HAVE_ICONV=1 CONFIG_HAVE_LANGINFO_CODESET=1 CONFIG_HAVE_SETLOCALE=1 +CONFIG_HAVE_PUTCHAR_UNLOCKED=1 +CONFIG_HAVE_FPUTS_UNLOCKED=1 +CONFIG_HAVE_FWRITE_UNLOCKED=1 +CONFIG_HAVE_FPUTC_UNLOCKED=1 # Declarations CONFIG_HAVE_DECL_ABORT=1 CONFIG_HAVE_DECL_ASPRINTF=1 -CONFIG_HAVE_DECL_BASENAME=0 +CONFIG_HAVE_DECL_BASENAME=1 CONFIG_HAVE_DECL_ERRNO=1 CONFIG_HAVE_DECL_FPRINTF_UNLOCKED=0 CONFIG_HAVE_DECL_GETOPT=1 @@ -41,7 +43,7 @@ CONFIG_HAVE_DECL_VASPRINTF=1 CONFIG_HAVE_UINTPTR_T=1 # Sizes -CONFIG_SIZEOF_DEV_T=4 +CONFIG_SIZEOF_DEV_T=8 CONFIG_SIZEOF_INO_T=8 CONFIG_SIZEOF_INT=4 CONFIG_SIZEOF_LONG=8 @@ -55,7 +57,7 @@ CONFIG_PACKAGE_TARNAME="cpplib" CONFIG_PACKAGE_URL="" CONFIG_PACKAGE_VERSION="0" -# iconv (macOS libc uses char**, same as glibc — ICONV_CONST is empty) +# iconv (glibc uses char**, ICONV_CONST is empty) CONFIG_ICONV_CONST= # Misc diff --git a/include/pup/cli/context.hpp b/include/pup/cli/context.hpp index 051c5eb..73fbf21 100644 --- a/include/pup/cli/context.hpp +++ b/include/pup/cli/context.hpp @@ -53,6 +53,7 @@ struct BuildContextOptions { bool auto_init = false; bool root_config_only = false; bool require_config = false; + std::vector parse_scopes = {}; graph::DepScannerRegistry* scanner_registry = nullptr; graph::RulePatternRegistry* pattern_registry = nullptr; VarAssignedCallback on_var_assigned = {}; diff --git a/include/pup/graph/dag.hpp b/include/pup/graph/dag.hpp index fe6a833..5d58d4b 100644 --- a/include/pup/graph/dag.hpp +++ b/include/pup/graph/dag.hpp @@ -10,6 +10,7 @@ #include "pup/graph/rule_pattern.hpp" #include +#include #include #include #include @@ -386,6 +387,17 @@ auto get_name(Graph const& graph, NodeId id) -> std::string_view; [[nodiscard]] auto expand_instruction(Graph const& graph, NodeId cmd_id, PathCache& cache) -> std::string; +/// Expand instruction with canonical path resolution for symlinked source trees. +/// When source_root is provided, build-tree paths are computed relative to the +/// canonical (physical) CWD instead of the logical CWD. +[[nodiscard]] +auto expand_instruction( + Graph const& graph, + NodeId cmd_id, + PathCache& cache, + std::filesystem::path const& source_root +) -> std::string; + /// Expand instruction pattern (convenience overload, creates temporary cache) [[nodiscard]] auto expand_instruction(Graph const& graph, NodeId cmd_id) -> std::string; diff --git a/src/cli/cmd_build.cpp b/src/cli/cmd_build.cpp index 8abce74..171f2f4 100644 --- a/src/cli/cmd_build.cpp +++ b/src/cli/cmd_build.cpp @@ -936,12 +936,25 @@ auto build_single_variant( vprint(variant_name, "Implicit dependency tracking enabled\n"); } + auto layout = discover_layout(make_layout_options(opts)); + if (!layout) { + veprint(variant_name, "Error: %s\n", layout.error().message.c_str()); + return EXIT_FAILURE; + } + auto scopes = compute_build_scopes(opts, *layout); + + // Only scope parsing when explicit targets are given. + // CWD-derived scoping should still parse all Tupfiles so that + // out-of-scope Tupfile changes are detected for incremental builds. + auto parse_scopes = opts.targets.empty() ? std::vector {} : scopes; + auto ctx_opts = BuildContextOptions { .verbose = opts.verbose, .keep_going = opts.keep_going, .auto_init = true, .root_config_only = false, .require_config = true, + .parse_scopes = parse_scopes, .scanner_registry = scanner_ptr, }; @@ -985,7 +998,6 @@ auto build_single_variant( auto cmd_index_elapsed = std::chrono::high_resolution_clock::now() - cmd_index_start; pup::thread_metrics().command_index_time = std::chrono::duration_cast(cmd_index_elapsed); - auto scopes = compute_build_scopes(opts, ctx.layout()); auto upstream_files = std::set {}; if (opts.include_all_deps && !scopes.empty()) { upstream_files = collect_upstream_files(ctx.graph(), scopes); diff --git a/src/cli/cmd_configure.cpp b/src/cli/cmd_configure.cpp index 8eee485..c2abac7 100644 --- a/src/cli/cmd_configure.cpp +++ b/src/cli/cmd_configure.cpp @@ -118,11 +118,13 @@ auto configure_single_variant( install_source_configs(*layout, variant_name, opts.verbose); // Step 3: Run config-generating rules + auto scopes = compute_build_scopes(opts, *layout); auto ctx_opts = BuildContextOptions { .verbose = opts.verbose, .keep_going = opts.keep_going, .auto_init = false, // Configure pass should not create .pup .root_config_only = true, // Configure uses only root tup.config + .parse_scopes = scopes, .scanner_registry = nullptr, }; @@ -153,7 +155,6 @@ auto configure_single_variant( } // Filter config commands by scope if specified - auto scopes = compute_build_scopes(opts, ctx.layout()); auto config_commands = std::set {}; for (auto const& cfg : configs) { auto const* node = ctx.graph().get_command_node(cfg.cmd_id); diff --git a/src/cli/cmd_parse.cpp b/src/cli/cmd_parse.cpp index 084630e..183b5c0 100644 --- a/src/cli/cmd_parse.cpp +++ b/src/cli/cmd_parse.cpp @@ -17,8 +17,15 @@ namespace { auto parse_single_variant(Options const& opts, std::string_view variant_name) -> int { + auto layout = discover_layout(make_layout_options(opts)); + if (!layout) { + fprintf(stderr, "[%.*s] Error: %s\n", static_cast(variant_name.size()), variant_name.data(), layout.error().message.c_str()); + return EXIT_FAILURE; + } + auto ctx_opts = BuildContextOptions { .verbose = opts.verbose, + .parse_scopes = compute_build_scopes(opts, *layout), }; auto result = pup::Result { build_context(opts, ctx_opts) }; @@ -44,10 +51,11 @@ auto parse_single_variant(Options const& opts, std::string_view variant_name) -> if (opts.verbose && !commands.empty()) { printf("[%.*s] Commands:\n", static_cast(variant_name.size()), variant_name.data()); + auto cache = pup::graph::PathCache {}; for (auto id : commands) { if (ctx.graph().get_command_node(id)) { auto display_sv = pup::graph::get_display_str(ctx.graph().graph(), id); - auto cmd_sv = pup::graph::expand_instruction(ctx.graph().graph(), id); + auto cmd_sv = pup::graph::expand_instruction(ctx.graph().graph(), id, cache, ctx.layout().source_root); auto label = display_sv.empty() ? cmd_sv : display_sv; printf("[%.*s] %.*s\n", static_cast(variant_name.size()), variant_name.data(), static_cast(label.size()), label.data()); } diff --git a/src/cli/context.cpp b/src/cli/context.cpp index e025835..79ec85c 100644 --- a/src/cli/context.cpp +++ b/src/cli/context.cpp @@ -118,7 +118,11 @@ auto compute_tup_variantdir( if (!output_root.empty() && source_root != output_root) { auto output_dir = output_root / source_dir; auto src_dir = source_root / source_dir; - auto rel = std::filesystem::relative(output_dir, src_dir); + // Canonicalize to resolve symlinks — commands run from physical paths, + // so the relative path must work from the physical location. + auto src_canonical = std::filesystem::weakly_canonical(src_dir); + auto out_canonical = std::filesystem::weakly_canonical(output_dir); + auto rel = std::filesystem::relative(out_canonical, src_canonical); return rel.generic_string(); } @@ -378,8 +382,8 @@ auto parse_directory(std::filesystem::path const& rel_dir, ParseContext& ctx) -> // For variant builds: e.g., "../../build/coreutils" from source/coreutils/ auto tup_outdir = std::string { "." }; if (ctx.source_root != ctx.output_root) { - auto source_dir = join_path(ctx.source_root, rel_dir_normalized); - auto output_dir = join_path(ctx.output_root, rel_dir_normalized); + auto source_dir = std::filesystem::weakly_canonical(join_path(ctx.source_root, rel_dir_normalized)); + auto output_dir = std::filesystem::weakly_canonical(join_path(ctx.output_root, rel_dir_normalized)); tup_outdir = std::filesystem::relative(output_dir, source_dir).generic_string(); } @@ -710,6 +714,10 @@ auto build_context( if (ctx.impl_->state.parsed.contains(dir)) { continue; } + if (!ctx_opts.parse_scopes.empty() + && !pup::is_path_in_any_scope(dir.generic_string(), ctx_opts.parse_scopes)) { + continue; + } auto result = Result { parse_directory(dir, parse_ctx) }; if (!result && !ctx_opts.keep_going) { return unexpected(result.error()); diff --git a/src/core/path_utils.cpp b/src/core/path_utils.cpp index 7d79f81..0659574 100644 --- a/src/core/path_utils.cpp +++ b/src/core/path_utils.cpp @@ -70,6 +70,15 @@ auto is_path_in_scope( return true; } + // Strip trailing separators from scope + while (!scope.empty() && (scope.back() == '/' || scope.back() == '\\')) { + scope.remove_suffix(1); + } + + if (scope.empty()) { + return true; + } + if (!path.starts_with(scope)) { return false; } diff --git a/src/exec/scheduler.cpp b/src/exec/scheduler.cpp index 9a7ab0e..bca3163 100644 --- a/src/exec/scheduler.cpp +++ b/src/exec/scheduler.cpp @@ -787,6 +787,7 @@ auto Scheduler::build_job_list( } auto jobs = std::vector {}; + auto cache = graph::PathCache {}; for (auto id : topo_result.order) { if (!node_id::is_command(id)) { @@ -820,7 +821,7 @@ auto Scheduler::build_job_list( } // Expand command from instruction pattern + operands - auto cmd_str = expand_instruction(graph.graph(), id); + auto cmd_str = expand_instruction(graph.graph(), id, cache, impl_->options.source_root); auto display_str = std::string { get_display_str(graph.graph(), id) }; // Convert exported_vars from StringIds to strings diff --git a/src/graph/builder.cpp b/src/graph/builder.cpp index e1b944d..9895645 100644 --- a/src/graph/builder.cpp +++ b/src/graph/builder.cpp @@ -59,15 +59,18 @@ auto normalize_group_dir( ) -> std::string { auto cleaned = strip_trailing_slashes(path_str); - auto path = fs::path { cleaned }.lexically_normal(); + auto raw_path = fs::path { cleaned }; + auto path = raw_path.lexically_normal(); if (path.is_absolute()) { path = fs::relative(path, source_root); } else if (!current_dir.empty() && !path.empty()) { - // Only combine with current_dir if path needs parent resolution (starts with ..) - // Paths like $(ROOT)/foo expand to root-relative and should NOT be combined - auto first = *path.begin(); - if (first == "..") { + // Check the pre-normalization first component to distinguish: + // "./" prefix (e.g. $(S)/foo/) → root-relative, do NOT combine + // "../" prefix → parent traversal, combine with current_dir + // bare name (e.g. mpn/) → subdirectory reference, combine with current_dir + auto first = *raw_path.begin(); + if (first != ".") { path = (current_dir / path).lexically_normal(); } } @@ -155,18 +158,35 @@ struct PathTransformContext { std::string current_dir_str; fs::path source_root; fs::path output_root; + fs::path canonical_cwd; // Canonical source CWD for symlink-safe path resolution }; auto make_transform_context(BuilderContext const& ctx) -> PathTransformContext { + auto canonical_cwd = fs::path {}; + if (!ctx.options.source_root.empty() && !ctx.options.output_root.empty() + && ctx.options.source_root != ctx.options.output_root) { + canonical_cwd = fs::weakly_canonical(ctx.options.source_root / ctx.current_dir); + } + return PathTransformContext { .source_to_root = pup::compute_source_to_root(ctx.current_dir.generic_string()), .current_dir_str = ctx.current_dir.generic_string(), .source_root = ctx.options.source_root, .output_root = ctx.options.output_root, + .canonical_cwd = std::move(canonical_cwd), }; } +/// Compute a canonical relative path from the source CWD to a build-tree file. +/// Resolves symlinks in the source tree so that `../` components in command paths +/// navigate correctly from the physical CWD (which the OS uses after resolving symlinks). +auto make_canonical_relative(PathTransformContext const& tc, std::string const& path) -> std::string +{ + auto abs = fs::weakly_canonical(tc.source_root / path); + return abs.lexically_relative(tc.canonical_cwd).generic_string(); +} + /// Transform an input path to Tupfile-relative for command expansion. /// Input paths are source-relative. For Generated/Ghost files under BUILD_ROOT_ID, /// we need to use get_full_path() to get the path including the build root prefix. @@ -181,6 +201,9 @@ auto transform_input_path( if (auto node_id = graph.find_by_path(inp, BUILD_ROOT_ID)) { auto full_path = graph.get_full_path(*node_id); if (!full_path.empty()) { + if (!tc.canonical_cwd.empty() && full_path.starts_with("..")) { + return make_canonical_relative(tc, full_path); + } return pup::make_source_relative(full_path, tc.source_to_root, tc.current_dir_str); } } @@ -192,6 +215,9 @@ auto transform_input_path( auto build_path = tc.output_root / inp; if (fs::exists(build_path)) { auto full_path = build_root_name + "/" + inp; + if (!tc.canonical_cwd.empty() && full_path.starts_with("..")) { + return make_canonical_relative(tc, full_path); + } return pup::make_source_relative(full_path, tc.source_to_root, tc.current_dir_str); } } @@ -208,8 +234,9 @@ auto transform_output_path( std::string const& out ) -> std::string { - // Outputs are already variant-mapped (stored under BUILD_ROOT_ID by expand_outputs). - // Just make the path relative to the Tupfile directory. + if (!tc.canonical_cwd.empty() && out.starts_with("..")) { + return make_canonical_relative(tc, out); + } return pup::make_source_relative(out, tc.source_to_root, tc.current_dir_str); } @@ -2467,11 +2494,17 @@ auto resolve_deferred_order_only_edges( } auto source_dir_str = std::string { graph.str(cmd_node->source_dir) }; + auto canonical_cwd = fs::path {}; + if (!state.options.source_root.empty() && !state.options.output_root.empty() + && state.options.source_root != state.options.output_root) { + canonical_cwd = fs::weakly_canonical(state.options.source_root / source_dir_str); + } auto tc = PathTransformContext { .source_to_root = pup::compute_source_to_root(source_dir_str), .current_dir_str = source_dir_str, .source_root = state.options.source_root, .output_root = state.options.output_root, + .canonical_cwd = std::move(canonical_cwd), }; auto replacement = std::string {}; diff --git a/src/graph/dag.cpp b/src/graph/dag.cpp index ac23cfa..5be39f9 100644 --- a/src/graph/dag.cpp +++ b/src/graph/dag.cpp @@ -690,7 +690,14 @@ auto path_extension(std::string_view name) -> std::string_view } // namespace -auto expand_instruction(Graph const& graph, NodeId cmd_id, PathCache& cache) -> std::string +/// Core expansion logic parameterized on the path resolver. +template +auto expand_instruction_impl( + Graph const& graph, + NodeId cmd_id, + PathCache& cache, + PathResolver const& get_operand_path +) -> std::string { auto const* cmd = get_command_node(graph, cmd_id); if (!cmd) { @@ -703,12 +710,6 @@ auto expand_instruction(Graph const& graph, NodeId cmd_id, PathCache& cache) -> } auto source_dir = graph.strings.get(cmd->source_dir); - auto source_to_root = pup::compute_source_to_root(source_dir); - - auto get_operand_path = [&](NodeId id) -> std::string { - auto full = get_full_path(graph, id, cache); - return pup::make_source_relative(full, source_to_root, source_dir); - }; auto get_operand_name = [&](NodeId id) -> std::string_view { return get_name(graph, id); @@ -834,6 +835,48 @@ auto expand_instruction(Graph const& graph, NodeId cmd_id, PathCache& cache) -> return result; } +auto expand_instruction(Graph const& graph, NodeId cmd_id, PathCache& cache) -> std::string +{ + auto const* cmd = get_command_node(graph, cmd_id); + if (!cmd) { + return {}; + } + auto source_dir = graph.strings.get(cmd->source_dir); + auto source_to_root = pup::compute_source_to_root(source_dir); + + return expand_instruction_impl(graph, cmd_id, cache, [&](NodeId id) -> std::string { + auto full = get_full_path(graph, id, cache); + return pup::make_source_relative(full, source_to_root, source_dir); + }); +} + +auto expand_instruction( + Graph const& graph, + NodeId cmd_id, + PathCache& cache, + std::filesystem::path const& source_root +) -> std::string +{ + auto const* cmd = get_command_node(graph, cmd_id); + if (!cmd) { + return {}; + } + auto source_dir = graph.strings.get(cmd->source_dir); + auto source_to_root = pup::compute_source_to_root(source_dir); + auto canonical_cwd = source_root.empty() + ? std::filesystem::path {} + : std::filesystem::weakly_canonical(source_root / std::string { source_dir }); + + return expand_instruction_impl(graph, cmd_id, cache, [&](NodeId id) -> std::string { + auto full = get_full_path(graph, id, cache); + if (!canonical_cwd.empty() && full.starts_with("..")) { + auto abs = std::filesystem::weakly_canonical(source_root / full); + return abs.lexically_relative(canonical_cwd).generic_string(); + } + return pup::make_source_relative(full, source_to_root, source_dir); + }); +} + auto expand_instruction(Graph const& graph, NodeId cmd_id) -> std::string { auto cache = PathCache {}; diff --git a/test/e2e/fixtures/groups_in_inputs/modules/Tupfile.fixture b/test/e2e/fixtures/groups_in_inputs/modules/Tupfile.fixture index 9fc651d..297eb84 100644 --- a/test/e2e/fixtures/groups_in_inputs/modules/Tupfile.fixture +++ b/test/e2e/fixtures/groups_in_inputs/modules/Tupfile.fixture @@ -1,4 +1,4 @@ include_rules -# Use source-root-relative path for cross-directory group -: |> echo "mod1" > %o |> mod1.header modules/ -: |> echo "mod2" > %o |> mod2.header modules/ +# Group lives in this directory (modules/) +: |> echo "mod1" > %o |> mod1.header +: |> echo "mod2" > %o |> mod2.header diff --git a/test/e2e/fixtures/groups_in_inputs/output/Tupfile.fixture b/test/e2e/fixtures/groups_in_inputs/output/Tupfile.fixture index 77afafe..11ea378 100644 --- a/test/e2e/fixtures/groups_in_inputs/output/Tupfile.fixture +++ b/test/e2e/fixtures/groups_in_inputs/output/Tupfile.fixture @@ -1,4 +1,4 @@ include_rules # Group reference in REGULAR inputs (before |), not order-only section # This tests that path/ syntax works in inputs and % expands in command -: modules/ |> cat % > %o |> headers.txt +: ../modules/ |> cat % > %o |> headers.txt From af9a6b59eff4d20ca53261aa27b74dcaf3d1fc4a Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:13:41 +0800 Subject: [PATCH 14/16] Add build-gcc-bsp CI job for end-to-end BSP validation Downloads real GCC 15.2.0 + binutils 2.44 source tarballs and builds the full examples/ BSP using the putup binary from build-linux. Smoke- tests cc1 by compiling a trivial C file to assembly. Also adds PUTUP variable to Makefile.pup so CI can override the binary path without modifying the file. --- .github/workflows/ci.yml | 25 +++++++++++++++++++++++++ examples/Makefile.pup | 15 ++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d56efd8..62feea0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -176,3 +176,28 @@ jobs: sudo apt-get install -y clang-tidy-21 - name: Run clang-tidy run: make tidy PUTUP=./build/putup RUN_CLANG_TIDY=run-clang-tidy-21 TIDY_FLAGS=-allow-no-checks + + 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 + run: make -f Makefile.pup download-source SRCDIR=../source-root + - name: Build + working-directory: examples + run: make -f Makefile.pup PUTUP=../build/putup SRCDIR=../source-root + - 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 diff --git a/examples/Makefile.pup b/examples/Makefile.pup index 78c86cc..9d5e073 100644 --- a/examples/Makefile.pup +++ b/examples/Makefile.pup @@ -26,16 +26,17 @@ 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) + $(PUTUP) configure --config configs/$(PLATFORM).config $(TREES) + $(PUTUP) $(TREES) -j$$(nproc) configure: resolve-mpn setup-host-configs - putup configure --config configs/$(PLATFORM).config $(TREES) + $(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)/. @@ -78,9 +79,9 @@ resolve-mpn: PLATFORMS ?= x86_64-linux aarch64-linux multi: @for p in $(PLATFORMS); do \ - putup configure --config configs/$$p.config -C . -S $(SRCDIR) -B $(BUILD)-$$p; \ + $(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) + $(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)/. @@ -109,7 +110,7 @@ download-binutils: fi clean: - putup clean $(TREES) + $(PUTUP) clean $(TREES) distclean: - putup distclean $(TREES) + $(PUTUP) distclean $(TREES) From 7518229f66421cda50c99b47ec4fca2d7759bc19 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:26:23 +0800 Subject: [PATCH 15/16] Slim clang-tidy config and drop LLVM 21 CI install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop clang-analyzer-* (path-sensitive symbolic execution — by far the most expensive family). Cherry-pick modernize-* (6 checks) and cppcoreguidelines-* (7 checks) instead of enabling full families. Modeled after DuckDB and Ladybird browser configs. Add 'src/|test/' file filter to run-clang-tidy so third_party TUs are never loaded, eliminating the need for --allow-no-checks and the LLVM 21 apt install (~10 min saved per CI run). Use system clang-tidy-18 from the ubuntu-24.04 runner instead. --- .clang-tidy | 233 +++++++++------------------------------ .github/workflows/ci.yml | 9 +- Makefile | 4 +- 3 files changed, 58 insertions(+), 188 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index b5ffae9..de87757 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,194 +1,81 @@ --- -# clang-tidy configuration for uld_cpp -# Based on Ladybird browser config, adapted for C++11 embedded/AOSP project +# clang-tidy configuration for putup +# +# Approach: allowlist high-value checks, skip expensive analysis families. +# Modeled after DuckDB (allowlist + cherry-pick) and Ladybird (no clang-analyzer +# in CI). See https://github.com/duckdb/duckdb and +# https://github.com/LadybirdBrowser/ladybird for reference. +# +# Families enabled in full: bugprone, cert, concurrency, misc, performance, +# portability, readability (with selective exclusions below). +# Families cherry-picked: modernize (6 checks), cppcoreguidelines (7 checks). +# Families omitted: +# clang-analyzer-* — path-sensitive symbolic execution; 10x slower than all +# other checks combined. DuckDB omits it; Ladybird only uses it locally. +# google-* — style rules for Google's C++ guidelines, not our style. # # ============================================================================= # DISABLED CHECKS RATIONALE # ============================================================================= # -# bugprone-easily-swappable-parameters: -# This check warns when adjacent function parameters have similar types and -# could be accidentally swapped by callers. While the warning is valid, it's -# extremely noisy and the suggested fix (wrapping in structs) adds complexity. -# Example: void foo(int width, int height) triggers this warning. -# -# bugprone-macro-parentheses: -# Warns when macro arguments aren't parenthesized in expansion. Our ALOGE/ALOGI -# logging macros use variadic arguments that can't be parenthesized. Ladybird -# also disables this for code-generating macros. -# -# bugprone-reserved-identifier, cert-dcl37-c, cert-dcl51-cpp: -# These warn about identifiers starting with underscore or containing double -# underscores. System headers and OpenSSL headers legitimately use these. -# cert-dcl37-c and cert-dcl51-cpp are aliases for bugprone-reserved-identifier. -# -# cert-err33-c: -# Requires checking return values of certain C functions including fprintf(). -# Our logging macros (ALOGE, ALOGI, etc.) expand to fprintf() calls where -# ignoring the return value is intentional - logging failures shouldn't crash. -# -# cert-err58-cpp: -# ENABLED: Warns about exceptions in static object constructors. This project -# doesn't use exceptions, so no warnings expected. -# -# concurrency-mt-unsafe: -# Flags functions like strerror(), localtime(), getenv() as thread-unsafe. -# This project is single-threaded and these are standard C idioms. Using -# thread-safe alternatives (_r variants) would reduce portability. -# -# misc-const-correctness: -# Suggests adding const to variables that could be const. While good practice, -# enabling this generates hundreds of warnings requiring significant refactoring -# with minimal practical benefit for this codebase. -# -# misc-include-cleaner: -# Analyzes whether includes are necessary. Very noisy, reports many false -# positives, and the suggested changes often break compilation due to -# transitive includes. -# -# misc-no-recursion: -# Warns about recursive function calls. This project intentionally uses -# recursion for tree traversal and nested data structure parsing. -# -# misc-non-private-member-variables-in-classes: -# Warns when classes have non-private member variables. This project uses -# POD-style structs (CAPHeader, FileInfo, etc.) where public members are -# appropriate. The CheckOption IgnoreClassesWithAllMemberVariablesBeingPublic -# handles most cases but some edge cases remain. -# -# misc-unused-parameters: -# Warns about unused function parameters. These are not a security or safety -# concern. Some parameters are intentionally unused in stub implementations -# or virtual method overrides where the signature is fixed. -# -# misc-use-anonymous-namespace: -# Suggests using anonymous namespaces instead of static for internal linkage. -# We prefer static for C++11 compatibility and consistency with existing code. -# Anonymous namespaces can cause issues with some debuggers. -# -# modernize-avoid-c-arrays: -# Suggests replacing C arrays with std::array. This project uses fixed-size -# C arrays intentionally for protocol buffers, crypto operations, and embedded -# compatibility. std::array adds overhead and isn't always available on AOSP. -# -# modernize-use-auto: -# ENABLED: We now use auto declarations where the type is clear from context -# (e.g., auto it = container.begin(), auto result = SomeFunction()). -# Explicit types are still preferred for numeric types where precision matters. -# -# modernize-use-trailing-return-type: -# ENABLED: We now use trailing return type syntax (auto foo() -> ReturnType) -# for consistency with modern C++ style and better readability with complex -# return types. -# -# modernize-raw-string-literal: -# Suggests R"(...)" for strings with escapes. Not always clearer, especially -# for short strings, and can hurt readability for strings with mixed content. -# -# performance-enum-size: -# Suggests using smaller base types for enums (int8_t instead of int). While -# this could save memory, enums in this project are not in hot paths or large -# arrays where size matters. The default int size aids debugging. -# -# performance-trivially-destructible: -# Suggests defaulting empty destructors in class definitions to make them -# trivially destructible. While technically correct, explicit destructor -# declarations document intent and allow future extension. -# -# performance-no-int-to-ptr: -# Warns about integer-to-pointer casts. Low-level serial and crypto code -# sometimes requires legitimate pointer arithmetic. This check is overly -# broad for systems programming. -# -# performance-noexcept-move-constructor: -# Suggests adding noexcept to move constructors. This project doesn't use -# exceptions (-fno-exceptions on AOSP), so noexcept provides no benefit -# and adds visual noise. -# -# readability-braces-around-statements: -# ENABLED: Project style now requires braces around all if/for/while bodies -# for consistency and to prevent bugs from later additions. -# -# readability-convert-member-functions-to-static: -# Suggests making member functions static when they don't use 'this'. This -# is a design choice - keeping methods as non-static preserves API flexibility -# and allows future refactoring to use member state without API changes. -# -# readability-else-after-return: -# Warns about using 'else' after a return statement. While early return can -# be cleaner, explicit else blocks can improve readability by making all -# branches visually parallel, especially in switch-like if/else chains. -# -# readability-function-cognitive-complexity: -# Measures function complexity and warns above threshold. Complex functions -# in crypto and protocol parsing are sometimes unavoidable. Warnings are -# hard to fix without artificial refactoring that hurts readability. -# -# readability-function-size: -# Warns when functions exceed size thresholds. Crypto functions (OAEP, -# decryption) and protocol parsers are inherently complex and can't be -# split without hurting readability. Test runners also legitimately large. -# -# readability-identifier-length: -# Warns about short variable names (i, n, fd, etc.). These are idiomatic -# in C/C++ for loop indices, counts, and file descriptors. Longer names -# would hurt readability in tight loops. -# -# readability-implicit-bool-conversion: -# Warns about implicit conversions to bool (if (ptr) instead of if (ptr != -# nullptr)). The implicit form is idiomatic C++ and often clearer. -# -# readability-magic-numbers: -# Warns about numeric literals in code. Despite recent cleanup to add named -# constants, many legitimate magic numbers remain (bit shifts, protocol -# offsets, etc.) where inline numbers are clearer than constants. -# -# readability-named-parameter: -# Requires naming all function parameters. We intentionally omit names for -# unused parameters to satisfy -Wunused-parameter: void foo(int /*unused*/) -# -# readability-simplify-boolean-expr: -# Suggests applying DeMorgan's theorem to simplify boolean expressions. While -# mathematically equivalent, the original form (explicit range checks like -# c >= '0' && c <= '9') is often more readable than the transformed version. -# -# readability-make-member-function-const: -# Suggests making member functions const when they don't modify member -# variables. This produces false positives for I/O methods that don't -# modify class state but have observable side effects (serial reads/writes, -# file operations). The check can't detect that calling read()/write() -# on a file descriptor has side effects. -# -# readability-uppercase-literal-suffix: -# Suggests 1UL instead of 1ul for literal suffixes. Low priority style issue -# with many occurrences. Can be enabled later for incremental cleanup. +# bugprone-easily-swappable-parameters: too noisy, fix adds complexity +# bugprone-macro-parentheses: variadic macros can't parenthesize args +# cert-err33-c: fprintf return values in logging are intentionally ignored +# concurrency-mt-unsafe: single-threaded project, standard C idioms fine +# misc-const-correctness: hundreds of warnings, marginal benefit +# misc-include-cleaner: noisy false positives, breaks transitive includes +# misc-no-recursion: intentional recursion for tree traversal / parsing +# misc-non-private-member-variables-in-classes: POD structs use public members +# misc-unused-parameters: intentional in stubs and virtual overrides +# performance-enum-size: not in hot paths; default int aids debugging +# performance-no-int-to-ptr: legitimate in low-level pointer arithmetic +# performance-noexcept-move-constructor: no exceptions in this project +# readability-convert-member-functions-to-static: design choice for API flex +# readability-function-cognitive-complexity: unavoidable in parsers +# readability-function-size: large functions in parsers are sometimes clearest +# readability-identifier-length: short names (i, n, fd) are idiomatic C++ +# readability-implicit-bool-conversion: if (ptr) is idiomatic +# readability-magic-numbers: inline numbers often clearer than constants +# readability-make-member-function-const: false positives on I/O methods +# readability-named-parameter: intentionally omitted for unused params +# readability-redundant-member-init: explicit init documents intent +# readability-simplify-boolean-expr: explicit range checks are more readable # # ============================================================================= Checks: > bugprone-*, - cert-*, - clang-analyzer-*, - -clang-analyzer-core.uninitialized.Assign, - concurrency-*, - misc-*, - modernize-*, - performance-*, - portability-*, - readability-*, -bugprone-easily-swappable-parameters, -bugprone-macro-parentheses, + cert-*, -cert-err33-c, + concurrency-*, -concurrency-mt-unsafe, + cppcoreguidelines-avoid-non-const-global-variables, + cppcoreguidelines-interfaces-global-init, + cppcoreguidelines-pro-type-const-cast, + cppcoreguidelines-pro-type-cstyle-cast, + cppcoreguidelines-rvalue-reference-param-not-moved, + cppcoreguidelines-slicing, + cppcoreguidelines-virtual-class-destructor, + misc-*, -misc-const-correctness, -misc-include-cleaner, -misc-no-recursion, -misc-non-private-member-variables-in-classes, -misc-unused-parameters, - -modernize-raw-string-literal, + modernize-use-auto, + modernize-use-bool-literals, + modernize-use-emplace, + modernize-use-nullptr, + modernize-use-override, + modernize-use-trailing-return-type, + performance-*, -performance-enum-size, -performance-no-int-to-ptr, -performance-noexcept-move-constructor, + portability-*, + readability-*, -readability-convert-member-functions-to-static, -readability-function-cognitive-complexity, -readability-function-size, @@ -199,12 +86,6 @@ Checks: > -readability-named-parameter, -readability-redundant-member-init, -readability-simplify-boolean-expr, - cppcoreguidelines-*, - -cppcoreguidelines-avoid-magic-numbers, - -cppcoreguidelines-pro-bounds-array-to-pointer-decay, - -cppcoreguidelines-pro-bounds-constant-array-index, - -cppcoreguidelines-pro-bounds-pointer-arithmetic, - -cppcoreguidelines-pro-type-reinterpret-cast WarningsAsErrors: '' @@ -219,9 +100,5 @@ CheckOptions: value: 'true' - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: true - - key: readability-function-size.LineThreshold - value: 200 - - key: readability-function-size.StatementThreshold - value: 400 - key: modernize-use-trailing-return-type.AllowOverridingMethods value: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62feea0..851df0f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -167,15 +167,8 @@ jobs: path: build/ - name: Fix permissions run: chmod +x build/putup - # clang-tidy 18 (ubuntu default) errors on Checks: '-*' in - # third_party/.clang-tidy ("no checks enabled", exit 1). - # --allow-no-checks was added in 19. See llvm/llvm-project#86355 - - name: Install LLVM 21 - run: | - wget -qO- https://apt.llvm.org/llvm.sh | sudo bash -s -- 21 - sudo apt-get install -y clang-tidy-21 - name: Run clang-tidy - run: make tidy PUTUP=./build/putup RUN_CLANG_TIDY=run-clang-tidy-21 TIDY_FLAGS=-allow-no-checks + run: make tidy PUTUP=./build/putup RUN_CLANG_TIDY=run-clang-tidy-18 build-gcc-bsp: needs: build-linux diff --git a/Makefile b/Makefile index b4fa4c6..0631c85 100644 --- a/Makefile +++ b/Makefile @@ -55,11 +55,11 @@ RUN_CLANG_TIDY ?= run-clang-tidy tidy: compdb @echo "Running clang-tidy..." - @$(RUN_CLANG_TIDY) -p . $(TIDY_FLAGS) + @$(RUN_CLANG_TIDY) -p . $(TIDY_FLAGS) 'src/|test/' tidy-fix: compdb @echo "Running clang-tidy with fixes..." - @$(RUN_CLANG_TIDY) -p . -fix $(TIDY_FLAGS) + @$(RUN_CLANG_TIDY) -p . -fix $(TIDY_FLAGS) 'src/|test/' format: @echo "Formatting sources..." From 06480a0228b447fcad03344411d5904a90e51002 Mon Sep 17 00:00:00 2001 From: Mura Li <2606021+typeless@users.noreply.github.com> Date: Thu, 26 Feb 2026 23:04:37 +0800 Subject: [PATCH 16/16] Fix stale docs after BSP flattening and toolchain expansion - gcc-example SKILL.md: update build command from examples/gcc/ to examples/, remove stale PUP_IMPLICIT_DEPS workaround, update phase list from 7 to 14, fix Phase 6 description, fix scope description - tupfile-patterns SKILL.md: fix root Tuprules example to use gcc/gmp paths matching actual BSP layout - examples/README.md: add Makefile Targets + Variables section, fix Architecture wording (not all dirs have gcc/ prefix), fix Known Limitations (no Tupfile.ini, not $(CC)) - examples/Tupfile: fix stale reference to gcc/gcc/config/i386/Tupfile (now gcc/gcc/targets/x86_64-pc-linux-gnu.tup) - examples/gcc/gcc/Tupfile: update header comment to 14 phases - examples/busybox/README.md: remove deleted Tupfile.ini from table - docs/reference.md: add -C/-S to configure Relevant Options --- .claude/skills/gcc-example/SKILL.md | 35 +++++++++++++++++------- .claude/skills/tupfile-patterns/SKILL.md | 4 +-- docs/reference.md | 2 ++ examples/README.md | 28 +++++++++++++++++-- examples/Tupfile | 2 +- examples/busybox/README.md | 1 - examples/gcc/gcc/Tupfile | 13 ++++----- 7 files changed, 61 insertions(+), 24 deletions(-) diff --git a/.claude/skills/gcc-example/SKILL.md b/.claude/skills/gcc-example/SKILL.md index c5150a8..e1d9ecc 100644 --- a/.claude/skills/gcc-example/SKILL.md +++ b/.claude/skills/gcc-example/SKILL.md @@ -1,37 +1,52 @@ --- name: gcc-example -description: Building GCC with putup. Use when working on the examples/gcc/ directory, debugging GCC build failures, adding new GCC source files to the build, fixing generator issues, or extending the cc1 build. Covers 3-tree mode workflow, generator patterns, config headers, and accumulated fixes. +description: Building GCC with putup. Use when working on the examples/ BSP directory, debugging GCC build failures, adding new GCC source files to the build, fixing generator issues, or extending the toolchain. Covers 3-tree mode workflow, generator patterns, config headers, and accumulated fixes. --- # GCC Example Build -The `examples/gcc/` directory builds GCC's cc1 C compiler from source using putup in 3-tree mode. This skill captures the architecture and hard-won knowledge from iterative debugging. +The `examples/` BSP directory builds GCC and binutils from source using putup in 3-tree mode. GCC-specific Tupfiles live under `examples/gcc/`. This skill captures the architecture and hard-won knowledge from iterative debugging. ## Build Command ```bash -cd /path/to/pup/examples/gcc && \ - PUP_IMPLICIT_DEPS=0 putup -C . -S /path/to/gcc-15.2.0 -B ../../build-gcc -j$(nproc) +cd /path/to/pup/examples && \ + make -f Makefile.pup SRCDIR=../source-root ``` -- `-C .` — config tree (our Tupfiles, tup.config, Tuprules.tup) -- `-S /path/to/gcc-15.2.0` — GCC source tree (read-only) -- `-B ../../build-gcc` — build output directory -- `PUP_IMPLICIT_DEPS=0` — workaround for 3-tree groups bug +Or directly with putup: + +```bash +cd /path/to/pup/examples && \ + 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) +``` + +- `-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 After editing any `tup.config`, re-run `putup configure` to propagate to the build dir. ## Architecture -Seven build phases in `gcc/Tupfile`: +14 build phases in `gcc/gcc/Tupfile`: 1. **Config headers** (``) — auto-host.h, bconfig.h, config.h, tm.h, tm_p.h, options.h, etc. 2. **Generator bootstrap** — genmodes → insn-modes.h → BUILD_RTL → genconditions → insn-conditions.md 3. **RTL generators** — 20+ generators producing insn-*.h/cc files (``) 4. **Generated source compilation** — compile all generated .cc into `` 5. **Backend objects** — ~445 source files from gcc/ -6. **Common objects** — from gcc/c/, gcc/c-family/, gcc/analyzer/, gcc/config/i386/ +6. **Common objects** — OBJS-libcommon + OBJS-libcommon-target 7. **cc1 link** — link everything with library archives +8. **xgcc driver** — main gcc/g++ driver executable +9. **cc1plus** — C++ compiler (C++ frontend objects from gcc/cp/) +10. **collect2** — linker wrapper +11. **g++ driver** (xg++) — C++ compilation driver +12. **cpp** — standalone C preprocessor +13. **lto-wrapper** — LTO linker plugin interface +14. **gcov + gcov-dump** — code coverage tools ### Group Dependencies diff --git a/.claude/skills/tupfile-patterns/SKILL.md b/.claude/skills/tupfile-patterns/SKILL.md index f1791f0..b6e34aa 100644 --- a/.claude/skills/tupfile-patterns/SKILL.md +++ b/.claude/skills/tupfile-patterns/SKILL.md @@ -142,8 +142,8 @@ For multi-library projects (like GCC with GMP, MPFR, MPC): ```tup S = $(TUP_CWD) B = $(TUP_VARIANT_OUTPUTDIR)/$(S) -GMP_DIR = gmp -MPFR_DIR = mpfr +GMP_DIR = gcc/gmp +MPFR_DIR = gcc/mpfr ``` **Each library's `Tuprules.tup`** — uses `?=` defaults for standalone builds: diff --git a/docs/reference.md b/docs/reference.md index 2fe38fc..3122288 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -269,6 +269,8 @@ putup # Pass 2: Build with generated configs - `-v` - Verbose output - `-k` - Continue after failures - `-n` - Dry-run: show what would execute +- `-C DIR` - Config directory (where Tupfiles and tup.config live) +- `-S DIR` - Source directory (read-only source tree) - `-B DIR` - Specify build directory (created automatically if it doesn't exist) - `-c, --config FILE` - Install FILE as root tup.config before running config rules diff --git a/examples/README.md b/examples/README.md index 4607ede..992a5f8 100644 --- a/examples/README.md +++ b/examples/README.md @@ -96,9 +96,33 @@ 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 + +| 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` | + +**Variables:** + +| 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` | + ## Architecture -- **Root `Tuprules.tup`** uses `=` (force-set) for all DIR variables with `gcc/` prefix +- **Root `Tuprules.tup`** uses `=` (force-set) for all DIR variables (e.g. `GCC_DIR = gcc/gcc`, `BINUTILS_DIR = binutils`) - **Group `Tuprules.tup`** uses `?=` (default) — overridden in BSP mode, effective standalone - **Package `Tuprules.tup`** uses `?=` for toolchain vars — overridden by both root and group - `include_rules` processes root-first; BSP root wins over group defaults @@ -106,4 +130,4 @@ putup -S /path/to/gcc-15.2.0 -B /path/to/build ## Known Limitations - putup `create_directories` crashes on symlinks in source tree -- busybox and helloworld are not yet integrated into the BSP (use `$(CC)` from root config) +- busybox and helloworld are not yet BSP-integrated (no `Tupfile.ini` — excluded from BSP scan) diff --git a/examples/Tupfile b/examples/Tupfile index f3c63c0..f426d5e 100644 --- a/examples/Tupfile +++ b/examples/Tupfile @@ -17,7 +17,7 @@ include_rules # gcc/gcc/cp/Tupfile → C++ frontend objects # gcc/gcc/c-family/Tupfile → C-family shared objects # gcc/gcc/analyzer/Tupfile → Static analyzer objects -# gcc/gcc/config/i386/Tupfile → x86_64 target-specific objects +# gcc/gcc/targets/x86_64-pc-linux-gnu.tup → x86_64 target rules (included by gcc/gcc/Tupfile) # # binutils tarball (binutils/): # binutils/Tupfile → as (cross-assembler), ar (cross-archiver) diff --git a/examples/busybox/README.md b/examples/busybox/README.md index 899fe66..2a964e7 100644 --- a/examples/busybox/README.md +++ b/examples/busybox/README.md @@ -36,7 +36,6 @@ putup build-android build-freebsd -j$(nproc) | File | Purpose | |------|---------| | `Makefile.pup` | Make wrapper for putup commands | -| `Tupfile.ini` | Project root marker | | `Tuprules.tup` | Compiler flags and macros | | `Tupfile` | Config generation + source compilation rules | | `scripts/kconfig/Tupfile` | Builds kconfig conf tool | diff --git a/examples/gcc/gcc/Tupfile b/examples/gcc/gcc/Tupfile index 73d5328..da67912 100644 --- a/examples/gcc/gcc/Tupfile +++ b/examples/gcc/gcc/Tupfile @@ -4,14 +4,11 @@ include_rules # GCC 15.2.0 — C compiler backend # ============================================================ # -# Builds cc1 from the GCC source tree via seven phases: -# 1. Config headers + options pipeline -# 2. Generator bootstrap (genmodes → BUILD_RTL → generators) -# 3. Machine-description generators + gengtype (GC type descriptors) -# 4. Generated source compilation -# 5. Backend + common object compilation -# 6. Common objects -# 7. cc1 link +# Builds the GCC toolchain from source via 14 phases: +# 1-3. Config headers, generator bootstrap, RTL generators +# 4-6. Generated source, backend objects, common objects +# 7. cc1 link +# 8-14. xgcc, cc1plus, collect2, g++, cpp, lto-wrapper, gcov # # Platform selection (from root tup.config): # @(TARGET) — target triple (e.g. x86_64-pc-linux-gnu)