#!/usr/bin/env python3
# Copyright 2011 The Emscripten Authors.  All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License.  Both these licenses can be
# found in the LICENSE file.

"""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.
"""


import atexit
import json
import logging
import os
import re
import shlex
import stat
import sys
import time
import base64
from enum import Enum
from subprocess import PIPE

import emscripten
from tools import shared, system_libs
from tools import colored_logger, diagnostics, building
from tools.shared import unsuffixed, unsuffixed_basename, WINDOWS, safe_move, safe_copy
from tools.shared import run_process, asbytes, read_and_preprocess, exit_with_error, DEBUG
from tools.response_file import substitute_response_files
from tools.minimal_runtime_shell import generate_minimal_runtime_html
import tools.line_endings
from tools.toolchain_profiler import ToolchainProfiler
from tools import js_manipulation
from tools import wasm2c
from tools import webassembly
from tools import config

if __name__ == '__main__':
  ToolchainProfiler.record_process_start()

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

logger = logging.getLogger('emcc')

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

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

EXECUTABLE_ENDINGS = ('.wasm', '.html', '.js', '.mjs', '.out', '')
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', '.s')
HEADER_ENDINGS = ('.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH')

# Supported LLD flags which we will pass through to the linker.
SUPPORTED_LINKER_FLAGS = (
    '--start-group', '--end-group',
    '-(', '-)',
    '--whole-archive', '--no-whole-archive',
    '-whole-archive', '-no-whole-archive'
)

# Unsupported LLD flags which we will ignore.
# Maps to true if the flag takes an argument.
UNSUPPORTED_LLD_FLAGS = {
    # macOS-specific linker flag that libtool (ltmain.sh) will if macOS is detected.
    '-bind_at_load': False,
    '-M': False,
    # wasm-ld doesn't support soname or other dynamic linking flags (yet).   Ignore them
    # in order to aid build systems that want to pass these flags.
    '-soname': True,
    '-allow-shlib-undefined': False,
    '-rpath': True,
    '-rpath-link': True,
    '-version-script': True,
}

LIB_PREFIXES = ('', 'lib')

DEFAULT_ASYNCIFY_IMPORTS = [
  'emscripten_sleep', 'emscripten_wget', 'emscripten_wget_data', 'emscripten_idb_load',
  'emscripten_idb_store', 'emscripten_idb_delete', 'emscripten_idb_exists',
  'emscripten_idb_load_blob', 'emscripten_idb_store_blob', 'SDL_Delay',
  'emscripten_scan_registers', 'emscripten_lazy_load_code',
  'emscripten_fiber_swap',
  'wasi_snapshot_preview1.fd_sync', '__wasi_fd_sync', '_emval_await']

# 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'],
}

# Target options
final_js = None

UBSAN_SANITIZERS = {
  'alignment',
  'bool',
  'builtin',
  'bounds',
  'enum',
  'float-cast-overflow',
  'float-divide-by-zero',
  'function',
  'implicit-unsigned-integer-truncation',
  'implicit-signed-integer-truncation',
  'implicit-integer-sign-change',
  'integer-divide-by-zero',
  'nonnull-attribute',
  'null',
  'nullability-arg',
  'nullability-assign',
  'nullability-return',
  'object-size',
  'pointer-overflow',
  'return',
  'returns-nonnull-attribute',
  'shift',
  'signed-integer-overflow',
  'unreachable',
  'unsigned-integer-overflow',
  'vla-bound',
  'vptr',
  'undefined',
  'undefined-trap',
  'implicit-integer-truncation',
  'implicit-integer-arithmetic-value-change',
  'implicit-conversion',
  'integer',
  'nullability',
}


VALID_ENVIRONMENTS = ('web', 'webview', 'worker', 'node', 'shell')


# 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, suffix='js'):
  if not DEBUG:
    return
  if not final_js:
    logger.debug('(not saving intermediate %s because not generating JS)' % name)
    return
  building.save_intermediate(final_js, name + '.' + suffix)


def save_intermediate_with_wasm(name, wasm_binary):
  if not DEBUG:
    return
  save_intermediate(name) # save the js
  building.save_intermediate(wasm_binary, name + '.wasm')


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()
    logger.debug('emcc step "%s" took %.2f seconds', name, now - TimeLogger.last)
    TimeLogger.update()


def base64_encode(b):
  b64 = base64.b64encode(b)
  if type(b64) == bytes:
    return b64.decode('ascii')
  else:
    return b64


class OFormat(Enum):
  WASM = 1
  JS = 2
  MJS = 3
  HTML = 4
  BARE = 5


class EmccOptions(object):
  def __init__(self):
    self.post_link = False
    self.executable = False
    self.compiler_wrapper = None
    self.oformat = None
    self.requested_debug = ''
    self.profiling = False
    self.profiling_funcs = False
    self.tracing = False
    self.emit_symbol_map = False
    self.llvm_opts = None
    self.use_closure_compiler = None
    self.closure_args = []
    self.js_transform = None
    self.pre_js = '' # before all js
    self.post_js = '' # after all js
    self.extern_pre_js = '' # before all js, external to optimized code
    self.extern_post_js = '' # after all js, external to optimized code
    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 = ''
    self.emrun = False
    self.cpu_profiler = False
    self.thread_profiler = False
    self.memory_profiler = False
    self.memory_init_file = None
    self.use_preload_cache = False
    self.use_preload_plugins = False
    self.proxy_to_worker = False
    self.default_object_extension = '.o'
    self.valid_abspaths = []
    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
    self.binaryen_passes = []
    self.no_entry = False
    self.shared = False
    self.relocatable = False


def will_metadce():
  # The metadce JS parsing code does not currently support the JS that gets generated
  # when assertions are enabled.
  if shared.Settings.ASSERTIONS:
    return False
  return shared.Settings.OPT_LEVEL >= 3 or shared.Settings.SHRINK_LEVEL >= 1


def setup_environment_settings():
  # Environment setting based on user input
  environments = shared.Settings.ENVIRONMENT.split(',')
  if any([x for x in environments if x not in VALID_ENVIRONMENTS]):
    exit_with_error('Invalid environment specified in "ENVIRONMENT": ' + shared.Settings.ENVIRONMENT + '. Should be one of: ' + ','.join(VALID_ENVIRONMENTS))

  shared.Settings.ENVIRONMENT_MAY_BE_WEB = not shared.Settings.ENVIRONMENT or 'web' in environments
  shared.Settings.ENVIRONMENT_MAY_BE_WEBVIEW = not shared.Settings.ENVIRONMENT or 'webview' in environments
  shared.Settings.ENVIRONMENT_MAY_BE_NODE = not shared.Settings.ENVIRONMENT or 'node' in environments
  shared.Settings.ENVIRONMENT_MAY_BE_SHELL = not shared.Settings.ENVIRONMENT or 'shell' in environments

  # The worker case also includes Node.js workers when pthreads are
  # enabled and Node.js is one of the supported environments for the build to
  # run on. Node.js workers are detected as a combination of
  # ENVIRONMENT_IS_WORKER and ENVIRONMENT_IS_NODE.
  shared.Settings.ENVIRONMENT_MAY_BE_WORKER = \
      not shared.Settings.ENVIRONMENT or \
      'worker' in environments or \
      (shared.Settings.ENVIRONMENT_MAY_BE_NODE and shared.Settings.USE_PTHREADS)

  if not shared.Settings.ENVIRONMENT_MAY_BE_WORKER and shared.Settings.PROXY_TO_WORKER:
    exit_with_error('If you specify --proxy-to-worker and specify a "-s ENVIRONMENT=" directive, it must include "worker" as a target! (Try e.g. -s ENVIRONMENT=web,worker)')

  if not shared.Settings.ENVIRONMENT_MAY_BE_WORKER and shared.Settings.USE_PTHREADS:
    exit_with_error('When building with multithreading enabled and a "-s ENVIRONMENT=" directive is specified, it must include "worker" as a target! (Try e.g. -s ENVIRONMENT=web,worker)')


def minify_whitespace():
  return shared.Settings.OPT_LEVEL >= 2 and shared.Settings.DEBUG_LEVEL == 0


def embed_memfile():
  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 shared.Settings.GENERATE_SOURCE_MAP)))


def expand_byte_size_suffixes(value):
  """Given a string with KB/MB size suffixes, such as "32MB", computes how
  many bytes that is and returns it as an integer.
  """
  value = value.strip()
  match = re.match(r'^(\d+)\s*([kmgt]?b)?$', value, re.I)
  if not match:
    exit_with_error("invalid byte size `%s`.  Valid suffixes are: kb, mb, gb, tb" % value)
  value, suffix = match.groups()
  value = int(value)
  if suffix:
    size_suffixes = {suffix: 1024 ** i for i, suffix in enumerate(['b', 'kb', 'mb', 'gb', 'tb'])}
    value *= size_suffixes[suffix.lower()]
  return value


def apply_settings(changes):
  """Take a list of settings in form `NAME=VALUE` and apply them to the global
  Settings object.
  """

  def standardize_setting_change(key, value):
    # boolean NO_X settings are aliases for X
    # (note that *non*-boolean setting values have special meanings,
    # and we can't just flip them, so leave them as-is to be
    # handled in a special way later)
    if key.startswith('NO_') and value in ('0', '1'):
      key = key[3:]
      value = str(1 - int(value))
    return key, value

  for change in changes:
    key, value = change.split('=', 1)
    key, value = standardize_setting_change(key, value)

    if key in shared.Settings.internal_settings:
      exit_with_error('%s is an internal setting and cannot be set from command line', key)

    # map legacy settings which have aliases to the new names
    # but keep the original key so errors are correctly reported via the `setattr` below
    user_key = key
    if key in shared.Settings.legacy_settings and key in shared.Settings.alt_names:
      key = shared.Settings.alt_names[key]

    # In those settings fields that represent amount of memory, translate suffixes to multiples of 1024.
    if key in ('TOTAL_STACK', 'INITIAL_MEMORY', 'MEMORY_GROWTH_LINEAR_STEP', 'MEMORY_GROWTH_GEOMETRIC_STEP',
               'GL_MAX_TEMP_BUFFER_SIZE', 'MAXIMUM_MEMORY', 'DEFAULT_PTHREAD_STACK_SIZE'):
      value = str(expand_byte_size_suffixes(value))

    if value and value[0] == '@':
      filename = value[1:]
      if not os.path.exists(filename):
        exit_with_error('%s: file not found parsing argument: %s' % (filename, change))
      value = open(filename).read()
    else:
      value = value.replace('\\', '\\\\')
    try:
      value = parse_value(value)
    except Exception as e:
      exit_with_error('a problem occurred in evaluating the content after a "-s", specifically "%s": %s', change, str(e))

    # Do some basic type checking by comparing to the existing settings.
    # Sadly we can't do this generically in the SettingsManager since there are settings
    # that so change types internally over time.
    existing = getattr(shared.Settings, user_key, None)
    if existing is not None:
      # We only currently worry about lists vs non-lists.
      if (type(existing) == list) != (type(value) == list):
        exit_with_error('setting `%s` expects `%s` but got `%s`' % (user_key, type(existing), type(value)))
    setattr(shared.Settings, user_key, value)

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

    # TODO(sbc): Remove this legacy way.
    if key == 'WASM_OBJECT_FILES':
      shared.Settings.LTO = 0 if value else 'full'


def find_output_arg(args):
  """Find and remove any -o arguments.  The final one takes precedence.
  Return the final -o target along with the remaining (non-o) arguments.
  """
  outargs = []
  specified_target = None

  arg_count = len(args)
  i = 0

  while i < arg_count:
    arg = args[i]

    if arg == '-o':
      if i != arg_count - 1:
        specified_target = args[i + 1]
      i += 2
      continue

    if arg.startswith('-o'):
      specified_target = arg[2:]
      i += 1
      continue

    outargs.append(arg)

    if arg == '-mllvm' and i != arg_count - 1:
      # Explicitly skip over -mllvm arguments and their values because their
      # values could potentially start with -o and be confused for output file
      # specifiers.
      outargs.append(args[i + 1])
      i += 2
    else:
      i += 1

  return specified_target, outargs


def is_ar_file_with_missing_index(archive_file):
  # We parse the archive header outselves because llvm-nm --print-armap is slower and less
  # reliable.
  # See: https://github.com/emscripten-core/emscripten/issues/10195
  archive_header = b'!<arch>\n'
  file_header_size = 60

  with open(archive_file, 'rb') as f:
    header = f.read(len(archive_header))
    if header != archive_header:
      # This is not even an ar file
      return False
    file_header = f.read(file_header_size)
    if len(file_header) != file_header_size:
      # We don't have any file entires at all so we don't consider the index missing
      return False

  name = file_header[:16].strip()
  # If '/' is the name of the first file we have an index
  return name != b'/'


def ensure_archive_index(archive_file):
  # Fastcomp linking works without archive indexes.
  if not shared.Settings.AUTO_ARCHIVE_INDEXES:
    return
  if is_ar_file_with_missing_index(archive_file):
    diagnostics.warning('emcc', '%s: archive is missing an index; Use emar when creating libraries to ensure an index is created', archive_file)
    diagnostics.warning('emcc', '%s: adding index', archive_file)
    run_process([shared.LLVM_RANLIB, archive_file])


def get_all_js_syms(temp_files):
  # Runs the js compiler to generate a list of all symbols available in the JS
  # libraries.  This must be done separately for each linker invokation since the
  # list of symbols depends on what settings are used.
  # TODO(sbc): Find a way to optimize this.  Potentially we could add a super-set
  # mode of the js compiler that would generate a list of all possible symbols
  # that could be checked in.
  old_full = shared.Settings.INCLUDE_FULL_LIBRARY
  try:
    # Temporarily define INCLUDE_FULL_LIBRARY since we want a full list
    # of all available JS library functions.
    shared.Settings.INCLUDE_FULL_LIBRARY = True
    shared.Settings.ONLY_CALC_JS_SYMBOLS = True
    emscripten.generate_struct_info()
    glue, forwarded_data = emscripten.compile_settings(temp_files)
    forwarded_json = json.loads(forwarded_data)
    library_fns = forwarded_json['Functions']['libraryFunctions']
    library_fns_list = []
    for name in library_fns:
      if shared.is_c_symbol(name):
        name = shared.demangle_c_symbol_name(name)
        library_fns_list.append(name)
  finally:
    shared.Settings.ONLY_CALC_JS_SYMBOLS = False
    shared.Settings.INCLUDE_FULL_LIBRARY = old_full

  return library_fns_list


