shithub: mc

ref: 5f46919fc6a471d9a75bb25fae64aecefc9ec864
dir: /mbld/main.myr/

View raw version
use std
use regex

use "build.use"
use "clean.use"
use "config.use"
use "deps.use"
use "install.use"
use "opts.use"
use "parse.use"
use "test.use"
use "types.use"
use "util.use"
use "syssel.use"

const main = {args : byte[:][:]
	var b : bld.build#
	var mt : bld.myrtarg
	var cleanfirst
	var dumponly
	var targname
	var bintarg
	var cmd 
	var tags

	dumponly = false
	cleanfirst = false
	cmd = std.optparse(args, &[
		.argdesc = "[inputs...]",
		.opts = [
			[.opt='c', .desc="clean before building"],
			[.opt='T', .desc="list all available targets"],
			[.opt='t', .arg="tag", .desc="build with specified systag"],
			[.opt='S', .desc="generate assembly when building"],
			[.opt='d', .desc="dump debugging information for mbld"],
			[.opt='I', .arg="inc", .desc="add 'inc' to your include path"],
			[.opt='R', .arg="root", .desc="install into 'root'"],
			[.opt='b', .arg="bin", .desc="compile binary named 'bin' from inputs"],
			[.opt='l', .arg="lib", .desc="compile lib named 'lib' from inputs"],
			[.opt='r', .arg="rt", .desc="link against runtime 'rt' instead of default"],
			[.opt='C', .arg="mc", .desc="compile with 'mc' instead of the default compiler"],
			[.opt='M', .arg="mu", .desc="merge uses with 'mu' instead of the default muse"],
		][:]
	])

	targname = ""
	tags = [][:]
	bld.initopts()
	for opt in cmd.opts
		match opt
		| ('T', ""):	dumponly = true
		| ('S', ""):	bld.opt_genasm = true
		| ('c', ""):	cleanfirst = true
		| ('I', arg):	bld.opt_incpaths = std.slpush(bld.opt_incpaths, arg)
		| ('R', arg):	bld.opt_instroot = arg
		| ('t', tag):	tags = std.slpush(tags, tag)
		| ('b', arg):
			targname = arg
			bintarg = true
		| ('l', arg):
			targname = arg
			bintarg = false
		| ('r', arg):
			if std.sleq(arg, "none")
				bld.opt_runtime = ""
			else
				bld.opt_runtime = arg
			;;
		/*
		internal undocumented args; used by compiler suite for
		building with an uninstalled compiler.
		*/
		| ('d', arg): bld.opt_debug = true
		| ('C', arg): bld.opt_mc = arg
		| ('M', arg): bld.opt_muse = arg
		| _:	std.die("unreachable\n")

		;;
	;;

	b = mkbuild(tags)
	if targname.len != 0
		mt = [
			.name=targname,
			.inputs=cmd.args,
			.runtime=bld.opt_runtime,
			.incpath=bld.opt_incpaths,
			.libdeps=[][:]
		]
		if cleanfirst
			bld.cleanmyr(b, &mt)
		;;
		if bintarg
			bld.buildbin(b, &mt, true)
		else
			bld.buildlib(b, &mt)
		;;
	elif dumponly
		findproj(b, "bld.proj")
		bld.load(b)
		for t in b.all
			std.put("{}\n", t)
		;;
	else
		findproj(b, "bld.proj")
		bld.load(b)
		/*bld.configure()*/
		/* default: buildall */
		if cleanfirst
			bld.cleanall(b)
		;;
		if cmd.args.len == 0
			bld.buildall(b)
		else
			for c in cmd.args
				match c
				| "all":	bld.buildall(b)
				| "gen":	bld.genall(b)
				| "clean":	bld.cleanall(b)
				| "install":	bld.install(b)
				| "uninstall":	bld.uninstall(b)
				| "test":	bld.test(b)
				| target:	bld.buildtarg(b, target)
				;;
			;;
		;;
	;;
}

const mkbuild = {tags
	var b

	b = std.zalloc()
	b.targs = std.mkht(std.strhash, std.streq)
	b.gensrc = std.mkht(std.strhash, std.streq)
	b.built = std.mkht(std.strhash, std.streq)
	b.sysattrs = std.mkht(std.strhash, std.streq)
	bld.addsysattrs(b, tags)
	-> b
}

const findproj = {b, bldfile
	if !findbase(b, bldfile) || !std.chdir(b.basedir)
		std.fatal("could not find {}\n", bldfile)
	;;
	bld.setdir(b, "")
}

const findbase = {b, file
	var p, bld, dir

	dir = std.getcwd()
	while !std.sleq(dir, "/")
		bld = std.pathcat(dir, file)
		if std.fexists(bld)
			std.put("project base {}:\n", dir)
			b.basedir = dir
			b.bldfile = bld
			-> true
		;;
		p = std.pathcat(dir, "..")
		std.slfree(dir)
		dir = p
	;;
	-> false
}