-
Notifications
You must be signed in to change notification settings - Fork 28
/
build.wake
331 lines (263 loc) · 9.51 KB
/
build.wake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# Copyright 2019 SiFive, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You should have received a copy of LICENSE.Apache2 along with
# this software. If not, you may obtain a copy at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
package build_wake
from wake import _
# Useful build variants (arguments to all)
def toVariant = match _
"default" -> Pass (Pair "native-cpp14-release" "native-c11-release")
"static" -> Pass (Pair "native-cpp14-static" "native-c11-static")
"debug" -> Pass (Pair "native-cpp14-debug" "native-c11-debug")
"wasm" -> Pass (Pair "wasm-cpp14-release" "wasm-c11-release")
s -> Fail "Unknown build target ({s})".makeError
export def build: List String => Result String Error = match _
"tarball", Nil ->
tarball Unit
| rmap (\_ "TARBALL")
"wasm", Nil ->
require Pass variant = toVariant "wasm"
buildLSP variant
| rmap format
kind, Nil ->
require Pass variant = toVariant kind
all variant
| rmap (\_ "BUILD")
_ -> Fail "no target specified (try: build default/debug/tarball)".makeError
export def install: List String => Result String Error = match _
dest, kind, Nil ->
doInstall (in cwd dest) kind
| rmap (\_ "INSTALL")
dest, Nil ->
doInstall (in cwd dest) "default"
| rmap (\_ "INSTALL")
_ -> Fail "no directory specified (try: install /opt/local)".makeError
def bootstrapTarget targetFn variant =
require Pass paths = targetFn variant
require Some _ = getenv "BOOTSTRAP_WAKE"
else Pass paths
def cppSuffixRegex =
(".", variant.getPairFirst, Nil)
| cat
| quote
def cSuffixRegex =
(".", variant.getPairSecond, Nil)
| cat
| quote
def getInstallName path =
path.getPathName
| replace cppSuffixRegex ""
| replace cSuffixRegex ""
def doInstall path =
def location = getInstallName path
def installed =
makeExecPlan ("cp", path.getPathName, location, Nil) (path,)
| setPlanLabel "Bootstrap {location}"
| runJobWith defaultRunner
| getJobOutputs
match installed
Pass (first, Nil) -> Pass first
_ -> Fail "Unexpected arity in bootstrap install".makeError
paths
| map doInstall
| findFail
# Build all wake targets
def targets =
buildWake,
buildWakeBox,
buildFuseDaemon,
buildShim,
buildHash,
buildBSP,
(bootstrapTarget buildLSP),
buildWakeFormat,
(bootstrapTarget buildJobCache),
Nil
def all variant =
require Pass x =
map (_ variant) targets
| findFail
Pass (flatten x)
# Install wake into a target location
def doInstall dest kind =
# kick off in parallel, but rsc, rsc_tool, and rsc_migration cannot be built at the same
# time right now. Force them to be serial relative to each other.
def install_rsc_bins =
require Pass rsc_migration = buildRSCMigration Unit
require Pass rsc_migration = installAs "{dest}/bin/wake-rsc-migration" rsc_migration
require Pass rsc = buildRSC Unit
require Pass rsc = installAs "{dest}/bin/wake-rsc" rsc
require Pass rsc_tool = buildRSCTool Unit
require Pass rsc_tool = installAs "{dest}/bin/wake-rsc-tool" rsc_tool
Pass (Triple rsc rsc_tool rsc_migration)
def install_log_viewer =
buildWakeLogViewer Unit
| rmapPass (installAs "{dest}/bin/wake-log-viewer")
def install_datfiles =
sources "{@here}/share" `.*`
| rmapPass (\files findFailFn (installIn dest ".") files)
def install_readme =
source "README.md"
| rmapPass (\file installIn "{dest}/share/doc/wake" "." file)
require Pass variant = toVariant kind
def releaseBin exe = installAs "{dest}/{replace `\.[^.]*$` '' exe.getPathName}" exe
def install_binfiles =
all variant
| rmapPass (\files findFailFn releaseBin files)
# Join on the installs now that everything has been kicked off
require Pass readme = install_readme
require Pass datfiles = install_datfiles
require Pass binfiles = install_binfiles
# Rust builds are slow, delay blocking on them for as long as possible
require Pass (Triple rsc rsc_tool rsc_migration) = install_rsc_bins
require Pass log_viewer = install_log_viewer
(readme, log_viewer, rsc, rsc_tool, rsc_migration, binfiles ++ datfiles)
| Pass
# Replace @VERSION@ with 'release'
def setVersion release file =
require Pass in = source "{file}.in"
def script =
"""
set -e
sed "s/@VERSION@/%{release}/g" "%{in.getPathName}" > "%{file}.tmp"
mv "%{file}.tmp" "%{file}"
"""
makeShellPlan script (in, Nil)
| setPlanLabel "release: replace placeholder with version number"
| runJobWith defaultRunner
| getJobOutput
# Create a release tarball
def tarball Unit =
def releaseResult = buildAs Unit
def timeResult = buildOn Unit
require Pass release = releaseResult
require Pass time = timeResult
# Create debian + RedHat package files
require Pass changelog = setVersion release "debian/changelog"
require Pass spec = setVersion release "wake.spec"
# Identify those sources files to include in the tarball
require Pass allSources = sources "." `.*`
def excludeGlobs =
"**/.gitignore",
".circleci/**",
"debian/**",
".github/**",
".vscode/**",
".clang-format",
".dockerignore",
".git-blame-ignore-revs",
".gitattributes",
".wakemanifest",
"wake.spec.in",
def matchesAnyGlob path =
excludeGlobs
| map globToRegExp
| exists (matches _ path.getPathName)
def Pair rejects srcs =
allSources
| splitBy matchesAnyGlob
def _ =
def files = (rejects | map (\x ((" ", x.getPathName, Nil) | cat)))
def msg = "Files below are excluded from tarball", files
msg
| map (printlnLevel logInfo _)
def Pair testPaths wakePaths = splitBy (matches `tests/.*` _.getPathName) srcs
def wakeSourcesString =
wakePaths
| map (_.getPathName.format)
| foldr (_, ",\n ", _) Nil
| cat
def testSourcesString =
testPaths
| map (getPathName _ | format | replace `^"tests/` '"{@here}/')
| foldr (_, ",\n ", _) Nil
| cat
def manifestStr =
"""
# Generated by 'wake tarball Unit':
package build_wake
from wake import source , Nil
publish releaseAs =
'%{release}', Nil
publish releaseOn =
'%{time}', Nil
publish source =
%{wakeSourcesString}Nil
"""
def testsManifestStr =
"""
# Generated by 'wake tarball Unit':
package test_wake
from wake import source , Nil
publish source =
%{testSourcesString}Nil
"""
# Create a manifest which describes the release and source files
require Pass manifest = write "manifest.wake" manifestStr
require Pass testManifest = write "tests/manifest.wake" testsManifestStr
# Execute tar to create a tarball of manifest + sources
require Pass tarball =
def cmd =
def gnutar = which "gnutar"
def tar = if gnutar ==* "gnutar" then which "tar" else gnutar
def files =
map getPathName (manifest, testManifest, spec, srcs)
| sortBy scmp
tar,
"--mtime={time}",
"--transform=s@^@wake-{release}/@",
"--owner=0",
"--group=0",
"--numeric-owner",
"-cJf",
"wake_{release}.tar.xz",
files
makeExecPlan cmd (manifest, testManifest, spec, srcs)
| setPlanLabel "release: package wake source tarball"
# Since this includes the current time, it's not going to benefit from caching.
| setPlanKeep False
| runJobWith defaultRunner
| getJobOutput
Pass (tarball, changelog, Nil)
export def static _: Result Path Error =
def filesResult = doInstall "tmp" "static"
def releaseResult = buildAs Unit
def timeResult = buildOn Unit
require Pass release = releaseResult
require Pass time = timeResult
require Pass files = filesResult
def cmd =
which "tar",
"--mtime={time}",
"--transform=s@^tmp/@wake-{release}/@",
"--owner=0",
"--group=0",
"--numeric-owner",
"-cJf",
"wake-static_{release}.tar.xz",
map getPathName files | sortBy scmp
makeExecPlan cmd files
| setPlanLabel "release: package wake-static tarball"
# Since this includes the current time, it's not going to benefit from caching.
| setPlanKeep False
| runJobWith defaultRunner
| getJobOutput
from test_wake import topic wakeTestBinary
from test_wake import topic wakeUnitTestBinary
publish wakeTestBinary =
defaultWake, Nil
publish wakeUnitTestBinary =
buildWakeUnit, Nil
def defaultWake Unit =
require Pass wakeVisible = doInstall "tmp" "default"
Pass (Pair "tmp/bin/wake" wakeVisible)