mirror of
https://github.com/natnat-mc/moonbuild
synced 2026-05-28 18:49:40 +02:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 678313d09f | |||
| ebd380fb0f | |||
| 803d1093bb | |||
| ec5fc1cf7d | |||
| 17578bb721 | |||
| d3c8414086 | |||
| d43e9350d3 | |||
| 0f3506c7b7 | |||
| eb28c9c8bb | |||
| e0afeaaf07 | |||
| e13705f232 | |||
| c6004f1582 | |||
| ce942f9da8 | |||
| cc776ef24e | |||
| 603d09fc84 | |||
| 2b3337fc69 | |||
| 5518c61fc1 | |||
| 81baa03624 | |||
| 77f73f3a21 | |||
| 31fcc58ccd | |||
| fcf7c3fa07 | |||
| 88a8117f06 | |||
| 69e781bc8f | |||
| ee0d76db98 | |||
| 6a6334fc78 | |||
| e5bd85933a | |||
| 50d0c662c5 | |||
| f742a3c003 | |||
| fcd3b07572 | |||
| b1f57c8929 | |||
| d31e5a9615 | |||
| 89db21b79e | |||
| 389627b430 | |||
| b2f0de7b38 | |||
| c8670ab903 | |||
| ceada11b0b | |||
| e7251a5b55 | |||
| 7203d38bdb | |||
| 80a5c54032 | |||
| 0779ea3ad4 | |||
| e3e185110a | |||
| 7b4973f0b4 | |||
| c96b2ece70 | |||
| 0e23ccecfb | |||
| ccce358155 | |||
| a125eab22f | |||
| 0c43e3a5b1 | |||
| cf252749f4 | |||
| 16673afc61 | |||
| a26a1500df | |||
| d2db470347 | |||
| b80e9d38bb | |||
| 61f32c0675 | |||
| 04ca1f5a10 | |||
| ffce216a34 |
+3
-1
@@ -1 +1,3 @@
|
|||||||
/*/**.lua
|
bin/*.lua
|
||||||
|
moonbuild/*.lua
|
||||||
|
moonbuild/*/*.lua
|
||||||
|
|||||||
+8
-2
@@ -1,7 +1,13 @@
|
|||||||
|
require 'moonscript'
|
||||||
|
moonbuild = require 'moonbuild'
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
build: =>
|
|
||||||
sh "moon bin/moonbuild.moon compile"
|
|
||||||
release: =>
|
release: =>
|
||||||
error "no version provided" unless @v
|
error "no version provided" unless @v
|
||||||
tasks.build!
|
tasks.build!
|
||||||
sh "rockbuild -m -t #{@v} upload"
|
sh "rockbuild -m -t #{@v} upload"
|
||||||
|
|
||||||
|
build: => moonbuild j: true
|
||||||
|
install: => moonbuild 'install', j: true
|
||||||
|
clean: => moonbuild 'clean'
|
||||||
|
mrproper: => moonbuild 'mrproper'
|
||||||
|
|||||||
+57
-16
@@ -1,21 +1,62 @@
|
|||||||
SOURCES_MOON = wildcard 'moonbuild/**.moon'
|
public var AMALG: 'amalg.lua'
|
||||||
BINARY = 'bin/moonbuild.moon'
|
public var RM: 'rm', '-f', '--'
|
||||||
OUT_LUA = patsubst SOURCES_MOON, '%.moon', '%.lua'
|
public var LUA: 'lua5.3'
|
||||||
BINARY_LUA = patsubst BINARY, '%.moon', '%.lua'
|
|
||||||
OUT_AMALG = 'moonbuild.lua'
|
|
||||||
|
|
||||||
public target 'clean', fn: =>
|
var LIB_SRC: _.wildcard 'moonbuild/**.moon'
|
||||||
-rm '-f', OUT_LUA
|
var BIN_SRC: _.wildcard 'bin/*.moon'
|
||||||
|
|
||||||
public target 'info', fn: =>
|
var LIB_LUA: _.patsubst LIB_SRC, '%.moon', '%.lua'
|
||||||
#echo "Moonscript sources:", SOURCES_MOON
|
var BIN_LUA: _.patsubst BIN_SRC, '%.moon', '%.lua'
|
||||||
#echo "Compiled lua:", OUT_LUA
|
var BIN: _.patsubst BIN_LUA, 'bin/%.lua', 'out/%'
|
||||||
|
var LIB: 'out/moonbuild.lua'
|
||||||
|
|
||||||
default target 'compile', from: OUT_AMALG
|
var MODULES: _.foreach (_.patsubst LIB_LUA, '%.lua', '%'), => @gsub '/', '.'
|
||||||
|
|
||||||
target OUT_AMALG, from: {BINARY_LUA, OUT_LUA}, out: OUT_AMALG, fn: =>
|
with public default target 'all'
|
||||||
modules = foreach (patsubst OUT_LUA, '%.lua', '%'), => @gsub '/', '.'
|
\after 'bin'
|
||||||
-Command 'amalg.lua', '-o', @outfile, '-s', 'bin/moonbuild.lua', modules
|
\after 'lib'
|
||||||
|
|
||||||
target '%.lua', in: '%.moon', out: '%.lua', fn: =>
|
with public target 'install'
|
||||||
-moonc @infile
|
\after 'install-bin'
|
||||||
|
\after 'install-lib'
|
||||||
|
|
||||||
|
with public target 'install-bin'
|
||||||
|
\depends BIN
|
||||||
|
\produces _.patsubst BIN, 'out/%', '/usr/local/bin/%'
|
||||||
|
\fn => _.cmd 'sudo', 'cp', @infile, @out
|
||||||
|
\sync!
|
||||||
|
|
||||||
|
with public target 'install-lib'
|
||||||
|
\depends LIB
|
||||||
|
\produces "/usr/local/share/lua/#{LUA\gsub 'lua', ''}/moonbuild.lua"
|
||||||
|
\fn => _.cmd 'sudo', 'cp', @infile, @out
|
||||||
|
\sync!
|
||||||
|
|
||||||
|
with public target 'clean'
|
||||||
|
\fn => _.cmd RM, LIB_LUA
|
||||||
|
\fn => _.cmd RM, BIN_LUA
|
||||||
|
|
||||||
|
with public target 'mrproper'
|
||||||
|
\after 'clean'
|
||||||
|
\fn => _.cmd RM, BIN, LIB
|
||||||
|
|
||||||
|
with pipeline! -- lib
|
||||||
|
\sources LIB_SRC
|
||||||
|
\step 'compile-lib'
|
||||||
|
pattern: {'%.moon', '%.lua'}
|
||||||
|
fn: => _.moonc @infile, @out
|
||||||
|
\step 'lib'
|
||||||
|
output: LIB
|
||||||
|
fn: => _.cmd AMALG, '-o', @out, '-s', 'moonbuild/init.lua', _.exclude MODULES, 'moonbuild.init'
|
||||||
|
|
||||||
|
with pipeline! -- bin
|
||||||
|
\sources BIN_SRC
|
||||||
|
\step 'compile-bin'
|
||||||
|
pattern: {'%.moon', '%.lua'}
|
||||||
|
fn: => _.moonc @infile, @out
|
||||||
|
\step 'bin'
|
||||||
|
pattern: {'bin/%.lua', 'out/%'}
|
||||||
|
mkdirs: true
|
||||||
|
fn: =>
|
||||||
|
_.writefile @out, "#!/usr/bin/env #{LUA}\n#{_.readfile @infile}"
|
||||||
|
_.cmd 'chmod', '+x', @out
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
.PHONY: all clean mrproper bin lib
|
||||||
|
|
||||||
|
MOONC = moonc
|
||||||
|
AMALG = amalg.lua
|
||||||
|
RM = rm -f --
|
||||||
|
LUA = lua5.3
|
||||||
|
|
||||||
|
LIB_SRC = $(wildcard moonbuild/*.moon) $(wildcard moonbuild/*/*.moon) $(wildcard moonbuild/*/*/*.moon)
|
||||||
|
BIN_SRC = $(wildcard bin/*.moon)
|
||||||
|
|
||||||
|
LIB_LUA = $(foreach moon, $(LIB_SRC), $(patsubst %.moon, %.lua, $(moon)))
|
||||||
|
BIN_LUA = $(foreach moon, $(BIN_SRC), $(patsubst %.moon, %.lua, $(moon)))
|
||||||
|
BIN = $(foreach lua, $(BIN_LUA), $(patsubst bin/%.lua, out/%, $(lua)))
|
||||||
|
|
||||||
|
MODULES = $(shell echo $(foreach lib, $(LIB_LUA), $(patsubst %.lua, %, $(lib))) | sed 's|/|.|g')
|
||||||
|
|
||||||
|
all: bin lib
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(LIB_LUA)
|
||||||
|
$(RM) $(BIN_LUA)
|
||||||
|
|
||||||
|
mrproper: clean
|
||||||
|
$(RM) $(BIN) out/moonbuild.lua
|
||||||
|
|
||||||
|
bin: $(BIN)
|
||||||
|
|
||||||
|
lib: $(LIB_LUA) out/moonbuild.lua
|
||||||
|
|
||||||
|
out/%: bin/%.lua $(LIB_LUA)
|
||||||
|
@mkdir -p `dirname $@`
|
||||||
|
@printf '#!/usr/bin/env %s\n' $(LUA) > $@.headline
|
||||||
|
@cat $@.headline $< > $@
|
||||||
|
@rm $@.headline
|
||||||
|
chmod +x $@
|
||||||
|
|
||||||
|
out/moonbuild.lua: moonbuild/init.lua $(LIB_LUA)
|
||||||
|
@mkdir -p `dirname $@`
|
||||||
|
$(AMALG) -o $@ -s $< $(MODULES)
|
||||||
|
|
||||||
|
%.lua: %.moon
|
||||||
|
moonc $^
|
||||||
@@ -1,115 +1,36 @@
|
|||||||
# Moonbuild
|
# moonbuild
|
||||||
Because `make` is painful to use, and build scripts are too slow. Moonbuild aims to be a good compromise.
|
**Now in v2 - complete rework from v1**
|
||||||
|
|
||||||
You should probably use [`tup`](http://gittup.org/tup/) instead if you want a good build system.
|
Because `make` is painful to use, and build scripts are too slow. Moonbuild aims to be a good compromise.
|
||||||
|
You should probably use [http://gittup.org/tup/](tup) instead if you want a good build system.
|
||||||
|
|
||||||
## How does it work?
|
## How does it work?
|
||||||
Basically like `make`, but in [Moonscript](https://moonscript.org) and with explicit ordering. See its `Build.moon` for examples (and you can compare it with the `Makefile`, both do the same thing).
|
`moonbuild` reads a build file, usually `Build.moon` that is written in a Moonscript DSL to define its targets and variables.
|
||||||
|
It then builds a DAG for the dependancies of the targets you tell it to build.
|
||||||
|
Then, it tries building every target in the graph while respecting dependancies, possibly on multiple processes.
|
||||||
|
|
||||||
## Why moonscript?
|
Essentially, it works the same way as `make`, just with a different language, you can compare the `Build.moon` and `Makefile` in this repo to see for yourself.
|
||||||
It's fast, based on lua, and it's easy to write DSLs with it, so the build instructions can be readable. Also, it's a full programming language, so there are no arbitrary restrictions.
|
|
||||||
|
|
||||||
## How do I install it?
|
## Why Moonscript?
|
||||||
- `luarocks install moonbuild` (probably as root)
|
Because it's fast, based on lua, and making DSLs with it is relatively easy.
|
||||||
|
It's also a language I like a lot, so I might have been biased when choosing it.
|
||||||
|
|
||||||
## Now, how do I use it?
|
## Installing
|
||||||
First, you'll need a `Build.moon`, `Buildfile.moon`, `Build` or `Buildfile` in the root of your project.
|
It is available on luarocks with `luarocks install moonbuild`.
|
||||||
Then, you'll need a few `target`s, and ideally a `default target` (or the default target will be `all`). `public target`s will be listed by `moonbuild -l`.
|
It is also recommended to install `luaposix` if you can, as it speeds it up a lot, or `luafilesystem` in case it isn't available.
|
||||||
To execute a command, you can use either `-cmd` or `#cmd` (the former will print it before executing it, the later won't).
|
|
||||||
|
|
||||||
### `[default] [public] target <name> [deps: <deps>] [in: <inputs>] [out: <outputs>] [from: <from>] [fn: <code>]`
|
## Building from source
|
||||||
Define a new target, and give it a list of depenancies, inputs, outputs and a function to run to build it.
|
You will need `argparse` and `moonscript` installed from luarocks, and `luaposix` or `luafilesystem` are recommended.
|
||||||
|
|
||||||
`deps`, `in` and `out` can be either strings or tables. `from` acts like both `in` and `deps`. `name` must be a string and `code` must be a function, that will be given a table with the following fields:
|
### Bootstrapping
|
||||||
- `name`: the name of the target
|
You can build moonbuild with itself: `moon bin/moonbuild.moon -qjy`.
|
||||||
- `ins`: the table of inputs
|
This will leave the binary ready to be used as `out/moonbuild` (it will still depend on the library to be used).
|
||||||
- `infile`: the first input
|
The binary and library can then be installed with `bin/moonbuild install`.
|
||||||
- `outs`: the table of outputs
|
|
||||||
- `outfile`: the first output
|
|
||||||
|
|
||||||
If `name` is a glob, the target becomes a glob target.
|
You can combine these steps with `moon bin/moonbuild.moon -qjy install` which will build and install moonbuild.
|
||||||
Glob targets can be used with name that matches them (with a limit of one glob target per name, and no ordering is specified).
|
|
||||||
Glob targets will have their name substituted for their inputs, outputs and dependancies.
|
|
||||||
|
|
||||||
### `-cmd [<args>...]`
|
### With `Alfons`
|
||||||
Prints and executes the command `cmd` with the given args. See `run` for how `args` works.
|
Alfons can use the devel version of moonbuild directly from its sources, so `alfons build` and `alfons install` will work directly.
|
||||||
|
|
||||||
### `#cmd [<args>...]`
|
## Docs
|
||||||
Executes without printing the command `cmd` with the given args. See `run` for how `args` works.
|
TODO
|
||||||
|
|
||||||
### `wildcard <wc>`
|
|
||||||
Returns a table with all the matching files. Valid wildcards contain `**`, which can be expanded by any characters, including '/', and `*`, which cannot be expanded by `/`.
|
|
||||||
|
|
||||||
`wc` must be a string
|
|
||||||
|
|
||||||
### `exclude <list> [<exclusions>...]`
|
|
||||||
Removes all exclusions from the given list, and returns it.
|
|
||||||
|
|
||||||
`list` must be a table, and `exclusions` can be any type
|
|
||||||
|
|
||||||
### `patsubst <str> <patt> <subst>`
|
|
||||||
If the string matches `patt`, makes it match `subst` instead. If `str` is a table, it is recursively applied to all array values.
|
|
||||||
|
|
||||||
Patterns are in the format `[prefix]%[suffix]`, with the `%` representing any sequence of characters, including `/`.
|
|
||||||
|
|
||||||
`str`, `pat` and `subst` must be strings
|
|
||||||
|
|
||||||
### `foreach <table> <code>`
|
|
||||||
Applies `code` to every element of `table`, and returns the resulting table.
|
|
||||||
|
|
||||||
`table` must be a table, and `code` a function.
|
|
||||||
|
|
||||||
### `min|max <table>`
|
|
||||||
Returns either the min or max value of the given table.
|
|
||||||
|
|
||||||
`table` must be a table
|
|
||||||
|
|
||||||
### `first <table> <code>`
|
|
||||||
Returns the first value of the table that verifies the given condition.
|
|
||||||
|
|
||||||
`table` must be a table, and `code` a function
|
|
||||||
|
|
||||||
### `flatten <table>`
|
|
||||||
Flattens a table so that it has exactly one dimension.
|
|
||||||
|
|
||||||
`table` can be anything
|
|
||||||
|
|
||||||
### `insert|unpack|concat`
|
|
||||||
The functions, imported from the `table` library.
|
|
||||||
|
|
||||||
### `mtime <file>`
|
|
||||||
Returns the modification time of `file`, or `nil` if it doesn't exist.
|
|
||||||
|
|
||||||
`file` must be a string
|
|
||||||
|
|
||||||
### `exists <file>`
|
|
||||||
Returns `true` if the file exists, `false` otherwise.
|
|
||||||
|
|
||||||
`file` must be a string
|
|
||||||
|
|
||||||
|
|
||||||
### `isdir <file>`
|
|
||||||
Returns `true` if the file exists and is a directory, `false` otherwise.
|
|
||||||
|
|
||||||
`file` must be a string
|
|
||||||
|
|
||||||
### `run <cmd> [<args> [print: <print>] [error: <error>]]`
|
|
||||||
Runs the given command with the given arguments. If `print` is truthy, prints the command before executing it, and if `error` is truthy, crashes if the command fails. Returns a boolean which is true if the command ended with success, and a number which is the return code.
|
|
||||||
|
|
||||||
`cmd` must be a string, `args` must be a table, which can contain either strings or other tables. `raw: <val>` is a special kind of argument that will not be escaped. `print` and `error` can be anything, but booleans or nil are recommended
|
|
||||||
|
|
||||||
### `popen <cmd> [<args> [print: <print>]]`
|
|
||||||
Same as `run`, but returns a `io.popen` handle.
|
|
||||||
|
|
||||||
### `calccdeps <infile> [includesys]`
|
|
||||||
Computes the dependancies required to compile a C source file. Optionally include system libraries as sources.
|
|
||||||
|
|
||||||
`infile` must be a string and `includesys` must be a boolean or `nil`
|
|
||||||
|
|
||||||
### `findclib <lib> [what]`
|
|
||||||
Finds the compiler or linker flags required to use a given C library.
|
|
||||||
|
|
||||||
`lib` must be a string and `what` must be either `nil`, `'all'`, `'cc'` or `'ld'`
|
|
||||||
|
|
||||||
## License
|
|
||||||
MIT
|
|
||||||
|
|||||||
@@ -1,429 +0,0 @@
|
|||||||
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
|
|
||||||
Executable → Regular
+70
-187
@@ -1,197 +1,80 @@
|
|||||||
#!/usr/bin/env moon
|
-- load everything we need
|
||||||
|
|
||||||
argparse=require 'argparse'
|
|
||||||
|
|
||||||
require 'moonscript'
|
|
||||||
import loadfile from require 'moonscript.base'
|
import loadfile from require 'moonscript.base'
|
||||||
import truncate_traceback, rewrite_traceback from require 'moonscript.errors'
|
import Context, DepGraph, Executor from require 'moonbuild'
|
||||||
import trim from require 'moonscript.util'
|
Variable = (require 'moonbuild')['core.Variable']
|
||||||
|
import parseargs from (require 'moonbuild')['_cmd.common']
|
||||||
|
argparse = require 'argparse'
|
||||||
|
import sort, concat from table
|
||||||
|
import exit from os
|
||||||
|
|
||||||
util=require 'moonbuild.util'
|
-- parse the arguments
|
||||||
import exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs from util
|
parser = with argparse "moonbuild", "A build system in moonscript"
|
||||||
|
\option '-b --buildfile', "Build file to use", 'Build.moon'
|
||||||
|
\option '-j --parallel', "Sets the number of parallel tasks, 'y' to run as many as we have cores", '1'
|
||||||
|
\flag '-l --list', "List the targets", false
|
||||||
|
\flag '-V --list-variables', "List the variables", false
|
||||||
|
\flag '-q --quiet', "Don't print targets as they are being built", false
|
||||||
|
\flag '-f --force', "Always rebuild every target", false
|
||||||
|
\flag '-v --verbose', "Be verbose", false
|
||||||
|
(\option '-u --unset', "Unsets a variable")\count '*'
|
||||||
|
(\option '-s --set', "Sets a variable")\args(2)\count '*'
|
||||||
|
(\option '-S --set-list', "Sets a variable to a list")\args(2)\count '*'
|
||||||
|
(\argument 'targets', "Targets to build")\args '*'
|
||||||
|
\add_complete!
|
||||||
|
|
||||||
import insert, concat from table
|
args = parser\parse!
|
||||||
|
|
||||||
parser=argparse 'moonbuild'
|
overrides = {}
|
||||||
parser\argument('targets', "Targets to run")\args '*'
|
for unset in *args.unset
|
||||||
parser\flag '-a --noskip', "Always run targets"
|
overrides[unset] = Variable.NIL
|
||||||
parser\flag '-l --list', "List available targets"
|
for set in *args.set
|
||||||
parser\flag '-d --deps', "List targets and their dependancies"
|
overrides[set[1]] = set[2]
|
||||||
args=parser\parse!
|
for set in *args.set_list
|
||||||
|
overrides[set[1]] = parseargs set[2]
|
||||||
|
|
||||||
-- util functions
|
args.parallel = args.parallel == 'y' and 'y' or ((tonumber args.parallel) or error "Invalid argument for -j: #{args.parallel}")
|
||||||
loadwithscope= (file, scope) ->
|
error "Invalid argument for -j: #{args.parallel}" if args.parallel != 'y' and (args.parallel<1 or args.parallel%1 != 0)
|
||||||
fn, err=loadfile file
|
print "Parsed CLI args" if args.verbose
|
||||||
error err or "failed to load code" unless fn
|
|
||||||
dumped, err=string.dump fn
|
|
||||||
error err or "failed to dump function" unless dumped
|
|
||||||
load dumped, file, 'b', scope
|
|
||||||
pcall= (fn, ...) ->
|
|
||||||
rewrite=(err) ->
|
|
||||||
trace=debug.traceback '', 2
|
|
||||||
trunc=truncate_traceback trim trace
|
|
||||||
rewrite_traceback trunc, err
|
|
||||||
xpcall fn, rewrite, ...
|
|
||||||
|
|
||||||
-- command object
|
-- load the buildfile
|
||||||
-- represents a command that can be called
|
ctx = Context!
|
||||||
class Command
|
ctx\load (loadfile args.buildfile), overrides
|
||||||
new: (@cmd, ...) =>
|
print "Loaded buildfile" if args.verbose
|
||||||
@args={...}
|
|
||||||
|
|
||||||
__unm: => @run error: true, print: true
|
|
||||||
__len: => @run error: true
|
|
||||||
__tostring: => @cmd
|
|
||||||
|
|
||||||
run: (params) => run @cmd, @args, params
|
|
||||||
@run: (...) => -@ ...
|
|
||||||
|
|
||||||
-- build object
|
|
||||||
-- represents a target
|
|
||||||
class BuildObject
|
|
||||||
all={}
|
|
||||||
skip={}
|
|
||||||
|
|
||||||
@find: (name) =>
|
|
||||||
target=all[name]
|
|
||||||
return target if target
|
|
||||||
for glob, tgt in pairs all
|
|
||||||
return tgt if match name, glob
|
|
||||||
nil
|
|
||||||
|
|
||||||
@list: =>
|
|
||||||
{target, {dep, @find dep for dep in *target.deps} for name, target in pairs all}
|
|
||||||
|
|
||||||
@build: (name, upper) =>
|
|
||||||
target=(@find name) or error "No such target: #{name}"
|
|
||||||
target\build name, upper
|
|
||||||
|
|
||||||
__tostring: =>
|
|
||||||
"Target #{@name} (#{concat @deps, ', '})"
|
|
||||||
|
|
||||||
new: (@name, @outs={}, @ins={}, @deps={}, @fn= =>) =>
|
|
||||||
@skip=false
|
|
||||||
error "Duplicate build name #{@name}" if all[@name]
|
|
||||||
all[@name]=@
|
|
||||||
|
|
||||||
build: (name, upper={}) =>
|
|
||||||
return if skip[name]
|
|
||||||
error "Cycle detected on #{@name}" if upper[@]
|
|
||||||
upper = setmetatable {[@]: true}, __index: upper
|
|
||||||
if @name!=name
|
|
||||||
@@build (patsubst name, @name, dep), upper for dep in *@deps
|
|
||||||
else
|
|
||||||
@@build dep, upper for dep in *@deps
|
|
||||||
return unless @shouldbuild name
|
|
||||||
|
|
||||||
ins=@ins
|
|
||||||
outs=@outs
|
|
||||||
if @name!=name
|
|
||||||
ins=[patsubst name, @name, elem for elem in *@ins]
|
|
||||||
outs=[patsubst name, @name, elem for elem in *@outs]
|
|
||||||
print "Building #{@name} as #{name}"
|
|
||||||
else
|
|
||||||
print "Building #{name}"
|
|
||||||
ok, err=pcall ->
|
|
||||||
@.fn
|
|
||||||
ins: ins
|
|
||||||
outs: outs
|
|
||||||
infile: ins[1]
|
|
||||||
outfile: outs[1]
|
|
||||||
name: name
|
|
||||||
error "Can't build #{@name}: lua error\n#{err}" unless ok
|
|
||||||
for f in *outs
|
|
||||||
error "Can't build #{@name}: output file #{f} not created" unless exists f
|
|
||||||
skip[name]=true
|
|
||||||
|
|
||||||
shouldbuild: (name) =>
|
|
||||||
return true if args.noskip
|
|
||||||
return true if #@ins==0 or #@outs==0
|
|
||||||
|
|
||||||
ins=if @name!=name
|
|
||||||
[patsubst name, @name, elem for elem in *@ins]
|
|
||||||
else
|
|
||||||
@ins
|
|
||||||
itimes=[mtime f for f in *ins]
|
|
||||||
for i=1, #@ins
|
|
||||||
error "Can't build #{@name}: missing inputs" unless itimes[i]
|
|
||||||
|
|
||||||
outs=if @name!=name
|
|
||||||
[patsubst name, @name, elem for elem in *@outs]
|
|
||||||
else
|
|
||||||
@outs
|
|
||||||
otimes=[mtime f for f in *outs]
|
|
||||||
for i=1, #@outs
|
|
||||||
return true if not otimes[i]
|
|
||||||
|
|
||||||
(max itimes)>(min otimes)
|
|
||||||
|
|
||||||
error "Need Lua >=5.2" if setfenv
|
|
||||||
|
|
||||||
targets={}
|
|
||||||
defaulttarget='all'
|
|
||||||
|
|
||||||
buildscope=
|
|
||||||
default: (target) ->
|
|
||||||
defaulttarget=target.name
|
|
||||||
target
|
|
||||||
public: (target) ->
|
|
||||||
insert targets, target.name
|
|
||||||
target
|
|
||||||
target: (name, params) ->
|
|
||||||
tout=flatten params.out
|
|
||||||
tin=flatten params.in
|
|
||||||
tdeps=flatten params.deps
|
|
||||||
for f in *flatten params.from
|
|
||||||
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,
|
|
||||||
__index: (k) =>
|
|
||||||
global=rawget _G, k
|
|
||||||
return global if global
|
|
||||||
(...) -> Command k, ...
|
|
||||||
|
|
||||||
file=first {'Build.moon', 'Buildfile.moon', 'Build', 'Buildfile'}, exists
|
|
||||||
error "No Build.moon or Buildfile found" unless file
|
|
||||||
buildfn=loadwithscope file, buildscope
|
|
||||||
error "Failed to load build function" unless buildfn
|
|
||||||
ok, err=pcall buildfn
|
|
||||||
unless ok
|
|
||||||
if err
|
|
||||||
io.stderr\write err, '\n'
|
|
||||||
else
|
|
||||||
io.stderr\write "Unknown error\n"
|
|
||||||
os.exit 1
|
|
||||||
|
|
||||||
|
-- handle -l and -V
|
||||||
if args.list
|
if args.list
|
||||||
io.write "Available targets:\n"
|
print "Public targets"
|
||||||
io.write "\t#{concat targets, ', '}\n"
|
targets, n = {}, 1
|
||||||
os.exit 0
|
for t in *ctx.targets
|
||||||
|
if t.public
|
||||||
|
targets[n], n = t.name, n+1
|
||||||
|
sort targets
|
||||||
|
print concat targets, ", "
|
||||||
|
print!
|
||||||
|
exit 0 unless args.list_variables
|
||||||
|
if args.list_variables
|
||||||
|
print "Public variables"
|
||||||
|
vars, n = {}, 1
|
||||||
|
for k, v in pairs ctx.variables
|
||||||
|
if v.public
|
||||||
|
vars[n], n = k, n+1
|
||||||
|
sort vars
|
||||||
|
print concat vars, ", "
|
||||||
|
print!
|
||||||
|
exit 0
|
||||||
|
|
||||||
if args.deps
|
-- initialize the buildfile further
|
||||||
io.write "Targets:\n"
|
ctx\init!
|
||||||
for target, deps in sortedpairs BuildObject\list!, (a, b) -> a.name<b.name
|
print "Initialized buildfile" if args.verbose
|
||||||
io.write "\t#{target.name} "
|
|
||||||
if #target.ins==0
|
|
||||||
if #target.outs==0
|
|
||||||
io.write "[no in/out]"
|
|
||||||
else
|
|
||||||
io.write "[spontaneous generation]"
|
|
||||||
else
|
|
||||||
if #target.outs==0
|
|
||||||
io.write "[consumer]"
|
|
||||||
else
|
|
||||||
io.write "(#{concat target.ins, ', '} -> #{concat target.outs, ', '})"
|
|
||||||
io.write "\n"
|
|
||||||
for name, dep in sortedpairs deps
|
|
||||||
io.write "\t\t#{name} (#{dep.name})\n"
|
|
||||||
os.exit 0
|
|
||||||
|
|
||||||
if #args.targets==0
|
-- create the DAG
|
||||||
BuildObject\build defaulttarget
|
targets = #args.targets==0 and ctx.defaulttargets or args.targets
|
||||||
for target in *args.targets
|
dag = DepGraph ctx, targets
|
||||||
BuildObject\build target
|
print "Created dependancy graph" if args.verbose
|
||||||
|
|
||||||
|
-- execute the build
|
||||||
|
nparallel = args.parallel == 'y' and Executor\getmaxparallel! or args.parallel
|
||||||
|
print "Building with #{nparallel} max parallel process#{nparallel>1 and "es" or ""}" if args.verbose
|
||||||
|
executor = Executor dag, nparallel
|
||||||
|
executor\execute args
|
||||||
|
print "Finished" if args.verbose
|
||||||
|
|||||||
-989
@@ -1,989 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import gmatch, match, gsub from string
|
||||||
|
import insert, remove, concat, sub, sort from table
|
||||||
|
|
||||||
|
_fs = require 'moonbuild._fs'
|
||||||
|
_cmd = require 'moonbuild._cmd'
|
||||||
|
_util = require 'moonbuild._util'
|
||||||
|
_common = require 'moonbuild._common'
|
||||||
|
|
||||||
|
_ = {}
|
||||||
|
|
||||||
|
for k, lib in pairs {:_fs, :_cmd, :_util, :_common}
|
||||||
|
_[k] = lib
|
||||||
|
for n in *lib!
|
||||||
|
_[n] = lib[n]
|
||||||
|
_
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import parseargs, escape from require 'moonbuild._cmd.common'
|
||||||
|
|
||||||
|
ok, cmd, backend = false, nil, nil
|
||||||
|
unless ok
|
||||||
|
ok, cmd = pcall -> require 'moonbuild._cmd.posix'
|
||||||
|
backend = 'posix'
|
||||||
|
unless ok
|
||||||
|
ok, cmd = pcall -> require 'moonbuild._cmd.lua'
|
||||||
|
backend = 'lua'
|
||||||
|
error "unable to load any cmd library, tried luaposix and posix commands" unless ok
|
||||||
|
|
||||||
|
-- from the backend
|
||||||
|
cmd = {k, v for k, v in pairs cmd}
|
||||||
|
cmd.backend = backend
|
||||||
|
|
||||||
|
-- common cmd function
|
||||||
|
cmd.parseargs = parseargs
|
||||||
|
cmd.escape = escape
|
||||||
|
|
||||||
|
-- derived cmd functions
|
||||||
|
_cmd = cmd.cmd
|
||||||
|
_cmdrst = cmd.cmdrst
|
||||||
|
cmd.cmdline = (cmdline) -> _cmd parseargs cmdline
|
||||||
|
cmd.cmdlinerst = (cmdline) -> _cmdrst parseargs cmdline
|
||||||
|
|
||||||
|
-- the library itself
|
||||||
|
setmetatable cmd, __call: => {'cmd', 'cmdrst', 'cmdline', 'cmdlinerst', 'sh'}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
import gsub, sub, match from string
|
||||||
|
import concat from table
|
||||||
|
|
||||||
|
specialchars =
|
||||||
|
'\"': '\\\"'
|
||||||
|
'\\': '\\\\'
|
||||||
|
'\'': '\\\''
|
||||||
|
'\n': '\\n'
|
||||||
|
'\r': '\\r'
|
||||||
|
'\t': '\\t'
|
||||||
|
|
||||||
|
replacespecialchar = (c) -> specialchars[c] or c
|
||||||
|
|
||||||
|
escape = (arg) ->
|
||||||
|
return arg if match arg, "^[a-zA-Z0-9_.-]+$"
|
||||||
|
'"'..(gsub arg, "([\"\\\n\r\t])", replacespecialchar)..'"'
|
||||||
|
|
||||||
|
parseargs = (argstr) ->
|
||||||
|
state = 'normal'
|
||||||
|
current, ci = {}, 1
|
||||||
|
args, ai = {}, 1
|
||||||
|
c = nil
|
||||||
|
i = 0
|
||||||
|
running = true
|
||||||
|
|
||||||
|
add = ->
|
||||||
|
current[ci], ci = c, ci+1
|
||||||
|
push = ->
|
||||||
|
args[ai], ai, current, ci = (concat current), ai+1, {}, 1 if ci!=1
|
||||||
|
addv = (v) ->
|
||||||
|
current[ci], ci = v, ci+1
|
||||||
|
fail = (msg) ->
|
||||||
|
error "failed to parse: #{msg} in state #{state} at pos #{i}", 2
|
||||||
|
finish = ->
|
||||||
|
running = false
|
||||||
|
EOF = ''
|
||||||
|
|
||||||
|
while running
|
||||||
|
i += 1
|
||||||
|
c = sub argstr, i, i
|
||||||
|
|
||||||
|
switch state
|
||||||
|
when 'normal'
|
||||||
|
switch c
|
||||||
|
when '\"'
|
||||||
|
state = 'doublequote'
|
||||||
|
when '\''
|
||||||
|
state = 'singlequote'
|
||||||
|
when ' '
|
||||||
|
push!
|
||||||
|
when '\n'
|
||||||
|
push!
|
||||||
|
when '\t'
|
||||||
|
push!
|
||||||
|
when '\\'
|
||||||
|
state = 'backslashnormal'
|
||||||
|
when EOF
|
||||||
|
push!
|
||||||
|
finish!
|
||||||
|
else
|
||||||
|
add!
|
||||||
|
|
||||||
|
when 'doublequote'
|
||||||
|
switch c
|
||||||
|
when '\"'
|
||||||
|
state = 'normal'
|
||||||
|
when '\\'
|
||||||
|
state = 'backslashdoublequote'
|
||||||
|
when EOF
|
||||||
|
fail "unexpected EOF"
|
||||||
|
else
|
||||||
|
add!
|
||||||
|
|
||||||
|
when 'singlequote'
|
||||||
|
switch c
|
||||||
|
when '\''
|
||||||
|
state = 'normal'
|
||||||
|
when EOF
|
||||||
|
fail "unexpected EOF"
|
||||||
|
else
|
||||||
|
add!
|
||||||
|
|
||||||
|
when 'backslashnormal'
|
||||||
|
switch c
|
||||||
|
when '\n'
|
||||||
|
state = 'normal'
|
||||||
|
when EOF
|
||||||
|
fail "unexpected EOF"
|
||||||
|
else
|
||||||
|
add!
|
||||||
|
state = 'normal'
|
||||||
|
|
||||||
|
when 'backslashdoublequote'
|
||||||
|
switch c
|
||||||
|
when '$'
|
||||||
|
add!
|
||||||
|
state = 'doublequote'
|
||||||
|
when '`'
|
||||||
|
add!
|
||||||
|
state = 'doublequote'
|
||||||
|
when '\"'
|
||||||
|
add!
|
||||||
|
state = 'doublequote'
|
||||||
|
when '\\'
|
||||||
|
add!
|
||||||
|
state = 'doublequote'
|
||||||
|
when '\n'
|
||||||
|
state = 'doublequote'
|
||||||
|
when EOF
|
||||||
|
fail "unexpected EOF"
|
||||||
|
else
|
||||||
|
addv '\\'
|
||||||
|
add!
|
||||||
|
state = 'doublequote'
|
||||||
|
|
||||||
|
args
|
||||||
|
|
||||||
|
{
|
||||||
|
:escape
|
||||||
|
:parseargs
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import escape from require 'moonbuild._cmd.common'
|
||||||
|
import flatten from require 'moonbuild._common'
|
||||||
|
import execute from require 'moonbuild.compat.execute'
|
||||||
|
import popen from io
|
||||||
|
import concat from table
|
||||||
|
|
||||||
|
cmdline = (...) ->
|
||||||
|
concat [escape arg for arg in *flatten ...], ' '
|
||||||
|
|
||||||
|
cmd = (...) ->
|
||||||
|
ok, ret, code = execute cmdline ...
|
||||||
|
error "command #{first ...} exited with #{code} (#{ret})" unless ok
|
||||||
|
|
||||||
|
cmdrst = (...) ->
|
||||||
|
fd, err = popen cmdline ...
|
||||||
|
error err unless fd
|
||||||
|
data = fd\read '*a'
|
||||||
|
fd\close!
|
||||||
|
data
|
||||||
|
|
||||||
|
sh = (cli) ->
|
||||||
|
ok, ret, code = execute cli
|
||||||
|
error "command '#{cli}' exited with #{code} (#{ret})" unless ok
|
||||||
|
|
||||||
|
{
|
||||||
|
:cmd
|
||||||
|
:cmdrst
|
||||||
|
:sh
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import spawn from require 'posix'
|
||||||
|
import fork, execp, pipe, dup2, _exit, close from require 'posix.unistd'
|
||||||
|
import fdopen from require 'posix.stdio'
|
||||||
|
import wait from require 'posix.sys.wait'
|
||||||
|
import flatten, first from require 'moonbuild._common'
|
||||||
|
import remove from table
|
||||||
|
|
||||||
|
cmd = (...) ->
|
||||||
|
code, ty = spawn flatten ...
|
||||||
|
error "command #{first ...} #{ty} with code #{code}" if ty!='exited' or code!=0
|
||||||
|
|
||||||
|
cmdrst = (...) ->
|
||||||
|
rd, wr = pipe!
|
||||||
|
pid, err = fork!
|
||||||
|
|
||||||
|
if pid == 0
|
||||||
|
dup2 wr, 1
|
||||||
|
close rd
|
||||||
|
args = flatten ...
|
||||||
|
c = remove args, 1
|
||||||
|
execp c, args
|
||||||
|
return _exit 1
|
||||||
|
|
||||||
|
if pid == nil
|
||||||
|
close rd
|
||||||
|
close wr
|
||||||
|
error "command #{first ...} failed to start: couldn't fork(): #{err}"
|
||||||
|
|
||||||
|
close wr
|
||||||
|
fd = fdopen rd, 'r'
|
||||||
|
data = fd\read '*a'
|
||||||
|
fd\close!
|
||||||
|
close rd
|
||||||
|
|
||||||
|
_, ty, code = wait pid
|
||||||
|
error "command #{first ...} #{ty} with code #{code}" if ty!='exited' or code!=0
|
||||||
|
data
|
||||||
|
|
||||||
|
sh = (cli) ->
|
||||||
|
cmd 'sh', '-c', cli
|
||||||
|
|
||||||
|
{
|
||||||
|
:cmd
|
||||||
|
:cmdrst
|
||||||
|
:sh
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
import sort, concat from table
|
||||||
|
import huge from math
|
||||||
|
import match, sub from string
|
||||||
|
|
||||||
|
common = {}
|
||||||
|
|
||||||
|
flatten = (list, ...) ->
|
||||||
|
return flatten {list, ...} if (select '#', ...)!=0
|
||||||
|
t = type list
|
||||||
|
switch t
|
||||||
|
when 'nil'
|
||||||
|
{}
|
||||||
|
when 'string'
|
||||||
|
{list}
|
||||||
|
when 'number'
|
||||||
|
{tostring list}
|
||||||
|
when 'boolean'
|
||||||
|
{list}
|
||||||
|
when 'table'
|
||||||
|
keys = [k for k in pairs list]
|
||||||
|
sort keys
|
||||||
|
elements, i = {}, 1
|
||||||
|
for k in *keys
|
||||||
|
if (type k)=='number'
|
||||||
|
for e in *(flatten list[k])
|
||||||
|
elements[i], i = e, i+1
|
||||||
|
else
|
||||||
|
return {list}
|
||||||
|
setmetatable elements, __tostring: => concat @, ' '
|
||||||
|
else
|
||||||
|
error "can't flatten elements of type #{t}"
|
||||||
|
|
||||||
|
first = (list, ...) ->
|
||||||
|
t = type list
|
||||||
|
switch t
|
||||||
|
when 'nil'
|
||||||
|
if (select '#', ...)==0
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
first ...
|
||||||
|
when 'string'
|
||||||
|
list
|
||||||
|
when 'number'
|
||||||
|
tostring list
|
||||||
|
when 'boolean'
|
||||||
|
list
|
||||||
|
when 'table'
|
||||||
|
min = huge
|
||||||
|
for k in pairs list
|
||||||
|
if (type k) == 'number'
|
||||||
|
min = k if k < min
|
||||||
|
else
|
||||||
|
return list
|
||||||
|
first list[min]
|
||||||
|
else
|
||||||
|
error "can't find first of type #{t}"
|
||||||
|
|
||||||
|
foreach = (list, fn) ->
|
||||||
|
[fn v for v in *flatten list]
|
||||||
|
|
||||||
|
filter = (list, fn) ->
|
||||||
|
[v for v in *flatten list when fn v]
|
||||||
|
|
||||||
|
includes = (list, v) ->
|
||||||
|
return true if list==v
|
||||||
|
if (type list) == 'table'
|
||||||
|
for k, e in pairs list
|
||||||
|
if (type k) == 'number'
|
||||||
|
return true if includes e, v
|
||||||
|
if (type list) == 'number'
|
||||||
|
return (tostring list) == (tostring v)
|
||||||
|
false
|
||||||
|
|
||||||
|
patget = (s, pat) ->
|
||||||
|
prefix, suffix = match pat, '^(.*)%%(.*)$'
|
||||||
|
return s==pat and s or nil unless prefix
|
||||||
|
if (sub s, 1, #prefix)==prefix and (suffix == '' or (sub s, -#suffix)==suffix)
|
||||||
|
sub s, #prefix+1, -#suffix-1
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
|
||||||
|
patset = (s, rep) ->
|
||||||
|
prefix, suffix = match rep, '^(.*)%%(.*)$'
|
||||||
|
if prefix
|
||||||
|
prefix..s..suffix
|
||||||
|
else
|
||||||
|
rep
|
||||||
|
|
||||||
|
patsubst = (s, pat, rep) ->
|
||||||
|
prefix, suffix = match pat, '^(.*)%%(.*)$'
|
||||||
|
rprefix, rsuffix = match rep, '^(.*)%%(.*)$'
|
||||||
|
|
||||||
|
t = type s
|
||||||
|
f = false
|
||||||
|
if t=='nil'
|
||||||
|
return nil
|
||||||
|
if t=='number'
|
||||||
|
t = 'string'
|
||||||
|
s = tostring s
|
||||||
|
if t=='string'
|
||||||
|
t = 'table'
|
||||||
|
s = {s}
|
||||||
|
f = true
|
||||||
|
if t!='table'
|
||||||
|
error "can't substitute patterns on type #{t}"
|
||||||
|
|
||||||
|
r, i = {}, 1
|
||||||
|
for s in *flatten s
|
||||||
|
if not prefix
|
||||||
|
if s==pat
|
||||||
|
if rprefix
|
||||||
|
r[i], i = rprefix..s..rsuffix, i+1
|
||||||
|
else
|
||||||
|
r[i], i = rep, i+1
|
||||||
|
elseif (sub s, 1, #prefix)==prefix and (suffix == '' or (sub s, -#suffix)==suffix)
|
||||||
|
if rprefix
|
||||||
|
r[i], i = rprefix..(sub s, #prefix+1, -#suffix-1)..rsuffix, i+1
|
||||||
|
else
|
||||||
|
r[i], i = rep, i+1
|
||||||
|
|
||||||
|
f and r[1] or r
|
||||||
|
|
||||||
|
exclude = (list, ...) ->
|
||||||
|
exclusions = flatten ...
|
||||||
|
[v for v in *flatten list when not includes exclusions, v]
|
||||||
|
|
||||||
|
min = (list) ->
|
||||||
|
m = list[1]
|
||||||
|
for i=2, #list
|
||||||
|
e = list[i]
|
||||||
|
m = e if e<m
|
||||||
|
m
|
||||||
|
|
||||||
|
max = (list) ->
|
||||||
|
m = list[1]
|
||||||
|
for i=2, #list
|
||||||
|
e = list[i]
|
||||||
|
m = e if e>m
|
||||||
|
m
|
||||||
|
|
||||||
|
minmax = (list) ->
|
||||||
|
m = list[1]
|
||||||
|
M = list[1]
|
||||||
|
for i=2, #list
|
||||||
|
e = list[i]
|
||||||
|
m = e if e<m
|
||||||
|
M = e if e>M
|
||||||
|
m, M
|
||||||
|
|
||||||
|
common.flatten = flatten
|
||||||
|
common.first = first
|
||||||
|
common.foreach = foreach
|
||||||
|
common.filter = filter
|
||||||
|
common.includes = includes
|
||||||
|
common.patget = patget
|
||||||
|
common.patset = patset
|
||||||
|
common.patsubst = patsubst
|
||||||
|
common.exclude = exclude
|
||||||
|
common.min = min
|
||||||
|
common.max = max
|
||||||
|
common.minmax = minmax
|
||||||
|
|
||||||
|
setmetatable common, __call: => [k for k in pairs common]
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
import remove, concat from table
|
||||||
|
import gmatch, match, gsub, sub from string
|
||||||
|
|
||||||
|
-- load backend
|
||||||
|
ok, fs, backend = false, nil, nil
|
||||||
|
unless ok
|
||||||
|
ok, fs = pcall -> require 'moonbuild._fs.posix'
|
||||||
|
backend = 'posix'
|
||||||
|
unless ok
|
||||||
|
ok, fs = pcall -> require 'moonbuild._fs.lfs'
|
||||||
|
backend = 'lfs'
|
||||||
|
unless ok
|
||||||
|
ok, fs = pcall -> require 'moonbuild._fs.cmd'
|
||||||
|
backend = 'cmd'
|
||||||
|
error "unable to load any fs library, tried luaposix, luafilesystem and posix commands" unless ok
|
||||||
|
|
||||||
|
-- caching mechanism
|
||||||
|
DISABLED = ( -> DISABLED )
|
||||||
|
NIL = ( -> NIL )
|
||||||
|
|
||||||
|
cacheenabled = true
|
||||||
|
caches = {}
|
||||||
|
|
||||||
|
clearcache = ->
|
||||||
|
v.clearcache! for k, v in pairs caches
|
||||||
|
clearentry = (entry) ->
|
||||||
|
v.clearentry entry for k, v in pairs caches
|
||||||
|
disableentry = (entry) ->
|
||||||
|
v.disableentry entry for k, v in pairs caches
|
||||||
|
disablecache = ->
|
||||||
|
cacheenabled = false
|
||||||
|
enablecache = ->
|
||||||
|
cacheenabled = true
|
||||||
|
|
||||||
|
withcache = (fn) ->
|
||||||
|
opts = {}
|
||||||
|
opts.cache = {}
|
||||||
|
opts.clearcache = ->
|
||||||
|
opts.cache = {}
|
||||||
|
opts.clearentry = (entry) ->
|
||||||
|
opts.cache[entry] = nil
|
||||||
|
opts.disableentry = (entry) ->
|
||||||
|
opts.cache[entry] = DISABLED
|
||||||
|
caches[fn] = opts
|
||||||
|
|
||||||
|
setmetatable opts,
|
||||||
|
__call: (arg) =>
|
||||||
|
return fn arg unless cacheenabled
|
||||||
|
cached = opts.cache[arg]
|
||||||
|
return fn arg if cached == DISABLED
|
||||||
|
return nil if cached == NIL
|
||||||
|
return cached if cached != nil
|
||||||
|
cached = fn arg
|
||||||
|
opts.cache[arg] = cached
|
||||||
|
opts.cache[arg] = NIL if cached == nil
|
||||||
|
return cached
|
||||||
|
|
||||||
|
fs = {
|
||||||
|
dir: withcache fs.dir
|
||||||
|
attributes: withcache fs.attributes
|
||||||
|
mkdir: fs.mkdir
|
||||||
|
}
|
||||||
|
import attributes, dir, mkdir from fs
|
||||||
|
|
||||||
|
-- actual functions
|
||||||
|
normalizepath = (file) ->
|
||||||
|
parts = [part for part in gmatch file, '[^/]+']
|
||||||
|
absolute = (sub file, 1, 1)=='/'
|
||||||
|
i = 1
|
||||||
|
while i<=#parts
|
||||||
|
if parts[i]=='.'
|
||||||
|
remove parts, i
|
||||||
|
continue
|
||||||
|
if parts[i]=='..' and i!=1 and parts[i-1]!='..'
|
||||||
|
remove parts, i
|
||||||
|
remove parts, i-1
|
||||||
|
i -= 1
|
||||||
|
continue
|
||||||
|
i += 1
|
||||||
|
if #parts==0
|
||||||
|
absolute and '/' or '.'
|
||||||
|
else
|
||||||
|
(absolute and '/' or '') .. concat parts, '/'
|
||||||
|
|
||||||
|
ls = (d) ->
|
||||||
|
[f for f in *dir normalizepath d when f!='.' and f!='..']
|
||||||
|
|
||||||
|
lswithpath = (d) ->
|
||||||
|
return ls '.' if d==''
|
||||||
|
[d..'/'..f for f in *dir normalizepath d when f!='.' and f!='..']
|
||||||
|
|
||||||
|
matchglob = (str, glob) ->
|
||||||
|
glob = gsub glob, '[%[%]%%+.?-]', => '%'..@
|
||||||
|
patt = '^'..(gsub glob, '%*%*?', => @=='**' and '.*' or '[^/]*')..'$'
|
||||||
|
rst = if (type str)=='table'
|
||||||
|
results, i = {}, 1
|
||||||
|
for s in *str
|
||||||
|
rst = (match s, patt) and s
|
||||||
|
results[i], i = rst, i+1 if rst
|
||||||
|
results
|
||||||
|
else
|
||||||
|
(match str, patt) and str
|
||||||
|
rst
|
||||||
|
|
||||||
|
exists = (f) ->
|
||||||
|
(attributes normalizepath f) != nil
|
||||||
|
|
||||||
|
isdir = (f) ->
|
||||||
|
((attributes normalizepath f) or {}).mode == 'directory'
|
||||||
|
|
||||||
|
wildcard = (glob) ->
|
||||||
|
parts = [part for part in gmatch glob, '[^/]+']
|
||||||
|
absolute = (sub glob, 1, 1)=='/'
|
||||||
|
|
||||||
|
for i, part in ipairs parts
|
||||||
|
prevpath = (absolute and '/' or '') .. concat parts, '/', 1, i-1
|
||||||
|
currpath = (i==1 and '' or (prevpath .. '/')) .. part
|
||||||
|
|
||||||
|
if match part, '%*%*.*%*%*'
|
||||||
|
error "Two '**' in the same path component in a wildcard"
|
||||||
|
|
||||||
|
if match part, '%*%*'
|
||||||
|
prefix = match currpath, '^(.*)%*%*'
|
||||||
|
suffix = (match part, '%*%*(.*)$') .. (i==#parts and '' or ('/'..concat parts, '/', i+1, #parts))
|
||||||
|
return {} unless exists prevpath
|
||||||
|
files = lswithpath prevpath
|
||||||
|
|
||||||
|
results, ri = {}, 1
|
||||||
|
for file in *files
|
||||||
|
if matchglob file, currpath
|
||||||
|
if i==#parts
|
||||||
|
results[ri], ri = file, ri+1
|
||||||
|
elseif isdir file
|
||||||
|
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
|
||||||
|
results[ri], ri = result, ri+1
|
||||||
|
if (matchglob file, prefix..'**') and isdir file
|
||||||
|
for result in *wildcard file .. '/**' .. suffix
|
||||||
|
results[ri], ri = result, ri+1
|
||||||
|
return results
|
||||||
|
|
||||||
|
if match part, '%*'
|
||||||
|
return {} unless exists prevpath
|
||||||
|
files = lswithpath prevpath
|
||||||
|
|
||||||
|
if i==#parts
|
||||||
|
return matchglob files, glob
|
||||||
|
|
||||||
|
results, ri = {}, 1
|
||||||
|
for file in *files
|
||||||
|
if (matchglob file, currpath) and isdir file
|
||||||
|
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
|
||||||
|
results[ri], ri = result, ri+1
|
||||||
|
return results
|
||||||
|
|
||||||
|
if exists glob
|
||||||
|
return {glob}
|
||||||
|
else
|
||||||
|
return {}
|
||||||
|
|
||||||
|
parent = (file) ->
|
||||||
|
normalizepath file..'/..'
|
||||||
|
|
||||||
|
actualmkdir = mkdir
|
||||||
|
mkdir = (dir) ->
|
||||||
|
actualmkdir dir
|
||||||
|
clearentry parent dir
|
||||||
|
|
||||||
|
mkdirs = (dir) ->
|
||||||
|
return if isdir dir
|
||||||
|
error "Can't mkdirs #{dir}: file exists" if exists dir
|
||||||
|
mkdirs parent dir
|
||||||
|
mkdir dir
|
||||||
|
|
||||||
|
-- from the backend
|
||||||
|
fs = {k, withcache fn for k, fn in pairs fs}
|
||||||
|
|
||||||
|
-- own functions
|
||||||
|
fs.normalizepath = normalizepath
|
||||||
|
fs.ls = ls
|
||||||
|
fs.lswithpath = lswithpath
|
||||||
|
fs.matchglob = matchglob
|
||||||
|
fs.exists = exists
|
||||||
|
fs.isdir = isdir
|
||||||
|
fs.wildcard = wildcard
|
||||||
|
fs.parent = parent
|
||||||
|
fs.mkdir = mkdir
|
||||||
|
fs.mkdirs = mkdirs
|
||||||
|
|
||||||
|
-- cache and backend
|
||||||
|
fs.clearcache = clearcache
|
||||||
|
fs.clearentry = clearentry
|
||||||
|
fs.disableentry = disableentry
|
||||||
|
fs.disablecache = disablecache
|
||||||
|
fs.enablecache = enablecache
|
||||||
|
fs.backend = backend
|
||||||
|
|
||||||
|
-- the library itself
|
||||||
|
setmetatable fs, __call: => {'dir', 'ls', 'normalizepath', 'exists', 'isdir', 'wildcard', 'mkdir', 'mkdirs'}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import escape from require 'moonbuild._cmd'
|
||||||
|
import execute from require 'moonbuild.compat.execute'
|
||||||
|
import popen from io
|
||||||
|
import gmatch, match, sub from string
|
||||||
|
|
||||||
|
error "commands ls and stat aren't available" unless (execute "which ls >/dev/null 2>&1") and (execute "which stat >/dev/null 2>&1")
|
||||||
|
|
||||||
|
{
|
||||||
|
dir: (path) ->
|
||||||
|
[file for file in (popen "ls -1 #{escape path}")\lines!]
|
||||||
|
|
||||||
|
attributes: (path) ->
|
||||||
|
fd = popen "stat -c '%d %i %A %h %u %g %s %b %t %T %X %Y %Z' #{escape path}"
|
||||||
|
stat = [part for part in gmatch (fd\read '*a'), "%S+"]
|
||||||
|
fd\close!
|
||||||
|
|
||||||
|
fd = popen "stat -f -c '%S' #{escape path}"
|
||||||
|
blksize = match (fd\read '*a'), '%S+'
|
||||||
|
fd\close!
|
||||||
|
|
||||||
|
{
|
||||||
|
dev: tonumber stat[1]
|
||||||
|
ino: tonumber stat[2]
|
||||||
|
nlink: tonumber stat[4]
|
||||||
|
uid: tonumber stat[5]
|
||||||
|
gid: tonumber stat[6]
|
||||||
|
size: tonumber stat[7]
|
||||||
|
blocks: tonumber stat[8]
|
||||||
|
blksize: tonumber blksize
|
||||||
|
access: tonumber stat[11]
|
||||||
|
modification: tonumber stat[12]
|
||||||
|
change: tonumber stat[13]
|
||||||
|
|
||||||
|
permissions: do
|
||||||
|
sub stat[3], 2
|
||||||
|
|
||||||
|
mode: do
|
||||||
|
switch sub stat[3], 1, 1
|
||||||
|
when '-' then 'file'
|
||||||
|
when 'd' then 'directory'
|
||||||
|
when 'l' then 'link'
|
||||||
|
when 's' then 'socket'
|
||||||
|
when 'p' then 'named pipe'
|
||||||
|
when 'c' then 'char device'
|
||||||
|
when 'b' then 'block device'
|
||||||
|
else 'other'
|
||||||
|
|
||||||
|
rdev: do
|
||||||
|
(tonumber stat[9]) * 256 + (tonumber stat[10])
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir: (path) ->
|
||||||
|
error "Mkdir #{path} failed" unless execute "mkdir #{escape path}"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import dir, attributes, mkdir from require 'lfs'
|
||||||
|
|
||||||
|
{
|
||||||
|
dir: (path) ->
|
||||||
|
[v for v in dir path]
|
||||||
|
|
||||||
|
attributes: attributes
|
||||||
|
|
||||||
|
mkdir: (path) ->
|
||||||
|
ok, err = mkdir path
|
||||||
|
error "Failed to mkdir #{path}: #{err}" unless ok
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import dir from require 'posix.dirent'
|
||||||
|
import stat, mkdir, S_IFMT, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLINK, S_IFREG, S_IFSOCK from require 'posix.sys.stat'
|
||||||
|
import band, btest from require 'moonbuild.compat.bit'
|
||||||
|
import concat from table
|
||||||
|
|
||||||
|
{
|
||||||
|
dir: dir
|
||||||
|
|
||||||
|
attributes: (path) ->
|
||||||
|
st = stat path
|
||||||
|
return nil unless st
|
||||||
|
mode = st.st_mode
|
||||||
|
{
|
||||||
|
mode: do
|
||||||
|
ty = band mode, S_IFMT
|
||||||
|
switch ty
|
||||||
|
when S_IFREG then 'file'
|
||||||
|
when S_IFDIR then 'directory'
|
||||||
|
when S_IFLINK then 'link'
|
||||||
|
when S_IFSOCK then 'socket'
|
||||||
|
when S_IFIFO then 'named pipe'
|
||||||
|
when S_IFCHR then 'char device'
|
||||||
|
when S_IFBLK then 'block device'
|
||||||
|
else 'other'
|
||||||
|
|
||||||
|
permissions: do
|
||||||
|
_suid = btest mode, 2048
|
||||||
|
_sgid = btest mode, 1024
|
||||||
|
_stic = btest mode, 512
|
||||||
|
_ur = btest mode, 256
|
||||||
|
_uw = btest mode, 128
|
||||||
|
_ux = btest mode, 64
|
||||||
|
_gr = btest mode, 32
|
||||||
|
_gw = btest mode, 16
|
||||||
|
_gx = btest mode, 8
|
||||||
|
_or = btest mode, 4
|
||||||
|
_ow = btest mode, 2
|
||||||
|
_ox = btest mode, 1
|
||||||
|
concat {
|
||||||
|
_ur and 'r' or '-'
|
||||||
|
_uw and 'w' or '-'
|
||||||
|
_suid and 's' or (_ux and 'x' or '-')
|
||||||
|
_gr and 'r' or '-'
|
||||||
|
_gw and 'w' or '-'
|
||||||
|
_sgid and 's' or (_gx and 'x' or '-')
|
||||||
|
_or and 'r' or '-'
|
||||||
|
_ow and 'w' or '-'
|
||||||
|
_stic and 't' or (_ox and 'x' or '-')
|
||||||
|
}
|
||||||
|
|
||||||
|
dev: st.st_dev
|
||||||
|
ino: st.st_ino
|
||||||
|
nlink: st.st_nlink
|
||||||
|
uid: st.st_uid
|
||||||
|
gid: st.st_gid
|
||||||
|
rdev: st.st_rdev
|
||||||
|
access: st.st_atime
|
||||||
|
modification: st.st_mtime
|
||||||
|
change: st.st_ctime
|
||||||
|
size: st.st_size
|
||||||
|
blocks: st.st_blocks
|
||||||
|
blksize: st.st_blksize
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir: (path) ->
|
||||||
|
ok, err = mkdir path
|
||||||
|
error "Failed to mkdir #{path}: #{err}" unless ok
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import to_lua from require 'moonscript.base'
|
||||||
|
import parseargs, cmdrst from require 'moonbuild._cmd'
|
||||||
|
import gmatch, match, gsub from string
|
||||||
|
import open from io
|
||||||
|
|
||||||
|
util = {}
|
||||||
|
|
||||||
|
_pkgconfig = (mode, ...) ->
|
||||||
|
parseargs cmdrst 'pkg-config', "--#{mode}", ...
|
||||||
|
pkgconfig = setmetatable {}, __index: (mode) => (...) -> _pkgconfig mode, ...
|
||||||
|
|
||||||
|
_cdeps = (cc, cflags, path) ->
|
||||||
|
raw = cmdrst cc, cflags, '-M', path
|
||||||
|
rawlist = gsub (match raw, ':(.+)'), '\\\n', ' '
|
||||||
|
[v for v in gmatch rawlist, '%S+']
|
||||||
|
cdeps = setmetatable {},
|
||||||
|
__index: (cc) => (path, cflags) -> _cdeps cc, cflags, path
|
||||||
|
__call: (path, cflags) => _cdeps 'cc', cflags, path
|
||||||
|
|
||||||
|
readfile = (filename) ->
|
||||||
|
fd, err = open filename, 'rb'
|
||||||
|
error err unless fd
|
||||||
|
data, err = fd\read '*a'
|
||||||
|
error err unless data
|
||||||
|
fd\close!
|
||||||
|
data
|
||||||
|
|
||||||
|
writefile = (filename, data) ->
|
||||||
|
fd, err = open filename, 'wb'
|
||||||
|
error err unless fd
|
||||||
|
ok, err = fd\write data
|
||||||
|
error err unless ok
|
||||||
|
fd\close!
|
||||||
|
nil
|
||||||
|
|
||||||
|
moonc = (infile, outfile) ->
|
||||||
|
code, err = to_lua readfile infile
|
||||||
|
error "Failed to compile #{@infile}: #{err}" unless code
|
||||||
|
writefile outfile, code
|
||||||
|
|
||||||
|
util.pkgconfig = pkgconfig
|
||||||
|
util.cdeps = cdeps
|
||||||
|
util.readfile = readfile
|
||||||
|
util.writefile = writefile
|
||||||
|
util.moonc = moonc
|
||||||
|
|
||||||
|
setmetatable util, __call: => [k for k in pairs util]
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
loadstring = loadstring or load
|
||||||
|
import floor, ceil, pow from math
|
||||||
|
|
||||||
|
band = loadstring [[local a, b = ...; return a & b ]]
|
||||||
|
bor = loadstring [[local a, b = ...; return a | b ]]
|
||||||
|
bxor = loadstring [[local a, b = ...; return a ~ b ]]
|
||||||
|
bnot = loadstring [[local a = ...; return ~a ]]
|
||||||
|
shl = loadstring [[local a, b = ...; return a << b]]
|
||||||
|
shr = loadstring [[local a, b = ...; return a >> b]]
|
||||||
|
|
||||||
|
unless band
|
||||||
|
_checkint = (n) ->
|
||||||
|
if n%1 == 0
|
||||||
|
n
|
||||||
|
else
|
||||||
|
error "not an int"
|
||||||
|
|
||||||
|
_shl = (a, b) ->
|
||||||
|
a * pow(2, b)
|
||||||
|
|
||||||
|
_shr = (a, b) ->
|
||||||
|
v = a / pow(2, b)
|
||||||
|
if v<0
|
||||||
|
ceil v
|
||||||
|
else
|
||||||
|
floor v
|
||||||
|
|
||||||
|
_shr1 = (n) ->
|
||||||
|
n /= 2
|
||||||
|
if n<0
|
||||||
|
ceil v
|
||||||
|
else
|
||||||
|
floor v
|
||||||
|
|
||||||
|
_band = (a, b) ->
|
||||||
|
v = 0
|
||||||
|
n = 1
|
||||||
|
for i=0, 63
|
||||||
|
if a%2 == 1 and b%2 == 1
|
||||||
|
v += n
|
||||||
|
if i!=63
|
||||||
|
a = _shr1 a
|
||||||
|
b = _shr1 b
|
||||||
|
n *= 2
|
||||||
|
v
|
||||||
|
|
||||||
|
_bor = (a, b) ->
|
||||||
|
v = 0
|
||||||
|
n = 1
|
||||||
|
for i=0, 63
|
||||||
|
if a%2 == 1 or b%2 == 1
|
||||||
|
v += n
|
||||||
|
if i!=63
|
||||||
|
a = _shr1 a
|
||||||
|
b = _shr1 b
|
||||||
|
n *= 2
|
||||||
|
v
|
||||||
|
|
||||||
|
_bxor = (a, b) ->
|
||||||
|
v = 0
|
||||||
|
n = 1
|
||||||
|
for i=0, 63
|
||||||
|
if a%2 != b%2
|
||||||
|
v += n
|
||||||
|
if i!=63
|
||||||
|
a = _shr1 a
|
||||||
|
b = _shr1 b
|
||||||
|
n *= 2
|
||||||
|
v
|
||||||
|
|
||||||
|
_bnot = (a) ->
|
||||||
|
v = 0
|
||||||
|
n = 1
|
||||||
|
for i=0, 63
|
||||||
|
if a%2 == 0
|
||||||
|
v += n
|
||||||
|
if i!=63
|
||||||
|
a = _shr1 a
|
||||||
|
n *= 2
|
||||||
|
v
|
||||||
|
|
||||||
|
band = (a, b) -> _band (_checkint a), (_checkint b)
|
||||||
|
bor = (a, b) -> _bor (_checkint a), (_checkint b)
|
||||||
|
bxor = (a, b) -> _bxor (_checkint a), (_checkint b)
|
||||||
|
bnot = (a) -> _bnot (_checkint a)
|
||||||
|
shl = (a, b) -> _shl (_checkint a), (_checkint b)
|
||||||
|
shr = (a, b) -> _shr (_checkint a), (_checkint b)
|
||||||
|
|
||||||
|
btest = (a, b) -> (band a, b) == b
|
||||||
|
|
||||||
|
{ :band, :bor, :bxor, :bnot, :shl, :shr, :btest }
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
pcall = require 'moonbuild.compat.pcall'
|
||||||
|
|
||||||
|
runwithcontext = if setfenv
|
||||||
|
(fn, ctx, ...) ->
|
||||||
|
env = getfenv fn
|
||||||
|
setfenv fn, ctx
|
||||||
|
local data, ndata, ok
|
||||||
|
acc = (succ, ...) ->
|
||||||
|
ok = succ
|
||||||
|
if succ
|
||||||
|
data = {...}
|
||||||
|
ndata = select '#', ...
|
||||||
|
else
|
||||||
|
data = ...
|
||||||
|
acc pcall fn, ...
|
||||||
|
setfenv fn, env
|
||||||
|
if ok
|
||||||
|
unpack data, 1, ndata
|
||||||
|
else
|
||||||
|
error data
|
||||||
|
|
||||||
|
else
|
||||||
|
import dump from string
|
||||||
|
(fn, ctx, ...) ->
|
||||||
|
code = dump fn, false
|
||||||
|
fn = load code, 'runwithcontext', 'b', ctx
|
||||||
|
fn ...
|
||||||
|
|
||||||
|
{ :runwithcontext }
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import execute from os
|
||||||
|
|
||||||
|
{
|
||||||
|
execute: (cmd) ->
|
||||||
|
a, b, c = execute cmd
|
||||||
|
if (type a) == 'boolean'
|
||||||
|
a, b, c
|
||||||
|
else
|
||||||
|
a==0 or nil, 'exit', a
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
pcall = _G.pcall
|
||||||
|
unpack = _G.unpack or table.unpack
|
||||||
|
|
||||||
|
testfn = (a, b) -> a == b and a == 1 and true or error!
|
||||||
|
testok, testrst = pcall testfn, 1, 1
|
||||||
|
unless testok and testrst
|
||||||
|
realpcall = pcall
|
||||||
|
pcall = (fn, ...) ->
|
||||||
|
args = { n: (select '#', ...), ... }
|
||||||
|
realpcall -> fn unpack args, 1, args.n
|
||||||
|
|
||||||
|
pcall
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import runwithcontext from require 'moonbuild.compat.ctx'
|
||||||
|
topenv = require 'moonbuild.env.top'
|
||||||
|
initenv = require 'moonbuild.env.init'
|
||||||
|
import includes from require 'moonbuild._common'
|
||||||
|
import insert from table
|
||||||
|
|
||||||
|
class Context
|
||||||
|
new: =>
|
||||||
|
@targets = {}
|
||||||
|
@defaulttargets = {}
|
||||||
|
@variables = {}
|
||||||
|
@inits = {}
|
||||||
|
|
||||||
|
addvar: (var) =>
|
||||||
|
@variables[var.name] = var
|
||||||
|
|
||||||
|
addinit: (fn) =>
|
||||||
|
insert @inits, fn
|
||||||
|
|
||||||
|
addtarget: (target) =>
|
||||||
|
insert @targets, target
|
||||||
|
|
||||||
|
resetexecuted: =>
|
||||||
|
@executedtargets = {}
|
||||||
|
|
||||||
|
adddefault: (target) =>
|
||||||
|
error "not a target of the current context: #{target}" unless includes @targets, target
|
||||||
|
error "not a named target" unless (type target.name) == 'string'
|
||||||
|
insert @defaulttargets, target.name
|
||||||
|
|
||||||
|
load: (code, overrides) =>
|
||||||
|
runwithcontext code, (topenv @, overrides)
|
||||||
|
|
||||||
|
init: =>
|
||||||
|
if @inits[1]
|
||||||
|
env = (initenv @)
|
||||||
|
for init in *@inits
|
||||||
|
runwithcontext code, env
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
import first, filter, foreach, flatten, patsubst, includes from require 'moonbuild._common'
|
||||||
|
import runwithcontext from require 'moonbuild.compat.ctx'
|
||||||
|
globalenv = require 'moonbuild.env.global'
|
||||||
|
import exists, parent, mkdirs, clearentry, disableentry, attributes from require 'moonbuild._fs'
|
||||||
|
import sort, insert, remove from table
|
||||||
|
import huge from math
|
||||||
|
|
||||||
|
local DepNode, FileTarget
|
||||||
|
|
||||||
|
nodepriority = (a, b) ->
|
||||||
|
ta = type a.name
|
||||||
|
tb = type b.name
|
||||||
|
da = #a.deps
|
||||||
|
db = #b.deps
|
||||||
|
sa = a.sync
|
||||||
|
sb = b.sync
|
||||||
|
if ta=='string' and tb!='string'
|
||||||
|
return true
|
||||||
|
elseif ta!='string' and tb=='string'
|
||||||
|
return false
|
||||||
|
elseif a.priority > b.priority
|
||||||
|
return true
|
||||||
|
elseif a.priority < b.priority
|
||||||
|
return false
|
||||||
|
elseif sa and not sb
|
||||||
|
return false
|
||||||
|
elseif sb and not sa
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return da < db
|
||||||
|
|
||||||
|
transclosure = (obj, prop) ->
|
||||||
|
elems = {}
|
||||||
|
i = 1
|
||||||
|
set = {}
|
||||||
|
imp = (e) ->
|
||||||
|
return unless e[prop]
|
||||||
|
for v in *e[prop]
|
||||||
|
if not set[v]
|
||||||
|
elems[i], i = v, i+1
|
||||||
|
set[v] = i
|
||||||
|
imp v
|
||||||
|
imp obj
|
||||||
|
elems
|
||||||
|
|
||||||
|
mtime = (path) ->
|
||||||
|
attr = attributes path
|
||||||
|
attr and attr.modification
|
||||||
|
|
||||||
|
class DepGraph
|
||||||
|
new: (@ctx, names={}) =>
|
||||||
|
@nodes = {}
|
||||||
|
@env = globalenv @ctx
|
||||||
|
for name in *names
|
||||||
|
@addnode name
|
||||||
|
|
||||||
|
addnode: (name) =>
|
||||||
|
return if @nodes[name]
|
||||||
|
elected = @resolvedeps name
|
||||||
|
@nodes[name] = elected
|
||||||
|
for dep in *(transclosure elected, 'deps')
|
||||||
|
@nodes[dep.name] = dep
|
||||||
|
dep.deps = nil
|
||||||
|
elected.deps = nil
|
||||||
|
|
||||||
|
resolvedeps: (name) =>
|
||||||
|
do
|
||||||
|
node = @nodes[name]
|
||||||
|
return node, {} if node
|
||||||
|
candidates = filter {@ctx.targets, FileTarget!}, (target) -> target\matches name
|
||||||
|
nodes = foreach candidates, (candidate) -> a: {pcall -> DepNode @, candidate, name}
|
||||||
|
resolved = foreach (filter nodes, (node) -> node.a[1]), (node) -> node.a[2]
|
||||||
|
sort resolved, nodepriority
|
||||||
|
resolved[1] or error "Cannot resolve target #{name}: #{#candidates} candidates, #{#resolved} resolved"
|
||||||
|
|
||||||
|
buildablenodes: =>
|
||||||
|
[v for k, v in pairs @nodes when v\canbuild! and not v.built]
|
||||||
|
|
||||||
|
reset: =>
|
||||||
|
n.built = false for k, n in pairs @nodes
|
||||||
|
|
||||||
|
resetchildren: (names) =>
|
||||||
|
done = {}
|
||||||
|
stack = [v for v in *names]
|
||||||
|
while #stack != 0
|
||||||
|
name = remove stack
|
||||||
|
continue if done[name]
|
||||||
|
done[name] = true
|
||||||
|
node = @nodes[name]
|
||||||
|
node.built = false
|
||||||
|
insert stack, n for n in *(node\children!)
|
||||||
|
|
||||||
|
class DepNode
|
||||||
|
new: (@dag, target, @name) =>
|
||||||
|
@priority = target.priority
|
||||||
|
@buildfunctions = target.buildfunctions
|
||||||
|
@mkdirs = target._mkdirs
|
||||||
|
@sync = target._sync
|
||||||
|
@type = target._type
|
||||||
|
@outs = foreach target.outfiles, (name) -> patsubst @name, target.pattern, name
|
||||||
|
@type = 'virtual' if #@outs == 0
|
||||||
|
@built = false
|
||||||
|
|
||||||
|
resolve = (name) -> @dag\resolvedeps patsubst @name, target.pattern, name
|
||||||
|
after = flatten foreach target.needtargets, resolve
|
||||||
|
deps = flatten foreach target.infiles, resolve
|
||||||
|
if #target.depfunctions!=0
|
||||||
|
ctx = setmetatable {},
|
||||||
|
__index: (_, k) ->
|
||||||
|
switch k
|
||||||
|
when 'infile', 'in'
|
||||||
|
f = first deps
|
||||||
|
f and f.name
|
||||||
|
when 'infiles'
|
||||||
|
foreach deps, => @name
|
||||||
|
when 'outfile', 'out'
|
||||||
|
f = first @outs
|
||||||
|
f and f.name
|
||||||
|
when 'outfiles'
|
||||||
|
foreach @outs, => @name
|
||||||
|
when 'name'
|
||||||
|
@name
|
||||||
|
else
|
||||||
|
error "No such field in TargetDepsContext: #{k}"
|
||||||
|
__newindex: (k) =>
|
||||||
|
error "Attempt to set field #{k} of TargetDepsContext"
|
||||||
|
for depfn in *target.depfunctions
|
||||||
|
deps = flatten deps, foreach (runwithcontext depfn, @dag.env, ctx), resolve
|
||||||
|
@ins = foreach deps, (dep) -> dep.name
|
||||||
|
@after = foreach after, (dep) -> dep.name
|
||||||
|
@deps = flatten { deps, after }
|
||||||
|
@built = true if #@deps == 0 and #@buildfunctions == 0
|
||||||
|
|
||||||
|
children: =>
|
||||||
|
[k for k, n in pairs @dag.nodes when (includes n.ins, @name) or (includes n.after, @name)]
|
||||||
|
|
||||||
|
canbuild: =>
|
||||||
|
for node in *flatten { @ins, @after }
|
||||||
|
if not @dag.nodes[node].built
|
||||||
|
return false
|
||||||
|
for file in *@ins
|
||||||
|
if not exists file
|
||||||
|
error "Node #{@name} has ran all of its parents, but can't run since #{file} doesn't exist. Did you mean to use after instead of depends?"
|
||||||
|
return true
|
||||||
|
|
||||||
|
build: (opts={}) =>
|
||||||
|
force = opts.force or false
|
||||||
|
quiet = opts.quiet or false
|
||||||
|
|
||||||
|
return false if @built or #@buildfunctions == 0
|
||||||
|
return false unless force or @shouldbuild!
|
||||||
|
print "#{@type == 'virtual' and "Running" or "Building"} #{@name}" unless quiet
|
||||||
|
@actuallybuild!
|
||||||
|
true
|
||||||
|
|
||||||
|
|
||||||
|
shouldbuild: =>
|
||||||
|
-- targets with no outputs / inputs and virtual targets *NEED* to be built
|
||||||
|
return true if #@outs == 0 or #@ins == 0 or @type == 'virtual'
|
||||||
|
|
||||||
|
-- check min mtime for outputs
|
||||||
|
minout = huge
|
||||||
|
for file in *@outs
|
||||||
|
time = mtime file
|
||||||
|
-- if an output file is missing, we *NEED* to build it
|
||||||
|
return true if not time
|
||||||
|
minout = time if time < minout
|
||||||
|
|
||||||
|
-- check max mtime for inputs
|
||||||
|
maxin = 0
|
||||||
|
for file in *@ins
|
||||||
|
time = mtime file
|
||||||
|
maxin = time if time > maxin
|
||||||
|
|
||||||
|
-- if any input file is more recent than any output file, we need to build
|
||||||
|
maxin > minout
|
||||||
|
|
||||||
|
actuallybuild: =>
|
||||||
|
if @mkdirs
|
||||||
|
mkdirs parent file for file in *@outs
|
||||||
|
disableentry file for file in *@outs
|
||||||
|
ctx = setmetatable {},
|
||||||
|
__index: (_, k) ->
|
||||||
|
switch k
|
||||||
|
when 'infile', 'in' then @ins[1]
|
||||||
|
when 'infiles' then @ins
|
||||||
|
when 'outfile', 'out' then @outs[1]
|
||||||
|
when 'outfiles' then @outs
|
||||||
|
when 'name' then @name
|
||||||
|
else error "No such field in TargetContext: #{k}"
|
||||||
|
__newindex: (k) =>
|
||||||
|
error "Attempt to set field #{k} of TargetContext"
|
||||||
|
for fn in *@buildfunctions
|
||||||
|
runwithcontext fn, @dag.env, ctx
|
||||||
|
|
||||||
|
updatecache: =>
|
||||||
|
clearentry file for file in *@outs
|
||||||
|
|
||||||
|
class FileTarget
|
||||||
|
new: =>
|
||||||
|
@priority = -huge
|
||||||
|
@buildfunctions = {}
|
||||||
|
@_mkdirs = false
|
||||||
|
@_sync = false
|
||||||
|
@_type = 'file'
|
||||||
|
@needtargets = {}
|
||||||
|
@infiles = {}
|
||||||
|
@depfunctions = {}
|
||||||
|
@outfiles = {'%'}
|
||||||
|
@pattern = '%'
|
||||||
|
|
||||||
|
matches: (name) =>
|
||||||
|
exists name
|
||||||
|
|
||||||
|
DepGraph
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
Target = require 'moonbuild.core.Target'
|
||||||
|
_ = require 'moonbuild._'
|
||||||
|
import flatten, patsubst from _
|
||||||
|
|
||||||
|
class Pipeline
|
||||||
|
new: (@ctx) =>
|
||||||
|
@lastsources = {}
|
||||||
|
|
||||||
|
sources: (...) =>
|
||||||
|
@lastsources = flatten @lastsources, ...
|
||||||
|
source: (src) =>
|
||||||
|
@lastsources = flatten @lastsources, src
|
||||||
|
|
||||||
|
step: (name, params) =>
|
||||||
|
public = true
|
||||||
|
public, params = false, name if (type name) == 'table'
|
||||||
|
|
||||||
|
tgttype = if params.pattern
|
||||||
|
error "pattern must be a table with the same format as patsubst" unless (type params.pattern) == 'table' and (type params.pattern[1]) == 'string' and (type params.pattern[2]) == 'string'
|
||||||
|
'pattern'
|
||||||
|
elseif params.output or params.out
|
||||||
|
error "output must be a string" unless (type params.output or params.out) == 'string'
|
||||||
|
'single'
|
||||||
|
else
|
||||||
|
error "invalid step type for pipeline: must be pattern or single (out/output)"
|
||||||
|
|
||||||
|
tgtouts = switch tgttype
|
||||||
|
when 'pattern' then patsubst @lastsources, params.pattern[1], params.pattern[2]
|
||||||
|
when 'single' then params.output or params.out
|
||||||
|
|
||||||
|
tgtpatt = switch tgttype
|
||||||
|
when 'pattern' then params.pattern[2]
|
||||||
|
when 'single' then nil
|
||||||
|
|
||||||
|
tgtins = switch tgttype
|
||||||
|
when 'pattern' then params.pattern[1]
|
||||||
|
when 'single' then @lastsources
|
||||||
|
|
||||||
|
tgtprod = switch tgttype
|
||||||
|
when 'pattern' then params.pattern[2]
|
||||||
|
when 'single' then '%'
|
||||||
|
|
||||||
|
tgt = with Target @ctx, tgtouts, pattern: tgtpatt
|
||||||
|
\depends tgtins
|
||||||
|
\produces tgtprod
|
||||||
|
\fn params.fn or error "pipeline steps need a fn"
|
||||||
|
tgt\mkdirs! if params.mkdirs
|
||||||
|
tgt\sync! if params.sync
|
||||||
|
@ctx\addtarget tgt
|
||||||
|
|
||||||
|
if public
|
||||||
|
@ctx\addtarget with Target @ctx, name
|
||||||
|
\depends tgtouts
|
||||||
|
.public = true
|
||||||
|
|
||||||
|
@lastsources = tgtouts
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import flatten, includes, patget from require 'moonbuild._common'
|
||||||
|
import insert from table
|
||||||
|
|
||||||
|
class Target
|
||||||
|
new: (@ctx, @name, opts={}) =>
|
||||||
|
@name = flatten @name if (type @name) != 'string'
|
||||||
|
@pattern = opts.pattern or ((type @name) == 'string' and @name or '%')
|
||||||
|
@priority = opts.priority or 0
|
||||||
|
error "pattern must be a string" unless (type @pattern) == 'string'
|
||||||
|
error "priority must be an int" unless (type @priority) == 'number' and @priority%1 == 0
|
||||||
|
|
||||||
|
@outfiles = {}
|
||||||
|
@infiles = {}
|
||||||
|
@needtargets = {}
|
||||||
|
@depfunctions = {}
|
||||||
|
@buildfunctions = {}
|
||||||
|
@_mkdirs = false
|
||||||
|
@_sync = false
|
||||||
|
@_type = 'normal'
|
||||||
|
@public = false
|
||||||
|
|
||||||
|
matches: (name) =>
|
||||||
|
if @name==name
|
||||||
|
return true
|
||||||
|
if (includes @name, name) and patget name, @pattern
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
produces: (...) =>
|
||||||
|
n = #@outfiles+1
|
||||||
|
for obj in *flatten ...
|
||||||
|
@outfiles[n], n = obj, n+1
|
||||||
|
|
||||||
|
depends: (...) =>
|
||||||
|
if (type ...) == 'function'
|
||||||
|
insert @depfunctions, (...)
|
||||||
|
else
|
||||||
|
n = #@infiles+1
|
||||||
|
for obj in *flatten ...
|
||||||
|
@infiles[n], n = obj, n+1
|
||||||
|
|
||||||
|
after: (...) =>
|
||||||
|
n = #@needtargets+1
|
||||||
|
for tgt in *flatten ...
|
||||||
|
@needtargets[n], n = tgt, n+1
|
||||||
|
|
||||||
|
fn: (fn) =>
|
||||||
|
insert @buildfunctions, fn
|
||||||
|
|
||||||
|
sync: =>
|
||||||
|
@_sync = true
|
||||||
|
|
||||||
|
mkdirs: =>
|
||||||
|
@_mkdirs = true
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import flatten from require 'moonbuild._common'
|
||||||
|
class Variable
|
||||||
|
@NIL: ->
|
||||||
|
|
||||||
|
new: (@name, ...) =>
|
||||||
|
@public = false
|
||||||
|
if (type @name) == 'table'
|
||||||
|
error "not a valid var table: #{next @name}" unless (type next @name) == 'string'
|
||||||
|
error "more than one var at once: #{next @name}, #{next @name, (next @name)}" if next @name, (next @name)
|
||||||
|
name = next @name
|
||||||
|
@name, param = name, @name
|
||||||
|
val = param[name]
|
||||||
|
if (select '#', ...) !=0 or (type val) == 'table'
|
||||||
|
@value = flatten val, ...
|
||||||
|
else
|
||||||
|
@value = val
|
||||||
|
elseif (select '#', ...) !=1 or (type ...) == 'table'
|
||||||
|
@value = flatten ...
|
||||||
|
else
|
||||||
|
@value = ...
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ok, MultiProcessExecutor = pcall -> require 'moonbuild.core.multiprocessexecutor'
|
||||||
|
ok and MultiProcessExecutor or require 'moonbuild.core.singleprocessexecutor'
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
SingleProcessExecutor = require 'moonbuild.core.singleprocessexecutor'
|
||||||
|
import fork, _exit from require 'posix.unistd'
|
||||||
|
import wait from require 'posix.sys.wait'
|
||||||
|
import open, stderr from io
|
||||||
|
import match from string
|
||||||
|
|
||||||
|
class Executor
|
||||||
|
@getmaxparallel: =>
|
||||||
|
fd = open '/proc/cpuinfo', 'r'
|
||||||
|
return 1 unless fd
|
||||||
|
ncpu = 0
|
||||||
|
for line in fd\lines!
|
||||||
|
ncpu += 1 if match line, '^processor%s*:'
|
||||||
|
fd\close!
|
||||||
|
ncpu == 0 and 1 or ncpu
|
||||||
|
|
||||||
|
new: (@dag, @nparallel) =>
|
||||||
|
@processes = {}
|
||||||
|
@nprocesses = 0
|
||||||
|
@building = {}
|
||||||
|
@nbuilt = 0
|
||||||
|
|
||||||
|
execute: (opts) =>
|
||||||
|
if @nparallel == 1
|
||||||
|
return (SingleProcessExecutor @dag, 1)\execute opts
|
||||||
|
|
||||||
|
block = @dag\buildablenodes!
|
||||||
|
while #block != 0
|
||||||
|
for node in *block
|
||||||
|
@addprocess node, opts
|
||||||
|
if @nprocesses == @nparallel
|
||||||
|
@waitprocess!
|
||||||
|
block = [node for node in *@dag\buildablenodes! when not @building[node]]
|
||||||
|
while #block == 0 and @nprocesses != 0
|
||||||
|
@waitprocess!
|
||||||
|
block = [node for node in *@dag\buildablenodes! when not @building[node]]
|
||||||
|
|
||||||
|
while @nprocesses !=0
|
||||||
|
@waitprocess!
|
||||||
|
|
||||||
|
for name, node in pairs @dag.nodes
|
||||||
|
error "Node #{name} wasn't built" unless node.built
|
||||||
|
|
||||||
|
unless opts.quiet
|
||||||
|
if @nbuilt == 0
|
||||||
|
print "Nothing to be done"
|
||||||
|
else
|
||||||
|
print "Built #{@nbuilt} targets"
|
||||||
|
|
||||||
|
addprocess: (node, opts) =>
|
||||||
|
if node.sync
|
||||||
|
while @nprocesses != 0
|
||||||
|
@waitprocess!
|
||||||
|
node\build opts
|
||||||
|
node.built = true
|
||||||
|
node\updatecache!
|
||||||
|
return
|
||||||
|
|
||||||
|
pid = fork!
|
||||||
|
error "Failed to fork" unless pid
|
||||||
|
if pid!=0
|
||||||
|
@processes[pid] = node
|
||||||
|
@nprocesses += 1
|
||||||
|
@building[node] = true
|
||||||
|
else
|
||||||
|
ok, status = pcall -> node\build opts
|
||||||
|
if ok
|
||||||
|
_exit status and 0 or 2
|
||||||
|
_exit 0
|
||||||
|
else
|
||||||
|
stderr\write status
|
||||||
|
_exit 1
|
||||||
|
|
||||||
|
waitprocess: =>
|
||||||
|
pid, ty, status = wait!
|
||||||
|
error "Failed to wait" unless pid
|
||||||
|
error "Failed to build #{@processes[pid].name}" if ty != 'exited' or status != 0 and status != 2
|
||||||
|
@processes[pid].built = true
|
||||||
|
@processes[pid]\updatecache!
|
||||||
|
@processes[pid] = nil
|
||||||
|
@nprocesses -= 1
|
||||||
|
@nbuilt += 1 if status == 0
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
class Executor
|
||||||
|
@getmaxparallel: => 1
|
||||||
|
|
||||||
|
new: (@dag, @nparallel) =>
|
||||||
|
|
||||||
|
execute: (opts) =>
|
||||||
|
nbuilt = 0
|
||||||
|
|
||||||
|
block = @dag\buildablenodes!
|
||||||
|
while #block != 0
|
||||||
|
for node in *block
|
||||||
|
nbuilt +=1 if node\build opts
|
||||||
|
node\updatecache!
|
||||||
|
node.built = true
|
||||||
|
block = @dag\buildablenodes!
|
||||||
|
|
||||||
|
for name, node in pairs @dag.nodes
|
||||||
|
error "Node #{name} wasn't built" unless node.built
|
||||||
|
|
||||||
|
unless opts.quiet
|
||||||
|
if nbuilt == 0
|
||||||
|
print "Nothing to be done"
|
||||||
|
else
|
||||||
|
print "Built #{nbuilt} targets"
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
_ = require 'moonbuild._'
|
||||||
|
|
||||||
|
(ctx) ->
|
||||||
|
varlayer = setmetatable {},
|
||||||
|
__index: _G
|
||||||
|
|
||||||
|
for name, var in pairs ctx.variables
|
||||||
|
rawset varlayer, name, var.value
|
||||||
|
|
||||||
|
env = setmetatable {},
|
||||||
|
__index: varlayer
|
||||||
|
__newindex: (k) => error "attempt to assign to global variable '#{k}', which is disabled in the global env"
|
||||||
|
|
||||||
|
rawset env, '_', _
|
||||||
|
rawset env, '_G', env
|
||||||
|
rawset env, '_ENV', env
|
||||||
|
|
||||||
|
env, varlayer
|
||||||
Vendored
+36
@@ -0,0 +1,36 @@
|
|||||||
|
Target = require 'moonbuild.core.Target'
|
||||||
|
Variable = require 'moonbuild.core.Variable'
|
||||||
|
Pipeline = require 'moonbuild.core.Pipeline'
|
||||||
|
_ = require 'moonbuild._'
|
||||||
|
import flatten from _
|
||||||
|
|
||||||
|
(ctx) ->
|
||||||
|
varlayer = setmetatable {},
|
||||||
|
__index: _G
|
||||||
|
|
||||||
|
for name, var in pairs ctx.variables
|
||||||
|
rawset varlayer, name, var.value
|
||||||
|
|
||||||
|
env = setmetatable {},
|
||||||
|
__index: varlayer
|
||||||
|
__newindex: (k) => error "attempt to assign to global variable '#{k}', use the function 'var' instead"
|
||||||
|
|
||||||
|
rawset env, '_', _
|
||||||
|
rawset env, '_G', env
|
||||||
|
rawset env, '_ENV', env
|
||||||
|
|
||||||
|
rawset env, 'var', (...) ->
|
||||||
|
var = Variable ...
|
||||||
|
ctx\addvar var
|
||||||
|
rawset varlayer, var.name, var.value
|
||||||
|
var
|
||||||
|
|
||||||
|
rawset env, 'target', (name, opts) ->
|
||||||
|
target = Target ctx, name, opts
|
||||||
|
ctx\addtarget target
|
||||||
|
target
|
||||||
|
|
||||||
|
rawset env, 'pipeline', ->
|
||||||
|
Pipeline ctx
|
||||||
|
|
||||||
|
env, varlayer
|
||||||
Vendored
+31
@@ -0,0 +1,31 @@
|
|||||||
|
initenv = require 'moonbuild.env.init'
|
||||||
|
Target = require 'moonbuild.core.Target'
|
||||||
|
Variable = require 'moonbuild.core.Variable'
|
||||||
|
|
||||||
|
(ctx, overrides) ->
|
||||||
|
env, varlayer = initenv ctx
|
||||||
|
|
||||||
|
rawset env, 'default', (target) ->
|
||||||
|
ctx\adddefault target
|
||||||
|
target
|
||||||
|
|
||||||
|
rawset env, 'public', (e) ->
|
||||||
|
clazz = ((getmetatable e) or {}).__class
|
||||||
|
if clazz == Target
|
||||||
|
e.public = true
|
||||||
|
elseif clazz == Variable
|
||||||
|
e.public = true
|
||||||
|
override = overrides[e.name]
|
||||||
|
if override
|
||||||
|
override = nil if override == Variable.NIL
|
||||||
|
e.value = override
|
||||||
|
rawset varlayer, e.name, override
|
||||||
|
else
|
||||||
|
error "cannot set an object of type #{clazz and clazz.__name or type e} public"
|
||||||
|
e
|
||||||
|
|
||||||
|
rawset env, 'init', (fn) ->
|
||||||
|
error "you can only add functions to init" unless (type fn) == 'function'
|
||||||
|
ctx\addinit fn
|
||||||
|
|
||||||
|
env, varlayer
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
import dir, attributes from require 'lfs'
|
|
||||||
|
|
||||||
import gmatch, match, gsub, sub from string
|
|
||||||
import insert, concat from table
|
|
||||||
|
|
||||||
ls = (d) ->
|
|
||||||
[f for f in dir d when f!='.' and f!='..']
|
|
||||||
|
|
||||||
lswithpath = (d) ->
|
|
||||||
if d==''
|
|
||||||
return ls '.'
|
|
||||||
[d..'/'..f for f in dir d when f!='.' and f!='..']
|
|
||||||
|
|
||||||
exists = (f) ->
|
|
||||||
(attributes f) != nil
|
|
||||||
|
|
||||||
isdir = (f) ->
|
|
||||||
a = attributes f
|
|
||||||
a and a.mode == 'directory' or false
|
|
||||||
|
|
||||||
mtime = (f) ->
|
|
||||||
a = attributes f
|
|
||||||
a and a.modification
|
|
||||||
|
|
||||||
matchglob = (str, glob) ->
|
|
||||||
patt = '^'..(gsub (gsub glob, '%*%*', '.*'), '%*', '[^/]*')..'$'
|
|
||||||
rst = if (type str)=='table'
|
|
||||||
results, i = {}, 1
|
|
||||||
for s in *str
|
|
||||||
rst = (match s, patt) and s
|
|
||||||
results[i], i = rst, i+1 if rst
|
|
||||||
results
|
|
||||||
else
|
|
||||||
(match str, patt) and str
|
|
||||||
rst
|
|
||||||
|
|
||||||
wildcard = (glob) ->
|
|
||||||
parts = [part for part in gmatch glob, '[^/]+']
|
|
||||||
absolute = (sub glob, 1, 1)=='/'
|
|
||||||
|
|
||||||
for i, part in ipairs parts
|
|
||||||
prevpath = (absolute and '/' or '') .. concat parts, '/', 1, i-1
|
|
||||||
currpath = prevpath .. '/' .. part
|
|
||||||
|
|
||||||
if match part, '%*%*.*%*%*'
|
|
||||||
error "Two '**' in the same path component in a wildcard"
|
|
||||||
|
|
||||||
if match part, '%*%*'
|
|
||||||
prefix = match currpath, '^(.*)%*%*'
|
|
||||||
suffix = (match part, '%*%*(.*)$') .. (i==#parts and '' or ('/'..concat parts, '/', i+1, #parts))
|
|
||||||
files = lswithpath prevpath
|
|
||||||
|
|
||||||
results = {}
|
|
||||||
for file in *files
|
|
||||||
if matchglob file, currpath
|
|
||||||
if i==#parts
|
|
||||||
insert results, file
|
|
||||||
elseif isdir file
|
|
||||||
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
|
|
||||||
insert results, result
|
|
||||||
if (matchglob file, prefix..'**') and isdir file
|
|
||||||
for result in *wildcard file .. '/**' .. suffix
|
|
||||||
insert results, result
|
|
||||||
return results
|
|
||||||
|
|
||||||
if match part, '%*'
|
|
||||||
files = lswithpath prevpath
|
|
||||||
|
|
||||||
if i==#parts
|
|
||||||
return matchglob files, glob
|
|
||||||
|
|
||||||
results = {}
|
|
||||||
for file in *files
|
|
||||||
if (matchglob file, currpath) and isdir file
|
|
||||||
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
|
|
||||||
insert results, result
|
|
||||||
return results
|
|
||||||
|
|
||||||
if exists glob
|
|
||||||
return {glob}
|
|
||||||
else
|
|
||||||
return {}
|
|
||||||
|
|
||||||
{
|
|
||||||
:wildcard
|
|
||||||
:exists, :isdir
|
|
||||||
:mtime
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import loadfile from require 'moonscript.base'
|
||||||
|
Context = require 'moonbuild.context'
|
||||||
|
DepGraph = require 'moonbuild.core.DAG'
|
||||||
|
Executor = require 'moonbuild.core.executor'
|
||||||
|
_ = require 'moonbuild._'
|
||||||
|
import insert from table
|
||||||
|
|
||||||
|
moonbuild = (...) ->
|
||||||
|
-- build argument table
|
||||||
|
opts = {}
|
||||||
|
for i=1, select '#', ...
|
||||||
|
arg = select i, ...
|
||||||
|
if (type arg) == 'string'
|
||||||
|
insert opts, arg
|
||||||
|
elseif (type arg) == 'table'
|
||||||
|
for k, v in pairs arg
|
||||||
|
opts[k] = v if (type k) != 'number'
|
||||||
|
for i, v in ipairs arg
|
||||||
|
insert opts, v
|
||||||
|
else
|
||||||
|
error "Invalid argument type #{type arg} for moonbuild"
|
||||||
|
|
||||||
|
-- resolve arguments
|
||||||
|
buildfile = opts.buildfile or opts.b or 'Build.moon'
|
||||||
|
opts.buildfile = buildfile
|
||||||
|
parallel = opts.parallel or opts.j or 1
|
||||||
|
parallel = true if parallel == 'y'
|
||||||
|
opts.parallel = parallel
|
||||||
|
quiet = opts.quiet or opts.q or false
|
||||||
|
opts.quiet = quiet
|
||||||
|
force = opts.force or opts.f or false
|
||||||
|
opts.force = force
|
||||||
|
verbose = opts.verbose or opts.v or false
|
||||||
|
opts.verbose = verbose
|
||||||
|
|
||||||
|
-- create context and DAG
|
||||||
|
ctx = Context!
|
||||||
|
ctx\load (loadfile buildfile), opts
|
||||||
|
print "Loaded buildfile" if verbose
|
||||||
|
ctx\init!
|
||||||
|
print "Initialized buildfile" if verbose
|
||||||
|
targets = #opts==0 and ctx.defaulttargets or opts
|
||||||
|
dag = DepGraph ctx, targets
|
||||||
|
print "Created dependancy graph" if verbose
|
||||||
|
|
||||||
|
-- and build
|
||||||
|
nparallel = parallel == true and Executor\getmaxparallel! or parallel
|
||||||
|
print "Building with #{nparallel} max parallel process#{nparallel>1 and "es" or ""}" if verbose
|
||||||
|
executor = Executor dag, nparallel
|
||||||
|
executor\execute opts
|
||||||
|
print "Finished" if verbose
|
||||||
|
|
||||||
|
table = {
|
||||||
|
:moonbuild, :_
|
||||||
|
:Context, :DepGraph, :Executor
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable table,
|
||||||
|
__call: (...) => moonbuild ...
|
||||||
|
__index: (name) => require "moonbuild.#{name}"
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import match, gmatch, sub from string
|
|
||||||
import upper, lower from string
|
|
||||||
|
|
||||||
GLOB_PATT='^([^%%]*)%%([^%%]*)$'
|
|
||||||
|
|
||||||
patsubst = (str, pattern, replacement) ->
|
|
||||||
return [patsubst s, pattern, replacement for s in *str] if (type str)=='table'
|
|
||||||
prefix, suffix = match pattern, GLOB_PATT
|
|
||||||
return str unless prefix
|
|
||||||
reprefix, resuffix = match replacement, GLOB_PATT
|
|
||||||
return replacement unless reprefix
|
|
||||||
|
|
||||||
if (sub str, 1, #prefix)==prefix and (sub str, -#suffix)==suffix
|
|
||||||
return reprefix..(sub str, #prefix+1, -#suffix-1)..resuffix
|
|
||||||
str
|
|
||||||
|
|
||||||
splitsp = (str) ->
|
|
||||||
[elem for elem in gmatch str, '%S+']
|
|
||||||
|
|
||||||
{
|
|
||||||
:patsubst
|
|
||||||
:splitsp
|
|
||||||
|
|
||||||
:upper, :lower
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
import insert, remove, concat, sort from table
|
|
||||||
unpack or= table.unpack
|
|
||||||
|
|
||||||
sortedpairs = (table, cmp) ->
|
|
||||||
keys = [k for k in pairs table]
|
|
||||||
sort keys, cmp
|
|
||||||
coroutine.wrap ->
|
|
||||||
for key in *keys
|
|
||||||
coroutine.yield key, table[key]
|
|
||||||
|
|
||||||
min = (table, cmp=(a, b) -> a<b) ->
|
|
||||||
val = table[1]
|
|
||||||
for i=2, #table
|
|
||||||
elem = table[i]
|
|
||||||
if cmp val, elem
|
|
||||||
val = elem
|
|
||||||
val
|
|
||||||
|
|
||||||
max = (table, cmp=(a, b) -> a<b) ->
|
|
||||||
val = table[1]
|
|
||||||
for i=2, #table
|
|
||||||
elem = table[i]
|
|
||||||
if not cmp val, elem
|
|
||||||
val = elem
|
|
||||||
val
|
|
||||||
|
|
||||||
foreach = (tab, fn) ->
|
|
||||||
[fn e for e in *tab]
|
|
||||||
|
|
||||||
first = (tab, fn) ->
|
|
||||||
for e in *tab
|
|
||||||
return e if fn e
|
|
||||||
|
|
||||||
exclude = (tab, ...) ->
|
|
||||||
i=1
|
|
||||||
while i<=#tab
|
|
||||||
removed=false
|
|
||||||
for j=1, select '#', ...
|
|
||||||
if tab[i]==select j, ...
|
|
||||||
remove tab, i
|
|
||||||
removed = true
|
|
||||||
break
|
|
||||||
i += 1 unless removed
|
|
||||||
tab
|
|
||||||
|
|
||||||
flatten = (tab) ->
|
|
||||||
return {tab} if (type tab)!='table'
|
|
||||||
out = {}
|
|
||||||
for e in *tab
|
|
||||||
if (type e)=='table'
|
|
||||||
insert out, v for v in *flatten e
|
|
||||||
else
|
|
||||||
insert out, e
|
|
||||||
out
|
|
||||||
|
|
||||||
{
|
|
||||||
:min, :max
|
|
||||||
:foreach
|
|
||||||
:first
|
|
||||||
:exclude
|
|
||||||
:flatten
|
|
||||||
:sortedpairs
|
|
||||||
|
|
||||||
:insert, :remove, :concat, :sort
|
|
||||||
:unpack
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
import wildcard, exists, isdir, mtime from require 'moonbuild.fsutil'
|
|
||||||
import foreach, first, flatten, exclude, sortedpairs, min, max from require 'moonbuild.tableutil'
|
|
||||||
import patsubst, splitsp from require 'moonbuild.stringutil'
|
|
||||||
|
|
||||||
import insert, concat, sort, pairs from require 'moonbuild.tableutil'
|
|
||||||
import upper, lower from require 'moonbuild.stringutil'
|
|
||||||
|
|
||||||
GLOB_PATT='^([^%%]*)%%([^%%]*)$'
|
|
||||||
|
|
||||||
-- command functions
|
|
||||||
escapecmdpart= (p) ->
|
|
||||||
if (type p)=='table'
|
|
||||||
return p.raw if p.raw
|
|
||||||
return concat [escapecmdpart part for part in *p], ' '
|
|
||||||
return p if p\match '^[a-zA-Z0-9_./-]+$'
|
|
||||||
'"'..p\gsub('\\', '\\\\')\gsub('"', '\\"')..'"'
|
|
||||||
escapecmd= (c, args={}) ->
|
|
||||||
c=escapecmdpart c
|
|
||||||
for a in *flatten args
|
|
||||||
c..=' '..escapecmdpart a if a
|
|
||||||
c
|
|
||||||
run= (c, args, params={}) ->
|
|
||||||
escaped=escapecmd c, args
|
|
||||||
print escaped if params.print
|
|
||||||
ret, _, code=os.execute escaped
|
|
||||||
ret, code=ret==0, ret if (type ret)=='number'
|
|
||||||
error "#{c} failed with code #{code}" if params.error and not ret
|
|
||||||
ret, code
|
|
||||||
popen= (c, args, mode='r', params={}) ->
|
|
||||||
escaped=escapecmd c, args
|
|
||||||
print escaped if params.print
|
|
||||||
io.popen escaped, mode
|
|
||||||
|
|
||||||
calccdeps= (infile, includesys=false) ->
|
|
||||||
data=(popen 'cc', {includesys and '-M' or '-MM', infile})\read '*a'
|
|
||||||
rawdeps=data\gsub('\\\n', '')\match ':(.+)'
|
|
||||||
[dep for dep in rawdeps\gmatch '%S+' when dep!=infile]
|
|
||||||
|
|
||||||
findclib= (name, mode='all') ->
|
|
||||||
args={name}
|
|
||||||
insert args, '--cflags' if mode=='all' or mode=='cc'
|
|
||||||
insert args, '--libs' if mode=='all' or mode=='ld'
|
|
||||||
[arg for arg in (popen 'pkg-config', args)\read('*a')\gmatch '%S+']
|
|
||||||
|
|
||||||
-- glob match
|
|
||||||
match= (str, glob) ->
|
|
||||||
prefix, suffix=glob\match GLOB_PATT
|
|
||||||
return str==glob unless prefix
|
|
||||||
return str\sub #prefix+1, -#suffix-1 if (str\sub 1, #prefix)==prefix and (str\sub -#suffix)==suffix
|
|
||||||
false
|
|
||||||
|
|
||||||
-- is a valid glob
|
|
||||||
isglob= (glob) ->
|
|
||||||
return if glob\match GLOB_PATT
|
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
|
|
||||||
-- getenv
|
|
||||||
env= (key, def) ->
|
|
||||||
(os.getenv key) or def
|
|
||||||
|
|
||||||
{
|
|
||||||
-- table function
|
|
||||||
:min, :max
|
|
||||||
:foreach
|
|
||||||
:first
|
|
||||||
:exclude
|
|
||||||
:flatten
|
|
||||||
:sortedpairs
|
|
||||||
|
|
||||||
:insert, :remove, :concat, :sort
|
|
||||||
:unpack
|
|
||||||
|
|
||||||
-- file functions
|
|
||||||
:wildcard
|
|
||||||
:mtime
|
|
||||||
:exists, :isdir
|
|
||||||
|
|
||||||
-- command functions
|
|
||||||
:run, :popen
|
|
||||||
:calccdeps, :findclib
|
|
||||||
|
|
||||||
-- string functions
|
|
||||||
:patsubst
|
|
||||||
:splitsp
|
|
||||||
|
|
||||||
:upper, :lower
|
|
||||||
|
|
||||||
-- glob functions
|
|
||||||
:match, :isglob
|
|
||||||
|
|
||||||
-- env functions
|
|
||||||
:env
|
|
||||||
}
|
|
||||||
Executable
+113
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env lua5.3
|
||||||
|
local loadfile
|
||||||
|
loadfile = require('moonscript.base').loadfile
|
||||||
|
local Context, DepGraph, Executor
|
||||||
|
do
|
||||||
|
local _obj_0 = require('moonbuild')
|
||||||
|
Context, DepGraph, Executor = _obj_0.Context, _obj_0.DepGraph, _obj_0.Executor
|
||||||
|
end
|
||||||
|
local Variable = (require('moonbuild'))['core.Variable']
|
||||||
|
local parseargs
|
||||||
|
parseargs = (require('moonbuild'))['_cmd.common'].parseargs
|
||||||
|
local argparse = require('argparse')
|
||||||
|
local sort, concat
|
||||||
|
do
|
||||||
|
local _obj_0 = table
|
||||||
|
sort, concat = _obj_0.sort, _obj_0.concat
|
||||||
|
end
|
||||||
|
local exit
|
||||||
|
exit = os.exit
|
||||||
|
local parser
|
||||||
|
do
|
||||||
|
local _with_0 = argparse("moonbuild", "A build system in moonscript")
|
||||||
|
_with_0:option('-b --buildfile', "Build file to use", 'Build.moon')
|
||||||
|
_with_0:option('-j --parallel', "Sets the number of parallel tasks, 'y' to run as many as we have cores", '1')
|
||||||
|
_with_0:flag('-l --list', "List the targets", false)
|
||||||
|
_with_0:flag('-V --list-variables', "List the variables", false)
|
||||||
|
_with_0:flag('-q --quiet', "Don't print targets as they are being built", false)
|
||||||
|
_with_0:flag('-f --force', "Always rebuild every target", false)
|
||||||
|
_with_0:flag('-v --verbose', "Be verbose", false);
|
||||||
|
(_with_0:option('-u --unset', "Unsets a variable")):count('*');
|
||||||
|
(_with_0:option('-s --set', "Sets a variable")):args(2):count('*');
|
||||||
|
(_with_0:option('-S --set-list', "Sets a variable to a list")):args(2):count('*');
|
||||||
|
(_with_0:argument('targets', "Targets to build")):args('*')
|
||||||
|
_with_0:add_complete()
|
||||||
|
parser = _with_0
|
||||||
|
end
|
||||||
|
local args = parser:parse()
|
||||||
|
local overrides = { }
|
||||||
|
local _list_0 = args.unset
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local unset = _list_0[_index_0]
|
||||||
|
overrides[unset] = Variable.NIL
|
||||||
|
end
|
||||||
|
local _list_1 = args.set
|
||||||
|
for _index_0 = 1, #_list_1 do
|
||||||
|
local set = _list_1[_index_0]
|
||||||
|
overrides[set[1]] = set[2]
|
||||||
|
end
|
||||||
|
local _list_2 = args.set_list
|
||||||
|
for _index_0 = 1, #_list_2 do
|
||||||
|
local set = _list_2[_index_0]
|
||||||
|
overrides[set[1]] = parseargs(set[2])
|
||||||
|
end
|
||||||
|
args.parallel = args.parallel == 'y' and 'y' or ((tonumber(args.parallel)) or error("Invalid argument for -j: " .. tostring(args.parallel)))
|
||||||
|
if args.parallel ~= 'y' and (args.parallel < 1 or args.parallel % 1 ~= 0) then
|
||||||
|
error("Invalid argument for -j: " .. tostring(args.parallel))
|
||||||
|
end
|
||||||
|
if args.verbose then
|
||||||
|
print("Parsed CLI args")
|
||||||
|
end
|
||||||
|
local ctx = Context()
|
||||||
|
ctx:load((loadfile(args.buildfile)), overrides)
|
||||||
|
if args.verbose then
|
||||||
|
print("Loaded buildfile")
|
||||||
|
end
|
||||||
|
if args.list then
|
||||||
|
print("Public targets")
|
||||||
|
local targets, n = { }, 1
|
||||||
|
local _list_3 = ctx.targets
|
||||||
|
for _index_0 = 1, #_list_3 do
|
||||||
|
local t = _list_3[_index_0]
|
||||||
|
if t.public then
|
||||||
|
targets[n], n = t.name, n + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sort(targets)
|
||||||
|
print(concat(targets, ", "))
|
||||||
|
print()
|
||||||
|
if not (args.list_variables) then
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if args.list_variables then
|
||||||
|
print("Public variables")
|
||||||
|
local vars, n = { }, 1
|
||||||
|
for k, v in pairs(ctx.variables) do
|
||||||
|
if v.public then
|
||||||
|
vars[n], n = k, n + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sort(vars)
|
||||||
|
print(concat(vars, ", "))
|
||||||
|
print()
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
ctx:init()
|
||||||
|
if args.verbose then
|
||||||
|
print("Initialized buildfile")
|
||||||
|
end
|
||||||
|
local targets = #args.targets == 0 and ctx.defaulttargets or args.targets
|
||||||
|
local dag = DepGraph(ctx, targets)
|
||||||
|
if args.verbose then
|
||||||
|
print("Created dependancy graph")
|
||||||
|
end
|
||||||
|
local nparallel = args.parallel == 'y' and Executor:getmaxparallel() or args.parallel
|
||||||
|
if args.verbose then
|
||||||
|
print("Building with " .. tostring(nparallel) .. " max parallel process" .. tostring(nparallel > 1 and "es" or ""))
|
||||||
|
end
|
||||||
|
local executor = Executor(dag, nparallel)
|
||||||
|
executor:execute(args)
|
||||||
|
if args.verbose then
|
||||||
|
return print("Finished")
|
||||||
|
end
|
||||||
+2821
File diff suppressed because it is too large
Load Diff
@@ -9,13 +9,18 @@ description:
|
|||||||
well as imperative rules.
|
well as imperative rules.
|
||||||
It represents the build as a DAG with explicit ordering,
|
It represents the build as a DAG with explicit ordering,
|
||||||
and doesn't give you any default confusing rules (unlike
|
and doesn't give you any default confusing rules (unlike
|
||||||
make)
|
make).
|
||||||
|
If you can, installing luaposix and/or luafilesystem
|
||||||
|
will speed up builds and increase stability.
|
||||||
homepage: https://github.com/natnat-mc/moonbuild
|
homepage: https://github.com/natnat-mc/moonbuild
|
||||||
dependencies:
|
dependencies:
|
||||||
- lua >= 5.3
|
- lua >= 5.1
|
||||||
- luafilesystem >= 1.7.0
|
- argparse >= 0.7.1-1
|
||||||
|
- moonscript >= 0.5.0-1
|
||||||
build:
|
build:
|
||||||
type: builtin
|
type: builtin
|
||||||
install:
|
install:
|
||||||
bin:
|
bin:
|
||||||
moonbuild: moonbuild.lua
|
moonbuild: out/moonbuild
|
||||||
|
modules:
|
||||||
|
moonbuild: out/moonbuild.lua
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.0.3",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.0.3-1"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.0.3",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.0.3-2"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.0.3",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.0.3-3"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.1.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.1.0-1"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.1.1",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.1.1-1"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.1.2",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.1.2-1"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.1.3",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.1.3-1"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.1.4",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.1.4-1"
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.3",
|
||||||
|
"luafilesystem >= 1.7.0",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v1.1.4",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "1.1.4-2"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.0.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.0.0-1"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.0.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.0.0-2"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.0.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.0.0-3"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.0-1"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.0-2"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.0-3"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.1",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.1-1"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.2",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.2-1"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.2",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.2-2"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.3",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.3-1"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.1.3",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.1.3-2"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.2.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.2.0-1"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.2.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.2.0-2"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.2.1",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.2.1-1"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.2.2",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.2.2-1"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.2.2",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.2.2-2"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.3.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.3.0-1"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.3.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.3.0-2"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
build = {
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
moonbuild = "out/moonbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modules = {
|
||||||
|
moonbuild = "out/moonbuild.lua"
|
||||||
|
},
|
||||||
|
type = "builtin"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"argparse >= 0.7.1-1",
|
||||||
|
"moonscript >= 0.5.0-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
|
||||||
|
summary = "Small build system in between make and a build.sh"
|
||||||
|
}
|
||||||
|
package = "moonbuild"
|
||||||
|
rockspec_format = "3.0"
|
||||||
|
source = {
|
||||||
|
tag = "v2.4.0",
|
||||||
|
url = "git://github.com/natnat-mc/moonbuild"
|
||||||
|
}
|
||||||
|
version = "2.4.0-1"
|
||||||
Reference in New Issue
Block a user