diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/js_optimizer.py | 13 | ||||
-rw-r--r-- | tools/jsrun.py | 18 | ||||
-rw-r--r-- | tools/shared.py | 25 | ||||
-rw-r--r-- | tools/tempfiles.py | 1 |
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: |