From 605651776e94c4a09ac2f35aa51d92f4cfdfff02 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 12 Jun 2016 20:59:43 +0200 Subject: [PATCH] We can build a real program now! --- first/ackbuilder.lua | 119 +++++++++++++++++++++++++++---------------- first/build.lua | 38 +++++++------- h/build.lua | 31 +++++++++++ util/ack/build.lua | 89 ++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 62 deletions(-) create mode 100644 h/build.lua create mode 100644 util/ack/build.lua diff --git a/first/ackbuilder.lua b/first/ackbuilder.lua index 866412848..525e6051c 100644 --- a/first/ackbuilder.lua +++ b/first/ackbuilder.lua @@ -57,44 +57,6 @@ local function concatpath(...) return p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/") end -local function basename(filename) - local _, _, b = filename:find("^.*/([^/]*)$") - if not b then - return filename - end - return b -end - -local function basenames(collection) - local o = {} - for _, s in pairs(collection) do - local b = basename(s) - if (b ~= "") then - o[#o+1] = b - end - end - return o -end - -local function dirname(filename) - local _, _, b = filename:find("^(.*)/[^/]*$") - if not b then - return "" - end - return b -end - -local function dirnames(collection) - local o = {} - for _, s in pairs(collection) do - local b = dirname(s) - if (b ~= "") then - o[#o+1] = b - end - end - return o -end - local function filenamesof(targets, pattern) local f = {} if targets then @@ -107,6 +69,8 @@ local function filenamesof(targets, pattern) end end end + elseif (type(r) == "string") then + f[#f+1] = r else error(string.format("list of targets contains a %s which isn't a target", type(r))) @@ -116,8 +80,75 @@ local function filenamesof(targets, pattern) return f end +local function dotocollection(collection, callback) + if (type(collection) == "string") then + return callback(collection) + elseif collection.is then + local files = filenamesof(collection.outs) + if (#files ~= 1) then + error("inputs with more than one output need to be in a list") + end + return callback(files[1]) + end + + local o = {} + for _, s in pairs(collection) do + if s.is then + for _, b in pairs(dotocollection(filenamesof(s), callback)) do + o[#o+1] = b + end + else + local b = callback(s) + if (b ~= "") then + o[#o+1] = b + end + end + end + return o +end + +local function abspath(collection) + return dotocollection(collection, + function(filename) + return concatpath(posix.getcwd(), filename) + end + ) +end + +local function basename(collection) + return dotocollection(collection, + function(filename) + local _, _, b = filename:find("^.*/([^/]*)$") + if not b then + return filename + end + return b + end + ) +end + +local function dirname(collection) + return dotocollection(collection, + function(filename) + local _, _, b = filename:find("^(.*)/[^/]*$") + if not b then + return "" + end + return b + end + ) +end + +local function fpairs(collection) + if (type(collection) == "string") or collection.is then + return tpairs({collection}) + end + + return pairs(filenamesof(collection)) +end + -- Selects all targets containing at least one output file that matches --- the pattern. +-- the pattern (or all, if the pattern is nil). local function selectof(targets, pattern) local o = {} for k, v in pairs(targets) do @@ -237,7 +268,7 @@ local function loadtarget(targetname) } targets[targetname] = target else - local _, _, filepart, targetpart = targetname:find("^([^:]*):(%w+)$") + local _, _, filepart, targetpart = targetname:find("^([^:]*):([%w-_]+)$") if not filepart or not targetpart then error(string.format("malformed target name '%s'", targetname)) end @@ -398,7 +429,7 @@ definerule("simplerule", function (e) e.environment:rule(filenamesof(e.ins), e.outs) e.environment:label(cwd..":"..e.name, " ", e.label or "") - e.environment:mkdirs(dirnames(e.outs)) + e.environment:mkdirs(dirname(e.outs)) local vars = inherit(e.vars, { ins = e.ins, @@ -419,20 +450,20 @@ definerule("simplerule", ----------------------------------------------------------------------------- globals = { + abspath = abspath, asstring = asstring, basename = basename, - basenames = basenames, concatpath = concatpath, - cwd = cwd, + cwd = function() return cwd end, definerule = definerule, dirname = dirname, - dirnames = dirnames, emit = emit, environment = environment, filenamesof = filenamesof, inherit = inherit, selectof = selectof, startswith = startswith, + fpairs = fpairs, uniquify = uniquify, } setmetatable(globals, diff --git a/first/build.lua b/first/build.lua index 47faa7f56..35821b484 100644 --- a/first/build.lua +++ b/first/build.lua @@ -1,20 +1,25 @@ +local function objdir(e) + return concatpath("$(OBJDIR)", cwd(), e.name) +end + definerule("normalrule", { ins = { type="targets" }, outleaves = { type="strings" }, label = { type="string", optional=true }, + objdir = { type="string", optional=true }, commands = { type="strings" }, vars = { type="table", default={} }, }, function (e) - local objpath = "$(OBJDIR)/"..e.name + local dir = e.objdir or objdir(e) local realouts = {} for k, v in pairs(e.outleaves) do - realouts[k] = concatpath(objpath, v) + realouts[k] = concatpath(dir, v) end local vars = inherit(e.vars, { - dir = objpath + dir = dir }) local result = simplerule { @@ -25,7 +30,7 @@ definerule("normalrule", commands = e.commands, vars = vars, } - result.dir = objpath + result.dir = dir return result end ) @@ -34,10 +39,11 @@ definerule("cfile", { srcs = { type="targets" }, deps = { type="targets", default={} }, + cflags = { type="strings", default={} }, commands = { type="strings", default={ - "$(CC) -c -o %{outs[1]} %{ins[1]} %{hdrpaths}" + "$(CC) -c -o %{outs[1]} %{ins[1]} %{hdrpaths} %{cflags}" }, } }, @@ -68,7 +74,8 @@ definerule("cfile", label = e.label, commands = e.commands, vars = { - hdrpaths = hdrpaths + hdrpaths = hdrpaths, + cflags = e.cflags, } } end @@ -87,7 +94,7 @@ definerule("bundle", function (e) local outleaves = {} local commands = {} - for _, f in pairs(filenamesof(e.srcs)) do + for _, f in fpairs(e.srcs) do local localf = basename(f) outleaves[#outleaves+1] = localf commands[#commands+1] = "cp "..f.." %{dir}/"..localf @@ -107,6 +114,7 @@ definerule("clibrary", { srcs = { type="targets" }, deps = { type="targets", default={} }, + cflags = { type="strings", default={} }, commands = { type="strings", default={ @@ -124,12 +132,16 @@ definerule("clibrary", local hsrcs = filenamesof(e.srcs, "%.h$") local ins = {} - for _, csrc in pairs(csrcs) do + for _, csrc in fpairs(csrcs) do local n = basename(csrc):gsub("%.%w*$", "") ins[#ins+1] = cfile { name = e.name.."/"..n, srcs = {csrc, unpack(hsrcs)}, deps = e.deps, + cflags = { + "-I"..cwd(), + unpack(e.cflags) + }, } end @@ -180,13 +192,3 @@ definerule("cprogram", end ) -cprogram { - name = "test", - srcs = { - "foo.c", - }, - deps = { - "modules:string" - } -} - diff --git a/h/build.lua b/h/build.lua new file mode 100644 index 000000000..25b7e3324 --- /dev/null +++ b/h/build.lua @@ -0,0 +1,31 @@ +normalrule { + name = "em_path", + ins = {}, + outleaves = { "em_path.h" }, + commands = { + "echo '#define TMP_DIR \"$(ACK_TEMP_DIR)\"' > %{outs}", + "echo '#define EM_DIR \"$(PREFIX)\"' >> %{outs}", + "echo '#define ACK_PATH \"share/ack/descr\"' >> %{outs}", + } +} + +bundle { + name = "emheaders", + srcs = { + "./em_*.h", + ":em_path", + } +} + +normalrule { + name = "local", + ins = {}, + outleaves = { "local.h" }, + commands = { + "echo '#define VERSION 3' > %{outs}", + "echo '#define ACKM \"$(DEFAULT_PLATFORM)\"' >> %{outs}", + "echo '#define BIGMACHINE 1' >> %{outs}", + "echo '#define SYS_5' >> %{outs}", + } +} + diff --git a/util/ack/build.lua b/util/ack/build.lua new file mode 100644 index 000000000..3e1b77167 --- /dev/null +++ b/util/ack/build.lua @@ -0,0 +1,89 @@ +cprogram { + name = "mktables", + srcs = { "./mktables.c" }, +} + +normalrule { + name = "tables", + outleaves = { "dmach.c", "intable.c" }, + ins = { + ":mktables", + "lib/descr/fe", + }, + commands = { + "(cd %{dir} && %{abspath(ins[1])} lib)" + } +} + +cprogram { + name = "ack", + srcs = { + "./*.c", + "./*.h", + ":tables", + }, + deps = { + "h:emheaders", + "h:local", + } +} + +--[[ +D := util/ack + +define util-ack-makeheaders-rule +$(eval g := $(OBJDIR)/$D/dmach.c $(OBJDIR)/$D/intable.c) +$(wordlist 2, $(words $g), $g): $(firstword $g) +$(firstword $g): $(util-ack-mktables) + @echo MKTABLES + @mkdir -p $(OBJDIR)/$D + $(hide) cd $(OBJDIR)/$D && $(util-ack-mktables) $(INSDIR)/share + +$(eval CLEANABLES += $g) +endef + +define build-ack-impl + $(call reset) + $(call cfile, $D/mktables.c) + $(call cprogram, $(OBJDIR)/$D/mktables) + $(eval util-ack-mktables := $o) + + $(call reset) + $(eval cflags += -I$D) + $(call cfile, $D/list.c) + $(call cfile, $D/data.c) + $(call cfile, $D/main.c) + $(call cfile, $D/scan.c) + $(call cfile, $D/svars.c) + $(call cfile, $D/trans.c) + $(call cfile, $D/util.c) + + $(call cfile, $D/rmach.c) + $(call dependson, $(INCDIR)/em_path.h) + + $(call cfile, $D/run.c) + $(call cfile, $D/grows.c) + + $(call cfile, $D/files.c) + $(call dependson, $(INCDIR)/em_path.h) + + $(eval $(util-ack-makeheaders-rule)) + $(call cfile, $(OBJDIR)/$D/dmach.c) + $(call cfile, $(OBJDIR)/$D/intable.c) + + $(call cprogram, $(BINDIR)/ack) + $(call installto, $(INSDIR)/bin/ack) + $(eval ACK := $o) + + $(call reset) + $(eval q := lib/descr/fe) + $(call installto, $(PLATIND)/descr/fe) + $(eval $(ACK): $o) + + $(call reset) + $(eval q := $D/ack.1.X) + $(call installto, $(INSDIR)/share/man/man1/ack.1) +endef + +$(eval $(build-ack-impl)) +--]]