Skip to content

feat(build): L3 build.mcpp — native imperative build program (v0.0.78)#190

Merged
Sunrisepeak merged 2 commits into
mainfrom
feat/l3-build-mcpp
Jun 30, 2026
Merged

feat(build): L3 build.mcpp — native imperative build program (v0.0.78)#190
Sunrisepeak merged 2 commits into
mainfrom
feat/l3-build-mcpp

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

What

Adds build.mcpp — a project-local native imperative build program (Zig build.zig / Cargo build.rs model, but in C++, so no second language and it dogfoods mcpp). mcpp compiles it with the host toolchain and runs it before the main build; it emits stdout mcpp: directives that augment the build.

This completes the manifest-environment/platform design's L3 phase (after L1 cfg flags 0.0.74, L1b cfg deps 0.0.75, L-1 [xlings] env 0.0.77).

Directives (Discipline 1 — structured output, not global mutation)

cxxflag / cflag / link-lib / link-search / cfg (→ -D) / generated=<src> / rerun-if-changed=<path> / rerun-if-env-changed=<VAR>. Non-mcpp: lines are ignored. The program requests leaf build edges; it cannot add a registry dependency (the graph stays declarative in mcpp.toml).

Declared-input cache (Discipline 2 — fixes the .mcpp_ok blind spot)

The program is not re-run every build. Its directives + declared inputs are cached at .mcpp/build.mcpp.cache; it re-runs only when the source, toolchain, a declared rerun-if-changed file, a declared rerun-if-env-changed var, or a missing generated output says so. Applied directives flow into buildConfig.{c,cxx,ld}flags → fingerprint and generated sources → modgraph, so the main build stays correctly incremental.

Constraints

  • Leaf only — cannot gate the top-level dependency graph (that's the applicative L1 [target.'cfg(...)'] tables).
  • Host build / target cfg — compiles+runs on the host; under a cross --target it is skipped with a warning (host-toolchain-for-cross is a follow-up).
  • -x c++ so the .mcpp extension compiles as C++ (see design doc's forward note: .mcpp as a first-class C++ extension inside mcpp projects).

Files

  • src/build/build_program.cppm (new module), wired in src/build/prepare.cppm after toolchain detect + L1 cfg merge, before the modgraph scan.
  • tests/e2e/89_build_mcpp.sh — define + generated source reach the build; cache short-circuits an unchanged re-run; a changed declared env forces re-run.
  • docs/07-build-mcpp.md (+ docs/zh/), indexed in both READMEs.
  • .agents/docs/2026-06-30-l3-build-mcpp-implementation-design.md; version → 0.0.78.

Verified locally (mcpp 0.0.78)

89_build_mcpp passes; focused regression set (02 new/build/run, 04 incremental, 85/86 cfg flags/deps, 87 default-profile, 88 xlings env) all green.

🤖 Generated with Claude Code

A project-local build.mcpp (C++, Zig build.zig / Cargo build.rs model) compiled
with the host toolchain and run before the main build. It emits stdout mcpp:
directives that augment the build; a declared-input cache re-runs it only when
its source/inputs/env change (the documented fix for the .mcpp_ok blind spot).

- src/build/build_program.cppm: new module — compile+run, directive parser
  (cxxflag/cflag/link-lib/link-search/cfg/generated/rerun-if-changed/
  rerun-if-env-changed), declared-input cache, apply to buildConfig
- prepare.cppm: invoke after toolchain detect + L1 cfg merge, before modgraph
  scan; skipped under cross --target (host build/run). -x c++ so the .mcpp
  extension compiles as C++
- tests/e2e/89_build_mcpp.sh: define+generated source reach the build; cache
  short-circuits unchanged re-run; changed env forces re-run
- docs/07-build-mcpp.md (+zh): user guide; design doc + version bump 0.0.78

🤖 Generated with [Claude Code](https://claude.com/claude-code)
CI e2e (fresh sandbox) failed compiling build.mcpp: a bare 'g++ file -o bin'
can't find crt/libc without the toolchain sysroot wiring the main build adds
(it works only on warm dev boxes). Pass the host subset from the resolved
Toolchain (host_base_flags): GCC --sysroot (or glibc-payload -idirafter/-B/-L),
binutils -B, link-runtime -L/-rpath; Clang trusts its .cfg. Mirrors flags.cppm's
GCC branch (build.mcpp is host-only, so only native cases needed).

Also move build.mcpp's binary + declared-input cache to target/.build-mcpp/
(per project direction: artifacts under target/, not the project tree).

design doc: host-flags rationale + typed import mcpp; library direction.
@Sunrisepeak Sunrisepeak merged commit 35eae70 into main Jun 30, 2026
5 checks passed
@Sunrisepeak Sunrisepeak deleted the feat/l3-build-mcpp branch June 30, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant