From fcc5a878ae391b595578a77ac259a3d33898cea0 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 8 Jun 2016 03:21:53 +0200 Subject: [PATCH] Rather cleaner cfile implementation where you just give it a .c and a pile of .h files. --- first/ackbuilder.lua | 37 ++++++++++++++++++++----------------- first/build.lua | 17 +++++++++-------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/first/ackbuilder.lua b/first/ackbuilder.lua index 72b4392a3..850e22875 100644 --- a/first/ackbuilder.lua +++ b/first/ackbuilder.lua @@ -91,38 +91,40 @@ local function dirnames(collection) return o end -local function filenamesof(results) +local function filenamesof(targets, pattern) local f = {} - if results then - for _, r in pairs(results) do - if (type(r) == "string") then - f[#f+1] = r - elseif (type(r) == "table") then - if r.is and r.outs then + if targets then + for _, r in pairs(targets) do + if (type(r) == "table") and r.is then + if r.outs then for _, o in pairs(r.outs) do - f[#f+1] = o + if not pattern or o:find(pattern) then + f[#f+1] = o + end end end + else + error("list of targets contains something which isn't a target") end end end return f end -local function selectof(pattern, targets) +-- Selects all targets containing at least one output file that matches +-- the pattern. +local function selectof(targets, pattern) local o = {} for k, v in pairs(targets) do if v.is and v.outs then - local targetmatches = nil + local matches = false for _, f in pairs(v.outs) do - local matches = not not f:find(pattern) - if (targetmatches == nil) then - targetmatches = matches - elseif (targetmatches ~= matches) then - error("selectof() is matching only part of a target") + if f:find(pattern) then + matches = true + break end end - if targetmatches then + if matches then o[#o+1] = v end end @@ -379,7 +381,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(filenamesof(e.outs))) + e.environment:mkdirs(dirnames(e.outs)) local vars = { ins = e.ins, @@ -415,6 +417,7 @@ globals = { environment = environment, filenamesof = filenamesof, selectof = selectof, + uniquify = uniquify, } setmetatable(globals, { diff --git a/first/build.lua b/first/build.lua index 03077a414..95b6a64f6 100644 --- a/first/build.lua +++ b/first/build.lua @@ -29,7 +29,6 @@ definerule("normalrule", definerule("cfile", { srcs = { type="targets" }, - hdrs = { type="targets", default={} }, commands = { type="strings", default={ @@ -38,20 +37,23 @@ definerule("cfile", } }, function (e) - if (#e.srcs ~= 1) then + local csrcs = filenamesof(e.srcs, "%.c$") + if (#csrcs ~= 1) then error("you must have exactly one .c file") end - hdrpaths = {} - for _, t in pairs(e.hdrs) do + local htargets = selectof(e.srcs, "%.h$") + local hdrpaths = {} + for _, t in pairs(htargets) do hdrpaths[#hdrpaths+1] = "-I"..t.dir end + hdrpaths = uniquify(hdrpaths) - local outleaf = basename(filenamesof(e.srcs)[1]):gsub("%.c$", ".o") + local outleaf = basename(csrcs[1]):gsub("%.c$", ".o") return normalrule { name = e.name, - ins = {e.srcs[1], unpack(e.hdrs)}, + ins = {csrcs[1], unpack(htargets)}, outleaves = {outleaf}, label = e.label, commands = e.commands, @@ -78,8 +80,7 @@ cfile { cfile { name = "testfile-bar", - srcs = "bar.c", - hdrs = ":mkheader", + srcs = {"bar.c", ":mkheader"}, } --[[