cfile with dynamically generated headers sort of works.
This commit is contained in:
parent
f4449e3f97
commit
8082ef16a7
|
@ -53,6 +53,25 @@ local function concatpath(...)
|
||||||
return p:gsub("/+", "/"):gsub("^%./", "")
|
return p:gsub("/+", "/"):gsub("^%./", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function basename(filename)
|
||||||
|
local _, _, b = filename:find("^.*/([^/]*)$")
|
||||||
|
if not b then
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
|
||||||
|
local function basenames(collection)
|
||||||
|
local o = {}
|
||||||
|
for _, s in pairs(collection) do
|
||||||
|
local b = basename(s)
|
||||||
|
if (b ~= "") then
|
||||||
|
o[#o+1] = b
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
local function dirname(filename)
|
local function dirname(filename)
|
||||||
local _, _, b = filename:find("^(.*)/[^/]*$")
|
local _, _, b = filename:find("^(.*)/[^/]*$")
|
||||||
if not b then
|
if not b then
|
||||||
|
@ -74,13 +93,15 @@ end
|
||||||
|
|
||||||
local function filenamesof(results)
|
local function filenamesof(results)
|
||||||
local f = {}
|
local f = {}
|
||||||
for _, r in pairs(results) do
|
if results then
|
||||||
if (type(r) == "string") then
|
for _, r in pairs(results) do
|
||||||
f[#f+1] = r
|
if (type(r) == "string") then
|
||||||
elseif (type(r) == "table") then
|
f[#f+1] = r
|
||||||
if r.is and r.outs then
|
elseif (type(r) == "table") then
|
||||||
for _, o in pairs(r.outs) do
|
if r.is and r.outs then
|
||||||
f[#f+1] = o
|
for _, o in pairs(r.outs) do
|
||||||
|
f[#f+1] = o
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -88,6 +109,27 @@ local function filenamesof(results)
|
||||||
return f
|
return f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function selectof(pattern, targets)
|
||||||
|
local o = {}
|
||||||
|
for k, v in pairs(targets) do
|
||||||
|
if v.is and v.outs then
|
||||||
|
local targetmatches = nil
|
||||||
|
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")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if targetmatches then
|
||||||
|
o[#o+1] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
local function uniquify(collection)
|
local function uniquify(collection)
|
||||||
local s = {}
|
local s = {}
|
||||||
local o = {}
|
local o = {}
|
||||||
|
@ -238,6 +280,13 @@ local typeconverters = {
|
||||||
end
|
end
|
||||||
return i
|
return i
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
table = function(propname, i)
|
||||||
|
if (type(i) ~= "table") then
|
||||||
|
error(string.format("property '%s' must be a table", propname))
|
||||||
|
end
|
||||||
|
return i
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function definerule(rulename, types, cb)
|
local function definerule(rulename, types, cb)
|
||||||
|
@ -258,7 +307,7 @@ local function definerule(rulename, types, cb)
|
||||||
local args = {}
|
local args = {}
|
||||||
for propname, typespec in pairs(types) do
|
for propname, typespec in pairs(types) do
|
||||||
if not e[propname] then
|
if not e[propname] then
|
||||||
if not typespec.optional then
|
if not typespec.optional and not typespec.default then
|
||||||
error(string.format("missing mandatory property '%s'", propname))
|
error(string.format("missing mandatory property '%s'", propname))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -325,19 +374,22 @@ definerule("simplerule",
|
||||||
outs = { type="strings" },
|
outs = { type="strings" },
|
||||||
label = { type="string", optional=true },
|
label = { type="string", optional=true },
|
||||||
commands = { type="strings" },
|
commands = { type="strings" },
|
||||||
|
vars = { type="table", default={} },
|
||||||
},
|
},
|
||||||
function (e)
|
function (e)
|
||||||
e.environment:rule(filenamesof(e.ins), e.outs)
|
e.environment:rule(filenamesof(e.ins), e.outs)
|
||||||
e.environment:label(cwd..":"..e.name, " ", e.label or "")
|
e.environment:label(cwd..":"..e.name, " ", e.label or "")
|
||||||
e.environment:mkdirs(dirnames(filenamesof(e.outs)))
|
e.environment:mkdirs(dirnames(filenamesof(e.outs)))
|
||||||
e.environment:exec(
|
|
||||||
templateexpand(e.commands,
|
local vars = {
|
||||||
{
|
ins = e.ins,
|
||||||
ins = e.ins,
|
outs = e.outs
|
||||||
outs = e.outs
|
}
|
||||||
}
|
for k, v in pairs(e.vars) do
|
||||||
)
|
vars[k] = v
|
||||||
)
|
end
|
||||||
|
|
||||||
|
e.environment:exec(templateexpand(e.commands, vars))
|
||||||
e.environment:endrule()
|
e.environment:endrule()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -352,11 +404,17 @@ definerule("simplerule",
|
||||||
|
|
||||||
globals = {
|
globals = {
|
||||||
asstring = asstring,
|
asstring = asstring,
|
||||||
|
basename = basename,
|
||||||
|
basenames = basenames,
|
||||||
concatpath = concatpath,
|
concatpath = concatpath,
|
||||||
cwd = cwd,
|
cwd = cwd,
|
||||||
definerule = definerule,
|
definerule = definerule,
|
||||||
|
dirname = dirname,
|
||||||
|
dirnames = dirnames,
|
||||||
emit = emit,
|
emit = emit,
|
||||||
environment = environment,
|
environment = environment,
|
||||||
|
filenamesof = filenamesof,
|
||||||
|
selectof = selectof,
|
||||||
}
|
}
|
||||||
setmetatable(globals,
|
setmetatable(globals,
|
||||||
{
|
{
|
||||||
|
|
101
first/build.lua
101
first/build.lua
|
@ -4,6 +4,7 @@ definerule("normalrule",
|
||||||
outleaves = { type="strings" },
|
outleaves = { type="strings" },
|
||||||
label = { type="string", optional=true },
|
label = { type="string", optional=true },
|
||||||
commands = { type="strings" },
|
commands = { type="strings" },
|
||||||
|
vars = { type="table", default={} },
|
||||||
},
|
},
|
||||||
function (e)
|
function (e)
|
||||||
local objpath = "$(OBJDIR)/"..e.name
|
local objpath = "$(OBJDIR)/"..e.name
|
||||||
|
@ -12,76 +13,76 @@ definerule("normalrule",
|
||||||
realouts[k] = concatpath(objpath, v)
|
realouts[k] = concatpath(objpath, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
return simplerule {
|
local result = simplerule {
|
||||||
name = e.name,
|
name = e.name,
|
||||||
ins = e.ins,
|
ins = e.ins,
|
||||||
outs = realouts,
|
outs = realouts,
|
||||||
label = e.label,
|
label = e.label,
|
||||||
commands = e.commands,
|
commands = e.commands,
|
||||||
|
vars = e.vars,
|
||||||
|
}
|
||||||
|
result.dir = objpath
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
definerule("cfile",
|
||||||
|
{
|
||||||
|
srcs = { type="targets" },
|
||||||
|
hdrs = { type="targets", default={} },
|
||||||
|
commands = {
|
||||||
|
type="strings",
|
||||||
|
default={
|
||||||
|
"$CC -c -o %{outs[1]} %{ins[1]} %{hdrpaths}"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (e)
|
||||||
|
if (#e.srcs ~= 1) then
|
||||||
|
error("you must have exactly one .c file")
|
||||||
|
end
|
||||||
|
|
||||||
|
hdrpaths = {}
|
||||||
|
for _, t in pairs(e.hdrs) do
|
||||||
|
hdrpaths[#hdrpaths+1] = "-I"..t.dir
|
||||||
|
end
|
||||||
|
|
||||||
|
local outleaf = basename(filenamesof(e.srcs)[1]):gsub("%.c$", ".o")
|
||||||
|
|
||||||
|
return normalrule {
|
||||||
|
name = e.name,
|
||||||
|
ins = {e.srcs[1], unpack(e.hdrs)},
|
||||||
|
outleaves = {outleaf},
|
||||||
|
label = e.label,
|
||||||
|
commands = e.commands,
|
||||||
|
vars = {
|
||||||
|
hdrpaths = hdrpaths
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
normalrule {
|
normalrule {
|
||||||
name = "random",
|
name = "mkheader",
|
||||||
ins = {},
|
ins = {},
|
||||||
outleaves = {"out"},
|
outleaves = {"foo.h"},
|
||||||
commands = {
|
commands = {
|
||||||
"dd if=/dev/random of=%{outs} bs=1024 count=1"
|
"echo 1 >> %{outs}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
normalrule {
|
cfile {
|
||||||
name = "onetwo",
|
name = "testfile-foo",
|
||||||
ins = {},
|
srcs = "foo.c",
|
||||||
outleaves = {"one.txt", "two.txt"},
|
|
||||||
commands = {
|
|
||||||
"echo 1 >> %{outs[1]}",
|
|
||||||
"echo 2 >> %{outs[2]}",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
normalrule {
|
cfile {
|
||||||
name = "concat",
|
name = "testfile-bar",
|
||||||
ins = {":onetwo"},
|
srcs = "bar.c",
|
||||||
outleaves = {"result.txt"},
|
hdrs = ":mkheader",
|
||||||
commands = {
|
|
||||||
"cat %{ins} > %{outs}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
simplerule {
|
|
||||||
name = "sorted",
|
|
||||||
ins = { ":random" },
|
|
||||||
outs = { "sorted" },
|
|
||||||
commands = {
|
|
||||||
"sort %{ins} > %{outs}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
function environment:cfileflags()
|
|
||||||
emit("$CFLAGS")
|
|
||||||
end
|
|
||||||
|
|
||||||
function environment:cfile(srcs, obj, includes)
|
|
||||||
emit("$CC -o", obj, srcs)
|
|
||||||
emit(ab.expand(includes, "-I%"))
|
|
||||||
self:cflags()
|
|
||||||
emit("\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
function environment:clinkflags()
|
|
||||||
emit("$LDFLAGS")
|
|
||||||
end
|
|
||||||
|
|
||||||
function environment:clink(objs, exe, libraryFlags)
|
|
||||||
emit("$CC -o", exe, objs, libraryFlags)
|
|
||||||
self:clinkflags()
|
|
||||||
emit("\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Targets:
|
-- Targets:
|
||||||
--
|
--
|
||||||
|
|
Loading…
Reference in a new issue