shithub: mc

Download patch

ref: a882c392dcde4b86d96b6b9e920c9d8e37f0aaad
parent: 77ab32804f07545e7a3fcc2b40b5b7b5565091e8
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Apr 12 17:58:13 EDT 2015

More work towards single process subbuilds.

    Put things into a hash table instead of a list.

--- a/build.myr
+++ b/build.myr
@@ -9,21 +9,24 @@
 use "subdir.use"
 
 pkg bld =
-	const buildall	: (p : build# -> bool)
-	const genall	: (p : build# -> bool)
-	const build	: (p : build#, target : byte[:] -> bool)
-	const buildbin	: (p : build#, bt : myrtarg#, addsrc : bool -> void)
-	const buildlib	: (p : build#, lt : myrtarg# -> void)
+	const buildall	: (b : build# -> bool)
+	const genall	: (b : build# -> bool)
+	const build	: (b : build#, target : byte[:] -> bool)
+	const buildbin	: (b : build#, bt : myrtarg#, addsrc : bool -> void)
+	const buildlib	: (b : build#, lt : myrtarg# -> void)
 ;;
 
-const buildall = {p
-	for t in p.targs
+const buildall = {b
+	var targs
+
+	targs = std.htgetv(b.targs, "", [][:])
+	for t in targs
 		match t
-		| `Bin bt:	buildbin(p, bt, false)
-		| `Lib lt:	buildlib(p, lt)
+		| `Bin bt:	buildbin(b, bt, false)
+		| `Lib lt:	buildlib(b, lt)
 		| `Test tt:	/* build on 'mbld test' by default */
-		| `Gen gt:	genfiles(p, gt)
-		| `Sub subs:	subdirs(p, subs, `std.None)
+		| `Gen gt:	genfiles(b, gt)
+		| `Sub subs:	subdirs(b, subs, `std.None)
 		| `Man m:	/* nothing needed */
 		;;
 	;;
@@ -30,8 +33,11 @@
 	-> true
 }
 
-const genall = {p
-	for t in p.targs
+const genall = {b
+	var targs
+
+	targs = std.htgetv(b.targs, "", [][:])
+	for t in targs
 		match t
 		| `Gen gt: run(gt.cmd, "")
 		| _:	/* skip */
@@ -41,24 +47,25 @@
 	-> true
 }
 
-const build = {p, targ
-	var found
+const build = {b, targ
+	var found, targs
 
 	found = false
-	for t in p.targs
+	targs = std.htgetv(b.targs, "", [][:])
+	for t in targs
 		match t
 		| `Bin bt:
 			if std.sleq(bt.name, targ)
-				buildbin(p, bt, false)
+				buildbin(b, bt, false)
 			;;
 		| `Lib lt:
 			if std.sleq(lt.name, targ)
-				buildlib(p, lt)
+				buildlib(b, lt)
 				found = true
 			;;
 		| `Test tt:
 			if std.sleq(tt.name, targ)
-				buildbin(p, tt, false)
+				buildbin(b, tt, false)
 				found = true
 			;;
 		| `Gen gt:
@@ -69,7 +76,7 @@
 			;;
 		| `Sub subs:
 			found = true
-			subdirs(p, subs, `std.Some targ)
+			subdirs(b, subs, `std.Some targ)
 		| `Man m:
 			found = true
 			/* nothing needed */
@@ -81,7 +88,7 @@
 	-> found
 }
 
-const buildbin = {p, targ, addsrc
+const buildbin = {b, targ, addsrc
 	var dg, src
 
 	if targ.built
@@ -92,17 +99,17 @@
 			targ.incpath = std.slpush(targ.incpath, ".")
 		;;
 		for l in targ.libdeps
-			build(p, l)
+			build(b, l)
 		;;
 	;;
 	std.put("%s...\n", targ.name)
-	if !myrdeps(p, targ, false, false, addsrc, &dg)
+	if !myrdeps(b, targ, false, false, addsrc, &dg)
 		std.fatal(1, "Could not load dependencies for %s\n", targ.name)
 	;;
 	if !std.hthas(dg.deps, targ.name)
 		std.fatal(1, "no input files for %s\n", targ.name)
 	;;
-	if builddep(p, &dg, targ.name, targ.incpath) || !freshlibs(targ, dg.libs)
+	if builddep(b, &dg, targ.name, targ.incpath) || !freshlibs(targ, dg.libs)
 		src = std.htkeys(dg.sources)
 		linkbin(&dg, targ.name, src, targ.ldscript, targ.runtime, targ.incpath, targ.libdeps)
 		std.slfree(src)
@@ -119,7 +126,7 @@
 	-> false
 }
 
-const buildlib = {p, targ
+const buildlib = {b, targ
 	var archive
 	var u, l
 	var dg
@@ -131,14 +138,14 @@
 	lib = targ.name
 	std.put("lib%s.a...\n", lib)
 	archive = std.fmt("lib%s.a", lib)
-	if !myrdeps(p, targ, true, false, false, &dg)
+	if !myrdeps(b, targ, true, false, false, &dg)
 		std.fatal(1, "Could not load dependencies for %s\n", lib)
 	;;
 	if !std.hthas(dg.deps, lib)
 		std.fatal(1, "no target declared for %s\n", lib)
 	;;
-	u = builddep(p, &dg, targ.name, targ.incpath)
-	l = builddep(p, &dg, archive, targ.incpath)
+	u = builddep(b, &dg, targ.name, targ.incpath)
+	l = builddep(b, &dg, archive, targ.incpath)
 	if  u || l || !freshlibs(targ, dg.libs)
 		src = std.htkeys(dg.sources)
 		mergeuse(&dg, lib, src, targ.incpath)
@@ -149,7 +156,7 @@
 	targ.built = true
 }
 
-const genfiles = {p, gt
+const genfiles = {b, gt
 	for f in gt.out
 		if !std.fexists(f)
 			run(gt.cmd, "")
@@ -158,7 +165,7 @@
 	;;
 }
 
-const builddep = {p, dg, out, incs
+const builddep = {b, dg, out, incs
 	var stale
 
 	stale = false
@@ -170,11 +177,11 @@
 	match std.htget(dg.deps, out)
 	| `std.Some deps:
 		for d in deps
-			if builddep(p, dg, d, incs)
+			if builddep(b, dg, d, incs)
 				stale = true
 			;;
 			if !std.fexists(d)
-				match std.htget(p.gensrc, d)
+				match std.htget(b.gensrc, d)
 				| `std.Some gt:	run(gt.cmd, "")
 				| `std.None:	std.fatal(1, "no input file %s\n", d)
 				;;
--- a/clean.myr
+++ b/clean.myr
@@ -8,19 +8,22 @@
 use "types.use"
 
 pkg bld =
-	const cleanall	: (p : build# -> bool)
-	const clean	: (p : build#, targ : byte[:] -> bool)
+	const cleanall	: (b : build# -> bool)
+	const clean	: (b : build#, targ : byte[:] -> bool)
 ;;
 
-const cleanall = {p
-	for t in p.targs
+const cleanall = {b
+	var targs
+
+	targs = std.htgetv(b.targs, "", [][:])
+	for t in targs
 		match t
 		| `Bin bt:
-			cleanup(p, bt, bt.inputs, true)
+			cleanup(b, bt, bt.inputs, true)
 		| `Lib lt:
-			cleanup(p, lt, lt.inputs, true)
+			cleanup(b, lt, lt.inputs, true)
 		| `Test tt:
-			cleanup(p, tt, tt.inputs, true)
+			cleanup(b, tt, tt.inputs, true)
 		| `Gen gt:
 			for f in gt.out
 				if !gt.durable && std.remove(f)
@@ -28,7 +31,7 @@
 				;;
 			;;
 		| `Sub subs:
-			subdirs(p, subs, `std.None)
+			subdirs(b, subs, `std.None)
 		| `Man m:
 		;;
 	;;
@@ -35,24 +38,27 @@
 	-> true
 }
 
-const clean = {p, targ
-	for t in p.targs
+const clean = {b, targ
+	var targs
+
+	targs = std.htgetv(b.targs, "", [][:])
+	for t in targs
 		match t
 		| `Bin bt:
 			if std.sleq(bt.name, targ)
-				cleanup(p, bt, bt.inputs, true)
+				cleanup(b, bt, bt.inputs, true)
 			;;
 		| `Lib lt:
 			if std.sleq(lt.name, targ)
-				cleanup(p, lt, lt.inputs, true)
+				cleanup(b, lt, lt.inputs, true)
 			;;
 		| `Test tt:
 			if std.sleq(tt.name, targ)
-				cleanup(p, tt, tt.inputs, true)
+				cleanup(b, tt, tt.inputs, true)
 			;;
 		| `Gen gt:
 		| `Sub subs:
-			subdirs(p, subs, `std.Some targ)
+			subdirs(b, subs, `std.Some targ)
 		| `Man m:
 		;;
 	;;
--- a/install.myr
+++ b/install.myr
@@ -14,19 +14,20 @@
 	const uninstall	: (p : build#	-> bool)
 ;;
 
-const install = {p
-	buildall(p)
-	-> movetargs(p, false)
+const install = {b
+	buildall(b)
+	-> movetargs(b, false)
 }
 
-const uninstall = {p
-	-> movetargs(p, true)
+const uninstall = {b
+	-> movetargs(b, true)
 }
 
-const movetargs = {p, delete
-	var libarchive
+const movetargs = {b, delete
+	var libarchive, targs
 
-	for t in p.targs
+	targs = std.htgetv(b.targs, "", [][:])
+	for t in targs
 		match t
 		| `Bin bt:
 			movefile(delete, bt.name, opt_instroot, opt_destdir, "bin", 0o755)
@@ -38,7 +39,7 @@
 		| `Gen gt:
 			/* nothing to do (?) */
 		| `Sub subs:
-			subdirs(p, subs, `std.None)
+			subdirs(b, subs, `std.None)
 		| `Man mans:
 			/* FIXME: figure out man section by number */
 			for m in mans
--- a/main.myr
+++ b/main.myr
@@ -56,6 +56,7 @@
 	| `std.Fail f:	std.fatal(1, "Failed to compile use pattern regex\n")
 	;;
 
+	b = mkbuild()
 	if targname.len != 0
 		mt = [
 			.name=targname,
@@ -65,15 +66,12 @@
 			.ldscript=bld.opt_ldscript,
 			.libdeps=[][:]
 		]
-		b = mkbuild()
 		if bintarg
 			bld.buildbin(b, &mt, true)
 		else
 			bld.buildlib(b, &mt)
 		;;
-		std.free(b)
 	else
-		b = mkbuild()
 		bld.load(b, bld.opt_bldfile)
 		/*bld.configure()*/
 		/* default: buildall */
@@ -99,6 +97,7 @@
 	var b
 
 	b = std.zalloc()
+	b.targs = std.mkht(std.strhash, std.streq)
 	b.gensrc = std.mkht(std.strhash, std.streq)
 	-> b
 }
--- a/parse.myr
+++ b/parse.myr
@@ -14,23 +14,57 @@
 	data	: byte[:]
 	rest	: byte[:]
 	fname	: byte[:]
+	fdir	: byte[:]	/* directory relative to base */
 	line	: int
+
+	/* extracted data for further parsing */
+	subdirs	: byte[:][:]
 ;;
 
 const load = {b, path
+	-> loadall(b, path, "")
+}
+
+
+const loadall = {b, path, dir
 	var p : parser#
+	var subpath, subbld, ok
 
+	p = mkparser(path, dir)
+	ok = bld.parse(b, p, "")
+	for s in p.subdirs
+		subpath = std.pathcat(p.fdir, s)
+		subbld = std.pathcat(subpath, "bldfile")
+		loadall(b, subbld, subpath)
+		std.slfree(subpath)
+		std.slfree(subbld)
+	;;
+	freeparser(p)
+	-> ok
+}
+
+const mkparser = {path, dir
+	var p
+
 	p = std.zalloc()
 	p.line = 1
 	p.fname = std.sldup(path)
+	p.fdir = std.sldup(dir)
 	match std.slurp(path)
 	| `std.Ok d:	p.data = d
-	| `std.Fail _:	std.fatal(1, "could not open file 'bldfile'\n")
+	| `std.Fail _:	std.fatal(1, "could not open '%s'\n", path)
 	;;
 	p.rest = p.data
-	-> bld.parse(b, p)
+	-> p
 }
 
+const freeparser = {p
+	std.slfree(p.fname)
+	std.slfree(p.fdir)
+	std.slfree(p.subdirs)
+	std.slfree(p.data)
+	std.free(p)
+}
 
 const failparse = {p, msg, args : ...
 	var buf : byte[1024]
@@ -43,7 +77,7 @@
 	std.exit(1)
 }
 
-const parse = {b, p
+const parse = {b, p, path
 	while true
 		skipspace(p)
 		if !target(b, p)
@@ -54,9 +88,8 @@
 	if p.rest.len > 0
 		failparse(p, "junk in file near %s\n", p.rest[:std.min(p.rest.len, 10)])
 		-> false
-	else
-		-> true
 	;;
+	-> true
 }
 
 const target = {b, p
@@ -65,8 +98,8 @@
 	| `std.Some "test":	testtarget(b, p)
 	| `std.Some "lib":	libtarget(b, p)
 	| `std.Some "gen":	gentarget(b, p)
-	| `std.Some "sub":	subtarget(b, p)
 	| `std.Some "man":	mantarget(b, p)
+	| `std.Some "sub":	subtarget(b, p)
 	| `std.Some targtype:	failparse(p, "unknown targtype type %s\n", targtype)
 	| `std.None:	-> false
 	;;
@@ -75,27 +108,27 @@
 
 /* bintarget: myrtarget */
 const bintarget = {b, p
-	b.targs = std.slpush(b.targs, `Bin myrtarget(p, "bin"))
+	addtarg(b, p.fdir, `Bin myrtarget(p, "bin"))
 }
 
 /* testtarget: myrtarget */
 const testtarget = {b, p
-	b.targs = std.slpush(b.targs, `Test myrtarget(p, "test"))
+	addtarg(b, p.fdir, `Test myrtarget(p, "test"))
 }
 
 /* libtarget: myrtarget */
 const libtarget = {b, p
-	b.targs = std.slpush(b.targs, `Lib myrtarget(p, "lib"))
+	addtarg(b, p.fdir, `Lib myrtarget(p, "lib"))
 }
 
 /* subtarget : anontarget */
 const subtarget = {b, p
-	b.targs = std.slpush(b.targs, `Sub anontarget(p, "sub"))
+	p.subdirs = std.sljoin(p.subdirs, anontarget(p, "sub"))
 }
 
 /* mantarget: anontarget */
 const mantarget = {b, p
-	b.targs = std.slpush(b.targs, `Man anontarget(p, "man"))
+	addtarg(b, p.fdir, `Man anontarget(p, "man"))
 }
 
 /* gentarget: wordlist {attrs} = wordlist ;; */
@@ -152,7 +185,7 @@
 	for o in outlist
 		std.htput(b.gensrc, o, gt)
 	;;
-	b.targs = std.slpush(b.targs, `Gen gt)
+	addtarg(b, p.fdir, `Gen gt)
 }
 
 /*
@@ -443,3 +476,10 @@
 	-> c
 }
 
+const addtarg = {b, d, t
+	var tl
+
+	tl = std.htgetv(b.targs, d, [][:])
+	tl = std.slpush(tl, t)
+	std.htput(b.targs, d, tl)
+}
--- a/test.myr
+++ b/test.myr
@@ -12,24 +12,25 @@
 use "config.use"
 
 pkg bld =
-	const test	: (p : build# -> void)
+	const test	: (b : build# -> void)
 ;;
 
-const test = {p
-	var hasdir, ok, bin
+const test = {b
+	var hasdir, ok, bin, targs
 
 	/* no implicit tests to run */
 	ok = true
 	hasdir = std.fexists("test")
+	targs = std.htgetv(b.targs, "", [][:])
 	if hasdir
-		for it in p.targs
-			match it
+		for tt in targs
+			match tt
 			| `Bin bt:
-				if !dotest(p, bt, ok)
+				if !dotest(b, bt, ok)
 					ok = false
 				;;
 			| `Lib lt:
-				if !dotest(p, lt, ok)
+				if !dotest(b, lt, ok)
 					ok = false
 				;;
 			| _:	/* ignore */
@@ -36,7 +37,7 @@
 			;;
 		;;
 	;;
-	for `Test t in p.targs
+	for `Test t in targs
 		for s in t.incpath
 			if std.sleq(".", s)
 				goto founddot
@@ -45,7 +46,7 @@
 		t.incpath = std.slpush(t.incpath, std.sldup("."))
 
 :founddot
-		buildbin(p, t, false)
+		buildbin(b, t, false)
 		bin = std.strcat("./", t.name)
 		if !runtest(bin)
 			ok = false
--- a/types.myr
+++ b/types.myr
@@ -4,19 +4,11 @@
 	type build = struct
 		cmd	: byte[:][:]
 		/* build params */
-		targs	: targ[:]
+		targs	: std.htab(byte[:], targ[:])#	/* dir => target mapping */
 		gensrc	: std.htab(byte[:], gentarg#)#
 		prefix	: byte[:]
 		system	: byte[:]
 		arch	: byte[:]
-	;;
-
-	type parser = struct
-		/* parse input */
-		data	: byte[:]
-		rest	: byte[:]
-		fname	: byte[:]
-		line	: int
 	;;