def filter_link_flags(flags, using_lld):
  def is_supported(f):
    if using_lld:
      for flag, takes_arg in UNSUPPORTED_LLD_FLAGS.items():
        # lld allows various flags to have either a single -foo or double --foo
        if f.startswith(flag) or f.startswith('-' + flag):
          diagnostics.warning('linkflags', 'ignoring unsupported linker flag: `%s`', f)
          return False, takes_arg
      return True, False
    else:
      if f in SUPPORTED_LINKER_FLAGS:
        return True, False
      # Silently ignore -l/-L flags when not using lld.  If using lld allow
      # them to pass through the linker
      if f.startswith('-l') or f.startswith('-L'):
        return False, False
      diagnostics.warning('linkflags', 'ignoring unsupported linker flag: `%s`', f)
      return False, False

  results = []
  skip_next = False
  for f in flags:
    if skip_next:
      skip_next = False
      continue
    keep, skip_next = is_supported(f[1])
    if keep:
      results.append(f)

  return results


def fix_windows_newlines(text):
  # Avoid duplicating \r\n to \r\r\n when writing out text.
  if WINDOWS:
    text = text.replace('\r\n', '\n')
  return text


def cxx_to_c_compiler(cxx):
  # Convert C++ compiler name into C compiler name
  dirname, basename = os.path.split(cxx)
  basename = basename.replace('clang++', 'clang').replace('g++', 'gcc').replace('em++', 'emcc')
  return os.path.join(dirname, basename)


def backend_binaryen_passes():
  # wasm backend output can benefit from the binaryen optimizer (in asm2wasm,
  # we run the optimizer during asm2wasm itself). use it, if not overridden.

  # run the binaryen optimizer in -O2+. in -O0 we don't need it obviously, while
  # in -O1 we don't run it as the LLVM optimizer has been run, and it does the
  # great majority of the work; not running the binaryen optimizer in that case
  # keeps -O1 mostly-optimized while compiling quickly and without rewriting
  # DWARF etc.
  run_binaryen_optimizer = shared.Settings.OPT_LEVEL >= 2

  passes = []
  # safe heap must run before post-emscripten, so post-emscripten can apply the sbrk ptr
  if shared.Settings.SAFE_HEAP:
    passes += ['--safe-heap']
  if run_binaryen_optimizer:
    passes += ['--post-emscripten']
    if not shared.Settings.EXIT_RUNTIME:
      passes += ['--no-exit-runtime']
  if run_binaryen_optimizer:
    passes += [building.opt_level_to_str(shared.Settings.OPT_LEVEL, shared.Settings.SHRINK_LEVEL)]
  elif shared.Settings.STANDALONE_WASM:
    # even if not optimizing, make an effort to remove all unused imports and
    # exports, to make the wasm as standalone as possible
    passes += ['--remove-unused-module-elements']
  # when optimizing, use the fact that low memory is never used (1024 is a
  # hardcoded value in the binaryen pass)
  if run_binaryen_optimizer and shared.Settings.GLOBAL_BASE >= 1024:
    passes += ['--low-memory-unused']
  if shared.Settings.AUTODEBUG:
    # adding '--flatten' here may make these even more effective
    passes += ['--instrument-locals']
    passes += ['--log-execution']
    passes += ['--instrument-memory']
    if shared.Settings.LEGALIZE_JS_FFI:
      # legalize it again now, as the instrumentation may need it
      passes += ['--legalize-js-interface']
  if shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
    # note that this pass must run before asyncify, as if it runs afterwards we only
    # generate the  byn$fpcast_emu  functions after asyncify runs, and so we wouldn't
    # be able to further process them.
    passes += ['--fpcast-emu']
  if shared.Settings.ASYNCIFY:
    passes += ['--asyncify']
    if shared.Settings.ASSERTIONS:
      passes += ['--pass-arg=asyncify-asserts']
    if shared.Settings.ASYNCIFY_ADVISE:
      passes += ['--pass-arg=asyncify-verbose']
    if shared.Settings.ASYNCIFY_IGNORE_INDIRECT:
      passes += ['--pass-arg=asyncify-ignore-indirect']
    else:
      # if we are not ignoring indirect calls, then we must treat invoke_* as if
      # they are indirect calls, since that is what they do - we can't see their
      # targets statically.
      shared.Settings.ASYNCIFY_IMPORTS += ['invoke_*']
    # with pthreads we may call main through the __call_main mechanism, which can
    # therefore reach anything in the program, so mark it as possibly causing a
    # sleep (the asyncify analysis doesn't look through JS, just wasm, so it can't
    # see what it itself calls)
    if shared.Settings.USE_PTHREADS:
      shared.Settings.ASYNCIFY_IMPORTS += ['__call_main']
    # add the default imports
    shared.Settings.ASYNCIFY_IMPORTS += DEFAULT_ASYNCIFY_IMPORTS

    # return the full import name, including module. The name may
    # already have a module prefix; if not, we assume it is "env".
    def get_full_import_name(name):
      if '.' in name:
        return name
      return 'env.' + name

    shared.Settings.ASYNCIFY_IMPORTS = [get_full_import_name(i) for i in shared.Settings.ASYNCIFY_IMPORTS]

    passes += ['--pass-arg=asyncify-imports@%s' % ','.join(shared.Settings.ASYNCIFY_IMPORTS)]

    # shell escaping can be confusing; try to emit useful warnings
    def check_human_readable_list(items):
      for item in items:
        if item.count('(') != item.count(')'):
          logger.warning('''emcc: ASYNCIFY list contains an item without balanced parentheses ("(", ")"):''')
          logger.warning('''   ''' + item)
          logger.warning('''This may indicate improper escaping that led to splitting inside your names.''')
          logger.warning('''Try to quote the entire argument, like this: -s 'ASYNCIFY_ONLY=["foo(int, char)", "bar"]' ''')
          break

    if shared.Settings.ASYNCIFY_REMOVE:
      check_human_readable_list(shared.Settings.ASYNCIFY_REMOVE)
      passes += ['--pass-arg=asyncify-removelist@%s' % ','.join(shared.Settings.ASYNCIFY_REMOVE)]
    if shared.Settings.ASYNCIFY_ADD:
      check_human_readable_list(shared.Settings.ASYNCIFY_ADD)
      passes += ['--pass-arg=asyncify-addlist@%s' % ','.join(shared.Settings.ASYNCIFY_ADD)]
    if shared.Settings.ASYNCIFY_ONLY:
      check_human_readable_list(shared.Settings.ASYNCIFY_ONLY)
      passes += ['--pass-arg=asyncify-onlylist@%s' % ','.join(shared.Settings.ASYNCIFY_ONLY)]
  if shared.Settings.BINARYEN_IGNORE_IMPLICIT_TRAPS:
    passes += ['--ignore-implicit-traps']
  # normally we can assume the memory, if imported, has not been modified
  # beforehand (in fact, in most cases the memory is not even imported anyhow,
  # but it is still safe to pass the flag), and is therefore filled with zeros.
  # the one exception is dynamic linking of a side module: the main module is ok
  # as it is loaded first, but the side module may be assigned memory that was
  # previously used.
  if run_binaryen_optimizer and not shared.Settings.SIDE_MODULE:
    passes += ['--zero-filled-memory']

  if shared.Settings.BINARYEN_EXTRA_PASSES:
    # BINARYEN_EXTRA_PASSES is comma-separated, and we support both '-'-prefixed and
    # unprefixed pass names
    extras = shared.Settings.BINARYEN_EXTRA_PASSES.split(',')
    passes += [('--' + p) if p[0] != '-' else p for p in extras if p]

  return passes


def make_js_executable(script):
  src = open(script).read()
  cmd = shared.shlex_join(config.JS_ENGINE)
  if not os.path.isabs(config.JS_ENGINE[0]):
    # TODO: use whereis etc. And how about non-*NIX?
    cmd = '/usr/bin/env -S ' + cmd
  logger.debug('adding `#!` to JavaScript file: %s' % cmd)
  # add shebang
  with open(script, 'w') as f:
    f.write('#!%s\n' % cmd)
    f.write(src)
  try:
    os.chmod(script, stat.S_IMODE(os.stat(script).st_mode) | stat.S_IXUSR) # make executable
  except OSError:
    pass # can fail if e.g. writing the executable to /dev/null


def do_replace(input_, pattern, replacement):
  if pattern not in input_:
    exit_with_error('expected to find pattern in input JS: %s' % pattern)
  return input_.replace(pattern, replacement)


def is_dash_s_for_emcc(args, i):
  # -s OPT=VALUE or -s OPT or -sOPT are all interpreted as emscripten flags.
  # -s by itself is a linker option (alias for --strip-all)
  if args[i] == '-s':
    if len(args) <= i + 1:
      return False
    arg = args[i + 1]
  else:
    arg = args[i][2:]
  return arg.split('=')[0].isupper()


def parse_s_args(args):
  settings_changes = []
  for i in range(len(args)):
    if args[i].startswith('-s'):
      if is_dash_s_for_emcc(args, i):
        if args[i] == '-s':
          key = args[i + 1]
          args[i + 1] = ''
        else:
          key = args[i][2:]
        args[i] = ''

        # If not = is specified default to 1
        if '=' not in key:
          key += '=1'

        # Special handling of browser version targets. A version -1 means that the specific version
        # is not supported at all. Replace those with INT32_MAX to make it possible to compare e.g.
        # #if MIN_FIREFOX_VERSION < 68
        if re.match(r'MIN_.*_VERSION(=.*)?', key):
          try:
            if int(key.split('=')[1]) < 0:
              key = key.split('=')[0] + '=0x7FFFFFFF'
          except Exception:
            pass

        settings_changes.append(key)

  newargs = [a for a in args if a]
  return (settings_changes, newargs)


def calc_cflags(options):
  # Flags we pass to the compiler when building C/C++ code
  # We add these to the user's flags (newargs), but not when building .s or .S assembly files
  cflags = []

  if options.tracing:
    cflags.append('-D__EMSCRIPTEN_TRACING__=1')

  if shared.Settings.USE_PTHREADS:
    cflags.append('-D__EMSCRIPTEN_PTHREADS__=1')

  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.
    cflags.append('-DEMSCRIPTEN')

  # if exception catching is disabled, we can prevent that code from being
  # generated in the frontend
  if shared.Settings.DISABLE_EXCEPTION_CATCHING == 1 and not shared.Settings.EXCEPTION_HANDLING:
    cflags.append('-fignore-exceptions')

  if shared.Settings.INLINING_LIMIT:
    cflags.append('-fno-inline-functions')

  if shared.Settings.RELOCATABLE:
    cflags.append('-fPIC')
    cflags.append('-fvisibility=default')

  if shared.Settings.LTO:
    cflags.append('-flto=' + shared.Settings.LTO)
  else:
    # With LTO mode these args get passed instead
    # at link time when the backend runs.
    for a in building.llvm_backend_args():
      cflags += ['-mllvm', a]

  return cflags


def get_file_suffix(filename):
  """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'"""
  if filename in SPECIAL_ENDINGLESS_FILENAMES:
    return filename
  while filename:
    filename, suffix = os.path.splitext(filename)
    if not suffix[1:].isdigit():
      return suffix
  return ''


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


run_via_emxx = False


