-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bdb3dda
Showing
11 changed files
with
491 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.o | ||
*.so |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
all: liblbuild_util.so | ||
|
||
liblbuild_util.so: util.c | ||
$(CC) $(CFLAGS) -fPIC -shared util.c -o liblbuild_util.so | ||
|
||
$(DESTDIR)/usr/lib/liblbuild_util.so: liblbuild_util.so | ||
install -D -m 0744 $< $@ | ||
|
||
$(DESTDIR)/usr/bin/lbuild: lbuild.lua | ||
install -D -m 0755 $< $@ | ||
|
||
$(DESTDIR)/usr/share/lua/5.1/lbuild/%.lua: lbuild/%.lua | ||
install -D -m 0744 $< $@ | ||
|
||
install: $(DESTDIR)/usr/lib/liblbuild_util.so $(DESTDIR)/usr/bin/lbuild \ | ||
$(foreach l,$(shell ls lbuild),$(DESTDIR)/usr/share/lua/5.1/lbuild/$(l)) | ||
|
||
clean: | ||
rm -f *.so example/*.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
addcmd("hello.o", {"hello.c"}, {"/usr/bin/cc", "hello.c", "-o", "hello.o"}) | ||
addcmd("hello", {}, {"/bin/echo", "hello", "world"}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#include<stdio.h> | ||
|
||
int main(int argc, char **argv) { | ||
printf("Hello world"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/bin/luajit | ||
|
||
local ruletable = require("lbuild.ruletable") | ||
local runner = require("lbuild.runner") | ||
|
||
local f = assert(io.open("build.lua", "rb")) | ||
loadstring([[ | ||
local runner = require("lbuild.runner") | ||
local ruletable = require("lbuild.ruletable") | ||
local add = function(...) | ||
ruletable:add(...) | ||
end | ||
local addcmd = function(...) | ||
ruletable:addcmd(...) | ||
end | ||
]] .. f:read("*all"))() | ||
|
||
local targs = {...} | ||
|
||
local n = #targs | ||
|
||
for _, r in ipairs(targs) do | ||
ruletable:run(r):prom(function() | ||
print("Done building " .. r) | ||
n = n - 1 | ||
if n == 0 then | ||
os.exit() | ||
end | ||
end) | ||
end | ||
|
||
if n == 0 then | ||
print("Nothing to do") | ||
end | ||
|
||
while true do runner:wait() end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
--util for compiling c/c++ | ||
--work in progress | ||
|
||
local runner = require("lbuild.runner") | ||
local path = require("lbuild.path") | ||
--local os lib | ||
local os = os | ||
|
||
--the library table | ||
local cc = {} | ||
|
||
--find cc to use | ||
cc.CC = (os.getenv("CC") or ""):gmatch("^[ \n]+") | ||
--find cxx to use | ||
cc.CXX = (os.getenv("CXX") or ""):gmatch("^[ \n]+") | ||
--load CFLAGS | ||
cc.CFLAGS = (os.getenv("CFLAGS") or ""):gmatch("^[ \n]+") | ||
--load CXXFLAGS | ||
cc.CXXFLAGS = (os.getenv("CXXFLAGS") or ""):gmatch("^[ \n]+") | ||
|
||
--compiling a file with the -c option | ||
--file, output file, extra args | ||
function cc:ccc(file, outf, ...) | ||
if outf == nil then | ||
outf = path:stripext(file) .. ".o" | ||
end | ||
return runner:run(self.CC, "-c", table:unpack(self.CFLAGS), ..., "-o", outf) | ||
end | ||
function cc:cxxc(file, outf, ...) | ||
if outf == nil then | ||
outf = path:stripext(file) .. ".o" | ||
end | ||
return runner:run(self.CXX, "-c", table:unpack(self.CXXFLAGS), ..., "-o", outf) | ||
end | ||
--link objects together (mid-stage) | ||
--syntax: output path, extra args (as a table), list of input objects (vararg) | ||
function cc:partialld(outf, args, ...) | ||
local inputs = {...} | ||
return runner:run(self.CC, "-c", table:unpack(self.CFLAGS), ..., "-o", outf) | ||
end | ||
--link a finished output | ||
--inputs: input file (multiple inputs possible as table), options table, output | ||
--options: | ||
--type: "executable", "shared" (default: executable) | ||
--static: true, false (default: false) | ||
--extraargs: string array (default: {}) | ||
function cc:ld(input, output, options) | ||
--select default options if missing | ||
options = options or {} | ||
options.type = options.type or "executable" | ||
options.static = options.static or false | ||
options.extraargs = options.extraargs or {} | ||
if options.type == "shared" then | ||
output = output or path:stripext(file) .. ".so" | ||
else | ||
output = output or path:stripext(file) .. ".o" | ||
end | ||
--check validity | ||
if options.type ~= "executable" and options.type ~= "shared" then | ||
error("bad cc type") | ||
end | ||
--check types | ||
if type(static) ~= "boolean" then | ||
error("static is not boolean") | ||
end | ||
if type(extraargs) ~= "table" then | ||
error("extraargs is not table") | ||
end | ||
--generate args | ||
local args = {} | ||
if options.type == "shared" then | ||
args[#args + 1] = "-shared" | ||
end | ||
if options.static then | ||
args[#args + 1] = "-static" | ||
end | ||
--run thing | ||
return runner:run(self.CC, table:unpack(args), table:unpack(self.CFLAGS), table:unpack(options.extraargs), ..., "-o", output) | ||
end | ||
|
||
return cc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--work in progress | ||
|
||
local path = {} | ||
|
||
function path:stripext(p) | ||
return string.gsub(a, "%.+%a", "") | ||
end | ||
|
||
return path |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
local p = {} | ||
|
||
p.__index = p | ||
|
||
function p:prom(success, fail) | ||
if fail == nil then | ||
fail = error | ||
end | ||
self.f(success, fail) | ||
end | ||
|
||
local function promise(func) | ||
return setmetatable({f = func}, p) | ||
end | ||
|
||
return promise |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
local path = require("lbuild.path") | ||
local promise = require("lbuild.promise") | ||
local runner = require("lbuild.runner") | ||
local ffi = require("ffi") | ||
|
||
ffi.cdef[[ | ||
int lbuild_util_isNewer(char *a, char *b); | ||
char *strerror(int errnum); | ||
bool exists(const char path[]); | ||
]] | ||
|
||
local lbuild_util = ffi.load("liblbuild_util.so") | ||
|
||
local ruletbl = {} | ||
local ruletable = ruletbl | ||
ruletable.gen = {} | ||
ruletable.rules = {} | ||
|
||
--add a rule | ||
--rule: table | ||
--rule.deps: a list or a function which returns a promise to a list | ||
--rule.run: a function which returns a promise | ||
function ruletbl:add(rule) | ||
self.rules[rule.name] = rule | ||
end | ||
|
||
--add a rule which executes a command | ||
--name is the name of the rule | ||
--deps are the dependencies of the command | ||
--cmd is the command to run | ||
--can be a table (argv) or a string | ||
--if a string, is translated to sh -c cmd | ||
function ruletbl:addcmd(name, deps, cmd) | ||
local rule = {name = name} | ||
function rule:deps() | ||
return deps | ||
end | ||
if type(cmd) == "string" then | ||
cmd = {"sh", "-c", cmd} | ||
end | ||
function rule:run() | ||
return runner:run(unpack(cmd)) | ||
end | ||
self:add(rule) | ||
end | ||
|
||
--add a rule generator | ||
--genfunc is a func which takes one argument (a name) and returns a rule | ||
--if the name does not match the generator pattern, genfunc should return nil | ||
--unmatched names will be passed to the next generator | ||
function ruletbl:addgenerator(genfunc) | ||
self.gen[#self.gen + 1] = genfunc | ||
end | ||
|
||
--returns whether file a is newer than b | ||
function ruletbl:cmptime(a, b) | ||
local res = lbuild_util:lbuild_util_isNewer(a, b) | ||
if res == 1 then | ||
return true | ||
else | ||
return false | ||
end | ||
end | ||
|
||
--run a dependency (as a promise) | ||
--value of promise is a boolean indicating whether the dep is newer or not | ||
function ruletbl:rundep(r, dep) | ||
local rt = self | ||
return promise(function(success, failure) | ||
rt:run(dep):prom(function() | ||
success(rt:cmptime(dep, r)) | ||
end, failure) | ||
end) | ||
end | ||
|
||
--run a rule (returns a promise) | ||
function ruletbl:run(name) | ||
local rt = self | ||
--get rule | ||
local rule = self.rules[name] | ||
if rule == nil then --rule not found - try to generate it | ||
local n = #self.gen | ||
while rule == nil and n ~= 0 do | ||
rule = self.gen[n](name) | ||
n = n - 1 | ||
end | ||
if rule == nil then --it wasn't found and could not be generated | ||
error("Rule " .. name .. " does not exist") | ||
end | ||
--add new rule to lookup table | ||
self.rules[name] = rule | ||
end | ||
return promise(function(success) | ||
if rule.state ~= nil then | ||
--if rule is already running (or done) dont start it again | ||
if rule.state == "done" then | ||
success() | ||
else | ||
if rule.cb ~= nil then | ||
rule.cb = {} | ||
end | ||
rule.cb[#rule.cb + 1] = success | ||
end | ||
else --otherwise start it | ||
--get dependencies | ||
rule.state = "deplookup" | ||
rule.cb = {success} | ||
local depcb = function(deps) | ||
rule.state = "deps" | ||
local runcb = function() | ||
for _, cb in ipairs(rule.cb) do | ||
cb() | ||
end | ||
end | ||
local n = #deps + 1 | ||
local ischng = false | ||
local startcb = function(chng) | ||
if chng then | ||
rule.state = "done" | ||
runcb() | ||
else | ||
rule:run():prom(runcb) | ||
end | ||
end | ||
local depfcb = function(chng) | ||
n = n - 1 | ||
ischng = ischng or chng | ||
if n == 0 then | ||
startcb(ischng) | ||
end | ||
end | ||
for _, dep in ipairs(deps) do | ||
rt:run(dep):prom(depfcb) | ||
end | ||
depfcb(false) | ||
end | ||
local dps = rule:deps() | ||
if dps == nil then | ||
depcb({}) | ||
elseif dps.prom ~= nil then | ||
dps:prom(depcb) | ||
else | ||
depcb(dps) | ||
end | ||
end | ||
end) | ||
end | ||
|
||
--add generator for rules for files that already exist | ||
ruletable:addgenerator(function(name) | ||
if lbuild_util.exists(name) then | ||
local rule = {} | ||
function rule:deps() | ||
return nil | ||
end | ||
function rule:run() | ||
return promise(function(s, f) | ||
s() | ||
end) | ||
end | ||
return rule | ||
end | ||
return nil | ||
end) | ||
|
||
return ruletable |
Oops, something went wrong.