#!/usr/bin/env python2
# -*- Mode: python -*-
"""emcc - compiler helper script
=============================

emcc is a drop-in replacement for a compiler like gcc or clang.

See  emcc --help  for details.

emcc can be influenced by a few environment variables:

  EMCC_DEBUG - "1" will log out useful information during compilation, as well as
               save each compiler step as an emcc-* file in the temp dir
               (by default /tmp/emscripten_temp). "2" will save additional emcc-*
               steps, that would normally not be separately produced (so this
               slows down compilation).

  EMMAKEN_NO_SDK - Will tell emcc *not* to use the emscripten headers. Instead
                   your system headers will be used.

  EMMAKEN_COMPILER - The compiler to be used, if you don't want the default clang.
"""

from __future__ import print_function

import stat
import os
import sys
import shutil
import tempfile
import shlex
import time
import re
import logging
from subprocess import PIPE

from tools import shared, jsrun, system_libs, client_mods, js_optimizer
from tools.shared import suffix, unsuffixed, unsuffixed_basename, WINDOWS, safe_copy, safe_move, run_process, asbytes, read_and_preprocess, exit_with_error
from tools.response_file import substitute_response_files
import tools.line_endings
from tools.toolchain_profiler import ToolchainProfiler
if __name__ == '__main__':
  ToolchainProfiler.record_process_start()

try:
  from urllib.parse import quote
except ImportError:
  # Python 2 compatibility
  from urllib import quote

# endings = dot + a suffix, safe to test by  filename.endswith(endings)
C_ENDINGS = ('.c', '.C', '.i')
CXX_ENDINGS = ('.cpp', '.cxx', '.cc', '.c++', '.CPP', '.CXX', '.CC', '.C++', '.ii')
OBJC_ENDINGS = ('.m', '.mi')
OBJCXX_ENDINGS = ('.mm', '.mii')
SPECIAL_ENDINGLESS_FILENAMES = ('/dev/null',)

SOURCE_ENDINGS = C_ENDINGS + CXX_ENDINGS + OBJC_ENDINGS + OBJCXX_ENDINGS + SPECIAL_ENDINGLESS_FILENAMES
C_ENDINGS = C_ENDINGS + SPECIAL_ENDINGLESS_FILENAMES # consider the special endingless filenames like /dev/null to be C

BITCODE_ENDINGS = ('.bc', '.o', '.obj', '.lo')
DYNAMICLIB_ENDINGS = ('.dylib', '.so') # Windows .dll suffix is not included in this list, since those are never linked to directly on the command line.
STATICLIB_ENDINGS = ('.a',)
ASSEMBLY_ENDINGS = ('.ll',)
HEADER_ENDINGS = ('.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH')
WASM_ENDINGS = ('.wasm', '.wast')

SUPPORTED_LINKER_FLAGS = ('--start-group', '-(', '--end-group', '-)')

LIB_PREFIXES = ('', 'lib')

JS_CONTAINING_SUFFIXES = ('js', 'html')
EXECUTABLE_SUFFIXES = JS_CONTAINING_SUFFIXES + ('wasm',)

DEFERRED_REPONSE_FILES = ('EMTERPRETIFY_BLACKLIST', 'EMTERPRETIFY_WHITELIST', 'EMTERPRETIFY_SYNCLIST')

# Mapping of emcc opt levels to llvm opt levels. We use llvm opt level 3 in emcc opt
# levels 2 and 3 (emcc 3 is unsafe opts, so unsuitable for the only level to get
# llvm opt level 3, and speed-wise emcc level 2 is already the slowest/most optimizing
# level)
LLVM_OPT_LEVEL = {
  0: ['-O0'],
  1: ['-O1'],
  2: ['-O3'],
  3: ['-O3'],
}

DEBUG = os.environ.get('EMCC_DEBUG')
if DEBUG == "0":
  DEBUG = None

# Do not compile .ll files into .bc, just compile them with emscripten directly
# Not recommended, this is mainly for the test runner, or if you have some other
# specific need.
# One major limitation with this mode is that libc and libc++ cannot be
# added in. Also, LLVM optimizations will not be done, nor dead code elimination
LEAVE_INPUTS_RAW = os.environ.get('EMCC_LEAVE_INPUTS_RAW')

# If emcc is running with LEAVE_INPUTS_RAW and then launches an emcc to build something like the struct info, then we don't want
# LEAVE_INPUTS_RAW to be active in that emcc subprocess.
if LEAVE_INPUTS_RAW:
  del os.environ['EMCC_LEAVE_INPUTS_RAW']

# If set to 1, we will run the autodebugger (the automatic debugging tool, see tools/autodebugger).
# Note that this will disable inclusion of libraries. This is useful because including
# dlmalloc makes it hard to compare native and js builds
AUTODEBUG = os.environ.get('EMCC_AUTODEBUG')

EMCC_CFLAGS = os.environ.get('EMCC_CFLAGS') # Additional compiler flags that we treat as if they were passed to us on the commandline

# Target options
final = None


class Intermediate(object):
  counter = 0


# this function uses the global 'final' variable, which contains the current
# final output file. if a method alters final, and calls this method, then it
# must modify final globally (i.e. it can't receive final as a param and
# return it)
# TODO: refactor all this, a singleton that abstracts over the final output
#       and saving of intermediates
def save_intermediate(name=None, suffix='js'):
  if not DEBUG:
    return
  name = os.path.join(shared.get_emscripten_temp_dir(), 'emcc-%d%s.%s' % (Intermediate.counter, '' if name is None else '-' + name, suffix))
  if isinstance(final, list):
    logging.debug('(not saving intermediate %s because deferring linking)' % name)
    return
  shutil.copyfile(final, name)
  Intermediate.counter += 1


def save_intermediate_with_wasm(name, wasm_binary):
  if not DEBUG:
    return
  save_intermediate(name) # save the js
  name = os.path.join(shared.get_emscripten_temp_dir(), 'emcc-%d-%s.wasm' % (Intermediate.counter - 1, name))
  shutil.copyfile(wasm_binary, name)


class TimeLogger(object):
  last = time.time()

  @staticmethod
  def update():
    TimeLogger.last = time.time()


def log_time(name):
  """Log out times for emcc stages"""
  if DEBUG:
    now = time.time()
    logging.debug('emcc step "%s" took %.2f seconds', name, now - TimeLogger.last)
    TimeLogger.update()


class EmccOptions(object):
  def __init__(self):
    self.opt_level = 0
    self.debug_level = 0
    self.shrink_level = 0
    self.requested_debug = ''
    self.profiling = False
    self.profiling_funcs = False
    self.tracing = False
    self.emit_symbol_map = False
    self.js_opts = None
    self.force_js_opts = False
    self.llvm_opts = None
    self.llvm_lto = None
    self.default_cxx_std = '-std=c++03' # Enforce a consistent C++ standard when compiling .cpp files, if user does not specify one on the cmdline.
    self.use_closure_compiler = None
    self.js_transform = None
    self.pre_js = '' # before all js
    self.post_js = '' # after all js
    self.preload_files = []
    self.embed_files = []
    self.exclude_files = []
    self.ignore_dynamic_linking = False
    self.shell_path = shared.path_from_root('src', 'shell.html')
    self.source_map_base = None
    self.js_libraries = []
    self.bind = False
    self.emrun = False
    self.cpu_profiler = False
    self.thread_profiler = False
    self.memory_profiler = False
    self.save_bc = False
    self.memory_init_file = None
    self.use_preload_cache = False
    self.no_heap_copy = False
    self.use_preload_plugins = False
    self.proxy_to_worker = False
    self.default_object_extension = '.o'
    self.valid_abspaths = []
    self.separate_asm = False
    self.cfi = False
    # Specifies the line ending format to use for all generated text files.
    # Defaults to using the native EOL on each platform (\r\n on Windows, \n on
    # Linux & MacOS)
    self.output_eol = os.linesep


def use_source_map(options):
  return options.debug_level >= 4


class JSOptimizer(object):
  def __init__(self, target, options, js_transform_tempfiles, in_temp):
    self.queue = []
    self.extra_info = {}
    self.queue_history = []
    self.blacklist = (os.environ.get('EMCC_JSOPT_BLACKLIST') or '').split(',')
    self.minify_whitespace = False
    self.cleanup_shell = False

    self.target = target
    self.opt_level = options.opt_level
    self.debug_level = options.debug_level
    self.emit_symbol_map = options.emit_symbol_map
    self.profiling_funcs = options.profiling_funcs
    self.use_closure_compiler = options.use_closure_compiler

    self.js_transform_tempfiles = js_transform_tempfiles
    self.in_temp = in_temp

  def flush(self, title='js_opts'):
    self.queue = [p for p in self.queue if p not in self.blacklist]

    assert not shared.Settings.WASM_BACKEND, 'JSOptimizer should not run with pure wasm output'

    if self.extra_info is not None and len(self.extra_info) == 0:
      self.extra_info = None

    if len(self.queue) and not(not shared.Settings.ASM_JS and len(self.queue) == 1 and self.queue[0] == 'last'):
      passes = self.queue[:]

      if DEBUG != '2' or len(passes) < 2:
        # by assumption, our input is JS, and our output is JS. If a pass is going to run in the native optimizer in C++, then we
        # must give it JSON and receive from it JSON
        chunks = []
        curr = []
        for p in passes:
          if len(curr) == 0:
            curr.append(p)
          else:
            native = js_optimizer.use_native(p, source_map=use_source_map(self))
            last_native = js_optimizer.use_native(curr[-1], source_map=use_source_map(self))
            if native == last_native:
              curr.append(p)
            else:
              curr.append('emitJSON')
              chunks.append(curr)
              curr = ['receiveJSON', p]
        if len(curr):
          chunks.append(curr)
        if len(chunks) == 1:
          self.run_passes(chunks[0], title, just_split=False, just_concat=False)
        else:
          for i, chunk in enumerate(chunks):
            self.run_passes(chunk, 'js_opts_' + str(i),
                            just_split='receiveJSON' in chunk,
                            just_concat='emitJSON' in chunk)
      else:
        # DEBUG 2, run each pass separately
        extra_info = self.extra_info
        for p in passes:
          self.queue = [p]
          self.flush(p)
          self.extra_info = extra_info # flush wipes it
          log_time('part of js opts')
      self.queue_history += self.queue
      self.queue = []
    self.extra_info = {}

  def run_passes(self, passes, title, just_split, just_concat):
    global final
    passes = ['asm'] + passes
    if shared.Settings.PRECISE_F32:
      passes = ['asmPreciseF32'] + passes
    if (self.emit_symbol_map or shared.Settings.CYBERDWARF) and 'minifyNames' in passes:
      passes += ['symbolMap=' + self.target + '.symbols']
    if self.profiling_funcs and 'minifyNames' in passes:
      passes += ['profilingFuncs']
    if self.minify_whitespace and 'last' in passes:
      passes += ['minifyWhitespace']
    if self.cleanup_shell and 'last' in passes:
      passes += ['cleanup']
    logging.debug('applying js optimization passes: %s', ' '.join(passes))
    final = shared.Building.js_optimizer(final, passes, use_source_map(self),
                                         self.extra_info, just_split=just_split,
                                         just_concat=just_concat,
                                         output_filename=self.in_temp(os.path.basename(final) + '.jsopted.js'))
    self.js_transform_tempfiles.append(final)
    save_intermediate(title, suffix='js' if 'emitJSON' not in passes else 'json')

  def do_minify(self):
    """minifies the code.

    this is also when we do certain optimizations that must be done right before or after minification
    """
    if shared.Settings.SPLIT_MEMORY:
      # must be done before minification
      self.queue += ['splitMemory', 'simplifyExpressions']

    if self.opt_level >= 2:
      if self.debug_level < 2 and not self.use_closure_compiler == 2:
        self.queue += ['minifyNames']
      if self.debug_level == 0:
        self.minify_whitespace = True

    if self.use_closure_compiler == 1:
      self.queue += ['closure']
    elif self.debug_level <= 2 and shared.Settings.FINALIZE_ASM_JS and not self.use_closure_compiler:
      self.cleanup_shell = True


def embed_memfile(options):
  return shared.Settings.SINGLE_FILE or (shared.Settings.MEM_INIT_METHOD == 0 and (not shared.Settings.MAIN_MODULE and not shared.Settings.SIDE_MODULE and not use_source_map(options)))