#
# Main run() function
#
def run(args):
  target = None

  # Additional compiler flags that we treat as if they were passed to us on the
  # commandline
  EMCC_CFLAGS = os.environ.get('EMCC_CFLAGS')
  if DEBUG:
    cmd = shared.shlex_join(args)
    if EMCC_CFLAGS:
      cmd += ' + ' + EMCC_CFLAGS
    logger.warning('invocation: ' + cmd + '  (in ' + os.getcwd() + ')')
  if EMCC_CFLAGS:
    args.extend(shlex.split(EMCC_CFLAGS))

  # Strip args[0] (program name)
  args = args[1:]

  misc_temp_files = shared.configuration.get_temp_files()

  # Handle some global flags

  # read response files very early on
  try:
    args = substitute_response_files(args)
  except IOError as e:
    exit_with_error(e)

  if '--help' in args:
    # Documentation for emcc and its options must be updated in:
    #    site/source/docs/tools_reference/emcc.rst
    # This then gets built (via: `make -C site text`) to:
    #    site/build/text/docs/tools_reference/emcc.txt
    # This then needs to be copied to its final home in docs/emcc.txt from where
    # we read it here.  We have CI rules that ensure its always up-to-date.
    with open(shared.path_from_root('docs', 'emcc.txt'), 'r') as f:
      print(f.read())

    print('''
------------------------------------------------------------------

emcc: supported targets: llvm bitcode, javascript, NOT elf
(autoconf likes to see elf above to enable shared object support)
''')
    return 0

  if '--version' in args:
    # if the emscripten folder is not a git repo, don't run git show - that can
    # look up and find the revision in a parent directory that is a git repo
    revision = ''
    if os.path.exists(shared.path_from_root('.git')):
      revision = run_process(['git', 'rev-parse', 'HEAD'], stdout=PIPE, stderr=PIPE, cwd=shared.path_from_root()).stdout.strip()
    elif os.path.exists(shared.path_from_root('emscripten-revision.txt')):
      revision = open(shared.path_from_root('emscripten-revision.txt')).read().strip()
    if revision:
      revision = ' (%s)' % revision
    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

  if run_via_emxx:
    clang = shared.CLANG_CXX
  else:
    clang = shared.CLANG_CC

  if len(args) == 1 and args[0] == '-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, file=sys.stderr)
    code = shared.check_call([clang, '-v'], check=False).returncode
    shared.check_sanity(force=True)
    return code

  shared.check_sanity(force=DEBUG)

  if '-dumpmachine' in args:
    print(shared.get_llvm_target())
    return 0

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

  if '--cflags' in args:
    # fake running the command, to see the full args we pass to clang
    args = [x for x in args if x != '--cflags']
    with misc_temp_files.get_file(suffix='.o') as temp_target:
      input_file = 'hello_world.c'
      cmd = [shared.PYTHON, sys.argv[0], shared.path_from_root('tests', input_file), '-v', '-c', '-o', temp_target] + args
      proc = run_process(cmd, stderr=PIPE, check=False)
      if proc.returncode != 0:
        print(proc.stderr)
        exit_with_error('error getting cflags')
      lines = [x for x in proc.stderr.splitlines() if clang in x and input_file in x]
      parts = shlex.split(lines[0].replace('\\', '\\\\'))
      parts = [x for x in parts if x not in ['-c', '-o', '-v', '-emit-llvm'] and input_file not in x and temp_target not in x]
      print(shared.shlex_join(parts[1:]))
    return 0

  def get_language_mode(args):
    return_next = False
    for item in args:
      if return_next:
        return item
      if item == '-x':
        return_next = True
        continue
      if item.startswith('-x'):
        return item[2:]
    return ''

  language_mode = get_language_mode(args)

  EMMAKEN_CFLAGS = os.environ.get('EMMAKEN_CFLAGS')
  if EMMAKEN_CFLAGS:
    args += 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] + shared.suffix(name)

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

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

  def need_llvm_debug_info():
    return shared.Settings.DEBUG_LEVEL >= 3

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

    newargs = list(args)

    # 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 = diagnostics.capture_warnings(newargs)

    if not config.config_file:
      diagnostics.warning('deprecated', 'Specifying EM_CONFIG as a python literal is deprecated. Please use a file instead.')

    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] = ''

    options, settings_changes, user_js_defines, newargs = parse_args(newargs)

    if options.post_link or options.oformat == OFormat.BARE:
      diagnostics.warning('experimental', '--oformat=base/--post-link are experimental and subject to change.')

    if '-print-search-dirs' in newargs:
      return run_process([clang, '-print-search-dirs'], check=False).returncode

    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.EXIT_RUNTIME = 1

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

    if options.memory_profiler:
      shared.Settings.MEMORYPROFILER = 1

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

    if options.llvm_opts is None:
      options.llvm_opts = LLVM_OPT_LEVEL[shared.Settings.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 = shared.Settings.OPT_LEVEL >= 2

    # TODO: support source maps with js_transform
    if options.js_transform and shared.Settings.GENERATE_SOURCE_MAP:
      logger.warning('disabling source maps because a js transform is being done')
      shared.Settings.DEBUG_LEVEL = 3

    explicit_settings_changes, newargs = parse_s_args(newargs)
    settings_changes += explicit_settings_changes

    settings_key_changes = {}
    for s in settings_changes:
      key, value = s.split('=', 1)
      settings_key_changes[key] = value

    # 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 = []

    has_header_inputs = False
    lib_dirs = []

    has_dash_c = '-c' in newargs
    has_dash_S = '-S' in newargs
    has_dash_E = '-E' in newargs

    compile_only = has_dash_c or has_dash_S or has_dash_E

    def add_link_flag(i, f):
      if f.startswith('-l'):
        libs.append((i, f[2:]))
      if f.startswith('-L'):
        lib_dirs.append(f[2:])

      link_flags.append((i, f))

    # find input files with 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
    skip = False
    for i in range(len(newargs)):
      if skip:
        skip = False
        continue

      arg = newargs[i]
      if arg in ('-MT', '-MF', '-MJ', '-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',
                 '-Xlinker', '-Xclang'):
        skip = True

      if not arg.startswith('-'):
        # os.devnul should always be reported as existing but there is bug in windows
        # python before 3.8:
        # https://bugs.python.org/issue1311
        if not os.path.exists(arg) and arg != os.devnull:
          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)
        file_suffix = get_file_suffix(arg)
        if file_suffix in SOURCE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS or building.is_ar(arg):
          # we already removed -o <target>, so all these should be inputs
          newargs[i] = ''
          if file_suffix in SOURCE_ENDINGS or (has_dash_c and file_suffix == '.bc'):
            input_files.append((i, arg))
          elif file_suffix in HEADER_ENDINGS:
            input_files.append((i, arg))
            has_header_inputs = True
          elif file_suffix in ASSEMBLY_ENDINGS or building.is_bitcode(arg) or building.is_ar(arg):
            input_files.append((i, arg))
          elif building.is_wasm(arg):
            input_files.append((i, arg))
          elif file_suffix in (STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS):
            # if it's not, and it's a library, just add it to libs to find later
            libname = unsuffixed_basename(arg)
            for prefix in LIB_PREFIXES:
              if not prefix:
                continue
              if libname.startswith(prefix):
                libname = libname[len(prefix):]
                break
            libs.append((i, libname))
        elif file_suffix in STATICLIB_ENDINGS:
          if not building.is_ar(arg):
            if 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 .bc or .o.'
            else:
              message = arg + ': Unknown format, not a static library!'
            exit_with_error(message)
        else:
          newargs[i] = ''
          input_files.append((i, arg))
      elif arg.startswith('-L'):
        add_link_flag(i, arg)
        newargs[i] = ''
      elif arg.startswith('-l'):
        add_link_flag(i, arg)
        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):
          add_link_flag(i + float(flag_index) / len(link_flags_to_add), flag)
        newargs[i] = ''
      elif arg == '-Xlinker':
        add_link_flag(i + 1, newargs[i + 1])
        newargs[i] = ''
        newargs[i + 1] = ''
      elif arg == '-s':
        # -s and some other compiler flags are normally passed onto the linker
        # TODO(sbc): Pass this and other flags through when using lld
        # link_flags.append((i, arg))
        newargs[i] = ''
      elif arg == '-':
        input_files.append((i, arg))
        newargs[i] = ''
    newargs = [a for a in newargs if a]

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

    strict_cmdline = settings_key_changes.get('STRICT')
    if strict_cmdline:
      shared.Settings.STRICT = int(strict_cmdline)

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

    # For users that opt out of WARN_ON_UNDEFINED_SYMBOLS we assume they also
    # want to opt out of ERROR_ON_UNDEFINED_SYMBOLS.
    if 'WARN_ON_UNDEFINED_SYMBOLS=0' in settings_changes:
      shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS = 0

    if shared.Settings.MINIMAL_RUNTIME or 'MINIMAL_RUNTIME=1' in settings_changes or 'MINIMAL_RUNTIME=2' in settings_changes:
      # Remove the default exported functions 'malloc', 'free', etc. those should only be linked in if used
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []

    # Apply -s settings in newargs here (after optimization levels, so they can override them)
    apply_settings(settings_changes)

    # Check if a target is specified on the command line
    specified_target, args = find_output_arg(args)

    if os.environ.get('EMMAKEN_JUST_CONFIGURE') or 'conftest.c' in args:
      # configure tests want a more shell-like style, where we emit return codes on exit()
      shared.Settings.EXIT_RUNTIME = 1
      # use node.js raw filesystem access, to behave just like a native executable
      shared.Settings.NODERAWFS = 1
      # Add `#!` line to output JS and make it executable.
      options.executable = True
      # Autoconf expects the executable output file to be called `a.out`
      default_target_name = 'a.out'
    elif shared.Settings.SIDE_MODULE:
      default_target_name = 'a.out.wasm'
    else:
      default_target_name = 'a.out.js'

    # specified_target is the user-specified one, target is what we will generate
    if specified_target:
      target = specified_target
      # check for the existence of the output directory now, to avoid having
      # to do so repeatedly when each of the various output files (.mem, .wasm,
      # etc) are written. This gives a more useful error message than the
      # IOError and python backtrace that users would otherwise see.
      dirname = os.path.dirname(target)
      if dirname and not os.path.isdir(dirname):
        exit_with_error("specified output file (%s) is in a directory that does not exist" % target)
    else:
      target = default_target_name

    shared.Settings.TARGET_BASENAME = target_basename = unsuffixed_basename(target)

    final_suffix = get_file_suffix(target)

    if has_dash_c or has_dash_S or has_dash_E or '-M' in newargs or '-MM' in newargs:
      if has_dash_c:
        if '-emit-llvm' in newargs:
          options.default_object_extension = '.bc'
      elif has_dash_S:
        if '-emit-llvm' in newargs:
          options.default_object_extension = '.ll'
        else:
          options.default_object_extension = '.s'
      elif '-M' in newargs or '-MM' in newargs:
        options.default_object_extension = '.mout' # not bitcode, not js; but just dependency rule of the input file

      if specified_target:
        if len(input_files) > 1:
          exit_with_error('cannot specify -o with -c/-S/-E/-M and multiple source files')
      else:
        target = target_basename + options.default_object_extension

    # If no output format was sepecific we try to imply the format based on
    # the output filename extension.
    if not options.oformat:
      if shared.Settings.SIDE_MODULE or final_suffix == '.wasm':
        options.oformat = OFormat.WASM
      elif final_suffix == '.mjs':
        options.oformat = OFormat.MJS
      elif final_suffix == '.html':
        options.oformat = OFormat.HTML
      else:
        options.oformat = OFormat.JS

    if options.oformat == OFormat.MJS:
      shared.Settings.EXPORT_ES6 = 1
      shared.Settings.MODULARIZE = 1

    if options.oformat in (OFormat.WASM, OFormat.BARE):
      # If the user asks directly for a wasm file then this *is* the target
      wasm_target = target
    else:
      # Otherwise the wasm file is produced alongside the final target.
      wasm_target = unsuffixed(target) + '.wasm'

    # Apply user -jsD settings
    for s in user_js_defines:
      shared.Settings.attrs[s[0]] = s[1]

    shared.verify_settings()

    if (options.oformat == OFormat.WASM or shared.Settings.PURE_WASI) and not shared.Settings.SIDE_MODULE:
      # if the output is just a wasm file, it will normally be a standalone one,
      # as there is no JS. an exception are side modules, as we can't tell at
      # compile time whether JS will be involved or not - the main module may
      # have JS, and the side module is expected to link against that.
      # we also do not support standalone mode in fastcomp.
      shared.Settings.STANDALONE_WASM = 1

    if shared.Settings.WASM2C:
      # wasm2c only makes sense with standalone wasm - there will be no JS,
      # just wasm and then C
      shared.Settings.STANDALONE_WASM = 1
      # wasm2c doesn't need any special handling of i64, we have proper i64
      # handling on the FFI boundary, which is exactly like the case of JS with
      # BigInt support
      shared.Settings.WASM_BIGINT = 1

    if options.no_entry:
      shared.Settings.EXPECT_MAIN = 0
    elif shared.Settings.STANDALONE_WASM:
      if '_main' in shared.Settings.EXPORTED_FUNCTIONS:
        # TODO(sbc): Make this into a warning?
        logger.debug('including `_main` in EXPORTED_FUNCTIONS is not necessary in standalone mode')
    else:
      # In normal non-standalone mode we have special handling of `_main` in EXPORTED_FUNCTIONS.
      # 1. If the user specifies exports, but doesn't include `_main` we assume they want to build a
      #    reactor.
      # 2. If the user doesn't export anything we default to exporting `_main` (unless `--no-entry`
      #    is specified (see above).
      if 'EXPORTED_FUNCTIONS' in settings_key_changes:
        if '_main' not in shared.Settings.USER_EXPORTED_FUNCTIONS:
          shared.Settings.EXPECT_MAIN = 0
      else:
        assert not shared.Settings.EXPORTED_FUNCTIONS
        shared.Settings.EXPORTED_FUNCTIONS = ['_main']

    if shared.Settings.STANDALONE_WASM:
      # In STANDALONE_WASM mode we either build a command or a reactor.
      # See https://github.com/WebAssembly/WASI/blob/master/design/application-abi.md
      # For a command we always want EXIT_RUNTIME=1
      # For a reactor we always want EXIT_RUNTIME=0
      if 'EXIT_RUNTIME' in settings_key_changes:
        exit_with_error('Explictly setting EXIT_RUNTIME not compatible with STANDALONE_WASM.  EXIT_RUNTIME will always be True for programs (with a main function) and False for reactors (not main function).')
      shared.Settings.EXIT_RUNTIME = shared.Settings.EXPECT_MAIN

    def filter_out_dynamic_libs(inputs):
      # 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 final_suffix not in EXECUTABLE_ENDINGS or options.ignore_dynamic_linking:
        def check(input_file):
          if get_file_suffix(input_file) in DYNAMICLIB_ENDINGS:
            if not options.ignore_dynamic_linking:
              diagnostics.warning('emcc', '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
        return [f for f in inputs if check(f[1])]
      return inputs

    def filter_out_duplicate_dynamic_libs(inputs):
      # Filter out duplicate shared libraries.
      # See test_core.py:test_redundant_link
      seen = set()
      rtn = []
      for i in inputs:
        if get_file_suffix(i[1]) in DYNAMICLIB_ENDINGS and os.path.exists(i[1]):
          abspath = os.path.abspath(i[1])
          if abspath in seen:
            continue
          seen.add(abspath)
        rtn.append(i)
      return rtn

    input_files = filter_out_dynamic_libs(input_files)
    input_files = filter_out_duplicate_dynamic_libs(input_files)

    if not input_files and not link_flags:
      exit_with_error('no input files')

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

    # -s ASSERTIONS=1 implies basic stack overflow checks, and ASSERTIONS=2
    # implies full stack overflow checks (unless the user specifically set
    # something else)
    if shared.Settings.ASSERTIONS and 'STACK_OVERFLOW_CHECK' not in settings_key_changes:
      shared.Settings.STACK_OVERFLOW_CHECK = max(shared.Settings.ASSERTIONS, shared.Settings.STACK_OVERFLOW_CHECK)

    if shared.Settings.LLD_REPORT_UNDEFINED or shared.Settings.STANDALONE_WASM:
      # Reporting undefined symbols at wasm-ld time requires us to know if we have a `main` function
      # or not, as does standalone wasm mode.
      # TODO(sbc): Remove this once this becomes the default
      shared.Settings.IGNORE_MISSING_MAIN = 0

    if shared.Settings.STRICT:
      shared.Settings.STRICT_JS = 1
      shared.Settings.AUTO_JS_LIBRARIES = 0
      shared.Settings.AUTO_ARCHIVE_INDEXES = 0
      shared.Settings.IGNORE_MISSING_MAIN = 0
      shared.Settings.DEFAULT_TO_CXX = 0

    if os.environ.get('EMCC_AUTODEBUG'):
      shared.Settings.AUTODEBUG = 1

    # Use settings

    if shared.Settings.DEBUG_LEVEL > 1 and options.use_closure_compiler:
      diagnostics.warning('emcc', 'disabling closure because debug info was requested')
      options.use_closure_compiler = False

    if shared.Settings.WASM == 2 and shared.Settings.SINGLE_FILE:
      exit_with_error('cannot have both WASM=2 and SINGLE_FILE enabled at the same time')

    if shared.Settings.SEPARATE_DWARF and shared.Settings.WASM2JS:
      exit_with_error('cannot have both SEPARATE_DWARF and WASM2JS at the same time (as there is no wasm file)')

    if shared.Settings.MINIMAL_RUNTIME_STREAMING_WASM_COMPILATION and shared.Settings.MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION:
      exit_with_error('MINIMAL_RUNTIME_STREAMING_WASM_COMPILATION and MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION are mutually exclusive!')

    if options.emrun:
      if shared.Settings.MINIMAL_RUNTIME:
        exit_with_error('--emrun is not compatible with -s MINIMAL_RUNTIME=1')
      shared.Settings.EXPORTED_RUNTIME_METHODS.append('addOnExit')

    if options.use_closure_compiler:
      shared.Settings.USE_CLOSURE_COMPILER = options.use_closure_compiler

    if shared.Settings.CLOSURE_WARNINGS not in ['quiet', 'warn', 'error']:
      exit_with_error('Invalid option -s CLOSURE_WARNINGS=%s specified! Allowed values are "quiet", "warn" or "error".' % shared.Settings.CLOSURE_WARNINGS)

    if shared.Settings.MAIN_MODULE:
      assert not shared.Settings.SIDE_MODULE
      if shared.Settings.MAIN_MODULE == 1:
        shared.Settings.INCLUDE_FULL_LIBRARY = 1
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$preloadDylibs']
    elif shared.Settings.SIDE_MODULE:
      assert not shared.Settings.MAIN_MODULE
      # memory init file is not supported with side modules, must be executable synchronously (for dlopen)
      options.memory_init_file = False

    if shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE:
      if shared.Settings.MAIN_MODULE == 1 or shared.Settings.SIDE_MODULE == 1:
        shared.Settings.LINKABLE = 1
        shared.Settings.EXPORT_ALL = 1
      shared.Settings.RELOCATABLE = 1

    # various settings require sbrk() access
    if shared.Settings.DETERMINISTIC or \
       shared.Settings.EMSCRIPTEN_TRACING or \
       shared.Settings.MALLOC == 'emmalloc' or \
       shared.Settings.SAFE_HEAP or \
       shared.Settings.MEMORYPROFILER:
      shared.Settings.EXPORTED_FUNCTIONS += ['_sbrk']

    if shared.Settings.MEMORYPROFILER:
      shared.Settings.EXPORTED_FUNCTIONS += ['___heap_base',
                                             '_emscripten_stack_get_base',
                                             '_emscripten_stack_get_end',
                                             '_emscripten_stack_get_current']

    if shared.Settings.ASYNCIFY:
      # See: https://github.com/emscripten-core/emscripten/issues/12065
      # See: https://github.com/emscripten-core/emscripten/issues/12066
      shared.Settings.USE_LEGACY_DYNCALLS = 1
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getDynCaller']
      shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_base',
                                             '_emscripten_stack_get_end',
                                             '_emscripten_stack_set_limits']

    # Reconfigure the cache now that settings have been applied. Some settings
    # such as LTO and SIDE_MODULE/MAIN_MODULE effect which cache directory we use.
    shared.reconfigure_cache()

    if not compile_only and not options.post_link:
      ldflags = shared.emsdk_ldflags(newargs)
      for f in ldflags:
        newargs.append(f)
        add_link_flag(len(newargs), f)

    # SSEx is implemented on top of SIMD128 instruction set, but do not pass SSE flags to LLVM
    # so it won't think about generating native x86 SSE code.
    newargs = [x for x in newargs if x not in shared.SIMD_INTEL_FEATURE_TOWER and x not in shared.SIMD_NEON_FLAGS]

    link_to_object = False
    if options.shared or options.relocatable:
      # Until we have a better story for actually producing runtime shared libraries
      # we support a compatibility mode where shared libraries are actually just
      # object files linked with `wasm-ld --relocatable` or `llvm-link` in the case
      # of LTO.
      if final_suffix in EXECUTABLE_ENDINGS:
        diagnostics.warning('emcc', '-shared/-r used with executable output suffix. This behaviour is deprecated.  Please remove -shared/-r to build an executable or avoid the executable suffix (%s) when building object files.' % final_suffix)
      else:
        if options.shared:
          diagnostics.warning('emcc', 'linking a library with `-shared` will emit a static object file.  This is a form of emulation to support existing build systems.  If you want to build a runtime shared library use the SIDE_MODULE setting.')
        link_to_object = True

    if shared.Settings.STACK_OVERFLOW_CHECK:
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$abortStackOverflow']
      shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_end', '_emscripten_stack_get_free']
      if shared.Settings.RELOCATABLE:
        shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_set_limits']
      else:
        shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_init']
      if shared.Settings.STACK_OVERFLOW_CHECK == 2:
        shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_base']

    if shared.Settings.MODULARIZE:
      assert not options.proxy_to_worker, '-s MODULARIZE=1 is not compatible with --proxy-to-worker (if you want to run in a worker with -s MODULARIZE=1, you likely want to do the worker side setup manually)'
      # in MINIMAL_RUNTIME we may not need to emit the Promise code, as the
      # HTML output creates a singleton instance, and it does so without the
      # Promise. However, in Pthreads mode the Promise is used for worker
      # creation.
      if shared.Settings.MINIMAL_RUNTIME and options.oformat == OFormat.HTML and not shared.Settings.USE_PTHREADS:
        shared.Settings.EXPORT_READY_PROMISE = 0

    if shared.Settings.LEGACY_VM_SUPPORT:
      if shared.Settings.WASM2JS:
        shared.Settings.POLYFILL_OLD_MATH_FUNCTIONS = 1

      # Support all old browser versions
      shared.Settings.MIN_FIREFOX_VERSION = 0
      shared.Settings.MIN_SAFARI_VERSION = 0
      shared.Settings.MIN_IE_VERSION = 0
      shared.Settings.MIN_EDGE_VERSION = 0
      shared.Settings.MIN_CHROME_VERSION = 0

    if shared.Settings.MIN_SAFARI_VERSION <= 9 and shared.Settings.WASM2JS:
      shared.Settings.WORKAROUND_IOS_9_RIGHT_SHIFT_BUG = 1

    if shared.Settings.MIN_CHROME_VERSION <= 37:
      shared.Settings.WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG = 1

    setup_environment_settings()

    # Silently drop any individual backwards compatibility emulation flags that are known never to occur on browsers that support WebAssembly.
    if not shared.Settings.WASM2JS:
      shared.Settings.POLYFILL_OLD_MATH_FUNCTIONS = 0
      shared.Settings.WORKAROUND_IOS_9_RIGHT_SHIFT_BUG = 0
      shared.Settings.WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG = 0

    if shared.Settings.STB_IMAGE and final_suffix in EXECUTABLE_ENDINGS:
      input_files.append((len(newargs), shared.path_from_root('third_party', 'stb_image.c')))
      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.USE_WEBGL2:
      shared.Settings.MAX_WEBGL_VERSION = 2

    if not shared.Settings.GL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS and shared.Settings.GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS:
      exit_with_error('-s GL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=0 only makes sense with -s GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=0!')

    forced_stdlibs = []

    if shared.Settings.ASMFS and final_suffix in EXECUTABLE_ENDINGS:
      forced_stdlibs.append('libasmfs')
      shared.Settings.FILESYSTEM = 0
      shared.Settings.SYSCALLS_REQUIRE_FILESYSTEM = 0
      shared.Settings.FETCH = 1
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_asmfs.js')))

    # Explicitly drop linking in a malloc implementation if program is not using any dynamic allocation calls.
    if not shared.Settings.USES_DYNAMIC_ALLOC:
      shared.Settings.MALLOC = 'none'

    if shared.Settings.MALLOC == 'emmalloc':
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_emmalloc.js')))

    if shared.Settings.FETCH and final_suffix in EXECUTABLE_ENDINGS:
      forced_stdlibs.append('libfetch')
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_fetch.js')))
      if shared.Settings.USE_PTHREADS:
        shared.Settings.FETCH_WORKER_FILE = unsuffixed(os.path.basename(target)) + '.fetch.js'

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

    if shared.Settings.FULL_ES3:
      shared.Settings.FULL_ES2 = 1
      shared.Settings.MAX_WEBGL_VERSION = max(2, shared.Settings.MAX_WEBGL_VERSION)

    if shared.Settings.EMBIND:
      forced_stdlibs.append('libembind')

    shared.Settings.EXPORTED_FUNCTIONS += ['_stackSave', '_stackRestore', '_stackAlloc']
    if not shared.Settings.STANDALONE_WASM:
      # in standalone mode, crt1 will call the constructors from inside the wasm
      shared.Settings.EXPORTED_FUNCTIONS.append('___wasm_call_ctors')

    if shared.Settings.RELOCATABLE and not shared.Settings.DYNAMIC_EXECUTION:
      exit_with_error('cannot have both DYNAMIC_EXECUTION=0 and RELOCATABLE enabled at the same time, since RELOCATABLE needs to eval()')

    if shared.Settings.SIDE_MODULE and shared.Settings.GLOBAL_BASE != -1:
      exit_with_error('Cannot set GLOBAL_BASE when building SIDE_MODULE')

    if shared.Settings.RELOCATABLE:
      shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS = 0
      shared.Settings.WARN_ON_UNDEFINED_SYMBOLS = 0

    if shared.Settings.DISABLE_EXCEPTION_THROWING and not shared.Settings.DISABLE_EXCEPTION_CATCHING:
      exit_with_error("DISABLE_EXCEPTION_THROWING was set (probably from -fno-exceptions) but is not compatible with enabling exception catching (DISABLE_EXCEPTION_CATCHING=0). If you don't want exceptions, set DISABLE_EXCEPTION_CATCHING to 1; if you do want exceptions, don't link with -fno-exceptions")

    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):
      if shared.Settings.NODERAWFS:
        exit_with_error('--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.MINIMAL_RUNTIME:
      # In non-MINIMAL_RUNTIME, the core runtime depends on these functions to be present. (In MINIMAL_RUNTIME, they are
      # no longer always bundled in)
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$demangle', '$demangleAll', '$jsStackTrace', '$stackTrace']

    if shared.Settings.FILESYSTEM:
      # 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 enabled EXIT_RUNTIME)
      if shared.Settings.EXIT_RUNTIME or shared.Settings.ASSERTIONS:
        shared.Settings.EXPORTED_FUNCTIONS += ['_fflush']

    if shared.Settings.SUPPORT_ERRNO:
      # so setErrNo JS library function can report errno back to C
      shared.Settings.EXPORTED_FUNCTIONS += ['___errno_location']

    if shared.Settings.SAFE_HEAP:
      # SAFE_HEAP check includes calling emscripten_get_sbrk_ptr() from wasm
      shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_get_sbrk_ptr', '_emscripten_stack_get_base']
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$unSign']

    if not shared.Settings.DECLARE_ASM_MODULE_EXPORTS:
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$exportAsmFunctions']

    if shared.Settings.ALLOW_MEMORY_GROWTH and 'ABORTING_MALLOC=1' not in settings_changes:
      # Setting ALLOW_MEMORY_GROWTH turns off ABORTING_MALLOC, as in that mode we default to
      # the behavior of trying to grow and returning 0 from malloc on failure, like
      # a standard system would. However, if the user sets the flag it
      # overrides that.
      shared.Settings.ABORTING_MALLOC = 0

    if shared.Settings.USE_PTHREADS:
      if shared.Settings.USE_PTHREADS == 2:
        exit_with_error('USE_PTHREADS=2 is not longer supported')
      if shared.Settings.ALLOW_MEMORY_GROWTH:
        diagnostics.warning('pthreads-mem-growth', 'USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, see https://github.com/WebAssembly/design/issues/1271')
      # UTF8Decoder.decode doesn't work with a view of a SharedArrayBuffer
      shared.Settings.TEXTDECODER = 0
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_pthread.js')))
      newargs += ['-pthread']
      # some pthreads code is in asm.js library functions, which are auto-exported; for the wasm backend, we must
      # manually export them

      shared.Settings.EXPORTED_FUNCTIONS += [
        '_emscripten_get_global_libc', '___pthread_tsd_run_dtors',
        'registerPthreadPtr', '_pthread_self',
        '___emscripten_pthread_data_constructor', '_emscripten_futex_wake',
        '_emscripten_stack_set_limits']

      # set location of worker.js
      shared.Settings.PTHREAD_WORKER_FILE = unsuffixed(os.path.basename(target)) + '.worker.js'
    else:
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_pthread_stub.js')))

    if shared.Settings.FORCE_FILESYSTEM and not shared.Settings.MINIMAL_RUNTIME:
      # 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)
      if not shared.Settings.ASMFS:
        shared.Settings.EXPORTED_RUNTIME_METHODS += [
          'FS_createPath',
          'FS_createDataFile',
          'FS_createPreloadedFile',
          'FS_createLazyFile',
          'FS_createDevice',
          'FS_unlink'
        ]

      shared.Settings.EXPORTED_RUNTIME_METHODS += [
        'addRunDependency',
        'removeRunDependency',
      ]

    if not shared.Settings.MINIMAL_RUNTIME or shared.Settings.EXIT_RUNTIME:
      # MINIMAL_RUNTIME only needs callRuntimeCallbacks in certain cases, but the normal runtime
      # always does.
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$callRuntimeCallbacks', '$dynCall']

    if shared.Settings.USE_PTHREADS:
      # memalign is used to ensure allocated thread stacks are aligned.
      shared.Settings.EXPORTED_FUNCTIONS += ['_memalign']

      # dynCall is used to call pthread entry points in worker.js (as
      # metadce does not consider worker.js, which is external, we must
      # consider it an export, i.e., one which can never be removed).
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$dynCall']
      shared.Settings.EXPORTED_FUNCTIONS += ['dynCall']

      if shared.Settings.MINIMAL_RUNTIME:
        building.user_requested_exports += ['exit']

      if shared.Settings.PROXY_TO_PTHREAD:
        shared.Settings.EXPORTED_FUNCTIONS += ['_proxy_main']

      # pthread stack setup and other necessary utilities
      def include_and_export(name):
        shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$' + name]
        shared.Settings.EXPORTED_FUNCTIONS += [name]

      include_and_export('establishStackSpace')
      if not shared.Settings.MINIMAL_RUNTIME:
        # noExitRuntime does not apply to MINIMAL_RUNTIME.
        include_and_export('getNoExitRuntime')

      if shared.Settings.MODULARIZE:
        if shared.Settings.EXPORT_NAME == 'Module':
          exit_with_error('pthreads + MODULARIZE currently require you to set -s EXPORT_NAME=Something (see settings.js) to Something != Module, so that the .worker.js file can work')

        # MODULARIZE+USE_PTHREADS mode requires extra exports out to Module so that worker.js
        # can access them:

        # general threading variables:
        shared.Settings.EXPORTED_RUNTIME_METHODS += ['PThread']

        # To keep code size to minimum, MINIMAL_RUNTIME does not utilize the global ExitStatus
        # object, only regular runtime has it.
        if not shared.Settings.MINIMAL_RUNTIME:
          shared.Settings.EXPORTED_RUNTIME_METHODS += ['ExitStatus']

      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.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.INITIAL_MEMORY % 65536 != 0:
      exit_with_error('For wasm, INITIAL_MEMORY must be a multiple of 64KB, was ' + str(shared.Settings.INITIAL_MEMORY))
    if shared.Settings.INITIAL_MEMORY >= 2 * 1024 * 1024 * 1024:
      exit_with_error('INITIAL_MEMORY must be less than 2GB due to current spec limitations')
    if shared.Settings.INITIAL_MEMORY < shared.Settings.TOTAL_STACK:
      exit_with_error('INITIAL_MEMORY must be larger than TOTAL_STACK, was ' + str(shared.Settings.INITIAL_MEMORY) + ' (TOTAL_STACK=' + str(shared.Settings.TOTAL_STACK) + ')')
    if shared.Settings.MAXIMUM_MEMORY != -1 and shared.Settings.MAXIMUM_MEMORY % 65536 != 0:
      exit_with_error('MAXIMUM_MEMORY must be a multiple of 64KB, was ' + str(shared.Settings.MAXIMUM_MEMORY))
    if shared.Settings.MEMORY_GROWTH_LINEAR_STEP != -1 and shared.Settings.MEMORY_GROWTH_LINEAR_STEP % 65536 != 0:
      exit_with_error('MEMORY_GROWTH_LINEAR_STEP must be a multiple of 64KB, was ' + str(shared.Settings.MEMORY_GROWTH_LINEAR_STEP))
    if shared.Settings.USE_PTHREADS and shared.Settings.ALLOW_MEMORY_GROWTH and shared.Settings.MAXIMUM_MEMORY == -1:
      exit_with_error('If pthreads and memory growth are enabled, MAXIMUM_MEMORY must be set')

    if shared.Settings.EXPORT_ES6 and not shared.Settings.MODULARIZE:
      # EXPORT_ES6 requires output to be a module
      if 'MODULARIZE' in settings_key_changes:
        exit_with_error('EXPORT_ES6 requires MODULARIZE to be set')
      shared.Settings.MODULARIZE = 1

    if shared.Settings.MODULARIZE and not shared.Settings.DECLARE_ASM_MODULE_EXPORTS:
      # When MODULARIZE option is used, currently requires declaring all module exports
      # individually - TODO: this could be optimized
      exit_with_error('DECLARE_ASM_MODULE_EXPORTS=0 is not compatible with MODULARIZE')

    # When not declaring asm module exports in outer scope one by one, disable minifying
    # asm.js/wasm module export names so that the names can be passed directly to the outer scope.
    # Also, if using library_exports.js API, disable minification so that the feature can work.
    if not shared.Settings.DECLARE_ASM_MODULE_EXPORTS or 'exports.js' in [x for _, x in libs]:
      shared.Settings.MINIFY_ASMJS_EXPORT_NAMES = 0

    # Enable minification of wasm imports and exports when appropriate, if we
    # are emitting an optimized JS+wasm combo (then the JS knows how to load the minified names).
    # Things that process the JS after this operation would be done must disable this.
    # For example, ASYNCIFY_LAZY_LOAD_CODE needs to identify import names.
    if will_metadce() and \
        shared.Settings.OPT_LEVEL >= 2 and \
        shared.Settings.DEBUG_LEVEL <= 2 and \
        options.oformat not in (OFormat.WASM, OFormat.BARE) and \
        not shared.Settings.LINKABLE and \
        not shared.Settings.STANDALONE_WASM and \
        not shared.Settings.AUTODEBUG and \
        not shared.Settings.ASSERTIONS and \
        not shared.Settings.RELOCATABLE and \
        not shared.Settings.ASYNCIFY_LAZY_LOAD_CODE and \
            shared.Settings.MINIFY_ASMJS_EXPORT_NAMES:
      shared.Settings.MINIFY_WASM_IMPORTS_AND_EXPORTS = 1
      shared.Settings.MINIFY_WASM_IMPORTED_MODULES = 1

    if shared.Settings.MINIMAL_RUNTIME:
      # Minimal runtime uses a different default shell file
      if options.shell_path == shared.path_from_root('src', 'shell.html'):
        options.shell_path = shared.path_from_root('src', 'shell_minimal_runtime.html')

      if shared.Settings.ASSERTIONS and shared.Settings.MINIMAL_RUNTIME:
        # In ASSERTIONS-builds, functions UTF8ArrayToString() and stringToUTF8Array() (which are not JS library functions), both
        # use warnOnce(), which in MINIMAL_RUNTIME is a JS library function, so explicitly have to mark dependency to warnOnce()
        # in that case. If string functions are turned to library functions in the future, then JS dependency tracking can be
        # used and this special directive can be dropped.
        shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$warnOnce']

      # Require explicit -lfoo.js flags to link with JS libraries.
      shared.Settings.AUTO_JS_LIBRARIES = 0

    if shared.Settings.MODULARIZE and shared.Settings.EXPORT_NAME == 'Module' and options.oformat == OFormat.HTML and \
       (options.shell_path == shared.path_from_root('src', 'shell.html') or options.shell_path == shared.path_from_root('src', 'shell_minimal.html')):
      exit_with_error('Due to collision in variable name "Module", the shell file "' + options.shell_path + '" is not compatible with build options "-s MODULARIZE=1 -s EXPORT_NAME=Module". Either provide your own shell file, change the name of the export to something else to avoid the name collision. (see https://github.com/emscripten-core/emscripten/issues/7950 for details)')

    if shared.Settings.STANDALONE_WASM:
      if shared.Settings.USE_PTHREADS:
        exit_with_error('STANDALONE_WASM does not support pthreads yet')
      if shared.Settings.MINIMAL_RUNTIME:
        exit_with_error('MINIMAL_RUNTIME reduces JS size, and is incompatible with STANDALONE_WASM which focuses on ignoring JS anyhow and being 100% wasm')
      if shared.Settings.WASM2JS:
        exit_with_error('WASM2JS is not compatible with STANDALONE_WASM output')
      # the wasm must be runnable without the JS, so there cannot be anything that
      # requires JS legalization
      shared.Settings.LEGALIZE_JS_FFI = 0

    if shared.Settings.WASM_BIGINT:
      shared.Settings.LEGALIZE_JS_FFI = 0

    shared.Settings.GENERATE_SOURCE_MAP = shared.Settings.DEBUG_LEVEL >= 4 and not shared.Settings.SINGLE_FILE

    if options.use_closure_compiler == 2 and not shared.Settings.WASM2JS:
      exit_with_error('closure compiler mode 2 assumes the code is asm.js, so not meaningful for wasm')

    if any(s.startswith('MEM_INIT_METHOD=') for s in settings_changes):
      exit_with_error('MEM_INIT_METHOD 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.')

    if shared.Settings.WASM2JS:
      shared.Settings.MAYBE_WASM2JS = 1
      # when using wasm2js, if the memory segments are in the wasm then they
      # end up converted by wasm2js into base64 encoded JS. alternatively, we
      # can use a .mem file like asm.js used to.
      # generally we follow what the options tell us to do (which is to use
      # a .mem file in most cases, since it is binary & compact). however, for
      # pthreads we must keep the memory segments in the wasm as they will be
      # passive segments which the .mem format cannot handle.
      shared.Settings.MEM_INIT_IN_WASM = not options.memory_init_file or shared.Settings.SINGLE_FILE or shared.Settings.USE_PTHREADS
    else:
      # wasm includes the mem init in the wasm binary. The exception is
      # wasm2js, which behaves more like js.
      options.memory_init_file = True
      shared.Settings.MEM_INIT_IN_WASM = True

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

    sanitize = set()

    for arg in newargs:
      if arg.startswith('-fsanitize='):
        sanitize.update(arg.split('=', 1)[1].split(','))
      elif arg.startswith('-fno-sanitize='):
        sanitize.difference_update(arg.split('=', 1)[1].split(','))

    if sanitize:
      shared.Settings.USE_OFFSET_CONVERTER = 1
      shared.Settings.EXPORTED_FUNCTIONS += [
          '_memalign',
          '_emscripten_builtin_memalign',
          '_emscripten_builtin_malloc',
          '_emscripten_builtin_free',
          '___heap_base',
          '___global_base'
      ]

    if sanitize & UBSAN_SANITIZERS:
      if '-fsanitize-minimal-runtime' in newargs:
        shared.Settings.UBSAN_RUNTIME = 1
      else:
        shared.Settings.UBSAN_RUNTIME = 2

    if 'leak' in sanitize:
      shared.Settings.USE_LSAN = 1
      shared.Settings.EXIT_RUNTIME = 1

      if shared.Settings.LINKABLE:
        exit_with_error('LSan does not support dynamic linking')

    if 'address' in sanitize:
      shared.Settings.USE_ASAN = 1
      if not shared.Settings.UBSAN_RUNTIME:
        shared.Settings.UBSAN_RUNTIME = 2

      shared.Settings.EXPORTED_FUNCTIONS += [
        '_emscripten_builtin_memset',
        '_asan_c_load_1', '_asan_c_load_1u',
        '_asan_c_load_2', '_asan_c_load_2u',
        '_asan_c_load_4', '_asan_c_load_4u',
        '_asan_c_load_f', '_asan_c_load_d',
        '_asan_c_store_1', '_asan_c_store_1u',
        '_asan_c_store_2', '_asan_c_store_2u',
        '_asan_c_store_4', '_asan_c_store_4u',
        '_asan_c_store_f', '_asan_c_store_d',
      ]

      if shared.Settings.ASAN_SHADOW_SIZE != -1:
        diagnostics.warning('emcc', 'ASAN_SHADOW_SIZE is ignored and will be removed in a future release')

      if shared.Settings.GLOBAL_BASE != -1:
        exit_with_error("ASan does not support custom GLOBAL_BASE")

      max_mem = shared.Settings.INITIAL_MEMORY
      if shared.Settings.ALLOW_MEMORY_GROWTH:
        max_mem = shared.Settings.MAXIMUM_MEMORY
        if max_mem == -1:
          exit_with_error('ASan requires a finite MAXIMUM_MEMORY')

      shadow_size = max_mem // 8
      shared.Settings.GLOBAL_BASE = shadow_size

      if shared.Settings.SAFE_HEAP:
        # SAFE_HEAP instruments ASan's shadow memory accesses.
        # Since the shadow memory starts at 0, the act of accessing the shadow memory is detected
        # by SAFE_HEAP as a null pointer dereference.
        exit_with_error('ASan does not work with SAFE_HEAP')

      if shared.Settings.LINKABLE:
        exit_with_error('ASan does not support dynamic linking')

    if sanitize and '-g4' in args:
      shared.Settings.LOAD_SOURCE_MAP = 1

    if shared.Settings.GLOBAL_BASE == -1:
      # default if nothing else sets it
      # a higher global base is useful for optimizing load/store offsets, as it
      # enables the --post-emscripten pass
      shared.Settings.GLOBAL_BASE = 1024

    if shared.Settings.RELOCATABLE:
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$reportUndefinedSymbols', '$relocateExports', '$GOTHandler']
      shared.Settings.EXTRA_WASM_IMPORTS += [
        # tell the memory segments where to place themselves
        ('__memory_base', str(shared.Settings.GLOBAL_BASE)),
        ('__indirect_function_table', 'wasmTable'),
        # the backend reserves slot 0 for the NULL function pointer
        ('__table_base', '1'),
        ('__stack_pointer', '__stack_pointer'),
      ]
      if options.use_closure_compiler:
        exit_with_error('cannot use closure compiler on shared modules')
      if shared.Settings.MINIMAL_RUNTIME:
        exit_with_error('MINIMAL_RUNTIME is not compatible with relocatable output')
      if shared.Settings.WASM2JS:
        exit_with_error('WASM2JS is not compatible with relocatable output')
      # shared modules need memory utilities to allocate their memory
      shared.Settings.EXPORTED_RUNTIME_METHODS += ['allocate']
      shared.Settings.ALLOW_TABLE_GROWTH = 1

    # various settings require malloc/free support from JS
    if shared.Settings.RELOCATABLE or \
       shared.Settings.BUILD_AS_WORKER or \
       shared.Settings.USE_WEBGPU or \
       shared.Settings.USE_PTHREADS or \
       shared.Settings.OFFSCREENCANVAS_SUPPORT or \
       shared.Settings.LEGACY_GL_EMULATION or \
       shared.Settings.DISABLE_EXCEPTION_CATCHING != 1 or \
       shared.Settings.ASYNCIFY or \
       shared.Settings.ASMFS or \
       shared.Settings.DEMANGLE_SUPPORT or \
       shared.Settings.FORCE_FILESYSTEM or \
       shared.Settings.STB_IMAGE or \
       shared.Settings.EMBIND or \
       shared.Settings.FETCH or \
       shared.Settings.PROXY_POSIX_SOCKETS or \
       options.memory_profiler or \
       sanitize:
      shared.Settings.EXPORTED_FUNCTIONS += ['_malloc', '_free']

    options.binaryen_passes += backend_binaryen_passes()

    if shared.Settings.WASM2JS and shared.Settings.GENERATE_SOURCE_MAP:
      exit_with_error('wasm2js does not support source maps yet (debug in wasm for now)')

    if shared.Settings.NODE_CODE_CACHING:
      if shared.Settings.WASM_ASYNC_COMPILATION:
        exit_with_error('NODE_CODE_CACHING requires sync compilation (WASM_ASYNC_COMPILATION=0)')
      if not shared.Settings.target_environment_may_be('node'):
        exit_with_error('NODE_CODE_CACHING only works in node, but target environments do not include it')
      if shared.Settings.SINGLE_FILE:
        exit_with_error('NODE_CODE_CACHING saves a file on the side and is not compatible with SINGLE_FILE')

    if options.tracing and shared.Settings.ALLOW_MEMORY_GROWTH:
      shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['emscripten_trace_report_memory_layout']
      shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_current',
                                             '_emscripten_stack_get_base',
                                             '_emscripten_stack_get_end']

    if shared.Settings.USE_PTHREADS:
      newargs.append('-pthread')

    # check if we can address the 2GB mark and higher: either if we start at
    # 2GB, or if we allow growth to either any amount or to 2GB or more.
    if shared.Settings.INITIAL_MEMORY > 2 * 1024 * 1024 * 1024 or \
       (shared.Settings.ALLOW_MEMORY_GROWTH and
        (shared.Settings.MAXIMUM_MEMORY < 0 or
         shared.Settings.MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024)):
      shared.Settings.CAN_ADDRESS_2GB = 1
      if shared.Settings.MALLOC == 'emmalloc':
        if shared.Settings.INITIAL_MEMORY >= 2 * 1024 * 1024 * 1024:
          suggestion = 'decrease INITIAL_MEMORY'
        elif shared.Settings.MAXIMUM_MEMORY < 0:
          suggestion = 'set MAXIMUM_MEMORY'
        else:
          suggestion = 'decrease MAXIMUM_MEMORY'
        exit_with_error('emmalloc only works on <2GB of memory. Use the default allocator, or ' + suggestion)

    shared.Settings.EMSCRIPTEN_VERSION = shared.EMSCRIPTEN_VERSION
    shared.Settings.PROFILING_FUNCS = options.profiling_funcs
    shared.Settings.SOURCE_MAP_BASE = options.source_map_base or ''

    ## Compile source code to bitcode

    logger.debug('compiling to bitcode')

    temp_files = []

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

  if DEBUG:
    # we are about to start using temp dirs. serialize access to the temp dir
    # when using EMCC_DEBUG, since we don't want multiple processes would to
    # use it at once, they might collide if they happen to use the same
    # tempfile names
    shared.Cache.acquire_cache_lock()
    atexit.register(shared.Cache.release_cache_lock)

  if options.post_link:
    process_libraries(libs, lib_dirs, temp_files)
    if len(input_files) != 1:
      exit_with_error('--post-link requires a single input file')
    post_link(options, input_files[0][1], wasm_target, target)
    return 0

  with ToolchainProfiler.profile_block('compile inputs'):
    def is_link_flag(flag):
      if flag.startswith('-nostdlib'):
        return True
      return flag.startswith(('-l', '-L', '-Wl,'))

    CXX = [shared.CLANG_CXX]
    CC = [shared.CLANG_CC]
    if config.COMPILER_WRAPPER:
      logger.debug('using compiler wrapper: %s', config.COMPILER_WRAPPER)
      CXX.insert(0, config.COMPILER_WRAPPER)
      CC.insert(0, config.COMPILER_WRAPPER)

    if 'EMMAKEN_COMPILER' in os.environ:
      diagnostics.warning('deprecated', '`EMMAKEN_COMPILER` is deprecated.\n'
                          'To use an alteranative LLVM build set `LLVM_ROOT` in the config file (or `EM_LLVM_ROOT` env var).\n'
                          'To wrap invocations of clang use the `COMPILER_WRAPPER` setting (or `EM_COMPILER_WRAPPER` env var.\n')
      CXX = [os.environ['EMMAKEN_COMPILER']]
      CC = [cxx_to_c_compiler(os.environ['EMMAKEN_COMPILER'])]

    compile_args = [a for a in newargs if a and not is_link_flag(a)]
    cflags = calc_cflags(options)
    system_libs.add_ports_cflags(cflags, shared.Settings)

    def use_cxx(src):
      if 'c++' in language_mode or run_via_emxx:
        return True
      # Next consider the filename
      if src.endswith(C_ENDINGS + OBJC_ENDINGS):
        return False
      if src.endswith(CXX_ENDINGS):
        return True
      # Finally fall back to the default
      if shared.Settings.DEFAULT_TO_CXX:
        # Default to using C++ even when run as `emcc`.
        # This means that emcc will act as a C++ linker when no source files are
        # specified.
        # This differs to clang and gcc where the default is always C unless run as
        # clang++/g++.
        return True
      return False

    def get_compiler(cxx):
      if cxx:
        return CXX
      return CC

    def get_clang_command(src_file):
      cxx = use_cxx(src_file)
      per_file_cflags = shared.get_cflags(args, cxx)
      return get_compiler(cxx) + cflags + per_file_cflags + compile_args + [src_file]

    def get_clang_command_asm(src_file):
      asflags = shared.get_asmflags()
      return get_compiler(use_cxx(src_file)) + asflags + compile_args + [src_file]

    # preprocessor-only (-E) support
    if has_dash_E or '-M' in newargs or '-MM' in newargs or '-fsyntax-only' in newargs:
      for input_file in [x[1] for x in input_files]:
        cmd = get_clang_command(input_file)
        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)
        logger.debug(('just preprocessor ' if has_dash_E else 'just dependencies: ') + ' '.join(cmd))
        shared.print_compiler_stage(cmd)
        rtn = run_process(cmd, check=False).returncode
        if rtn:
          return rtn
      return 0

    # Precompiled headers support
    if has_header_inputs:
      headers = [header for _, header in input_files]
      for header in headers:
        if not header.endswith(HEADER_ENDINGS):
          exit_with_error('cannot mix precompile headers with non-header inputs: ' + str(headers) + ' : ' + header)
        cmd = get_clang_command(header)
        if specified_target:
          cmd += ['-o', specified_target]
        logger.debug("running (for precompiled headers): " + cmd[0] + ' ' + ' '.join(cmd[1:]))
        shared.print_compiler_stage(cmd)
        return run_process(cmd, check=False).returncode

    def get_object_filename(input_file):
      if compile_only:
        # In compile-only mode we don't use any temp file.   The object files are written directly
        # to their final output locations.
        if specified_target:
          assert len(input_files) == 1
          return specified_target
        else:
          return unsuffixed_basename(input_file) + options.default_object_extension
      else:
        return in_temp(unsuffixed(uniquename(input_file)) + options.default_object_extension)

    def compile_source_file(i, input_file):
      logger.debug('compiling source file: ' + input_file)
      output_file = get_object_filename(input_file)
      temp_files.append((i, output_file))
      if get_file_suffix(input_file) in ASSEMBLY_ENDINGS:
        cmd = get_clang_command_asm(input_file)
      else:
        cmd = get_clang_command(input_file)
      cmd += ['-c', '-o', output_file]
      shared.print_compiler_stage(cmd)
      shared.check_call(cmd)
      if output_file not in ('-', os.devnull):
        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_suffix = get_file_suffix(input_file)
      if file_suffix in SOURCE_ENDINGS + ASSEMBLY_ENDINGS or (has_dash_c and file_suffix == '.bc'):
        compile_source_file(i, input_file)
      elif file_suffix in DYNAMICLIB_ENDINGS:
        logger.debug('using shared library: ' + input_file)
        temp_files.append((i, input_file))
      elif building.is_ar(input_file):
        logger.debug('using static library: ' + input_file)
        ensure_archive_index(input_file)
        temp_files.append((i, input_file))
      elif language_mode:
        compile_source_file(i, input_file)
      elif input_file == '-':
        exit_with_error('-E or -x required when input is from standard input')
      else:
        # Default to assuming the inputs are object files and pass them to the linker
        logger.debug('using object file: ' + input_file)
        temp_files.append((i, input_file))

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

  if compile_only:
    logger.debug('stopping after compile phase')
    for flag in link_flags:
      diagnostics.warning('unused-command-line-argument', "argument unused during compilation: '%s'" % flag[1])
    return 0

  if specified_target and specified_target.startswith('-'):
    exit_with_error('invalid output filename: `%s`' % specified_target)

  using_lld = not (link_to_object and shared.Settings.LTO)
  link_flags = filter_link_flags(link_flags, using_lld)

  # Decide what we will link
  consumed = process_libraries(libs, lib_dirs, temp_files)
  # Filter out libraries that are actually JS libs
  link_flags = [l for l in link_flags if l[0] not in consumed]
  temp_files = filter_out_dynamic_libs(temp_files)

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

  if link_to_object:
    with ToolchainProfiler.profile_block('linking to object file'):
      logger.debug('link_to_object: ' + str(linker_inputs) + ' -> ' + target)
      if len(temp_files) == 1:
        temp_file = temp_files[0][1]
        # skip running the linker and just copy the object file
        safe_copy(temp_file, target)
      else:
        building.link_to_object(linker_inputs, target)
      logger.debug('stopping after linking to object file')
      return 0

  if final_suffix in ('.o', '.bc', '.so', '.dylib') and not shared.Settings.SIDE_MODULE:
   diagnostics.warning('emcc', 'generating an executable with an object extension (%s).  If you meant to build an object file please use `-c, `-r`, or `-shared`' % final_suffix)

  ## Continue on to create JavaScript

  with ToolchainProfiler.profile_block('calculate system libraries'):
    # link in ports and system libraries, if necessary
    if 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)
      if '-nostdlib' not in newargs and '-nodefaultlibs' not in newargs:
        link_as_cxx = run_via_emxx
        # Traditionally we always link as C++.  For compatibility we continue to do that,
        # unless running in strict mode.
        if not shared.Settings.STRICT and '-nostdlib++' not in newargs:
          link_as_cxx = True
        extra_files_to_link += system_libs.calculate([f for _, f in sorted(temp_files)] + extra_files_to_link, link_as_cxx, forced=forced_stdlibs)
      linker_inputs += extra_files_to_link

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

  def dedup_list(lst):
    rtn = []
    for item in lst:
      if item not in rtn:
        rtn.append(item)
    return rtn

  # Make a final pass over shared.Settings.EXPORTED_FUNCTIONS to remove any
  # duplication between functions added by the driver/libraries and function
  # specified by the user
  shared.Settings.EXPORTED_FUNCTIONS = dedup_list(shared.Settings.EXPORTED_FUNCTIONS)

  with ToolchainProfiler.profile_block('link'):
    logger.debug('linking: ' + str(linker_inputs))

    # 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
    js_funcs = None
    if shared.Settings.LLD_REPORT_UNDEFINED and shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS:
      js_funcs = get_all_js_syms(misc_temp_files)
      log_time('JS symbol generation')
    building.link_lld(linker_inputs, wasm_target, external_symbol_list=js_funcs)
    # Special handling for when the user passed '-Wl,--version'.  In this case the linker
    # does not create the output file, but just prints its version and exits with 0.
    if '--version' in linker_inputs:
      return 0

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

  if target == os.devnull:
    # TODO(sbc): In theory we should really run the whole pipeline even if the output is
    # /dev/null, but that will take some refactoring
    return 0

  # Perform post-link steps (unless we are running bare mode)
  if options.oformat != OFormat.BARE:
    post_link(options, wasm_target, wasm_target, target)

  return 0


