forked from sunjay/turtle
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild-wasm
More file actions
executable file
·166 lines (131 loc) · 5.07 KB
/
build-wasm
File metadata and controls
executable file
·166 lines (131 loc) · 5.07 KB
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
#!/usr/bin/env python3
# Minimum python version 3.5.2
##################################################################
#
# FOR USAGE INSTRUCTIONS: ./build-wasm --help
#
##################################################################
# To build with emscripten instead, download `wargo` and use `wargo build`
# instead of `cargo build`
# https://github.com/lord/wargo
import os
import sys
import shlex
import argparse
import subprocess
import pathlib
description = """
Build turtle or its examples into WebAssembly files. Automatically builds in
release mode (with debug symbols) and uses wasm-gc to compress the generated
WASM even further. Reasonably configurable, see documentation below.
Uses the stable toolchain (configurable via the rust-toolchain file) because
that is the version supported by turtle.
# Examples
Build `examples/circle.rs` into WebAssembly:
./build-wasm --example circle
To also generate a .wat file in the WebAssembly text format, use --wat:
./build-wasm --example circle --wat
To see the exact commands being run, use -V or --verbose:
./build-wasm --example circle --wat -V
# Tools
cargo is available via: https://rustup.rs
wasm-gc is available via: https://github.com/alexcrichton/wasm-gc
or via: `cargo install wasm-gc`
wasm2wat is available via: https://github.com/WebAssembly/wabt
# Usage
""".strip()
class Color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
def main():
args = parse_args()
cwd = os.path.abspath(os.path.dirname(__file__))
build_command = ['cargo', 'build', '--no-default-features']
env = dict(**os.environ)
dest_wasm = ''
if args.target:
build_command.extend(['--target', args.target])
if args.release_mode:
build_command.append('--release')
# Make sure debug symbols are included so we can debug
env.setdefault("RUSTFLAGS", "-g")
if args.example:
build_command.extend(['--example', args.example])
build_mode = 'release' if args.release_mode else 'debug'
dest_wasm = os.path.join(
cwd,
"target",
args.target,
build_mode,
'examples',
'{}.wasm'.format(args.example),
)
run_debug(build_command, env=env, cwd=cwd, verbose=args.verbose)
if args.wasm_gc and dest_wasm:
gc_file = str(pathlib.Path(dest_wasm).with_suffix('.gc.wasm'))
wasm_gc = ['wasm-gc', dest_wasm, '-o', gc_file]
run_debug(wasm_gc, cwd=cwd, verbose=args.verbose)
dest_wasm = gc_file
if dest_wasm:
info('Output WASM:', os.path.relpath(dest_wasm))
if args.wat and dest_wasm:
wat_file = str(pathlib.Path(dest_wasm).with_suffix('.wat'))
wasm_gc = [
'wasm2wat',
'--ignore',
'--fold',
'--gen',
'--inline-export',
'--no-check',
dest_wasm,
]
with open(wat_file, 'w') as f:
run_debug(wasm_gc, cwd=cwd, verbose=args.verbose, stdout=f)
info('Output WAT:', os.path.relpath(wat_file))
def parse_args():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=description
)
parser.add_argument('--example', dest='example', default=None,
help='The specific example to compile into WASM')
parser.add_argument('--target', dest='target', metavar='TARGET',
default='wasm32-unknown-unknown',
help='Default: wasm32-unknown-unknown')
parser.add_argument('--no-release', dest='release_mode', action='store_false',
default=True, help='Do not use --release')
parser.add_argument('--no-gc', dest='wasm_gc', action='store_false',
default=True, help='Do not run wasm-gc on the file')
parser.add_argument('--wat', dest='wat', action='store_true',
default=False, help='Generate .wat file from .wasm using wasm2wat')
parser.add_argument('-V', '--verbose', dest='verbose', action='store_true',
default=False, help='More verbose logging')
return parser.parse_args()
def run_debug(cmd, *, env=os.environ, cwd, verbose, **kwargs):
if verbose:
debug('Running command:', ' '.join(map(shlex.quote, cmd)))
# Only print the environment variables that we added
added_vars = {k: env[k] for k in set(env.keys()) - set(os.environ.keys())}
debug(' Added Environment:', added_vars)
debug(' Current Working Directory:', os.path.relpath(cwd))
subprocess.run(cmd, env=env, cwd=cwd, **kwargs).check_returncode()
def info(*args, bold=False, **kwargs):
fmt_print(Color.BLUE, *args, bold=bold, **kwargs)
def debug(*args, bold=False, **kwargs):
fmt_print(Color.YELLOW, *args, bold=bold, **kwargs)
def fmt_print(color, *args, bold=False, **kwargs):
print(color, end='')
if bold:
print(Color.BOLD, end='')
print(*args, **kwargs)
print(Color.END, end='')
if __name__ == '__main__':
main()