build: make executable and test roots package actions
This commit is contained in:
@@ -14,9 +14,9 @@ package packedwwi_test;
|
||||
// type.ha:122-126). Both driver stages must build the -I tree and run
|
||||
// exit 91 (9*10+1; a dropped @packed gives 168). Strengthened over
|
||||
// the carrier: the re-emitted `struct @packed {` is also asserted in
|
||||
// the retained sepwork pk2.wwi. A single-file two-package form
|
||||
// produces NO .wwi (one __root unit), so the real -I tree is
|
||||
// irreducible here.
|
||||
// the retained sepwork pk2.wwi. A single-file two-package form produces
|
||||
// only one raw `__root.wwi`, not an independently importable pk2 package,
|
||||
// so the real directory-package -I tree is irreducible here.
|
||||
//
|
||||
// identityreject: assigning packed A to a structurally-identical
|
||||
// unpacked B — packed is type identity (harec types.c:621). STAGE-
|
||||
|
||||
@@ -786,6 +786,11 @@ fn workescape(s: str) str = {
|
||||
let referencesameunit: str = "";
|
||||
let referenceexternalunit: str = "";
|
||||
let referenceproductionunit: str = "";
|
||||
let packageactions: []str = ["__ww-test-000-same",
|
||||
"__ww-test-000-main", "__ww-test-001-external",
|
||||
"__ww-test-001-main"];
|
||||
let referenceactionexports: []str = ["", "", "", ""];
|
||||
let referenceactionarchives: []str = ["", "", "", ""];
|
||||
let i: i32 = 0;
|
||||
for (i < drivers.len) {
|
||||
let av: []str = [driver(drivers[i]), "test", "-c", "-I", root,
|
||||
@@ -807,6 +812,10 @@ fn workescape(s: str) str = {
|
||||
"__ww-test-001-external.unit.ww"));
|
||||
let externalproduction: str = readfile(strings.concat(sharedwork,
|
||||
"__ww-test-001-external-production.unit.ww"));
|
||||
let samemainunit: str = readfile(strings.concat(sharedwork,
|
||||
"__ww-test-000-main.unit.ww"));
|
||||
let externalmainunit: str = readfile(strings.concat(sharedwork,
|
||||
"__ww-test-001-main.unit.ww"));
|
||||
assert(!os.exists(strings.concat(externalbin, ".sepwork")));
|
||||
assert(!has(sameunit, "//ww:module "));
|
||||
assert(os.exists(strings.concat(sharedwork,
|
||||
@@ -824,28 +833,43 @@ fn workescape(s: str) str = {
|
||||
assert(!has(externalproduction, "//ww:module "));
|
||||
assert(!has(externalproduction, "SAME_TEST_SOURCE"));
|
||||
assert(!has(externalproduction, "EXTERNAL_TEST_SOURCE"));
|
||||
assert(same(samemainunit, strings.concat(
|
||||
"//ww:module-reset __wwtestmain.000.main\n",
|
||||
"package main;\nimport pkg;\nimport test;\n")));
|
||||
assert(same(externalmainunit, strings.concat(
|
||||
"//ww:module-reset __wwtestmain.001.main\n",
|
||||
"package main;\nimport pkg_test;\nimport test;\n")));
|
||||
assert(!has(samemainunit, "PACKAGE_PRODUCTION"));
|
||||
assert(!has(samemainunit, "SAME_TEST_SOURCE"));
|
||||
assert(!has(externalmainunit, "EXTERNAL_TEST_SOURCE"));
|
||||
assert(!has(readfile(strings.concat(sharedwork, "api.unit.ww")),
|
||||
"TEST_DEPENDENCY_MUST_NOT_COMPILE"));
|
||||
let artifacts: []str = ["implementation", "api",
|
||||
"__ww-test-001-external-production",
|
||||
"__same", "__external", "test"];
|
||||
"__same", "__external", "test", "__ww-test-000-same",
|
||||
"__ww-test-000-main", "__ww-test-001-external",
|
||||
"__ww-test-001-main"];
|
||||
let ai: i32 = 0;
|
||||
for (ai < artifacts.len) {
|
||||
assert(os.exists(strings.concat(sharedwork, artifacts[ai], ".wwi")));
|
||||
assert(os.exists(strings.concat(sharedwork, artifacts[ai], ".a")));
|
||||
ai += 1;
|
||||
};
|
||||
assert(os.exists(strings.concat(sharedwork, "__ww-test-000-same.o")));
|
||||
assert(os.exists(strings.concat(sharedwork,
|
||||
"__ww-test-001-external.o")));
|
||||
assert(!os.exists(strings.concat(sharedwork,
|
||||
"__ww-test-000-same.wwi")));
|
||||
assert(!os.exists(strings.concat(sharedwork,
|
||||
"__ww-test-001-external.wwi")));
|
||||
assert(!os.exists(strings.concat(sharedwork,
|
||||
"__ww-test-000-same.a")));
|
||||
assert(!os.exists(strings.concat(sharedwork,
|
||||
"__ww-test-001-external.a")));
|
||||
ai = 0;
|
||||
for (ai < packageactions.len) {
|
||||
let ex: str = readfile(strings.concat(sharedwork,
|
||||
packageactions[ai], ".wwi"));
|
||||
let ar: str = readfile(strings.concat(sharedwork,
|
||||
packageactions[ai], ".a"));
|
||||
if (i == 0) {
|
||||
referenceactionexports[ai] = strings.dup(ex);
|
||||
referenceactionarchives[ai] = strings.dup(ar);
|
||||
} else {
|
||||
assert(same(referenceactionexports[ai], ex));
|
||||
assert(same(referenceactionarchives[ai], ar));
|
||||
};
|
||||
ai += 1;
|
||||
};
|
||||
assert(os.exists(samebin));
|
||||
assert(os.exists(externalbin));
|
||||
if (i == 0) {
|
||||
@@ -862,7 +886,11 @@ fn workescape(s: str) str = {
|
||||
assert(occurrences(ctrace,
|
||||
"__ww-test-001-external.unit.ww") == 1);
|
||||
assert(occurrences(ctrace,
|
||||
"-T --test-support-module") == 2);
|
||||
"__ww-test-000-main.unit.ww") == 1);
|
||||
assert(occurrences(ctrace,
|
||||
"__ww-test-001-main.unit.ww") == 1);
|
||||
assert(occurrences(ctrace, "-T --entry --test-support-module") == 2);
|
||||
assert(occurrences(ctrace, "--test-package") == 2);
|
||||
let samecompile: str = linecontaining(ctrace,
|
||||
"__ww-test-000-same.unit.ww");
|
||||
let externalcompile: str = linecontaining(ctrace,
|
||||
@@ -870,18 +898,36 @@ fn workescape(s: str) str = {
|
||||
let productioncompile: str = linecontaining(ctrace,
|
||||
"__ww-test-001-external-production.unit.ww");
|
||||
assert(same(samecompile, strings.concat(
|
||||
"-T --test-support-module test -c --import __same ",
|
||||
"--test-package -c --import __same ",
|
||||
sharedwork, "__same.wwi --import api ", sharedwork,
|
||||
"api.wwi --import test ", sharedwork, "test.wwi -o ",
|
||||
"api.wwi -I ", sharedwork, "__ww-test-000-same.wwi -o ",
|
||||
sharedwork, "__ww-test-000-same.s ", sharedwork,
|
||||
"__ww-test-000-same.unit.ww")));
|
||||
assert(same(externalcompile, strings.concat(
|
||||
"-T --test-support-module test -c --import __external ",
|
||||
"--test-package -c --import __external ",
|
||||
sharedwork, "__external.wwi --import pkg ", sharedwork,
|
||||
"__ww-test-001-external-production.wwi --import test ",
|
||||
sharedwork, "test.wwi -o ", sharedwork,
|
||||
"__ww-test-001-external-production.wwi -I ", sharedwork,
|
||||
"__ww-test-001-external.wwi -o ", sharedwork,
|
||||
"__ww-test-001-external.s ", sharedwork,
|
||||
"__ww-test-001-external.unit.ww")));
|
||||
let samemaincompile: str = linecontaining(ctrace,
|
||||
"__ww-test-000-main.unit.ww");
|
||||
let externalmaincompile: str = linecontaining(ctrace,
|
||||
"__ww-test-001-main.unit.ww");
|
||||
assert(same(samemaincompile, strings.concat(
|
||||
"-T --entry --test-support-module test -c --import pkg ",
|
||||
sharedwork, "__ww-test-000-same.wwi --import test ",
|
||||
sharedwork, "test.wwi -I ", sharedwork,
|
||||
"__ww-test-000-main.wwi -o ", sharedwork,
|
||||
"__ww-test-000-main.s ", sharedwork,
|
||||
"__ww-test-000-main.unit.ww")));
|
||||
assert(same(externalmaincompile, strings.concat(
|
||||
"-T --entry --test-support-module test -c --import pkg_test ",
|
||||
sharedwork, "__ww-test-001-external.wwi --import test ",
|
||||
sharedwork, "test.wwi -I ", sharedwork,
|
||||
"__ww-test-001-main.wwi -o ", sharedwork,
|
||||
"__ww-test-001-main.s ", sharedwork,
|
||||
"__ww-test-001-main.unit.ww")));
|
||||
assert(same(productioncompile, strings.concat(
|
||||
"-c --import api ", sharedwork, "api.wwi -I ", sharedwork,
|
||||
"__ww-test-001-external-production.wwi -o ", sharedwork,
|
||||
@@ -897,12 +943,22 @@ fn workescape(s: str) str = {
|
||||
assert(has(samelink,
|
||||
strings.concat(sharedwork, "implementation.a")));
|
||||
assert(has(samelink, strings.concat(sharedwork, "__same.a")));
|
||||
assert(has(samelink, strings.concat(sharedwork,
|
||||
"__ww-test-000-main.a")));
|
||||
assert(has(samelink, strings.concat(sharedwork,
|
||||
"__ww-test-000-same.a")));
|
||||
assert(!has(samelink, strings.concat(sharedwork,
|
||||
"__ww-test-001-external-production.a")));
|
||||
assert(!has(samelink,
|
||||
strings.concat(sharedwork, "__external.a")));
|
||||
assert(has(externallink, strings.concat(sharedwork,
|
||||
"__ww-test-001-external-production.a")));
|
||||
assert(has(externallink, strings.concat(sharedwork,
|
||||
"__ww-test-001-main.a")));
|
||||
assert(has(externallink, strings.concat(sharedwork,
|
||||
"__ww-test-001-external.a")));
|
||||
assert(!has(samelink, ".wwi"));
|
||||
assert(!has(externallink, ".wwi"));
|
||||
assert(has(externallink, strings.concat(sharedwork, "api.a")));
|
||||
assert(has(externallink,
|
||||
strings.concat(sharedwork, "implementation.a")));
|
||||
@@ -1176,6 +1232,8 @@ fn workescape(s: str) str = {
|
||||
let rootkeys: []str = ["__ww-test-000-same",
|
||||
"__ww-test-001-external", "__ww-test-002-same",
|
||||
"__ww-test-003-external"];
|
||||
let mainkeys: []str = ["__ww-test-000-main", "__ww-test-001-main",
|
||||
"__ww-test-002-main", "__ww-test-003-main"];
|
||||
let alphaartifact: str = "__ww-test-001-external-production";
|
||||
let betaartifact: str = "__ww-test-003-external-production";
|
||||
let expectedtests: []str = ["alpha_same_runs ... ok\n",
|
||||
@@ -1248,7 +1306,11 @@ fn workescape(s: str) str = {
|
||||
assert(!has(roots[3], "MULTIDIR_BETA_SAME"));
|
||||
let products: []str = ["leaf", "common", alphaartifact, betaartifact,
|
||||
"_alpha_same", "_alpha_external", "_beta_same",
|
||||
"_beta_external", "test"];
|
||||
"_beta_external", "test", "__ww-test-000-same",
|
||||
"__ww-test-001-external", "__ww-test-002-same",
|
||||
"__ww-test-003-external", "__ww-test-000-main",
|
||||
"__ww-test-001-main", "__ww-test-002-main",
|
||||
"__ww-test-003-main"];
|
||||
let pi: i32 = 0;
|
||||
for (pi < products.len) {
|
||||
assert(os.exists(strings.concat(sharedwork, products[pi],
|
||||
@@ -1260,8 +1322,11 @@ fn workescape(s: str) str = {
|
||||
let ri: i32 = 0;
|
||||
for (ri < rootkeys.len) {
|
||||
assert(os.exists(strings.concat(sharedwork, rootkeys[ri], ".o")));
|
||||
assert(!os.exists(strings.concat(sharedwork, rootkeys[ri], ".wwi")));
|
||||
assert(!os.exists(strings.concat(sharedwork, rootkeys[ri], ".a")));
|
||||
assert(os.exists(strings.concat(sharedwork, rootkeys[ri], ".wwi")));
|
||||
assert(os.exists(strings.concat(sharedwork, rootkeys[ri], ".a")));
|
||||
assert(os.exists(strings.concat(sharedwork, mainkeys[ri], ".unit.ww")));
|
||||
assert(os.exists(strings.concat(sharedwork, mainkeys[ri], ".wwi")));
|
||||
assert(os.exists(strings.concat(sharedwork, mainkeys[ri], ".a")));
|
||||
assert(os.exists(bins[ri]));
|
||||
if (ri > 0) {
|
||||
assert(!os.exists(strings.concat(bins[ri], ".sepwork")));
|
||||
@@ -1293,6 +1358,8 @@ fn workescape(s: str) str = {
|
||||
for (ri < rootkeys.len) {
|
||||
assert(occurrences(ctrace, strings.concat(rootkeys[ri],
|
||||
".unit.ww")) == 1);
|
||||
assert(occurrences(ctrace, strings.concat(mainkeys[ri],
|
||||
".unit.ww")) == 1);
|
||||
ri += 1;
|
||||
};
|
||||
assert(pos(ctrace, "/leaf.unit.ww")
|
||||
@@ -1309,7 +1376,9 @@ fn workescape(s: str) str = {
|
||||
for (ri < bins.len) {
|
||||
let link: str = linecontaining(ltrace,
|
||||
strings.concat("-o ", bins[ri], " "));
|
||||
assert(has(link, strings.concat(sharedwork, rootkeys[ri], ".o")));
|
||||
assert(has(link, strings.concat(sharedwork, mainkeys[ri], ".a")));
|
||||
assert(has(link, strings.concat(sharedwork, rootkeys[ri], ".a")));
|
||||
assert(!has(link, ".wwi"));
|
||||
assert(has(link, strings.concat(sharedwork, "common.a")));
|
||||
assert(has(link, strings.concat(sharedwork, "leaf.a")));
|
||||
assert(has(link, strings.concat(sharedwork, "test.a")));
|
||||
@@ -1399,6 +1468,8 @@ fn workescape(s: str) str = {
|
||||
for (ri < rootkeys.len) {
|
||||
assert(occurrences(wwtrace, strings.concat(rootkeys[ri],
|
||||
".unit.ww")) == 1);
|
||||
assert(occurrences(wwtrace, strings.concat(mainkeys[ri],
|
||||
".unit.ww")) == 1);
|
||||
ri += 1;
|
||||
};
|
||||
assert(occurrences(readfile(wwlinkertrace), "\n") == 4);
|
||||
@@ -1747,7 +1818,7 @@ fn workescape(s: str) str = {
|
||||
let cbin: str = readfile(bin);
|
||||
let rootunit: str = readfile(strings.concat(work,
|
||||
"__ww-test-000-same.unit.ww"));
|
||||
assert(has(rootunit, "//ww:module-reset\npackage target;"));
|
||||
assert(has(rootunit, "//ww:module-reset target\npackage target;"));
|
||||
assert(!has(rootunit, "//ww:module "));
|
||||
let linkargs: str = readfile(trace);
|
||||
assert(linkargs.len > 8192);
|
||||
@@ -2214,7 +2285,7 @@ fn workescape(s: str) str = {
|
||||
let workroot: str = strings.concat(bin, ".sepwork");
|
||||
let work: str = strings.concat(workroot, "/");
|
||||
let artifacts: []str = ["ww_root_parity_base_7f3",
|
||||
"ww_root_parity_left_7f3", "ww_root_parity_right_7f3"];
|
||||
"ww_root_parity_left_7f3", "ww_root_parity_right_7f3", "__root"];
|
||||
let unitartifacts: []str = ["ww_root_parity_base_7f3",
|
||||
"ww_root_parity_left_7f3", "ww_root_parity_right_7f3", "__root"];
|
||||
let wantunits: []str = [strings.concat(
|
||||
@@ -2224,10 +2295,10 @@ fn workescape(s: str) str = {
|
||||
leftbody, "\n"),
|
||||
strings.concat("//ww:module-reset ww_root_parity_right_7f3\n",
|
||||
rightbody, "\n"),
|
||||
strings.concat("//ww:module-reset\n", rootbody, "\n")];
|
||||
strings.concat("//ww:module-reset main\n", rootbody, "\n")];
|
||||
let referenceunits: []str = ["", "", "", ""];
|
||||
let referenceexports: []str = ["", "", ""];
|
||||
let referencearchives: []str = ["", "", ""];
|
||||
let referenceexports: []str = ["", "", "", ""];
|
||||
let referencearchives: []str = ["", "", "", ""];
|
||||
let referencebin: str = "";
|
||||
let referencecompiler: str = "";
|
||||
let referenceassembler: str = "";
|
||||
@@ -2327,8 +2398,6 @@ fn workescape(s: str) str = {
|
||||
};
|
||||
ai += 1;
|
||||
};
|
||||
assert(!os.exists(strings.concat(work, "__root.wwi")));
|
||||
assert(!os.exists(strings.concat(work, "__root.a")));
|
||||
assert(os.exists(bin));
|
||||
|
||||
let ctrace: str = readfile(compilertrace);
|
||||
@@ -2351,11 +2420,12 @@ fn workescape(s: str) str = {
|
||||
"ww_root_parity_right_7f3.wwi><-o><", work,
|
||||
"ww_root_parity_right_7f3.s><", work,
|
||||
"ww_root_parity_right_7f3.unit.ww>");
|
||||
let rootline: str = strings.concat("BEGIN<-c><--import>",
|
||||
let rootline: str = strings.concat("BEGIN<--entry><-c><--import>",
|
||||
"<ww_root_parity_left_7f3><", work,
|
||||
"ww_root_parity_left_7f3.wwi><--import>",
|
||||
"<ww_root_parity_right_7f3><", work,
|
||||
"ww_root_parity_right_7f3.wwi><-o><", work,
|
||||
"ww_root_parity_right_7f3.wwi><-I><", work,
|
||||
"__root.wwi><-o><", work,
|
||||
"__root.s><", work, "__root.unit.ww>");
|
||||
assert(same(linecontaining(ctrace,
|
||||
"ww_root_parity_base_7f3.unit.ww"), baseline));
|
||||
@@ -2371,7 +2441,7 @@ fn workescape(s: str) str = {
|
||||
"ww_root_parity_left_7f3.s>")));
|
||||
assert(occurrences(ltrace, "\n") == 1);
|
||||
assert(has(ltrace, strings.concat("BEGIN<-o><", bin, "><", work,
|
||||
"__root.o>")));
|
||||
"__root.a>")));
|
||||
ai = 0;
|
||||
for (ai < artifacts.len) {
|
||||
assert(occurrences(ltrace, strings.concat("<", work, artifacts[ai],
|
||||
|
||||
@@ -97,12 +97,14 @@ fn samefile(a: str, b: str, why: str) void = {
|
||||
|| testenv.has(foounit, "//ww:module ")) {
|
||||
fail("foo unit is not exactly its sorted, owned source set");
|
||||
};
|
||||
let wantroot: str = strings.concat("//ww:module-reset\n", appsrc, "\n");
|
||||
let wantroot: str = strings.concat("//ww:module-reset main\n", appsrc,
|
||||
"\n");
|
||||
if (!testenv.same(wantroot, testenv.readfile(strings.concat(cwork,
|
||||
"__root.unit.ww")))) {
|
||||
fail("root unit is not exactly its owned source");
|
||||
};
|
||||
let keys: []str = ["example.base", "example.bar", "example.foo"];
|
||||
let keys: []str = ["example.base", "example.bar", "example.foo",
|
||||
"__root"];
|
||||
let suffixes: []str = [".unit.ww", ".wwi", ".a"];
|
||||
i = 0;
|
||||
for (i < keys.len) {
|
||||
@@ -117,10 +119,6 @@ fn samefile(a: str, b: str, why: str) void = {
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
samefile(strings.concat(cwork, "__root.unit.ww"), strings.concat(cwork2,
|
||||
"__root.unit.ww"), "root unit changed across clean C builds");
|
||||
samefile(strings.concat(cwork, "__root.unit.ww"), strings.concat(wwork,
|
||||
"__root.unit.ww"), "root unit differs between stages");
|
||||
samefile(stems[0], stems[1], "C executables are not deterministic");
|
||||
samefile(stems[0], stems[2], "C/WW executables differ");
|
||||
|
||||
|
||||
@@ -286,7 +286,8 @@ fn rejectstable(dir: str, label: str, target: str, needle: str) void = {
|
||||
|| testenv.has(apiiface, "hidden")) {
|
||||
fail("self-contained", "api export leaked unrelated or private declarations");
|
||||
};
|
||||
let expectedunit: str = strings.concat("//ww:module-reset\n", mainsrc, "\n");
|
||||
let expectedunit: str = strings.concat("//ww:module-reset main\n",
|
||||
mainsrc, "\n");
|
||||
if (!testenv.same(expectedunit, testenv.readfile(strings.concat(cwork,
|
||||
"__root.unit.ww"))) || !testenv.same(expectedunit,
|
||||
testenv.readfile(strings.concat(wwork, "__root.unit.ww")))) {
|
||||
@@ -405,7 +406,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
let unit: str = testenv.readfile(strings.concat(scratch,
|
||||
"__root.unit.ww"));
|
||||
let rootbody: str = testenv.readfile(strings.concat(main, "/main.ww"));
|
||||
let wantroot: str = strings.concat("//ww:module-reset\n", rootbody,
|
||||
let wantroot: str = strings.concat("//ww:module-reset main\n", rootbody,
|
||||
"\n");
|
||||
if (!testenv.same(unit, wantroot) || testenv.has(unit,
|
||||
"//ww:module ")) {
|
||||
@@ -530,6 +531,8 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
let referenceunit: str = "";
|
||||
let referencewwi: str = "";
|
||||
let referencearchive: str = "";
|
||||
let referencerootwwi: str = "";
|
||||
let referencerootarchive: str = "";
|
||||
let referencebin: str = "";
|
||||
let referencecompiler: str = "";
|
||||
let referenceassembler: str = "";
|
||||
@@ -567,7 +570,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
"__root.unit.ww"));
|
||||
let depunit: str = testenv.readfile(strings.concat(work,
|
||||
"dep.unit.ww"));
|
||||
if (!testenv.has(rootunit, "//ww:module-reset\npackage main;")
|
||||
if (!testenv.has(rootunit, "//ww:module-reset main\npackage main;")
|
||||
|| testenv.has(rootunit, "//ww:module ")
|
||||
|| !testenv.has(depunit, "//ww:module-reset dep\npackage dep;")
|
||||
|| testenv.has(depunit, "//ww:module ")) {
|
||||
@@ -578,8 +581,8 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
|| !testenv.exists(strings.concat(work, "dep.wwi"))
|
||||
|| !testenv.exists(strings.concat(work, "dep.a"))
|
||||
|| !testenv.exists(strings.concat(work, "__root.o"))
|
||||
|| testenv.exists(strings.concat(work, "__root.wwi"))
|
||||
|| testenv.exists(strings.concat(work, "__root.a"))) {
|
||||
|| !testenv.exists(strings.concat(work, "__root.wwi"))
|
||||
|| !testenv.exists(strings.concat(work, "__root.a"))) {
|
||||
fail("library-roots", "package artifacts do not match root ownership");
|
||||
};
|
||||
let ctrace: str = testenv.readfile(compilertrace);
|
||||
@@ -603,6 +606,10 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
"BEGIN<-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,
|
||||
"dep.wwi><-I><", work, "__root.wwi><-o><", work,
|
||||
"__root.s><", work, "__root.unit.ww>"))
|
||||
|| testenv.occurrences(atrace, "\n") != 3
|
||||
|| !testenv.has(atrace, strings.concat("BEGIN<-o><", work,
|
||||
"dep.o><", work, "dep.s>"))) {
|
||||
@@ -610,7 +617,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
};
|
||||
if (testenv.occurrences(ltrace, "\n") != 1
|
||||
|| !testenv.has(ltrace, strings.concat("BEGIN<-o><", bin, "><",
|
||||
work, "__root.o>"))
|
||||
work, "__root.a>"))
|
||||
|| testenv.pos(ltrace, strings.concat("<", work, "dep.a>")) < 0
|
||||
|| testenv.pos(ltrace, strings.concat("<", work, "leaf.a>"))
|
||||
< testenv.pos(ltrace, strings.concat("<", work, "dep.a>"))
|
||||
@@ -643,6 +650,10 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
"dep.wwi")));
|
||||
referencearchive = strings.dup(testenv.readfile(strings.concat(work,
|
||||
"dep.a")));
|
||||
referencerootwwi = strings.dup(testenv.readfile(strings.concat(work,
|
||||
"__root.wwi")));
|
||||
referencerootarchive = strings.dup(testenv.readfile(strings.concat(work,
|
||||
"__root.a")));
|
||||
referencebin = strings.dup(testenv.readfile(bin));
|
||||
referencecompiler = strings.dup(ctrace);
|
||||
referenceassembler = strings.dup(atrace);
|
||||
@@ -653,6 +664,10 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
work, "dep.wwi")))
|
||||
|| !testenv.same(referencearchive, testenv.readfile(strings.concat(
|
||||
work, "dep.a")))
|
||||
|| !testenv.same(referencerootwwi,
|
||||
testenv.readfile(strings.concat(work, "__root.wwi")))
|
||||
|| !testenv.same(referencerootarchive,
|
||||
testenv.readfile(strings.concat(work, "__root.a")))
|
||||
|| !testenv.same(referencebin, testenv.readfile(bin))
|
||||
|| !testenv.same(referencecompiler, ctrace)
|
||||
|| !testenv.same(referenceassembler, atrace)
|
||||
@@ -723,7 +738,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
runav) != 42) {
|
||||
fail("library-roots", "empty override did not use default roots");
|
||||
};
|
||||
if (!testenv.has(rootunit, "//ww:module-reset\npackage main;")
|
||||
if (!testenv.has(rootunit, "//ww:module-reset main\npackage main;")
|
||||
|| testenv.has(rootunit, "//ww:module ")
|
||||
|| !testenv.exists(strings.concat(emptywork, "types.wwi"))
|
||||
|| !testenv.exists(strings.concat(emptywork, "types.a"))
|
||||
@@ -870,7 +885,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
let depunitpath: str = strings.concat(work, "/dep.unit.ww");
|
||||
let rootunit: str = testenv.readfile(rootunitpath);
|
||||
let depunit: str = testenv.readfile(depunitpath);
|
||||
if (!testenv.has(rootunit, "//ww:module-reset\npackage main;")
|
||||
if (!testenv.has(rootunit, "//ww:module-reset main\npackage main;")
|
||||
|| testenv.has(rootunit, "//ww:module ")
|
||||
|| !testenv.has(depunit, "//ww:module-reset dep\npackage dep;")
|
||||
|| testenv.has(depunit, "//ww:module ")) {
|
||||
@@ -880,8 +895,8 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
|| !testenv.exists(strings.concat(work, "/leaf.a"))
|
||||
|| !testenv.exists(strings.concat(work, "/dep.wwi"))
|
||||
|| !testenv.exists(strings.concat(work, "/dep.a"))
|
||||
|| testenv.exists(strings.concat(work, "/__root.wwi"))
|
||||
|| testenv.exists(strings.concat(work, "/__root.a"))
|
||||
|| !testenv.exists(strings.concat(work, "/__root.wwi"))
|
||||
|| !testenv.exists(strings.concat(work, "/__root.a"))
|
||||
|| !testenv.same(testenv.readfile(strings.concat(work,
|
||||
"/.wwtool.ww")), testenv.readfile(copied[si]))
|
||||
|| !testenv.same(testenv.readfile(strings.concat(work,
|
||||
@@ -890,7 +905,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 6 mode build asm 0\n")) {
|
||||
"ww workdir fmt 7 mode build asm 0\n")) {
|
||||
fail("driver-identity", "persistent artifacts or identities are incomplete");
|
||||
};
|
||||
let coldwwi: str = testenv.readfile(strings.concat(work, "/dep.wwi"));
|
||||
@@ -905,7 +920,8 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
"/dep.wwi.new><-o><", work,
|
||||
"/dep.s.new><", work, "/dep.unit.new>"))
|
||||
|| !testenv.has(coldcompiler, strings.concat(
|
||||
"BEGIN<-c><--import><dep><", work, "/dep.wwi><-o><", work,
|
||||
"BEGIN<--entry><-c><--import><dep><", work,
|
||||
"/dep.wwi><-I><", work, "/__root.wwi.new><-o><", work,
|
||||
"/__root.s.new><", work,
|
||||
"/__root.unit.new>"))
|
||||
|| testenv.occurrences(coldassembler, "\n") != 3
|
||||
@@ -916,7 +932,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
};
|
||||
if (testenv.occurrences(coldlinker, "\n") != 1
|
||||
|| !testenv.has(coldlinker, strings.concat("BEGIN<-o><", bin,
|
||||
"><", work, "/__root.o>"))
|
||||
"><", work, "/__root.a>"))
|
||||
|| testenv.pos(coldlinker, strings.concat("<", work,
|
||||
"/dep.a>")) < 0
|
||||
|| testenv.pos(coldlinker, strings.concat("<", work,
|
||||
|
||||
@@ -8,19 +8,16 @@ package sepbuild_test;
|
||||
//
|
||||
// sepbuild (#46 commit-3) — build_one_sep END-TO-END on the real lib
|
||||
// chain root -> os -> {rt,time} (transitive-closure discovery + topo):
|
||||
// build+run exit 7 both stages; {time,rt,os}.wwi + __root.s
|
||||
// materialize (#69: the root is compiled without -I, so no
|
||||
// __root.wwi); per-package .s/.wwi/.unit.ww and the final binary
|
||||
// build+run exit 7 both stages; {time,rt,os,__root}.wwi/.a
|
||||
// materialize; per-package .s/.wwi/.a/.unit.ww and the final binary
|
||||
// byte-id cs vs ww; every .unit.ww is the package's own sorted source
|
||||
// set; `ww run` routes through the same sole sep path (exit 7 both
|
||||
// stages).
|
||||
//
|
||||
// seproot (#69 BUG-1) — a ROOT whose `export fn use(a: *t)` names an
|
||||
// unexported local `type t` builds (exit 37 both stages) because the
|
||||
// root is compiled WITHOUT the -I .wwi-producer flag: __root.wwi must
|
||||
// NOT exist; replaying the driver's own __root.unit.ww plus c.wwi
|
||||
// through w6c/w6c_ww with -I must REJECT (the isolated bug) while -c
|
||||
// -o alone must accept; __root.s carries the exported fn.
|
||||
// seproot — a ROOT whose `export fn use(a: *t)` reaches an unexported
|
||||
// local `type t` builds and emits a deterministic self-contained .wwi/.a.
|
||||
// The private type is carried as compiler export data without `export`, and
|
||||
// an importing source still cannot qualify `main.t`.
|
||||
//
|
||||
// sepstructdef (#70 BUG-2) — a dep exporting aggregate-init defs
|
||||
// (struct-lit + array-lit) sep-builds and links (exit 20 both
|
||||
@@ -91,29 +88,25 @@ fn samefile(label: str, what: str, a: str, b: str) void = {
|
||||
s += 1;
|
||||
};
|
||||
|
||||
// discovery/topo: the transitive package set materialized. #69: the
|
||||
// root emits no .wwi (compiled without -I); its .s stands in.
|
||||
// discovery/topo: every reachable package action materialized.
|
||||
let pkgs: []str = ["time", "rt", "os", "__root"];
|
||||
let i: i32 = 0;
|
||||
for (i < pkgs.len) {
|
||||
let suffix: str = ".wwi";
|
||||
if (testenv.same(pkgs[i], "__root")) { suffix = ".s"; };
|
||||
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/",
|
||||
pkgs[i], suffix))) {
|
||||
fail("sepbuild", strings.concat(pkgs[i], suffix,
|
||||
pkgs[i], ".wwi")) || !testenv.exists(strings.concat(td,
|
||||
"/prog.cs.sepwork/", pkgs[i], ".a"))) {
|
||||
fail("sepbuild", strings.concat(pkgs[i], ".wwi/.a",
|
||||
" missing (discovery/topo)"));
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
|
||||
// cs==ww (rule 10): per-package artifacts + the final binary
|
||||
let sufs: []str = [".s", ".wwi", ".unit.ww"];
|
||||
let sufs: []str = [".s", ".wwi", ".a", ".unit.ww"];
|
||||
let p: i32 = 0;
|
||||
for (p < pkgs.len) {
|
||||
let k: i32 = 0;
|
||||
for (k < sufs.len) {
|
||||
if (testenv.same(pkgs[p], "__root")
|
||||
&& testenv.same(sufs[k], ".wwi")) { k += 1; continue; };
|
||||
samefile("sepbuild", strings.concat(pkgs[p], sufs[k]),
|
||||
strings.concat(td, "/prog.cs.sepwork/", pkgs[p], sufs[k]),
|
||||
strings.concat(td, "/prog.ww.sepwork/", pkgs[p], sufs[k]));
|
||||
@@ -171,15 +164,13 @@ fn samefile(label: str, what: str, a: str, b: str) void = {
|
||||
s += 1;
|
||||
};
|
||||
|
||||
// cs==ww; the root's .wwi is intentionally absent (asserted below)
|
||||
// cs==ww for the complete package artifacts, including the root archive.
|
||||
let pkgs: []str = ["c", "__root"];
|
||||
let sufs: []str = [".s", ".wwi", ".unit.ww"];
|
||||
let sufs: []str = [".s", ".wwi", ".a", ".unit.ww"];
|
||||
let p: i32 = 0;
|
||||
for (p < pkgs.len) {
|
||||
let k: i32 = 0;
|
||||
for (k < sufs.len) {
|
||||
if (testenv.same(pkgs[p], "__root")
|
||||
&& testenv.same(sufs[k], ".wwi")) { k += 1; continue; };
|
||||
samefile("seproot", strings.concat(pkgs[p], sufs[k]),
|
||||
strings.concat(td, "/prog.cs.sepwork/", pkgs[p], sufs[k]),
|
||||
strings.concat(td, "/prog.ww.sepwork/", pkgs[p], sufs[k]));
|
||||
@@ -190,38 +181,51 @@ fn samefile(label: str, what: str, a: str, b: str) void = {
|
||||
samefile("seproot", "the final binary",
|
||||
strings.concat(td, "/prog.cs"), strings.concat(td, "/prog.ww"));
|
||||
|
||||
// the fix: the root is compiled WITHOUT -I, so no __root.wwi
|
||||
// The reachable private nominal is compiler data, not a public source name.
|
||||
let s2: i32 = 0;
|
||||
for (s2 < 2) {
|
||||
if (testenv.exists(strings.concat(td, "/prog.", tags[s2],
|
||||
".sepwork/__root.wwi"))) {
|
||||
let rootiface: str = strings.concat(td, "/prog.", tags[s2],
|
||||
".sepwork/__root.wwi");
|
||||
let ifacebytes: str = testenv.readfile(rootiface);
|
||||
if (!testenv.has(ifacebytes, "type t = struct { v: i32 }")
|
||||
|| testenv.has(ifacebytes, "export type t")
|
||||
|| !testenv.has(ifacebytes, "export fn use(a: *t) i32;")) {
|
||||
fail("seproot", strings.concat(drvs[s2],
|
||||
" produced __root.wwi (-I still passed for the root)"));
|
||||
" did not carry a private reachable type as compiler data"));
|
||||
};
|
||||
s2 += 1;
|
||||
};
|
||||
|
||||
// replay the pre-fix invocation on the driver's own __root.unit.ww:
|
||||
// with -I the export-check FIRES (the isolated bug); without it the
|
||||
// post-fix invocation accepts. Both compilers.
|
||||
// Replay the package compile with -I: both compilers accept and emit the
|
||||
// same self-contained export. A source importer cannot name its private t.
|
||||
let unit: str = strings.concat(td, "/prog.cs.sepwork/__root.unit.ww");
|
||||
let ciface: str = strings.concat(td, "/prog.cs.sepwork/c.wwi");
|
||||
let consumer: str = strings.concat(td, "/consumer.ww");
|
||||
testenv.writefile(consumer, strings.concat(
|
||||
"package consumer;\n",
|
||||
"import main;\n",
|
||||
"fn forbidden(v: *main.t) void = {};\n"));
|
||||
let comps: []str = ["w6c", "w6c_ww"];
|
||||
let c: i32 = 0;
|
||||
for (c < 2) {
|
||||
let wwi: str = strings.concat(td, "/nv.", comps[c], ".wwi");
|
||||
let asmf: str = strings.concat(td, "/nv.", comps[c], ".s");
|
||||
let rav: []str = [testenv.driver(comps[c]), "-c", "--import", "c",
|
||||
ciface, "-I", wwi, "-o", asmf, unit];
|
||||
if (runcode(td, strings.concat("nvI_", comps[c]), rav) == 0) {
|
||||
fail("seproot", strings.concat(comps[c], " -c -I accepted the ",
|
||||
"root export-over-unexported-type (vacuous gate)"));
|
||||
let rav: []str = [testenv.driver(comps[c]), "--entry", "-c",
|
||||
"--import", "c", ciface, "-I", wwi, "-o", asmf, unit];
|
||||
if (runcode(td, strings.concat("reexport_", comps[c]), rav) != 0) {
|
||||
fail("seproot", strings.concat(comps[c],
|
||||
" rejected the self-contained root export"));
|
||||
};
|
||||
let aav: []str = [testenv.driver(comps[c]), "-c", "--import", "c",
|
||||
ciface, "-o", asmf, unit];
|
||||
if (runcode(td, strings.concat("nvO_", comps[c]), aav) != 0) {
|
||||
fail("seproot", strings.concat(comps[c], " -c -o (no -I) ",
|
||||
"rejected the root unit (post-fix invocation)"));
|
||||
let rejectav: []str = [testenv.driver(comps[c]), "-c", "--import",
|
||||
"main", wwi, "-o", asmf, consumer];
|
||||
let reject: testenv.commandout;
|
||||
testenv.runcommand(td, td, strings.concat("private_", comps[c]),
|
||||
rejectav, tmo(), &reject);
|
||||
if (reject.termination != exec.termination.EXIT || reject.code == 0
|
||||
|| !testenv.has(reject.stderr,
|
||||
"package 'main' has no exported declaration 't'")) {
|
||||
fail("seproot", strings.concat(comps[c],
|
||||
" exposed the compiler-private type to source importers"));
|
||||
};
|
||||
c += 1;
|
||||
};
|
||||
|
||||
@@ -69,7 +69,8 @@ fn cmpsepwork(label: str, csdir: str, wwdir: str) void = {
|
||||
let i: i32 = 0;
|
||||
for (i < names.len) {
|
||||
if (strings.hassuffix(names[i], ".s")
|
||||
|| strings.hassuffix(names[i], ".wwi")) {
|
||||
|| strings.hassuffix(names[i], ".wwi")
|
||||
|| strings.hassuffix(names[i], ".a")) {
|
||||
seen += 1;
|
||||
if (!testenv.same(
|
||||
testenv.readfile(strings.concat(csdir, "/", names[i])),
|
||||
@@ -81,7 +82,7 @@ fn cmpsepwork(label: str, csdir: str, wwdir: str) void = {
|
||||
i += 1;
|
||||
};
|
||||
// an existing-but-empty sepwork would pass the loop vacuously
|
||||
if (seen == 0) { fail(label, "no .s/.wwi in cs sepwork"); };
|
||||
if (seen == 0) { fail(label, "no package artifacts in cs sepwork"); };
|
||||
};
|
||||
|
||||
@test fn coloimport() void = {
|
||||
@@ -210,11 +211,11 @@ fn depmainrow(label: str, entry: str, want: i32, deps: str,
|
||||
l += 1;
|
||||
};
|
||||
|
||||
// the root emits no .wwi post-#69, so its suffix set omits .wwi
|
||||
let parts: []str = ["aa.s", "aa.wwi", "aa.unit.ww", "__root.s",
|
||||
"__root.unit.ww"];
|
||||
// Both the dependency and raw explicit root emit complete package artifacts.
|
||||
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 fixed 5-part table
|
||||
// cs==ww (rule 10) per layout over the complete package-artifact table
|
||||
let l2: i32 = 0;
|
||||
for (l2 < 2) {
|
||||
let p: i32 = 0;
|
||||
|
||||
@@ -4,12 +4,11 @@ package seplink_test;
|
||||
// retired native carriers test/wcc/989_separchive_run.c and
|
||||
// 989_sepcycle_dup.c; every assertion preserved.
|
||||
//
|
||||
// archive (#46 commit-5a) — `ww build` wraps each DEP package's .o in
|
||||
// a deterministic single-member .a and links the ROOT as a positional
|
||||
// .o (force-loaded): build+run exit 7 both stages; __root.a absent,
|
||||
// __root.o + helper.a present; cs helper.a == ww helper.a (rule 10,
|
||||
// the .a byte-id substrate); 3 cold cstage rebuilds emit
|
||||
// byte-identical helper.a (zeroed mtime/uid/gid, fixed mode/member —
|
||||
// archive — `ww build` wraps every package action's .o in the existing
|
||||
// deterministic single-member .a and links the 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 —
|
||||
// a floating byte would poison the content cache key).
|
||||
//
|
||||
// archivedup (#31 PASS 3) — two dep packages force the same link
|
||||
@@ -94,22 +93,20 @@ fn runcode(dir: str, name: str, argv: []str) i32 = {
|
||||
s += 1;
|
||||
};
|
||||
|
||||
// layout: root stays a positional force-loaded .o, deps become .a
|
||||
if (testenv.exists(strings.concat(td, "/prog.cs.sepwork/__root.a"))) {
|
||||
fail("archive", "root wrapped in .a (should stay positional .o)");
|
||||
};
|
||||
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/__root.o"))) {
|
||||
fail("archive", "missing root .o");
|
||||
};
|
||||
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/helper.a"))) {
|
||||
fail("archive", "missing dep helper.a");
|
||||
// layout: root and dependency are both package archives.
|
||||
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/__root.a"))
|
||||
|| !testenv.exists(strings.concat(td, "/prog.cs.sepwork/helper.a"))) {
|
||||
fail("archive", "missing root or dependency archive");
|
||||
};
|
||||
|
||||
// rule 10: the .a byte-id substrate
|
||||
// rule 10: the complete .a byte-id substrate
|
||||
if (!testenv.same(
|
||||
testenv.readfile(strings.concat(td, "/prog.cs.sepwork/helper.a")),
|
||||
testenv.readfile(strings.concat(td, "/prog.ww.sepwork/helper.a")))) {
|
||||
fail("archive", "cs helper.a != ww helper.a (rule 10 .a byte-id)");
|
||||
testenv.readfile(strings.concat(td, "/prog.ww.sepwork/helper.a")))
|
||||
|| !testenv.same(
|
||||
testenv.readfile(strings.concat(td, "/prog.cs.sepwork/__root.a")),
|
||||
testenv.readfile(strings.concat(td, "/prog.ww.sepwork/__root.a")))) {
|
||||
fail("archive", "cs package archives != ww package archives");
|
||||
};
|
||||
|
||||
// determinism: 3 cold cstage rebuilds -> byte-identical .a
|
||||
@@ -132,9 +129,18 @@ fn runcode(dir: str, name: str, argv: []str) i32 = {
|
||||
let a2: str = testenv.readfile(strings.concat(det2,
|
||||
".sepwork/helper.a"));
|
||||
if (!testenv.same(a0, a1) || !testenv.same(a1, a2)) {
|
||||
fail("archive", strings.concat(".a not deterministic across 3 ",
|
||||
fail("archive", strings.concat("dependency .a not deterministic across 3 ",
|
||||
"builds (floating bytes poison the cache key)"));
|
||||
};
|
||||
let r0: str = testenv.readfile(strings.concat(det0,
|
||||
".sepwork/__root.a"));
|
||||
let r1: str = testenv.readfile(strings.concat(det1,
|
||||
".sepwork/__root.a"));
|
||||
let r2: str = testenv.readfile(strings.concat(det2,
|
||||
".sepwork/__root.a"));
|
||||
if (!testenv.same(r0, r1) || !testenv.same(r1, r2)) {
|
||||
fail("archive", "root .a not deterministic across 3 builds");
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ slurp(const char *path, char **outbuf, size_t *outlen)
|
||||
}
|
||||
|
||||
/* #93 sep layout: the flip stops emitting a monolithic <tool>/main.o;
|
||||
* the linkable unit is now the per-package .o + reverse-topo .a set the
|
||||
* sep driver assembles (a raw `w6l <root>.o *.a libwwrt.a` from the test
|
||||
* the linkable unit is now the root .a + reverse-topo .a set the
|
||||
* sep driver assembles (a raw `w6l <root>.a *.a libwwrt.a` from the test
|
||||
* side fails — `undefined reference` — because it can't reproduce the
|
||||
* driver's topo order). Drive each real directory package through the
|
||||
* full sep build twice; both compile directly and differ only in the
|
||||
@@ -139,7 +139,7 @@ main(void)
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return 1;
|
||||
|
||||
/* Real bootstrap-style links: each selfhost tool's full sep build
|
||||
* (root .o + reverse-topo dep .a set + libwwrt.a). Both builds compile
|
||||
* (root .a + reverse-topo dep .a set + libwwrt.a). Both builds compile
|
||||
* directly and differ only in the selected linker. (wwdump is excluded —
|
||||
* it imports the compiler-internal cmd packages syntax/check/cgen, which don't resolve
|
||||
* under the lib-path sep dep scan; w6a/w6l are self-contained
|
||||
@@ -157,6 +157,6 @@ main(void)
|
||||
return 1;
|
||||
}
|
||||
printf("w6l_ww: byte-identical to C w6l on %d selfhost tool links "
|
||||
"(sep root .o + reverse-topo .a set + libwwrt.a)\n", n);
|
||||
"(sep root .a + reverse-topo .a set + libwwrt.a)\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user