Multiple build files work. Use deps intelligently. clibraries.
This commit is contained in:
parent
fcc5a878ae
commit
f47bb49c1f
|
@ -15,14 +15,18 @@ local buildfiles = {}
|
|||
local globals
|
||||
local cwd = "."
|
||||
|
||||
local function subenv(old, cb)
|
||||
if not old then
|
||||
old = environment
|
||||
local function inherit(high, low)
|
||||
local o = {}
|
||||
setmetatable(o, {
|
||||
__index = function(self, k)
|
||||
local x = high[k]
|
||||
if x then
|
||||
return x
|
||||
end
|
||||
local new = {}
|
||||
setmetatable(new, {__index = old})
|
||||
cb(new, old)
|
||||
return new
|
||||
return low[k]
|
||||
end
|
||||
})
|
||||
return o
|
||||
end
|
||||
|
||||
local function asstring(o)
|
||||
|
@ -50,7 +54,7 @@ end
|
|||
|
||||
local function concatpath(...)
|
||||
local p = table.concat({...}, "/")
|
||||
return p:gsub("/+", "/"):gsub("^%./", "")
|
||||
return p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/")
|
||||
end
|
||||
|
||||
local function basename(filename)
|
||||
|
@ -144,6 +148,10 @@ local function uniquify(collection)
|
|||
return o
|
||||
end
|
||||
|
||||
local function startswith(needle, haystack)
|
||||
return haystack:sub(1, #needle) == needle
|
||||
end
|
||||
|
||||
local function emit(...)
|
||||
local n = select("#", ...)
|
||||
local args = {...}
|
||||
|
@ -158,7 +166,7 @@ local function emit(...)
|
|||
end
|
||||
|
||||
local function templateexpand(list, vars)
|
||||
setmetatable(vars, { __index = globals })
|
||||
vars = inherit(vars, globals)
|
||||
|
||||
local o = {}
|
||||
for _, s in ipairs(list) do
|
||||
|
@ -210,8 +218,18 @@ local function loadtarget(targetname)
|
|||
|
||||
local target
|
||||
if not targetname:find(":") then
|
||||
local files
|
||||
if targetname:find("[?*]") then
|
||||
files = posix.glob(targetname)
|
||||
if not files then
|
||||
error(string.format("glob '%s' matches no files", targetname))
|
||||
end
|
||||
else
|
||||
files = {targetname}
|
||||
end
|
||||
|
||||
target = {
|
||||
outs = {targetname},
|
||||
outs = files,
|
||||
is = {
|
||||
__implicitfile = true
|
||||
}
|
||||
|
@ -251,11 +269,9 @@ local typeconverters = {
|
|||
if (type(s) == "table") and s.is then
|
||||
o[#o+1] = s
|
||||
elseif (type(s) == "string") then
|
||||
if s:find("^//") then
|
||||
s = s:gsub("^//", "")
|
||||
elseif s:find("^:") then
|
||||
if s:find("^:") then
|
||||
s = cwd..s
|
||||
elseif s:find("^[^/]") then
|
||||
elseif s:find("^%./") then
|
||||
s = concatpath(cwd, s)
|
||||
end
|
||||
o[#o+1] = loadtarget(s)
|
||||
|
@ -383,13 +399,10 @@ definerule("simplerule",
|
|||
e.environment:label(cwd..":"..e.name, " ", e.label or "")
|
||||
e.environment:mkdirs(dirnames(e.outs))
|
||||
|
||||
local vars = {
|
||||
local vars = inherit(e.vars, {
|
||||
ins = e.ins,
|
||||
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()
|
||||
|
@ -416,7 +429,9 @@ globals = {
|
|||
emit = emit,
|
||||
environment = environment,
|
||||
filenamesof = filenamesof,
|
||||
inherit = inherit,
|
||||
selectof = selectof,
|
||||
startswith = startswith,
|
||||
uniquify = uniquify,
|
||||
}
|
||||
setmetatable(globals,
|
||||
|
|
102
first/build.lua
102
first/build.lua
|
@ -13,13 +13,17 @@ definerule("normalrule",
|
|||
realouts[k] = concatpath(objpath, v)
|
||||
end
|
||||
|
||||
local vars = inherit(e.vars, {
|
||||
dir = objpath
|
||||
})
|
||||
|
||||
local result = simplerule {
|
||||
name = e.name,
|
||||
ins = e.ins,
|
||||
outs = realouts,
|
||||
label = e.label,
|
||||
commands = e.commands,
|
||||
vars = e.vars,
|
||||
vars = vars,
|
||||
}
|
||||
result.dir = objpath
|
||||
return result
|
||||
|
@ -29,10 +33,11 @@ definerule("normalrule",
|
|||
definerule("cfile",
|
||||
{
|
||||
srcs = { type="targets" },
|
||||
deps = { type="targets", default={} },
|
||||
commands = {
|
||||
type="strings",
|
||||
default={
|
||||
"$CC -c -o %{outs[1]} %{ins[1]} %{hdrpaths}"
|
||||
"$(CC) -c -o %{outs[1]} %{ins[1]} %{hdrpaths}"
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -42,18 +47,23 @@ definerule("cfile",
|
|||
error("you must have exactly one .c file")
|
||||
end
|
||||
|
||||
local htargets = selectof(e.srcs, "%.h$")
|
||||
local hsrcs = filenamesof(e.srcs, "%.h$")
|
||||
local hdeps = selectof(e.deps, "%.h$")
|
||||
local hdrpaths = {}
|
||||
for _, t in pairs(htargets) do
|
||||
for _, t in pairs(hdeps) do
|
||||
hdrpaths[#hdrpaths+1] = "-I"..t.dir
|
||||
end
|
||||
hdrpaths = uniquify(hdrpaths)
|
||||
|
||||
for _, f in pairs(filenamesof(hdeps)) do
|
||||
hsrcs[#hsrcs+1] = f
|
||||
end
|
||||
|
||||
local outleaf = basename(csrcs[1]):gsub("%.c$", ".o")
|
||||
|
||||
return normalrule {
|
||||
name = e.name,
|
||||
ins = {csrcs[1], unpack(htargets)},
|
||||
ins = {csrcs[1], unpack(hsrcs)},
|
||||
outleaves = {outleaf},
|
||||
label = e.label,
|
||||
commands = e.commands,
|
||||
|
@ -64,23 +74,83 @@ definerule("cfile",
|
|||
end
|
||||
)
|
||||
|
||||
normalrule {
|
||||
name = "mkheader",
|
||||
ins = {},
|
||||
outleaves = {"foo.h"},
|
||||
definerule("bundle",
|
||||
{
|
||||
srcs = { type="targets" },
|
||||
commands = {
|
||||
"echo 1 >> %{outs}"
|
||||
type="strings",
|
||||
default={
|
||||
"tar cf - %{ins} | (cd %{dir} && tar xf -)"
|
||||
}
|
||||
}
|
||||
},
|
||||
function (e)
|
||||
local outleaves = {}
|
||||
local commands = {}
|
||||
for _, f in pairs(filenamesof(e.srcs)) do
|
||||
local localf = basename(f)
|
||||
outleaves[#outleaves+1] = localf
|
||||
commands[#commands+1] = "cp "..f.." %{dir}/"..localf
|
||||
end
|
||||
|
||||
cfile {
|
||||
name = "testfile-foo",
|
||||
srcs = "foo.c",
|
||||
return normalrule {
|
||||
name = e.name,
|
||||
ins = e.srcs,
|
||||
outleaves = outleaves,
|
||||
label = e.label,
|
||||
commands = commands
|
||||
}
|
||||
end
|
||||
)
|
||||
|
||||
cfile {
|
||||
name = "testfile-bar",
|
||||
srcs = {"bar.c", ":mkheader"},
|
||||
definerule("clibrary",
|
||||
{
|
||||
srcs = { type="targets" },
|
||||
deps = { type="targets", default={} },
|
||||
commands = {
|
||||
type="strings",
|
||||
default={
|
||||
"rm -f %{outs}",
|
||||
"$(AR) qs %{outs} %{ins}"
|
||||
},
|
||||
}
|
||||
},
|
||||
function (e)
|
||||
local csrcs = filenamesof(e.srcs, "%.c$")
|
||||
if (#csrcs < 1) then
|
||||
error("you must supply at least one C source file")
|
||||
end
|
||||
|
||||
local hsrcs = filenamesof(e.srcs, "%.h$")
|
||||
|
||||
local ins = {}
|
||||
for _, csrc in pairs(csrcs) do
|
||||
local n = basename(csrc):gsub("%.%w*$", "")
|
||||
ins[#ins+1] = cfile {
|
||||
name = e.name.."/"..n,
|
||||
srcs = {csrc, unpack(hsrcs)},
|
||||
deps = e.deps,
|
||||
}
|
||||
end
|
||||
|
||||
return normalrule {
|
||||
name = e.name,
|
||||
ins = ins,
|
||||
outleaves = { e.name..".a" },
|
||||
label = e.label,
|
||||
commands = e.commands
|
||||
}
|
||||
end
|
||||
)
|
||||
|
||||
clibrary {
|
||||
name = "mylib",
|
||||
srcs = {
|
||||
"modules/src/string/*.c",
|
||||
},
|
||||
deps = {
|
||||
"modules:headers"
|
||||
}
|
||||
}
|
||||
|
||||
--[[
|
||||
|
|
5
modules/build.lua
Normal file
5
modules/build.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
bundle {
|
||||
name = "headers",
|
||||
srcs = { "./h/*.h" }
|
||||
}
|
||||
|
Loading…
Reference in a new issue