|
3 | 3 |
|
4 | 4 | This wrapper currently serves the following purposes.
|
5 | 5 |
|
6 |
| -1. Ensures we always link to file with .js extension. The upstream default |
7 |
| - it to link to an llvm bitcode file which is never (AFAICT) want to do that. |
8 |
| -
|
9 |
| -2. When building with --config=wasm the final output is multiple files, usually |
| 6 | +1. When building with --config=wasm the final output is multiple files, usually |
10 | 7 | at least one .js and one .wasm file. Since the cc_binary link step only
|
11 | 8 | allows a single output, we must tar up the outputs into a single file.
|
12 | 9 |
|
13 |
| -3. Add quotes around arguments that need them in the response file to work |
| 10 | +2. Add quotes around arguments that need them in the response file to work |
14 | 11 | around a bazel quirk.
|
| 12 | +
|
| 13 | +3. Ensure the external_debug_info section of the wasm points at the correct |
| 14 | + bazel path. |
15 | 15 | """
|
16 | 16 |
|
17 | 17 | from __future__ import print_function
|
18 | 18 |
|
| 19 | +import argparse |
19 | 20 | import os
|
20 | 21 | import subprocess
|
21 | 22 | import sys
|
|
25 | 26 | param_filename = sys.argv[1][1:]
|
26 | 27 | param_file_args = [l.strip() for l in open(param_filename, 'r').readlines()]
|
27 | 28 |
|
28 |
| -output_index = param_file_args.index('-o') + 1 |
29 |
| -orig_output = js_output = param_file_args[output_index] |
30 |
| -outdir = os.path.dirname(orig_output) |
31 |
| - |
32 |
| -# google3-only(TODO(b/139440956): Default to False once the bug is fixed) |
33 |
| -replace_response_file = any(' ' in a for a in param_file_args) |
34 |
| - |
35 |
| -if not os.path.splitext(orig_output)[1]: |
36 |
| - js_output = orig_output + '.js' |
37 |
| - param_file_args[output_index] = js_output |
38 |
| - replace_response_file = True |
39 |
| - |
40 | 29 | # Re-write response file if needed.
|
41 |
| -if replace_response_file: |
| 30 | +if any(' ' in a for a in param_file_args): |
42 | 31 | new_param_filename = param_filename + '.modified'
|
43 | 32 | with open(new_param_filename, 'w') as f:
|
44 | 33 | for param in param_file_args:
|
|
54 | 43 | if rtn != 0:
|
55 | 44 | sys.exit(1)
|
56 | 45 |
|
57 |
| -js_name = os.path.basename(js_output) |
58 |
| -base_name = os.path.splitext(js_name)[0] |
| 46 | +# Parse the arguments that we gave to the linker to determine what the output |
| 47 | +# file is named and what the output format is. |
| 48 | +parser = argparse.ArgumentParser(add_help=False) |
| 49 | +parser.add_argument('-o') |
| 50 | +parser.add_argument('--oformat') |
| 51 | +options = parser.parse_known_args(param_file_args)[0] |
| 52 | +output_file = options.o |
| 53 | +oformat = options.oformat |
| 54 | +outdir = os.path.dirname(output_file) |
| 55 | +base_name = os.path.basename(output_file) |
| 56 | + |
| 57 | +# The output file name is the name of the build rule that was built. |
| 58 | +# Add an appropriate file extension based on --oformat. |
| 59 | +if oformat is not None: |
| 60 | + base_name_split = os.path.splitext(base_name) |
| 61 | + |
| 62 | + # If the output name has no extension, give it the appropriate extension. |
| 63 | + if not base_name_split[1]: |
| 64 | + os.rename(output_file, output_file + '.' + oformat) |
| 65 | + |
| 66 | + # If the output name does have an extension and it matches the output format, |
| 67 | + # change the base_name so it doesn't have an extension. |
| 68 | + elif base_name_split[1] == '.' + oformat: |
| 69 | + base_name = base_name_split[0] |
| 70 | + |
| 71 | + # If the output name does have an extension and it does not match the output |
| 72 | + # format, change the base_name so it doesn't have an extension and rename |
| 73 | + # the output_file so it has the proper extension. |
| 74 | + # Note that if you do something like name your build rule "foo.js" and pass |
| 75 | + # "--oformat=html", emscripten will write to the same file for both the js and |
| 76 | + # html output, overwriting the js output entirely with the html. |
| 77 | + # Please don't do that. |
| 78 | + else: |
| 79 | + base_name = base_name_split[0] |
| 80 | + os.rename(output_file, os.path.join(outdir, base_name + '.' + oformat)) |
59 | 81 |
|
60 | 82 | files = []
|
61 | 83 | extensions = [
|
|
67 | 89 | '.worker.js',
|
68 | 90 | '.data',
|
69 | 91 | '.js.symbols',
|
70 |
| - '.wasm.debug.wasm' |
| 92 | + '.wasm.debug.wasm', |
| 93 | + '.html' |
71 | 94 | ]
|
72 | 95 |
|
73 | 96 | for ext in extensions:
|
|
112 | 135 | binary_part = '1' + binary_part
|
113 | 136 | final_bytes.append(int(binary_part, 2))
|
114 | 137 | # Finally, add the actual filename.
|
115 |
| - final_bytes.extend(base_name + '.wasm.debug.wasm') |
| 138 | + final_bytes.extend((base_name + '.wasm.debug.wasm').encode()) |
116 | 139 |
|
117 | 140 | # Write our length + filename bytes to a temp file.
|
118 | 141 | with open('debugsection.tmp', 'wb+') as f:
|
|
134 | 157 | if len(files) > 1:
|
135 | 158 | cmd = ['tar', 'cf', 'tmp.tar'] + files
|
136 | 159 | subprocess.check_call(cmd, cwd=outdir)
|
137 |
| - os.rename(os.path.join(outdir, 'tmp.tar'), orig_output) |
| 160 | + os.rename(os.path.join(outdir, 'tmp.tar'), output_file) |
138 | 161 | elif len(files) == 1:
|
139 | 162 | # Otherwise, if only have a single output than move it to the expected name
|
140 |
| - if files[0] != os.path.basename(orig_output): |
141 |
| - os.rename(os.path.join(outdir, files[0]), orig_output) |
| 163 | + if files[0] != os.path.basename(output_file): |
| 164 | + os.rename(os.path.join(outdir, files[0]), output_file) |
142 | 165 | else:
|
143 | 166 | print('emcc.py did not appear to output any known files!')
|
144 | 167 | sys.exit(1)
|
|
0 commit comments