aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/js_optimizer.py13
-rw-r--r--tools/jsrun.py18
-rw-r--r--tools/shared.py25
-rw-r--r--tools/tempfiles.py1
4 files changed, 46 insertions, 11 deletions
diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py
index a11da7f0..d6f8921c 100644
--- a/tools/js_optimizer.py
+++ b/tools/js_optimizer.py
@@ -367,6 +367,17 @@ EMSCRIPTEN_FUNCS();
return filename
-def run(filename, passes, js_engine, jcache, source_map=False, extra_info=None):
+def run(filename, passes, js_engine=shared.NODE_JS, jcache=False, source_map=False, extra_info=None):
return temp_files.run_and_clean(lambda: run_on_js(filename, passes, js_engine, jcache, source_map, extra_info))
+if __name__ == '__main__':
+ last = sys.argv[-1]
+ if '{' in last:
+ extra_info = json.loads(last)
+ sys.argv = sys.argv[:-1]
+ else:
+ extra_info = None
+ out = run(sys.argv[1], sys.argv[2:], extra_info=extra_info)
+ import shutil
+ shutil.copyfile(out, sys.argv[1] + '.jsopt.js')
+
diff --git a/tools/jsrun.py b/tools/jsrun.py
index 6f77ce51..7acfc978 100644
--- a/tools/jsrun.py
+++ b/tools/jsrun.py
@@ -1,6 +1,8 @@
-import time
+import time, os, sys, logging
from subprocess import Popen, PIPE, STDOUT
+TRACK_PROCESS_SPAWNS = True if (os.getenv('EM_BUILD_VERBOSE') and int(os.getenv('EM_BUILD_VERBOSE')) >= 3) else False
+
def timeout_run(proc, timeout, note='unnamed process', full_output=False):
start = time.time()
if timeout is not None:
@@ -11,19 +13,25 @@ def timeout_run(proc, timeout, note='unnamed process', full_output=False):
raise Exception("Timed out: " + note)
out = proc.communicate()
out = map(lambda o: '' if o is None else o, out)
+ if TRACK_PROCESS_SPAWNS:
+ logging.info('Process ' + str(proc.pid) + ' finished after ' + str(time.time() - start) + ' seconds.')
return '\n'.join(out) if full_output else out[0]
def run_js(filename, engine=None, args=[], check_timeout=False, stdin=None, stdout=PIPE, stderr=None, cwd=None, full_output=False):
if type(engine) is not list:
engine = [engine]
command = engine + [filename] + (['--'] if 'd8' in engine[0] or 'jsc' in engine[0] else []) + args
- return timeout_run(
- Popen(
+ proc = Popen(
command,
stdin=stdin,
stdout=stdout,
stderr=stderr,
- cwd=cwd),
- 15*60 if check_timeout else None,
+ cwd=cwd)
+ timeout = 15*60 if check_timeout else None
+ if TRACK_PROCESS_SPAWNS:
+ logging.info('Blocking on process ' + str(proc.pid) + ': ' + str(command) + (' for ' + str(timeout) + ' seconds' if timeout else ' until it finishes.'))
+ return timeout_run(
+ proc,
+ timeout,
'Execution',
full_output=full_output)
diff --git a/tools/shared.py b/tools/shared.py
index 53f83185..c5df34f1 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -47,6 +47,7 @@ class WindowsPopen:
try:
# Call the process with fixed streams.
self.process = subprocess.Popen(args, bufsize, executable, self.stdin_, self.stdout_, self.stderr_, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags)
+ self.pid = self.process.pid
except Exception, e:
logging.error('\nsubprocess.Popen(args=%s) failed! Exception %s\n' % (' '.join(args), str(e)))
raise e
@@ -84,10 +85,6 @@ class WindowsPopen:
except:
pass # Mute all exceptions in dtor, particularly if we didn't use a response file, self.response_filename doesn't exist.
-# Install our replacement Popen handler if we are running on Windows to avoid python spawn process function.
-if os.name == 'nt':
- Popen = WindowsPopen
-
__rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
def path_from_root(*pathelems):
return os.path.join(__rootpath__, *pathelems)
@@ -250,6 +247,19 @@ except Exception, e:
logging.error('Error in evaluating %s (at %s): %s, text: %s' % (EM_CONFIG, CONFIG_FILE, str(e), config_text))
sys.exit(1)
+try:
+ EM_POPEN_WORKAROUND
+except:
+ EM_POPEN_WORKAROUND = os.environ.get('EM_POPEN_WORKAROUND')
+
+# Install our replacement Popen handler if we are running on Windows to avoid python spawn process function.
+# nb. This is by default disabled since it has the adverse effect of buffering up all logging messages, which makes
+# builds look unresponsive (messages are printed only after the whole build finishes). Whether this workaround is needed
+# seems to depend on how the host application that invokes emcc has set up its stdout and stderr.
+if EM_POPEN_WORKAROUND and os.name == 'nt':
+ logging.debug('Installing Popen workaround handler to avoid bug http://bugs.python.org/issue3905')
+ Popen = WindowsPopen
+
# Expectations
EXPECTED_LLVM_VERSION = (3,2)
@@ -304,7 +314,7 @@ def find_temp_directory():
# we re-check sanity when the settings are changed)
# We also re-check sanity and clear the cache when the version changes
-EMSCRIPTEN_VERSION = '1.5.10'
+EMSCRIPTEN_VERSION = '1.6.4'
def generate_sanity():
return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT
@@ -1413,6 +1423,9 @@ class Building:
emcc_debug = os.environ.get('EMCC_DEBUG')
if emcc_debug: del os.environ['EMCC_DEBUG']
+ emcc_leave_inputs_raw = os.environ.get('EMCC_LEAVE_INPUTS_RAW')
+ if emcc_leave_inputs_raw: del os.environ['EMCC_LEAVE_INPUTS_RAW']
+
def make(opt_level):
raw = relooper + '.raw.js'
Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js',
@@ -1442,8 +1455,10 @@ class Building:
finally:
os.chdir(curr)
if emcc_debug: os.environ['EMCC_DEBUG'] = emcc_debug
+ if emcc_leave_inputs_raw: os.environ['EMCC_LEAVE_INPUTS_RAW'] = emcc_leave_inputs_raw
if not ok:
logging.error('bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten')
+ try_delete(relooper) # do not leave a phase-1 version if phase 2 broke
1/0
@staticmethod
diff --git a/tools/tempfiles.py b/tools/tempfiles.py
index 1721b2bb..27da1082 100644
--- a/tools/tempfiles.py
+++ b/tools/tempfiles.py
@@ -27,6 +27,7 @@ class TempFiles:
def clean(self):
if self.save_debug_files:
+ import sys
print >> sys.stderr, 'not cleaning up temp files since in debug-save mode, see them in %s' % (self.tmp,)
return
for filename in self.to_clean: