From 750b6e152a0cfd446a707297125c5df3298abd65 Mon Sep 17 00:00:00 2001 From: Nathan DECHER Date: Sun, 13 Sep 2020 18:42:42 +0200 Subject: [PATCH] depend on amalg.lua to produce a single binary, fix #10 --- .gitignore | 1 + Alfons.moon | 2 +- Build.moon | 11 +- bin/moonbuild.lua | 3 +- bin/moonbuild.moon | 1 + moonbuild.lua | 989 +++++++++++++++++++++++++++++++++++++++ moonbuild/fsutil.lua | 155 ------ moonbuild/stringutil.lua | 52 -- moonbuild/tableutil.lua | 132 ------ moonbuild/util.lua | 189 -------- rock.yml | 7 +- 11 files changed, 1004 insertions(+), 538 deletions(-) create mode 100644 moonbuild.lua delete mode 100644 moonbuild/fsutil.lua delete mode 100644 moonbuild/stringutil.lua delete mode 100644 moonbuild/tableutil.lua delete mode 100644 moonbuild/util.lua diff --git a/.gitignore b/.gitignore index e69de29..35a954f 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/*/**.lua diff --git a/Alfons.moon b/Alfons.moon index c37d7e3..bf4520c 100644 --- a/Alfons.moon +++ b/Alfons.moon @@ -1,6 +1,6 @@ tasks: build: => - sh "moon bin/moonbuild.moon compile-lua" + sh "moon bin/moonbuild.moon compile" release: => error "no version provided" unless @v tasks.build! diff --git a/Build.moon b/Build.moon index 6f2ea55..50b23e6 100644 --- a/Build.moon +++ b/Build.moon @@ -1,5 +1,8 @@ -SOURCES_MOON = flatten {'bin/moonbuild.moon', wildcard 'moonbuild/**.moon'} +SOURCES_MOON = wildcard 'moonbuild/**.moon' +BINARY = 'bin/moonbuild.moon' OUT_LUA = patsubst SOURCES_MOON, '%.moon', '%.lua' +BINARY_LUA = patsubst BINARY, '%.moon', '%.lua' +OUT_AMALG = 'moonbuild.lua' public target 'clean', fn: => -rm '-f', OUT_LUA @@ -8,7 +11,11 @@ public target 'info', fn: => #echo "Moonscript sources:", SOURCES_MOON #echo "Compiled lua:", OUT_LUA -default target 'compile-lua', from: OUT_LUA +default target 'compile', from: OUT_AMALG + +target OUT_AMALG, from: {BINARY_LUA, OUT_LUA}, out: OUT_AMALG, fn: => + modules = foreach (patsubst OUT_LUA, '%.lua', '%'), => @gsub '/', '.' + -Command 'amalg.lua', '-o', @outfile, '-s', 'bin/moonbuild.lua', modules target '%.lua', in: '%.moon', out: '%.lua', fn: => -moonc @infile diff --git a/bin/moonbuild.lua b/bin/moonbuild.lua index 1b7446a..6bb558a 100644 --- a/bin/moonbuild.lua +++ b/bin/moonbuild.lua @@ -349,7 +349,8 @@ local buildscope = { insert(tdeps, f) end return BuildObject(name, tout, tin, tdeps, params.fn) - end + end, + Command = Command } for k, fn in pairs(util) do buildscope[k] = fn diff --git a/bin/moonbuild.moon b/bin/moonbuild.moon index 70c68d6..e265acc 100755 --- a/bin/moonbuild.moon +++ b/bin/moonbuild.moon @@ -146,6 +146,7 @@ buildscope= insert tin, f insert tdeps, f BuildObject name, tout, tin, tdeps, params.fn + :Command buildscope[k]=fn for k, fn in pairs util setmetatable buildscope, diff --git a/moonbuild.lua b/moonbuild.lua new file mode 100644 index 0000000..f2d09ca --- /dev/null +++ b/moonbuild.lua @@ -0,0 +1,989 @@ +do + +do +local _ENV = _ENV +package.preload[ "moonbuild.fsutil" ] = function( ... ) local arg = _G.arg; +local dir, attributes +do + local _obj_0 = require('lfs') + dir, attributes = _obj_0.dir, _obj_0.attributes +end +local gmatch, match, gsub, sub +do + local _obj_0 = string + gmatch, match, gsub, sub = _obj_0.gmatch, _obj_0.match, _obj_0.gsub, _obj_0.sub +end +local insert, concat +do + local _obj_0 = table + insert, concat = _obj_0.insert, _obj_0.concat +end +local ls +ls = function(d) + local _accum_0 = { } + local _len_0 = 1 + for f in dir(d) do + if f ~= '.' and f ~= '..' then + _accum_0[_len_0] = f + _len_0 = _len_0 + 1 + end + end + return _accum_0 +end +local lswithpath +lswithpath = function(d) + if d == '' then + return ls('.') + end + local _accum_0 = { } + local _len_0 = 1 + for f in dir(d) do + if f ~= '.' and f ~= '..' then + _accum_0[_len_0] = d .. '/' .. f + _len_0 = _len_0 + 1 + end + end + return _accum_0 +end +local exists +exists = function(f) + return (attributes(f)) ~= nil +end +local isdir +isdir = function(f) + local a = attributes(f) + return a and a.mode == 'directory' or false +end +local mtime +mtime = function(f) + local a = attributes(f) + return a and a.modification +end +local matchglob +matchglob = function(str, glob) + local patt = '^' .. (gsub((gsub(glob, '%*%*', '.*')), '%*', '[^/]*')) .. '$' + local rst + if (type(str)) == 'table' then + local results, i = { }, 1 + for _index_0 = 1, #str do + local s = str[_index_0] + rst = (match(s, patt)) and s + if rst then + results[i], i = rst, i + 1 + end + end + rst = results + else + rst = (match(str, patt)) and str + end + return rst +end +local wildcard +wildcard = function(glob) + local parts + do + local _accum_0 = { } + local _len_0 = 1 + for part in gmatch(glob, '[^/]+') do + _accum_0[_len_0] = part + _len_0 = _len_0 + 1 + end + parts = _accum_0 + end + local absolute = (sub(glob, 1, 1)) == '/' + for i, part in ipairs(parts) do + local prevpath = (absolute and '/' or '') .. concat(parts, '/', 1, i - 1) + local currpath = prevpath .. '/' .. part + if match(part, '%*%*.*%*%*') then + error("Two '**' in the same path component in a wildcard") + end + if match(part, '%*%*') then + local prefix = match(currpath, '^(.*)%*%*') + local suffix = (match(part, '%*%*(.*)$')) .. (i == #parts and '' or ('/' .. concat(parts, '/', i + 1, #parts))) + local files = lswithpath(prevpath) + local results = { } + for _index_0 = 1, #files do + local file = files[_index_0] + if matchglob(file, currpath) then + if i == #parts then + insert(results, file) + elseif isdir(file) then + local _list_0 = wildcard(file .. '/' .. concat(parts, '/', i + 1, #parts)) + for _index_1 = 1, #_list_0 do + local result = _list_0[_index_1] + insert(results, result) + end + end + end + if (matchglob(file, prefix .. '**')) and isdir(file) then + local _list_0 = wildcard(file .. '/**' .. suffix) + for _index_1 = 1, #_list_0 do + local result = _list_0[_index_1] + insert(results, result) + end + end + end + return results + end + if match(part, '%*') then + local files = lswithpath(prevpath) + if i == #parts then + return matchglob(files, glob) + end + local results = { } + for _index_0 = 1, #files do + local file = files[_index_0] + if (matchglob(file, currpath)) and isdir(file) then + local _list_0 = wildcard(file .. '/' .. concat(parts, '/', i + 1, #parts)) + for _index_1 = 1, #_list_0 do + local result = _list_0[_index_1] + insert(results, result) + end + end + end + return results + end + end + if exists(glob) then + return { + glob + } + else + return { } + end +end +return { + wildcard = wildcard, + exists = exists, + isdir = isdir, + mtime = mtime +} + +end +end + +do +local _ENV = _ENV +package.preload[ "moonbuild.stringutil" ] = function( ... ) local arg = _G.arg; +local match, gmatch, sub +do + local _obj_0 = string + match, gmatch, sub = _obj_0.match, _obj_0.gmatch, _obj_0.sub +end +local upper, lower +do + local _obj_0 = string + upper, lower = _obj_0.upper, _obj_0.lower +end +local GLOB_PATT = '^([^%%]*)%%([^%%]*)$' +local patsubst +patsubst = function(str, pattern, replacement) + if (type(str)) == 'table' then + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #str do + local s = str[_index_0] + _accum_0[_len_0] = patsubst(s, pattern, replacement) + _len_0 = _len_0 + 1 + end + return _accum_0 + end + local prefix, suffix = match(pattern, GLOB_PATT) + if not (prefix) then + return str + end + local reprefix, resuffix = match(replacement, GLOB_PATT) + if not (reprefix) then + return replacement + end + if (sub(str, 1, #prefix)) == prefix and (sub(str, -#suffix)) == suffix then + return reprefix .. (sub(str, #prefix + 1, -#suffix - 1)) .. resuffix + end + return str +end +local splitsp +splitsp = function(str) + local _accum_0 = { } + local _len_0 = 1 + for elem in gmatch(str, '%S+') do + _accum_0[_len_0] = elem + _len_0 = _len_0 + 1 + end + return _accum_0 +end +return { + patsubst = patsubst, + splitsp = splitsp, + upper = upper, + lower = lower +} + +end +end + +do +local _ENV = _ENV +package.preload[ "moonbuild.tableutil" ] = function( ... ) local arg = _G.arg; +local insert, remove, concat, sort +do + local _obj_0 = table + insert, remove, concat, sort = _obj_0.insert, _obj_0.remove, _obj_0.concat, _obj_0.sort +end +local unpack = unpack or table.unpack +local sortedpairs +sortedpairs = function(table, cmp) + local keys + do + local _accum_0 = { } + local _len_0 = 1 + for k in pairs(table) do + _accum_0[_len_0] = k + _len_0 = _len_0 + 1 + end + keys = _accum_0 + end + sort(keys, cmp) + return coroutine.wrap(function() + for _index_0 = 1, #keys do + local key = keys[_index_0] + coroutine.yield(key, table[key]) + end + end) +end +local min +min = function(table, cmp) + if cmp == nil then + cmp = function(a, b) + return a < b + end + end + local val = table[1] + for i = 2, #table do + local elem = table[i] + if cmp(val, elem) then + val = elem + end + end + return val +end +local max +max = function(table, cmp) + if cmp == nil then + cmp = function(a, b) + return a < b + end + end + local val = table[1] + for i = 2, #table do + local elem = table[i] + if not cmp(val, elem) then + val = elem + end + end + return val +end +local foreach +foreach = function(tab, fn) + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #tab do + local e = tab[_index_0] + _accum_0[_len_0] = fn(e) + _len_0 = _len_0 + 1 + end + return _accum_0 +end +local first +first = function(tab, fn) + for _index_0 = 1, #tab do + local e = tab[_index_0] + if fn(e) then + return e + end + end +end +local exclude +exclude = function(tab, ...) + local i = 1 + while i <= #tab do + local removed = false + for j = 1, select('#', ...) do + if tab[i] == select(j, ...) then + remove(tab, i) + removed = true + break + end + end + if not (removed) then + i = i + 1 + end + end + return tab +end +local flatten +flatten = function(tab) + if (type(tab)) ~= 'table' then + return { + tab + } + end + local out = { } + for _index_0 = 1, #tab do + local e = tab[_index_0] + if (type(e)) == 'table' then + local _list_0 = flatten(e) + for _index_1 = 1, #_list_0 do + local v = _list_0[_index_1] + insert(out, v) + end + else + insert(out, e) + end + end + return out +end +return { + min = min, + max = max, + foreach = foreach, + first = first, + exclude = exclude, + flatten = flatten, + sortedpairs = sortedpairs, + insert = insert, + remove = remove, + concat = concat, + sort = sort, + unpack = unpack +} + +end +end + +do +local _ENV = _ENV +package.preload[ "moonbuild.util" ] = function( ... ) local arg = _G.arg; +local wildcard, exists, isdir, mtime +do + local _obj_0 = require('moonbuild.fsutil') + wildcard, exists, isdir, mtime = _obj_0.wildcard, _obj_0.exists, _obj_0.isdir, _obj_0.mtime +end +local foreach, first, flatten, exclude, sortedpairs, min, max +do + local _obj_0 = require('moonbuild.tableutil') + foreach, first, flatten, exclude, sortedpairs, min, max = _obj_0.foreach, _obj_0.first, _obj_0.flatten, _obj_0.exclude, _obj_0.sortedpairs, _obj_0.min, _obj_0.max +end +local patsubst, splitsp +do + local _obj_0 = require('moonbuild.stringutil') + patsubst, splitsp = _obj_0.patsubst, _obj_0.splitsp +end +local insert, concat, sort, pairs +do + local _obj_0 = require('moonbuild.tableutil') + insert, concat, sort, pairs = _obj_0.insert, _obj_0.concat, _obj_0.sort, _obj_0.pairs +end +local upper, lower +do + local _obj_0 = require('moonbuild.stringutil') + upper, lower = _obj_0.upper, _obj_0.lower +end +local GLOB_PATT = '^([^%%]*)%%([^%%]*)$' +local escapecmdpart +escapecmdpart = function(p) + if (type(p)) == 'table' then + if p.raw then + return p.raw + end + return concat((function() + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #p do + local part = p[_index_0] + _accum_0[_len_0] = escapecmdpart(part) + _len_0 = _len_0 + 1 + end + return _accum_0 + end)(), ' ') + end + if p:match('^[a-zA-Z0-9_./-]+$') then + return p + end + return '"' .. p:gsub('\\', '\\\\'):gsub('"', '\\"') .. '"' +end +local escapecmd +escapecmd = function(c, args) + if args == nil then + args = { } + end + c = escapecmdpart(c) + local _list_0 = flatten(args) + for _index_0 = 1, #_list_0 do + local a = _list_0[_index_0] + if a then + c = c .. (' ' .. escapecmdpart(a)) + end + end + return c +end +local run +run = function(c, args, params) + if params == nil then + params = { } + end + local escaped = escapecmd(c, args) + if params.print then + print(escaped) + end + local ret, _, code = os.execute(escaped) + if (type(ret)) == 'number' then + ret, code = ret == 0, ret + end + if params.error and not ret then + error(tostring(c) .. " failed with code " .. tostring(code)) + end + return ret, code +end +local popen +popen = function(c, args, mode, params) + if mode == nil then + mode = 'r' + end + if params == nil then + params = { } + end + local escaped = escapecmd(c, args) + if params.print then + print(escaped) + end + return io.popen(escaped, mode) +end +local calccdeps +calccdeps = function(infile, includesys) + if includesys == nil then + includesys = false + end + local data = (popen('cc', { + includesys and '-M' or '-MM', + infile + })):read('*a') + local rawdeps = data:gsub('\\\n', ''):match(':(.+)') + local _accum_0 = { } + local _len_0 = 1 + for dep in rawdeps:gmatch('%S+') do + if dep ~= infile then + _accum_0[_len_0] = dep + _len_0 = _len_0 + 1 + end + end + return _accum_0 +end +local findclib +findclib = function(name, mode) + if mode == nil then + mode = 'all' + end + local args = { + name + } + if mode == 'all' or mode == 'cc' then + insert(args, '--cflags') + end + if mode == 'all' or mode == 'ld' then + insert(args, '--libs') + end + local _accum_0 = { } + local _len_0 = 1 + for arg in (popen('pkg-config', args)):read('*a'):gmatch('%S+') do + _accum_0[_len_0] = arg + _len_0 = _len_0 + 1 + end + return _accum_0 +end +local match +match = function(str, glob) + local prefix, suffix = glob:match(GLOB_PATT) + if not (prefix) then + return str == glob + end + if (str:sub(1, #prefix)) == prefix and (str:sub(-#suffix)) == suffix then + return str:sub(#prefix + 1, -#suffix - 1) + end + return false +end +local isglob +isglob = function(glob) + if glob:match(GLOB_PATT) then + return true + else + return false + end +end +local env +env = function(key, def) + return (os.getenv(key)) or def +end +return { + min = min, + max = max, + foreach = foreach, + first = first, + exclude = exclude, + flatten = flatten, + sortedpairs = sortedpairs, + insert = insert, + remove = remove, + concat = concat, + sort = sort, + unpack = unpack, + wildcard = wildcard, + mtime = mtime, + exists = exists, + isdir = isdir, + run = run, + popen = popen, + calccdeps = calccdeps, + findclib = findclib, + patsubst = patsubst, + splitsp = splitsp, + upper = upper, + lower = lower, + match = match, + isglob = isglob, + env = env +} + +end +end + +end + +local argparse = require('argparse') +require('moonscript') +local loadfile +loadfile = require('moonscript.base').loadfile +local truncate_traceback, rewrite_traceback +do + local _obj_0 = require('moonscript.errors') + truncate_traceback, rewrite_traceback = _obj_0.truncate_traceback, _obj_0.rewrite_traceback +end +local trim +trim = require('moonscript.util').trim +local util = require('moonbuild.util') +local exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs +exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs = util.exists, util.mtime, util.run, util.min, util.max, util.first, util.flatten, util.match, util.patsubst, util.sortedpairs +local insert, concat +do + local _obj_0 = table + insert, concat = _obj_0.insert, _obj_0.concat +end +local parser = argparse('moonbuild') +parser:argument('targets', "Targets to run"):args('*') +parser:flag('-a --noskip', "Always run targets") +parser:flag('-l --list', "List available targets") +parser:flag('-d --deps', "List targets and their dependancies") +local args = parser:parse() +local loadwithscope +loadwithscope = function(file, scope) + local fn, err = loadfile(file) + if not (fn) then + error(err or "failed to load code") + end + local dumped + dumped, err = string.dump(fn) + if not (dumped) then + error(err or "failed to dump function") + end + return load(dumped, file, 'b', scope) +end +local pcall +pcall = function(fn, ...) + local rewrite + rewrite = function(err) + local trace = debug.traceback('', 2) + local trunc = truncate_traceback(trim(trace)) + return rewrite_traceback(trunc, err) + end + return xpcall(fn, rewrite, ...) +end +local Command +do + local _class_0 + local _base_0 = { + __unm = function(self) + return self:run({ + error = true, + print = true + }) + end, + __len = function(self) + return self:run({ + error = true + }) + end, + __tostring = function(self) + return self.cmd + end, + run = function(self, params) + return run(self.cmd, self.args, params) + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self, cmd, ...) + self.cmd = cmd + self.args = { + ... + } + end, + __base = _base_0, + __name = "Command" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + local self = _class_0 + self.run = function(self, ...) + return -self(...) + end + Command = _class_0 +end +local BuildObject +do + local _class_0 + local all, skip + local _base_0 = { + __tostring = function(self) + return "Target " .. tostring(self.name) .. " (" .. tostring(concat(self.deps, ', ')) .. ")" + end, + build = function(self, name, upper) + if upper == nil then + upper = { } + end + if skip[name] then + return + end + if upper[self] then + error("Cycle detected on " .. tostring(self.name)) + end + upper = setmetatable({ + [self] = true + }, { + __index = upper + }) + if self.name ~= name then + local _list_0 = self.deps + for _index_0 = 1, #_list_0 do + local dep = _list_0[_index_0] + self.__class:build((patsubst(name, self.name, dep)), upper) + end + else + local _list_0 = self.deps + for _index_0 = 1, #_list_0 do + local dep = _list_0[_index_0] + self.__class:build(dep, upper) + end + end + if not (self:shouldbuild(name)) then + return + end + local ins = self.ins + local outs = self.outs + if self.name ~= name then + do + local _accum_0 = { } + local _len_0 = 1 + local _list_0 = self.ins + for _index_0 = 1, #_list_0 do + local elem = _list_0[_index_0] + _accum_0[_len_0] = patsubst(name, self.name, elem) + _len_0 = _len_0 + 1 + end + ins = _accum_0 + end + do + local _accum_0 = { } + local _len_0 = 1 + local _list_0 = self.outs + for _index_0 = 1, #_list_0 do + local elem = _list_0[_index_0] + _accum_0[_len_0] = patsubst(name, self.name, elem) + _len_0 = _len_0 + 1 + end + outs = _accum_0 + end + print("Building " .. tostring(self.name) .. " as " .. tostring(name)) + else + print("Building " .. tostring(name)) + end + local ok, err = pcall(function() + return self.fn({ + ins = ins, + outs = outs, + infile = ins[1], + outfile = outs[1], + name = name + }) + end) + if not (ok) then + error("Can't build " .. tostring(self.name) .. ": lua error\n" .. tostring(err)) + end + for _index_0 = 1, #outs do + local f = outs[_index_0] + if not (exists(f)) then + error("Can't build " .. tostring(self.name) .. ": output file " .. tostring(f) .. " not created") + end + end + skip[name] = true + end, + shouldbuild = function(self, name) + if args.noskip then + return true + end + if #self.ins == 0 or #self.outs == 0 then + return true + end + local ins + if self.name ~= name then + do + local _accum_0 = { } + local _len_0 = 1 + local _list_0 = self.ins + for _index_0 = 1, #_list_0 do + local elem = _list_0[_index_0] + _accum_0[_len_0] = patsubst(name, self.name, elem) + _len_0 = _len_0 + 1 + end + ins = _accum_0 + end + else + ins = self.ins + end + local itimes + do + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #ins do + local f = ins[_index_0] + _accum_0[_len_0] = mtime(f) + _len_0 = _len_0 + 1 + end + itimes = _accum_0 + end + for i = 1, #self.ins do + if not (itimes[i]) then + error("Can't build " .. tostring(self.name) .. ": missing inputs") + end + end + local outs + if self.name ~= name then + do + local _accum_0 = { } + local _len_0 = 1 + local _list_0 = self.outs + for _index_0 = 1, #_list_0 do + local elem = _list_0[_index_0] + _accum_0[_len_0] = patsubst(name, self.name, elem) + _len_0 = _len_0 + 1 + end + outs = _accum_0 + end + else + outs = self.outs + end + local otimes + do + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #outs do + local f = outs[_index_0] + _accum_0[_len_0] = mtime(f) + _len_0 = _len_0 + 1 + end + otimes = _accum_0 + end + for i = 1, #self.outs do + if not otimes[i] then + return true + end + end + return (max(itimes)) > (min(otimes)) + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self, name, outs, ins, deps, fn) + if outs == nil then + outs = { } + end + if ins == nil then + ins = { } + end + if deps == nil then + deps = { } + end + if fn == nil then + fn = function(self) end + end + self.name, self.outs, self.ins, self.deps, self.fn = name, outs, ins, deps, fn + self.skip = false + if all[self.name] then + error("Duplicate build name " .. tostring(self.name)) + end + all[self.name] = self + end, + __base = _base_0, + __name = "BuildObject" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + local self = _class_0 + all = { } + skip = { } + self.find = function(self, name) + local target = all[name] + if target then + return target + end + for glob, tgt in pairs(all) do + if match(name, glob) then + return tgt + end + end + return nil + end + self.list = function(self) + local _tbl_0 = { } + for name, target in pairs(all) do + do + local _tbl_1 = { } + local _list_0 = target.deps + for _index_0 = 1, #_list_0 do + local dep = _list_0[_index_0] + _tbl_1[dep] = self:find(dep) + end + _tbl_0[target] = _tbl_1 + end + end + return _tbl_0 + end + self.build = function(self, name, upper) + local target = (self:find(name)) or error("No such target: " .. tostring(name)) + return target:build(name, upper) + end + BuildObject = _class_0 +end +if setfenv then + error("Need Lua >=5.2") +end +local targets = { } +local defaulttarget = 'all' +local buildscope = { + default = function(target) + defaulttarget = target.name + return target + end, + public = function(target) + insert(targets, target.name) + return target + end, + target = function(name, params) + local tout = flatten(params.out) + local tin = flatten(params["in"]) + local tdeps = flatten(params.deps) + local _list_0 = flatten(params.from) + for _index_0 = 1, #_list_0 do + local f = _list_0[_index_0] + insert(tin, f) + insert(tdeps, f) + end + return BuildObject(name, tout, tin, tdeps, params.fn) + end, + Command = Command +} +for k, fn in pairs(util) do + buildscope[k] = fn +end +setmetatable(buildscope, { + __index = function(self, k) + local global = rawget(_G, k) + if global then + return global + end + return function(...) + return Command(k, ...) + end + end +}) +local file = first({ + 'Build.moon', + 'Buildfile.moon', + 'Build', + 'Buildfile' +}, exists) +if not (file) then + error("No Build.moon or Buildfile found") +end +local buildfn = loadwithscope(file, buildscope) +if not (buildfn) then + error("Failed to load build function") +end +local ok, err = pcall(buildfn) +if not (ok) then + if err then + io.stderr:write(err, '\n') + else + io.stderr:write("Unknown error\n") + end + os.exit(1) +end +if args.list then + io.write("Available targets:\n") + io.write("\t" .. tostring(concat(targets, ', ')) .. "\n") + os.exit(0) +end +if args.deps then + io.write("Targets:\n") + for target, deps in sortedpairs(BuildObject:list(), function(a, b) + return a.name < b.name + end) do + io.write("\t" .. tostring(target.name) .. " ") + if #target.ins == 0 then + if #target.outs == 0 then + io.write("[no in/out]") + else + io.write("[spontaneous generation]") + end + else + if #target.outs == 0 then + io.write("[consumer]") + else + io.write("(" .. tostring(concat(target.ins, ', ')) .. " -> " .. tostring(concat(target.outs, ', ')) .. ")") + end + end + io.write("\n") + for name, dep in sortedpairs(deps) do + io.write("\t\t" .. tostring(name) .. " (" .. tostring(dep.name) .. ")\n") + end + end + os.exit(0) +end +if #args.targets == 0 then + BuildObject:build(defaulttarget) +end +local _list_0 = args.targets +for _index_0 = 1, #_list_0 do + local target = _list_0[_index_0] + BuildObject:build(target) +end diff --git a/moonbuild/fsutil.lua b/moonbuild/fsutil.lua deleted file mode 100644 index f4de9ba..0000000 --- a/moonbuild/fsutil.lua +++ /dev/null @@ -1,155 +0,0 @@ -local dir, attributes -do - local _obj_0 = require('lfs') - dir, attributes = _obj_0.dir, _obj_0.attributes -end -local gmatch, match, gsub, sub -do - local _obj_0 = string - gmatch, match, gsub, sub = _obj_0.gmatch, _obj_0.match, _obj_0.gsub, _obj_0.sub -end -local insert, concat -do - local _obj_0 = table - insert, concat = _obj_0.insert, _obj_0.concat -end -local ls -ls = function(d) - local _accum_0 = { } - local _len_0 = 1 - for f in dir(d) do - if f ~= '.' and f ~= '..' then - _accum_0[_len_0] = f - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end -local lswithpath -lswithpath = function(d) - if d == '' then - return ls('.') - end - local _accum_0 = { } - local _len_0 = 1 - for f in dir(d) do - if f ~= '.' and f ~= '..' then - _accum_0[_len_0] = d .. '/' .. f - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end -local exists -exists = function(f) - return (attributes(f)) ~= nil -end -local isdir -isdir = function(f) - local a = attributes(f) - return a and a.mode == 'directory' or false -end -local mtime -mtime = function(f) - local a = attributes(f) - return a and a.modification -end -local matchglob -matchglob = function(str, glob) - local patt = '^' .. (gsub((gsub(glob, '%*%*', '.*')), '%*', '[^/]*')) .. '$' - local rst - if (type(str)) == 'table' then - local results, i = { }, 1 - for _index_0 = 1, #str do - local s = str[_index_0] - rst = (match(s, patt)) and s - if rst then - results[i], i = rst, i + 1 - end - end - rst = results - else - rst = (match(str, patt)) and str - end - return rst -end -local wildcard -wildcard = function(glob) - local parts - do - local _accum_0 = { } - local _len_0 = 1 - for part in gmatch(glob, '[^/]+') do - _accum_0[_len_0] = part - _len_0 = _len_0 + 1 - end - parts = _accum_0 - end - local absolute = (sub(glob, 1, 1)) == '/' - for i, part in ipairs(parts) do - local prevpath = (absolute and '/' or '') .. concat(parts, '/', 1, i - 1) - local currpath = prevpath .. '/' .. part - if match(part, '%*%*.*%*%*') then - error("Two '**' in the same path component in a wildcard") - end - if match(part, '%*%*') then - local prefix = match(currpath, '^(.*)%*%*') - local suffix = (match(part, '%*%*(.*)$')) .. (i == #parts and '' or ('/' .. concat(parts, '/', i + 1, #parts))) - local files = lswithpath(prevpath) - local results = { } - for _index_0 = 1, #files do - local file = files[_index_0] - if matchglob(file, currpath) then - if i == #parts then - insert(results, file) - elseif isdir(file) then - local _list_0 = wildcard(file .. '/' .. concat(parts, '/', i + 1, #parts)) - for _index_1 = 1, #_list_0 do - local result = _list_0[_index_1] - insert(results, result) - end - end - end - if (matchglob(file, prefix .. '**')) and isdir(file) then - local _list_0 = wildcard(file .. '/**' .. suffix) - for _index_1 = 1, #_list_0 do - local result = _list_0[_index_1] - insert(results, result) - end - end - end - return results - end - if match(part, '%*') then - local files = lswithpath(prevpath) - if i == #parts then - return matchglob(files, glob) - end - local results = { } - for _index_0 = 1, #files do - local file = files[_index_0] - if (matchglob(file, currpath)) and isdir(file) then - local _list_0 = wildcard(file .. '/' .. concat(parts, '/', i + 1, #parts)) - for _index_1 = 1, #_list_0 do - local result = _list_0[_index_1] - insert(results, result) - end - end - end - return results - end - end - if exists(glob) then - return { - glob - } - else - return { } - end -end -return { - wildcard = wildcard, - exists = exists, - isdir = isdir, - mtime = mtime -} diff --git a/moonbuild/stringutil.lua b/moonbuild/stringutil.lua deleted file mode 100644 index d5b4e35..0000000 --- a/moonbuild/stringutil.lua +++ /dev/null @@ -1,52 +0,0 @@ -local match, gmatch, sub -do - local _obj_0 = string - match, gmatch, sub = _obj_0.match, _obj_0.gmatch, _obj_0.sub -end -local upper, lower -do - local _obj_0 = string - upper, lower = _obj_0.upper, _obj_0.lower -end -local GLOB_PATT = '^([^%%]*)%%([^%%]*)$' -local patsubst -patsubst = function(str, pattern, replacement) - if (type(str)) == 'table' then - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #str do - local s = str[_index_0] - _accum_0[_len_0] = patsubst(s, pattern, replacement) - _len_0 = _len_0 + 1 - end - return _accum_0 - end - local prefix, suffix = match(pattern, GLOB_PATT) - if not (prefix) then - return str - end - local reprefix, resuffix = match(replacement, GLOB_PATT) - if not (reprefix) then - return replacement - end - if (sub(str, 1, #prefix)) == prefix and (sub(str, -#suffix)) == suffix then - return reprefix .. (sub(str, #prefix + 1, -#suffix - 1)) .. resuffix - end - return str -end -local splitsp -splitsp = function(str) - local _accum_0 = { } - local _len_0 = 1 - for elem in gmatch(str, '%S+') do - _accum_0[_len_0] = elem - _len_0 = _len_0 + 1 - end - return _accum_0 -end -return { - patsubst = patsubst, - splitsp = splitsp, - upper = upper, - lower = lower -} diff --git a/moonbuild/tableutil.lua b/moonbuild/tableutil.lua deleted file mode 100644 index ea771e6..0000000 --- a/moonbuild/tableutil.lua +++ /dev/null @@ -1,132 +0,0 @@ -local insert, remove, concat, sort -do - local _obj_0 = table - insert, remove, concat, sort = _obj_0.insert, _obj_0.remove, _obj_0.concat, _obj_0.sort -end -local unpack = unpack or table.unpack -local sortedpairs -sortedpairs = function(table, cmp) - local keys - do - local _accum_0 = { } - local _len_0 = 1 - for k in pairs(table) do - _accum_0[_len_0] = k - _len_0 = _len_0 + 1 - end - keys = _accum_0 - end - sort(keys, cmp) - return coroutine.wrap(function() - for _index_0 = 1, #keys do - local key = keys[_index_0] - coroutine.yield(key, table[key]) - end - end) -end -local min -min = function(table, cmp) - if cmp == nil then - cmp = function(a, b) - return a < b - end - end - local val = table[1] - for i = 2, #table do - local elem = table[i] - if cmp(val, elem) then - val = elem - end - end - return val -end -local max -max = function(table, cmp) - if cmp == nil then - cmp = function(a, b) - return a < b - end - end - local val = table[1] - for i = 2, #table do - local elem = table[i] - if not cmp(val, elem) then - val = elem - end - end - return val -end -local foreach -foreach = function(tab, fn) - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #tab do - local e = tab[_index_0] - _accum_0[_len_0] = fn(e) - _len_0 = _len_0 + 1 - end - return _accum_0 -end -local first -first = function(tab, fn) - for _index_0 = 1, #tab do - local e = tab[_index_0] - if fn(e) then - return e - end - end -end -local exclude -exclude = function(tab, ...) - local i = 1 - while i <= #tab do - local removed = false - for j = 1, select('#', ...) do - if tab[i] == select(j, ...) then - remove(tab, i) - removed = true - break - end - end - if not (removed) then - i = i + 1 - end - end - return tab -end -local flatten -flatten = function(tab) - if (type(tab)) ~= 'table' then - return { - tab - } - end - local out = { } - for _index_0 = 1, #tab do - local e = tab[_index_0] - if (type(e)) == 'table' then - local _list_0 = flatten(e) - for _index_1 = 1, #_list_0 do - local v = _list_0[_index_1] - insert(out, v) - end - else - insert(out, e) - end - end - return out -end -return { - min = min, - max = max, - foreach = foreach, - first = first, - exclude = exclude, - flatten = flatten, - sortedpairs = sortedpairs, - insert = insert, - remove = remove, - concat = concat, - sort = sort, - unpack = unpack -} diff --git a/moonbuild/util.lua b/moonbuild/util.lua deleted file mode 100644 index 0470d5a..0000000 --- a/moonbuild/util.lua +++ /dev/null @@ -1,189 +0,0 @@ -local wildcard, exists, isdir, mtime -do - local _obj_0 = require('moonbuild.fsutil') - wildcard, exists, isdir, mtime = _obj_0.wildcard, _obj_0.exists, _obj_0.isdir, _obj_0.mtime -end -local foreach, first, flatten, exclude, sortedpairs, min, max -do - local _obj_0 = require('moonbuild.tableutil') - foreach, first, flatten, exclude, sortedpairs, min, max = _obj_0.foreach, _obj_0.first, _obj_0.flatten, _obj_0.exclude, _obj_0.sortedpairs, _obj_0.min, _obj_0.max -end -local patsubst, splitsp -do - local _obj_0 = require('moonbuild.stringutil') - patsubst, splitsp = _obj_0.patsubst, _obj_0.splitsp -end -local insert, concat, sort, pairs -do - local _obj_0 = require('moonbuild.tableutil') - insert, concat, sort, pairs = _obj_0.insert, _obj_0.concat, _obj_0.sort, _obj_0.pairs -end -local upper, lower -do - local _obj_0 = require('moonbuild.stringutil') - upper, lower = _obj_0.upper, _obj_0.lower -end -local GLOB_PATT = '^([^%%]*)%%([^%%]*)$' -local escapecmdpart -escapecmdpart = function(p) - if (type(p)) == 'table' then - if p.raw then - return p.raw - end - return concat((function() - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #p do - local part = p[_index_0] - _accum_0[_len_0] = escapecmdpart(part) - _len_0 = _len_0 + 1 - end - return _accum_0 - end)(), ' ') - end - if p:match('^[a-zA-Z0-9_./-]+$') then - return p - end - return '"' .. p:gsub('\\', '\\\\'):gsub('"', '\\"') .. '"' -end -local escapecmd -escapecmd = function(c, args) - if args == nil then - args = { } - end - c = escapecmdpart(c) - local _list_0 = flatten(args) - for _index_0 = 1, #_list_0 do - local a = _list_0[_index_0] - if a then - c = c .. (' ' .. escapecmdpart(a)) - end - end - return c -end -local run -run = function(c, args, params) - if params == nil then - params = { } - end - local escaped = escapecmd(c, args) - if params.print then - print(escaped) - end - local ret, _, code = os.execute(escaped) - if (type(ret)) == 'number' then - ret, code = ret == 0, ret - end - if params.error and not ret then - error(tostring(c) .. " failed with code " .. tostring(code)) - end - return ret, code -end -local popen -popen = function(c, args, mode, params) - if mode == nil then - mode = 'r' - end - if params == nil then - params = { } - end - local escaped = escapecmd(c, args) - if params.print then - print(escaped) - end - return io.popen(escaped, mode) -end -local calccdeps -calccdeps = function(infile, includesys) - if includesys == nil then - includesys = false - end - local data = (popen('cc', { - includesys and '-M' or '-MM', - infile - })):read('*a') - local rawdeps = data:gsub('\\\n', ''):match(':(.+)') - local _accum_0 = { } - local _len_0 = 1 - for dep in rawdeps:gmatch('%S+') do - if dep ~= infile then - _accum_0[_len_0] = dep - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end -local findclib -findclib = function(name, mode) - if mode == nil then - mode = 'all' - end - local args = { - name - } - if mode == 'all' or mode == 'cc' then - insert(args, '--cflags') - end - if mode == 'all' or mode == 'ld' then - insert(args, '--libs') - end - local _accum_0 = { } - local _len_0 = 1 - for arg in (popen('pkg-config', args)):read('*a'):gmatch('%S+') do - _accum_0[_len_0] = arg - _len_0 = _len_0 + 1 - end - return _accum_0 -end -local match -match = function(str, glob) - local prefix, suffix = glob:match(GLOB_PATT) - if not (prefix) then - return str == glob - end - if (str:sub(1, #prefix)) == prefix and (str:sub(-#suffix)) == suffix then - return str:sub(#prefix + 1, -#suffix - 1) - end - return false -end -local isglob -isglob = function(glob) - if glob:match(GLOB_PATT) then - return true - else - return false - end -end -local env -env = function(key, def) - return (os.getenv(key)) or def -end -return { - min = min, - max = max, - foreach = foreach, - first = first, - exclude = exclude, - flatten = flatten, - sortedpairs = sortedpairs, - insert = insert, - remove = remove, - concat = concat, - sort = sort, - unpack = unpack, - wildcard = wildcard, - mtime = mtime, - exists = exists, - isdir = isdir, - run = run, - popen = popen, - calccdeps = calccdeps, - findclib = findclib, - patsubst = patsubst, - splitsp = splitsp, - upper = upper, - lower = lower, - match = match, - isglob = isglob, - env = env -} diff --git a/rock.yml b/rock.yml index e19e0c8..83c06ee 100644 --- a/rock.yml +++ b/rock.yml @@ -16,11 +16,6 @@ dependencies: - luafilesystem >= 1.7.0 build: type: builtin - modules: - moonbuild.util: moonbuild/util.lua - moonbuild.fsutil: moonbuild/fsutil.lua - moonbuild.stringutil: moonbuild/stringutil.lua - moonbuild.tableutil: moonbuild/tableutil.lua install: bin: - moonbuild: bin/moonbuild.lua + moonbuild: moonbuild.lua