master
setup.lua
1#!/bin/lua
2
3-- prevent accidental use of undefined globals
4setmetatable(_G, {__index=function(_, var) error('undefined global \''..var..'\'') end})
5
6-- Lua 5.1 compatibility
7do
8 local os_execute = os.execute
9 os.execute = function(cmd)
10 local ret = os_execute(cmd)
11 return ret == true or ret == 0
12 end
13end
14
15basedir = arg[0]:match('(.*)/') or '.'
16
17if not os.execute('exec test -f config.lua') then
18 os.execute('exec cp '..basedir..'/config.def.lua config.lua')
19end
20
21dofile(basedir..'/ninja.lua')
22config = dofile 'config.lua'
23if not config.prefix then
24 config.prefix = ''
25end
26if not config.distdir then
27 config.distdir = 'dist'
28end
29
30local function shellpath(path, base)
31 if path == '.' then return base end
32 local abs = path:find('^/')
33 path = "'"..path:gsub([[']], [['\'']]).."'"
34 if abs then return path end
35 return base..'/'..path
36end
37local f = io.open('paths.sh', 'w')
38f:write(string.format([[
39basedir=%s
40builddir=%s
41distdir=%s
42]], shellpath(basedir, '$PWD'), shellpath(config.builddir, '$PWD'), shellpath(config.distdir, '$basedir')))
43f:close()
44
45local function gen(gendir)
46 local dir = basedir..'/'..gendir
47 local outdir = config.builddir..'/'..gendir
48 pkg={
49 name=gendir:match('[^/]*$'),
50 dir=dir,
51 gendir=gendir,
52 srcdir=dir..'/src',
53 outdir=outdir,
54 inputs={
55 index={},
56 fspec={},
57 gen={},
58 fetch={},
59 },
60 fspec={},
61 }
62 assert(os.execute(('exec mkdir -p %s %s'):format(gendir, outdir)))
63 io.output(gendir..'/local.ninja.tmp')
64 set('gendir', gendir)
65 if gendir ~= '.' then
66 set('dir', '$basedir/$gendir')
67 set('outdir', '$builddir/$gendir')
68 set('srcdir', '$dir/src')
69 end
70 load('gen.lua')
71
72 build('phony', '$gendir/gen', pkg.inputs.gen)
73
74 if pkg.hdrs then
75 phony('headers', pkg.hdrs)
76 if pkg.hdrs.install then
77 for hdr in iterstrings(pkg.hdrs) do
78 if not hdr:hasprefix('$outdir/include/') then
79 error('header is not in $outdir/include: '..hdr)
80 end
81 file(hdr:sub(9), '644', hdr)
82 end
83 end
84 end
85 if pkg.deps then
86 phony('deps', pkg.deps)
87 end
88
89 if next(pkg.fspec) then
90 local out = outdir..'/local.fspec'
91 local tmp = out..'.tmp'
92 local f = assert(io.open(tmp, 'w'))
93 local srcs = {}
94 for _, path, fspec in sortedpairs(pkg.fspec) do
95 f:write(('/%s\n'):format(path))
96 for _, k in ipairs{'type', 'mode', 'source', 'target'} do
97 local v = fspec[k]
98 if v then
99 f:write(('%s=%s\n'):format(k, v))
100 end
101 end
102 f:write('\n')
103 local src = fspec.source
104 if src then
105 srcs[#srcs + 1] = src
106 end
107 end
108 f:close()
109 if os.execute(('exec cmp -s %s %s'):format(tmp, out)) then
110 os.remove(tmp)
111 else
112 os.rename(tmp, out)
113 end
114 build('fspec-hash', '$outdir/local-hashed.fspec', {'$outdir/local.fspec', '|', '$builddir/pkg/fspec-sync/host/fspec-hash', srcs})
115 table.insert(pkg.inputs.fspec, '$outdir/local-hashed.fspec')
116 end
117 if next(pkg.inputs.index) then
118 build('cat', '$outdir/root.index', pkg.inputs.index, {
119 description=' INDEX $outdir/root.index',
120 })
121 else
122 build('empty', '$outdir/root.index')
123 end
124 if next(pkg.inputs.fspec) then
125 build('cat', '$outdir/tree.fspec', pkg.inputs.fspec, {
126 description = ' FSPEC $outdir/tree.fspec',
127 })
128 else
129 build('empty', '$outdir/tree.fspec')
130 end
131 build('phony', '$dir/root', pkg.inputs.root)
132 io.close()
133 os.rename(gendir..'/local.ninja.tmp', gendir..'/local.ninja')
134 if gendir == '.' then
135 os.execute('exec ln -sf local.ninja build.ninja')
136 end
137end
138
139function subgen(dir)
140 local file = '$gendir/'..dir..'/local.ninja'
141 subninja(file)
142 table.insert(pkg.inputs.gen, '$gendir/'..dir..'/gen')
143 table.insert(pkg.inputs.index, '$outdir/'..dir..'/root.index')
144 table.insert(pkg.inputs.fspec, '$outdir/'..dir..'/tree.fspec')
145 local oldpkg, oldout = pkg, io.output()
146 if pkg.gendir ~= '.' then
147 dir = pkg.gendir..'/'..dir
148 end
149 gen(dir)
150 pkg = oldpkg
151 io.output(oldout)
152end
153
154gen('.')