blob: e7a1c3a2df8f8494540d3d9724d65e63667f9f0f [file] [log] [blame]
James Kuszmaul9b8125e2019-09-01 17:42:25 -07001def _emcc_expand_files_impl(ctx):
2 tarfile = ctx.file.tarfile
3 html_shell = ctx.file.html_shell
4 basename = ctx.attr.name
5 html_out = ctx.actions.declare_file(basename + ".html")
6 tar_outs = [
7 ctx.actions.declare_file(basename + "." + extension)
8 for extension in ["js", "wasm"]
9 ]
10 if html_shell:
11 ctx.actions.expand_template(
12 output=html_out,
13 template=html_shell,
14 substitutions={
15 "{{{ SCRIPT }}}":
16 "<script async type=\"text/javascript\" src=\"" + basename +
17 ".js\"></script>",
18 })
19 else:
20 tar_outs.append(html_out)
21
22 ctx.actions.run_shell(
23 outputs=tar_outs,
24 inputs=[tarfile],
25 command="tar xf " + tarfile.path + " -C \"" + html_out.dirname + "\"")
26
27 return [DefaultInfo(files=depset(tar_outs + [html_out]))]
28
29
30emcc_expand_files = rule(
31 attrs={
32 "html_shell": attr.label(
33 mandatory=False,
34 allow_single_file=True,
35 ),
36 "tarfile": attr.label(
37 mandatory=True,
38 allow_single_file=True,
39 ),
40 },
41 doc="""
42 Handles the intermediate processing to extra files from a tarball
43 for emcc_binary. See emcc_binary for more detail.""",
44 implementation=_emcc_expand_files_impl,
45)
46
47
James Kuszmaul36816f32019-08-31 16:58:23 -070048def emcc_binary(name, srcs=[], linkopts=[], html_shell=None, **kwargs):
49 """Produces a deployable set of WebAssembly files.
50
51 Depending on the settings, the exact format of the output varies.
52 The output will be a a .js, .wasm, and optional .html file, all sharing the
53 same basename. The .js file is the script that should be included in any
54 webpage, and will handle calling the code compiled to the .wasm file.
55
56 The optional .html file uses some existing template html file and adds the
57 necessary <script> statement to import the .js script. This html file will
58 be generated if the name of the rule ends with ".html"; if the html_shell
59 argument is specified, then the provided html file is used to generate the
60 output html. The only change made to the template html is to replace any
61 instances of "{{{ SCRIPT }}}" with the appropriate <script> tags. This is
62 consistent with how the "--shell-file" flag works in emscripten. However, we
63 can't use the builtin flag with the script in its current form, because
64 that would require making an html file an input to a cc_library rule,
65 which bazel gets obnoxious about.
James Kuszmaul36816f32019-08-31 16:58:23 -070066
67 This macro also defines a rule with a name equal to the basename of
68 the name argument (e.g., if name = "foo.html", basename = "foo"). This rule
James Kuszmaul9b8125e2019-09-01 17:42:25 -070069 is the rule that actually outputs the required files.
James Kuszmaul36816f32019-08-31 16:58:23 -070070
71 Internally, this rule works by:
72 1) Generating a tarball that contains the .js and .wasm files, using
73 a cc_binary that calls the emscripten compiler.
74 2) Extracting said tarball.
James Kuszmaul9b8125e2019-09-01 17:42:25 -070075 3) [if necessary] Generating the output html from the html shell template.
James Kuszmaul36816f32019-08-31 16:58:23 -070076 """
James Kuszmaul27da8142019-07-21 16:13:55 -070077 includehtml = False
78 linkopts = list(linkopts)
James Kuszmaul36816f32019-08-31 16:58:23 -070079 srcs = list(srcs)
James Kuszmaul27da8142019-07-21 16:13:55 -070080 if name.endswith(".html"):
81 basename = name[:-5]
82 includehtml = True
James Kuszmaul27da8142019-07-21 16:13:55 -070083 elif name.endswith(".js"):
84 basename = name[:-3]
James Kuszmaul27da8142019-07-21 16:13:55 -070085 outputs = []
James Kuszmaul36816f32019-08-31 16:58:23 -070086 outputs.append(basename + ".js")
87 outputs.append(basename + ".wasm")
James Kuszmaul27da8142019-07-21 16:13:55 -070088
James Kuszmaul36816f32019-08-31 16:58:23 -070089 if includehtml and not html_shell:
James Kuszmaul27da8142019-07-21 16:13:55 -070090 outputs.append(basename + ".html")
James Kuszmaul36816f32019-08-31 16:58:23 -070091 tarfile = name + ".tar"
92 if html_shell:
93 tarfile = basename + ".js.tar"
94 native.cc_binary(
95 name=tarfile,
96 srcs=srcs,
97 linkopts=linkopts,
James Kuszmaul9b8125e2019-09-01 17:42:25 -070098 restricted_to=["//tools:web"],
James Kuszmaul36816f32019-08-31 16:58:23 -070099 **kwargs)
James Kuszmaul9b8125e2019-09-01 17:42:25 -0700100 emcc_expand_files(
101 name=basename,
102 html_shell=html_shell,
103 tarfile=tarfile,
104 restricted_to=["//tools:web"],
James Kuszmaul36816f32019-08-31 16:58:23 -0700105 )