Target lists can now have keyed items ({["foo"] = "+target"); this is

used by both installable and by clibrary{} to allow headers to be
installed into subdirectories.
This commit is contained in:
David Given 2016-08-08 23:55:23 +02:00
parent 0d77cb8279
commit c213602a02
2 changed files with 49 additions and 22 deletions

View file

@ -114,13 +114,13 @@ local function concatpath(...)
return (p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/")) return (p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/"))
end end
-- Turns a list of strings or targets into a list of targets, expanding -- Returns a list of the targets within the given collection; the keys of any
-- recursive lists and wildcards. -- keyed items are lost. Lists and wildcards are expanded.
local function targetsof(...) local function targetsof(...)
local o = {} local o = {}
local function process(items) local function process(items)
for _, item in ipairs(items) do for _, item in pairs(items) do
if (type(item) == "table") then if (type(item) == "table") then
if item.is then if item.is then
-- This is a target. -- This is a target.
@ -430,7 +430,23 @@ local typeconverters = {
elseif (type(i) ~= "table") then elseif (type(i) ~= "table") then
error(string.format("property '%s' must be a target list", propname)) error(string.format("property '%s' must be a target list", propname))
end end
return targetsof(i)
local m = {}
for k, v in pairs(i) do
local ts = targetsof(v)
if (type(k) == "number") then
for _, t in ipairs(ts) do
m[#m+1] = t
end
else
if (#ts ~= 1) then
error(string.format("named target '%s' can only be assigned from a single target", k))
else
m[k] = ts[1]
end
end
end
return m
end, end,
strings = function(propname, i) strings = function(propname, i)
@ -653,7 +669,7 @@ definerule("simplerule",
definerule("installable", definerule("installable",
{ {
map = { type="table", default={} }, map = { type="targets", default={} },
}, },
function (e) function (e)
local deps = {} local deps = {}
@ -661,12 +677,6 @@ definerule("installable",
local srcs = {} local srcs = {}
local dests = {} local dests = {}
for dest, src in pairs(e.map) do for dest, src in pairs(e.map) do
src = targetsof(src)
if (#src ~= 1) then
error("installable can only cope with one target at a time")
end
src = src[1]
if src.is.installable then if src.is.installable then
if (type(dest) ~= "number") then if (type(dest) ~= "number") then
error("can't specify a destination filename when installing an installable") error("can't specify a destination filename when installing an installable")

View file

@ -170,27 +170,44 @@ definerule("clibrary",
} }
end end
local hdrs = filenamesof(e.hdrs)
local commands = {} local commands = {}
local outleaves = {}
if (#e.srcs > 0) then
for _, s in ipairs(e.commands) do for _, s in ipairs(e.commands) do
commands[#commands+1] = s commands[#commands+1] = s
end end
if (#hdrs > 0) then outleaves[#outleaves+1] = e.name..".a"
commands[#commands+1] = "cp %{hdrs} %{dir}" end
local hdrsin = {}
for dest, src in pairs(e.hdrs) do
if (type(dest) == "number") then
for _, f in ipairs(filenamesof(src)) do
hdrsin[#hdrsin+1] = f
outleaves[#outleaves+1] = basename(f)
commands[#commands+1] = "cp "..asstring(f).." %{dir}"
end
else
local fs = filenamesof(src)
if (#fs ~= 1) then
error(string.format("keyed header '%s' can only be a single file", dest))
end
local f = fs[1]
hdrsin[#hdrsin+1] = f
outleaves[#outleaves+1] = dest
commands[#commands+1] = "cp "..asstring(f).." %{dir}/"..dest
end
end end
return normalrule { return normalrule {
name = e.name, name = e.name,
cwd = e.cwd, cwd = e.cwd,
ins = ins, ins = ins,
deps = concat(e.hdrs, e.deps), deps = {hdrsin, e.deps},
outleaves = concat(e.name..".a", basename(hdrs)), outleaves = outleaves,
label = e.label, label = e.label,
commands = commands, commands = commands,
vars = {
hdrs = hdrs
}
} }
end end
) )