ref: 74d91a0021de012908cfdb35fb61a1473a376130
dir: /mbld/libs.myr/
use std use bio use "config" use "opts" use "types" pkg bld = const addlibs : (b : build#, \ sl : byte[:][:]#, \ libs : byte[:][:], \ incs : byte[:][:] -> bool) const builtlib : (b : build#, \ lt : myrtarg#, \ dep : byte[:][:], \ dyndep : byte[:][:] -> void) const scrapelib : (b : build#, \ targ : byte[:], \ libs : byte[:], \ incs : byte[:][:] -> void) ;; /* Keep in sync with parse/parse.h */ const Abiversion = 23 const builtlib = {b, mt, dep, dyndep var ldep, l, u l = std.fmt("lib{}.a", mt.name) u = std.fmt("lib{}.use", mt.name) ldep = std.mk([ .name=mt.name, .dir=std.pathcat(opt_objdir, mt.dir), .dep=dep, .dyndep=dyndep, .genuse=std.pathjoin([opt_objdir, mt.dir, u][:]), .genar=std.pathjoin([opt_objdir, mt.dir, l][:]), ]) std.slfree(l) std.slfree(u) for d : dep scrapelib(b, mt.name, d, mt.incpath) ;; std.htput(b.libs, mt.name, ldep) } const scrapelib = {b, targ, lib, incs var path, dep, dyndep, ldep var f, dir if std.hthas(b.libs, lib) -> void ;; (f, path, dir) = openlib(lib, targ, incs) match bio.getc(f) | `std.Ok 'U': /* ok */ | `std.Ok _: std.fput(1, "{}/{}: not a usefile\n", dir, lib) | `std.Err e: std.fatal("{}/{}: error reading: {}\n", dir, lib, e) ;; match bio.getbe32(f) | `std.Ok Abiversion: /* nothing: version matches. */ | `std.Ok v: std.fput(1, "{}/{}: mismatched abi {}\n", dir, lib, v) | `std.Err e: std.fatal("{}/{}: error reading: {}\n", dir, lib, e) ;; std.slfree(rdstr(f)) dep = [][:] dyndep = [][:] while true match bio.getc(f) | `std.Ok 'L': std.slpush(&dep, rdstr(f)) | `std.Ok 'X': std.slpush(&dyndep, rdstr(f)) | `std.Err e: std.fatal("{}: error reading {}\n", lib, e) | _: break ;; ;; bio.close(f) ldep = std.mk([ .name=lib, .dir=dir, .dep=dep, .dyndep=dyndep, .genuse="", .genar="", .mtime=std.tryv(std.fmtime(path), 0) ]) std.slfree(path) std.htput(b.libs, lib, ldep) for d : dep scrapelib(b, targ, d, incs) ;; } const openlib = {lib, targ, incs var path, libname path = "" libname = "" for p : incs libname = std.fmt("lib{}.use", lib) path = std.pathjoin([p, libname][:]) std.slfree(libname) if std.fisreg(path) match bio.open(path, bio.Rd) | `std.Ok file: -> (file, path, p) | `std.Err m: /* next */ ;; std.fatal("{}: {} does not exist in {j=, }\n", targ, lib, incs) ;; std.slfree(path) ;; std.fatal("{}: {} does not exist in {j= }\n", targ, lib, incs) } const addlibs = {b, sl, libs, incs var added, diradded, looped var dynlink var lo added = std.mkht() looped = std.mkht() diradded = std.mkht() lo = sl#.len dynlink = false for l : libs dynlink = addlib(b, sl, l, added, diradded, looped, dynlink) ;; for var i = 0; i < sl#[lo:].len/2; i++ std.swap(&sl#[lo+i], &sl#[sl#.len - i - 1]) ;; std.htfree(diradded) std.htfree(looped) std.htfree(added) -> dynlink } const addlib = {b, sl, lib, added, diradded, looped, dl var ar if std.hthas(looped, lib) std.fatal("{}: loop in deps\n", lib) ;; std.htput(looped, lib, void) match std.htget(b.libs, lib) | `std.None: std.slpush(sl, std.fmt("-l{}", lib)) dl = true | `std.Some ld: for l : ld.dep dl = addlib(b, sl, l, added, diradded, looped, dl) ;; for l : ld.dyndep dl = addlib(b, sl, l, added, diradded, looped, dl) ;; if !std.hthas(added, lib) if config.Directlib ar = std.fmt("lib{}.a", lib) std.slpush(sl, std.pathcat(ld.dir, ar)) std.slfree(ar) else std.slpush(sl, std.fmt("-l{}", lib)) ;; std.htput(added, lib, void) ;; if !config.Directlib && !std.hthas(diradded, ld.dir) std.htput(diradded, ld.dir, void) std.slpush(sl, std.fmt("-L{}", ld.dir)) ;; ;; std.htdel(looped, lib) -> dl } const rdstr = {f -> byte[:] var len var sl match bio.getbe32(f) | `std.Ok l: len = l sl = std.slalloc(len) | `std.Err e: std.fatal("error while reading string: {}", e) ;; bio.read(f, sl) -> sl }