aboutsummaryrefslogtreecommitdiff
path: root/emcc
diff options
context:
space:
mode:
Diffstat (limited to 'emcc')
-rwxr-xr-xemcc94
1 files changed, 67 insertions, 27 deletions
diff --git a/emcc b/emcc
index 4222caa3..6a483a39 100755
--- a/emcc
+++ b/emcc
@@ -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')