cmd: honor package library roots in both stages

This commit is contained in:
2026-08-12 15:18:46 +09:00
parent bb71b31f81
commit 5a2e4ba28d
2 changed files with 94 additions and 41 deletions

View File

@@ -9,7 +9,7 @@
//
// Tool paths default to siblings of $0 so a fresh build runs out of
// out/bin/. WW_W6C / WW_W6A / WW_W6L select exact executable paths.
// Source-library and runtime-library overrides are not yet supported.
// WW_SRCLIB selects package sources and WW_LIB selects runtime artifacts.
package main;
@@ -162,13 +162,19 @@ fn owncstr(s: str) *u8 = {
return b.ptr;
};
fn toolpath(selfdir: *u8, envvar: str, name: str) *u8 = {
match (os.getenv(envvar)) {
fn envpath(name: str) *u8 = {
match (os.getenv(name)) {
case let p: str => {
if (p.len != 0) { return owncstr(p); };
};
case void => void;
};
return nil;
};
fn toolpath(selfdir: *u8, envvar: str, name: str) *u8 = {
let p: *u8 = envpath(envvar);
if (p != nil) { return p; };
return joinpathlit(selfdir, name);
};
@@ -285,6 +291,11 @@ fn importpathform(name: *u8, namelen: u64) *u8 = {
// `foo/foo.ha` fallback; a module IS the directory).
fn locatein(dir: *u8, dirlen: u64,
pathform: *u8, pflen: u64, isdir: *i32, wantdir: i32) *u8 = {
let tail: u64 = 1u64; // NUL for the directory form
if (wantdir == 0i32) { tail = 4u64; }; // ".ww" + NUL
if (dirlen + 1u64 + pflen + tail > os.PATH_MAX: u64) {
return nil;
};
let buf: []u8 = alloc([], (os.PATH_MAX: u64))!;
let off: u64 = 0u64;
let i: u64 = 0u64;
@@ -2031,13 +2042,18 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
let c6: *u8 = toolpath(selfdir, "WW_W6C", "w6c_ww");
let a6: *u8 = toolpath(selfdir, "WW_W6A", "w6a_ww");
let l6: *u8 = toolpath(selfdir, "WW_W6L", "w6l_ww");
let dotdotlib: []u8 = alloc([], (os.PATH_MAX: u64))!;
dotdotlib.len = os.PATH_MAX;
{
let off: u64 = cstrinto(dotdotlib.ptr, 0u64, selfdir);
off = strinto(dotdotlib.ptr, off, "/../../lib");
cstrseal(dotdotlib.ptr, off);
let libdir: *u8 = envpath("WW_LIB");
if (libdir == nil) { libdir = joinpathlit(selfdir, "../lib"); };
let toolsrcdir: *u8 = envpath("WW_SRCLIB");
if (toolsrcdir == nil) {
let candidate: *u8 = joinpathlit(selfdir, "../../lib");
if (os.access(pathstr(candidate), 0i32) == 0) {
toolsrcdir = candidate;
} else { if (os.access("lib", 0i32) == 0) {
toolsrcdir = "lib\0".ptr;
} else {
toolsrcdir = libdir;
}; };
};
let srcd: []u8 = alloc([], (os.PATH_MAX: u64))!;
@@ -2144,12 +2160,21 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
if (staleall && invalidateworkdirunits(scratch) != 0) { return 1; };
};
let libwwrt: []u8 = alloc([], (os.PATH_MAX: u64))!;
libwwrt.len = os.PATH_MAX;
{
let off: u64 = cstrinto(libwwrt.ptr, 0u64, selfdir);
off = strinto(libwwrt.ptr, off, "/../lib/libwwrt.a");
cstrseal(libwwrt.ptr, off);
let rtpaths: []*u8 = alloc([], 2u64)!;
rtpaths.len = 2;
let nrt: i32 = 1;
let havearchive: bool = false;
if (cstrlen(libdir) + 1u64 + "libwwrt.a".len: u64 + 1u64
<= os.PATH_MAX: u64) {
rtpaths[0] = joinpathlit(libdir, "libwwrt.a");
if (os.access(pathstr(rtpaths[0]), 0i32) == 0) {
havearchive = true;
};
};
if (!havearchive) {
nrt = 2;
rtpaths[0] = joinpathlit(selfdir, "../obj/rt/start.o");
rtpaths[1] = joinpathlit(selfdir, "../obj/rt/syscall.o");
};
let pkgslot: []seppkg = alloc([], SEP_MAXPKG: u64)!;
@@ -2175,7 +2200,7 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
let contextroot: *u8 = entry;
if (entryisdir == 0) { contextroot = srcd.ptr; };
products[producti].context = sepcontextfor(g, contextroot,
incs, dotdotlib.ptr);
incs, toolsrcdir);
if (products[producti].context < 0) { return 1; };
products[producti].root = sepfindoraddvariant(g, rootpath, entry,
entryisdir, products[producti].variant,
@@ -2192,11 +2217,11 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
// it distinct. The linker receives the same support archive closure.
if (istest != 0) {
let td: i32 = 0;
let tp: *u8 = locateimport(dotdotlib.ptr, "test".ptr,
let tp: *u8 = locateimport(toolsrcdir, "test".ptr,
"test".len: u64, &td);
if (tp != nil) {
g.supportcontext = sepcontextfor(g, dotdotlib.ptr, nil,
dotdotlib.ptr);
g.supportcontext = sepcontextfor(g, toolsrcdir, nil,
toolsrcdir);
if (g.supportcontext < 0) { return 1; };
let collision: bool = false;
producti = 0;
@@ -2629,8 +2654,8 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
let nlink: i32 = 0;
if (septopovisit(g, root, linkorder, &nlink,
linkstack, 0) < 0) { return 1; };
// argv: 3 fixed + closure + libwwrt + joined flags + nil.
let total: i32 = 3 + nlink + 1 + nldirs + nllibs + 1;
// argv: 3 fixed + closure + runtime inputs + joined flags + nil.
let total: i32 = 3 + nlink + nrt + nldirs + nllibs + 1;
let largv: []*u8 = alloc([], total: u64)!;
largv.len = total;
largv[0] = "w6l\0".ptr;
@@ -2655,7 +2680,12 @@ fn buildonesepimpl(selfdir: *u8, src: *u8, entryisdir: i32,
pos += 1;
li -= 1;
};
largv[pos] = libwwrt.ptr; pos += 1;
let ri: i32 = 0;
for (ri < nrt) {
largv[pos] = rtpaths[ri];
pos += 1;
ri += 1;
};
let k: i32 = 0;
for (k < nldirs) {
let n: u64 = cstrlen(ldirs[k]);
@@ -2817,9 +2847,26 @@ fn arenadupcstr(src: *u8, plen: u64) *u8 = {
return buf.ptr;
};
// resolvemodule search-path order: "." : <incs> : <selfdir>/../../lib
// resolvemodule search-path order: "." : <incs> : selected source library.
fn buildsearchpath(selfdir: *u8, incs: *u8) *u8 = {
let buf: []u8 = alloc([], (os.PATH_MAX: u64) * 2u64)!;
let libdir: *u8 = envpath("WW_SRCLIB");
if (libdir == nil) { libdir = envpath("WW_LIB"); };
if (libdir == nil) {
let candidate: *u8 = joinpathlit(selfdir, "../../lib");
if (os.access(pathstr(candidate), 0i32) == 0) {
libdir = candidate;
} else { if (os.access("lib", 0i32) == 0) {
libdir = "lib\0".ptr;
} else {
libdir = joinpathlit(selfdir, "../lib");
}; };
};
let need: u64 = 1u64 + 1u64 + cstrlen(libdir) + 1u64;
if (incs != nil && incs[0u64] != 0u8) {
need += cstrlen(incs) + 1u64;
};
let buf: []u8 = alloc([], need)!;
buf.len = need: i32;
let off: u64 = 0u64;
buf[off] = 46u8; off += 1u64; // '.'
if (incs != nil) {
@@ -2829,8 +2876,7 @@ fn buildsearchpath(selfdir: *u8, incs: *u8) *u8 = {
};
};
buf[off] = 58u8; off += 1u64;
off = cstrinto(buf.ptr, off, selfdir);
off = strinto(buf.ptr, off, "/../../lib");
off = cstrinto(buf.ptr, off, libdir);
cstrseal(buf.ptr, off);
return buf.ptr;
};
@@ -3038,7 +3084,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let isdir: i32 = 0;
let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir);
if (resolved == nil) {
cerr("ww build: cannot find module\n");
cerrpath("ww build: cannot find module ", src, "\n");
return 1;
};
if (packageonly != 0 && isdir == 0) {
@@ -3225,7 +3271,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let isdir: i32 = 0;
let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir);
if (resolved == nil) {
cerr("ww run: cannot find module\n");
cerrpath("ww run: cannot find module ", src, "\n");
return 1;
};