shithub: mc

ref: 0f469133aed044569f4d6ae9efc1d961124c05cd
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 dumponly
	var targname
	var bintarg
	var cmd 
	var libpath
	var tags

	dumponly = false
	cmd = std.optparse(args, &[
		.argdesc = "[inputs...]",
		.opts = [
			[.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
		| ('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")

		;;
	;;
	if bld.opt_instroot.len > 0 && !std.sleq(bld.opt_instroot, "none")
		libpath = std.pathcat(bld.opt_instroot, config.Libpath)
		bld.opt_incpaths = std.slpush(bld.opt_incpaths, libpath)
	;;

	match regex.compile("^\\s*use\\s+((\\<\\S+\\>)|\"(\\S+)\").*")
	| `std.Ok re:	bld.usepat = re
	| `std.Fail f:	std.fatal("Failed to compile use pattern regex\n")
	;;

	b = mkbuild(tags)
	if targname.len != 0
		mt = [
			.name=targname,
			.inputs=cmd.args,
			.runtime=bld.opt_runtime,
			.incpath=bld.opt_incpaths,
			.libdeps=[][:]
		]
		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 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)
			b.basedir = dir
			b.bldfile = bld
			-> true
		;;
		p = std.pathcat(dir, "..")
		std.slfree(dir)
		dir = p
	;;
	-> false
}