Deep Dive Make: The Course-Book Capstone¶
The capstone is the executable reference build for Deep Dive Make: a compact C project whose Makefiles are written to prove, not merely claim, production-grade properties—truthful DAGs, atomic publication, parallel safety, determinism, and self-testing invariants. It is the practical companion to the course-book in course-book/: every major pattern in the text has a living implementation here, with repros for common failure modes and CI-enforced verification.
In one line: a small build that behaves like a serious build—correct under change, correct under
-j, and instrumented to catch its own lies.
Table of Contents¶
- Purpose
- Quick start
- Public targets
- What it builds
- Architecture
- Platform notes
- Repro pack
- Links into the course-book
- Contributing
- License
Purpose¶
This capstone exists to eliminate ambiguity. “Correct Makefiles” should not be a matter of taste; they should be a matter of verifiable properties.
This build is designed to enforce:
- Truthful DAG: edges are explicit (depfiles, manifests/stamps where required), with deterministic discovery.
- Atomic publication: outputs are not visible until they are valid.
- Parallel safety: -j accelerates execution but does not alter meaning.
- Determinism: serial and parallel runs converge to identical outputs.
- Self-tests: the build system is treated as code—tested, gated, and regression-resistant.
Back to top
Quick start¶
From this directory (make-capstone/):
selftest is the signal that the contract holds: convergence, serial/parallel equivalence, and negative tests designed to detect common defects.
Back to top
Public targets¶
These are the stable entrypoints you can rely on and extend:
| Target | Meaning | Why you care |
|---|---|---|
help |
Print available targets and key knobs. | Discoverability. |
all |
Build primary artifacts. | Normal build. |
test |
Run runtime checks on outputs. | Functional validation. |
selftest |
Verify build-system invariants (convergence, equivalence, negatives). | Integrity gate. |
discovery-audit |
Confirm discovery is rooted and stable. | Prevent “works on my machine” edges. |
attest |
Record toolchain/flag/env facts (non-contaminating by default). | Reproducibility audit. |
portability-audit |
Check version/tool assumptions and feature availability. | Cross-platform discipline. |
repro |
List available failure repros. | Training + debugging. |
clean |
Remove build outputs and stamps. | Reset. |
Optional (explicit opt-in): USE_EVAL=yes eval-demo demonstrates quarantined $(eval) patterns.
Back to top
What it builds¶
A deliberately small C project with real build-system pressure points:
* app: main executable built from a small set of sources.
* Dynamic binaries: src/dynamic/*.c discovered deterministically and built into build/bin/dyn*.
* Generated header: build/include/dynamic.h generated by scripts/ and used across translation units.
Core mechanics:
* depfiles (*.d) are treated as true edges
* publication is atomic (temp → rename)
* tests assert behavior (not just “it compiled”)
Back to top
Architecture¶
The Makefiles are intentionally layered so the design stays readable under growth:
make-capstone/
├── Makefile # Entry point: public targets + includes
├── mk/ # Build mechanics, separated by responsibility
│ ├── common.mk # toolchain defaults and shared configuration
│ ├── macros.mk # reusable primitives (atomic publish, helpers)
│ ├── objects.mk # discovery and object graph construction
│ ├── stamps.mk # modeled hidden inputs (tools/flags/env)
│ ├── contract.mk # selftests, gates, and invariants
│ └── rules_eval.mk # quarantined eval patterns (opt-in)
├── src/ # C sources (including dynamic/ discovery)
├── include/ # stable headers
├── scripts/ # generators (e.g., generated headers)
├── tests/ # runtime assertions + build invariants harness
├── repro/ # intentionally broken cases with fixes
└── thirdparty/ # stub boundary for external integration
Back to top
Platform notes¶
- macOS:
/usr/bin/makeis BSD Make—use GNU Make (gmake). - Toolchains differ: determinism is verified via stamps/equivalence checks rather than assumed.
- Portability: the build declares its boundary (GNU Make floor, shell assumptions) and audits it with
portability-audit.
Back to top
Repro pack¶
repro/ contains small Makefiles that intentionally demonstrate failure modes (often only visible under -j), along with the repair patterns taught in the course-book.
Examples include:
* shared append/log races
* temp file collisions and partial writes
* incorrect stamp usage that hides inputs
* incorrect modeling of generated headers
* directory creation hazards
Run a repro directly:
Links into the course-book¶
- Course text: https://bijux.github.io/deep-dive-make/
- Source chapters:
course-book/The capstone is referenced throughout the modules via “tie-ins.” The expectation is a tight loop: read → reproduce → repair → verify
Back to top
Contributing¶
Contributions are welcome when they improve correctness, clarity, or reproducibility (new repros, sharper invariants, better diagnostics). Minimum bar for changes that touch the build (from repository root):
(orgmake -C make-capstone selftest on macOS)
Open a PR against main with a short “claim → proof” note (what you changed, why it’s correct, and how it’s verified).Back to top
License¶
MIT — see LICENSE. © 2025 Bijan Mousavi.
Back to top