ww: finish initialization validation parity

This commit is contained in:
2026-08-14 20:03:11 +09:00
parent 25da54936d
commit c59a7c11de
26 changed files with 528 additions and 143 deletions

View File

@@ -93,17 +93,26 @@ fn samefile(a: str, b: str, why: str) void = {
"example.foo.unit.ww"));
let wantfoo: str = strings.concat("//ww:module-reset example.foo\n", afoosrc,
"\n//ww:module-reset example.foo\n", zfoosrc, "\n");
if (!testenv.same(foounit, wantfoo)
let foovoucher: str = "//ww:direct-export example.bar ";
if (!strings.hasprefix(foounit, wantfoo)
|| testenv.occurrences(foounit, "//ww:direct-export ") != 1
|| testenv.occurrences(foounit, foovoucher) != 1
|| testenv.pos(foounit, foovoucher) != wantfoo.len
|| testenv.has(foounit, "DECOY_FILE")
|| testenv.has(foounit, "//ww:module ")) {
fail("foo unit is not exactly its sorted, owned source set");
fail("foo owner prefix/direct-export voucher mismatch");
};
let wantroot: str = strings.concat("//ww:module-reset ", appidentity,
"\n", appsrc,
"\n");
if (!testenv.same(wantroot, testenv.readfile(strings.concat(cwork,
appidentity, ".unit.ww")))) {
fail("root unit is not exactly its owned source");
let rootunit: str = testenv.readfile(strings.concat(cwork,
appidentity, ".unit.ww"));
let rootvoucher: str = "//ww:direct-export example.foo ";
if (!strings.hasprefix(rootunit, wantroot)
|| testenv.occurrences(rootunit, "//ww:direct-export ") != 1
|| testenv.occurrences(rootunit, rootvoucher) != 1
|| testenv.pos(rootunit, rootvoucher) != wantroot.len) {
fail("root owner prefix/direct-export voucher mismatch");
};
let keys: []str = ["example.base", "example.bar", "example.foo",
appidentity];

View File

@@ -288,10 +288,14 @@ fn rejectstable(dir: str, label: str, target: str, needle: str) void = {
};
let expectedunit: str = strings.concat("//ww:module-reset main\n",
mainsrc, "\n");
if (!testenv.same(expectedunit, testenv.readfile(strings.concat(cwork,
"main.unit.ww"))) || !testenv.same(expectedunit,
testenv.readfile(strings.concat(wwork, "main.unit.ww")))) {
fail("self-contained", "consumer unit was not exactly its owned source");
let cunit: str = testenv.readfile(strings.concat(cwork, "main.unit.ww"));
let cunit2: str = testenv.readfile(strings.concat(cwork2, "main.unit.ww"));
let wunit: str = testenv.readfile(strings.concat(wwork, "main.unit.ww"));
if (!strings.hasprefix(cunit, expectedunit)
|| testenv.occurrences(cunit, "//ww:direct-export api ") != 1
|| testenv.pos(cunit, "//ww:direct-export api ") != expectedunit.len
|| !testenv.same(cunit, cunit2) || !testenv.same(cunit, wunit)) {
fail("self-contained", "consumer owner prefix/direct-export voucher mismatch");
};
if (!testenv.exists(strings.concat(cwork, "implementation.a"))
|| !testenv.exists(strings.concat(cwork, "dimensions.a"))) {
@@ -408,9 +412,16 @@ fn writediamond(td: str, reverse: bool) str = {
let rootbody: str = testenv.readfile(strings.concat(main, "/main.ww"));
let wantroot: str = strings.concat("//ww:module-reset main\n", rootbody,
"\n");
if (!testenv.same(unit, wantroot) || testenv.has(unit,
"//ww:module ")) {
fail("diamond", "root unit contains non-owned export text");
let leftvoucher: str = "//ww:direct-export left ";
let rightvoucher: str = "//ww:direct-export right ";
if (!strings.hasprefix(unit, wantroot) || testenv.has(unit,
"//ww:module ")
|| testenv.occurrences(unit, "//ww:direct-export ") != 2
|| testenv.occurrences(unit, leftvoucher) != 1
|| testenv.occurrences(unit, rightvoucher) != 1
|| testenv.pos(unit, leftvoucher) != wantroot.len
|| testenv.pos(unit, leftvoucher) >= testenv.pos(unit, rightvoucher)) {
fail("diamond", "root owner prefix/sorted direct-export vouchers changed");
};
let sharedunit: str = testenv.readfile(strings.concat(scratch,
"shared.unit.ww"));
@@ -534,6 +545,9 @@ fn writediamond(td: str, reverse: bool) str = {
let referencearchive: str = "";
let referencerootwwi: str = "";
let referencerootarchive: str = "";
let referenceinitunit: str = "";
let referenceinitasm: str = "";
let referenceinitobj: str = "";
let referencebin: str = "";
let referencecompiler: str = "";
let referenceassembler: str = "";
@@ -583,9 +597,21 @@ fn writediamond(td: str, reverse: bool) str = {
|| !testenv.exists(strings.concat(work, "dep.a"))
|| !testenv.exists(strings.concat(work, "main.o"))
|| !testenv.exists(strings.concat(work, "main.wwi"))
|| !testenv.exists(strings.concat(work, "main.a"))) {
|| !testenv.exists(strings.concat(work, "main.a"))
|| !testenv.exists(strings.concat(work, "main.init.unit.ww"))
|| !testenv.exists(strings.concat(work, "main.init.s"))
|| !testenv.exists(strings.concat(work, "main.init.o"))) {
fail("library-roots", "package artifacts do not match root ownership");
};
let initunit: str = testenv.readfile(strings.concat(work,
"main.init.unit.ww"));
if (!testenv.same(initunit, strings.concat(
"//ww:init-root __ww..pkg.p.main.v0.r0.init\n",
"//ww:init-call __ww..pkg.p.leaf.v0.r0.init\n",
"//ww:init-call __ww..pkg.p.dep.v0.r0.init\n",
"//ww:init-call __ww..pkg.p.main.v0.r0.init\n"))) {
fail("library-roots", "root dispatcher unit order changed");
};
let ctrace: str = testenv.readfile(compilertrace);
let atrace: str = testenv.readfile(assemblertrace);
let ltrace: str = testenv.readfile(linkertrace);
@@ -604,20 +630,29 @@ fn writediamond(td: str, reverse: bool) str = {
fail("library-roots", "compiler actions were not deterministic postorder");
};
if (!testenv.has(ctrace, strings.concat(
"BEGIN<-c><--import><leaf><", work, "leaf.wwi><-I><", work,
"BEGIN<--package-init-symbol><__ww..pkg.p.leaf.v0.r0.init>",
"<-c><-I><", work, "leaf.wwi><-o><", work,
"leaf.s><", work, "leaf.unit.ww>"))
|| !testenv.has(ctrace, strings.concat(
"BEGIN<--package-init-symbol><__ww..pkg.p.dep.v0.r0.init>",
"<-c><--import><leaf><", work, "leaf.wwi><-I><", work,
"dep.wwi><-o><", work,
"dep.s><", work, "dep.unit.ww>"))
|| !testenv.has(ctrace, strings.concat(
"BEGIN<--entry><-c><--import><dep><", work,
"BEGIN<--entry><--package-init-symbol>",
"<__ww..pkg.p.main.v0.r0.init><--init-dispatch-symbol>",
"<__ww..dispatch><-c><--import><dep><", work,
"dep.wwi><-I><", work, "main.wwi><-o><", work,
"main.s><", work, "main.unit.ww>"))
|| testenv.occurrences(atrace, "\n") != 3
|| testenv.occurrences(atrace, "\n") != 4
|| !testenv.has(atrace, strings.concat("BEGIN<-o><", work,
"dep.o><", work, "dep.s>"))) {
"dep.o><", work, "dep.s>"))
|| !testenv.has(atrace, strings.concat("BEGIN<-o><", work,
"main.init.o><", work, "main.init.s>"))) {
fail("library-roots", "compiler or assembler argv changed");
};
if (testenv.occurrences(ltrace, "\n") != 1
|| !testenv.has(ltrace, strings.concat("BEGIN<-o><", bin, "><",
|| !testenv.has(ltrace, strings.concat("BEGIN<-o><", bin, ".new><",
work, "main.a>"))
|| testenv.pos(ltrace, strings.concat("<", work, "dep.a>")) < 0
|| testenv.pos(ltrace, strings.concat("<", work, "leaf.a>"))
@@ -655,6 +690,11 @@ fn writediamond(td: str, reverse: bool) str = {
"main.wwi")));
referencerootarchive = strings.dup(testenv.readfile(strings.concat(work,
"main.a")));
referenceinitunit = strings.dup(initunit);
referenceinitasm = strings.dup(testenv.readfile(strings.concat(work,
"main.init.s")));
referenceinitobj = strings.dup(testenv.readfile(strings.concat(work,
"main.init.o")));
referencebin = strings.dup(testenv.readfile(bin));
referencecompiler = strings.dup(ctrace);
referenceassembler = strings.dup(atrace);
@@ -669,6 +709,11 @@ fn writediamond(td: str, reverse: bool) str = {
testenv.readfile(strings.concat(work, "main.wwi")))
|| !testenv.same(referencerootarchive,
testenv.readfile(strings.concat(work, "main.a")))
|| !testenv.same(referenceinitunit, initunit)
|| !testenv.same(referenceinitasm,
testenv.readfile(strings.concat(work, "main.init.s")))
|| !testenv.same(referenceinitobj,
testenv.readfile(strings.concat(work, "main.init.o")))
|| !testenv.same(referencebin, testenv.readfile(bin))
|| !testenv.same(referencecompiler, ctrace)
|| !testenv.same(referenceassembler, atrace)
@@ -747,7 +792,7 @@ fn writediamond(td: str, reverse: bool) str = {
|| !testenv.exists(strings.concat(emptywork, "types.a"))
|| testenv.occurrences(ctrace, strings.concat("<", emptywork,
"types.unit.ww>")) != 1
|| testenv.occurrences(atrace, "\n") != 2) {
|| testenv.occurrences(atrace, "\n") != 3) {
fail("library-roots", "empty WW_SRCLIB did not use the default source root");
};
if (testenv.occurrences(ltrace, "\n") != 1
@@ -900,6 +945,9 @@ fn writediamond(td: str, reverse: bool) str = {
|| !testenv.exists(strings.concat(work, "/dep.a"))
|| !testenv.exists(strings.concat(work, "/main.wwi"))
|| !testenv.exists(strings.concat(work, "/main.a"))
|| !testenv.exists(strings.concat(work, "/main.init.unit.ww"))
|| !testenv.exists(strings.concat(work, "/main.init.s"))
|| !testenv.exists(strings.concat(work, "/main.init.o"))
|| !testenv.same(testenv.readfile(strings.concat(work,
"/.wwtool.ww")), testenv.readfile(copied[si]))
|| !testenv.same(testenv.readfile(strings.concat(work,
@@ -908,7 +956,7 @@ fn writediamond(td: str, reverse: bool) str = {
"/.wwtool.w6a")), testenv.readfile(assembler))
|| !testenv.same(testenv.readfile(strings.concat(work,
"/.wwtool.stamp")),
"ww workdir fmt 15 mode build asm 0\n")) {
"ww workdir fmt 17 mode build asm 0\n")) {
fail("driver-identity", "persistent artifacts or identities are incomplete");
};
let coldwwi: str = testenv.readfile(strings.concat(work, "/dep.wwi"));
@@ -919,28 +967,38 @@ fn writediamond(td: str, reverse: bool) str = {
let coldlinker: str = testenv.readfile(linkertrace);
if (testenv.occurrences(coldcompiler, "\n") != 3
|| !testenv.has(coldcompiler, strings.concat(
"BEGIN<-c><--import><leaf><", work, "/leaf.wwi><-I><", work,
"BEGIN<--package-init-symbol><__ww..pkg.p.leaf.v0.r0.init>",
"<-c><-I><", work, "/leaf.wwi.new><-o><", work,
"/leaf.s.new><", work, "/leaf.unit.new>"))
|| !testenv.has(coldcompiler, strings.concat(
"BEGIN<--package-init-symbol><__ww..pkg.p.dep.v0.r0.init>",
"<-c><--import><leaf><", work, "/leaf.wwi.new><-I><", work,
"/dep.wwi.new><-o><", work,
"/dep.s.new><", work, "/dep.unit.new>"))
|| !testenv.has(coldcompiler, strings.concat(
"BEGIN<--entry><-c><--import><dep><", work,
"/dep.wwi><-I><", work, "/main.wwi.new><-o><", work,
"BEGIN<--entry><--package-init-symbol>",
"<__ww..pkg.p.main.v0.r0.init><--init-dispatch-symbol>",
"<__ww..dispatch><-c><--import><dep><", work,
"/dep.wwi.new><-I><", work, "/main.wwi.new><-o><", work,
"/main.s.new><", work,
"/main.unit.new>"))
|| testenv.occurrences(coldassembler, "\n") != 3
|| testenv.occurrences(coldassembler, "\n") != 4
|| !testenv.has(coldassembler, strings.concat(
"BEGIN<-o><", work, "/dep.o.new><", work,
"/dep.s.new>"))) {
"/dep.s.new>"))
|| !testenv.has(coldassembler, strings.concat(
"BEGIN<-o><", work, "/main.init.o.new><", work,
"/main.init.s.new>"))) {
fail("driver-identity", "cold compiler or assembler argv changed");
};
if (testenv.occurrences(coldlinker, "\n") != 1
|| !testenv.has(coldlinker, strings.concat("BEGIN<-o><", bin,
"><", work, "/main.a>"))
".new><", work, "/main.a.new>"))
|| testenv.pos(coldlinker, strings.concat("<", work,
"/dep.a>")) < 0
"/dep.a.new>")) < 0
|| testenv.pos(coldlinker, strings.concat("<", work,
"/leaf.a>")) < testenv.pos(coldlinker, strings.concat("<",
work, "/dep.a>"))
"/leaf.a.new>")) < testenv.pos(coldlinker, strings.concat("<",
work, "/dep.a.new>"))
|| !testenv.has(coldlinker, strings.concat("<", runtime,
"/libwwrt.a>"))
|| testenv.has(coldlinker, ".wwi>")) {
@@ -970,7 +1028,7 @@ fn writediamond(td: str, reverse: bool) str = {
|| testenv.occurrences(changedexportcompiler, strings.concat("<", work,
"/main.unit.new>")) != 1
|| testenv.occurrences(changedexportcompiler, "\n") != 5
|| testenv.occurrences(changedexportassembler, "\n") != 5) {
|| testenv.occurrences(changedexportassembler, "\n") != 6) {
fail("driver-identity", "changed export did not stop at an unchanged importer export");
};
if (code(cwd, strings.concat("driver-export-change-run-", tags[si]),
@@ -1004,7 +1062,7 @@ fn writediamond(td: str, reverse: bool) str = {
|| testenv.occurrences(testenv.readfile(compilertrace), strings.concat(
"<", work, "/main.unit.new>")) != 1
|| testenv.occurrences(testenv.readfile(compilertrace), "\n") != 7
|| testenv.occurrences(testenv.readfile(assemblertrace), "\n") != 7
|| testenv.occurrences(testenv.readfile(assemblertrace), "\n") != 8
|| !testenv.same(coldbin, testenv.readfile(bin))) {
fail("driver-identity", "restored export did not rebuild only its direct importer");
};
@@ -1029,7 +1087,7 @@ fn writediamond(td: str, reverse: bool) str = {
|| testenv.occurrences(changedcompiler, strings.concat("<", work,
"/main.unit.new>")) != 2
|| testenv.occurrences(changedcompiler, "\n") != 10
|| testenv.occurrences(changedassembler, "\n") != 10
|| testenv.occurrences(changedassembler, "\n") != 12
|| testenv.occurrences(changedlinker, "\n") != 5) {
fail("driver-identity", "driver change reused stale package actions");
};
@@ -1339,9 +1397,11 @@ fn writediamond(td: str, reverse: bool) str = {
let linkers: []str = ["w6l", "w6l_ww"];
let tags: []str = ["c", "ww"];
let suffixes: []str = [".unit.ww", ".wwi", ".s", ".o", ".a"];
let initsuffixes: []str = [".init.unit.ww", ".init.s", ".init.o"];
let rootreference: []str = ["", "", "", "", ""];
let depreference: []str = ["", "", "", "", ""];
let commandreference: []str = ["", "", "", "", ""];
let commandinitreference: []str = ["", "", ""];
let nooutrootreference: []str = ["", "", "", "", ""];
let nooutdepreference: []str = ["", "", "", "", ""];
let publishreference: str = "";
@@ -1382,11 +1442,14 @@ fn writediamond(td: str, reverse: bool) str = {
let ctrace: str = testenv.readfile(compilertrace);
let atrace: str = testenv.readfile(assemblertrace);
let wantcompiler: str = strings.concat(
"BEGIN<-c><-I><", work,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.dep.v0.r0.init><-c><-I><", work,
"/foo.dep.wwi.new><-o><", work,
"/foo.dep.s.new><", work, "/foo.dep.unit.new>\n",
"BEGIN<-c><--import><foo.dep><", work,
"/foo.dep.wwi><-I><", work,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.bar.v0.r0.init><-c>",
"<--import><foo.dep><", work,
"/foo.dep.wwi.new><-I><", work,
"/foo.bar.wwi.new><-o><", work,
"/foo.bar.s.new><", work, "/foo.bar.unit.new>\n");
let wantassembler: str = strings.concat(
@@ -1461,15 +1524,20 @@ fn writediamond(td: str, reverse: bool) str = {
atrace = testenv.readfile(assemblertrace);
let commandlink: str = testenv.readfile(linkertrace);
let wantcommandcompiler: str = strings.concat(
"BEGIN<-c><-I><", commandwork,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.dep.v0.r0.init><-c><-I><", commandwork,
"/foo.dep.wwi.new><-o><", commandwork,
"/foo.dep.s.new><", commandwork, "/foo.dep.unit.new>\n",
"BEGIN<-c><--import><foo.dep><", commandwork,
"/foo.dep.wwi><-I><", commandwork,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.bar.v0.r0.init><-c>",
"<--import><foo.dep><", commandwork,
"/foo.dep.wwi.new><-I><", commandwork,
"/foo.bar.wwi.new><-o><", commandwork,
"/foo.bar.s.new><", commandwork, "/foo.bar.unit.new>\n",
"BEGIN<--entry><-c><--import><foo.bar><", commandwork,
"/foo.bar.wwi><-I><", commandwork,
"BEGIN<--entry><--package-init-symbol>",
"<__ww..pkg.p.foo.cmd.v0.r0.init><--init-dispatch-symbol>",
"<__ww..dispatch><-c><--import><foo.bar><", commandwork,
"/foo.bar.wwi.new><-I><", commandwork,
"/foo.cmd.wwi.new><-o><", commandwork,
"/foo.cmd.s.new><", commandwork, "/foo.cmd.unit.new>\n");
let wantcommandassembler: str = strings.concat(
@@ -1478,10 +1546,12 @@ fn writediamond(td: str, reverse: bool) str = {
"BEGIN<-o><", commandwork, "/foo.bar.o.new><", commandwork,
"/foo.bar.s.new>\n",
"BEGIN<-o><", commandwork, "/foo.cmd.o.new><", commandwork,
"/foo.cmd.s.new>\n");
"/foo.cmd.s.new>\n",
"BEGIN<-o><", commandwork, "/foo.cmd.init.o.new><", commandwork,
"/foo.cmd.init.s.new>\n");
let wantcommandlink: str = strings.concat("BEGIN<-o><", commandbin,
"><", commandwork, "/foo.cmd.a><", commandwork,
"/foo.bar.a><", commandwork, "/foo.dep.a><", runtime,
".new><", commandwork, "/foo.cmd.a.new><", commandwork,
"/foo.bar.a.new><", commandwork, "/foo.dep.a.new><", runtime,
"/libwwrt.a>\n");
if (out.termination != exec.termination.EXIT || out.code != 0
|| out.stderr.len != 0
@@ -1510,6 +1580,18 @@ fn writediamond(td: str, reverse: bool) str = {
}; };
ai += 1;
};
ai = 0;
for (ai < initsuffixes.len) {
let initbytes: str = testenv.readfile(strings.concat(commandwork,
"/foo.cmd", initsuffixes[ai]));
if (si == 0) {
commandinitreference[ai] = strings.dup(initbytes);
} else { if (!testenv.same(commandinitreference[ai], initbytes)) {
fail("package-autoaction",
"Cstage and WWstage dispatcher artifacts differ");
}; };
ai += 1;
};
let commandrun: []str = [commandbin];
if (code(td, strings.concat("auto-command-run-", tags[si]),
commandrun) != 42) {
@@ -1544,11 +1626,14 @@ fn writediamond(td: str, reverse: bool) str = {
ctrace = testenv.readfile(compilertrace);
atrace = testenv.readfile(assemblertrace);
let wantnooutcompiler: str = strings.concat(
"BEGIN<-c><-I><", nooutwork,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.dep.v0.r0.init><-c><-I><", nooutwork,
"/foo.dep.wwi.new><-o><", nooutwork,
"/foo.dep.s.new><", nooutwork, "/foo.dep.unit.new>\n",
"BEGIN<-c><--import><foo.dep><", nooutwork,
"/foo.dep.wwi><-I><", nooutwork,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.bar.v0.r0.init><-c>",
"<--import><foo.dep><", nooutwork,
"/foo.dep.wwi.new><-I><", nooutwork,
"/foo.bar.wwi.new><-o><", nooutwork,
"/foo.bar.s.new><", nooutwork, "/foo.bar.unit.new>\n");
let wantnooutassembler: str = strings.concat(
@@ -1660,11 +1745,14 @@ fn writediamond(td: str, reverse: bool) str = {
testenv.runcommandenv(td, td, strings.concat("auto-asm-long-output-",
tags[si]), asmav, env, tmo(), &out);
let wantasmcompiler: str = strings.concat(
"BEGIN<-c><-I><", asmwork,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.dep.v0.r0.init><-c><-I><", asmwork,
"/foo.dep.wwi.new><-o><", asmwork,
"/foo.dep.s.new><", asmwork, "/foo.dep.unit.new>\n",
"BEGIN<-c><--import><foo.dep><", asmwork,
"/foo.dep.wwi><-I><", asmwork,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.bar.v0.r0.init><-c>",
"<--import><foo.dep><", asmwork,
"/foo.dep.wwi.new><-I><", asmwork,
"/foo.bar.wwi.new><-o><", asmwork,
"/foo.bar.s.new><", asmwork, "/foo.bar.unit.new>\n");
if (out.termination != exec.termination.EXIT || out.code != 0
@@ -1752,7 +1840,8 @@ fn writediamond(td: str, reverse: bool) str = {
ctrace = testenv.readfile(compilertrace);
atrace = testenv.readfile(assemblertrace);
let wantprivatecompiler: str = strings.concat(
"BEGIN<-c><-I><", work,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.dep.v0.r0.init><-c><-I><", work,
"/foo.dep.wwi.new><-o><", work,
"/foo.dep.s.new><", work, "/foo.dep.unit.new>\n");
let wantprivateassembler: str = strings.concat(
@@ -1778,11 +1867,14 @@ fn writediamond(td: str, reverse: bool) str = {
ctrace = testenv.readfile(compilertrace);
atrace = testenv.readfile(assemblertrace);
let wantexportcompiler: str = strings.concat(
"BEGIN<-c><-I><", work,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.dep.v0.r0.init><-c><-I><", work,
"/foo.dep.wwi.new><-o><", work,
"/foo.dep.s.new><", work, "/foo.dep.unit.new>\n",
"BEGIN<-c><--import><foo.dep><", work,
"/foo.dep.wwi><-I><", work,
"BEGIN<--package-init-symbol>",
"<__ww..pkg.p.foo.bar.v0.r0.init><-c>",
"<--import><foo.dep><", work,
"/foo.dep.wwi.new><-I><", work,
"/foo.bar.wwi.new><-o><", work,
"/foo.bar.s.new><", work, "/foo.bar.unit.new>\n");
let wantexportassembler: str = strings.concat(

View File

@@ -101,7 +101,8 @@ fn samefile(label: str, what: str, a: str, b: str) void = {
i += 1;
};
// cs==ww (rule 10): per-package artifacts + the final binary
// cs==ww (rule 10): per-source-action artifacts + the final binary;
// sepinit owns the command root's additional dispatcher artifacts.
let sufs: []str = [".s", ".wwi", ".a", ".unit.ww"];
let p: i32 = 0;
for (p < pkgs.len) {
@@ -164,7 +165,8 @@ fn samefile(label: str, what: str, a: str, b: str) void = {
s += 1;
};
// cs==ww for the complete package artifacts, including the root archive.
// cs==ww for every source-action artifact, including the root archive;
// sepinit owns the command root's additional dispatcher artifacts.
let pkgs: []str = ["c", "__root"];
let sufs: []str = [".s", ".wwi", ".a", ".unit.ww"];
let p: i32 = 0;

View File

@@ -209,11 +209,12 @@ fn depmainrow(label: str, entry: str, want: i32, deps: str,
l += 1;
};
// Both the dependency and raw explicit root emit complete package artifacts.
// Both the dependency and raw explicit root emit complete source-action
// artifacts; sepinit owns command-dispatcher artifact parity.
let parts: []str = ["aa.s", "aa.wwi", "aa.a", "aa.unit.ww",
"__root.s", "__root.wwi", "__root.a", "__root.unit.ww"];
// cs==ww (rule 10) per layout over the complete package-artifact table
// cs==ww (rule 10) per layout over the source-action artifact table
let l2: i32 = 0;
for (l2 < 2) {
let p: i32 = 0;

View File

@@ -4,8 +4,9 @@ package seplink_test;
// retired native carriers test/wcc/989_separchive_run.c and
// 989_sepcycle_dup.c; every assertion preserved.
//
// archive — `ww build` wraps every package action's .o in the existing
// deterministic single-member .a and links the root archive first:
// archive — `ww build` wraps every library package action's .o in the existing
// deterministic single-member .a; the command root also owns its fixed
// dispatcher member, and the linker receives that root archive first:
// build+run exit 7 both stages; __root.a + helper.a present; both archives
// are byte-identical across stages; 3 cold cstage rebuilds emit
// byte-identical archives (zeroed mtime/uid/gid, fixed mode/member —