#
# Main run() function
#
def run():
  global final
  target = None

  if DEBUG:
    logging.warning('invocation: ' + ' '.join(sys.argv) + (' + ' + EMCC_CFLAGS if EMCC_CFLAGS else '') + '  (in ' + os.getcwd() + ')')
  if EMCC_CFLAGS:
    sys.argv.extend(shlex.split(EMCC_CFLAGS))

  if DEBUG and LEAVE_INPUTS_RAW:
    logging.warning('leaving inputs raw')

  EMCC_CXX = '--emscripten-cxx' in sys.argv
  sys.argv = [x for x in sys.argv if x != '--emscripten-cxx']

  if len(sys.argv) <= 1 or ('--help' not in sys.argv and len(sys.argv) >= 2 and sys.argv[1] != '--version'):
    shared.check_sanity(force=DEBUG)

  misc_temp_files = shared.configuration.get_temp_files()

  # Handle some global flags

  if len(sys.argv) == 1:
    logging.warning('no input files')
    return 1

  # read response files very early on
  sys.argv = substitute_response_files(sys.argv)

  if len(sys.argv) == 1 or '--help' in sys.argv:
    # Documentation for emcc and its options must be updated in:
    #    site/source/docs/tools_reference/emcc.rst
    # A prebuilt local version of the documentation is available at:
    #    site/build/text/docs/tools_reference/emcc.txt
    #    (it is read from there and printed out when --help is invoked)
    # You can also build docs locally as HTML or other formats in site/
    # An online HTML version (which may be of a different version of Emscripten)
    #    is up at http://kripken.github.io/emscripten-site/docs/tools_reference/emcc.html

    print('''%s

------------------------------------------------------------------

emcc: supported targets: llvm bitcode, javascript, NOT elf
(autoconf likes to see elf above to enable shared object support)
''' % (open(shared.path_from_root('site', 'build', 'text', 'docs', 'tools_reference', 'emcc.txt')).read()))
    return 0

  elif sys.argv[1] == '--version':
    revision = '(unknown revision)'
    here = os.getcwd()
    os.chdir(shared.path_from_root())
    try:
      revision = run_process(['git', 'show'], stdout=PIPE, stderr=PIPE).stdout.split('\n')[0]
    except:
      pass
    finally:
      os.chdir(here)
    print('''emcc (Emscripten gcc/clang-like replacement) %s (%s)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  ''' % (shared.EMSCRIPTEN_VERSION, revision))
    return 0

  elif len(sys.argv) == 2 and sys.argv[1] == '-v': # -v with no inputs
    # autoconf likes to see 'GNU' in the output to enable shared object support
    print('emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) %s' % shared.EMSCRIPTEN_VERSION)
    code = run_process([shared.CLANG, '-v'], check=False).returncode
    shared.check_sanity(force=True)
    return code

  elif '-dumpmachine' in sys.argv:
    print(shared.get_llvm_target())
    return 0

  elif '-dumpversion' in sys.argv: # gcc's doc states "Print the compiler version [...] and don't do anything else."
    print(shared.EMSCRIPTEN_VERSION)
    return 0

  elif '--cflags' in sys.argv:
    # fake running the command, to see the full args we pass to clang
    debug_env = os.environ.copy()
    debug_env['EMCC_DEBUG'] = '1'
    args = [x for x in sys.argv if x != '--cflags']
    with misc_temp_files.get_file(suffix='.o') as temp_target:
      input_file = 'hello_world.c'
      err = run_process([shared.PYTHON] + args + [shared.path_from_root('tests', input_file), '-c', '-o', temp_target], stderr=PIPE, env=debug_env).stderr
      lines = [x for x in err.split('\n') if shared.CLANG_CC in x and input_file in x]
      line = re.search('running: (.*)', lines[0]).group(1)
      parts = shlex.split(line.replace('\\', '\\\\'))
      parts = [x for x in parts if x != '-c' and x != '-o' and input_file not in x and temp_target not in x and '-emit-llvm' not in x]
      print(' '.join(shared.Building.doublequote_spaces(parts[1:])))
    return 0

  def is_minus_s_for_emcc(newargs, i):
    assert newargs[i] == '-s'
    if i + 1 < len(newargs) and '=' in newargs[i + 1] and not newargs[i + 1].startswith('-'): # -s OPT=VALUE is for us, -s by itself is a linker option
      return True
    else:
      logging.debug('treating -s as linker option and not as -s OPT=VALUE for js compilation')
      return False

  # If this is a configure-type thing, do not compile to JavaScript, instead use clang
  # to compile to a native binary (using our headers, so things make sense later)
  CONFIGURE_CONFIG = (os.environ.get('EMMAKEN_JUST_CONFIGURE') or 'conftest.c' in sys.argv) and not os.environ.get('EMMAKEN_JUST_CONFIGURE_RECURSE')
  CMAKE_CONFIG = 'CMakeFiles/cmTryCompileExec.dir' in ' '.join(sys.argv)# or 'CMakeCCompilerId' in ' '.join(sys.argv)
  if CONFIGURE_CONFIG or CMAKE_CONFIG:
    debug_configure = 0 # XXX use this to debug configure stuff. ./configure's generally hide our normal output including stderr so we write to a file

    # Whether we fake configure tests using clang - the local, native compiler - or not. if not we generate JS and use node with a shebang
    # Neither approach is perfect, you can try both, but may need to edit configure scripts in some cases
    # By default we configure in js, which can break on local filesystem access, etc., but is otherwise accurate so we
    # disable this if we think we have to. A value of '2' here will force JS checks in all cases. In summary:
    # 0 - use native compilation for configure checks
    # 1 - use js when we think it will work
    # 2 - always use js for configure checks
    use_js = int(os.environ.get('EMCONFIGURE_JS') or 2)

    if debug_configure:
      tempout = '/tmp/emscripten_temp/out'
      if not os.path.exists(tempout):
        open(tempout, 'w').write('//\n')

    src = None
    for arg in sys.argv:
      if arg.endswith(SOURCE_ENDINGS):
        try:
          src = open(arg).read()
          if debug_configure:
            open(tempout, 'a').write('============= ' + arg + '\n' + src + '\n=============\n\n')
        except:
          pass
      elif arg.endswith('.s'):
        if debug_configure:
          open(tempout, 'a').write('(compiling .s assembly, must use clang\n')
        if use_js == 1:
          use_js = 0
      elif arg == '-E' or arg == '-M' or arg == '-MM':
        if use_js == 1:
          use_js = 0

    if src:
      if 'fopen' in src and '"w"' in src:
        if use_js == 1:
          use_js = 0 # we cannot write to files from js!
        if debug_configure:
          open(tempout, 'a').write('Forcing clang since uses fopen to write\n')

    compiler = os.environ.get('CONFIGURE_CC') or (shared.CLANG if not use_js else shared.EMCC) # if CONFIGURE_CC is defined, use that. let's you use local gcc etc. if you need that
    if not ('CXXCompiler' in ' '.join(sys.argv) or EMCC_CXX):
      compiler = shared.to_cc(compiler)

    def filter_emscripten_options(argv):
      idx = 0
      skip_next = False
      for el in argv:
        if skip_next:
          skip_next = False
          idx += 1
          continue
        if not use_js and el == '-s' and is_minus_s_for_emcc(argv, idx): # skip -s X=Y if not using js for configure
          skip_next = True
        if not use_js and el == '--tracing':
          pass
        else:
          yield el
        idx += 1

    if compiler == shared.EMCC:
      compiler = [shared.PYTHON, shared.EMCC]
    else:
      compiler = [compiler]
    cmd = compiler + list(filter_emscripten_options(sys.argv[1:]))
    if not use_js:
      cmd += shared.EMSDK_OPTS + ['-D__EMSCRIPTEN__']
      # The preprocessor define EMSCRIPTEN is deprecated. Don't pass it to code in strict mode. Code should use the define __EMSCRIPTEN__ instead.
      if not shared.Settings.STRICT:
        cmd += ['-DEMSCRIPTEN']
    if use_js:
      cmd += ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=1'] # configure tests should fail when an undefined symbol exists
      cmd += ['-s', 'NO_EXIT_RUNTIME=0'] # configure tests want a more shell-like style, where we emit return codes on exit()
      cmd += ['-s', 'NODERAWFS=1'] # use node.js raw filesystem access, to behave just like a native executable
      # Disable wasm in configuration checks so that (1) we do not depend on wasm support just for configuration (perhaps the user does not intend
      # to build to wasm; using asm.js only depends on js which we need anyhow), and (2) we don't have issues with a separate .wasm file
      # on the side, async startup, etc..
      cmd += ['-s', 'WASM=0']

    logging.debug('just configuring: ' + ' '.join(cmd))
    if debug_configure:
      open(tempout, 'a').write('emcc, just configuring: ' + ' '.join(cmd) + '\n\n')

    if not use_js:
      return run_process(cmd, check=False).returncode
    else:
      only_object = '-c' in cmd
      for i in reversed(range(len(cmd) - 1)): # Last -o directive should take precedence, if multiple are specified
        if cmd[i] == '-o':
          if not only_object:
            cmd[i + 1] += '.js'
          target = cmd[i + 1]
          break
      if not target:
        target = 'a.out.js'
      os.environ['EMMAKEN_JUST_CONFIGURE_RECURSE'] = '1'
      ret = run_process(cmd, check=False).returncode
      os.environ['EMMAKEN_JUST_CONFIGURE_RECURSE'] = ''
      if not os.path.exists(target):
        # note that emcc -c will cause target to have the wrong value here;
        # but then, we don't care about bitcode outputs anyhow, below, so
        # skipping returning early is fine
        return ret
      if target.endswith('.js'):
        shutil.copyfile(target, unsuffixed(target))
        target = unsuffixed(target)
      if not target.endswith(BITCODE_ENDINGS):
        src = open(target).read()
        full_node = ' '.join(shared.NODE_JS)
        if os.path.sep not in full_node:
          full_node = '/usr/bin/' + full_node # TODO: use whereis etc. And how about non-*NIX?
        open(target, 'w').write('#!' + full_node + '\n' + src) # add shebang
        try:
          os.chmod(target, stat.S_IMODE(os.stat(target).st_mode) | stat.S_IXUSR) # make executable
        except:
          pass # can fail if e.g. writing the executable to /dev/null
      return ret

  if os.environ.get('EMMAKEN_COMPILER'):
    CXX = os.environ['EMMAKEN_COMPILER']
  else:
    CXX = shared.CLANG

  CC = shared.to_cc(CXX)

  # If we got here from a redirection through emmakenxx.py, then force a C++ compiler here
  if EMCC_CXX:
    CC = CXX

  CC_ADDITIONAL_ARGS = shared.COMPILER_OPTS

  EMMAKEN_CFLAGS = os.environ.get('EMMAKEN_CFLAGS')
  if EMMAKEN_CFLAGS:
    sys.argv += shlex.split(EMMAKEN_CFLAGS)

  # ---------------- Utilities ---------------

  seen_names = {}

  def uniquename(name):
    if name not in seen_names:
      seen_names[name] = str(len(seen_names))
    return unsuffixed(name) + '_' + seen_names[name] + (('.' + suffix(name)) if suffix(name) else '')

  # ---------------- End configs -------------

  if len(sys.argv) == 1 or sys.argv[1] in ['x', 't']:
    # noop ar
    logging.debug('just ar')
    return 0

  # Check if a target is specified
  target = None
  if any(arg.startswith('-o=') for arg in sys.argv):
    raise Exception('Invalid syntax: do not use -o=X, use -o X')

  for i in reversed(range(len(sys.argv) - 1)): # Last -o directive should take precedence, if multiple are specified
    if sys.argv[i] == '-o':
      target = sys.argv[i + 1]
      sys.argv = sys.argv[:i] + sys.argv[i + 2:]
      break

  specified_target = target
  target = specified_target if specified_target is not None else 'a.out.js' # specified_target is the user-specified one, target is what we will generate
  target_basename = unsuffixed_basename(target)

  if '.' in target:
    final_suffix = target.split('.')[-1]
  else:
    final_suffix = ''

  # Temporary file handling: we ensure that TEMP_DIR exists, which is the general
  # location for all temp files from us on this system. We then create a temp dir
  # under that, and store our main files there. As we process the main js file,
  # we update the variable `final`, giving it an extra suffix each time, and
  # relying on the entire dir going away for cleanup. For other miscellaneous
  # temporary files (like in the js optimizer) we need to note() them so they
  # get removed.

  temp_root = shared.TEMP_DIR
  if not os.path.exists(temp_root):
    try:
      os.makedirs(temp_root)
    except Exception as e:
      if os.path.exists(temp_root):
        pass # If running multiple emcc instances simultaneously, they may race to create the temp directory if it did not initially exist. In that case, we can proceed.
      else:
        raise

  temp_dir = tempfile.mkdtemp(dir=temp_root)

  def in_temp(name):
    return os.path.join(temp_dir, os.path.basename(name))

  # Parses the essential suffix of a filename, discarding Unix-style version numbers in the name. For example for 'libz.so.1.2.8' returns '.so'
  def filename_type_suffix(filename):
    for i in reversed(filename.split('.')[1:]):
      if not i.isdigit():
        return i
    return ''

  def filename_type_ending(filename):
    if filename in SPECIAL_ENDINGLESS_FILENAMES:
      return filename
    suffix = filename_type_suffix(filename)
    return '' if not suffix else ('.' + suffix)

  def optimizing(opts):
    return '-O0' not in opts

  use_cxx = True

  try:
    with ToolchainProfiler.profile_block('parse arguments and setup'):
      ## Parse args

      newargs = sys.argv[1:]

      # Scan and strip emscripten specific cmdline warning flags
      # This needs to run before other cmdline flags have been parsed, so that warnings are properly printed during arg parse
      newargs = shared.WarningManager.capture_warnings(newargs)

      for i in range(len(newargs)):
        if newargs[i] in ['-l', '-L', '-I']:
          # Scan for individual -l/-L/-I arguments and concatenate the next arg on if there is no suffix
          newargs[i] += newargs[i + 1]
          newargs[i + 1] = ''

      def detect_fixed_language_mode(args):
        check_next = False
        for item in args:
          if check_next:
            if item in ("c++", "c"):
              return True
            else:
              check_next = False
          if item.startswith("-x"):
            lmode = item[2:] if len(item) > 2 else None
            if lmode in ("c++", "c"):
              return True
            else:
              check_next = True
              continue
        return False

      has_fixed_language_mode = detect_fixed_language_mode(newargs)

      options, settings_changes, newargs = parse_args(newargs)

      for arg in newargs:
        if arg == '-xc':
          use_cxx = False
          break
        elif arg == '-xc++':
          use_cxx = True
          break
        elif not arg.startswith('-'):
          if arg.endswith(C_ENDINGS + OBJC_ENDINGS):
            use_cxx = False

      if not use_cxx:
        options.default_cxx_std = '' # Compiling C code with .c files, don't enforce a default C++ std.

      call = CXX if use_cxx else CC

      # If user did not specify a default -std for C++ code, specify the emscripten default.
      if options.default_cxx_std:
        newargs = newargs + [options.default_cxx_std]

      if options.emrun:
        options.pre_js += open(shared.path_from_root('src', 'emrun_prejs.js')).read() + '\n'
        options.post_js += open(shared.path_from_root('src', 'emrun_postjs.js')).read() + '\n'
        # emrun mode waits on program exit
        shared.Settings.NO_EXIT_RUNTIME = 0

      if options.cpu_profiler:
        options.post_js += open(shared.path_from_root('src', 'cpuprofiler.js')).read() + '\n'

      if options.memory_profiler:
        options.post_js += open(shared.path_from_root('src', 'memoryprofiler.js')).read() + '\n'

      if options.thread_profiler:
        options.post_js += open(shared.path_from_root('src', 'threadprofiler.js')).read() + '\n'

      if options.js_opts is None:
        options.js_opts = options.opt_level >= 2

      if options.llvm_opts is None:
        options.llvm_opts = LLVM_OPT_LEVEL[options.opt_level]
      elif type(options.llvm_opts) == int:
        options.llvm_opts = ['-O%d' % options.llvm_opts]

      if options.memory_init_file is None:
        options.memory_init_file = options.opt_level >= 2

      # TODO: support source maps with js_transform
      if options.js_transform and use_source_map(options):
        logging.warning('disabling source maps because a js transform is being done')
        options.debug_level = 3

      if DEBUG:
        start_time = time.time() # done after parsing arguments, which might affect debug state

      for i in range(len(newargs)):
        if newargs[i] == '-s':
          if is_minus_s_for_emcc(newargs, i):
            key = newargs[i + 1]
            settings_changes.append(key)
            newargs[i] = newargs[i + 1] = ''
            assert key != 'WASM_BACKEND', 'do not set -s WASM_BACKEND, instead set EMCC_WASM_BACKEND=1 in the environment'
      newargs = [arg for arg in newargs if arg is not '']

      # Handle aliases in settings flags. These are settings whose name
      # has changed.
      settings_aliases = {
          'BINARYEN': 'WASM',
          'BINARYEN_MEM_MAX': 'WASM_MEM_MAX',
          # TODO: change most (all?) other BINARYEN* names to WASM*
      }
      settings_key_changes = set()

      def setting_sub(s):
        key, rest = s.split('=', 1)
        settings_key_changes.add(key)
        return '='.join([settings_aliases.get(key, key), rest])

      settings_changes = list(map(setting_sub, settings_changes))

      # Find input files

      # These three arrays are used to store arguments of different types for
      # type-specific processing. In order to shuffle the arguments back together
      # after processing, all of these arrays hold tuples (original_index, value).
      # Note that the index part of the tuple can have a fractional part for input
      # arguments that expand into multiple processed arguments, as in -Wl,-f1,-f2.
      input_files = []
      libs = []
      link_flags = []

      # All of the above arg lists entries contain indexes into the full argument
      # list. In order to add extra implicit args (embind.cc, etc) below, we keep a
      # counter for the next index that should be used.
      next_arg_index = len(newargs)

      has_source_inputs = False
      has_header_inputs = False
      lib_dirs = [shared.path_from_root('system', 'local', 'lib'),
                  shared.path_from_root('system', 'lib')]
      for i in range(len(newargs)): # find input files XXX this a simple heuristic. we should really analyze based on a full understanding of gcc params,
                                    # right now we just assume that what is left contains no more |-x OPT| things
        arg = newargs[i]

        if i > 0:
          prev = newargs[i - 1]
          if prev in ('-MT', '-MF', '-MQ', '-D', '-U', '-o', '-x',
                      '-Xpreprocessor', '-include', '-imacros', '-idirafter',
                      '-iprefix', '-iwithprefix', '-iwithprefixbefore',
                      '-isysroot', '-imultilib', '-A', '-isystem', '-iquote',
                      '-install_name', '-compatibility_version',
                      '-current_version', '-I', '-L', '-include-pch'):
            continue # ignore this gcc-style argument

        if os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS):
          arg = os.path.realpath(arg)

        if not arg.startswith('-'):
          if not os.path.exists(arg):
            exit_with_error('%s: No such file or directory ("%s" was expected to be an input file, based on the commandline arguments provided)', arg, arg)

          arg_ending = filename_type_ending(arg)
          if arg_ending.endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS) or shared.Building.is_ar(arg): # we already removed -o <target>, so all these should be inputs
            newargs[i] = ''
            if arg_ending.endswith(SOURCE_ENDINGS):
              input_files.append((i, arg))
              has_source_inputs = True
            elif arg_ending.endswith(HEADER_ENDINGS):
              input_files.append((i, arg))
              has_header_inputs = True
            elif arg_ending.endswith(ASSEMBLY_ENDINGS) or shared.Building.is_bitcode(arg): # this should be bitcode, make sure it is valid
              input_files.append((i, arg))
            elif arg_ending.endswith(STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS):
              # if it's not, and it's a library, just add it to libs to find later
              l = unsuffixed_basename(arg)
              for prefix in LIB_PREFIXES:
                if not prefix:
                  continue
                if l.startswith(prefix):
                  l = l[len(prefix):]
                  break
              libs.append((i, l))
              newargs[i] = ''
            else:
              logging.warning(arg + ' is not valid LLVM bitcode')
          elif arg_ending.endswith(STATICLIB_ENDINGS):
            if not shared.Building.is_ar(arg):
              if shared.Building.is_bitcode(arg):
                message = arg + ': File has a suffix of a static library ' + str(STATICLIB_ENDINGS) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_ENDINGS)
              else:
                message = arg + ': Unknown format, not a static library!'
              exit_with_error(message)
          else:
            if has_fixed_language_mode:
              newargs[i] = ''
              input_files.append((i, arg))
              has_source_inputs = True
            else:
              exit_with_error(arg + ": Input file has an unknown suffix, don't know what to do with it!")
        elif arg.startswith('-L'):
          lib_dirs.append(arg[2:])
          newargs[i] = ''
        elif arg.startswith('-l'):
          libs.append((i, arg[2:]))
          newargs[i] = ''
        elif arg.startswith('-Wl,'):
          # Multiple comma separated link flags can be specified. Create fake
          # fractional indices for these: -Wl,a,b,c,d at index 4 becomes:
          # (4, a), (4.25, b), (4.5, c), (4.75, d)
          link_flags_to_add = arg.split(',')[1:]
          for flag_index, flag in enumerate(link_flags_to_add):
            link_flags.append((i + float(flag_index) / len(link_flags_to_add), flag))

          newargs[i] = ''

      original_input_files = input_files[:]

      newargs = [a for a in newargs if a is not '']

      # -c means do not link in gcc, and for us, the parallel is to not go all the way to JS, but stop at bitcode
      has_dash_c = '-c' in newargs
      if has_dash_c:
        assert has_source_inputs or has_header_inputs, 'Must have source code or header inputs to use -c'
        target = target_basename + '.o'
        final_suffix = 'o'
      if '-E' in newargs:
        final_suffix = 'eout' # not bitcode, not js; but just result from preprocessing stage of the input file
      if '-M' in newargs or '-MM' in newargs:
        final_suffix = 'mout' # not bitcode, not js; but just dependency rule of the input file
      final_ending = ('.' + final_suffix) if len(final_suffix) else ''

      # target is now finalized, can finalize other _target s
      js_target = unsuffixed(target) + '.js'

      asm_target = unsuffixed(js_target) + '.asm.js' # might not be used, but if it is, this is the name
      wasm_text_target = asm_target.replace('.asm.js', '.wast') # ditto, might not be used
      wasm_binary_target = asm_target.replace('.asm.js', '.wasm') # ditto, might not be used

      if final_suffix == 'html' and not options.separate_asm and ('PRECISE_F32=2' in settings_changes or 'USE_PTHREADS=2' in settings_changes):
        options.separate_asm = True
        logging.warning('forcing separate asm output (--separate-asm), because -s PRECISE_F32=2 or -s USE_PTHREADS=2 was passed.')
      if options.separate_asm:
        shared.Settings.SEPARATE_ASM = shared.JS.get_subresource_location(asm_target)

      if 'EMCC_STRICT' in os.environ:
        shared.Settings.STRICT = os.environ.get('EMCC_STRICT') != '0'

      # Libraries are searched before settings_changes are applied, so apply the value for STRICT and ERROR_ON_MISSING_LIBRARIES from
      # command line already now.

      def get_last_setting_change(setting):
        return ([None] + [x for x in settings_changes if x.startswith(setting + '=')])[-1]

      strict_cmdline = get_last_setting_change('STRICT')
      if strict_cmdline:
        shared.Settings.STRICT = int(strict_cmdline[len('STRICT='):])

      if shared.Settings.STRICT:
        shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS = 1
        shared.Settings.ERROR_ON_MISSING_LIBRARIES = 1

      error_on_missing_libraries_cmdline = get_last_setting_change('ERROR_ON_MISSING_LIBRARIES')
      if error_on_missing_libraries_cmdline:
        shared.Settings.ERROR_ON_MISSING_LIBRARIES = int(error_on_missing_libraries_cmdline[len('ERROR_ON_MISSING_LIBRARIES='):])

      settings_changes.append(system_js_libraries_setting_str(libs, lib_dirs, settings_changes, input_files))

      # If not compiling to JS, then we are compiling to an intermediate bitcode objects or library, so
      # ignore dynamic linking, since multiple dynamic linkings can interfere with each other
      if filename_type_suffix(target) not in JS_CONTAINING_SUFFIXES or options.ignore_dynamic_linking:
        def check(input_file):
          if filename_type_ending(input_file) in DYNAMICLIB_ENDINGS:
            if not options.ignore_dynamic_linking:
              logging.warning('ignoring dynamic library %s because not compiling to JS or HTML, remember to link it when compiling to JS or HTML at the end', os.path.basename(input_file))
            return False
          else:
            return True
        input_files = [f for f in input_files if check(f[1])]

      if len(input_files) == 0:
        exit_with_error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + STATICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS))

      newargs = CC_ADDITIONAL_ARGS + newargs

      if options.separate_asm and final_suffix != 'html':
        shared.WarningManager.warn('SEPARATE_ASM')

      # Apply optimization level settings
      shared.Settings.apply_opt_level(opt_level=options.opt_level, shrink_level=options.shrink_level, noisy=True)

      if os.environ.get('EMCC_FAST_COMPILER') == '0':
        logging.critical('Non-fastcomp compiler is no longer available, please use fastcomp or an older version of emscripten')
        return 0

      # Set ASM_JS default here so that we can override it from the command line.
      shared.Settings.ASM_JS = 1 if options.opt_level > 0 else 2

      # Apply -s settings in newargs here (after optimization levels, so they can override them)
      for change in settings_changes:
        key, value = change.split('=', 1)

        # In those settings fields that represent amount of memory, translate suffixes to multiples of 1024.
        if key in ['TOTAL_STACK', 'TOTAL_MEMORY', 'GL_MAX_TEMP_BUFFER_SIZE', 'SPLIT_MEMORY', 'WASM_MEM_MAX', 'DEFAULT_PTHREAD_STACK_SIZE']:
          value = str(shared.expand_byte_size_suffixes(value))

        original_exported_response = False

        if value[0] == '@':
          if key not in DEFERRED_REPONSE_FILES:
            if key == 'EXPORTED_FUNCTIONS':
              original_exported_response = value
            value = open(value[1:]).read()
          else:
            value = '"' + value + '"'
        else:
          value = value.replace('\\', '\\\\')
        try:
          setattr(shared.Settings, key, parse_value(value))
        except Exception as e:
          exit_with_error('a problem occured in evaluating the content after a "-s", specifically "%s": %s', change, str(e))

        if key == 'EXPORTED_FUNCTIONS':
          # used for warnings in emscripten.py
          shared.Settings.ORIGINAL_EXPORTED_FUNCTIONS = original_exported_response or shared.Settings.EXPORTED_FUNCTIONS[:]

      shared.verify_settings()

      # Note the exports the user requested
      shared.Building.user_requested_exports = shared.Settings.EXPORTED_FUNCTIONS[:]

      if options.bind:
        # If we are using embind and generating JS, now is the time to link in bind.cpp
        if final_suffix in JS_CONTAINING_SUFFIXES:
          input_files.append((next_arg_index, shared.path_from_root('system', 'lib', 'embind', 'bind.cpp')))
          next_arg_index += 1

      # -s ASSERTIONS=1 implies the heaviest stack overflow check mode. Set the implication here explicitly to avoid having to
      # do preprocessor "#if defined(ASSERTIONS) || defined(STACK_OVERFLOW_CHECK)" in .js files, which is not supported.
      if shared.Settings.ASSERTIONS:
        shared.Settings.STACK_OVERFLOW_CHECK = 2

      if not shared.Settings.STRICT:
        # The preprocessor define EMSCRIPTEN is deprecated. Don't pass it to code in strict mode. Code should use the define __EMSCRIPTEN__ instead.
        shared.COMPILER_OPTS += ['-DEMSCRIPTEN']

        # The system include path system/include/emscripten/ is deprecated, i.e. instead of #include <emscripten.h>, one should pass in #include <emscripten/emscripten.h>.
        # This path is not available in Emscripten strict mode.
        if shared.USE_EMSDK:
          shared.C_INCLUDE_PATHS += [shared.path_from_root('system', 'include', 'emscripten')]

      # Use settings

      try:
        assert shared.Settings.ASM_JS > 0, 'ASM_JS must be enabled in fastcomp'
        assert shared.Settings.SAFE_HEAP in [0, 1], 'safe heap must be 0 or 1 in fastcomp'
        assert shared.Settings.UNALIGNED_MEMORY == 0, 'forced unaligned memory not supported in fastcomp'
        assert shared.Settings.FORCE_ALIGNED_MEMORY == 0, 'forced aligned memory is not supported in fastcomp'
        assert shared.Settings.PGO == 0, 'pgo not supported in fastcomp'
        assert shared.Settings.QUANTUM_SIZE == 4, 'altering the QUANTUM_SIZE is not supported'
      except Exception as e:
        logging.error('Compiler settings error: {}'.format(e))
        exit_with_error('Compiler settings are incompatible with fastcomp. You can fall back to the older compiler core, although that is not recommended, see http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html')

      assert not shared.Settings.PGO, 'cannot run PGO in ASM_JS mode'

      if options.debug_level > 1 and options.use_closure_compiler:
        logging.warning('disabling closure because debug info was requested')
        options.use_closure_compiler = False

      assert not (shared.Settings.EMTERPRETIFY_FILE and shared.Settings.SINGLE_FILE), 'cannot have both EMTERPRETIFY_FILE and SINGLE_FILE enabled at the same time'

      assert not (shared.Settings.NO_DYNAMIC_EXECUTION and options.use_closure_compiler), 'cannot have both NO_DYNAMIC_EXECUTION and closure compiler enabled at the same time'

      if options.emrun:
        shared.Settings.EXPORTED_RUNTIME_METHODS.append('addOnExit')

      if options.use_closure_compiler:
        shared.Settings.USE_CLOSURE_COMPILER = options.use_closure_compiler
        if not shared.check_closure_compiler():
          exit_with_error('fatal: closure compiler is not configured correctly')
        if options.use_closure_compiler == 2 and shared.Settings.ASM_JS == 1:
          shared.WarningManager.warn('ALMOST_ASM', 'not all asm.js optimizations are possible with --closure 2, disabling those - your code will be run more slowly')
          shared.Settings.ASM_JS = 2

      if shared.Settings.MAIN_MODULE:
        assert not shared.Settings.SIDE_MODULE
        if shared.Settings.MAIN_MODULE != 2:
          shared.Settings.INCLUDE_FULL_LIBRARY = 1
      elif shared.Settings.SIDE_MODULE:
        assert not shared.Settings.MAIN_MODULE
        options.memory_init_file = False # memory init file is not supported with asm.js side modules, must be executable synchronously (for dlopen)

      if shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE:
        assert shared.Settings.ASM_JS, 'module linking requires asm.js output (-s ASM_JS=1)'
        if shared.Settings.MAIN_MODULE != 2 and shared.Settings.SIDE_MODULE != 2:
          shared.Settings.LINKABLE = 1
        shared.Settings.RELOCATABLE = 1
        shared.Settings.PRECISE_I64_MATH = 1 # other might use precise math, we need to be able to print it
        assert not options.use_closure_compiler, 'cannot use closure compiler on shared modules'
        # shared modules need memory utilities to allocate their memory
        shared.Settings.EXPORTED_RUNTIME_METHODS += [
          'allocate',
          'getMemory',
        ]
      if shared.Settings.USE_PTHREADS:
        # These runtime methods are called from pthread-main.js
        shared.Settings.EXPORTED_RUNTIME_METHODS += ['establishStackSpace', 'dynCall_ii']

      if shared.Settings.MODULARIZE_INSTANCE:
        shared.Settings.MODULARIZE = 1

      if shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
        shared.Settings.ALIASING_FUNCTION_POINTERS = 0

      if shared.Settings.LEGACY_VM_SUPPORT:
        # legacy vms don't have wasm
        assert not shared.Settings.WASM, 'LEGACY_VM_SUPPORT is only supported for asm.js, and not wasm. Build with -s WASM=0'

      if shared.Settings.SPLIT_MEMORY:
        if shared.Settings.WASM:
          logging.error('WASM is not compatible with SPLIT_MEMORY')
          sys.exit(1)
        assert shared.Settings.SPLIT_MEMORY > shared.Settings.TOTAL_STACK, 'SPLIT_MEMORY must be at least TOTAL_STACK (stack must fit in first chunk)'
        assert shared.Settings.SPLIT_MEMORY & (shared.Settings.SPLIT_MEMORY - 1) == 0, 'SPLIT_MEMORY must be a power of 2'
        if shared.Settings.ASM_JS == 1:
          shared.WarningManager.warn('ALMOST_ASM', "not all asm.js optimizations are possible with SPLIT_MEMORY, disabling those.")
          shared.Settings.ASM_JS = 2
        if shared.Settings.SAFE_HEAP:
          shared.Settings.SAFE_HEAP = 0
          shared.Settings.SAFE_SPLIT_MEMORY = 1 # we use our own infrastructure
        assert not shared.Settings.RELOCATABLE, 'no SPLIT_MEMORY with RELOCATABLE'
        assert not shared.Settings.USE_PTHREADS, 'no SPLIT_MEMORY with pthreads'
        if not options.js_opts:
          options.js_opts = True
          logging.debug('enabling js opts for SPLIT_MEMORY')
        options.force_js_opts = True
        if options.use_closure_compiler:
          options.use_closure_compiler = False
          logging.warning('cannot use closure compiler on split memory, for now, disabling')

      if shared.Settings.STB_IMAGE and final_suffix in JS_CONTAINING_SUFFIXES:
        input_files.append((next_arg_index, shared.path_from_root('third_party', 'stb_image.c')))
        next_arg_index += 1
        shared.Settings.EXPORTED_FUNCTIONS += ['_stbi_load', '_stbi_load_from_memory', '_stbi_image_free']
        # stb_image 2.x need to have STB_IMAGE_IMPLEMENTATION defined to include the implementation when compiling
        newargs.append('-DSTB_IMAGE_IMPLEMENTATION')

      if shared.Settings.ASMFS and final_suffix in JS_CONTAINING_SUFFIXES:
        if shared.Settings.WASM:
          logging.error('ASMFS not yet compatible with wasm (shared.make_fetch_worker is asm.js-specific)')
          sys.exit(1)
        input_files.append((next_arg_index, shared.path_from_root('system', 'lib', 'fetch', 'asmfs.cpp')))
        newargs.append('-D__EMSCRIPTEN_ASMFS__=1')
        next_arg_index += 1
        shared.Settings.NO_FILESYSTEM = 1
        shared.Settings.FETCH = 1
        if not shared.Settings.USE_PTHREADS:
          exit_with_error('-s ASMFS=1 requires either -s USE_PTHREADS=1 or -s USE_PTHREADS=2 to be set!')

      if shared.Settings.FETCH and final_suffix in JS_CONTAINING_SUFFIXES:
        if shared.Settings.WASM:
          logging.error('FETCH not yet compatible with wasm (shared.make_fetch_worker is asm.js-specific)')
          sys.exit(1)
        input_files.append((next_arg_index, shared.path_from_root('system', 'lib', 'fetch', 'emscripten_fetch.cpp')))
        next_arg_index += 1
        options.js_libraries.append(shared.path_from_root('src', 'library_fetch.js'))

      forced_stdlibs = []
      if shared.Settings.DEMANGLE_SUPPORT:
        shared.Settings.EXPORTED_FUNCTIONS += ['___cxa_demangle']
        forced_stdlibs += ['libcxxabi']

      if not shared.Settings.ONLY_MY_CODE:
        if type(shared.Settings.EXPORTED_FUNCTIONS) in (list, tuple):
          # always need malloc and free to be kept alive and exported, for internal use and other modules
          for required_export in ['_malloc', '_free']:
            if required_export not in shared.Settings.EXPORTED_FUNCTIONS:
              shared.Settings.EXPORTED_FUNCTIONS.append(required_export)
        else:
          logging.debug('using response file for EXPORTED_FUNCTIONS, make sure it includes _malloc and _free')

      assert not (shared.Settings.NO_DYNAMIC_EXECUTION and shared.Settings.RELOCATABLE), 'cannot have both NO_DYNAMIC_EXECUTION and RELOCATABLE enabled at the same time, since RELOCATABLE needs to eval()'

      if shared.Settings.RELOCATABLE:
        assert shared.Settings.GLOBAL_BASE < 1
        if shared.Settings.EMULATED_FUNCTION_POINTERS == 0:
          shared.Settings.EMULATED_FUNCTION_POINTERS = 2 # by default, use optimized function pointer emulation
        shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS = shared.Settings.WARN_ON_UNDEFINED_SYMBOLS = 0
        if not shared.Settings.SIDE_MODULE:
          shared.Settings.EXPORT_ALL = 1

      if shared.Settings.EMTERPRETIFY:
        shared.Settings.FINALIZE_ASM_JS = 0
        # shared.Settings.GLOBAL_BASE = 8*256 # keep enough space at the bottom for a full stack frame, for z-interpreter
        shared.Settings.SIMPLIFY_IFS = 0 # this is just harmful for emterpreting
        shared.Settings.EXPORTED_FUNCTIONS += ['emterpret']
        if not options.js_opts:
          logging.debug('enabling js opts for EMTERPRETIFY')
          options.js_opts = True
        options.force_js_opts = True
        assert options.use_closure_compiler is not 2, 'EMTERPRETIFY requires valid asm.js, and is incompatible with closure 2 which disables that'
        assert not use_source_map(options), 'EMTERPRETIFY is not compatible with source maps (maps are not useful in emterpreted code, and splitting out non-emterpreted source maps is not yet implemented)'

      if shared.Settings.DEAD_FUNCTIONS:
        if not options.js_opts:
          logging.debug('enabling js opts for DEAD_FUNCTIONS')
          options.js_opts = True
        options.force_js_opts = True

      if options.proxy_to_worker:
        shared.Settings.PROXY_TO_WORKER = 1

      if options.use_preload_plugins or len(options.preload_files) or len(options.embed_files):
        assert not shared.Settings.NODERAWFS, '--preload-file and --embed-file cannot be used with NODERAWFS which disables virtual filesystem'
        # if we include any files, or intend to use preload plugins, then we definitely need filesystem support
        shared.Settings.FORCE_FILESYSTEM = 1

      if options.proxy_to_worker or options.use_preload_plugins:
        shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$Browser']

      if not shared.Settings.NO_FILESYSTEM and not shared.Settings.ONLY_MY_CODE:
        shared.Settings.EXPORTED_FUNCTIONS += ['___errno_location'] # so FS can report errno back to C
        # to flush streams on FS exit, we need to be able to call fflush
        # we only include it if the runtime is exitable, or when ASSERTIONS
        # (ASSERTIONS will check that streams do not need to be flushed,
        # helping people see when they should have disabled NO_EXIT_RUNTIME)
        if not shared.Settings.NO_EXIT_RUNTIME or shared.Settings.ASSERTIONS:
          shared.Settings.EXPORTED_FUNCTIONS += ['_fflush']

      if shared.Settings.USE_PTHREADS:
        if not any(s.startswith('PTHREAD_POOL_SIZE=') for s in settings_changes):
          settings_changes.append('PTHREAD_POOL_SIZE=0')
        options.js_libraries.append(shared.path_from_root('src', 'library_pthread.js'))
        newargs.append('-D__EMSCRIPTEN_PTHREADS__=1')
        shared.Settings.FORCE_FILESYSTEM = 1 # proxying of utime requires the filesystem
      else:
        options.js_libraries.append(shared.path_from_root('src', 'library_pthread_stub.js'))

      if shared.Settings.FORCE_FILESYSTEM:
        # when the filesystem is forced, we export by default methods that filesystem usage
        # may need, including filesystem usage from standalone file packager output (i.e.
        # file packages not built together with emcc, but that are loaded at runtime
        # separately, and they need emcc's output to contain the support they need)
        shared.Settings.EXPORTED_RUNTIME_METHODS += [
          'FS_createFolder',
          'FS_createPath',
          'FS_createDataFile',
          'FS_createPreloadedFile',
          'FS_createLazyFile',
          'FS_createLink',
          'FS_createDevice',
          'FS_unlink',
          'getMemory',
          'addRunDependency',
          'removeRunDependency',
        ]

      if shared.Settings.USE_PTHREADS:
        if shared.Settings.LINKABLE:
          exit_with_error('-s LINKABLE=1 is not supported with -s USE_PTHREADS>0!')
        if shared.Settings.SIDE_MODULE:
          exit_with_error('-s SIDE_MODULE=1 is not supported with -s USE_PTHREADS>0!')
        if shared.Settings.MAIN_MODULE:
          exit_with_error('-s MAIN_MODULE=1 is not supported with -s USE_PTHREADS>0!')
        if shared.Settings.EMTERPRETIFY:
          exit_with_error('-s EMTERPRETIFY=1 is not supported with -s USE_PTHREADS>0!')
        if shared.Settings.PROXY_TO_WORKER:
          exit_with_error('--proxy-to-worker is not supported with -s USE_PTHREADS>0! Use the option -s PROXY_TO_PTHREAD=1 if you want to run the main thread of a multithreaded application in a web worker.')
      else:
        if shared.Settings.PROXY_TO_PTHREAD:
          exit_with_error('-s PROXY_TO_PTHREAD=1 requires -s USE_PTHREADS to work!')

      if shared.Settings.OUTLINING_LIMIT:
        if not options.js_opts:
          logging.debug('enabling js opts as optional functionality implemented as a js opt was requested')
          options.js_opts = True
        options.force_js_opts = True

      if shared.Settings.WASM:
        # When only targeting wasm, the .asm.js file is not executable, so is treated as an intermediate build file that can be cleaned up.
        if shared.Building.is_wasm_only():
          asm_target = asm_target.replace('.asm.js', '.temp.asm.js')
          misc_temp_files.note(asm_target)

      if shared.Settings.WASM:
        if shared.Settings.TOTAL_MEMORY % 65536 != 0:
          exit_with_error('For wasm, TOTAL_MEMORY must be a multiple of 64KB, was ' + str(shared.Settings.TOTAL_MEMORY))
      else:
        if shared.Settings.TOTAL_MEMORY < 16 * 1024 * 1024:
          exit_with_error('TOTAL_MEMORY must be at least 16MB, was ' + str(shared.Settings.TOTAL_MEMORY))
        if shared.Settings.TOTAL_MEMORY % (16 * 1024 * 1024) != 0:
          exit_with_error('For asm.js, TOTAL_MEMORY must be a multiple of 16MB, was ' + str(shared.Settings.TOTAL_MEMORY))
      if shared.Settings.TOTAL_MEMORY < shared.Settings.TOTAL_STACK:
        exit_with_error('TOTAL_MEMORY must be larger than TOTAL_STACK, was ' + str(shared.Settings.TOTAL_MEMORY) + ' (TOTAL_STACK=' + str(shared.Settings.TOTAL_STACK) + ')')
      if shared.Settings.WASM_MEM_MAX != -1 and shared.Settings.WASM_MEM_MAX % 65536 != 0:
        exit_with_error('WASM_MEM_MAX must be a multiple of 64KB, was ' + str(shared.Settings.WASM_MEM_MAX))
      if shared.Settings.USE_PTHREADS and shared.Settings.WASM and shared.Settings.ALLOW_MEMORY_GROWTH and shared.Settings.WASM_MEM_MAX == -1:
        exit_with_error('If pthreads and memory growth are enabled, WASM_MEM_MAX must be set')

      if shared.Settings.WASM_BACKEND:
        options.js_opts = None

        # wasm backend output can benefit from the binaryen optimizer (in asm2wasm,
        # we run the optimizer during asm2wasm itself). use it, if not overridden
        if 'BINARYEN_PASSES' not in settings_key_changes:
          if options.opt_level > 0 or options.shrink_level > 0:
            shared.Settings.BINARYEN_PASSES = shared.Building.opt_level_to_str(options.opt_level, options.shrink_level)

        # to bootstrap struct_info, we need binaryen
        os.environ['EMCC_WASM_BACKEND_BINARYEN'] = '1'

      if shared.Settings.WASM:
        if shared.Settings.SINGLE_FILE:
          # placeholder strings for JS glue, to be replaced with subresource locations in do_binaryen
          shared.Settings.WASM_TEXT_FILE = shared.FilenameReplacementStrings.WASM_TEXT_FILE
          shared.Settings.WASM_BINARY_FILE = shared.FilenameReplacementStrings.WASM_BINARY_FILE
          shared.Settings.ASMJS_CODE_FILE = shared.FilenameReplacementStrings.ASMJS_CODE_FILE
        else:
          # set file locations, so that JS glue can find what it needs
          shared.Settings.WASM_TEXT_FILE = shared.JS.escape_for_js_string(os.path.basename(wasm_text_target))
          shared.Settings.WASM_BINARY_FILE = shared.JS.escape_for_js_string(os.path.basename(wasm_binary_target))
          shared.Settings.ASMJS_CODE_FILE = shared.JS.escape_for_js_string(os.path.basename(asm_target))

        shared.Settings.ASM_JS = 2 # when targeting wasm, we use a wasm Memory, but that is not compatible with asm.js opts
        shared.Settings.GLOBAL_BASE = 1024 # leave some room for mapping global vars
        assert not shared.Settings.SPLIT_MEMORY, 'WebAssembly does not support split memory'
        if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS:
          logging.warning('for wasm there is no need to set ELIMINATE_DUPLICATE_FUNCTIONS, the binaryen optimizer does it automatically')
          shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS = 0
        if shared.Settings.OUTLINING_LIMIT:
          logging.warning('for wasm there is usually no need to set OUTLINING_LIMIT, as VMs can handle large functions well anyhow')
        # default precise-f32 to on, since it works well in wasm
        # also always use f32s when asm.js is not in the picture
        if ('PRECISE_F32=0' not in settings_changes and 'PRECISE_F32=2' not in settings_changes) or 'asmjs' not in shared.Settings.BINARYEN_METHOD:
          shared.Settings.PRECISE_F32 = 1
        if options.js_opts and not options.force_js_opts and 'asmjs' not in shared.Settings.BINARYEN_METHOD:
          options.js_opts = None
          logging.debug('asm.js opts not forced by user or an option that depends them, and we do not intend to run the asm.js, so disabling and leaving opts to the binaryen optimizer')
        assert not options.use_closure_compiler == 2, 'closure compiler mode 2 assumes the code is asm.js, so not meaningful for wasm'
        # for simplicity, we always have a mem init file, which may also be imported into the wasm module.
        #  * if we also supported js mem inits we'd have 4 modes
        #  * and js mem inits are useful for avoiding a side file, but the wasm module avoids that anyhow
        if 'MEM_INIT_METHOD' in settings_changes:
          logging.error('Mem init method selection is not supported in wasm. Memory will be embedded in the wasm binary if threads are not used, and included in a separate file if threads are used.')
          sys.exit(1)
        options.memory_init_file = True
        # async compilation requires wasm-only mode, and also not interpreting (the interpreter needs sync input)
        if shared.Settings.BINARYEN_ASYNC_COMPILATION == 1 and shared.Building.is_wasm_only() and 'interpret' not in shared.Settings.BINARYEN_METHOD:
          # async compilation requires a swappable module - we swap it in when it's ready
          shared.Settings.SWAPPABLE_ASM_MODULE = 1
        else:
          # if not wasm-only, we can't do async compilation as the build can run in other
          # modes than wasm (like asm.js) which may not support an async step
          shared.Settings.BINARYEN_ASYNC_COMPILATION = 0
          warning = 'This will reduce performance and compatibility (some browsers limit synchronous compilation), see https://github.com/kripken/emscripten/wiki/WebAssembly#codegen-effects'
          if 'BINARYEN_ASYNC_COMPILATION=1' in settings_changes:
            logging.warning('BINARYEN_ASYNC_COMPILATION requested, but disabled because of user options. ' + warning)
          elif 'BINARYEN_ASYNC_COMPILATION=0' not in settings_changes:
            logging.warning('BINARYEN_ASYNC_COMPILATION disabled due to user options. ' + warning)
        # run safe-heap as a binaryen pass
        if shared.Settings.SAFE_HEAP and shared.Building.is_wasm_only():
          if shared.Settings.BINARYEN_PASSES:
            shared.Settings.BINARYEN_PASSES += ','
          shared.Settings.BINARYEN_PASSES += 'safe-heap'
        if shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
          # emulated function pointer casts is emulated in wasm using a binaryen pass
          if shared.Settings.BINARYEN_PASSES:
            shared.Settings.BINARYEN_PASSES += ','
          shared.Settings.BINARYEN_PASSES += 'fpcast-emu'
          # we also need emulated function pointers for that, as we need a single flat
          # table, as is standard in wasm, and not asm.js split ones.
          shared.Settings.EMULATED_FUNCTION_POINTERS = 1

        # we will include the mem init data in the wasm, when we don't need the
        # mem init file to be loadable by itself
        shared.Settings.MEM_INIT_IN_WASM = 'asmjs' not in shared.Settings.BINARYEN_METHOD and \
                                           'interpret-asm2wasm' not in shared.Settings.BINARYEN_METHOD and \
                                           not shared.Settings.USE_PTHREADS

        # wasm side modules have suffix .wasm
        if shared.Settings.SIDE_MODULE and target.endswith('.js'):
          logging.warning('output suffix .js requested, but wasm side modules are just wasm files; emitting only a .wasm, no .js')

        if options.separate_asm:
          logging.error('cannot --separate-asm when emitting wasm, since not emitting asm.js')
          sys.exit(1)

      # wasm outputs are only possible with a side wasm
      if target.endswith(WASM_ENDINGS):
        if not (shared.Settings.WASM and shared.Settings.SIDE_MODULE):
          logging.warning('output file "%s" has a wasm suffix, but we cannot emit wasm by itself, except as a dynamic library (see SIDE_MODULE option). specify an output file with suffix .js or .html, and a wasm file will be created on the side' % target)
          return 1

      if shared.Settings.EVAL_CTORS:
        if not shared.Settings.WASM:
          # for asm.js: this option is not a js optimizer pass, but does run the js optimizer internally, so
          # we need to generate proper code for that (for wasm, we run a binaryen tool for this)
          shared.Settings.RUNNING_JS_OPTS = 1
        else:
          if 'interpret' in shared.Settings.BINARYEN_METHOD:
            logging.warning('disabling EVAL_CTORS as the bundled interpreter confuses the ctor tool')
            shared.Settings.EVAL_CTORS = 0

      # memory growth does not work in dynamic linking, except for wasm
      if not shared.Settings.WASM and (shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE):
        assert not shared.Settings.ALLOW_MEMORY_GROWTH, 'memory growth is not supported with shared asm.js modules'

      if shared.Settings.ALLOW_MEMORY_GROWTH and shared.Settings.ASM_JS == 1:
        # this is an issue in asm.js, but not wasm
        if not shared.Settings.WASM or 'asmjs' in shared.Settings.BINARYEN_METHOD:
          shared.WarningManager.warn('ALMOST_ASM')
          shared.Settings.ASM_JS = 2 # memory growth does not validate as asm.js http://discourse.wicg.io/t/request-for-comments-switching-resizing-heaps-in-asm-js/641/23

      # safe heap in asm.js uses the js optimizer (in wasm-only mode we can use binaryen)
      if shared.Settings.SAFE_HEAP and not shared.Building.is_wasm_only():
        if not options.js_opts:
          logging.debug('enabling js opts for SAFE_HEAP')
          options.js_opts = True
        options.force_js_opts = True

      if options.js_opts:
        shared.Settings.RUNNING_JS_OPTS = 1

      if shared.Settings.CYBERDWARF:
        newargs.append('-g')
        options.debug_level = max(options.debug_level, 2)
        shared.Settings.BUNDLED_CD_DEBUG_FILE = target + ".cd"
        options.js_libraries.append(shared.path_from_root('src', 'library_cyberdwarf.js'))
        options.js_libraries.append(shared.path_from_root('src', 'library_debugger_toolkit.js'))

      if options.tracing:
        if shared.Settings.ALLOW_MEMORY_GROWTH:
          shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['emscripten_trace_report_memory_layout']

      if shared.Settings.ONLY_MY_CODE:
        shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []
        options.separate_asm = True
        shared.Settings.FINALIZE_ASM_JS = False

      if shared.Settings.GLOBAL_BASE < 0:
        shared.Settings.GLOBAL_BASE = 8 # default if nothing else sets it

      if shared.Settings.WASM_BACKEND:
        if shared.Settings.SIMD:
          newargs.append('-msimd128')
      else:
        # We leave the -O option in place so that the clang front-end runs in that
        # optimization mode, but we disable the actual optimization passes, as we'll
        # run them separately.
        if options.opt_level > 0:
          newargs.append('-mllvm')
          newargs.append('-disable-llvm-optzns')

      if not shared.Settings.LEGALIZE_JS_FFI:
        assert shared.Building.is_wasm_only(), 'LEGALIZE_JS_FFI incompatible with RUNNING_JS_OPTS and non-wasm BINARYEN_METHOD.'

      shared.Settings.EMSCRIPTEN_VERSION = shared.EMSCRIPTEN_VERSION
      shared.Settings.OPT_LEVEL = options.opt_level
      shared.Settings.DEBUG_LEVEL = options.debug_level
      shared.Settings.PROFILING_FUNCS = options.profiling_funcs
      shared.Settings.SOURCE_MAP_BASE = options.source_map_base or ''

      ## Compile source code to bitcode

      logging.debug('compiling to bitcode')

      temp_files = []

    # exit block 'parse arguments and setup'
    log_time('parse arguments and setup')

    with ToolchainProfiler.profile_block('bitcodeize inputs'):
      # Precompiled headers support
      if has_header_inputs:
        headers = [header for _, header in input_files]
        for header in headers:
          assert header.endswith(HEADER_ENDINGS), 'if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ' + str(headers) + ' : ' + header
        args = newargs + shared.EMSDK_CXX_OPTS + headers
        if specified_target:
          args += ['-o', specified_target]
        args = system_libs.process_args(args, shared.Settings)
        logging.debug("running (for precompiled headers): " + call + ' ' + ' '.join(args))
        return run_process([call] + args, check=False).returncode

      def get_bitcode_file(input_file):
        if final_suffix not in JS_CONTAINING_SUFFIXES:
          # no need for a temp file, just emit to the right place
          if len(input_files) == 1:
            # can just emit directly to the target
            if specified_target:
              if specified_target.endswith('/') or specified_target.endswith('\\') or os.path.isdir(specified_target):
                return os.path.join(specified_target, os.path.basename(unsuffixed(input_file))) + options.default_object_extension
              return specified_target
            return unsuffixed(input_file) + final_ending
          else:
            if has_dash_c:
              return unsuffixed(input_file) + options.default_object_extension
        return in_temp(unsuffixed(uniquename(input_file)) + options.default_object_extension)

      # Request LLVM debug info if explicitly specified, or building bitcode with -g, or if building a source all the way to JS with -g
      if use_source_map(options) or ((final_suffix not in JS_CONTAINING_SUFFIXES or (has_source_inputs and final_suffix in JS_CONTAINING_SUFFIXES)) and options.requested_debug == '-g'):
        # do not save llvm debug info if js optimizer will wipe it out anyhow (but if source maps are used, keep it)
        if use_source_map(options) or not (final_suffix in JS_CONTAINING_SUFFIXES and options.js_opts):
          newargs.append('-g') # preserve LLVM debug info
          options.debug_level = 4
          shared.Settings.DEBUG_LEVEL = 4

      # Bitcode args generation code
      def get_bitcode_args(input_files):
        file_ending = filename_type_ending(input_files[0])
        args = [call] + newargs + input_files
        if file_ending.endswith(CXX_ENDINGS):
          args += shared.EMSDK_CXX_OPTS
        if not shared.Building.can_inline():
          args.append('-fno-inline-functions')
        # For fastcomp backend, no LLVM IR functions should ever be annotated 'optnone', because that would skip running the SimplifyCFG pass on them, which is required to always run to
        # clean up LandingPadInst instructions that are not needed.
        if not shared.Settings.WASM_BACKEND:
          args += ['-Xclang', '-disable-O0-optnone']
        args = system_libs.process_args(args, shared.Settings)
        return args

      # -E preprocessor-only support
      if '-E' in newargs or '-M' in newargs or '-MM' in newargs:
        input_files = [x[1] for x in input_files]
        cmd = get_bitcode_args(input_files)
        if specified_target:
          cmd += ['-o', specified_target]
        # Do not compile, but just output the result from preprocessing stage or output the dependency rule. Warning: clang and gcc behave differently with -MF! (clang seems to not recognize it)
        logging.debug(('just preprocessor ' if '-E' in newargs else 'just dependencies: ') + ' '.join(cmd))
        return run_process(cmd, check=False).returncode

      def compile_source_file(i, input_file):
        logging.debug('compiling source file: ' + input_file)
        output_file = get_bitcode_file(input_file)
        temp_files.append((i, output_file))
        args = get_bitcode_args([input_file]) + ['-emit-llvm', '-c', '-o', output_file]
        logging.debug("running: " + ' '.join(shared.Building.doublequote_spaces(args))) # NOTE: Printing this line here in this specific format is important, it is parsed to implement the "emcc --cflags" command
        if run_process(args, check=False).returncode != 0:
          exit_with_error('compiler frontend failed to generate LLVM bitcode, halting')
        assert(os.path.exists(output_file))

      # First, generate LLVM bitcode. For each input file, we get base.o with bitcode
      for i, input_file in input_files:
        file_ending = filename_type_ending(input_file)
        if file_ending.endswith(SOURCE_ENDINGS):
          compile_source_file(i, input_file)
        else: # bitcode
          if file_ending.endswith(BITCODE_ENDINGS):
            logging.debug('using bitcode file: ' + input_file)
            temp_files.append((i, input_file))
          elif file_ending.endswith(DYNAMICLIB_ENDINGS) or shared.Building.is_ar(input_file):
            logging.debug('using library file: ' + input_file)
            temp_files.append((i, input_file))
          elif file_ending.endswith(ASSEMBLY_ENDINGS):
            if not LEAVE_INPUTS_RAW:
              logging.debug('assembling assembly file: ' + input_file)
              temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o')
              shared.Building.llvm_as(input_file, temp_file)
              temp_files.append((i, temp_file))
          else:
            if has_fixed_language_mode:
              compile_source_file(i, input_file)
            else:
              exit_with_error(input_file + ': Unknown file suffix when compiling to LLVM bitcode!')

    # exit block 'bitcodeize inputs'
    log_time('bitcodeize inputs')

    with ToolchainProfiler.profile_block('process inputs'):
      if not LEAVE_INPUTS_RAW and not shared.Settings.WASM_BACKEND:
        assert len(temp_files) == len(input_files)

        # Optimize source files
        if optimizing(options.llvm_opts):
          for pos, (_, input_file) in enumerate(input_files):
            file_ending = filename_type_ending(input_file)
            if file_ending.endswith(SOURCE_ENDINGS):
              temp_file = temp_files[pos][1]
              logging.debug('optimizing %s', input_file)
              # if DEBUG:
              #   shutil.copyfile(temp_file, os.path.join(shared.configuration.CANONICAL_TEMP_DIR, 'to_opt.bc')) # useful when LLVM opt aborts
              new_temp_file = in_temp(unsuffixed(uniquename(temp_file)) + '.o')
              # after optimizing, lower intrinsics to libc calls so that our linking code
              # will find them (otherwise, llvm.cos.f32() will not link in cosf(), and
              # we end up calling out to JS for Math.cos).
              opts = options.llvm_opts + ['-lower-non-em-intrinsics']
              shared.Building.llvm_opt(temp_file, opts, new_temp_file)
              temp_files[pos] = (temp_files[pos][0], new_temp_file)

      # Decide what we will link
      stop_at_bitcode = final_suffix not in EXECUTABLE_SUFFIXES

      if stop_at_bitcode or not shared.Settings.WASM_BACKEND:
        # Filter link flags, keeping only those that shared.Building.link knows
        # how to deal with.  We currently can't handle flags with options (like
        # -Wl,-rpath,/bin:/lib, where /bin:/lib is an option for the -rpath
        # flag).
        link_flags = [f for f in link_flags if f[1] in SUPPORTED_LINKER_FLAGS]

      linker_inputs = [val for _, val in sorted(temp_files + link_flags)]

      # If we were just asked to generate bitcode, stop there
      if stop_at_bitcode:
        if not specified_target:
          assert len(temp_files) == len(input_files)
          for tempf, inputf in zip(temp_files, input_files):
            safe_move(tempf[1], unsuffixed_basename(inputf[1]) + final_ending)
        else:
          if len(input_files) == 1:
            input_file = input_files[0][1]
            temp_file = temp_files[0][1]
            bitcode_target = specified_target if specified_target else unsuffixed_basename(input_file) + final_ending
            if temp_file != input_file:
              safe_move(temp_file, bitcode_target)
            else:
              shutil.copyfile(temp_file, bitcode_target)
            temp_output_base = unsuffixed(temp_file)
            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 + options.default_object_extension, specified_target)
              with open(os.path.join(os.path.dirname(specified_target), os.path.basename(unsuffixed(input_file) + '.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
            # we have multiple files: Link them
            logging.debug('link: ' + str(linker_inputs) + specified_target)
            # Sort arg tuples and pass the extracted values to link.
            shared.Building.link(linker_inputs, specified_target)
        logging.debug('stopping at bitcode')
        if shared.Settings.SIDE_MODULE:
          exit_with_error('SIDE_MODULE must only be used when compiling to an executable shared library, and not when emitting LLVM bitcode. That is, you should be emitting a .wasm file (for wasm) or a .js file (for asm.js). Note that when compiling to a typical native suffix for a shared library (.so, .dylib, .dll; which many build systems do) then Emscripten emits an LLVM bitcode file, which you should then compile to .wasm or .js with SIDE_MODULE.')
        if final_suffix.lower() in ['so', 'dylib', 'dll']:
          logging.warning('When Emscripten compiles to a typical native suffix for shared libraries (.so, .dylib, .dll) then it emits an LLVM bitcode file. You should then compile that to an emscripten SIDE_MODULE (using that flag) with suffix .wasm (for wasm) or .js (for asm.js). (You may also want to adapt your build system to emit the more standard suffix for a file with LLVM bitcode, \'.bc\', which would avoid this warning.)')
        return 0

    # exit block 'process inputs'
    log_time('process inputs')

    ## Continue on to create JavaScript

    with ToolchainProfiler.profile_block('calculate system libraries'):
      logging.debug('will generate JavaScript')

      extra_files_to_link = []

      # link in ports and system libraries, if necessary
      if not LEAVE_INPUTS_RAW and \
         not shared.Settings.BUILD_AS_SHARED_LIB and \
         not shared.Settings.BOOTSTRAPPING_STRUCT_INFO and \
         not shared.Settings.ONLY_MY_CODE and \
         not shared.Settings.SIDE_MODULE: # shared libraries/side modules link no C libraries, need them in parent
        extra_files_to_link = system_libs.get_ports(shared.Settings)
        extra_files_to_link += system_libs.calculate([f for _, f in sorted(temp_files)] + extra_files_to_link, in_temp, stdout_=None, stderr_=None, forced=forced_stdlibs)

    # exit block 'calculate system libraries'
    log_time('calculate system libraries')

    with ToolchainProfiler.profile_block('link'):
      # final will be an array if linking is deferred, otherwise a normal string.
      if shared.Settings.WASM_BACKEND:
        DEFAULT_FINAL = in_temp(target_basename + '.wasm')
      else:
        DEFAULT_FINAL = in_temp(target_basename + '.bc')

      def get_final():
        global final
        if isinstance(final, list):
          final = DEFAULT_FINAL
        return final

      # First, combine the bitcode files if there are several. We must also link if we have a singleton .a
      linker_inputs += extra_files_to_link
      perform_link = len(linker_inputs) > 1 or shared.Settings.WASM_BACKEND
      if not perform_link and not LEAVE_INPUTS_RAW:
        is_bc = suffix(temp_files[0][1]) in BITCODE_ENDINGS
        is_dylib = suffix(temp_files[0][1]) in DYNAMICLIB_ENDINGS
        is_ar = shared.Building.is_ar(temp_files[0][1])
        perform_link = not (is_bc or is_dylib) and is_ar
      if perform_link:
        logging.debug('linking: ' + str(linker_inputs))
        # force archive contents to all be included, if just archives, or if linking shared modules
        force_archive_contents = len([temp for i, temp in temp_files if not temp.endswith(STATICLIB_ENDINGS)]) == 0 or not shared.Building.can_build_standalone()

        # if  EMCC_DEBUG=2  then we must link now, so the temp files are complete.
        # if using the wasm backend, we might be using vanilla LLVM, which does not allow our fastcomp deferred linking opts.
        # TODO: we could check if this is a fastcomp build, and still speed things up here
        just_calculate = DEBUG != '2' and not shared.Settings.WASM_BACKEND
        if shared.Settings.WASM_BACKEND:
          # If LTO is enabled then use the -O opt level as the LTO level
          if options.llvm_lto:
            lto_level = options.opt_level
          else:
            lto_level = 0
          final = shared.Building.link_lld(linker_inputs, DEFAULT_FINAL, options.llvm_opts, lto_level)
        else:
          final = shared.Building.link(linker_inputs, DEFAULT_FINAL, force_archive_contents=force_archive_contents, temp_files=misc_temp_files, just_calculate=just_calculate)
      else:
        if not LEAVE_INPUTS_RAW:
          _, temp_file = temp_files[0]
          _, input_file = input_files[0]
          final = in_temp(target_basename + '.bc')
          if temp_file != input_file:
            shutil.move(temp_file, final)
          else:
            shutil.copyfile(temp_file, final)
        else:
          _, input_file = input_files[0]
          final = in_temp(input_file)
          shutil.copyfile(input_file, final)

    # exit block 'link'
    log_time('link')

    if not shared.Settings.WASM_BACKEND:
      with ToolchainProfiler.profile_block('post-link'):
        if DEBUG:
          logging.debug('saving intermediate processing steps to %s', shared.get_emscripten_temp_dir())
          if not LEAVE_INPUTS_RAW:
            save_intermediate('basebc', 'bc')

        # Optimize, if asked to
        if not LEAVE_INPUTS_RAW:
          # remove LLVM debug if we are not asked for it
          link_opts = [] if use_source_map(options) or shared.Settings.CYBERDWARF else ['-strip-debug']
          if not shared.Settings.ASSERTIONS:
            link_opts += ['-disable-verify']
          else:
            # when verifying, LLVM debug info has some tricky linking aspects, and llvm-link will
            # disable the type map in that case. we added linking to opt, so we need to do
            # something similar, which we can do with a param to opt
            link_opts += ['-disable-debug-info-type-map']

          if options.llvm_lto is not None and options.llvm_lto >= 2 and optimizing(options.llvm_opts):
            logging.debug('running LLVM opts as pre-LTO')
            final = shared.Building.llvm_opt(final, options.llvm_opts, DEFAULT_FINAL)
            save_intermediate('opt', 'bc')

          # If we can LTO, do it before dce, since it opens up dce opportunities
          if shared.Building.can_build_standalone() and options.llvm_lto and options.llvm_lto != 2:
            if not shared.Building.can_inline():
              link_opts.append('-disable-inlining')
            # add a manual internalize with the proper things we need to be kept alive during lto
            link_opts += shared.Building.get_safe_internalize() + ['-std-link-opts']
            # execute it now, so it is done entirely before we get to the stage of legalization etc.
            final = shared.Building.llvm_opt(final, link_opts, DEFAULT_FINAL)
            save_intermediate('lto', 'bc')
            link_opts = []
          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']

          if options.cfi:
            if use_cxx:
               link_opts.append("-wholeprogramdevirt")
            link_opts.append("-lowertypetests")

          if AUTODEBUG:
            # let llvm opt directly emit ll, to skip writing and reading all the bitcode
            link_opts += ['-S']
            final = shared.Building.llvm_opt(final, link_opts, get_final() + '.link.ll')
            save_intermediate('linktime', 'll')
          else:
            if len(link_opts) > 0:
              final = shared.Building.llvm_opt(final, link_opts, DEFAULT_FINAL)
              save_intermediate('linktime', 'bc')
            if options.save_bc:
              shutil.copyfile(final, options.save_bc)

        # Prepare .ll for Emscripten
        if LEAVE_INPUTS_RAW:
          assert len(input_files) == 1
        if options.save_bc:
          save_intermediate('ll', 'll')

        if AUTODEBUG:
          logging.debug('autodebug')
          next = get_final() + '.ad.ll'
          run_process([shared.PYTHON, shared.AUTODEBUGGER, final, next])
          final = next
          save_intermediate('autodebug', 'll')

        assert not isinstance(final, list), 'we must have linked the final files, if linking was deferred, by this point'

    # exit block 'post-link'
    log_time('post-link')

    with ToolchainProfiler.profile_block('emscript'):
      # Emscripten
      logging.debug('LLVM => JS')
      extra_args = []
      if options.js_libraries:
        extra_args = ['--libraries', ','.join(map(os.path.abspath, options.js_libraries))]
      if options.memory_init_file:
        shared.Settings.MEM_INIT_METHOD = 1
      else:
        assert shared.Settings.MEM_INIT_METHOD != 1

      if embed_memfile(options):
        shared.Settings.SUPPORT_BASE64_EMBEDDING = 1

      final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
      save_intermediate('original')

      if shared.Settings.WASM_BACKEND:
        # we also received wast and wasm at this stage
        temp_basename = unsuffixed(final)
        wasm_temp = temp_basename + '.wasm'
        shutil.move(wasm_temp, wasm_binary_target)
        open(wasm_text_target + '.mappedGlobals', 'w').write('{}') # no need for mapped globals for now, but perhaps some day
        if use_source_map(options):
          shutil.move(wasm_temp + '.map', wasm_binary_target + '.map')

      if shared.Settings.CYBERDWARF:
        cd_target = final + '.cd'
        shutil.move(cd_target, target + '.cd')

    # exit block 'emscript'
    log_time('emscript (llvm => executable code)')

    with ToolchainProfiler.profile_block('source transforms'):
      # Embed and preload files
      if len(options.preload_files) or len(options.embed_files):

        # copying into the heap is risky when split - the chunks might be too small for the file package!
        if shared.Settings.SPLIT_MEMORY and not options.no_heap_copy:
          logging.info('Enabling --no-heap-copy because -s SPLIT_MEMORY=1 is being used with file_packager.py (pass --no-heap-copy to suppress this notification)')
          options.no_heap_copy = True

        # Also, MEMFS is not aware of heap resizing feature in wasm, so if MEMFS and memory growth are used together, force
        # no_heap_copy to be enabled.
        if shared.Settings.ALLOW_MEMORY_GROWTH and not options.no_heap_copy:
          logging.info('Enabling --no-heap-copy because -s ALLOW_MEMORY_GROWTH=1 is being used with file_packager.py (pass --no-heap-copy to suppress this notification)')
          options.no_heap_copy = True

        logging.debug('setting up files')
        file_args = ['--from-emcc', '--export-name=' + shared.Settings.EXPORT_NAME]
        if len(options.preload_files):
          file_args.append('--preload')
          file_args += options.preload_files
        if len(options.embed_files):
          file_args.append('--embed')
          file_args += options.embed_files
        if len(options.exclude_files):
          file_args.append('--exclude')
          file_args += options.exclude_files
        if options.use_preload_cache:
          file_args.append('--use-preload-cache')
        if options.no_heap_copy:
          file_args.append('--no-heap-copy')
        if shared.Settings.LZ4:
          file_args.append('--lz4')
        if options.use_preload_plugins:
          file_args.append('--use-preload-plugins')
        file_code = run_process([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE).stdout
        options.pre_js = file_code + options.pre_js

      # Apply pre and postjs files
      if options.pre_js or options.post_js:
        logging.debug('applying pre/postjses')
        src = open(final).read()
        final += '.pp.js'
        if WINDOWS: # Avoid duplicating \r\n to \r\r\n when writing out.
          if options.pre_js:
            options.pre_js = options.pre_js.replace('\r\n', '\n')
          if options.post_js:
            options.post_js = options.post_js.replace('\r\n', '\n')
        outfile = open(final, 'w')
        # pre-js code goes right after the Module integration code (so it
        # can use Module), we have a marker for it
        outfile.write(src.replace('// {{PRE_JSES}}', options.pre_js))
        outfile.write(options.post_js)
        outfile.close()
        options.pre_js = src = options.post_js = None
        save_intermediate('pre-post')

      # Apply a source code transformation, if requested
      if options.js_transform:
        shutil.copyfile(final, final + '.tr.js')
        final += '.tr.js'
        posix = not shared.WINDOWS
        logging.debug('applying transform: %s', options.js_transform)
        shared.check_call(shared.Building.remove_quotes(shlex.split(options.js_transform, posix=posix) + [os.path.abspath(final)]))
        save_intermediate('transformed')

      js_transform_tempfiles = [final]

    # exit block 'source transforms'
    log_time('source transforms')

    with ToolchainProfiler.profile_block('memory initializer'):
      memfile = None

      if shared.Settings.MEM_INIT_METHOD > 0 or embed_memfile(options):
        memfile = target + '.mem'
        shared.try_delete(memfile)

        def repl(m):
          # handle chunking of the memory initializer
          s = m.group(1)
          if len(s) == 0:
            return '' # don't emit 0-size ones
          membytes = [int(x or '0') for x in s.split(',')]
          while membytes and membytes[-1] == 0:
            membytes.pop()
          if not membytes:
            return ''
          if shared.Settings.MEM_INIT_METHOD == 2:
            # memory initializer in a string literal
            return "memoryInitializer = '%s';" % shared.JS.generate_string_initializer(membytes)
          open(memfile, 'wb').write(bytearray(membytes))
          if DEBUG:
            # Copy into temp dir as well, so can be run there too
            shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
          if not shared.Settings.WASM or not shared.Settings.MEM_INIT_IN_WASM:
            return 'memoryInitializer = "%s";' % shared.JS.get_subresource_location(memfile, embed_memfile(options))
          else:
            return ''

        src = re.sub(shared.JS.memory_initializer_pattern, repl, open(final).read(), count=1)
        open(final + '.mem.js', 'w').write(src)
        final += '.mem.js'
        src = None
        js_transform_tempfiles[-1] = final # simple text substitution preserves comment line number mappings
        if os.path.exists(memfile):
          save_intermediate('meminit')
          logging.debug('wrote memory initialization to %s', memfile)
        else:
          logging.debug('did not see memory initialization')

      if shared.Settings.USE_PTHREADS:
        target_dir = os.path.dirname(os.path.abspath(target))
        shutil.copyfile(shared.path_from_root('src', 'pthread-main.js'),
                        os.path.join(target_dir, 'pthread-main.js'))

      # Generate the fetch-worker.js script for multithreaded emscripten_fetch() support if targeting pthreads.
      if shared.Settings.FETCH and shared.Settings.USE_PTHREADS:
        shared.make_fetch_worker(final, os.path.join(os.path.dirname(os.path.abspath(target)), 'fetch-worker.js'))

    # exit block 'memory initializer'
    log_time('memory initializer')

    optimizer = JSOptimizer(
      target=target,
      options=options,
      js_transform_tempfiles=js_transform_tempfiles,
      in_temp=in_temp,
    )
    with ToolchainProfiler.profile_block('js opts'):
      # It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing
      if shared.Settings.DEAD_FUNCTIONS:
        optimizer.queue += ['eliminateDeadFuncs']
        optimizer.extra_info['dead_functions'] = shared.Settings.DEAD_FUNCTIONS

      if options.opt_level >= 1 and options.js_opts:
        logging.debug('running js post-opts')

        if DEBUG == '2':
          # Clean up the syntax a bit
          optimizer.queue += ['noop']

        def get_eliminate():
          if shared.Settings.ALLOW_MEMORY_GROWTH:
            return 'eliminateMemSafe'
          else:
            return 'eliminate'

        if options.opt_level >= 2:
          optimizer.queue += [get_eliminate()]

          if shared.Settings.AGGRESSIVE_VARIABLE_ELIMINATION:
            # note that this happens before registerize/minification, which can obfuscate the name of 'label', which is tricky
            optimizer.queue += ['aggressiveVariableElimination']

          optimizer.queue += ['simplifyExpressions']

          if shared.Settings.EMTERPRETIFY:
            # emterpreter code will not run through a JS optimizing JIT, do more work ourselves
            optimizer.queue += ['localCSE']

      if shared.Settings.EMTERPRETIFY:
        # add explicit label setting, as we will run aggressiveVariableElimination late, *after* 'label' is no longer notable by name
        optimizer.queue += ['safeLabelSetting']

      if options.opt_level >= 1 and options.js_opts:
        if options.opt_level >= 2:
          # simplify ifs if it is ok to make the code somewhat unreadable, and unless outlining (simplified ifs
          # with commaified code breaks late aggressive variable elimination)
          # do not do this with binaryen, as commaifying confuses binaryen call type detection (FIXME, in theory, but unimportant)
          debugging = options.debug_level == 0 or options.profiling
          if shared.Settings.SIMPLIFY_IFS and debugging and shared.Settings.OUTLINING_LIMIT == 0 and not shared.Settings.WASM:
            optimizer.queue += ['simplifyIfs']

          if shared.Settings.PRECISE_F32:
            optimizer.queue += ['optimizeFrounds']

      if options.js_opts:
        if shared.Settings.SAFE_HEAP and not shared.Building.is_wasm_only():
          optimizer.queue += ['safeHeap']

        if shared.Settings.OUTLINING_LIMIT > 0:
          optimizer.queue += ['outline']
          optimizer.extra_info['sizeToOutline'] = shared.Settings.OUTLINING_LIMIT

        if options.opt_level >= 2 and options.debug_level < 3:
          if options.opt_level >= 3 or options.shrink_level > 0:
            optimizer.queue += ['registerizeHarder']
          else:
            optimizer.queue += ['registerize']

        # NOTE: Important that this comes after registerize/registerizeHarder
        if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS and options.opt_level >= 2:
          optimizer.flush()
          shared.Building.eliminate_duplicate_funcs(final)
          save_intermediate('dfe', 'js')

      if shared.Settings.EVAL_CTORS and options.memory_init_file and not use_source_map(options) and not shared.Settings.WASM:
        optimizer.flush()
        shared.Building.eval_ctors(final, memfile)
        save_intermediate('eval-ctors', 'js')

      if options.js_opts:
        # some compilation modes require us to minify later or not at all
        if not shared.Settings.EMTERPRETIFY and not shared.Settings.WASM:
          optimizer.do_minify()

        if options.opt_level >= 2:
          optimizer.queue += ['asmLastOpts']

        if shared.Settings.FINALIZE_ASM_JS:
          optimizer.queue += ['last']

        optimizer.flush()

      if options.use_closure_compiler == 2:
        optimizer.flush()

        logging.debug('running closure')
        # no need to add this to js_transform_tempfiles, because closure and
        # debug_level > 0 are never simultaneously true
        final = shared.Building.closure_compiler(final, pretty=options.debug_level >= 1)
        save_intermediate('closure')

    log_time('js opts')

    with ToolchainProfiler.profile_block('final emitting'):
      if shared.Settings.EMTERPRETIFY:
        emterpretify(js_target, optimizer, options)

      # Remove some trivial whitespace
      # TODO: do not run when compress has already been done on all parts of the code
      # src = open(final).read()
      # src = re.sub(r'\n+[ \n]*\n+', '\n', src)
      # open(final, 'w').write(src)

      # Bundle symbol data in with the cyberdwarf file
      if shared.Settings.CYBERDWARF:
        run_process([shared.PYTHON, shared.path_from_root('tools', 'emdebug_cd_merger.py'), target + '.cd', target + '.symbols'])

      if use_source_map(options) and not shared.Settings.WASM:
        emit_js_source_maps(target, optimizer.js_transform_tempfiles)

      # track files that will need native eols
      generated_text_files_with_native_eols = []

      if (options.separate_asm or shared.Settings.WASM) and not shared.Settings.WASM_BACKEND:
        separate_asm_js(final, asm_target)
        generated_text_files_with_native_eols += [asm_target]

      if shared.Settings.WASM:
        binaryen_method_sanity_check()
        do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
                    wasm_text_target, misc_temp_files, optimizer)

      if shared.Settings.MODULARIZE:
        modularize()

      module_export_name_substitution()

      # The JS is now final. Move it to its final location
      shutil.move(final, js_target)

      generated_text_files_with_native_eols += [js_target]

      # If we were asked to also generate HTML, do that
      if final_suffix == 'html':
        generate_html(target, options, js_target, target_basename,
                      asm_target, wasm_binary_target,
                      memfile, optimizer)
      else:
        if options.proxy_to_worker:
          generate_worker_js(target, js_target, target_basename)

      if embed_memfile(options):
        shared.try_delete(memfile)

      for f in generated_text_files_with_native_eols:
        tools.line_endings.convert_line_endings_in_file(f, os.linesep, options.output_eol)
    log_time('final emitting')
    # exit block 'final emitting'

    if DEBUG:
      logging.debug('total time: %.2f seconds', (time.time() - start_time))

  finally:
    try:
      shutil.rmtree(temp_dir)
    except:
      pass

  return 0


def parse_args(newargs):
  options = EmccOptions()
  settings_changes = []
  should_exit = False

  for i in range(len(newargs)):
    # On Windows Vista (and possibly others), excessive spaces in the command line
    # leak into the items in this array, so trim e.g. 'foo.cpp ' -> 'foo.cpp'
    newargs[i] = newargs[i].strip()
    if newargs[i].startswith('-O'):
      # Let -O default to -O2, which is what gcc does.
      options.requested_level = newargs[i][2:] or '2'
      if options.requested_level == 's':
        options.llvm_opts = ['-Os']
        options.requested_level = 2
        options.shrink_level = 1
        settings_changes.append('INLINING_LIMIT=50')
      elif options.requested_level == 'z':
        options.llvm_opts = ['-Oz']
        options.requested_level = 2
        options.shrink_level = 2
        settings_changes.append('INLINING_LIMIT=25')
      options.opt_level = validate_arg_level(options.requested_level, 3, 'Invalid optimization level: ' + newargs[i], clamp=True)
    elif newargs[i].startswith('--js-opts'):
      check_bad_eq(newargs[i])
      options.js_opts = int(newargs[i + 1])
      if options.js_opts:
        options.force_js_opts = True
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--llvm-opts'):
      check_bad_eq(newargs[i])
      options.llvm_opts = parse_value(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--llvm-lto'):
      check_bad_eq(newargs[i])
      options.llvm_lto = int(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--closure'):
      check_bad_eq(newargs[i])
      options.use_closure_compiler = int(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--js-transform'):
      check_bad_eq(newargs[i])
      options.js_transform = newargs[i + 1]
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--pre-js'):
      check_bad_eq(newargs[i])
      options.pre_js += open(newargs[i + 1]).read() + '\n'
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--post-js'):
      check_bad_eq(newargs[i])
      options.post_js += open(newargs[i + 1]).read() + '\n'
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--minify'):
      check_bad_eq(newargs[i])
      assert newargs[i + 1] == '0', '0 is the only supported option for --minify; 1 has been deprecated'
      options.debug_level = max(1, options.debug_level)
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('-g'):
      requested_level = newargs[i][2:] or '3'
      options.debug_level = validate_arg_level(requested_level, 4, 'Invalid debug level: ' + newargs[i])
      options.requested_debug = newargs[i]
      newargs[i] = ''
    elif newargs[i] == '-profiling' or newargs[i] == '--profiling':
      options.debug_level = 2
      options.profiling = True
      newargs[i] = ''
    elif newargs[i] == '-profiling-funcs' or newargs[i] == '--profiling-funcs':
      options.profiling_funcs = True
      newargs[i] = ''
    elif newargs[i] == '--tracing' or newargs[i] == '--memoryprofiler':
      if newargs[i] == '--memoryprofiler':
        options.memory_profiler = True
      options.tracing = True
      newargs[i] = ''
      newargs.append('-D__EMSCRIPTEN_TRACING__=1')
      settings_changes.append("EMSCRIPTEN_TRACING=1")
      options.js_libraries.append(shared.path_from_root('src', 'library_trace.js'))
    elif newargs[i] == '--emit-symbol-map':
      options.emit_symbol_map = True
      newargs[i] = ''
    elif newargs[i] == '--bind':
      options.bind = True
      newargs[i] = ''
      options.js_libraries.append(shared.path_from_root('src', 'embind', 'emval.js'))
      options.js_libraries.append(shared.path_from_root('src', 'embind', 'embind.js'))
      if options.default_cxx_std:
        # Force C++11 for embind code, but only if user has not explicitly overridden a standard.
        options.default_cxx_std = '-std=c++11'
    elif newargs[i].startswith('-std=') or newargs[i].startswith('--std='):
      # User specified a standard to use, clear Emscripten from specifying it.
      options.default_cxx_std = ''
    elif newargs[i].startswith('--embed-file'):
      check_bad_eq(newargs[i])
      options.embed_files.append(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--preload-file'):
      check_bad_eq(newargs[i])
      options.preload_files.append(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--exclude-file'):
      check_bad_eq(newargs[i])
      options.exclude_files.append(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--use-preload-cache'):
      options.use_preload_cache = True
      newargs[i] = ''
    elif newargs[i].startswith('--no-heap-copy'):
      options.no_heap_copy = True
      newargs[i] = ''
    elif newargs[i].startswith('--use-preload-plugins'):
      options.use_preload_plugins = True
      newargs[i] = ''
    elif newargs[i] == '--ignore-dynamic-linking':
      options.ignore_dynamic_linking = True
      newargs[i] = ''
    elif newargs[i] == '-v':
      shared.COMPILER_OPTS += ['-v']
      shared.check_sanity(force=True)
      newargs[i] = ''
    elif newargs[i].startswith('--shell-file'):
      check_bad_eq(newargs[i])
      options.shell_path = newargs[i + 1]
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--source-map-base'):
      check_bad_eq(newargs[i])
      options.source_map_base = newargs[i + 1]
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i].startswith('--js-library'):
      check_bad_eq(newargs[i])
      options.js_libraries.append(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i] == '--remove-duplicates':
      logging.warning('--remove-duplicates is deprecated as it is no longer needed. If you cannot link without it, file a bug with a testcase')
      newargs[i] = ''
    elif newargs[i] == '--jcache':
      logging.error('jcache is no longer supported')
      newargs[i] = ''
    elif newargs[i] == '--cache':
      check_bad_eq(newargs[i])
      os.environ['EM_CACHE'] = newargs[i + 1]
      shared.reconfigure_cache()
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i] == '--clear-cache':
      logging.info('clearing cache as requested by --clear-cache')
      shared.Cache.erase()
      shared.check_sanity(force=True) # this is a good time for a sanity check
      should_exit = True
    elif newargs[i] == '--clear-ports':
      logging.info('clearing ports and cache as requested by --clear-ports')
      system_libs.Ports.erase()
      shared.Cache.erase()
      shared.check_sanity(force=True) # this is a good time for a sanity check
      should_exit = True
    elif newargs[i] == '--show-ports':
      system_libs.show_ports()
      should_exit = True
    elif newargs[i] == '--save-bc':
      check_bad_eq(newargs[i])
      options.save_bc = newargs[i + 1]
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i] == '--memory-init-file':
      check_bad_eq(newargs[i])
      options.memory_init_file = int(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i] == '--proxy-to-worker':
      options.proxy_to_worker = True
      newargs[i] = ''
    elif newargs[i] == '--valid-abspath':
      options.valid_abspaths.append(newargs[i + 1])
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i] == '--separate-asm':
      options.separate_asm = True
      newargs[i] = ''
    elif newargs[i].startswith(('-I', '-L')):
      options.path_name = newargs[i][2:]
      if os.path.isabs(options.path_name) and not is_valid_abspath(options, options.path_name):
        # Of course an absolute path to a non-system-specific library or header
        # is fine, and you can ignore this warning. The danger are system headers
        # that are e.g. x86 specific and nonportable. The emscripten bundled
        # headers are modified to be portable, local system ones are generally not.
        shared.WarningManager.warn(
            'ABSOLUTE_PATHS', '-I or -L of an absolute path "' + newargs[i] +
            '" encountered. If this is to a local system header/library, it may '
            'cause problems (local system files make sense for compiling natively '
            'on your system, but not necessarily to JavaScript).')
    elif newargs[i] == '--emrun':
      options.emrun = True
      newargs[i] = ''
    elif newargs[i] == '--cpuprofiler':
      options.cpu_profiler = True
      newargs[i] = ''
    elif newargs[i] == '--threadprofiler':
      options.thread_profiler = True
      settings_changes.append('PTHREADS_PROFILING=1')
      newargs[i] = ''
    elif newargs[i] == '--default-obj-ext':
      newargs[i] = ''
      options.default_object_extension = newargs[i + 1]
      if not options.default_object_extension.startswith('.'):
        options.default_object_extension = '.' + options.default_object_extension
      newargs[i + 1] = ''
    elif newargs[i] == '-msse':
      newargs.append('-D__SSE__=1')
      newargs[i] = ''
    elif newargs[i] == '-msse2':
      newargs.append('-D__SSE__=1')
      newargs.append('-D__SSE2__=1')
      newargs[i] = ''
    elif newargs[i] == '-msse3':
      newargs.append('-D__SSE__=1')
      newargs.append('-D__SSE2__=1')
      newargs.append('-D__SSE3__=1')
      newargs[i] = ''
    elif newargs[i] == '-mssse3':
      newargs.append('-D__SSE__=1')
      newargs.append('-D__SSE2__=1')
      newargs.append('-D__SSE3__=1')
      newargs.append('-D__SSSE3__=1')
      newargs[i] = ''
    elif newargs[i] == '-msse4.1':
      newargs.append('-D__SSE__=1')
      newargs.append('-D__SSE2__=1')
      newargs.append('-D__SSE3__=1')
      newargs.append('-D__SSSE3__=1')
      newargs.append('-D__SSE4_1__=1')
      newargs[i] = ''
    elif newargs[i].startswith("-fsanitize=cfi"):
      options.cfi = True
    elif newargs[i] == "--output_eol":
      if newargs[i + 1].lower() == 'windows':
        options.output_eol = '\r\n'
      elif newargs[i + 1].lower() == 'linux':
        options.output_eol = '\n'
      else:
        exit_with_error('Invalid value "' + newargs[i + 1] + '" to --output_eol!')
      newargs[i] = ''
      newargs[i + 1] = ''
    elif newargs[i] == '--generate-config':
      optarg = newargs[i + 1]
      path = os.path.expanduser(optarg)
      if os.path.exists(path):
        exit_with_error('File ' + optarg + ' passed to --generate-config already exists!')
      else:
        shared.generate_config(optarg)
      should_exit = True

  if should_exit:
    sys.exit(0)

  newargs = [arg for arg in newargs if arg is not '']
  return options, settings_changes, newargs


def emterpretify(js_target, optimizer, options):
  global final
  optimizer.flush('pre-emterpretify')
  logging.debug('emterpretifying')
  import json
  try:
    # move temp js to final position, alongside its mem init file
    shutil.move(final, js_target)
    args = [shared.PYTHON,
            shared.path_from_root('tools', 'emterpretify.py'),
            js_target,
            final + '.em.js',
            json.dumps(shared.Settings.EMTERPRETIFY_BLACKLIST),
            json.dumps(shared.Settings.EMTERPRETIFY_WHITELIST),
            json.dumps(shared.Settings.EMTERPRETIFY_SYNCLIST),
            str(shared.Settings.SWAPPABLE_ASM_MODULE)]
    if shared.Settings.EMTERPRETIFY_ASYNC:
      args += ['ASYNC=1']
    if shared.Settings.EMTERPRETIFY_ADVISE:
      args += ['ADVISE=1']
    if options.profiling or options.profiling_funcs:
      args += ['PROFILING=1']
    if shared.Settings.ASSERTIONS:
      args += ['ASSERTIONS=1']
    if shared.Settings.PRECISE_F32:
      args += ['FROUND=1']
    if shared.Settings.ALLOW_MEMORY_GROWTH:
      args += ['MEMORY_SAFE=1']
    if shared.Settings.EMTERPRETIFY_FILE:
      args += ['FILE="' + shared.Settings.EMTERPRETIFY_FILE + '"']
    run_process(args)
    final = final + '.em.js'
  finally:
    shared.try_delete(js_target)

  if shared.Settings.EMTERPRETIFY_ADVISE:
    logging.warning('halting compilation due to EMTERPRETIFY_ADVISE')
    sys.exit(0)

  # minify (if requested) after emterpreter processing, and finalize output
  logging.debug('finalizing emterpreted code')
  shared.Settings.FINALIZE_ASM_JS = 1
  if not shared.Settings.WASM:
    optimizer.do_minify()
  optimizer.queue += ['last']
  optimizer.flush('finalizing-emterpreted-code')

  # finalize the original as well, if we will be swapping it in (TODO: add specific option for this)
  if shared.Settings.SWAPPABLE_ASM_MODULE:
    real = final
    original = js_target + '.orig.js' # the emterpretify tool saves the original here
    final = original
    logging.debug('finalizing original (non-emterpreted) code at ' + final)
    if not shared.Settings.WASM:
      optimizer.do_minify()
    optimizer.queue += ['last']
    optimizer.flush('finalizing-original-code')
    safe_copy(final, original)
    final = real


def emit_js_source_maps(target, js_transform_tempfiles):
  logging.debug('generating source maps')
  jsrun.run_js(shared.path_from_root('tools', 'source-maps', 'sourcemapper.js'),
               shared.NODE_JS, js_transform_tempfiles +
               ['--sourceRoot', os.getcwd(),
                '--mapFileBaseName', target,
                '--offset', str(0)])


def separate_asm_js(final, asm_target):
  """Separate out the asm.js code, if asked. Or, if necessary for another option"""
  logging.debug('separating asm')
  shared.check_call([shared.PYTHON, shared.path_from_root('tools', 'separate_asm.py'), final, asm_target, final])

  # extra only-my-code logic
  if shared.Settings.ONLY_MY_CODE:
    temp = asm_target + '.only.js'
    print(jsrun.run_js(shared.path_from_root('tools', 'js-optimizer.js'), shared.NODE_JS, args=[asm_target, 'eliminateDeadGlobals', 'last', 'asm'], stdout=open(temp, 'w')))
    shutil.move(temp, asm_target)


def binaryen_method_sanity_check():
  if shared.Settings.BINARYEN_METHOD:
    methods = shared.Settings.BINARYEN_METHOD.split(',')
    valid_methods = ['asmjs', 'native-wasm', 'interpret-s-expr', 'interpret-binary', 'interpret-asm2wasm']
    for m in methods:
      if m.strip() not in valid_methods:
        exit_with_error('Unrecognized BINARYEN_METHOD "' + m.strip() + '" specified! Please pass a comma-delimited list containing one or more of: ' + ','.join(valid_methods))


def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
                wasm_text_target, misc_temp_files, optimizer):
  global final
  logging.debug('using binaryen, with method: ' + shared.Settings.BINARYEN_METHOD)
  binaryen_bin = shared.Building.get_binaryen_bin()
  binaryen_lib = shared.Building.get_binaryen_lib()
  # Emit wasm.js at the top of the js. This is *not* optimized with the rest of the code, since
  # (1) it contains asm.js, whose validation would be broken, and (2) it's very large so it would
  # be slow in cleanup/JSDCE etc.
  # TODO: for html, it could be a separate script tag
  # We need wasm.js if there is a chance the polyfill will be used. If the user sets
  # BINARYEN_METHOD with something that doesn't use the polyfill, then we don't need it.
  if not shared.Settings.BINARYEN_METHOD or 'interpret' in shared.Settings.BINARYEN_METHOD:
    logging.debug('integrating wasm.js polyfill interpreter')
    wasm_js = open(os.path.join(binaryen_lib, 'wasm.js')).read()
    wasm_js = wasm_js.replace('EMSCRIPTEN_', 'emscripten_') # do not confuse the markers
    js = open(final).read()
    combined = open(final, 'w')
    combined.write(wasm_js)
    combined.write('\n//^wasm.js\n')
    combined.write(js)
    combined.close()
  # normally we emit binary, but for debug info, we might emit text first
  wrote_wasm_text = False
  debug_info = options.debug_level >= 2 or options.profiling_funcs
  emit_symbol_map = options.emit_symbol_map or shared.Settings.CYBERDWARF
  # finish compiling to WebAssembly, using asm2wasm, if we didn't already emit WebAssembly directly using the wasm backend.
  if not shared.Settings.WASM_BACKEND:
    if DEBUG:
      # save the asm.js input
      shared.safe_copy(asm_target, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(asm_target)))
    cmd = [os.path.join(binaryen_bin, 'asm2wasm'), asm_target, '--total-memory=' + str(shared.Settings.TOTAL_MEMORY)]
    if shared.Settings.BINARYEN_TRAP_MODE in ('js', 'clamp', 'allow'):
      cmd += ['--trap-mode=' + shared.Settings.BINARYEN_TRAP_MODE]
    else:
      exit_with_error('invalid BINARYEN_TRAP_MODE value: ' + shared.Settings.BINARYEN_TRAP_MODE + ' (should be js/clamp/allow)')
    if shared.Settings.BINARYEN_IGNORE_IMPLICIT_TRAPS:
      cmd += ['--ignore-implicit-traps']
    # pass optimization level to asm2wasm (if not optimizing, or which passes we should run was overridden, do not optimize)
    if options.opt_level > 0:
      cmd.append(shared.Building.opt_level_to_str(options.opt_level, options.shrink_level))
    # import mem init file if it exists, and if we will not be using asm.js as a binaryen method (as it needs the mem init file, of course)
    mem_file_exists = options.memory_init_file and os.path.exists(memfile)
    import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
    if import_mem_init:
      cmd += ['--mem-init=' + memfile]
      if not shared.Settings.RELOCATABLE:
        cmd += ['--mem-base=' + str(shared.Settings.GLOBAL_BASE)]
    # various options imply that the imported table may not be the exact size as the wasm module's own table segments
    if shared.Settings.RELOCATABLE or shared.Settings.RESERVED_FUNCTION_POINTERS > 0 or shared.Settings.EMULATED_FUNCTION_POINTERS:
      cmd += ['--table-max=-1']
    if shared.Settings.SIDE_MODULE:
      cmd += ['--mem-max=-1']
    elif shared.Settings.WASM_MEM_MAX >= 0:
      cmd += ['--mem-max=' + str(shared.Settings.WASM_MEM_MAX)]
    if shared.Settings.LEGALIZE_JS_FFI != 1:
      cmd += ['--no-legalize-javascript-ffi']
    if shared.Building.is_wasm_only():
      cmd += ['--wasm-only'] # this asm.js is code not intended to run as asm.js, it is only ever going to be wasm, an can contain special fastcomp-wasm support
    if shared.Settings.USE_PTHREADS:
      cmd += ['--enable-threads']
    if debug_info:
      cmd += ['-g']
    if emit_symbol_map:
      cmd += ['--symbolmap=' + target + '.symbols']
    # we prefer to emit a binary, as it is more efficient. however, when we
    # want full debug info support (not just function names), then we must
    # emit text (at least until wasm gains support for debug info in binaries)
    target_binary = options.debug_level < 3
    if target_binary:
      cmd += ['-o', wasm_binary_target]
    else:
      cmd += ['-o', wasm_text_target, '-S']
      wrote_wasm_text = True
    logging.debug('asm2wasm (asm.js => WebAssembly): ' + ' '.join(cmd))
    TimeLogger.update()
    shared.check_call(cmd)

    if not target_binary:
      cmd = [os.path.join(binaryen_bin, 'wasm-as'), wasm_text_target, '-o', wasm_binary_target]
      if debug_info:
        cmd += ['-g']
        if use_source_map(options):
          cmd += ['--source-map=' + wasm_binary_target + '.map']
          if options.source_map_base:
            cmd += ['--source-map-url=' + options.source_map_base + os.path.basename(wasm_binary_target) + '.map']
      logging.debug('wasm-as (text => binary): ' + ' '.join(cmd))
      shared.check_call(cmd)
    if import_mem_init:
      # remove the mem init file in later processing; it does not need to be prefetched in the html, etc.
      if DEBUG:
        safe_move(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
      else:
        os.unlink(memfile)
    log_time('asm2wasm')
  if shared.Settings.BINARYEN_PASSES:
    shutil.move(wasm_binary_target, wasm_binary_target + '.pre')
    # BINARYEN_PASSES is comma-separated, and we support both '-'-prefixed and unprefixed pass names
    passes = [('--' + p) if p[0] != '-' else p for p in shared.Settings.BINARYEN_PASSES.split(',')]
    cmd = [os.path.join(binaryen_bin, 'wasm-opt'), wasm_binary_target + '.pre', '-o', wasm_binary_target] + passes
    if debug_info:
      cmd += ['-g'] # preserve the debug info
    logging.debug('wasm-opt on BINARYEN_PASSES: ' + ' '.join(cmd))
    shared.check_call(cmd)
  if not wrote_wasm_text and 'interpret-s-expr' in shared.Settings.BINARYEN_METHOD:
    cmd = [os.path.join(binaryen_bin, 'wasm-dis'), wasm_binary_target, '-o', wasm_text_target]
    logging.debug('wasm-dis (binary => text): ' + ' '.join(cmd))
    shared.check_call(cmd)
  if shared.Settings.BINARYEN_SCRIPTS:
    binaryen_scripts = os.path.join(shared.Settings.BINARYEN_ROOT, 'scripts')
    script_env = os.environ.copy()
    root_dir = os.path.abspath(os.path.dirname(__file__))
    if script_env.get('PYTHONPATH'):
      script_env['PYTHONPATH'] += ':' + root_dir
    else:
      script_env['PYTHONPATH'] = root_dir
    for script in shared.Settings.BINARYEN_SCRIPTS.split(','):
      logging.debug('running binaryen script: ' + script)
      shared.check_call([shared.PYTHON, os.path.join(binaryen_scripts, script), final, wasm_text_target], env=script_env)
  if shared.Settings.EVAL_CTORS:
    if DEBUG:
      save_intermediate('pre-eval-ctors', 'js')
      shutil.copyfile(wasm_binary_target, os.path.join(shared.get_emscripten_temp_dir(), 'pre-eval-ctors.wasm'))
    shared.Building.eval_ctors(final, wasm_binary_target, binaryen_bin, debug_info=debug_info)
  # after generating the wasm, do some final operations
  if not shared.Settings.WASM_BACKEND:
    if shared.Settings.SIDE_MODULE:
      wso = shared.WebAssembly.make_shared_library(final, wasm_binary_target)
      # replace the wasm binary output with the dynamic library. TODO: use a specific suffix for such files?
      shutil.move(wso, wasm_binary_target)
      if not DEBUG:
        os.unlink(asm_target) # we don't need the asm.js, it can just confuse
      sys.exit(0) # and we are done.
  if options.opt_level >= 2:
    # minify the JS
    optimizer.do_minify() # calculate how to minify
    if optimizer.cleanup_shell or options.use_closure_compiler:
      save_intermediate_with_wasm('preclean', wasm_binary_target)
      final = shared.Building.minify_wasm_js(js_file=final,
                                             wasm_file=wasm_binary_target,
                                             expensive_optimizations=options.opt_level >= 3 or options.shrink_level > 0,
                                             minify_whitespace=optimizer.minify_whitespace,
                                             use_closure_compiler=options.use_closure_compiler,
                                             debug_info=debug_info,
                                             emit_symbol_map=emit_symbol_map)
      save_intermediate_with_wasm('postclean', wasm_binary_target)
  # replace placeholder strings with correct subresource locations
  if shared.Settings.SINGLE_FILE:
    f = open(final, 'r')
    js = f.read()
    f.close()
    f = open(final, 'w')
    for target, replacement_string, should_embed in (
        (wasm_text_target, shared.FilenameReplacementStrings.WASM_TEXT_FILE, True),
        (wasm_binary_target, shared.FilenameReplacementStrings.WASM_BINARY_FILE, True),
        (asm_target, shared.FilenameReplacementStrings.ASMJS_CODE_FILE, not shared.Building.is_wasm_only())
      ):
      if should_embed and os.path.isfile(target):
        js = js.replace(replacement_string, shared.JS.get_subresource_location(target))
      else:
        js = js.replace(replacement_string, '')
      shared.try_delete(target)
    f.write(js)
    f.close()


def modularize():
  global final
  logging.debug('Modularizing, assigning to var ' + shared.Settings.EXPORT_NAME)
  src = open(final).read()
  final = final + '.modular.js'
  f = open(final, 'w')

  # Included code may refer to Module (e.g. from file packager), so alias it
  f.write('''var %(EXPORT_NAME)s = function(%(EXPORT_NAME)s) {
  %(EXPORT_NAME)s = %(EXPORT_NAME)s || {};

%(src)s

  return %(EXPORT_NAME)s;
};
%(EXPORT_NAME)s = %(EXPORT_NAME)s.bind({
  _currentScript: typeof document !== 'undefined' ? document.currentScript : undefined
})%(instantiate)s;
''' % {
    'EXPORT_NAME': shared.Settings.EXPORT_NAME,
    'src': src,
    'instantiate': '()' if shared.Settings.MODULARIZE_INSTANCE else ''
  })

  # Export using a UMD style export, or ES6 exports if selected
  if shared.Settings.EXPORT_ES6:
    f.write('''export default %s;''' % shared.Settings.EXPORT_NAME)
  else:
    f.write('''if (typeof exports === 'object' && typeof module === 'object')
    module.exports = %(EXPORT_NAME)s;
  else if (typeof define === 'function' && define['amd'])
    define([], function() { return %(EXPORT_NAME)s; });
  else if (typeof exports === 'object')
    exports["%(EXPORT_NAME)s"] = %(EXPORT_NAME)s;
  ''' % {
      'EXPORT_NAME': shared.Settings.EXPORT_NAME
    })

  f.close()
  save_intermediate('modularized', 'js')


def module_export_name_substitution():
  global final
  logging.debug('Private module export name substitution with ' + shared.Settings.EXPORT_NAME)
  src = open(final).read()
  final = final + '.module_export_name_substitution.js'
  f = open(final, 'w')
  replacement = "typeof %(EXPORT_NAME)s !== 'undefined' ? %(EXPORT_NAME)s : {}" % {"EXPORT_NAME": shared.Settings.EXPORT_NAME}
  f.write(src.replace(shared.JS.module_export_name_substitution_pattern, replacement))
  f.close()
  save_intermediate('module_export_name_substitution', 'js')


def generate_html(target, options, js_target, target_basename,
                  asm_target, wasm_binary_target,
                  memfile, optimizer):
  script = ScriptSource()

  logging.debug('generating HTML')
  shell = read_and_preprocess(options.shell_path)
  assert '{{{ SCRIPT }}}' in shell, 'HTML shell must contain  {{{ SCRIPT }}}  , see src/shell.html for an example'
  base_js_target = os.path.basename(js_target)

  asm_mods = []

  if options.proxy_to_worker:
    proxy_worker_filename = (shared.Settings.PROXY_TO_WORKER_FILENAME or target_basename) + '.js'
    worker_js = worker_js_script(proxy_worker_filename)
    script.inline = ('''
  var filename = '%s';
  if ((',' + window.location.search.substr(1) + ',').indexOf(',noProxy,') < 0) {
    console.log('running code in a web worker');
''' % shared.JS.get_subresource_location(proxy_worker_filename)) + worker_js + '''
  } else {
    // note: no support for code mods (PRECISE_F32==2)
    console.log('running code on the main thread');
    var fileBytes = tryParseAsDataURI(filename);
    var script = document.createElement('script');
    if (fileBytes) {
      script.innerHTML = intArrayToString(fileBytes);
    } else {
      script.src = filename;
    }
    document.body.appendChild(script);
  }
'''
  else:
    # Normal code generation path
    script.src = base_js_target

    asm_mods = client_mods.get_mods(shared.Settings,
                                    minified='minifyNames' in optimizer.queue_history,
                                    separate_asm=options.separate_asm)

  if not shared.Settings.SINGLE_FILE:
    if shared.Settings.EMTERPRETIFY_FILE:
      # We need to load the emterpreter file before anything else, it has to be synchronously ready
      script.un_src()
      script.inline = '''
          var emterpretURL = '%s';
          var emterpretXHR = new XMLHttpRequest();
          emterpretXHR.open('GET', emterpretURL, true);
          emterpretXHR.responseType = 'arraybuffer';
          emterpretXHR.onload = function() {
            if (emterpretXHR.status === 200 || emterpretXHR.status === 0) {
              Module.emterpreterFile = emterpretXHR.response;
            } else {
              var emterpretURLBytes = tryParseAsDataURI(emterpretURL);
              if (emterpretURLBytes) {
                Module.emterpreterFile = emterpretURLBytes.buffer;
              }
            }
%s
          };
          emterpretXHR.send(null);
''' % (shared.JS.get_subresource_location(shared.Settings.EMTERPRETIFY_FILE), script.inline)

    if options.memory_init_file and not shared.Settings.MEM_INIT_IN_WASM:
      # start to load the memory init file in the HTML, in parallel with the JS
      script.un_src()
      script.inline = ('''
          var memoryInitializer = '%s';
          memoryInitializer = Module['locateFile'] ? Module['locateFile'](memoryInitializer, '') : memoryInitializer;
          Module['memoryInitializerRequestURL'] = memoryInitializer;
          var meminitXHR = Module['memoryInitializerRequest'] = new XMLHttpRequest();
          meminitXHR.open('GET', memoryInitializer, true);
          meminitXHR.responseType = 'arraybuffer';
          meminitXHR.send(null);
''' % shared.JS.get_subresource_location(memfile)) + script.inline

    # Download .asm.js if --separate-asm was passed in an asm.js build, or if 'asmjs' is one
    # of the wasm run methods.
    if not options.separate_asm or (shared.Settings.WASM and 'asmjs' not in shared.Settings.BINARYEN_METHOD):
      assert len(asm_mods) == 0, 'no --separate-asm means no client code mods are possible'
    else:
      script.un_src()
      if len(asm_mods) == 0:
        # just load the asm, then load the rest
        script.inline = '''
    var filename = '%s';
    var fileBytes = tryParseAsDataURI(filename);
    var script = document.createElement('script');
    if (fileBytes) {
      script.innerHTML = intArrayToString(fileBytes);
    } else {
      script.src = filename;
    }
    script.onload = function() {
      setTimeout(function() {
        %s
      }, 1); // delaying even 1ms is enough to allow compilation memory to be reclaimed
    };
    document.body.appendChild(script);
''' % (shared.JS.get_subresource_location(asm_target), script.inline)
      else:
        # may need to modify the asm code, load it as text, modify, and load asynchronously
        script.inline = '''
    var codeURL = '%s';
    var codeXHR = new XMLHttpRequest();
    codeXHR.open('GET', codeURL, true);
    codeXHR.onload = function() {
      var code;
      if (codeXHR.status === 200 || codeXHR.status === 0) {
        code = codeXHR.responseText;
      } else {
        var codeURLBytes = tryParseAsDataURI(codeURL);
        if (codeURLBytes) {
          code = intArrayToString(codeURLBytes);
        }
      }
      %s
      var blob = new Blob([code], { type: 'text/javascript' });
      codeXHR = null;
      var src = URL.createObjectURL(blob);
      var script = document.createElement('script');
      script.src = src;
      script.onload = function() {
        setTimeout(function() {
          %s
        }, 1); // delaying even 1ms is enough to allow compilation memory to be reclaimed
        URL.revokeObjectURL(script.src);
      };
      document.body.appendChild(script);
    };
    codeXHR.send(null);
''' % (shared.JS.get_subresource_location(asm_target), '\n'.join(asm_mods), script.inline)

    if shared.Settings.WASM and not shared.Settings.BINARYEN_ASYNC_COMPILATION:
      # We need to load the wasm file before anything else, it has to be synchronously ready TODO: optimize
      script.un_src()
      script.inline = '''
          var wasmURL = '%s';
          var wasmXHR = new XMLHttpRequest();
          wasmXHR.open('GET', wasmURL, true);
          wasmXHR.responseType = 'arraybuffer';
          wasmXHR.onload = function() {
            if (wasmXHR.status === 200 || wasmXHR.status === 0) {
              Module.wasmBinary = wasmXHR.response;
            } else {
              var wasmURLBytes = tryParseAsDataURI(wasmURL);
              if (wasmURLBytes) {
                Module.wasmBinary = wasmURLBytes.buffer;
              }
            }
%s
          };
          wasmXHR.send(null);
''' % (shared.JS.get_subresource_location(wasm_binary_target), script.inline)

  # when script.inline isn't empty, add required helper functions such as tryParseAsDataURI
  if script.inline:
    for file in ['arrayUtils.js', 'base64Utils.js', 'URIUtils.js']:
      f = open(shared.path_from_root('src', file), 'r')
      script.inline = f.read() + script.inline
      f.close()

    script.inline = 'var ASSERTIONS = %s;\n%s' % (shared.Settings.ASSERTIONS, script.inline)

  # inline script for SINGLE_FILE output
  if shared.Settings.SINGLE_FILE:
    js_contents = script.inline or ''
    if script.src:
      js = open(js_target, 'r')
      js_contents += js.read()
      js.close()
    shared.try_delete(js_target)
    script.src = None
    script.inline = js_contents

  html = open(target, 'wb')
  html_contents = shell.replace('{{{ SCRIPT }}}', script.replacement())
  html_contents = tools.line_endings.convert_line_endings(html_contents, '\n', options.output_eol)
  html.write(asbytes(html_contents))
  html.close()


def generate_worker_js(target, js_target, target_basename):
  # compiler output is embedded as base64
  if shared.Settings.SINGLE_FILE:
    proxy_worker_filename = shared.JS.get_subresource_location(js_target)

  # compiler output goes in .worker.js file
  else:
    shutil.move(js_target, unsuffixed(js_target) + '.worker.js')
    worker_target_basename = target_basename + '.worker'
    proxy_worker_filename = (shared.Settings.PROXY_TO_WORKER_FILENAME or worker_target_basename) + '.js'

  target_contents = worker_js_script(proxy_worker_filename)
  open(target, 'w').write(target_contents)


def worker_js_script(proxy_worker_filename):
  web_gl_client_src = open(shared.path_from_root('src', 'webGLClient.js')).read()
  idb_store_src = open(shared.path_from_root('src', 'IDBStore.js')).read()
  proxy_client_src = (
    open(shared.path_from_root('src', 'proxyClient.js')).read()
    .replace('{{{ filename }}}', proxy_worker_filename)
    .replace('{{{ IDBStore.js }}}', idb_store_src)
  )

  return web_gl_client_src + '\n' + proxy_client_src


def system_js_libraries_setting_str(libs, lib_dirs, settings_changes, input_files):
  libraries = []

  # Find library files
  for i, lib in libs:
    logging.debug('looking for library "%s"', lib)
    found = False
    for prefix in LIB_PREFIXES:
      for suff in STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS:
        name = prefix + lib + suff
        for lib_dir in lib_dirs:
          path = os.path.join(lib_dir, name)
          if os.path.exists(path):
            logging.debug('found library "%s" at %s', lib, path)
            input_files.append((i, path))
            found = True
            break
        if found:
          break
      if found:
        break
    if not found:
      libraries += shared.Building.path_to_system_js_libraries(lib)

  # Certain linker flags imply some link libraries to be pulled in by default.
  libraries += shared.Building.path_to_system_js_libraries_for_settings(settings_changes)
  return 'SYSTEM_JS_LIBRARIES="' + ','.join(libraries) + '"'


class ScriptSource(object):
  def __init__(self):
    self.src = None # if set, we have a script to load with a src attribute
    self.inline = None # if set, we have the contents of a script to write inline in a script

  def un_src(self):
    """Use this if you want to modify the script and need it to be inline."""
    if self.src is None:
      return
    self.inline = '''
          var script = document.createElement('script');
          script.src = "%s";
          document.body.appendChild(script);
''' % self.src
    self.src = None

  def replacement(self):
    """Returns the script tag to replace the {{{ SCRIPT }}} tag in the target"""
    assert (self.src or self.inline) and not (self.src and self.inline)
    if self.src:
      return '<script async type="text/javascript" src="%s"></script>' % quote(self.src)
    else:
      return '<script>\n%s\n</script>' % self.inline


def is_valid_abspath(options, path_name):
  # Any path that is underneath the emscripten repository root must be ok.
  if shared.path_from_root().replace('\\', '/') in path_name.replace('\\', '/'):
    return True

  def in_directory(root, child):
    # make both path absolute
    root = os.path.realpath(root)
    child = os.path.realpath(child)

    # return true, if the common prefix of both is equal to directory
    # e.g. /a/b/c/d.rst and directory is /a/b, the common prefix is /a/b
    return os.path.commonprefix([root, child]) == root

  for valid_abspath in options.valid_abspaths:
    if in_directory(valid_abspath, path_name):
      return True
  return False


def parse_value(text):
  # Note that using response files can introduce whitespace, if the file
  # has a newline at the end. For that reason, we rstrip() in relevant
  # places here.
  def parse_string_value(text):
    first = text[0]
    if first == "'" or first == '"':
      text = text.rstrip()
      assert text[-1] == text[0] and len(text) > 1, 'unclosed opened quoted string. expected final character to be "%s" and length to be greater than 1 in "%s"' % (text[0], text)
      return text[1:-1]
    else:
      return text

  def parse_string_list_members(text, sep):
    values = text.split(sep)
    result = []
    index = 0
    while True:
      current = values[index].lstrip() # Cannot safely rstrip for cases like: "HERE-> ,"
      assert len(current), "string array should not contain an empty value"
      first = current[0]
      if not(first == "'" or first == '"'):
        result.append(current.rstrip())
      else:
        start = index
        while True: # Continue until closing quote found
          assert index < len(values), "unclosed quoted string. expected final character to be '%s' in '%s'" % (first, values[start])
          new = values[index].rstrip()
          if not len(new) == 0 and new[-1] == first:
            if start == index:
              result.append(current[1:-1])
            else:
              result.append((current + sep + new)[1:-1])
            break
          else:
            current += sep + values[index]
            index += 1

      index += 1
      if index >= len(values):
        break
    return result

  if text[0] == '[':
    text = text.rstrip()
    assert text[-1] == ']', 'unclosed opened string list. expected final character to be "]" in "%s"' % (text)
    inner = text[1:-1]
    if inner.strip() == "":
      return []
    else:
      return parse_string_list_members(inner, ",")
  else:
    try:
      return int(text)
    except ValueError:
      return parse_string_value(text)


def check_bad_eq(arg):
  assert '=' not in arg, 'Invalid parameter (do not use "=" with "--" options)'


def validate_arg_level(level_string, max_level, err_msg, clamp=False):
  try:
    level = int(level_string)
    if clamp:
      if level > max_level:
        logging.warning("optimization level '-O" + level_string + "' is not supported; using '-O" + str(max_level) + "' instead")
        level = max_level
    assert 0 <= level <= max_level
  except:
    raise Exception(err_msg)
  return level


if __name__ == '__main__':
  try:
    sys.exit(run())
  except KeyboardInterrupt:
    logging.warning("KeyboardInterrupt")
    sys.exit(1)
  except shared.FatalError as e:
    logging.error(str(e))
    sys.exit(1)
