From c213602a0263a9e8b9f3eaf9bf0b9542fe2aa3b1 Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 8 Aug 2016 23:55:23 +0200 Subject: [PATCH] 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. --- first/ackbuilder.lua | 32 +++++++++++++++++++++----------- first/build.lua | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/first/ackbuilder.lua b/first/ackbuilder.lua index 7bbf2ee04..c7798e6b8 100644 --- a/first/ackbuilder.lua +++ b/first/ackbuilder.lua @@ -114,13 +114,13 @@ local function concatpath(...) return (p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/")) end --- Turns a list of strings or targets into a list of targets, expanding --- recursive lists and wildcards. +-- Returns a list of the targets within the given collection; the keys of any +-- keyed items are lost. Lists and wildcards are expanded. local function targetsof(...) local o = {} local function process(items) - for _, item in ipairs(items) do + for _, item in pairs(items) do if (type(item) == "table") then if item.is then -- This is a target. @@ -430,7 +430,23 @@ local typeconverters = { elseif (type(i) ~= "table") then error(string.format("property '%s' must be a target list", propname)) 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, strings = function(propname, i) @@ -653,7 +669,7 @@ definerule("simplerule", definerule("installable", { - map = { type="table", default={} }, + map = { type="targets", default={} }, }, function (e) local deps = {} @@ -661,12 +677,6 @@ definerule("installable", local srcs = {} local dests = {} 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 (type(dest) ~= "number") then error("can't specify a destination filename when installing an installable") diff --git a/first/build.lua b/first/build.lua index 9bbb905a9..0efdadb12 100644 --- a/first/build.lua +++ b/first/build.lua @@ -170,27 +170,44 @@ definerule("clibrary", } end - local hdrs = filenamesof(e.hdrs) - local commands = {} - for _, s in ipairs(e.commands) do - commands[#commands+1] = s + local outleaves = {} + if (#e.srcs > 0) then + for _, s in ipairs(e.commands) do + commands[#commands+1] = s + end + outleaves[#outleaves+1] = e.name..".a" end - if (#hdrs > 0) then - commands[#commands+1] = "cp %{hdrs} %{dir}" + + 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 return normalrule { name = e.name, cwd = e.cwd, ins = ins, - deps = concat(e.hdrs, e.deps), - outleaves = concat(e.name..".a", basename(hdrs)), + deps = {hdrsin, e.deps}, + outleaves = outleaves, label = e.label, commands = commands, - vars = { - hdrs = hdrs - } } end )