shithub: mc

ref: 5d986e613a56c158f3cdab000a12a75da2f6b28b
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"

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

	dumponly = false
	cmd = std.optparse(args, &[
		.argdesc = "[inputs...]",
		.opts = [
			[.opt='t', .desc="list all available targets"],
			[.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 = ""
	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
		| ('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()
	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.build(b, target)
				;;
			;;
		;;
	;;
}

const mkbuild = {
	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
}

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
}