blob: cd374720e24991b1591b5107ef1b8fc81ed4d057 [file] [log] [blame]
James Kuszmaul27da8142019-07-21 16:13:55 -07001# Sourced from https://github.com/ribrdb/rules_emscripten/blob/master/toolchain/defs.bzl
2# TODO(james): Specialize this more for our purposes--e.g.,
3# we probably will only actually use one set of the possible options.
James Kuszmaul36816f32019-08-31 16:58:23 -07004def emcc_binary(name, srcs=[], linkopts=[], html_shell=None, **kwargs):
5 """Produces a deployable set of WebAssembly files.
6
7 Depending on the settings, the exact format of the output varies.
8 The output will be a a .js, .wasm, and optional .html file, all sharing the
9 same basename. The .js file is the script that should be included in any
10 webpage, and will handle calling the code compiled to the .wasm file.
11
12 The optional .html file uses some existing template html file and adds the
13 necessary <script> statement to import the .js script. This html file will
14 be generated if the name of the rule ends with ".html"; if the html_shell
15 argument is specified, then the provided html file is used to generate the
16 output html. The only change made to the template html is to replace any
17 instances of "{{{ SCRIPT }}}" with the appropriate <script> tags. This is
18 consistent with how the "--shell-file" flag works in emscripten. However, we
19 can't use the builtin flag with the script in its current form, because
20 that would require making an html file an input to a cc_library rule,
21 which bazel gets obnoxious about.
22 TODO(james): Rewrite this as a rule so that we can do some of this more
23 cleanly.
24
25 This macro also defines a rule with a name equal to the basename of
26 the name argument (e.g., if name = "foo.html", basename = "foo"). This rule
27 is a filegroup containing all the output files of this rule.
28
29 Internally, this rule works by:
30 1) Generating a tarball that contains the .js and .wasm files, using
31 a cc_binary that calls the emscripten compiler.
32 2) Extracting said tarball.
33 3) Generating the output html from the html shell template.
34 """
James Kuszmaul27da8142019-07-21 16:13:55 -070035 includehtml = False
36 linkopts = list(linkopts)
James Kuszmaul36816f32019-08-31 16:58:23 -070037 srcs = list(srcs)
James Kuszmaul27da8142019-07-21 16:13:55 -070038 if name.endswith(".html"):
39 basename = name[:-5]
40 includehtml = True
James Kuszmaul27da8142019-07-21 16:13:55 -070041 elif name.endswith(".js"):
42 basename = name[:-3]
James Kuszmaul27da8142019-07-21 16:13:55 -070043 outputs = []
James Kuszmaul36816f32019-08-31 16:58:23 -070044 outputs.append(basename + ".js")
45 outputs.append(basename + ".wasm")
James Kuszmaul27da8142019-07-21 16:13:55 -070046
James Kuszmaul36816f32019-08-31 16:58:23 -070047 if includehtml and not html_shell:
James Kuszmaul27da8142019-07-21 16:13:55 -070048 outputs.append(basename + ".html")
James Kuszmaul36816f32019-08-31 16:58:23 -070049 tarfile = name + ".tar"
50 if html_shell:
51 tarfile = basename + ".js.tar"
52 native.cc_binary(
53 name=tarfile,
54 srcs=srcs,
55 linkopts=linkopts,
56 restricted_to = ["//tools:web"],
57 **kwargs)
58 native.genrule(
59 name="emcc_extract_" + tarfile,
60 srcs=[tarfile],
61 outs=outputs,
62 output_to_bindir=1,
63 testonly=kwargs.get('testonly'),
64 restricted_to = ["//tools:web"],
65 cmd="""tar xf $< -C "$(@D)"/$$(dirname "%s")""" % [outputs[0]])
66 if html_shell:
67 native.genrule(
68 name = "generate_shell_" + name,
69 srcs = [html_shell],
70 outs = [basename + ".html"],
71 restricted_to = ["//tools:web"],
72 cmd = "sed 's/{{{ SCRIPT }}}/<script async type=\"text\/javascript\" src=\"" + basename + ".js\"><\/script>/' $< > $@",
73 )
74 outputs.append(basename + ".html")
75 native.filegroup(
76 name = basename,
77 srcs = outputs,
78 restricted_to = ["//tools:web"]
79 )