def post_link(options, in_wasm, wasm_target, target):
  global final_js

  target_basename = unsuffixed_basename(target)

  if options.oformat != OFormat.WASM:
    final_js = in_temp(target_basename + '.js')

  if shared.Settings.MEM_INIT_IN_WASM:
    memfile = None
  else:
    memfile = shared.replace_or_append_suffix(target, '.mem')

  with ToolchainProfiler.profile_block('emscript'):
    # Emscripten
    logger.debug('emscript')
    if options.memory_init_file:
      shared.Settings.MEM_INIT_METHOD = 1
    else:
      assert shared.Settings.MEM_INIT_METHOD != 1

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

    emscripten.run(in_wasm, wasm_target, final_js, memfile)
    save_intermediate('original')

  # exit block 'emscript'
  log_time('emscript)')

  with ToolchainProfiler.profile_block('source transforms'):
    # Embed and preload files
    if len(options.preload_files) or len(options.embed_files):
      logger.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 shared.Settings.LZ4:
        file_args.append('--lz4')
      if options.use_preload_plugins:
        file_args.append('--use-preload-plugins')
      file_code = shared.check_call([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE).stdout
      options.pre_js = js_manipulation.add_files_pre_js(options.pre_js, file_code)

    # Apply pre and postjs files
    if final_js and (options.pre_js or options.post_js):
      logger.debug('applying pre/postjses')
      src = open(final_js).read()
      final_js += '.pp.js'
      with open(final_js, 'w') as f:
        # pre-js code goes right after the Module integration code (so it
        # can use Module), we have a marker for it
        f.write(do_replace(src, '// {{PRE_JSES}}', fix_windows_newlines(options.pre_js)))
        f.write(fix_windows_newlines(options.post_js))
      options.pre_js = src = options.post_js = None
      save_intermediate('pre-post')

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

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

  if memfile and not shared.Settings.MINIMAL_RUNTIME:
    # MINIMAL_RUNTIME doesn't use `var memoryInitializer` but instead expects Module['mem'] to
    # be loaded before the module.  See src/postamble_minimal.js.
    with ToolchainProfiler.profile_block('memory initializer'):
      # For the wasm backend, we don't have any memory info in JS. All we need to do
      # is set the memory initializer url.
      src = open(final_js).read()
      src = do_replace(src, '// {{MEM_INITIALIZER}}', 'var memoryInitializer = "%s";' % os.path.basename(memfile))
      open(final_js + '.mem.js', 'w').write(src)
      final_js += '.mem.js'

    log_time('memory initializer')

  with ToolchainProfiler.profile_block('binaryen'):
    do_binaryen(target, options, wasm_target)

  log_time('binaryen')
  # If we are not emitting any JS then we are all done now
  if options.oformat == OFormat.WASM:
    return

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

    if shared.Settings.USE_PTHREADS:
      target_dir = os.path.dirname(os.path.abspath(target))
      worker_output = os.path.join(target_dir, shared.Settings.PTHREAD_WORKER_FILE)
      with open(worker_output, 'w') as f:
        f.write(shared.read_and_preprocess(shared.path_from_root('src', 'worker.js'), expand_macros=True))

      # Minify the worker.js file in optimized builds
      if (shared.Settings.OPT_LEVEL >= 1 or shared.Settings.SHRINK_LEVEL >= 1) and not shared.Settings.DEBUG_LEVEL:
        minified_worker = building.acorn_optimizer(worker_output, ['minifyWhitespace'], return_output=True)
        open(worker_output, 'w').write(minified_worker)

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

    if shared.Settings.MODULARIZE:
      modularize()

    module_export_name_substitution()

    # Run a final regex pass to clean up items that were not possible to optimize by Closure, or unoptimalities that were left behind
    # by processing steps that occurred after Closure.
    if shared.Settings.MINIMAL_RUNTIME == 2 and shared.Settings.USE_CLOSURE_COMPILER and shared.Settings.DEBUG_LEVEL == 0 and not shared.Settings.SINGLE_FILE:
      # Process .js runtime file. Note that we need to handle the license text
      # here, so that it will not confuse the hacky script.
      shared.JS.handle_license(final_js)
      shared.run_process([shared.PYTHON, shared.path_from_root('tools', 'hacky_postprocess_around_closure_limitations.py'), final_js])

    # Apply pre and postjs files
    if options.extern_pre_js or options.extern_post_js:
      logger.debug('applying extern pre/postjses')
      src = open(final_js).read()
      final_js += '.epp.js'
      with open(final_js, 'w') as f:
        f.write(fix_windows_newlines(options.extern_pre_js))
        f.write(src)
        f.write(fix_windows_newlines(options.extern_post_js))
      save_intermediate('extern-pre-post')

    shared.JS.handle_license(final_js)

    if options.oformat in (OFormat.JS, OFormat.MJS):
      js_target = target
    else:
      js_target = unsuffixed(target) + '.js'

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

    if not shared.Settings.SINGLE_FILE:
      generated_text_files_with_native_eols += [js_target]

    # If we were asked to also generate HTML, do that
    if options.oformat == OFormat.HTML:
      generate_html(target, options, js_target, target_basename,
                    wasm_target, memfile)
    elif options.proxy_to_worker:
      generate_worker_js(target, js_target, target_basename)

    if embed_memfile() and memfile:
      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)

    if options.executable:
      make_js_executable(js_target)

  log_time('final emitting')
  # exit block 'final emitting'

  return 0


