build: pass direct exports to package compilers
This commit is contained in:
@@ -88,25 +88,22 @@ fn samefile(a: str, b: str, why: str) void = {
|
||||
let cwork: str = strings.concat(stems[0], ".sepwork/");
|
||||
let cwork2: str = strings.concat(stems[1], ".sepwork/");
|
||||
let wwork: str = strings.concat(stems[2], ".sepwork/");
|
||||
let bariface: str = testenv.readfile(strings.concat(cwork, "example.bar.wwi"));
|
||||
let fooiface: str = testenv.readfile(strings.concat(cwork, "example.foo.wwi"));
|
||||
let foounit: str = testenv.readfile(strings.concat(cwork,
|
||||
"example.foo.unit.ww"));
|
||||
let wantfoo: str = strings.concat("//ww:module example.bar\n", bariface,
|
||||
"\n//ww:module-reset example.foo\n", afoosrc,
|
||||
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)
|
||||
|| testenv.has(foounit, "DECOY_FILE")) {
|
||||
fail("foo unit is not its sorted, owned source set plus direct bar export");
|
||||
|| testenv.has(foounit, "DECOY_FILE")
|
||||
|| testenv.has(foounit, "//ww:module ")) {
|
||||
fail("foo unit is not exactly its sorted, owned source set");
|
||||
};
|
||||
let wantroot: str = strings.concat("//ww:module example.foo\n", fooiface,
|
||||
"\n//ww:module-reset\n", appsrc, "\n");
|
||||
let wantroot: str = strings.concat("//ww:module-reset\n", appsrc, "\n");
|
||||
if (!testenv.same(wantroot, testenv.readfile(strings.concat(cwork,
|
||||
"__root.unit.ww")))) {
|
||||
fail("root unit is not direct-foo-only");
|
||||
fail("root unit is not exactly its owned source");
|
||||
};
|
||||
let keys: []str = ["example.base", "example.bar", "example.foo"];
|
||||
let suffixes: []str = [".wwi", ".a"];
|
||||
let suffixes: []str = [".unit.ww", ".wwi", ".a"];
|
||||
i = 0;
|
||||
for (i < keys.len) {
|
||||
let j: i32 = 0;
|
||||
@@ -120,6 +117,10 @@ 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,12 +286,11 @@ 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 api\n", apiiface,
|
||||
"\n//ww:module-reset\n", mainsrc, "\n");
|
||||
let expectedunit: str = strings.concat("//ww:module-reset\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")))) {
|
||||
fail("self-contained", "consumer compiler input was not direct-api-only");
|
||||
fail("self-contained", "consumer unit was not exactly its owned source");
|
||||
};
|
||||
if (!testenv.exists(strings.concat(cwork, "implementation.a"))
|
||||
|| !testenv.exists(strings.concat(cwork, "dimensions.a"))) {
|
||||
@@ -405,10 +404,12 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
};
|
||||
let unit: str = testenv.readfile(strings.concat(scratch,
|
||||
"__root.unit.ww"));
|
||||
let lp: i32 = testenv.pos(unit, "//ww:module left\n");
|
||||
let rp: i32 = testenv.pos(unit, "//ww:module right\n");
|
||||
if (lp < 0 || rp < 0 || lp >= rp) {
|
||||
fail("diamond", "dependency traversal did not byte-sort imports");
|
||||
let rootbody: str = testenv.readfile(strings.concat(main, "/main.ww"));
|
||||
let wantroot: str = strings.concat("//ww:module-reset\n", rootbody,
|
||||
"\n");
|
||||
if (!testenv.same(unit, wantroot) || testenv.has(unit,
|
||||
"//ww:module ")) {
|
||||
fail("diamond", "root unit contains non-owned export text");
|
||||
};
|
||||
let sharedunit: str = testenv.readfile(strings.concat(scratch,
|
||||
"shared.unit.ww"));
|
||||
@@ -426,8 +427,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
};
|
||||
if (testenv.occurrences(leftiface, "export type token") != 1
|
||||
|| testenv.occurrences(rightiface, "export type token") != 1
|
||||
|| testenv.occurrences(unit, "export type token") != 2
|
||||
|| testenv.occurrences(unit, "//ww:module shared\n") != 2) {
|
||||
|| testenv.has(unit, "export type token")) {
|
||||
fail("diamond", "origin fact closure did not merge deterministically");
|
||||
};
|
||||
i += 1;
|
||||
@@ -452,43 +452,6 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
fail("diamond", "shuffled enumeration changed package units");
|
||||
};
|
||||
|
||||
// Count actual compiler actions, rather than inferring interning from
|
||||
// artifact names. The wrapper is selected through the production
|
||||
// driver's existing tool override and records one row per w6c process.
|
||||
let trace: str = strings.concat(td, "/compiler.trace");
|
||||
let wrapper: str = strings.concat(td, "/trace-w6c.sh");
|
||||
testenv.writefile(trace, "");
|
||||
testenv.writeexecutable(wrapper, strings.concat(
|
||||
"#!/bin/sh\n",
|
||||
"printf '%s\\n' \"$*\" >> \"$WW_LOCALBUILD_TRACE\"\n",
|
||||
"exec \"$WW_LOCALBUILD_W6C\" \"$@\"\n"));
|
||||
let baseenv: []str = os.getenvs();
|
||||
let env: []str = alloc([], (baseenv.len + 3): u64)!;
|
||||
let ei: i32 = 0;
|
||||
for (ei < baseenv.len) {
|
||||
if (!strings.hasprefix(baseenv[ei], "WW_W6C=")
|
||||
&& !strings.hasprefix(baseenv[ei], "WW_LOCALBUILD_TRACE=")
|
||||
&& !strings.hasprefix(baseenv[ei], "WW_LOCALBUILD_W6C=")) {
|
||||
append(env, baseenv[ei]);
|
||||
};
|
||||
ei += 1;
|
||||
};
|
||||
append(env, strings.concat("WW_W6C=", wrapper));
|
||||
append(env, strings.concat("WW_LOCALBUILD_TRACE=", trace));
|
||||
append(env, strings.concat("WW_LOCALBUILD_W6C=",
|
||||
testenv.driver("w6c")));
|
||||
let countedout: str = strings.concat(td, "/diamond-counted");
|
||||
let countedav: []str = [testenv.driver("ww"), "build", "-I", treea,
|
||||
"-o", countedout, main];
|
||||
let counted: testenv.commandout;
|
||||
testenv.runcommandenv(td, td, "diamond_compile_count", countedav,
|
||||
env, tmo(), &counted);
|
||||
if (counted.termination != exec.termination.EXIT || counted.code != 0) {
|
||||
fail("diamond", "instrumented build failed");
|
||||
};
|
||||
if (testenv.occurrences(testenv.readfile(trace), "shared.unit.ww") != 1) {
|
||||
fail("diamond", "shared package was not compiled exactly once");
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
@@ -604,10 +567,11 @@ 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 dep\n")
|
||||
|| testenv.has(rootunit, "//ww:module leaf\n")
|
||||
|| !testenv.has(depunit, "//ww:module leaf\n")) {
|
||||
fail("library-roots", "compiler inputs crossed the direct-export boundary");
|
||||
if (!testenv.has(rootunit, "//ww:module-reset\npackage main;")
|
||||
|| testenv.has(rootunit, "//ww:module ")
|
||||
|| !testenv.has(depunit, "//ww:module-reset dep\npackage dep;")
|
||||
|| testenv.has(depunit, "//ww:module ")) {
|
||||
fail("library-roots", "package units contain non-owned export text");
|
||||
};
|
||||
if (!testenv.exists(strings.concat(work, "leaf.wwi"))
|
||||
|| !testenv.exists(strings.concat(work, "leaf.a"))
|
||||
@@ -636,7 +600,8 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
fail("library-roots", "compiler actions were not deterministic postorder");
|
||||
};
|
||||
if (!testenv.has(ctrace, strings.concat(
|
||||
"BEGIN<-c><-I><", work, "dep.wwi><-o><", work,
|
||||
"BEGIN<-c><--import><leaf><", work, "leaf.wwi><-I><", work,
|
||||
"dep.wwi><-o><", work,
|
||||
"dep.s><", work, "dep.unit.ww>"))
|
||||
|| testenv.occurrences(atrace, "\n") != 3
|
||||
|| !testenv.has(atrace, strings.concat("BEGIN<-o><", work,
|
||||
@@ -758,7 +723,8 @@ 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 types\n")
|
||||
if (!testenv.has(rootunit, "//ww:module-reset\npackage main;")
|
||||
|| testenv.has(rootunit, "//ww:module ")
|
||||
|| !testenv.exists(strings.concat(emptywork, "types.wwi"))
|
||||
|| !testenv.exists(strings.concat(emptywork, "types.a"))
|
||||
|| testenv.occurrences(ctrace, strings.concat("<", emptywork,
|
||||
@@ -904,10 +870,11 @@ 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 dep\n")
|
||||
|| testenv.has(rootunit, "//ww:module leaf\n")
|
||||
|| !testenv.has(depunit, "//ww:module leaf\n")) {
|
||||
fail("driver-identity", "warm units crossed the direct-export boundary");
|
||||
if (!testenv.has(rootunit, "//ww:module-reset\npackage main;")
|
||||
|| testenv.has(rootunit, "//ww:module ")
|
||||
|| !testenv.has(depunit, "//ww:module-reset dep\npackage dep;")
|
||||
|| testenv.has(depunit, "//ww:module ")) {
|
||||
fail("driver-identity", "warm units contain non-owned export text");
|
||||
};
|
||||
if (!testenv.exists(strings.concat(work, "/leaf.wwi"))
|
||||
|| !testenv.exists(strings.concat(work, "/leaf.a"))
|
||||
@@ -923,7 +890,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 5 mode build asm 0\n")) {
|
||||
"ww workdir fmt 6 mode build asm 0\n")) {
|
||||
fail("driver-identity", "persistent artifacts or identities are incomplete");
|
||||
};
|
||||
let coldwwi: str = testenv.readfile(strings.concat(work, "/dep.wwi"));
|
||||
@@ -934,10 +901,12 @@ 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><-I><", work, "/dep.wwi.new><-o><", work,
|
||||
"BEGIN<-c><--import><leaf><", work, "/leaf.wwi><-I><", work,
|
||||
"/dep.wwi.new><-o><", work,
|
||||
"/dep.s.new><", work, "/dep.unit.new>"))
|
||||
|| !testenv.has(coldcompiler, strings.concat(
|
||||
"BEGIN<-c><-o><", work, "/__root.s.new><", work,
|
||||
"BEGIN<-c><--import><dep><", work, "/dep.wwi><-o><", work,
|
||||
"/__root.s.new><", work,
|
||||
"/__root.unit.new>"))
|
||||
|| testenv.occurrences(coldassembler, "\n") != 3
|
||||
|| !testenv.has(coldassembler, strings.concat(
|
||||
@@ -964,21 +933,62 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
fail("driver-identity", "cold binary returned the wrong value");
|
||||
};
|
||||
|
||||
testenv.writefile(strings.concat(leaf, "/extra.ww"), strings.concat(
|
||||
"package leaf;\n",
|
||||
"export fn unchanged_api() i32 = { return 1; };\n"));
|
||||
testenv.runcommandenv(cwd, td, strings.concat("driver-export-change-",
|
||||
tags[si]), av, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0) {
|
||||
fail("driver-identity", "dependency export-change build failed");
|
||||
};
|
||||
let changedexportcompiler: str = testenv.readfile(compilertrace);
|
||||
let changedexportassembler: str = testenv.readfile(assemblertrace);
|
||||
if (testenv.occurrences(changedexportcompiler, strings.concat("<", work,
|
||||
"/leaf.unit.new>")) != 2
|
||||
|| testenv.occurrences(changedexportcompiler, strings.concat("<", work,
|
||||
"/dep.unit.new>")) != 2
|
||||
|| testenv.occurrences(changedexportcompiler, strings.concat("<", work,
|
||||
"/__root.unit.new>")) != 1
|
||||
|| testenv.occurrences(changedexportcompiler, "\n") != 5
|
||||
|| testenv.occurrences(changedexportassembler, "\n") != 5) {
|
||||
fail("driver-identity", "changed export did not stop at an unchanged importer export");
|
||||
};
|
||||
if (code(cwd, strings.concat("driver-export-change-run-", tags[si]),
|
||||
runav) != 42) {
|
||||
fail("driver-identity", "export-change binary returned the wrong value");
|
||||
};
|
||||
let changedexportbin: str = testenv.readfile(bin);
|
||||
let beforewarmcompiler: str = strings.dup(changedexportcompiler);
|
||||
let beforewarmassembler: str = strings.dup(changedexportassembler);
|
||||
|
||||
testenv.runcommandenv(cwd, td, strings.concat("driver-warm-",
|
||||
tags[si]), av, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| !testenv.same(coldcompiler, testenv.readfile(compilertrace))
|
||||
|| !testenv.same(coldassembler, testenv.readfile(assemblertrace))
|
||||
|| testenv.occurrences(testenv.readfile(linkertrace), "\n") != 2
|
||||
|| !testenv.same(beforewarmcompiler, testenv.readfile(compilertrace))
|
||||
|| !testenv.same(beforewarmassembler, testenv.readfile(assemblertrace))
|
||||
|| testenv.occurrences(testenv.readfile(linkertrace), "\n") != 3
|
||||
|| !testenv.same(rootunit, testenv.readfile(rootunitpath))
|
||||
|| !testenv.same(coldwwi, testenv.readfile(strings.concat(work,
|
||||
"/dep.wwi")))
|
||||
|| !testenv.same(coldarchive, testenv.readfile(strings.concat(work,
|
||||
"/dep.a")))
|
||||
|| !testenv.same(coldbin, testenv.readfile(bin))) {
|
||||
|| !testenv.same(changedexportbin, testenv.readfile(bin))) {
|
||||
fail("driver-identity", "unchanged warm build did not reuse packages");
|
||||
};
|
||||
assert(os.remove(strings.concat(leaf, "/extra.ww")) == 0);
|
||||
testenv.runcommandenv(cwd, td, strings.concat("driver-export-restore-",
|
||||
tags[si]), av, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| testenv.occurrences(testenv.readfile(compilertrace), strings.concat(
|
||||
"<", work, "/leaf.unit.new>")) != 3
|
||||
|| testenv.occurrences(testenv.readfile(compilertrace), strings.concat(
|
||||
"<", work, "/dep.unit.new>")) != 3
|
||||
|| testenv.occurrences(testenv.readfile(compilertrace), strings.concat(
|
||||
"<", work, "/__root.unit.new>")) != 1
|
||||
|| testenv.occurrences(testenv.readfile(compilertrace), "\n") != 7
|
||||
|| testenv.occurrences(testenv.readfile(assemblertrace), "\n") != 7
|
||||
|| !testenv.same(coldbin, testenv.readfile(bin))) {
|
||||
fail("driver-identity", "restored export did not rebuild only its direct importer");
|
||||
};
|
||||
|
||||
assert(os.remove(copied[si]) == 0);
|
||||
testenv.writeexecutable(copied[si], strings.concat(driverbytes,
|
||||
@@ -994,14 +1004,14 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
let changedassembler: str = testenv.readfile(assemblertrace);
|
||||
let changedlinker: str = testenv.readfile(linkertrace);
|
||||
if (testenv.occurrences(changedcompiler, strings.concat("<", work,
|
||||
"/leaf.unit.new>")) != 2
|
||||
"/leaf.unit.new>")) != 4
|
||||
|| testenv.occurrences(changedcompiler, strings.concat("<", work,
|
||||
"/dep.unit.new>")) != 2
|
||||
"/dep.unit.new>")) != 4
|
||||
|| testenv.occurrences(changedcompiler, strings.concat("<", work,
|
||||
"/__root.unit.new>")) != 2
|
||||
|| testenv.occurrences(changedcompiler, "\n") != 6
|
||||
|| testenv.occurrences(changedassembler, "\n") != 6
|
||||
|| testenv.occurrences(changedlinker, "\n") != 3) {
|
||||
|| testenv.occurrences(changedcompiler, "\n") != 10
|
||||
|| testenv.occurrences(changedassembler, "\n") != 10
|
||||
|| testenv.occurrences(changedlinker, "\n") != 5) {
|
||||
fail("driver-identity", "driver change reused stale package actions");
|
||||
};
|
||||
if (!testenv.same(testenv.readfile(strings.concat(work,
|
||||
|
||||
@@ -3,26 +3,24 @@ package sepbuild_test;
|
||||
// `ww build` sep-driver layout observers, both stages. Ports of the
|
||||
// retired native carriers test/wcc/989_sepbuild_run.c,
|
||||
// 989_seproot_export_run.c, 989_sepstructdef_run.c and
|
||||
// 989_wwispread_sep.c; every assertion preserved.
|
||||
// 989_wwispread_sep.c; assertions retained where their production boundary
|
||||
// remains live.
|
||||
//
|
||||
// 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
|
||||
// byte-id cs vs ww; the KEYSTONE (spec 3.1) recompiles the driver's
|
||||
// own non-leaf .unit.ww with each dep's .wwi section replaced by that
|
||||
// dep's full directory bodies and requires byte-identical .s — the
|
||||
// proof the .wwi conveys exactly the dep facts P's codegen needs;
|
||||
// `ww run` routes through the same sole sep path (exit 7 both
|
||||
// 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 through
|
||||
// w6c/w6c_ww with -I must REJECT (the isolated bug) while -c -o alone
|
||||
// must accept; __root.s carries the exported fn.
|
||||
// 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.
|
||||
//
|
||||
// sepstructdef (#70 BUG-2) — a dep exporting aggregate-init defs
|
||||
// (struct-lit + array-lit) sep-builds and links (exit 20 both
|
||||
@@ -69,80 +67,6 @@ fn samefile(label: str, what: str, a: str, b: str) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// A package directory's *.ww bodies (less *test.ww), byte-sorted, each
|
||||
// newline-terminated — mirrors the driver's body enumeration so the
|
||||
// substituted bodies-unit matches the sep-unit structurally.
|
||||
fn dirbodies(dir: str) str = {
|
||||
let out: str = "";
|
||||
let names: []str = testenv.listdir(dir);
|
||||
let i: i32 = 0;
|
||||
for (i < names.len) {
|
||||
if (strings.hassuffix(names[i], ".ww")
|
||||
&& !strings.hassuffix(names[i], "test.ww")) {
|
||||
out = strings.concat(out,
|
||||
testenv.readfile(strings.concat(dir, "/", names[i])),
|
||||
"\n");
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
return out;
|
||||
};
|
||||
|
||||
// Byte-offset borrow: strings.sub is rune-indexed, and the driver
|
||||
// units embed lib comment bytes outside ASCII, so rune indices would
|
||||
// mis-address the byte cursor below (readfile's borrow idiom).
|
||||
fn bslice(s: str, start: i32, end: i32) str = {
|
||||
assert(start <= end && end <= s.len);
|
||||
let r: str;
|
||||
r.ptr = s.ptr + (start: u64);
|
||||
r.len = end - start;
|
||||
return r;
|
||||
};
|
||||
|
||||
// Transform a driver sep-unit into a bodies-unit: every `//ww:module
|
||||
// <path>` dep section (its .wwi content) is replaced by <path>'s full
|
||||
// directory bodies (dots -> slashes under libdir); the trailing
|
||||
// `//ww:module-reset` primary body is copied verbatim. The keystone's
|
||||
// other arm.
|
||||
fn composebodies(unit: str, libdir: str) str = {
|
||||
let out: str = "";
|
||||
let n: i32 = unit.len;
|
||||
let i: i32 = 0;
|
||||
for (i < n) {
|
||||
let j: i32 = i;
|
||||
for (j < n && unit[j] != '\n') { j += 1; };
|
||||
let line: str = bslice(unit, i, j);
|
||||
if (strings.hasprefix(line, "//ww:module-reset")) {
|
||||
out = strings.concat(out, bslice(unit, i, n));
|
||||
return out;
|
||||
};
|
||||
if (strings.hasprefix(line, "//ww:module ")) {
|
||||
out = strings.concat(out, line, "\n");
|
||||
let path: str = bslice(line, 12, line.len);
|
||||
let d: []u8 = alloc([], (path.len + 1): u64)!;
|
||||
let k: i32 = 0;
|
||||
for (k < path.len) {
|
||||
if (path[k] == '.') { append(d, '/'); }
|
||||
else { append(d, path[k]); };
|
||||
k += 1;
|
||||
};
|
||||
out = strings.concat(out, dirbodies(strings.concat(libdir,
|
||||
"/", strings.frombytes(d))));
|
||||
i = j + 1;
|
||||
for (i < n) {
|
||||
let e: i32 = i;
|
||||
for (e < n && unit[e] != '\n') { e += 1; };
|
||||
if (strings.hasprefix(bslice(unit, i, e),
|
||||
"//ww:module")) { break; };
|
||||
i = e + 1;
|
||||
};
|
||||
continue;
|
||||
};
|
||||
i = j + 1;
|
||||
};
|
||||
return out;
|
||||
};
|
||||
|
||||
@test fn sepbuild() void = {
|
||||
let td: str = testenv.fresh();
|
||||
let rootww: str = strings.concat(td, "/root.ww");
|
||||
@@ -200,34 +124,6 @@ fn composebodies(unit: str, libdir: str) str = {
|
||||
samefile("sepbuild", "the final binary",
|
||||
strings.concat(td, "/prog.cs"), strings.concat(td, "/prog.ww"));
|
||||
|
||||
// KEYSTONE through the driver, non-leaf packages only (leaves have
|
||||
// no dep sections, so their keystone is vacuous)
|
||||
let libdir: str = strings.concat(testenv.repo(), "/lib");
|
||||
let keypkgs: []str = ["os", "__root"];
|
||||
let kp: i32 = 0;
|
||||
for (kp < keypkgs.len) {
|
||||
let unit: str = testenv.readfile(strings.concat(td,
|
||||
"/prog.cs.sepwork/", keypkgs[kp], ".unit.ww"));
|
||||
let bodiesf: str = strings.concat(td, "/", keypkgs[kp],
|
||||
".bodies.ww");
|
||||
testenv.writefile(bodiesf, composebodies(unit, libdir));
|
||||
let bodiess: str = strings.concat(td, "/", keypkgs[kp],
|
||||
".bodies.s");
|
||||
let av: []str = [testenv.driver("w6c"), "-c", "-o", bodiess,
|
||||
bodiesf];
|
||||
if (runcode(td, strings.concat("key_", keypkgs[kp]), av) != 0) {
|
||||
fail("sepbuild", strings.concat(keypkgs[kp], " bodies -c failed"));
|
||||
};
|
||||
if (!testenv.same(testenv.readfile(bodiess),
|
||||
testenv.readfile(strings.concat(td, "/prog.cs.sepwork/",
|
||||
keypkgs[kp], ".s")))) {
|
||||
fail("sepbuild", strings.concat(keypkgs[kp],
|
||||
" bodies.s != driver sep.s (the .wwi does not convey ",
|
||||
"the dep facts P needs)"));
|
||||
};
|
||||
kp += 1;
|
||||
};
|
||||
|
||||
// `ww run` routes through the sole sep path on both stages
|
||||
let cav: []str = [testenv.driver("ww"), "run", rootww];
|
||||
let rccs: i32 = runcode(td, "run_cs", cav);
|
||||
@@ -309,19 +205,20 @@ fn composebodies(unit: str, libdir: str) str = {
|
||||
// with -I the export-check FIRES (the isolated bug); without it the
|
||||
// post-fix invocation accepts. Both compilers.
|
||||
let unit: str = strings.concat(td, "/prog.cs.sepwork/__root.unit.ww");
|
||||
let ciface: str = strings.concat(td, "/prog.cs.sepwork/c.wwi");
|
||||
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", "-I", wwi,
|
||||
"-o", asmf, unit];
|
||||
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 aav: []str = [testenv.driver(comps[c]), "-c", "-o", asmf,
|
||||
unit];
|
||||
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)"));
|
||||
|
||||
Reference in New Issue
Block a user