build.h (6684B)
1 #ifndef KIT_BUILD_BUILD_H 2 #define KIT_BUILD_BUILD_H 3 4 #include <kit/cas.h> 5 #include <kit/core.h> 6 #include <stdarg.h> 7 #include <stddef.h> 8 #include <stdint.h> 9 10 /* 11 * Shared substrate for the content-addressed build coordinator 12 * (`<kit/build_coord.h>`, `kit build`). See doc/BUILD_COORDINATOR.md. 13 * 14 * This layer sits *on top of* the public content store (`<kit/cas.h>`), the 15 * digest surface (`<kit/hash.h>`), and the signed-package machinery 16 * (`<kit/package.h>`). It deliberately does not reach into src/dist internals: 17 * every id it computes is a plain BLAKE2b-256 of canonical bytes, which is 18 * exactly a CAS blob id (`kit_blob_info`), so need-overlay maps, argv vectors, 19 * and trace bodies content-address themselves through the ordinary CAS. 20 * 21 * Naming/result conventions mirror src/dist: internal modules return `int` 22 * (BUILD_OK / BUILD_ERR), parse/emit modules also take a `char* err, size_t 23 * errcap` sink, and the public composition layer (src/api/build.c) maps the 24 * result to KitStatus and routes human-readable detail through ctx->diag. All 25 * ids are lowercase hex on the wire and in every canonical text body. 26 */ 27 28 /* All content ids are BLAKE2b-256, shared with the CAS. */ 29 #define BUILD_HASH_LEN KIT_CAS_HASH_LEN 30 #define BUILD_HEX_LEN (2u * BUILD_HASH_LEN + 1u) 31 32 /* Result convention for internal modules: 0 = ok, non-zero = error. */ 33 #define BUILD_OK 0 34 #define BUILD_ERR 1 35 36 /* Canonical text magics (version lines), in the `kit-tree 1` / `kit-package 3` 37 * family: a version line, ordered scalar fields, then sorted sections. */ 38 #define BUILD_SHALLOW_MAGIC "kit-build-shallow 1" 39 #define BUILD_DEEP_MAGIC "kit-build-deep 1" 40 #define BUILD_TEST_SHALLOW_MAGIC "kit-build-test-shallow 1" 41 #define BUILD_TEST_DEEP_MAGIC "kit-build-test-deep 1" 42 #define BUILD_DEEPSET_MAGIC \ 43 "kit-build-deepset 1" /* one node of the transitive input-closure DAG */ 44 #define BUILD_RECORD_MAGIC "kit-build-record 1" 45 #define BUILD_CONFIG_MAGIC \ 46 "kit-build-config 1" /* serialized propagated map \ 47 */ 48 #define BUILD_ARGV_MAGIC "kit-build-argv 1" /* serialized local argv vector */ 49 #define BUILD_TRACES_MAGIC \ 50 "kit-build-traces 1" /* signed trace-bundle manifest */ 51 #define BUILD_DEFN_MAGIC "kit-build 1" /* build-definition file */ 52 53 /* The resolution identity of a build is the triple (target-name, config-id, 54 * argv-id): config-id is the effective propagated config, argv-id the effective 55 * local argv. Two requests for one target that differ in either are distinct 56 * builds. Traces record all three and match on all three. 57 * 58 * Domain-separation prefix for the per-target index key: 59 * target-key = BLAKE2b("kit build target v1" || target-name). 60 * The index key depends on the target NAME only — never config, argv, or 61 * recipe-id — so a target's mutable record is a stable handle holding candidate 62 * traces across every (config, argv) it was recently built under, while its 63 * inputs churn. */ 64 #define BUILD_TARGET_KEY_DOMAIN "kit build target v1" 65 #define BUILD_TEST_TARGET_KEY_DOMAIN "kit build test target v1" 66 67 /* Fixed string capacities. A target name and config key/value are bounded; a 68 * workspace/source path is bounded by BUILD_PATH_MAX. These cap a single 69 * canonical row, never an aggregate. */ 70 #define BUILD_TARGET_MAX 256u /* e.g. "//app:server" */ 71 #define BUILD_KEY_MAX 64u /* config key name */ 72 #define BUILD_VAL_MAX 512u /* config value */ 73 #define BUILD_PATH_MAX 1024u /* workspace-relative or absolute fs path */ 74 #define BUILD_URL_MAX 1024u /* one fetch URL hint */ 75 #define BUILD_PATTERN_MAX 256u /* glob pattern */ 76 77 /* Per-recipe trace section capacities. These are aggregate limits for one 78 * recipe execution, not row-size limits. They need to fit real C-library 79 * recipes that log one source leaf per compiled source/header while staying 80 * fixed-size and VLA-free. */ 81 #define BUILD_RECIPE_CONFIG_CAP 256u 82 #define BUILD_RECIPE_SOURCE_CAP 1024u 83 #define BUILD_RECIPE_GLOB_CAP 256u 84 #define BUILD_RECIPE_BLOB_CAP 256u 85 #define BUILD_RECIPE_DEP_CAP 256u 86 87 /* The two kinds of trace a build records. Written together on every real 88 * build; resolution picks whichever fits the change it sees. */ 89 typedef enum BuildTraceKind { 90 BUILD_TRACE_DEEP = 0, 91 BUILD_TRACE_SHALLOW = 1, 92 } BuildTraceKind; 93 94 /* MRU window size of the mutable per-target record (each kind capped 95 * independently). Older candidates age out and become GC-eligible. */ 96 #define KIT_BUILD_RECORD_CAP 8u 97 98 /* The first two lowercase-hex chars of an id form its fan-out dir, as in 99 * doc/DISTRIBUTE.md (`<pp>/<id>`). */ 100 #define BUILD_PP_LEN 2u 101 102 /* Byte-exact id equality. */ 103 static inline int build_id_eq(const uint8_t a[BUILD_HASH_LEN], 104 const uint8_t b[BUILD_HASH_LEN]) { 105 size_t i; 106 for (i = 0; i < BUILD_HASH_LEN; ++i) 107 if (a[i] != b[i]) return 0; 108 return 1; 109 } 110 111 /* Compute target-key = BLAKE2b(BUILD_TARGET_KEY_DOMAIN || target-name). */ 112 int build_target_key(KitSlice target_name, uint8_t out[BUILD_HASH_LEN]); 113 /* Compute test-target-key = BLAKE2b(BUILD_TEST_TARGET_KEY_DOMAIN || target-name). 114 * Test and build records are intentionally disjoint for the same target. */ 115 int build_test_target_key(KitSlice target_name, uint8_t out[BUILD_HASH_LEN]); 116 117 /* One (path, blob-id) pair in a glob's canonical match listing. Structurally a 118 * source leaf, but defined at the foundation so the glob-result hash stays a 119 * pure, separately-testable helper — it is the SOLE producer of the value the 120 * deep/shallow traces store and match on under [glob], so coord (which expands 121 * the glob) and any future consumer agree on its bytes by construction. */ 122 typedef struct BuildPathBlob { 123 char path[BUILD_PATH_MAX]; 124 uint8_t blob[BUILD_HASH_LEN]; 125 } BuildPathBlob; 126 127 /* glob-result-hash = BLAKE2b of the canonical listing of a glob's matches: one 128 * "<path> <hex blob-id>\n" row per entry, entries pre-sorted by path and 129 * deduped by the caller. One row thus covers the existence AND content of the 130 * whole match set, so files read through a glob need no separate source rows. 131 * Pure: emits the canonical bytes through a scratch writer off `heap`, then 132 * hashes (kit_blob_info), so the result equals the BLAKE2b that would name the 133 * listing as a CAS blob. */ 134 int build_glob_result_hash(KitHeap* heap, const BuildPathBlob* entries, 135 size_t n, uint8_t out[BUILD_HASH_LEN]); 136 137 /* Emit a human-readable operational error through ctx->diag (no source 138 * location), mirroring cas_diagf. No-op when ctx/diag is NULL. */ 139 void build_diagf(const KitContext* ctx, const char* fmt, ...); 140 141 #endif