summaryrefslogtreecommitdiff
path: root/skills/incremental-builds.md
diff options
context:
space:
mode:
authorDibyendu Majumdar <mobile@majumdar.org.uk>2023-08-19 08:52:57 -0700
committerDibyendu Majumdar <mobile@majumdar.org.uk>2026-10-25 14:24:09 -0700
commit5728a38120004e61fe4d49c756dc2c18649f5431 (patch)
treead93aa0cff278a9f15915653aae8a2206c0248e7 /skills/incremental-builds.md
downloadSimple-5728a38120004e61fe4d49c756dc2c18649f5431.tar.gz
Simple-5728a38120004e61fe4d49c756dc2c18649f5431.zip
Chapter 1: Introduction
Co-authored-by: Cliff Click <cliffc@acm.org> Co-authored-by: Thalia Archibald <thalia@archibald.dev> Co-authored-by: hadha <helsgithub15@gmail.com> Co-authored-by: XmiliaH <45106915+XmiliaH@users.noreply.github.com> Co-authored-by: Tamás Hadházy <85063808+Hels15@users.noreply.github.com> Co-authored-by: Jun Kawasaki <jun784@gmail.com>
Diffstat (limited to 'skills/incremental-builds.md')
-rw-r--r--skills/incremental-builds.md75
1 files changed, 75 insertions, 0 deletions
diff --git a/skills/incremental-builds.md b/skills/incremental-builds.md
new file mode 100644
index 00000000..050bd1ba
--- /dev/null
+++ b/skills/incremental-builds.md
@@ -0,0 +1,75 @@
+# Incremental builds
+
+Implementation notes and remaining build-driver work, reviewed 2026-10-25.
+
+## Current reuse check
+
+Chapter 28b's `CompUnit` decides whether to reuse a local object by walking its
+recorded dependencies before loading saved types or IR. It checks all sources
+owned by each local object, missing inputs, and dependency object timestamps.
+Dependencies use the same local/library resolution for checking and loading.
+
+For example:
+
+1. A depends on B and has inlined some of B.
+2. B's source changes, leaving B's object unchanged.
+3. A client discovers A. The check follows A's recorded dependency to B and
+ finds B's newer source, even though B's object has not changed.
+4. A is reparsed, so its saved inlined copy of B is never accepted.
+
+Use a fresh visited set for each candidate object. Cycles terminate safely,
+but a provisional success inside a cycle must not be cached for another root.
+Dependencies owned by the same object are checked through its bundled sources.
+An unchanged public signature is insufficient: Simple imports implementation
+details for optimization as well as declarations for type checking.
+
+Object-only libraries are still supplied as a coherent build. Do not reject
+them merely because one dependency has a newer installation timestamp: existing
+tests compile cyclic libraries against stubs and then combine their real
+objects. Validating those combinations requires saved input versions, not a
+guess from file times. A newer library object does invalidate a source-backed
+local dependent that can be rebuilt.
+
+`IncrementalBuildTest` covers unchanged reuse, transitive source edits, bundled
+cycles, missing inputs, library dependencies, and clean/incremental native
+execution parity. It sets file times directly, without sleeps.
+
+## Required pieces
+
+- Plan object targets and rebuilds across invocations. Handle cycles as groups
+ and newly discovered dependencies. The compiler's per-object reuse check is
+ not a complete scheduling or linking policy.
+- Record actual input identities. An object can own several source units, so
+ track all of their sources and resolved library paths and versions. A search
+ path change can select a different library even with an older timestamp.
+- Record compiler and serialization versions, target, ABI, and relevant
+ options. Content hashes would also detect changes with preserved timestamps.
+ Specify which changes require rebuilding source and which reject an
+ incompatible source-free library.
+- Make build targets match output ownership. The old ignored `testModule0`
+ expects separate A.o and A/B.o, while the current compiler can bundle several
+ units into one object. The target must identify the complete set it owns.
+- Provide an "ensure current" build operation. Explicit source compilation
+ currently always recompiles. An unchanged build should do no compilation or
+ linking; a changed object or link input should trigger relinking.
+- Publish successful outputs without leaving a partial object accepted after
+ failure, and keep the recorded inputs consistent with those outputs.
+
+Initially, rebuilding every dependent of a changed object is a reasonable
+conservative rule. Fine-grained interface/body fingerprints can come later.
+
+## Suggested first implementation
+
+Put a small build driver around the compiler with explicit object targets,
+recorded inputs, and dependency propagation. Keep individual compilation
+requests straightforward. A clean build and an incremental build must produce
+the same observable program behavior.
+
+Cover unchanged builds, direct and transitive source edits, inlined constants
+and bodies, cyclic dependencies, bundled sources, removed inputs, library-path
+changes, compiler/target changes, and failed builds. Use controlled timestamps
+or hashes instead of sleeps. Replace the ignored historical experiment with
+tests matching the chosen object ownership model.
+
+Selective library IR loading is separate future work. It can reduce compile
+cost, but is not required to make conservative incremental rebuilding correct.