cmd: honor package library roots in both stages
This commit is contained in:
@@ -33,11 +33,18 @@ static const char *usage =
|
||||
|
||||
static char *self_dir;
|
||||
|
||||
static const char *
|
||||
envpath(const char *name)
|
||||
{
|
||||
const char *p = getenv(name);
|
||||
return p && p[0] ? p : NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
toolpath(const char *envvar, const char *name)
|
||||
{
|
||||
const char *p = getenv(envvar);
|
||||
if (p && p[0]) return p;
|
||||
const char *p = envpath(envvar);
|
||||
if (p) return p;
|
||||
static char buf[1024];
|
||||
snprintf(buf, sizeof buf, "%s/%s", self_dir, name);
|
||||
return strdup(buf);
|
||||
@@ -1681,15 +1688,15 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
const char *c6 = toolpath("WW_W6C", "w6c");
|
||||
const char *a6 = toolpath("WW_W6A", "w6a");
|
||||
const char *l6 = toolpath("WW_W6L", "w6l");
|
||||
const char *libdir = getenv("WW_LIB");
|
||||
if (libdir == NULL || libdir[0] == 0) {
|
||||
const char *libdir = envpath("WW_LIB");
|
||||
if (libdir == NULL) {
|
||||
static char libbuf[1024];
|
||||
snprintf(libbuf, sizeof libbuf, "%s/../lib", self_dir);
|
||||
libdir = libbuf;
|
||||
}
|
||||
const char *srcdir = getenv("WW_SRCLIB");
|
||||
const char *srcdir = envpath("WW_SRCLIB");
|
||||
static char srcbuf[1024];
|
||||
if (srcdir == NULL || srcdir[0] == 0) {
|
||||
if (srcdir == NULL) {
|
||||
snprintf(srcbuf, sizeof srcbuf, "%s/../../lib", self_dir);
|
||||
if (access(srcbuf, 0) == 0) srcdir = srcbuf;
|
||||
else if (access("lib", 0) == 0) srcdir = "lib";
|
||||
@@ -2267,17 +2274,17 @@ do_version(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the standard module search path: cwd : <extra-includes> : $WW_LIB
|
||||
* source dir. The `extra` string is colon-separated -I dirs from argv. */
|
||||
/* Compose the standard module search path: cwd : <extra-includes> : selected
|
||||
* source library. The `extra` string is colon-separated -I dirs from argv. */
|
||||
static const char *
|
||||
search_path(const char *extra, char *buf, size_t bufsz)
|
||||
{
|
||||
const char *libdir = getenv("WW_SRCLIB");
|
||||
const char *libdir = envpath("WW_SRCLIB");
|
||||
static char libbuf[1024];
|
||||
if (libdir == NULL || libdir[0] == 0) {
|
||||
libdir = getenv("WW_LIB");
|
||||
if (libdir == NULL) {
|
||||
libdir = envpath("WW_LIB");
|
||||
}
|
||||
if (libdir == NULL || libdir[0] == 0) {
|
||||
if (libdir == NULL) {
|
||||
snprintf(libbuf, sizeof libbuf, "%s/../../lib", self_dir);
|
||||
if (access(libbuf, 0) == 0) libdir = libbuf;
|
||||
else if (access("lib", 0) == 0) libdir = "lib";
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user