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 globals
|
||||||
local cwd = "."
|
local cwd = "."
|
||||||
|
|
||||||
local function subenv(old, cb)
|
local function inherit(high, low)
|
||||||
if not old then
|
local o = {}
|
||||||
old = environment
|
setmetatable(o, {
|
||||||
end
|
__index = function(self, k)
|
||||||
local new = {}
|
local x = high[k]
|
||||||
setmetatable(new, {__index = old})
|
if x then
|
||||||
cb(new, old)
|
return x
|
||||||
return new
|
end
|
||||||
|
return low[k]
|
||||||
|
end
|
||||||
|
})
|
||||||
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
local function asstring(o)
|
local function asstring(o)
|
||||||
|
@ -50,7 +54,7 @@ end
|
||||||
|
|
||||||
local function concatpath(...)
|
local function concatpath(...)
|
||||||
local p = table.concat({...}, "/")
|
local p = table.concat({...}, "/")
|
||||||
return p:gsub("/+", "/"):gsub("^%./", "")
|
return p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function basename(filename)
|
local function basename(filename)
|
||||||
|
@ -144,6 +148,10 @@ local function uniquify(collection)
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function startswith(needle, haystack)
|
||||||
|
return haystack:sub(1, #needle) == needle
|
||||||
|
end
|
||||||
|
|
||||||
local function emit(...)
|
local function emit(...)
|
||||||
local n = select("#", ...)
|
local n = select("#", ...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
|
@ -158,7 +166,7 @@ local function emit(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function templateexpand(list, vars)
|
local function templateexpand(list, vars)
|
||||||
setmetatable(vars, { __index = globals })
|
vars = inherit(vars, globals)
|
||||||
|
|
||||||
local o = {}
|
local o = {}
|
||||||
for _, s in ipairs(list) do
|
for _, s in ipairs(list) do
|
||||||
|
@ -210,8 +218,18 @@ local function loadtarget(targetname)
|
||||||
|
|
||||||
local target
|
local target
|
||||||
if not targetname:find(":") then
|
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 = {
|
target = {
|
||||||
outs = {targetname},
|
outs = files,
|
||||||
is = {
|
is = {
|
||||||
__implicitfile = true
|
__implicitfile = true
|
||||||
}
|
}
|
||||||
|
@ -251,11 +269,9 @@ local typeconverters = {
|
||||||
if (type(s) == "table") and s.is then
|
if (type(s) == "table") and s.is then
|
||||||
o[#o+1] = s
|
o[#o+1] = s
|
||||||
elseif (type(s) == "string") then
|
elseif (type(s) == "string") then
|
||||||
if s:find("^//") then
|
if s:find("^:") then
|
||||||
s = s:gsub("^//", "")
|
|
||||||
elseif s:find("^:") then
|
|
||||||
s = cwd..s
|
s = cwd..s
|
||||||
elseif s:find("^[^/]") then
|
elseif s:find("^%./") then
|
||||||
s = concatpath(cwd, s)
|
s = concatpath(cwd, s)
|
||||||
end
|
end
|
||||||
o[#o+1] = loadtarget(s)
|
o[#o+1] = loadtarget(s)
|
||||||
|
@ -383,13 +399,10 @@ definerule("simplerule",
|
||||||
e.environment:label(cwd..":"..e.name, " ", e.label or "")
|
e.environment:label(cwd..":"..e.name, " ", e.label or "")
|
||||||
e.environment:mkdirs(dirnames(e.outs))
|
e.environment:mkdirs(dirnames(e.outs))
|
||||||
|
|
||||||
local vars = {
|
local vars = inherit(e.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:exec(templateexpand(e.commands, vars))
|
||||||
e.environment:endrule()
|
e.environment:endrule()
|
||||||
|
@ -416,7 +429,9 @@ globals = {
|
||||||
emit = emit,
|
emit = emit,
|
||||||
environment = environment,
|
environment = environment,
|
||||||
filenamesof = filenamesof,
|
filenamesof = filenamesof,
|
||||||
|
inherit = inherit,
|
||||||
selectof = selectof,
|
selectof = selectof,
|
||||||
|
startswith = startswith,
|
||||||
uniquify = uniquify,
|
uniquify = uniquify,
|
||||||
}
|
}
|
||||||
setmetatable(globals,
|
setmetatable(globals,
|
||||||
|
|
112
first/build.lua
112
first/build.lua
|
@ -13,13 +13,17 @@ definerule("normalrule",
|
||||||
realouts[k] = concatpath(objpath, v)
|
realouts[k] = concatpath(objpath, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local vars = inherit(e.vars, {
|
||||||
|
dir = objpath
|
||||||
|
})
|
||||||
|
|
||||||
local result = 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,
|
vars = vars,
|
||||||
}
|
}
|
||||||
result.dir = objpath
|
result.dir = objpath
|
||||||
return result
|
return result
|
||||||
|
@ -29,10 +33,11 @@ definerule("normalrule",
|
||||||
definerule("cfile",
|
definerule("cfile",
|
||||||
{
|
{
|
||||||
srcs = { type="targets" },
|
srcs = { type="targets" },
|
||||||
|
deps = { type="targets", default={} },
|
||||||
commands = {
|
commands = {
|
||||||
type="strings",
|
type="strings",
|
||||||
default={
|
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")
|
error("you must have exactly one .c file")
|
||||||
end
|
end
|
||||||
|
|
||||||
local htargets = selectof(e.srcs, "%.h$")
|
local hsrcs = filenamesof(e.srcs, "%.h$")
|
||||||
|
local hdeps = selectof(e.deps, "%.h$")
|
||||||
local hdrpaths = {}
|
local hdrpaths = {}
|
||||||
for _, t in pairs(htargets) do
|
for _, t in pairs(hdeps) do
|
||||||
hdrpaths[#hdrpaths+1] = "-I"..t.dir
|
hdrpaths[#hdrpaths+1] = "-I"..t.dir
|
||||||
end
|
end
|
||||||
hdrpaths = uniquify(hdrpaths)
|
hdrpaths = uniquify(hdrpaths)
|
||||||
|
|
||||||
|
for _, f in pairs(filenamesof(hdeps)) do
|
||||||
|
hsrcs[#hsrcs+1] = f
|
||||||
|
end
|
||||||
|
|
||||||
local outleaf = basename(csrcs[1]):gsub("%.c$", ".o")
|
local outleaf = basename(csrcs[1]):gsub("%.c$", ".o")
|
||||||
|
|
||||||
return normalrule {
|
return normalrule {
|
||||||
name = e.name,
|
name = e.name,
|
||||||
ins = {csrcs[1], unpack(htargets)},
|
ins = {csrcs[1], unpack(hsrcs)},
|
||||||
outleaves = {outleaf},
|
outleaves = {outleaf},
|
||||||
label = e.label,
|
label = e.label,
|
||||||
commands = e.commands,
|
commands = e.commands,
|
||||||
|
@ -64,25 +74,85 @@ definerule("cfile",
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
normalrule {
|
definerule("bundle",
|
||||||
name = "mkheader",
|
{
|
||||||
ins = {},
|
srcs = { type="targets" },
|
||||||
outleaves = {"foo.h"},
|
commands = {
|
||||||
commands = {
|
type="strings",
|
||||||
"echo 1 >> %{outs}"
|
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
|
||||||
|
|
||||||
|
return normalrule {
|
||||||
|
name = e.name,
|
||||||
|
ins = e.srcs,
|
||||||
|
outleaves = outleaves,
|
||||||
|
label = e.label,
|
||||||
|
commands = commands
|
||||||
|
}
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfile {
|
|
||||||
name = "testfile-foo",
|
|
||||||
srcs = "foo.c",
|
|
||||||
}
|
|
||||||
|
|
||||||
cfile {
|
|
||||||
name = "testfile-bar",
|
|
||||||
srcs = {"bar.c", ":mkheader"},
|
|
||||||
}
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
--
|
--
|
||||||
-- Targets:
|
-- Targets:
|
||||||
|
|
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