aboutsummaryrefslogtreecommitdiff
path: root/tools/shared.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/shared.py')
-rw-r--r--tools/shared.py76
1 files changed, 63 insertions, 13 deletions
diff --git a/tools/shared.py b/tools/shared.py
index bdfec8ed..44fc428a 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -33,7 +33,8 @@ else:
config_file = config_file.replace('{{{ LLVM_ROOT }}}', llvm_root)
node = 'node'
try:
- node = Popen(['which', 'node'], stdout=PIPE).communicate()[0].replace('\n', '')
+ node = Popen(['which', 'node'], stdout=PIPE).communicate()[0].replace('\n', '') or \
+ Popen(['which', 'nodejs'], stdout=PIPE).communicate()[0].replace('\n', '')
except:
pass
config_file = config_file.replace('{{{ NODE }}}', node)
@@ -533,6 +534,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
@staticmethod
def configure(args, stdout=None, stderr=None, env=None):
+ if not args:
+ return
if env is None:
env = Building.get_building_env()
env['EMMAKEN_JUST_CONFIGURE'] = '1'
@@ -617,7 +620,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
actual_files = []
unresolved_symbols = set(['main']) # tracking unresolveds is necessary for .a linking, see below. (and main is always a necessary symbol)
resolved_symbols = set()
- temp_dir = None
+ temp_dirs = []
files = map(os.path.abspath, files)
for f in files:
if not Building.is_ar(f):
@@ -631,7 +634,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# (link in an entire .o from the archive if it supplies symbols still unresolved)
cwd = os.getcwd()
try:
- temp_dir = os.path.join(EMSCRIPTEN_TEMP_DIR, 'ar_output_' + str(os.getpid()))
+ temp_dir = os.path.join(EMSCRIPTEN_TEMP_DIR, 'ar_output_' + str(os.getpid()) + '_' + str(len(temp_dirs)))
+ temp_dirs.append(temp_dir)
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
os.chdir(temp_dir)
@@ -684,7 +688,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Finish link
output = Popen([LLVM_LINK] + actual_files + ['-o', target], stdout=PIPE).communicate()[0]
assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output + '\nemcc: If you get duplicate symbol errors, try --remove-duplicates'
- if temp_dir:
+ for temp_dir in temp_dirs:
try_delete(temp_dir)
# Emscripten optimizations that we run on the .ll file
@@ -908,15 +912,60 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
Building.LLVM_OPT_OPTS = opts
return opts
+ MAX_JS_PROCESS_SIZE = 12*1024*1024
+ BEST_JS_PROCESS_SIZE = 8*1024*1024
+
+ @staticmethod
+ def splitter(filename, addendum, func, args=[]):
+ # Split up huge files into pieces small enough for node/uglify/etc. to handle
+ js = open(filename).read()
+ if len(js) > Building.MAX_JS_PROCESS_SIZE:
+ if os.environ.get('EMCC_DEBUG'): print >> sys.stderr, 'splitting up js file'
+
+ suffix_marker = '// EMSCRIPTEN_GENERATED_FUNCTIONS'
+ suffix_start = js.find(suffix_marker)
+ suffix = ''
+ if suffix_start >= 0:
+ suffix = js[suffix_start:js.find('\n', suffix_start)] + '\n'
+
+ filename += addendum
+ f = open(filename, 'w')
+
+ i = 0
+ f_start = 0
+ while True:
+ f_end = f_start
+ while f_end-f_start < Building.BEST_JS_PROCESS_SIZE and f_end != -1:
+ f_end = js.find('\n}\n', f_end+1)
+ chunk = js[f_start:(-1 if f_end == -1 else f_end+3)] + suffix
+ temp_in_file = filename + '.p%d.js' % i
+ if os.environ.get('EMCC_DEBUG'): print >> sys.stderr, ' split %d, size %d' % (i, len(chunk))
+ i += 1
+ open(temp_in_file, 'w').write(chunk)
+ temp_out_file = func(*([temp_in_file] + args + [False])) # maybe_big is now false
+ f.write(
+ ''.join(filter(lambda line: not line.startswith(suffix_marker), open(temp_out_file).readlines()))
+ )
+ if f_end == -1: break
+ f_start = f_end+3
+ if f_start >= len(js): break
+
+ f.write(suffix)
+ f.close()
+ return filename
+
@staticmethod
- def js_optimizer(filename, passes):
- if not check_engine(NODE_JS):
- raise Exception('Node.js appears to be missing or broken, looked at: ' + str(NODE_JS))
+ def js_optimizer(filename, passes, maybe_big=True):
+ if maybe_big:
+ # When we split up, we cannot do unGlobalize, the only pass which is *not* function-local
+ args = [filter(lambda p: p != 'unGlobalize', passes)]
+ ret = Building.splitter(filename, addendum='.jo.js', func=Building.js_optimizer, args=args)
+ if ret: return ret
if type(passes) == str:
passes = [passes]
- # XXX Disable crankshaft to work around v8 bug 1895
- output = Popen([NODE_JS, '--nocrankshaft', JS_OPTIMIZER, filename] + passes, stdout=PIPE).communicate()[0]
+ # XXX Might need to disable crankshaft to work around v8 bug 1895 , '--nocrankshaft'
+ output = Popen([NODE_JS, JS_OPTIMIZER, filename] + passes, stdout=PIPE).communicate()[0]
assert len(output) > 0 and not output.startswith('Assertion failed'), 'Error in js optimizer: ' + output
filename += '.jo.js'
f = open(filename, 'w')
@@ -925,9 +974,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
return filename
@staticmethod
- def eliminator(filename):
- if not check_engine(NODE_JS):
- raise Exception('Node.js appears to be missing or broken, looked at: ' + str(NODE_JS))
+ def eliminator(filename, maybe_big=True):
+ if maybe_big:
+ ret = Building.splitter(filename, addendum='.el.js', func=Building.eliminator)
+ if ret: return ret
coffee = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee')
eliminator = path_from_root('tools', 'eliminator', 'eliminator.coffee')
@@ -948,7 +998,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Something like this (adjust memory as needed):
# java -Xmx1024m -jar CLOSURE_COMPILER --compilation_level ADVANCED_OPTIMIZATIONS --variable_map_output_file src.cpp.o.js.vars --js src.cpp.o.js --js_output_file src.cpp.o.cc.js
args = [JAVA,
- '-Xmx1024m',
+ '-Xmx' + (os.environ.get('JAVA_HEAP_SIZE') or '1024m'), # if you need a larger Java heap, use this environment variable
'-jar', CLOSURE_COMPILER,
'--compilation_level', 'ADVANCED_OPTIMIZATIONS',
'--formatting', 'PRETTY_PRINT',