def parse_args(newargs):
  options = EmccOptions()
  settings_changes = []
  user_js_defines = []
  should_exit = False
  eh_enabled = False
  wasm_eh_enabled = 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()
    arg = newargs[i]
    arg_value = None

    def check_flag(value):
      # Check for and consume a flag
      if arg == value:
        newargs[i] = ''
        return True
      return False

    def check_arg(value):
      nonlocal arg_value
      if arg.startswith(value) and '=' in arg:
        arg_value = arg.split('=', 1)[1]
        newargs[i] = ''
        return True
      if arg == value:
        if len(newargs) <= i + 1:
          exit_with_error("option '%s' requires an argument" % arg)
        arg_value = newargs[i + 1]
        newargs[i] = ''
        newargs[i + 1] = ''
        return True
      return False

    def consume_arg():
      nonlocal arg_value
      assert arg_value is not None
      rtn = arg_value
      arg_value = None
      return rtn

    if arg.startswith('-O'):
      # Let -O default to -O2, which is what gcc does.
      options.requested_level = arg[2:] or '2'
      if options.requested_level == 's':
        options.llvm_opts = ['-Os']
        options.requested_level = 2
        shared.Settings.SHRINK_LEVEL = 1
        settings_changes.append('INLINING_LIMIT=50')
      elif options.requested_level == 'z':
        options.llvm_opts = ['-Oz']
        options.requested_level = 2
        shared.Settings.SHRINK_LEVEL = 2
        settings_changes.append('INLINING_LIMIT=25')
      shared.Settings.OPT_LEVEL = validate_arg_level(options.requested_level, 3, 'Invalid optimization level: ' + arg, clamp=True)
    elif check_arg('--js-opts'):
      logger.warning('--js-opts ignored when using llvm backend')
      consume_arg()
    elif check_arg('--llvm-opts'):
      options.llvm_opts = parse_value(consume_arg())
    elif arg.startswith('-flto'):
      if '=' in arg:
        shared.Settings.LTO = arg.split('=')[1]
      else:
        shared.Settings.LTO = "full"
    elif check_arg('--llvm-lto'):
      logger.warning('--llvm-lto ignored when using llvm backend')
      consume_arg()
    elif check_arg('--closure-args'):
      args = consume_arg()
      options.closure_args += shlex.split(args)
    elif check_arg('--closure'):
      options.use_closure_compiler = int(consume_arg())
    elif check_arg('--js-transform'):
      options.js_transform = consume_arg()
    elif check_arg('--pre-js'):
      options.pre_js += open(consume_arg()).read() + '\n'
    elif check_arg('--post-js'):
      options.post_js += open(consume_arg()).read() + '\n'
    elif check_arg('--extern-pre-js'):
      options.extern_pre_js += open(consume_arg()).read() + '\n'
    elif check_arg('--extern-post-js'):
      options.extern_post_js += open(consume_arg()).read() + '\n'
    elif check_arg('--compiler-wrapper'):
      config.COMPILER_WRAPPER = consume_arg()
    elif check_flag('--post-link'):
      options.post_link = True
    elif check_arg('--oformat'):
      formats = [f.lower() for f in OFormat.__members__]
      fmt = consume_arg()
      if fmt not in formats:
        exit_with_error('invalid output format: `%s` (must be one of %s)' % (fmt, formats))
      options.oformat = getattr(OFormat, fmt.upper())
    elif check_arg('--minify'):
      arg = consume_arg()
      if arg != '0':
        exit_with_error('0 is the only supported option for --minify; 1 has been deprecated')
      shared.Settings.DEBUG_LEVEL = max(1, shared.Settings.DEBUG_LEVEL)
    elif arg.startswith('-g'):
      options.requested_debug = arg
      requested_level = arg[2:] or '3'
      if is_int(requested_level):
        # the -gX value is the debug level (-g1, -g2, etc.)
        shared.Settings.DEBUG_LEVEL = validate_arg_level(requested_level, 4, 'Invalid debug level: ' + arg)
        # if we don't need to preserve LLVM debug info, do not keep this flag
        # for clang
        if shared.Settings.DEBUG_LEVEL < 3:
          newargs[i] = ''
        else:
          # for 3+, report -g to clang as -g4 is not accepted
          newargs[i] = '-g'
      else:
        if requested_level.startswith('force_dwarf'):
          exit_with_error('gforce_dwarf was a temporary option and is no longer necessary (use -g)')
        elif requested_level.startswith('separate-dwarf'):
          # emit full DWARF but also emit it in a file on the side
          newargs[i] = '-g'
          # if a file is provided, use that; otherwise use the default location
          # (note that we do not know the default location until all args have
          # been parsed, so just note True for now).
          if requested_level != 'separate-dwarf':
            if not requested_level.startswith('separate-dwarf=') or requested_level.count('=') != 1:
              exit_with_error('invalid -gseparate-dwarf=FILENAME notation')
            shared.Settings.SEPARATE_DWARF = requested_level.split('=')[1]
          else:
            shared.Settings.SEPARATE_DWARF = True
        # a non-integer level can be something like -gline-tables-only. keep
        # the flag for the clang frontend to emit the appropriate DWARF info.
        # set the emscripten debug level to 3 so that we do not remove that
        # debug info during link (during compile, this does not make a
        # difference).
        shared.Settings.DEBUG_LEVEL = 3
    elif check_flag('-profiling') or check_flag('--profiling'):
      shared.Settings.DEBUG_LEVEL = max(shared.Settings.DEBUG_LEVEL, 2)
      options.profiling = True
    elif check_flag('-profiling-funcs') or check_flag('--profiling-funcs'):
      options.profiling_funcs = True
    elif newargs[i] == '--tracing' or newargs[i] == '--memoryprofiler':
      if newargs[i] == '--memoryprofiler':
        options.memory_profiler = True
      options.tracing = True
      newargs[i] = ''
      settings_changes.append("EMSCRIPTEN_TRACING=1")
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_trace.js')))
    elif check_flag('--emit-symbol-map'):
      options.emit_symbol_map = True
      shared.Settings.EMIT_SYMBOL_MAP = 1
    elif check_flag('--bind'):
      shared.Settings.EMBIND = 1
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'embind', 'emval.js')))
      shared.Settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'embind', 'embind.js')))
    elif check_arg('--embed-file'):
      options.embed_files.append(consume_arg())
    elif check_arg('--preload-file'):
      options.preload_files.append(consume_arg())
    elif check_arg('--exclude-file'):
      options.exclude_files.append(consume_arg())
    elif check_flag('--use-preload-cache'):
      options.use_preload_cache = True
    elif check_flag('--no-heap-copy'):
      diagnostics.warning('legacy-settings', 'ignoring legacy flag --no-heap-copy (that is the only mode supported now)')
    elif check_flag('--use-preload-plugins'):
      options.use_preload_plugins = True
    elif check_flag('--ignore-dynamic-linking'):
      options.ignore_dynamic_linking = True
    elif arg == '-v':
      shared.PRINT_STAGES = True
      shared.check_sanity(force=True)
    elif check_arg('--shell-file'):
      options.shell_path = consume_arg()
    elif check_arg('--source-map-base'):
      options.source_map_base = consume_arg()
    elif check_flag('--no-entry'):
      options.no_entry = True
    elif check_arg('--js-library'):
      shared.Settings.SYSTEM_JS_LIBRARIES.append((i + 1, os.path.abspath(consume_arg())))
    elif check_flag('--remove-duplicates'):
      diagnostics.warning('legacy-settings', '--remove-duplicates is deprecated as it is no longer needed. If you cannot link without it, file a bug with a testcase')
    elif check_flag('--jcache'):
      logger.error('jcache is no longer supported')
    elif check_flag('--clear-cache'):
      logger.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 check_flag('--clear-ports'):
      logger.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 check_flag('--show-ports'):
      system_libs.show_ports()
      should_exit = True
    elif check_arg('--memory-init-file'):
      options.memory_init_file = int(consume_arg())
    elif check_flag('--proxy-to-worker'):
      options.proxy_to_worker = True
    elif check_arg('--valid-abspath'):
      options.valid_abspaths.append(consume_arg())
    elif check_flag('--separate-asm'):
      exit_with_error('cannot --separate-asm with the wasm backend, since not emitting asm.js')
    elif arg.startswith(('-I', '-L')):
      path_name = arg[2:]
      if os.path.isabs(path_name) and not is_valid_abspath(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.
        diagnostics.warning(
            'absolute-paths', '-I or -L of an absolute path "' + arg +
            '" 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 check_flag('--emrun'):
      options.emrun = True
    elif check_flag('--cpuprofiler'):
      options.cpu_profiler = True
    elif check_flag('--threadprofiler'):
      options.thread_profiler = True
      settings_changes.append('PTHREADS_PROFILING=1')
    elif arg == '-fno-exceptions':
      shared.Settings.DISABLE_EXCEPTION_CATCHING = 1
      shared.Settings.DISABLE_EXCEPTION_THROWING = 1
      shared.Settings.EXCEPTION_HANDLING = 0
    elif arg == '-fexceptions':
      eh_enabled = True
    elif arg == '-fwasm-exceptions':
      wasm_eh_enabled = True
    elif arg == '-fignore-exceptions':
      shared.Settings.DISABLE_EXCEPTION_CATCHING = 1
    elif check_arg('--default-obj-ext'):
      options.default_object_extension = consume_arg()
      if not options.default_object_extension.startswith('.'):
        options.default_object_extension = '.' + options.default_object_extension
    elif arg == '-fsanitize=cfi':
      options.cfi = True
    elif check_arg('--output_eol'):
      style = consume_arg()
      if style.lower() == 'windows':
        options.output_eol = '\r\n'
      elif style.lower() == 'linux':
        options.output_eol = '\n'
      else:
        exit_with_error('Invalid value "' + style + '" to --output_eol!')
    elif check_arg('--generate-config'):
      optarg = consume_arg()
      path = os.path.expanduser(optarg)
      if os.path.exists(path):
        exit_with_error('File ' + optarg + ' passed to --generate-config already exists!')
      else:
        config.generate_config(optarg)
      should_exit = True
    # Record USE_PTHREADS setting because it controls whether --shared-memory is passed to lld
    elif arg == '-pthread':
      settings_changes.append('USE_PTHREADS=1')
    elif arg in ('-fno-diagnostics-color', '-fdiagnostics-color=never'):
      colored_logger.disable()
      diagnostics.color_enabled = False
    elif arg == '-fno-rtti':
      shared.Settings.USE_RTTI = 0
    elif arg == '-frtti':
      shared.Settings.USE_RTTI = 1
    elif arg.startswith('-jsD'):
      key = arg[4:]
      if '=' in key:
        key, value = key.split('=')
      else:
        value = '1'
      if key in shared.Settings.attrs:
        exit_with_error(arg + ': cannot change built-in settings values with a -jsD directive. Pass -s ' + key + '=' + value + ' instead!')
      user_js_defines += [(key, value)]
      newargs[i] = ''
    elif check_flag('-shared'):
      options.shared = True
    elif check_flag('-r'):
      options.relocatable = True

  if should_exit:
    sys.exit(0)

  # TODO Currently -fexceptions only means Emscripten EH. Switch to wasm
  # exception handling by default when -fexceptions is given when wasm
  # exception handling becomes stable.
  if wasm_eh_enabled:
    shared.Settings.EXCEPTION_HANDLING = 1
    shared.Settings.DISABLE_EXCEPTION_THROWING = 1
    shared.Settings.DISABLE_EXCEPTION_CATCHING = 1
  elif eh_enabled:
    shared.Settings.EXCEPTION_HANDLING = 0
    shared.Settings.DISABLE_EXCEPTION_THROWING = 0
    shared.Settings.DISABLE_EXCEPTION_CATCHING = 0

  newargs = [a for a in newargs if a]
  return options, settings_changes, user_js_defines, newargs


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


def do_binaryen(target, options, wasm_target):
  global final_js
  logger.debug('using binaryen')
  if shared.Settings.GENERATE_SOURCE_MAP and not shared.Settings.SOURCE_MAP_BASE:
    logger.warning("Wasm source map won't be usable in a browser without --source-map-base")
  # whether we need to emit -g (function name debug info) in the final wasm
  debug_info = shared.Settings.DEBUG_LEVEL >= 2 or options.profiling_funcs
  # whether we need to emit -g in the intermediate binaryen invocations (but not necessarily at the very end).
  # this is necessary for emitting a symbol map at the end.
  intermediate_debug_info = bool(debug_info or options.emit_symbol_map or shared.Settings.ASYNCIFY_ONLY or shared.Settings.ASYNCIFY_REMOVE or shared.Settings.ASYNCIFY_ADD)
  # note that wasm-ld can strip DWARF info for us too (--strip-debug), but it
  # also strips the Names section. so to emit just the Names section we don't
  # tell wasm-ld to strip anything, and we do it here.
  strip_debug = shared.Settings.DEBUG_LEVEL < 3
  strip_producers = not shared.Settings.EMIT_PRODUCERS_SECTION
  # run wasm-opt if we have work for it: either passes, or if we are using
  # source maps (which requires some extra processing to keep the source map
  # but remove DWARF)
  if options.binaryen_passes or shared.Settings.GENERATE_SOURCE_MAP:
    # if we need to strip certain sections, and we have wasm-opt passes
    # to run anyhow, do it with them.
    if strip_debug:
      options.binaryen_passes += ['--strip-debug']
    if strip_producers:
      options.binaryen_passes += ['--strip-producers']
    building.save_intermediate(wasm_target, 'pre-byn.wasm')
    building.run_wasm_opt(wasm_target,
                          wasm_target,
                          args=options.binaryen_passes,
                          debug=intermediate_debug_info)
  else:
    # we are not running wasm-opt. if we need to strip certain sections
    # then do so using llvm-objcopy which is fast and does not rewrite the
    # code (which is better for debug info)
    if strip_debug or strip_producers:
      building.save_intermediate(wasm_target, 'pre-strip.wasm')
      building.strip(wasm_target, wasm_target, debug=strip_debug, producers=strip_producers)

  if shared.Settings.EVAL_CTORS:
    building.save_intermediate(wasm_target, 'pre-ctors.wasm')
    building.eval_ctors(final_js, wasm_target, debug_info=intermediate_debug_info)

  # after generating the wasm, do some final operations
  if shared.Settings.SIDE_MODULE:
    webassembly.add_dylink_section(wasm_target, shared.Settings.RUNTIME_LINKED_LIBS)

  if shared.Settings.EMIT_EMSCRIPTEN_METADATA:
    diagnostics.warning('deprecated', 'We hope to remove support for EMIT_EMSCRIPTEN_METADATA. See https://github.com/emscripten-core/emscripten/issues/12231')
    webassembly.add_emscripten_metadata(wasm_target)

  if final_js:
    # pthreads memory growth requires some additional JS fixups
    if shared.Settings.USE_PTHREADS and shared.Settings.ALLOW_MEMORY_GROWTH:
      final_js = building.apply_wasm_memory_growth(final_js)

    # >=2GB heap support requires pointers in JS to be unsigned. rather than
    # require all pointers to be unsigned by default, which increases code size
    # a little, keep them signed, and just unsign them here if we need that.
    if shared.Settings.CAN_ADDRESS_2GB:
      final_js = building.use_unsigned_pointers_in_js(final_js)

    if shared.Settings.USE_ASAN:
      final_js = building.instrument_js_for_asan(final_js)

    if shared.Settings.SAFE_HEAP:
      final_js = building.instrument_js_for_safe_heap(final_js)

    if shared.Settings.OPT_LEVEL >= 2 and shared.Settings.DEBUG_LEVEL <= 2:
      # minify the JS. Do not minify whitespace if Closure is used, so that
      # Closure can print out readable error messages (Closure will then
      # minify whitespace afterwards)
      save_intermediate_with_wasm('preclean', wasm_target)
      final_js = building.minify_wasm_js(js_file=final_js,
                                         wasm_file=wasm_target,
                                         expensive_optimizations=will_metadce(),
                                         minify_whitespace=minify_whitespace() and not options.use_closure_compiler,
                                         debug_info=intermediate_debug_info)
      save_intermediate_with_wasm('postclean', wasm_target)

  if shared.Settings.ASYNCIFY_LAZY_LOAD_CODE:
    if not shared.Settings.ASYNCIFY:
      exit_with_error('ASYNCIFY_LAZY_LOAD_CODE requires ASYNCIFY')
    building.asyncify_lazy_load_code(wasm_target, debug=intermediate_debug_info)

  def preprocess_wasm2js_script():
    return read_and_preprocess(shared.path_from_root('src', 'wasm2js.js'), expand_macros=True)

  def run_closure_compiler():
    global final_js
    final_js = building.closure_compiler(final_js, pretty=not minify_whitespace(),
                                         extra_closure_args=options.closure_args)
    save_intermediate_with_wasm('closure', wasm_target)

  if final_js and options.use_closure_compiler:
    run_closure_compiler()

  symbols_file = shared.replace_or_append_suffix(target, '.symbols') if options.emit_symbol_map else None

  if shared.Settings.WASM2JS:
    if shared.Settings.WASM == 2:
      wasm2js_template = wasm_target + '.js'
      open(wasm2js_template, 'w').write(preprocess_wasm2js_script())
    else:
      wasm2js_template = final_js

    wasm2js = building.wasm2js(wasm2js_template,
                               wasm_target,
                               opt_level=shared.Settings.OPT_LEVEL,
                               minify_whitespace=minify_whitespace(),
                               use_closure_compiler=options.use_closure_compiler,
                               debug_info=debug_info,
                               symbols_file=symbols_file)
    if shared.Settings.WASM == 2:
      safe_copy(wasm2js, wasm2js_template)
      shared.try_delete(wasm2js)

    if shared.Settings.WASM != 2:
      final_js = wasm2js
      # if we only target JS, we don't need the wasm any more
      shared.try_delete(wasm_target)

    save_intermediate('wasm2js')

  # emit the final symbols, either in the binary or in a symbol map.
  # this will also remove debug info if we only kept it around in the intermediate invocations.
  # note that if we aren't emitting a binary (like in wasm2js) then we don't
  # have anything to do here.
  if options.emit_symbol_map and os.path.exists(wasm_target):
    building.handle_final_wasm_symbols(wasm_file=wasm_target, symbols_file=symbols_file, debug_info=debug_info)
    save_intermediate_with_wasm('symbolmap', wasm_target)

  if shared.Settings.DEBUG_LEVEL >= 3 and shared.Settings.SEPARATE_DWARF and os.path.exists(wasm_target):
    building.emit_debug_on_side(wasm_target, shared.Settings.SEPARATE_DWARF)

  if shared.Settings.WASM2C:
    wasm2c.do_wasm2c(wasm_target)

  # replace placeholder strings with correct subresource locations
  if final_js and shared.Settings.SINGLE_FILE and not shared.Settings.WASM2JS:
    js = open(final_js).read()

    if shared.Settings.MINIMAL_RUNTIME:
      js = do_replace(js, '{{{ WASM_BINARY_DATA }}}', base64_encode(open(wasm_target, 'rb').read()))
    else:
      js = do_replace(js, '<<< WASM_BINARY_FILE >>>', shared.JS.get_subresource_location(wasm_target))
    shared.try_delete(wasm_target)
    with open(final_js, 'w') as f:
      f.write(js)


def modularize():
  global final_js
  logger.debug('Modularizing, assigning to var ' + shared.Settings.EXPORT_NAME)
  src = open(final_js).read()

  return_value = shared.Settings.EXPORT_NAME
  if shared.Settings.WASM_ASYNC_COMPILATION:
    return_value += '.ready'
  if not shared.Settings.EXPORT_READY_PROMISE:
    return_value = '{}'

  src = '''
function(%(EXPORT_NAME)s) {
  %(EXPORT_NAME)s = %(EXPORT_NAME)s || {};

%(src)s

  return %(return_value)s
}
''' % {
    'EXPORT_NAME': shared.Settings.EXPORT_NAME,
    'src': src,
    'return_value': return_value
  }

  if shared.Settings.MINIMAL_RUNTIME and not shared.Settings.USE_PTHREADS:
    # Single threaded MINIMAL_RUNTIME programs do not need access to
    # document.currentScript, so a simple export declaration is enough.
    src = 'var %s=%s' % (shared.Settings.EXPORT_NAME, src)
  else:
    script_url_node = ""
    # When MODULARIZE this JS may be executed later,
    # after document.currentScript is gone, so we save it.
    # In EXPORT_ES6 + USE_PTHREADS the 'thread' is actually an ES6 module webworker running in strict mode,
    # so doesn't have access to 'document'. In this case use 'import.meta' instead.
    if shared.Settings.EXPORT_ES6 and shared.Settings.USE_ES6_IMPORT_META:
      script_url = "import.meta.url"
    else:
      script_url = "typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined"
      if shared.Settings.target_environment_may_be('node'):
        script_url_node = "if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;"
    src = '''
var %(EXPORT_NAME)s = (function() {
  var _scriptDir = %(script_url)s;
  %(script_url_node)s
  return (%(src)s);
})();
''' % {
      'EXPORT_NAME': shared.Settings.EXPORT_NAME,
      'script_url': script_url,
      'script_url_node': script_url_node,
      'src': src
    }

  final_js += '.modular.js'
  with open(final_js, 'w') as f:
    f.write(src)

    # 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)
    elif not shared.Settings.MINIMAL_RUNTIME:
      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})

  save_intermediate('modularized')


