cmd: bind package workdirs to driver identity

This commit is contained in:
2026-08-12 15:51:44 +09:00
parent 5c19f51a4d
commit 5eec5d3711
2 changed files with 46 additions and 13 deletions

View File

@@ -32,6 +32,7 @@ static const char *usage =
" . build the cwd's <basename>.ww\n";
static char *self_dir;
static const char *self_path;
static const char *
envpath(const char *name)
@@ -1533,8 +1534,8 @@ archive_o(const char *objpath, const char *apath)
* package-artifact tree that replaces the fresh `.sepwork` scratch.
* Staleness is pure content
* identity, never mtime: a package is reused only when its freshly
* composed unit byte-equals the committed unit AND the tool copies
* recorded in the dir byte-equal the live tools — every decision is
* composed unit byte-equals the committed unit AND the driver/tool copies
* recorded in the dir byte-equal the live executables — every decision is
* reproducible by hand with cmp(1) against plain files. Artifacts commit
* via temp + rename with the unit renamed last, so a killed build can
* never leave a committed unit vouching for uncommitted artifacts. The
@@ -1629,10 +1630,10 @@ static void
workdir_stamp_text(char *buf, size_t bufsz, int is_test, int emit_asm)
{
snprintf(buf, bufsz, "ww workdir fmt %d mode %s asm %d\n",
is_test ? 5 : 4, is_test ? "test" : "build", emit_asm);
is_test ? 6 : 5, is_test ? "test" : "build", emit_asm);
}
/* A stale global tool identity invalidates every committed unit voucher in
/* A stale global builder identity invalidates every committed unit voucher in
* this driver-owned workdir before compilation starts. Artifacts may remain,
* but without their unit they cannot be reused. That makes it safe to record
* the new identity after a partial multi-root pass: successful actions have
@@ -1753,9 +1754,16 @@ build_one_sep_impl(const char *src, int entry_is_dir,
if (scratchout) snprintf(scratchout, scratchoutsz, "%s", scratch);
}
int stale_all = 0, stampok = 0;
char toolc[1200] = {0}, toola[1200] = {0}, stampf[1200] = {0};
char toolw[1200] = {0}, toolc[1200] = {0}, toola[1200] = {0};
char stampf[1200] = {0};
char stampwant[128];
if (warm) {
if (self_path == NULL || !file_is_reg(self_path)) {
fprintf(stderr, "ww: cannot read driver identity %s\n",
self_path ? self_path : "(unknown)");
return 1;
}
snprintf(toolw, sizeof toolw, "%s/.wwtool.ww", scratch);
snprintf(toolc, sizeof toolc, "%s/.wwtool.w6c", scratch);
snprintf(toola, sizeof toola, "%s/.wwtool.w6a", scratch);
snprintf(stampf, sizeof stampf, "%s/.wwtool.stamp", scratch);
@@ -1768,7 +1776,8 @@ build_one_sep_impl(const char *src, int entry_is_dir,
fclose(sf);
}
stampok = strcmp(stampwant, got) == 0;
if (!stampok || !file_equal(toolc, c6)
if (!stampok || !file_equal(toolw, self_path)
|| !file_equal(toolc, c6)
|| (!emit_asm && !file_equal(toola, a6)))
stale_all = 1;
if (stale_all && invalidate_workdir_units(scratch) != 0)
@@ -2069,6 +2078,11 @@ build_one_sep_impl(const char *src, int entry_is_dir,
* root failed; a killed pass leaves the old identity and forces another
* invalidating pass, never false reuse. */
if (warm) {
if (!file_equal(toolw, self_path)
&& copy_file_atomic(self_path, toolw) != 0) {
fprintf(stderr, "ww: cannot record %s\n", toolw);
free(order); return 1;
}
if (!file_equal(toolc, c6)
&& copy_file_atomic(c6, toolc) != 0) {
fprintf(stderr, "ww: cannot record %s\n", toolc);
@@ -2973,6 +2987,7 @@ int
main(int argc, char **argv)
{
if (argc >= 1) {
self_path = argv[0];
char buf[1024];
snprintf(buf, sizeof buf, "%s", argv[0]);
self_dir = strdup(dirname(buf));