shithub: mc

ref: 99cc92c31eadabe470d781af2f5fd4410594e10e
dir: /mbld/main.myr/

View raw version
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='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)
		| ('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:])
			| "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(std.strhash, std.streq)
	b.proc = std.mkht(std.inthash, std.inteq)
	b.targs = std.mkht(std.strhash, std.streq)
	b.tags = std.mkht(std.strhash, std.streq)
	b.deps = std.mk([
		.targs = std.mkht(std.strhash, std.streq),
		.gen = std.mkht(std.strhash, std.streq),
		.leaves = [][:],
		.nodes = [][:],
	])
	bld.addsysattrs(b, tags)
	-> b
}

const findproj = {b
	var dir

	dir = std.getcwd()
	while dir.len > 0 && !std.sleq(dir, "/")
		if std.chdir(dir) && std.fexists("bld.proj")
			b.basedir = dir
			break
		;;
		dir = std.dirname(dir)
	;;
	if dir.len > 0 && std.sleq(b.basedir, "/")
		std.fatal("could not find bld.proj\n")
	;;
}

const show = {b, targs
	var k = std.htkeys(b.targs)
	std.put("{j=\n}\n", k)
	-> true
}