def module_export_name_substitution():
  global final_js
  logger.debug('Private module export name substitution with ' + shared.Settings.EXPORT_NAME)
  src = open(final_js).read()
  final_js += '.module_export_name_substitution.js'
  if shared.Settings.MINIMAL_RUNTIME:
    # In MINIMAL_RUNTIME the Module object is always present to provide the .asm.js/.wasm content
    replacement = shared.Settings.EXPORT_NAME
  else:
    replacement = "typeof %(EXPORT_NAME)s !== 'undefined' ? %(EXPORT_NAME)s : {}" % {"EXPORT_NAME": shared.Settings.EXPORT_NAME}
  with open(final_js, 'w') as f:
    src = re.sub(r'{\s*[\'"]?__EMSCRIPTEN_PRIVATE_MODULE_EXPORT_NAME_SUBSTITUTION__[\'"]?:\s*1\s*}', replacement, src)
    # For Node.js and other shell environments, create an unminified Module object so that
    # loading external .asm.js file that assigns to Module['asm'] works even when Closure is used.
    if shared.Settings.MINIMAL_RUNTIME and (shared.Settings.target_environment_may_be('node') or shared.Settings.target_environment_may_be('shell')):
      src = 'if(typeof Module==="undefined"){var Module={};}\n' + src
    f.write(src)
  save_intermediate('module_export_name_substitution')


