Rather cleaner cfile implementation where you just give it a .c and a pile of .h...
authorDavid Given <dg@cowlark.com>
Wed, 8 Jun 2016 01:21:53 +0000 (03:21 +0200)
committerDavid Given <dg@cowlark.com>
Wed, 8 Jun 2016 01:21:53 +0000 (03:21 +0200)
first/ackbuilder.lua
first/build.lua

index 72b4392..850e228 100644 (file)
@@ -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,
        {
index 03077a4..95b6a64 100644 (file)
@@ -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"},
 }
 
 --[[