We can build a real program now!

This commit is contained in:
David Given 2016-06-12 20:59:43 +02:00
parent a04dbf33f3
commit 605651776e
4 changed files with 215 additions and 62 deletions

View file

@ -57,44 +57,6 @@ local function concatpath(...)
return p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/") return p:gsub("/+", "/"):gsub("^%./", ""):gsub("/%./", "/")
end end
local function basename(filename)
local _, _, b = filename:find("^.*/([^/]*)$")
if not b then
return filename
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 _, _, b = filename:find("^(.*)/[^/]*$")
if not b then
return ""
end
return b
end
local function dirnames(collection)
local o = {}
for _, s in pairs(collection) do
local b = dirname(s)
if (b ~= "") then
o[#o+1] = b
end
end
return o
end
local function filenamesof(targets, pattern) local function filenamesof(targets, pattern)
local f = {} local f = {}
if targets then if targets then
@ -107,6 +69,8 @@ local function filenamesof(targets, pattern)
end end
end end
end end
elseif (type(r) == "string") then
f[#f+1] = r
else else
error(string.format("list of targets contains a %s which isn't a target", error(string.format("list of targets contains a %s which isn't a target",
type(r))) type(r)))
@ -116,8 +80,75 @@ local function filenamesof(targets, pattern)
return f return f
end end
local function dotocollection(collection, callback)
if (type(collection) == "string") then
return callback(collection)
elseif collection.is then
local files = filenamesof(collection.outs)
if (#files ~= 1) then
error("inputs with more than one output need to be in a list")
end
return callback(files[1])
end
local o = {}
for _, s in pairs(collection) do
if s.is then
for _, b in pairs(dotocollection(filenamesof(s), callback)) do
o[#o+1] = b
end
else
local b = callback(s)
if (b ~= "") then
o[#o+1] = b
end
end
end
return o
end
local function abspath(collection)
return dotocollection(collection,
function(filename)
return concatpath(posix.getcwd(), filename)
end
)
end
local function basename(collection)
return dotocollection(collection,
function(filename)
local _, _, b = filename:find("^.*/([^/]*)$")
if not b then
return filename
end
return b
end
)
end
local function dirname(collection)
return dotocollection(collection,
function(filename)
local _, _, b = filename:find("^(.*)/[^/]*$")
if not b then
return ""
end
return b
end
)
end
local function fpairs(collection)
if (type(collection) == "string") or collection.is then
return tpairs({collection})
end
return pairs(filenamesof(collection))
end
-- Selects all targets containing at least one output file that matches -- Selects all targets containing at least one output file that matches
-- the pattern. -- the pattern (or all, if the pattern is nil).
local function selectof(targets, pattern) local function selectof(targets, pattern)
local o = {} local o = {}
for k, v in pairs(targets) do for k, v in pairs(targets) do
@ -237,7 +268,7 @@ local function loadtarget(targetname)
} }
targets[targetname] = target targets[targetname] = target
else else
local _, _, filepart, targetpart = targetname:find("^([^:]*):(%w+)$") local _, _, filepart, targetpart = targetname:find("^([^:]*):([%w-_]+)$")
if not filepart or not targetpart then if not filepart or not targetpart then
error(string.format("malformed target name '%s'", targetname)) error(string.format("malformed target name '%s'", targetname))
end end
@ -398,7 +429,7 @@ definerule("simplerule",
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(e.outs)) e.environment:mkdirs(dirname(e.outs))
local vars = inherit(e.vars, { local vars = inherit(e.vars, {
ins = e.ins, ins = e.ins,
@ -419,20 +450,20 @@ definerule("simplerule",
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
globals = { globals = {
abspath = abspath,
asstring = asstring, asstring = asstring,
basename = basename, basename = basename,
basenames = basenames,
concatpath = concatpath, concatpath = concatpath,
cwd = cwd, cwd = function() return cwd end,
definerule = definerule, definerule = definerule,
dirname = dirname, dirname = dirname,
dirnames = dirnames,
emit = emit, emit = emit,
environment = environment, environment = environment,
filenamesof = filenamesof, filenamesof = filenamesof,
inherit = inherit, inherit = inherit,
selectof = selectof, selectof = selectof,
startswith = startswith, startswith = startswith,
fpairs = fpairs,
uniquify = uniquify, uniquify = uniquify,
} }
setmetatable(globals, setmetatable(globals,

View file

@ -1,20 +1,25 @@
local function objdir(e)
return concatpath("$(OBJDIR)", cwd(), e.name)
end
definerule("normalrule", definerule("normalrule",
{ {
ins = { type="targets" }, ins = { type="targets" },
outleaves = { type="strings" }, outleaves = { type="strings" },
label = { type="string", optional=true }, label = { type="string", optional=true },
objdir = { type="string", optional=true },
commands = { type="strings" }, commands = { type="strings" },
vars = { type="table", default={} }, vars = { type="table", default={} },
}, },
function (e) function (e)
local objpath = "$(OBJDIR)/"..e.name local dir = e.objdir or objdir(e)
local realouts = {} local realouts = {}
for k, v in pairs(e.outleaves) do for k, v in pairs(e.outleaves) do
realouts[k] = concatpath(objpath, v) realouts[k] = concatpath(dir, v)
end end
local vars = inherit(e.vars, { local vars = inherit(e.vars, {
dir = objpath dir = dir
}) })
local result = simplerule { local result = simplerule {
@ -25,7 +30,7 @@ definerule("normalrule",
commands = e.commands, commands = e.commands,
vars = vars, vars = vars,
} }
result.dir = objpath result.dir = dir
return result return result
end end
) )
@ -34,10 +39,11 @@ definerule("cfile",
{ {
srcs = { type="targets" }, srcs = { type="targets" },
deps = { type="targets", default={} }, deps = { type="targets", default={} },
cflags = { type="strings", 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} %{cflags}"
}, },
} }
}, },
@ -68,7 +74,8 @@ definerule("cfile",
label = e.label, label = e.label,
commands = e.commands, commands = e.commands,
vars = { vars = {
hdrpaths = hdrpaths hdrpaths = hdrpaths,
cflags = e.cflags,
} }
} }
end end
@ -87,7 +94,7 @@ definerule("bundle",
function (e) function (e)
local outleaves = {} local outleaves = {}
local commands = {} local commands = {}
for _, f in pairs(filenamesof(e.srcs)) do for _, f in fpairs(e.srcs) do
local localf = basename(f) local localf = basename(f)
outleaves[#outleaves+1] = localf outleaves[#outleaves+1] = localf
commands[#commands+1] = "cp "..f.." %{dir}/"..localf commands[#commands+1] = "cp "..f.." %{dir}/"..localf
@ -107,6 +114,7 @@ definerule("clibrary",
{ {
srcs = { type="targets" }, srcs = { type="targets" },
deps = { type="targets", default={} }, deps = { type="targets", default={} },
cflags = { type="strings", default={} },
commands = { commands = {
type="strings", type="strings",
default={ default={
@ -124,12 +132,16 @@ definerule("clibrary",
local hsrcs = filenamesof(e.srcs, "%.h$") local hsrcs = filenamesof(e.srcs, "%.h$")
local ins = {} local ins = {}
for _, csrc in pairs(csrcs) do for _, csrc in fpairs(csrcs) do
local n = basename(csrc):gsub("%.%w*$", "") local n = basename(csrc):gsub("%.%w*$", "")
ins[#ins+1] = cfile { ins[#ins+1] = cfile {
name = e.name.."/"..n, name = e.name.."/"..n,
srcs = {csrc, unpack(hsrcs)}, srcs = {csrc, unpack(hsrcs)},
deps = e.deps, deps = e.deps,
cflags = {
"-I"..cwd(),
unpack(e.cflags)
},
} }
end end
@ -180,13 +192,3 @@ definerule("cprogram",
end end
) )
cprogram {
name = "test",
srcs = {
"foo.c",
},
deps = {
"modules:string"
}
}

31
h/build.lua Normal file
View file

@ -0,0 +1,31 @@
normalrule {
name = "em_path",
ins = {},
outleaves = { "em_path.h" },
commands = {
"echo '#define TMP_DIR \"$(ACK_TEMP_DIR)\"' > %{outs}",
"echo '#define EM_DIR \"$(PREFIX)\"' >> %{outs}",
"echo '#define ACK_PATH \"share/ack/descr\"' >> %{outs}",
}
}
bundle {
name = "emheaders",
srcs = {
"./em_*.h",
":em_path",
}
}
normalrule {
name = "local",
ins = {},
outleaves = { "local.h" },
commands = {
"echo '#define VERSION 3' > %{outs}",
"echo '#define ACKM \"$(DEFAULT_PLATFORM)\"' >> %{outs}",
"echo '#define BIGMACHINE 1' >> %{outs}",
"echo '#define SYS_5' >> %{outs}",
}
}

89
util/ack/build.lua Normal file
View file

@ -0,0 +1,89 @@
cprogram {
name = "mktables",
srcs = { "./mktables.c" },
}
normalrule {
name = "tables",
outleaves = { "dmach.c", "intable.c" },
ins = {
":mktables",
"lib/descr/fe",
},
commands = {
"(cd %{dir} && %{abspath(ins[1])} lib)"
}
}
cprogram {
name = "ack",
srcs = {
"./*.c",
"./*.h",
":tables",
},
deps = {
"h:emheaders",
"h:local",
}
}
--[[
D := util/ack
define util-ack-makeheaders-rule
$(eval g := $(OBJDIR)/$D/dmach.c $(OBJDIR)/$D/intable.c)
$(wordlist 2, $(words $g), $g): $(firstword $g)
$(firstword $g): $(util-ack-mktables)
@echo MKTABLES
@mkdir -p $(OBJDIR)/$D
$(hide) cd $(OBJDIR)/$D && $(util-ack-mktables) $(INSDIR)/share
$(eval CLEANABLES += $g)
endef
define build-ack-impl
$(call reset)
$(call cfile, $D/mktables.c)
$(call cprogram, $(OBJDIR)/$D/mktables)
$(eval util-ack-mktables := $o)
$(call reset)
$(eval cflags += -I$D)
$(call cfile, $D/list.c)
$(call cfile, $D/data.c)
$(call cfile, $D/main.c)
$(call cfile, $D/scan.c)
$(call cfile, $D/svars.c)
$(call cfile, $D/trans.c)
$(call cfile, $D/util.c)
$(call cfile, $D/rmach.c)
$(call dependson, $(INCDIR)/em_path.h)
$(call cfile, $D/run.c)
$(call cfile, $D/grows.c)
$(call cfile, $D/files.c)
$(call dependson, $(INCDIR)/em_path.h)
$(eval $(util-ack-makeheaders-rule))
$(call cfile, $(OBJDIR)/$D/dmach.c)
$(call cfile, $(OBJDIR)/$D/intable.c)
$(call cprogram, $(BINDIR)/ack)
$(call installto, $(INSDIR)/bin/ack)
$(eval ACK := $o)
$(call reset)
$(eval q := lib/descr/fe)
$(call installto, $(PLATIND)/descr/fe)
$(eval $(ACK): $o)
$(call reset)
$(eval q := $D/ack.1.X)
$(call installto, $(INSDIR)/share/man/man1/ack.1)
endef
$(eval $(build-ack-impl))
--]]