diff options
Diffstat (limited to 'emcc')
-rwxr-xr-x | emcc | 94 |
1 files changed, 67 insertions, 27 deletions
@@ -50,7 +50,7 @@ emcc can be influenced by a few environment variables: import os, sys, shutil, tempfile, subprocess, shlex, time, re, logging from subprocess import PIPE, STDOUT from tools import shared, jsrun -from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename +from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename, WINDOWS from tools.response_file import read_response_file CXX_SUFFIXES = ('.cpp', '.cxx', '.cc') @@ -397,7 +397,8 @@ Options that are modified or new in %s include: --shell-file <path> The path name to a skeleton HTML file used when generating HTML output. The shell file used needs to have this token inside it: - {{{ SCRIPT_CODE }}} + {{{ SCRIPT }}} + (see src/shell.html for an example) Note that this argument is ignored if a target other than HTML is specified using the -o option. @@ -501,7 +502,8 @@ The target file, if specified (-o <target>), defines what will be generated: <name>.js JavaScript - <name>.html HTML with embedded JavaScript + <name>.html HTML + side JavaScript file (<name>.js) + (JS on the side improves page load time) <name>.bc LLVM bitcode (default) <name>.o LLVM bitcode (same as .bc) @@ -542,7 +544,7 @@ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR P exit(0) elif len(sys.argv) == 2 and sys.argv[1] == '-v': # -v with no inputs - print 'emcc (Emscripten GCC-like replacement + linker emulating GNU ld ) 2.0' + print 'emcc (Emscripten GCC-like replacement + linker emulating GNU ld ) %s' % shared.EMSCRIPTEN_VERSION exit(subprocess.call([shared.CLANG, '-v'])) def is_minus_s_for_emcc(newargs,i): @@ -775,6 +777,7 @@ try: save_bc = False memory_init_file = False use_preload_cache = False + no_heap_copy = False proxy_to_worker = False if use_cxx: @@ -884,8 +887,17 @@ try: check_bad_eq(newargs[i]) parts = newargs[i+1].split(',') assert len(parts) == 3, '--compression requires specifying native_encoder,js_decoder,js_name - see emcc --help. got: %s' % newargs[i+1] - Compression.encoder = parts[0] - Compression.decoder = parts[1] + def locate(tool): + if WINDOWS: + if os.path.exists(tool+'.exe'): + return tool+'.exe' + if os.path.exists(tool+'.bat'): + return tool+'.bat' + if os.path.exists(tool+'.cmd'): + return tool+'.cmd' + return tool + Compression.encoder = locate(parts[0]) + Compression.decoder = locate(parts[1]) Compression.js_name = parts[2] assert os.path.exists(Compression.encoder), 'native encoder %s does not exist' % Compression.encoder assert os.path.exists(Compression.decoder), 'js decoder %s does not exist' % Compression.decoder @@ -895,6 +907,9 @@ try: elif newargs[i].startswith('--use-preload-cache'): use_preload_cache = True newargs[i] = '' + elif newargs[i].startswith('--no-heap-copy'): + no_heap_copy = True + newargs[i] = '' elif newargs[i] == '--ignore-dynamic-linking': ignore_dynamic_linking = True newargs[i] = '' @@ -1127,10 +1142,11 @@ try: heap = 4096 while heap < shared.Settings.TOTAL_MEMORY: - if heap <= 16*1024*1024: - heap *= 2 - else: - heap += 16*1024*1024 + heap *= 2 + #if heap <= 16*1024*1024: + # heap *= 2 + #else: + # heap += 16*1024*1024 if heap != shared.Settings.TOTAL_MEMORY: logging.warning('increasing TOTAL_MEMORY to %d to be more reasonable for asm.js' % heap) shared.Settings.TOTAL_MEMORY = heap @@ -1258,7 +1274,16 @@ try: shutil.move(in_temp(unsuffixed(uniquename(input_file)) + '.o'), unsuffixed_basename(input_file) + '.' + final_suffix) else: if len(input_files) == 1: - shutil.move(in_temp(unsuffixed(uniquename(input_files[0])) + '.o'), specified_target) + temp_output_base = in_temp(unsuffixed(uniquename(input_files[0]))) + shutil.move(temp_output_base + '.o', specified_target) + if os.path.exists(temp_output_base + '.d'): + # There was a .d file generated, from -MD or -MMD and friends, save a copy of it to where the output resides, + # adjusting the target name away from the temporary file name to the specified target. + # It will be deleted with the rest of the temporary directory. + deps = open(temp_output_base + '.d').read() + deps = deps.replace(temp_output_base + '.o', specified_target) + with open(os.path.join(os.path.dirname(specified_target), os.path.basename(unsuffixed(input_files[0]) + '.d')), "w") as out_dep: + out_dep.write(deps) else: assert len(original_input_files) == 1 or not has_dash_c, 'fatal error: cannot specify -o with -c with multiple files' + str(sys.argv) + ':' + str(original_input_files) # We have a specified target (-o <target>), which is not JavaScript or HTML, and @@ -1423,6 +1448,12 @@ try: 'wctob.c', 'wctomb.c', ]], + ['regex', [ + 'regcomp.c', + 'regerror.c', + 'regexec.c', + 'tre-mem.c', + ]], ['stdio', [ 'fwprintf.c', 'swprintf.c', @@ -1625,18 +1656,26 @@ try: else: # At minimum remove dead functions etc., this potentially saves a lot in the size of the generated code (and the time to compile it) link_opts += shared.Building.get_safe_internalize() + ['-globaldce'] - shared.Building.llvm_opt(in_temp(target_basename + '.bc'), link_opts) - if DEBUG: save_intermediate('linktime', 'bc') + if not save_bc: + # let llvm opt directly emit ll, to skip writing and reading all the bitcode + link_opts += ['-S'] + shared.Building.llvm_opt(final, link_opts, final + '.link.ll') + final = final + '.link.ll' + if DEBUG: save_intermediate('linktime', 'll') + else: + shared.Building.llvm_opt(final, link_opts) + if DEBUG: save_intermediate('linktime', 'bc') if save_bc: shutil.copyfile(final, save_bc) # Prepare .ll for Emscripten if not LEAVE_INPUTS_RAW: - final = shared.Building.llvm_dis(final, final + '.ll') + if save_bc: + final = shared.Building.llvm_dis(final, final + '.ll') else: assert len(input_files) == 1 - if DEBUG: save_intermediate('ll', 'll') + if DEBUG and save_bc: save_intermediate('ll', 'll') if AUTODEBUG: logging.debug('autodebug') @@ -1665,6 +1704,8 @@ try: file_args += ['--compress', Compression.encoder, Compression.decoder, Compression.js_name] if use_preload_cache: file_args.append('--use-preload-cache') + if no_heap_copy: + file_args.append('--no-heap-copy') file_code = execute([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0] pre_js = file_code + pre_js @@ -1818,22 +1859,21 @@ try: if final_suffix == 'html': logging.debug('generating HTML') shell = open(shell_path).read() + assert '{{{ SCRIPT }}}' in shell, 'HTML shell must contain {{{ SCRIPT }}} , see src/shell.html for an example' html = open(target, 'w') + js_target = unsuffixed(target) + '.js' + base_js_target = os.path.basename(js_target) if proxy_to_worker: - html.write(shell.replace('{{{ SCRIPT_CODE }}}', open(shared.path_from_root('src', 'proxyClient.js')).read().replace('{{{ filename }}}', target_basename))) - js_target = unsuffixed(target) + '.js' - shutil.copyfile(final, js_target) + html.write(shell.replace('{{{ SCRIPT }}}', '<script>' + open(shared.path_from_root('src', 'proxyClient.js')).read().replace('{{{ filename }}}', target_basename) + '</script>')) + shutil.move(final, js_target) elif not Compression.on: if debug_level >= 4: - match = re.match('.*?<script[^>]*>{{{ SCRIPT_CODE }}}</script>', shell, - re.DOTALL) - if match is None: - raise RuntimeError('''Could not find script insertion point - make sure you have <script type='text/javascript'>{{{ SCRIPT_CODE }}}</script> in your HTML file (with no newlines)''') - generate_source_map(target, match.group().count('\n')) - html.write(shell.replace('{{{ SCRIPT_CODE }}}', open(final).read())) + generate_source_map(target) + shutil.move(final, js_target) + script_tag = '''<script async type="text/javascript" src="%s"></script>''' % base_js_target + html.write(shell.replace('{{{ SCRIPT }}}', script_tag)) else: # Compress the main code - js_target = unsuffixed(target) + '.js' shutil.move(final, js_target) Compression.compress(js_target) @@ -1881,8 +1921,8 @@ try: }); }; compiledCodeXHR.send(null); -''' % Compression.compressed_name(js_target) - html.write(shell.replace('{{{ SCRIPT_CODE }}}', decoding)) +''' % Compression.compressed_name(base_js_target) + html.write(shell.replace('{{{ SCRIPT }}}', '<script>' + decoding + '</script>')) # Add decompressor with web worker glue code decompressor = open('decompress.js', 'w') |