From 5ec06a73ebd7897416c86d142a1d55dec32c7984 Mon Sep 17 00:00:00 2001 From: Ori Bernstein Date: Fri, 23 Feb 2018 11:31:56 -0800 Subject: Add mpkg. --- mbld/bld.sub | 43 ++++++++++++-- mbld/main.myr | 182 --------------------------------------------------------- mbld/mbld.myr | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ mbld/mpkg.myr | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ mbld/opts.myr | 4 ++ mbld/parse.myr | 65 ++++++++++++++++++--- mbld/types.myr | 5 +- 7 files changed, 421 insertions(+), 198 deletions(-) delete mode 100644 mbld/main.myr create mode 100644 mbld/mbld.myr create mode 100644 mbld/mpkg.myr diff --git a/mbld/bld.sub b/mbld/bld.sub index 5f6b129..7bd5370 100644 --- a/mbld/bld.sub +++ b/mbld/bld.sub @@ -1,10 +1,45 @@ bin mbld = + mbld.myr + + # probed (or hard coded) system config + config.myr + config+plan9-x64.myr + + # Currently, mbld doesn't add all deps transitively. + # Until this gets fixed, we need to list all dependent + # libraries here explicitly. + lib bld + lib ../lib/sys:sys + lib ../lib/std:std + lib ../lib/bio:bio + lib ../lib/regex:regex + lib ../lib/thread:thread +;; + +bin mpkg = + mpkg.myr + + # probed (or hard coded) system config + config.myr + config+plan9-x64.myr + + # See above + lib ../mbld:bld + lib ../lib/sys:sys + lib ../lib/std:std + lib ../lib/bio:bio + lib ../lib/http:http + lib ../lib/regex:regex + lib ../lib/thread:thread + lib ../lib/fileutil:fileutil +;; + +lib bld = build.myr cpufeatures+posixy-x64.s deps.myr libs.myr install.myr - main.myr opts.myr parse.myr subtest.myr @@ -13,13 +48,11 @@ bin mbld = types.myr util.myr - # probed (or hard coded) system config + # probed (or hard coded) system config. config.myr config+plan9-x64.myr - # Currently, mbld doesn't add all deps transitively. - # Until this gets fixed, we need to list all dependent - # libraries here explicitly. + # See above lib ../lib/sys:sys lib ../lib/std:std lib ../lib/bio:bio diff --git a/mbld/main.myr b/mbld/main.myr deleted file mode 100644 index 3ca9b07..0000000 --- a/mbld/main.myr +++ /dev/null @@ -1,182 +0,0 @@ -use std -use regex -use thread - -use "build" -use "config" -use "deps" -use "install" -use "opts" -use "parse" -use "test" -use "types" -use "util" -use "syssel" - -const main = {args : byte[:][:] - var b : bld.build# - var targname - var runsrc - var path - var tmp - var cmd - var tags - var pid - var ok, r - - cmd = std.optparse(args, &[ - .argdesc = "[inputs...]", - .opts = [ - [.opt='j', .arg="jobs", .desc="build with at most 'jobs' jobs"], - [.opt='t', .arg="tag", .desc="build with specified systag"], - [.opt='T', .arg="tag", .desc="build with only the specified systag"], - [.opt='S', .desc="generate assembly when building"], - [.opt='I', .arg="inc", .desc="add 'inc' to your include path"], - [.opt='R', .arg="runsrc", .desc="source to compile and run"], - [.opt='B', .arg="base", .desc="install into 'base'"], - [.opt='b', .arg="bin", .desc="compile binary 'bin' from inputs"], - [.opt='r', .arg="rt", .desc="link against runtime 'rt'"], - [.opt='o', .arg="dir", .desc="output directory"], - ][:] - ]) - - tags = [][:] - runsrc = "" - targname = "" - ok = true - - bld.initopts() - for opt : cmd.opts - match opt - | ('S', ""): bld.opt_genasm = true - | ('I', arg): std.slpush(&bld.opt_incpaths, arg) - | ('B', arg): bld.opt_instbase = arg - | ('t', tag): std.slpush(&tags, tag) - | ('T', tag): std.slpush(&bld.opt_alltags, tag) - | ('j', arg): bld.opt_maxproc = std.getv(std.intparse(arg), 1) - | ('R', arg): runsrc = arg - | ('o', arg): bld.opt_objdir = arg - | ('b', arg): targname = arg - | ('r', arg): bld.opt_runtime = arg - | _: std.die("unreachable\n") - ;; - ;; - path = std.pathcat(bld.opt_instbase, config.Libpath) - std.slpush(&bld.opt_incpaths, path) - - for (e, v) : config.Env - std.setenv(e, v) - ;; - - b = mkbuild(tags) - if targname.len != 0 - ok = buildimm(b, targname, cmd.args) - elif runsrc.len != 0 - bld.opt_silent = true - tmp = std.mktemppath("runmyr") - ok = buildimm(b, tmp, [runsrc][:]) - if ok - pid = runcmd(tmp, cmd.args) - match std.wait(pid) - | `std.Wsuccess: ok = true - | _: ok = false - ;; - ;; - std.remove(tmp) - else - findproj(b) - bld.load(b) - bld.deps(b) - bld.testdeps(b) - bld.resolve(b) - /* default: buildall */ - if cmd.args.len == 0 - ok = bld.buildtarg(b, "all") - else - match cmd.args[0] - | "clean": r = bld.clean(b) - | "install": r = bld.install(b) - | "uninstall": r = bld.uninstall(b) - | "test": r = bld.test(b, cmd.args[1:]) - | "bench": r = bld.bench(b, cmd.args[1:]) - | "list": r = show(b, cmd.args[1:]) - | _: - ok = true - for target : cmd.args - r = ok && bld.buildtarg(b, target) - ;; - ;; - ;; - ;; - if !ok - std.exit(1) - ;; -} - -const buildimm = {b, targ, inputs - var mt : bld.myrtarg - - mt = [ - .name=targ, - .inputs=inputs, - .runtime=bld.opt_runtime, - .incpath=bld.opt_incpaths, - .libdeps=[][:] - ] - bld.opt_objdir = "" - std.slpush(&b.all, "__out__") - std.htput(b.targs, "__out__", `bld.Bin &mt) - bld.deps(b) - bld.resolve(b) - -> bld.buildtarg(b, "all") -} - -const runcmd = {bin, args - var sl - - sl = std.sldup([bin][:]) - -> bld.run(std.sljoin(&sl, args), "") -} - -const mkbuild = {tags - var b - - b = std.zalloc() - b.libs = std.mkht() - b.proc = std.mkht() - b.targs = std.mkht() - b.tags = std.mkht() - b.deps = std.mk([ - .targs = std.mkht(), - .gen = std.mkht(), - .leaves = [][:], - .nodes = [][:], - ]) - bld.addsysattrs(b, tags) - -> b -} - -const findproj = {b - var dir - - dir = std.getcwd() - while dir.len > 0 && !std.eq(dir, "/") - if std.chdir(dir) && std.fexists("bld.proj") - b.basedir = dir - break - ;; - dir = std.dirname(dir) - ;; - if dir.len > 0 && std.eq(b.basedir, "/") - std.fatal("could not find bld.proj\n") - ;; -} - -const show = {b, targs - var k - - k = std.htkeys(b.targs) - std.put("{j=\n}\n", k) - std.slfree(k) - -> true -} diff --git a/mbld/mbld.myr b/mbld/mbld.myr new file mode 100644 index 0000000..c2724d1 --- /dev/null +++ b/mbld/mbld.myr @@ -0,0 +1,160 @@ +use std +use regex +use thread +use bld + +use "config" + +const main = {args : byte[:][:] + var b : bld.build# + var targname + var runsrc + var path + var tmp + var cmd + var tags + var pid + var ok, r + + cmd = std.optparse(args, &[ + .argdesc = "[inputs...]", + .opts = [ + [.opt='j', .arg="jobs", .desc="build with at most 'jobs' jobs"], + [.opt='t', .arg="tag", .desc="build with specified systag"], + [.opt='T', .arg="tag", .desc="build with only the specified systag"], + [.opt='S', .desc="generate assembly when building"], + [.opt='I', .arg="inc", .desc="add 'inc' to your include path"], + [.opt='R', .arg="runsrc", .desc="source to compile and run"], + [.opt='B', .arg="base", .desc="install into 'base'"], + [.opt='b', .arg="bin", .desc="compile binary 'bin' from inputs"], + [.opt='r', .arg="rt", .desc="link against runtime 'rt'"], + [.opt='o', .arg="dir", .desc="output directory"], + [.opt='p', .arg="proj", .desc="build from project 'proj'"], + [.opt='D', .arg="dir", .desc="store deps in 'dir'"], + ][:] + ]) + + tags = [][:] + runsrc = "" + targname = "" + ok = true + + bld.initopts() + for opt : cmd.opts + match opt + | ('S', ""): bld.opt_genasm = true + | ('I', arg): std.slpush(&bld.opt_incpaths, arg) + | ('B', arg): bld.opt_instbase = arg + | ('t', tag): std.slpush(&tags, tag) + | ('T', tag): std.slpush(&bld.opt_alltags, tag) + | ('j', arg): bld.opt_maxproc = std.getv(std.intparse(arg), 1) + | ('R', arg): runsrc = arg + | ('o', arg): bld.opt_objdir = arg + | ('b', arg): targname = arg + | ('r', arg): bld.opt_runtime = arg + | ('p', arg): std.chdir(arg) + | ('D', dir): bld.opt_depsdir = dir + | _: std.die("unreachable\n") + ;; + ;; + path = std.pathcat(bld.opt_instbase, config.Libpath) + std.slpush(&bld.opt_incpaths, path) + + for (e, v) : config.Env + std.setenv(e, v) + ;; + + b = bld.mkbuild(tags, true) + if targname.len != 0 + ok = buildimm(b, targname, cmd.args) + elif runsrc.len != 0 + bld.opt_silent = true + tmp = std.mktemppath("runmyr") + ok = buildimm(b, tmp, [runsrc][:]) + if ok + pid = runcmd(tmp, cmd.args) + match std.wait(pid) + | `std.Wsuccess: ok = true + | _: ok = false + ;; + ;; + std.remove(tmp) + else + findproj(b) + bld.load(b) + bld.deps(b) + bld.testdeps(b) + bld.resolve(b) + /* default: buildall */ + if cmd.args.len == 0 + ok = bld.buildtarg(b, "all") + else + match cmd.args[0] + | "clean": r = bld.clean(b) + | "install": r = bld.install(b) + | "uninstall": r = bld.uninstall(b) + | "test": r = bld.test(b, cmd.args[1:]) + | "bench": r = bld.bench(b, cmd.args[1:]) + | "list": r = show(b, cmd.args[1:]) + | _: + ok = true + for target : cmd.args + r = ok && bld.buildtarg(b, target) + ;; + ;; + ;; + ;; + if !ok + std.exit(1) + ;; +} + +const buildimm = {b, targ, inputs + var mt : bld.myrtarg + + mt = [ + .name=targ, + .inputs=inputs, + .runtime=bld.opt_runtime, + .incpath=bld.opt_incpaths, + .libdeps=[][:] + ] + bld.opt_objdir = "" + std.slpush(&b.all, "__out__") + std.htput(b.targs, "__out__", `bld.Bin &mt) + bld.deps(b) + bld.resolve(b) + -> bld.buildtarg(b, "all") +} + +const runcmd = {bin, args + var sl + + sl = std.sldup([bin][:]) + -> bld.run(std.sljoin(&sl, args), "") +} + +const findproj = {b + var dir + + dir = std.getcwd() + while dir.len > 0 && !std.eq(dir, "/") + if std.chdir(dir) && std.fexists("bld.proj") + b.basedir = dir + break + ;; + dir = std.dirname(dir) + ;; + if dir.len > 0 && std.eq(b.basedir, "/") + std.fatal("could not find bld.proj\n") + ;; +} + +const show = {b, targs + var k + + k = std.htkeys(b.targs) + std.put("{j=\n}\n", k) + std.slfree(k) + -> true +} diff --git a/mbld/mpkg.myr b/mbld/mpkg.myr new file mode 100644 index 0000000..5de5296 --- /dev/null +++ b/mbld/mpkg.myr @@ -0,0 +1,160 @@ +use std +use bio +use regex +use thread +use fileutil +use http +use bld + +const main = {args : byte[:][:] + var b, repo, cmd, tags, update + + cmd = std.optparse(args, &[ + .argdesc = "[inputs...]", + .noargs = true, + .opts = [ + [.opt='u', .desc="update all dependencies"], + [.opt='t', .arg="tag", .desc="apply specified systag"], + [.opt='p', .arg="proj", .desc="fetch packages for project 'proj'"], + [.opt='D', .arg="dir", .desc="store deps in 'dir'"], + ][:] + ]) + + tags = [][:] + update = false + bld.initopts() + for opt : cmd.opts + match opt + | ('u', ""): update = true + | ('t', tag): std.slpush(&tags, tag) + | ('p', dir): std.chdir(dir) + | ('D', dir): bld.opt_depsdir = dir + | _: std.die("unreachable\n") + ;; + ;; + b = bld.mkbuild(tags, false) + findproj(b) + repo = loadrepo(b) + bld.load(b) + fetch(b, repo, update) +} + +const fetch = {b, repo, update + var deps + + deps = [][:] + std.mkdir(".deps", 0o755) + for name : b.all + match bld.gettarg(b.targs, name) + | `bld.Bin bt: fetchdeps(b, repo, bt, update, &deps) + | `bld.Lib lt: fetchdeps(b, repo, lt, update, &deps) + | _: /* skip */ + ;; + ;; + std.slfree(deps) +} + +const fetchdeps = {b, repo, targ, update, deps + for (depdir, dep, _) : targ.libdeps + if !std.hasprefix(depdir, ".deps") + continue + ;; + std.put("{}: fetch {} => {}\n", targ.name, dep, depdir) + std.slpush(deps, dep) + match std.htget(repo, dep) + | `std.None: std.fatal("unknown dep {}\n", dep) + | `std.Some ("git", url): getgit(dep, url) + | `std.Some ("hg", url): gethg(dep, url) + | `std.Some ("http", url): gethttp(dep, url) + | `std.Some (schema, url): std.fatal("unknown schema '{}' for '{}'\n", schema, url) + ;; + ;; +} + +const findproj = {b + var dir + + dir = std.getcwd() + while dir.len > 0 && !std.eq(dir, "/") + if std.chdir(dir) && std.fexists("bld.proj") + b.basedir = dir + break + ;; + dir = std.dirname(dir) + ;; + if dir.len > 0 && std.eq(b.basedir, "/") + std.fatal("could not find bld.proj\n") + ;; +} + +const loadrepo = {b + var home, repo + + repo = std.mkht() + home = fileutil.homedir() + if !readlocalrepo(repo, b.basedir) && !readlocalrepo(repo, home) + std.fatal("could not find repo\n") + ;; + -> repo +} + +const readlocalrepo = {repo, dir + var sp, spbuf : byte[:][3] + var fd, path + + path = std.pathcat(dir, "bld.repo") + if !std.fexists(path) + std.slfree(path) + -> false + ;; + + match bio.open(path, bio.Rd) + | `std.Ok f: fd = f + | `std.Err e: std.fatal("could not open repo {}: {}\n", path, e) + ;; + + for ln : bio.byline(fd) + ln = std.strstrip(ln) + if std.decode(ln) == '#' + continue + ;; + + sp = std.bstrtok(spbuf[:], ln) + if sp.len != 3 + std.fatal("malformed repo line {}\n", ln) + ;; + + std.htput(repo, std.sldup(sp[0]), (std.sldup(sp[1]), std.sldup(sp[2]))) + ;; + + std.slfree(path) + -> true +} + +const getgit = {name, repo + var out + + out = std.pathcat(".deps", name) + if !std.fexists(out) + std.run(["git", "clone", repo, out][:]) + std.run(["mpkg", "-p", out][:]) + std.run(["mbld", "-p", out][:]) + ;; + std.slfree(out) +} + +const gethg = {name, repo + var out + + out = std.pathcat(".deps", name) + if !std.fexists(out) + std.run(["hg", "clone", repo, out][:]) + std.run(["mpkg", "-p", out][:]) + std.run(["mbld", "-p", out][:]) + ;; + std.slfree(out) +} + +const gethttp = {name, repo + std.fatal("http blobs not yet implemented\n") +} diff --git a/mbld/opts.myr b/mbld/opts.myr index b82921f..40cac75 100644 --- a/mbld/opts.myr +++ b/mbld/opts.myr @@ -21,6 +21,7 @@ pkg bld = var opt_maxproc : std.size var opt_debug : bool var opt_silent : bool + var opt_depsdir : byte[:] /* undocumented/unsupported opts */ var opt_mc : byte[:] @@ -60,6 +61,7 @@ var opt_objdir = "obj" var opt_genasm = false var opt_silent = false var opt_maxproc = 1 +var opt_depsdir = "" const initopts = { var si @@ -92,6 +94,8 @@ const initopts = { opt_mc = std.getenvv("MYR_MC", "6m") opt_muse = std.getenvv("MYR_MUSE", "muse") opt_runtime = std.getenvv("MYR_RT", "") + opt_depsdir = std.pathcat(std.getcwd(), ".deps") + match std.getenv("MYR_MCFLAGS") | `std.Some s: opt_mcflags = std.strtok(s) | `std.None: /* ok */ diff --git a/mbld/parse.myr b/mbld/parse.myr index 41cf1c7..6a5e323 100644 --- a/mbld/parse.myr +++ b/mbld/parse.myr @@ -6,6 +6,7 @@ use "opts" use "syssel" pkg bld = + const mkbuild : (tags : byte[:][:], resolve : bool -> build#) const load : (b : build# -> bool) $noret const failparse : (p : parser#, msg : byte[:], args : ... -> void) ;; @@ -35,23 +36,45 @@ type parser = struct targsel : syssel((byte[:], targ))# ;; +const mkbuild = {tags, resolve + var b + + b = std.zalloc() + b.libs = std.mkht() + b.proc = std.mkht() + b.targs = std.mkht() + b.tags = std.mkht() + b.resolve = resolve + b.deps = std.mk([ + .targs = std.mkht(), + .gen = std.mkht(), + .leaves = [][:], + .nodes = [][:], + ]) + bld.addsysattrs(b, tags) + -> b +} + const load = {b var ok, sel var targs sel = mksyssel(b, "mbld", 0, "mbld") - ok = loadall(b, "bld.proj", "", sel) + ok = loadall(b, "bld.proj", "", sel, true) targs = sysselfin(sel) for (name, targ) : targs std.slpush(&b.all, name) + std.put("targ name: {}\n", name) std.htput(b.targs, name, targ) ;; - if ok - ok = sortdeps(b) + if b.resolve + if ok + ok = sortdeps(b) + ;; + std.slfree(targs) ;; - std.slfree(targs) -> ok } @@ -107,7 +130,7 @@ const getdeps = {b, parent, targname } /* recursively load all bld.{proj,sub} files in project */ -const loadall = {b, path, dir, sel +const loadall = {b, path, dir, sel, isroot var p : parser# var subbld, subproj, ok var curbase @@ -130,16 +153,16 @@ const loadall = {b, path, dir, sel build root. */ if std.fexists(subbld) - loadall(b, subbld, sub, sel) + loadall(b, subbld, sub, sel, false) /* bld.proj reroots the project -- @/ is relative to the most recent bld.proj in the heirarchy. */ - elif std.fexists(sub) + elif std.fexists(subproj) curbase = b.basedir b.basedir = sub - loadall(b, subproj, sub, sel) + loadall(b, subproj, sub, sel, false) b.basedir = curbase else std.fatal("could not open {} or {} \n", subbld, subproj) @@ -147,6 +170,26 @@ const loadall = {b, path, dir, sel std.slfree(subbld) std.slfree(subproj) ;; + if isroot + match std.diropen(opt_depsdir) + | `std.Err _: /* no deps to load */ + | `std.Ok depdir: + for ent : std.byentry(depdir) + subbld = std.pathjoin([opt_depsdir, ent, "bld.sub"][:]) + subproj = std.pathjoin([opt_depsdir, ent, "bld.proj"][:]) + if std.fexists(subbld) + loadall(b, subbld, std.dirname(subbld), sel, false) + elif std.fexists(subproj) + curbase = b.basedir + b.basedir = std.dirname(subproj) + loadall(b, subproj, std.dirname(subproj), sel, false) + b.basedir = curbase + ;; + std.slfree(subbld) + std.slfree(subproj) + ;; + ;; + ;; freeparser(p) -> ok } @@ -778,7 +821,11 @@ const libpath = {p, libpath std.fatal("libdep {} missing library after ':'\n") ;; /* absolute path */ - if std.hasprefix(libpath, "@/") || std.hasprefix(libpath, "@:") + if std.hasprefix(libpath, "@deps/") + dir = std.pathcat(opt_depsdir, libpath[6:idx]) + lib = std.sldup(libpath[idx+1:]) + targ = std.pathcat(".deps", libpath[6:]) + elif std.hasprefix(libpath, "@/") || std.hasprefix(libpath, "@:") dir = std.sldup(libpath[2:idx]) lib = std.sldup(libpath[idx+1:]) targ = std.sldup(libpath[2:]) diff --git a/mbld/types.myr b/mbld/types.myr index 03bb151..8637b74 100644 --- a/mbld/types.myr +++ b/mbld/types.myr @@ -7,6 +7,8 @@ pkg bld = tags : std.htab(byte[:], (int, int, int))# libs : std.htab(byte[:], libdep#)# deps : depgraph# + all : byte[:][:] + targs : std.htab(byte[:], targ)# /* in flight builds */ queue : node#[:] @@ -14,11 +16,10 @@ pkg bld = fail : bool /* build params */ - all : byte[:][:] - targs : std.htab(byte[:], targ)# prefix : byte[:] system : byte[:] arch : byte[:] + resolve : bool ;; -- cgit v1.1