cmd: compile packages from direct exports
This commit is contained in:
@@ -624,16 +624,12 @@ type lflags = struct {
|
||||
// producer (writes this package's `.wwi` via -I). Reverse-topo order
|
||||
// guarantees a package's deps' `.wwi` exist before it compiles.
|
||||
//
|
||||
// The load-bearing rule (#56, rob-resolved): every dep is tagged by its
|
||||
// FULL DOTTED import path on prepend (`//ww:module <path>`), so the
|
||||
// definer's qualified symbol (#53) equals the consumer's qualified
|
||||
// reference (#40) and the sep `.o`s link. The prepend is the TRANSITIVE
|
||||
// closure of a package's deps (lead-ratified): a dep's interface can
|
||||
// name a transitive dep's type, so the consuming unit needs the whole
|
||||
// closure for resolution. Qualifier lookup remains scoped to the direct
|
||||
// imports owned by each source package, so those type facts do not expose
|
||||
// a transitive package. The unit composition is byte-identical to the cstage
|
||||
// driver (rule 10) so w6c/w6c_ww emit identical `.s`.
|
||||
// Every direct dep is tagged by its FULL DOTTED import path on prepend
|
||||
// (`//ww:module <path>`), so the definer's qualified symbol equals the
|
||||
// consumer's qualified reference and the sep `.o`s link. A dependency's
|
||||
// compiler-owned `.wwi` carries its reachable public foreign type facts;
|
||||
// separately prepending transitive interfaces is neither necessary nor
|
||||
// allowed. The unit composition is byte-identical to the cstage driver.
|
||||
|
||||
def SEP_MAXPKG: i32 = 256;
|
||||
|
||||
@@ -670,7 +666,8 @@ fn sepfindoradd(g: *sepgraph, path: *u8, entry: *u8, isdir: i32) i32 = {
|
||||
return i;
|
||||
};
|
||||
if (os.samefile(pathstr(g.pkg[i].entry), pathstr(entry))) {
|
||||
cerr("ww: one package directory has identities ");
|
||||
cerr("ww: package directory "); cerr(pathstr(entry));
|
||||
cerr(" has identities ");
|
||||
if (g.pkg[i].path[0u64] == 0u8) { cerr("(root)"); }
|
||||
else { cerr(pathstr(g.pkg[i].path)); };
|
||||
cerr(" and ");
|
||||
@@ -1047,18 +1044,6 @@ fn septopovisit(g: *sepgraph, pi: i32, order: []i32, no: *i32,
|
||||
return 0;
|
||||
};
|
||||
|
||||
fn sepmarkdeps(g: *sepgraph, pi: i32, inset: []u8) void = {
|
||||
let k: i32 = 0;
|
||||
for (k < g.pkg[pi].ndeps) {
|
||||
let di: i32 = g.pkg[pi].deps[k];
|
||||
if (inset[di] == 0u8) {
|
||||
inset[di] = 1u8;
|
||||
sepmarkdeps(g, di, inset);
|
||||
};
|
||||
k += 1;
|
||||
};
|
||||
};
|
||||
|
||||
// Emit one of pi's own source files into the sep-unit under the
|
||||
// //ww:module-reset primary boundary (so -c emits its decls, imported
|
||||
// ==0). DIRECTORY imports are skipped (provided as `.wwi` ahead);
|
||||
@@ -1165,50 +1150,41 @@ fn sepemitbody(fd: i32, path: *u8, visit: *expctx, searchpath: *u8,
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Compose pi's sep-unit at `unitf`: the transitive-closure `.wwi`s
|
||||
// (reverse-topo order, each tagged by its dotted path), then pi's own
|
||||
// body under //ww:module-reset. Directory membership comes only from the
|
||||
// package node loaded before planning.
|
||||
fn sepcomposeunit(g: *sepgraph, pi: i32, scratch: *u8, order: []i32,
|
||||
norder: i32, searchpath: *u8, unitf: *u8) i32 = {
|
||||
// Compose pi's sep-unit at `unitf`: its byte-sorted DIRECT dependency
|
||||
// `.wwi`s, each tagged by its dotted path, then pi's own body under
|
||||
// //ww:module-reset. Compiler exports are self-contained for public type
|
||||
// facts; the linker separately retains the reachable archive closure.
|
||||
fn sepcomposeunit(g: *sepgraph, pi: i32, scratch: *u8,
|
||||
searchpath: *u8, unitf: *u8) i32 = {
|
||||
let u: i32 = os.open(pathstr(unitf), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644
|
||||
if (u < 0) {
|
||||
cerr("ww: cannot open unit\n");
|
||||
return -1;
|
||||
};
|
||||
let inset: []u8 = alloc([], g.n: u64)!;
|
||||
inset.len = g.n;
|
||||
let z: i32 = 0;
|
||||
for (z < g.n) { inset[z] = 0u8; z += 1; };
|
||||
sepmarkdeps(g, pi, inset);
|
||||
let oi: i32 = 0;
|
||||
for (oi < norder) {
|
||||
let dj: i32 = order[oi];
|
||||
if (dj != pi) {
|
||||
if (inset[dj] != 0u8) {
|
||||
let wwi: *u8 = sepfname(g, dj, scratch, ".wwi");
|
||||
let wb: *u8;
|
||||
let wn: u64;
|
||||
wb, wn = slurp(wwi);
|
||||
if (wb == nil) {
|
||||
cerr("ww: missing wwi\n");
|
||||
os.close(u);
|
||||
return -1;
|
||||
};
|
||||
let dm: str = "//ww:module ";
|
||||
if (!sepwriteall(u, dm.ptr, dm.len: u64)
|
||||
|| !sepwriteall(u, g.pkg[dj].path,
|
||||
cstrlen(g.pkg[dj].path))
|
||||
|| !sepwriteall(u, "\n".ptr, 1u64)
|
||||
|| !sepwriteall(u, wb, wn)
|
||||
|| !sepwriteall(u, "\n".ptr, 1u64)) {
|
||||
cerr("ww: cannot compose package unit\n");
|
||||
os.close(u);
|
||||
return -1;
|
||||
};
|
||||
};
|
||||
let k: i32 = 0;
|
||||
for (k < g.pkg[pi].ndeps) {
|
||||
let dj: i32 = g.pkg[pi].deps[k];
|
||||
let wwi: *u8 = sepfname(g, dj, scratch, ".wwi");
|
||||
let wb: *u8;
|
||||
let wn: u64;
|
||||
wb, wn = slurp(wwi);
|
||||
if (wb == nil) {
|
||||
cerr("ww: missing wwi\n");
|
||||
os.close(u);
|
||||
return -1;
|
||||
};
|
||||
oi += 1;
|
||||
let dm: str = "//ww:module ";
|
||||
if (!sepwriteall(u, dm.ptr, dm.len: u64)
|
||||
|| !sepwriteall(u, g.pkg[dj].path,
|
||||
cstrlen(g.pkg[dj].path))
|
||||
|| !sepwriteall(u, "\n".ptr, 1u64)
|
||||
|| !sepwriteall(u, wb, wn)
|
||||
|| !sepwriteall(u, "\n".ptr, 1u64)) {
|
||||
cerr("ww: cannot compose package unit\n");
|
||||
os.close(u);
|
||||
return -1;
|
||||
};
|
||||
k += 1;
|
||||
};
|
||||
let bv: expctx;
|
||||
bv.out = u;
|
||||
@@ -1429,14 +1405,14 @@ fn copyfileatomic(src: *u8, dst: *u8) i32 = {
|
||||
fn workdirstamptext(istest: i32, emitasm: i32) str = {
|
||||
if (istest != 0) {
|
||||
if (emitasm != 0) {
|
||||
return "ww workdir fmt 1 mode test asm 1\n";
|
||||
return "ww workdir fmt 2 mode test asm 1\n";
|
||||
};
|
||||
return "ww workdir fmt 1 mode test asm 0\n";
|
||||
return "ww workdir fmt 2 mode test asm 0\n";
|
||||
};
|
||||
if (emitasm != 0) {
|
||||
return "ww workdir fmt 1 mode build asm 1\n";
|
||||
return "ww workdir fmt 2 mode build asm 1\n";
|
||||
};
|
||||
return "ww workdir fmt 1 mode build asm 0\n";
|
||||
return "ww workdir fmt 2 mode build asm 0\n";
|
||||
};
|
||||
|
||||
fn stampmatches(path: *u8, want: str) bool = {
|
||||
@@ -1699,7 +1675,7 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
|
||||
};
|
||||
let needsexport: bool = (pi != root) || rootpackage;
|
||||
let needsarchive: bool = (pi != root) || rootpackage;
|
||||
if (sepcomposeunit(g, pi, scratch, order, norder, searchpath.ptr, cu) < 0) {
|
||||
if (sepcomposeunit(g, pi, scratch, searchpath.ptr, cu) < 0) {
|
||||
return 1;
|
||||
};
|
||||
let fresh: bool = false;
|
||||
|
||||
Reference in New Issue
Block a user