ref: ce10ff586027ea9dcac0f074b16a23f9888cc6df
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)
;;
const Abiversion = 19
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
}