def generate_traditional_runtime_html(target, options, js_target, target_basename,
                                      wasm_target, memfile):
  script = ScriptSource()

  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)

  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 {
    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

  if not shared.Settings.SINGLE_FILE:
    if memfile and not shared.Settings.MINIMAL_RUNTIME:
      # 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

    if not shared.Settings.WASM_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_target), script.inline)

    if shared.Settings.WASM == 2:
      # If target browser does not support WebAssembly, we need to load the .wasm.js file before the main .js file.
      script.un_src()
      script.inline = '''
          function loadMainJs() {
%s
          }
          if (!window.WebAssembly || location.search.indexOf('_rwasm=0') > 0) {
            // Current browser does not support WebAssembly, load the .wasm.js JavaScript fallback
            // before the main JS runtime.
            var wasm2js = document.createElement('script');
            wasm2js.src = '%s';
            wasm2js.onload = loadMainJs;
            document.body.appendChild(wasm2js);
          } else {
            // Current browser supports Wasm, proceed with loading the main JS runtime.
            loadMainJs();
          }
''' % (script.inline, shared.JS.get_subresource_location(wasm_target) + '.js')

  # when script.inline isn't empty, add required helper functions such as tryParseAsDataURI
  if script.inline:
    for filename in ('arrayUtils.js', 'base64Utils.js', 'URIUtils.js'):
      content = read_and_preprocess(shared.path_from_root('src', filename))
      script.inline = content + script.inline

    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_contents += open(js_target).read()
    shared.try_delete(js_target)
    script.src = None
    script.inline = js_contents

  html_contents = do_replace(shell, '{{{ SCRIPT }}}', script.replacement())
  html_contents = tools.line_endings.convert_line_endings(html_contents, '\n', options.output_eol)
  with open(target, 'wb') as f:
    f.write(asbytes(html_contents))


