Skip to content

Commit

Permalink
Work around Closure compiler issue google/closure-compiler#3784 that …
Browse files Browse the repository at this point in the history
…prevents calling Closure compiler with a cmdline that contains unicode characters.
  • Loading branch information
juj committed Mar 16, 2021
1 parent 229e9ea commit 3400528
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
8 changes: 8 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -7468,6 +7468,14 @@ def test_closure_full_js_library(self):
def test_closure_externs(self):
self.run_process([EMCC, test_file('hello_world.c'), '--closure=1', '--pre-js', test_file('test_closure_externs_pre_js.js'), '--closure-args', '--externs "' + test_file('test_closure_externs.js') + '"'])

# Tests that it is possible to enable the Closure compiler via --closure=1 even if any of the input files reside in a path with unicode characters.
def test_closure_cmdline_utf8_chars(self):
test = "☃ äö Ć € ' 🦠.c"
shutil.copyfile(test_file('hello_world.c'), test)
externs = '💩' + test
open(externs, 'w').write('')
self.run_process([EMCC, test, '--closure=1', '--closure-args', '--externs "' + externs + '"'])

def test_toolchain_profiler(self):
environ = os.environ.copy()
environ['EM_PROFILE_TOOLCHAIN'] = '1'
Expand Down
34 changes: 28 additions & 6 deletions tools/building.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,8 +993,6 @@ def add_to_path(dirname):

if Settings.MINIMAL_RUNTIME and Settings.USE_PTHREADS and not Settings.MODULARIZE:
CLOSURE_EXTERNS += [path_from_root('src', 'minimal_runtime_worker_externs.js')]
outfile = filename + '.cc.js'
configuration.get_temp_files().note(outfile)

args = ['--compilation_level', 'ADVANCED_OPTIMIZATIONS' if advanced else 'SIMPLE_OPTIMIZATIONS']
# Keep in sync with ecmaVersion in tools/acorn-optimizer.js
Expand All @@ -1006,19 +1004,43 @@ def add_to_path(dirname):
# Tell closure never to inject the 'use strict' directive.
args += ['--emit_use_strict=false']

# Closure compiler is unable to deal with path names that are not 7-bit ASCII:
# https://github.com/google/closure-compiler/issues/3784
outfile = configuration.get_temp_files().get('.cc.js').name # Safe 7-bit filename
def move_to_safe_7bit_ascii_filename(filename):
safe_filename = configuration.get_temp_files().get('.js').name # Safe 7-bit filename
shutil.copyfile(filename, safe_filename)
return os.path.relpath(safe_filename, configuration.get_temp_files_directory())

for e in CLOSURE_EXTERNS:
args += ['--externs', e]
args += ['--js_output_file', outfile]
args += ['--externs', move_to_safe_7bit_ascii_filename(e)]

for i in range(len(user_args)):
if user_args[i] == '--externs':
user_args[i+1] = move_to_safe_7bit_ascii_filename(user_args[i+1])

# Specify output file relative to the temp directory to avoid specifying non-7-bit-ASCII path names.
args += ['--js_output_file', os.path.relpath(outfile, configuration.get_temp_files_directory())]

if Settings.IGNORE_CLOSURE_COMPILER_ERRORS:
args.append('--jscomp_off=*')
if pretty:
args += ['--formatting', 'PRETTY_PRINT']
args += ['--js', filename]
# Specify input file relative to the temp directory to avoid specifying non-7-bit-ASCII path names.
args += ['--js', move_to_safe_7bit_ascii_filename(filename)]
cmd = closure_cmd + args + user_args
logger.debug('closure compiler: ' + ' '.join(cmd))

proc = run_process(cmd, stderr=PIPE, check=False, env=env)
# Closure compiler does not work if any of the input files contain characters outside the
# 7-bit ASCII range. Therefore make sure the command line we pass does not contain any such
# input files by passing all input filenames relative to the cwd. (user temp directory might
# be in user's home directory, and user's profile name might contain unicode characters)
cwd = os.getcwd()
try:
os.chdir(configuration.get_temp_files_directory())
proc = run_process(cmd, stderr=PIPE, check=False, env=env)
finally:
os.chdir(cwd)

# XXX Closure bug: if Closure is invoked with --create_source_map, Closure should create a
# outfile.map source map file (https://github.com/google/closure-compiler/wiki/Source-Maps)
Expand Down
9 changes: 6 additions & 3 deletions tools/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,14 +421,17 @@ def __init__(self):
lock.acquire()
atexit.register(lock.release)

def get_temp_files(self):
def get_temp_files_directory(self):
if DEBUG_SAVE:
# In debug mode store all temp files in the emscripten-specific temp dir
# and don't worry about cleaning them up.
return tempfiles.TempFiles(get_emscripten_temp_dir(), save_debug_files=True)
return get_emscripten_temp_dir()
else:
# Otherwise use the system tempdir and try to clean up after ourselves.
return tempfiles.TempFiles(self.TEMP_DIR, save_debug_files=False)
return self.TEMP_DIR

def get_temp_files(self):
return tempfiles.TempFiles(self.get_temp_files_directory(), save_debug_files=DEBUG_SAVE)


def apply_configuration():
Expand Down

0 comments on commit 3400528

Please sign in to comment.