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
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,
environment = environment,
filenamesof = filenamesof,
selectof = selectof,
+ uniquify = uniquify,
}
setmetatable(globals,
{
definerule("cfile",
{
srcs = { type="targets" },
- hdrs = { type="targets", default={} },
commands = {
type="strings",
default={
}
},
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,
cfile {
name = "testfile-bar",
- srcs = "bar.c",
- hdrs = ":mkheader",
+ srcs = {"bar.c", ":mkheader"},
}
--[[