From 1978867fd280ed7d7b9a41f2523fbfc800026cca Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 19 Jun 2016 08:55:02 +0200 Subject: [PATCH] Add ninja support. It works so much better than make. --- first/ackbuilder.lua | 164 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 137 insertions(+), 27 deletions(-) diff --git a/first/ackbuilder.lua b/first/ackbuilder.lua index e919a8d90..66f6f7027 100644 --- a/first/ackbuilder.lua +++ b/first/ackbuilder.lua @@ -394,40 +394,81 @@ end -- DEFAULT RULES -- ----------------------------------------------------------------------------- -function environment:rule(name, ins, outs) - emit(".INTERMEDIATE:", name, "\n") - for i = 1, #ins do - emit(name..":", ins[i], "\n") - end - for i = 1, #outs do - emit(outs[i]..":", name, "\n") +local function install_make_environment() + emit("hide = @\n") + function environment:rule(name, ins, outs) + emit(".INTERMEDIATE:", name, "\n") + for i = 1, #ins do + emit(name..":", ins[i], "\n") + end + for i = 1, #outs do + emit(outs[i]..":", name, "\n") + end + emit(name..":\n") + + local dirs = uniquify(dirname(outs)) + if (#dirs > 0) then + emit("\t@mkdir -p", dirs, "\n") + end end - emit(name..":\n") - local dirs = uniquify(dirname(outs)) - if (#dirs > 0) then - emit("\t@mkdir -p", dirs, "\n") + function environment:phony(name, ins, outs) + emit(".PHONY:", name, "\n") + self:rule(name, ins, outs) end -end -function environment:phony(name, ins, outs) - emit(".PHONY:", name, "\n") - self:rule(name, ins, outs) -end + function environment:label(...) + local s = table.concat({...}, " ") + emit("\t@echo", s, "\n") + end -function environment:label(...) - local s = table.concat({...}, " ") - emit("\t@echo", s, "\n") -end + function environment:exec(commands) + for _, s in ipairs(commands) do + emit("\t$(hide)", s, "\n") + end + end -function environment:exec(commands) - for _, s in ipairs(commands) do - emit("\t$(hide)", s, "\n") + function environment:endrule() + emit("\n") end end -function environment:endrule() +local function install_ninja_environment() + emit("rule build\n") + emit(" command = $command\n") emit("\n") + + local function unmake(collection) + return dotocollection(collection, + function(s) + return s:gsub("%$%b()", + function(expr) + return "${"..expr:sub(3, -2).."}" + end + ) + end + ) + end + + function environment:rule(name, ins, outs) + if (#outs == 0) then + emit("build", name, ": phony", unmake(ins), "\n") + else + emit("build", name, ": phony", unmake(outs), "\n") + emit("build", unmake(outs), ": build", unmake(ins), "\n") + end + end + + function environment:label(...) + end + + function environment:exec(commands) + emit(" command =", table.concat(unmake(commands), " && "), "\n") + end + + function environment:endrule() + emit("\n") + end end definerule("simplerule", @@ -498,6 +539,51 @@ definerule("installable", -- MAIN PROGRAM -- ----------------------------------------------------------------------------- +local function parse_arguments(argmap, arg) + local i = 1 + local files = {} + + local function unrecognisedarg(arg) + argmap[" unrecognised"](arg) + end + + while (i <= #arg) do + local o = arg[i] + local op + + if (o:byte(1) == 45) then + -- This is an option. + if (o:byte(2) == 45) then + -- ...with a -- prefix. + o = o:sub(3) + local fn = argmap[o] + if not fn then + unrecognisedarg("--"..o) + end + i = i + fn(arg[i+1], arg[i+2]) + else + -- ...without a -- prefix. + local od = o:sub(2, 2) + local fn = argmap[od] + if not fn then + unrecognisedarg("-"..od) + end + op = o:sub(3) + if (op == "") then + i = i + fn(arg[i+1], arg[i+2]) + else + fn(op) + end + end + else + files[#files+1] = o + end + i = i + 1 + end + + argmap[" files"](files) +end + globals = { abspath = abspath, asstring = asstring, @@ -528,8 +614,32 @@ setmetatable(globals, } ) -emit("hide=@\n") -for _, file in ipairs({...}) do - loadbuildfile(file) +do + local environment_type = install_make_environment + parse_arguments( + { + ["make"] = function() + environment_type = install_make_environment + return 1 + end, + + ["ninja"] = function() + environment_type = install_ninja_environment + return 1 + end, + + [" unrecognised"] = function(arg) + error(string.format("unrecognised argument '%s'", arg)) + end, + + [" files"] = function(files) + environment_type() + for _, f in ipairs(files) do + loadbuildfile(f) + end + end + }, + {...} + ) end -- 2.34.1