def minify_html(filename):
  if shared.Settings.DEBUG_LEVEL >= 2:
    return

  opts = []
  # -g1 and greater retain whitespace and comments in source
  if shared.Settings.DEBUG_LEVEL == 0:
    opts += ['--collapse-whitespace',
             '--collapse-inline-tag-whitespace',
             '--remove-comments',
             '--remove-tag-whitespace',
             '--sort-attributes',
             '--sort-class-name']
  # -g2 and greater do not minify HTML at all
  if shared.Settings.DEBUG_LEVEL <= 1:
    opts += ['--decode-entities',
             '--collapse-boolean-attributes',
             '--remove-attribute-quotes',
             '--remove-redundant-attributes',
             '--remove-script-type-attributes',
             '--remove-style-link-type-attributes',
             '--use-short-doctype',
             '--minify-css', 'true',
             '--minify-js', 'true']

  # html-minifier also has the following options, but they look unsafe for use:
  # '--remove-optional-tags': removes e.g. <head></head> and <body></body> tags from the page.
  #                           (Breaks at least browser.test_sdl2glshader)
  # '--remove-empty-attributes': removes all attributes with whitespace-only values.
  #                              (Breaks at least browser.test_asmfs_hello_file)
  # '--remove-empty-elements': removes all elements with empty contents.
  #                            (Breaks at least browser.test_asm_swapping)

  logger.debug('minifying HTML file ' + filename)
  size_before = os.path.getsize(filename)
  start_time = time.time()
  shared.check_call(shared.get_npm_cmd('html-minifier-terser') + [filename, '-o', filename] + opts, env=shared.env_with_node_in_path())

  elapsed_time = time.time() - start_time
  size_after = os.path.getsize(filename)
  delta = size_after - size_before
  logger.debug('HTML minification took {:.2f}'.format(elapsed_time) + ' seconds, and shrunk size of ' + filename + ' from ' + str(size_before) + ' to ' + str(size_after) + ' bytes, delta=' + str(delta) + ' ({:+.2f}%)'.format(delta * 100.0 / size_before))


def generate_html(target, options, js_target, target_basename,
                  wasm_target, memfile):
  logger.debug('generating HTML')

  if shared.Settings.EXPORT_NAME != 'Module' and \
     not shared.Settings.MINIMAL_RUNTIME and \
     options.shell_path == shared.path_from_root('src', 'shell.html'):
    # the minimal runtime shell HTML is designed to support changing the export
    # name, but the normal one does not support that currently
    exit_with_error('Customizing EXPORT_NAME requires that the HTML be customized to use that name (see https://github.com/emscripten-core/emscripten/issues/10086)')

  if shared.Settings.MINIMAL_RUNTIME:
    generate_minimal_runtime_html(target, options, js_target, target_basename)
  else:
    generate_traditional_runtime_html(target, options, js_target, target_basename,
                                      wasm_target, memfile)

  if shared.Settings.MINIFY_HTML and (shared.Settings.OPT_LEVEL >= 1 or shared.Settings.SHRINK_LEVEL >= 1):
    minify_html(target)


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:
    safe_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()
  proxy_client_src = do_replace(proxy_client_src, '{{{ filename }}}', proxy_worker_filename)
  proxy_client_src = do_replace(proxy_client_src, '{{{ IDBStore.js }}}', idb_store_src)
  return web_gl_client_src + '\n' + proxy_client_src


def process_libraries(libs, lib_dirs, temp_files):
  libraries = []
  consumed = []
  suffixes = list(STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS)

  # Find library files
  for i, lib in libs:
    logger.debug('looking for library "%s"', lib)

    found = False
    for prefix in LIB_PREFIXES:
      for suff in suffixes:
        name = prefix + lib + suff
        for lib_dir in lib_dirs:
          path = os.path.join(lib_dir, name)
          if os.path.exists(path):
            logger.debug('found library "%s" at %s', lib, path)
            temp_files.append((i, path))
            consumed.append(i)
            found = True
            break
        if found:
          break
      if found:
        break

    if not found:
      jslibs = building.map_to_js_libs(lib)
      if jslibs is not None:
        libraries += [(i, jslib) for jslib in jslibs]
        consumed.append(i)
      elif building.map_and_apply_to_settings(lib):
        consumed.append(i)

  shared.Settings.SYSTEM_JS_LIBRARIES += libraries

  # At this point processing SYSTEM_JS_LIBRARIES is finished, no more items will be added to it.
  # Sort the input list from (order, lib_name) pairs to a flat array in the right order.
  shared.Settings.SYSTEM_JS_LIBRARIES.sort(key=lambda lib: lib[0])
  shared.Settings.SYSTEM_JS_LIBRARIES = [lib[1] for lib in shared.Settings.SYSTEM_JS_LIBRARIES]
  return consumed


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):
  if not text:
    return 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]
    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-> ,"
      if not len(current):
        exit_with_error('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
          if index >= len(values):
            exit_with_error("unclosed quoted string. expected final character to be '%s' in '%s'" % (first, values[start]))
          new = values[index].rstrip()
          if new and new[-1] == first:
            if start == index:
              result.append(current.rstrip()[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

  def parse_string_list(text):
    text = text.rstrip()
    if text[-1] != ']':
      exit_with_error('unclosed opened string list. expected final character to be "]" in "%s"' % (text))
    inner = text[1:-1]
    if inner.strip() == "":
      return []
    return parse_string_list_members(inner)

  if text[0] == '[':
    # if json parsing fails, we fall back to our own parser, which can handle a few
    # simpler syntaxes
    try:
      return json.loads(text)
    except ValueError:
      return parse_string_list(text)

  try:
    return int(text)
  except ValueError:
    return parse_string_value(text)


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


def is_int(s):
  try:
    int(s)
    return True
  except ValueError:
    return False


def main(args):
  start_time = time.time()
  ret = run(args)
  logger.debug('total time: %.2f seconds', (time.time() - start_time))
  return ret


if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv))
  except KeyboardInterrupt:
    logger.warning('KeyboardInterrupt')
    sys.exit(1)
