#!/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 base64
import json
import logging
import os
import re
import shlex
import shutil
import stat
import sys
import time
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_copy
from tools.shared import run_process, read_and_preprocess, exit_with_error, DEBUG
from tools.shared import do_replace
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
from tools.settings import settings

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,
}

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')
SIMD_INTEL_FEATURE_TOWER = ['-msse', '-msse2', '-msse3', '-mssse3', '-msse4.1', '-msse4.2', '-mavx']
SIMD_NEON_FLAGS = ['-mfpu=neon']


# 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:
  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)
  return b64.decode('ascii')


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


class EmccOptions:
  def __init__(self):
    self.output_file = None
    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.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.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.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 settings.ASSERTIONS:
    return False
  return settings.OPT_LEVEL >= 3 or settings.SHRINK_LEVEL >= 1


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

  settings.ENVIRONMENT_MAY_BE_WEB = not settings.ENVIRONMENT or 'web' in environments
  settings.ENVIRONMENT_MAY_BE_WEBVIEW = not settings.ENVIRONMENT or 'webview' in environments
  settings.ENVIRONMENT_MAY_BE_NODE = not settings.ENVIRONMENT or 'node' in environments
  settings.ENVIRONMENT_MAY_BE_SHELL = not 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.
  settings.ENVIRONMENT_MAY_BE_WORKER = \
      not settings.ENVIRONMENT or \
      'worker' in environments or \
      (settings.ENVIRONMENT_MAY_BE_NODE and settings.USE_PTHREADS)

  if not settings.ENVIRONMENT_MAY_BE_WORKER and 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 settings.ENVIRONMENT_MAY_BE_WORKER and 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 settings.OPT_LEVEL >= 2 and settings.DEBUG_LEVEL == 0


def embed_memfile():
  return (settings.SINGLE_FILE or
          (settings.MEM_INIT_METHOD == 0 and
           (not settings.MAIN_MODULE and
            not settings.SIDE_MODULE and
            not 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 map of users settings {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 key, value in changes.items():
    key, value = standardize_setting_change(key, value)

    if key in 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 settings.legacy_settings and key in settings.alt_names:
      key = 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_CAP',
               '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=%s' % (filename, key, value))
      value = open(filename).read()
    else:
      value = value.replace('\\', '\\\\')

    existing = getattr(settings, user_key, None)
    expect_list = type(existing) == list

    try:
      value = parse_value(value, expect_list)
    except Exception as e:
      exit_with_error('a problem occurred in evaluating the content after a "-s", specifically "%s=%s": %s', key, value, 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.
    # We only currently worry about lists vs non-lists.
    if expect_list != (type(value) == list):
      exit_with_error('setting `%s` expects `%s` but got `%s`' % (user_key, type(existing), type(value)))

    setattr(settings, user_key, value)

    if key == 'EXPORTED_FUNCTIONS':
      # used for warnings in emscripten.py
      settings.USER_EXPORTED_FUNCTIONS = settings.EXPORTED_FUNCTIONS.copy()

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


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 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():
  # 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 = settings.INCLUDE_FULL_LIBRARY
  try:
    # Temporarily define INCLUDE_FULL_LIBRARY since we want a full list
    # of all available JS library functions.
    settings.INCLUDE_FULL_LIBRARY = True
    settings.ONLY_CALC_JS_SYMBOLS = True
    emscripten.generate_struct_info()
    glue, forwarded_data = emscripten.compile_settings()
    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:
    settings.ONLY_CALC_JS_SYMBOLS = False
    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 get_binaryen_passes():
  # 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 = settings.OPT_LEVEL >= 2

  passes = []
  # safe heap must run before post-emscripten, so post-emscripten can apply the sbrk ptr
  if settings.SAFE_HEAP:
    passes += ['--safe-heap']
  if settings.MEMORY64 == 2:
    passes += ['--memory64-lowering']
  if run_binaryen_optimizer:
    passes += ['--post-emscripten']
    if not settings.EXIT_RUNTIME:
      passes += ['--no-exit-runtime']
  if run_binaryen_optimizer:
    passes += [building.opt_level_to_str(settings.OPT_LEVEL, settings.SHRINK_LEVEL)]
  elif 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 settings.GLOBAL_BASE >= 1024:
    passes += ['--low-memory-unused']
  if settings.AUTODEBUG:
    # adding '--flatten' here may make these even more effective
    passes += ['--instrument-locals']
    passes += ['--log-execution']
    passes += ['--instrument-memory']
    if settings.LEGALIZE_JS_FFI:
      # legalize it again now, as the instrumentation may need it
      passes += ['--legalize-js-interface']
  if 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 settings.ASYNCIFY:
    passes += ['--asyncify']
    if settings.ASSERTIONS:
      passes += ['--pass-arg=asyncify-asserts']
    if settings.ASYNCIFY_ADVISE:
      passes += ['--pass-arg=asyncify-verbose']
    if settings.ASYNCIFY_IGNORE_INDIRECT:
      passes += ['--pass-arg=asyncify-ignore-indirect']
    passes += ['--pass-arg=asyncify-imports@%s' % ','.join(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 settings.ASYNCIFY_REMOVE:
      check_human_readable_list(settings.ASYNCIFY_REMOVE)
      passes += ['--pass-arg=asyncify-removelist@%s' % ','.join(settings.ASYNCIFY_REMOVE)]
    if settings.ASYNCIFY_ADD:
      check_human_readable_list(settings.ASYNCIFY_ADD)
      passes += ['--pass-arg=asyncify-addlist@%s' % ','.join(settings.ASYNCIFY_ADD)]
    if settings.ASYNCIFY_ONLY:
      check_human_readable_list(settings.ASYNCIFY_ONLY)
      passes += ['--pass-arg=asyncify-onlylist@%s' % ','.join(settings.ASYNCIFY_ONLY)]
  if 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 settings.SIDE_MODULE:
    passes += ['--zero-filled-memory']

  if settings.BINARYEN_EXTRA_PASSES:
    # BINARYEN_EXTRA_PASSES is comma-separated, and we support both '-'-prefixed and
    # unprefixed pass names
    extras = 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_split_module(wasm_file):
  os.rename(wasm_file, wasm_file + '.orig')
  args = ['--instrument']
  building.run_binaryen_command('wasm-split', wasm_file + '.orig', outfile=wasm_file, args=args)


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:]
  arg = arg.split('=')[0]
  return arg.isidentifier() and arg.isupper()


def process_dynamic_libs(dylibs):
  for dylib in dylibs:
    imports = webassembly.get_imports(dylib)
    new_exports = []
    for imp in imports:
      if imp.kind not in (webassembly.ExternType.FUNC, webassembly.ExternType.GLOBAL):
        continue
      new_exports.append(imp.field)
    logger.debug('Adding exports based on `%s`: %s', dylib, new_exports)
    settings.EXPORTED_FUNCTIONS.extend(shared.asmjs_mangle(e) for e in new_exports)
    settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.extend(new_exports)

    exports = webassembly.get_exports(dylib)
    for export in exports:
      settings.SIDE_MODULE_EXPORTS.append(shared.asmjs_mangle(export.name))


def unmangle_symbols_from_cmdline(symbols):
  def unmangle(x):
    return x.replace('.', ' ').replace('#', '&').replace('?', ',')

  if type(symbols) is list:
    return [unmangle(x) for x in symbols]
  return unmangle(symbols)


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 emsdk_ldflags(user_args):
  if os.environ.get('EMMAKEN_NO_SDK'):
    return []

  library_paths = [
     shared.Cache.get_lib_dir(absolute=True)
  ]
  ldflags = ['-L' + l for l in library_paths]

  if '-nostdlib' in user_args:
    return ldflags

  # TODO(sbc): Add system libraries here rather than conditionally including
  # them via .symbols files.
  libraries = []
  ldflags += ['-l' + l for l in libraries]

  return ldflags


def emsdk_cflags(user_args):
  cflags = ['--sysroot=' + shared.Cache.get_sysroot_dir(absolute=True)]

  def array_contains_any_of(hay, needles):
    for n in needles:
      if n in hay:
        return True

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER) or array_contains_any_of(user_args, SIMD_NEON_FLAGS):
    if '-msimd128' not in user_args:
      exit_with_error('Passing any of ' + ', '.join(SIMD_INTEL_FEATURE_TOWER + SIMD_NEON_FLAGS) + ' flags also requires passing -msimd128!')
    cflags += ['-D__SSE__=1']

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[1:]):
    cflags += ['-D__SSE2__=1']

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[2:]):
    cflags += ['-D__SSE3__=1']

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[3:]):
    cflags += ['-D__SSSE3__=1']

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[4:]):
    cflags += ['-D__SSE4_1__=1']

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[5:]):
    cflags += ['-D__SSE4_2__=1']

  if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[6:]):
    cflags += ['-D__AVX__=1']

  if array_contains_any_of(user_args, SIMD_NEON_FLAGS):
    cflags += ['-D__ARM_NEON__=1']

  return cflags + ['-Xclang', '-iwithsysroot' + os.path.join('/include', 'compat')]


def get_clang_flags():
  return ['-target', get_llvm_target()]


def get_llvm_target():
  if settings.MEMORY64:
    return 'wasm64-unknown-emscripten'
  else:
    return 'wasm32-unknown-emscripten'


cflags = None


def get_cflags(options, user_args):
  global cflags
  if cflags:
    return cflags

  # 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 = get_clang_flags()

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

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

  if not 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 settings.DISABLE_EXCEPTION_CATCHING and not settings.EXCEPTION_HANDLING:
    cflags.append('-fignore-exceptions')

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

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

  if settings.LTO:
    cflags.append('-flto=' + 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]

  # Set the LIBCPP ABI version to at least 2 so that we get nicely aligned string
  # data and other nice fixes.
  cflags += [# '-fno-threadsafe-statics', # disabled due to issue 1289
             '-D__EMSCRIPTEN_major__=' + str(shared.EMSCRIPTEN_VERSION_MAJOR),
             '-D__EMSCRIPTEN_minor__=' + str(shared.EMSCRIPTEN_VERSION_MINOR),
             '-D__EMSCRIPTEN_tiny__=' + str(shared.EMSCRIPTEN_VERSION_TINY),
             '-D_LIBCPP_ABI_VERSION=2']

  # For compatability with the fastcomp compiler that defined these
  cflags += ['-Dunix',
             '-D__unix',
             '-D__unix__']

  # Changes to default clang behavior

  # Implicit functions can cause horribly confusing function pointer type errors, see #2175
  # If your codebase really needs them - very unrecommended! - you can disable the error with
  #   -Wno-error=implicit-function-declaration
  # or disable even a warning about it with
  #   -Wno-implicit-function-declaration
  cflags += ['-Werror=implicit-function-declaration']

  system_libs.add_ports_cflags(cflags, settings)

  if os.environ.get('EMMAKEN_NO_SDK') or '-nostdinc' in user_args:
    return cflags

  cflags += emsdk_cflags(user_args)
  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 get_secondary_target(target, ext):
  # Depending on the output format emscripten creates zero or more secondary
  # output files (e.g. the .wasm file when creating JS output, or the
  # .js and the .wasm file when creating html output.
  # Thus function names the secondary output files, while ensuring they
  # never collide with the primary one.
  base = unsuffixed(target)
  if get_file_suffix(target) == ext:
    base += '_'
  return base + ext


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):
  # 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, WebAssembly, 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('''%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.
  ''' % (version_string(), 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(version_string(), file=sys.stderr)
    return shared.check_call([clang, '-v'] + get_clang_flags(), check=False).returncode

  if '-dumpmachine' in args:
    print(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

  shared.check_sanity()

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

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

    newargs = args.copy()

    # 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)

    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
      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:
      settings.MEMORYPROFILER = 1

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

    if options.memory_init_file is None:
      options.memory_init_file = settings.OPT_LEVEL >= 2

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

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

    # Find input files

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

    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('-'):
        # we already removed -o <target>, so all these should be inputs
        newargs[i] = ''
        # 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 HEADER_ENDINGS:
          has_header_inputs = True
        if file_suffix in STATICLIB_ENDINGS and 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)
        if file_suffix in DYNAMICLIB_ENDINGS and not building.is_bitcode(arg) and not building.is_wasm(arg):
          # For shared libraries that are neither bitcode nor wasm, assuming its local native
          # library and attempt to find a library by the same name in our own library path.
          # TODO(sbc): Do we really need this feature?  See test_other.py:test_local_link
          libname = unsuffixed_basename(arg).lstrip('lib')
          libs.append((i, libname))
        else:
          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]

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

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

    strict_cmdline = settings_map.get('STRICT')
    if strict_cmdline:
      settings.STRICT = int(strict_cmdline)

    # Apply optimization level settings

    if settings.OPT_LEVEL >= 1:
      settings.ASSERTIONS = 0
    if settings.SHRINK_LEVEL >= 2:
      settings.EVAL_CTORS = 1

    # For users that opt out of WARN_ON_UNDEFINED_SYMBOLS we assume they also
    # want to opt out of ERROR_ON_UNDEFINED_SYMBOLS.
    if settings_map.get('WARN_ON_UNDEFINED_SYMBOLS') == '0':
      settings.ERROR_ON_UNDEFINED_SYMBOLS = 0

    if settings.MINIMAL_RUNTIME or settings_map.get('MINIMAL_RUNTIME') in ('1', '2'):
      # Remove the default exported functions 'malloc', 'free', etc. those should only be linked in if used
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []

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

    specified_target = options.output_file

    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()
      settings.EXIT_RUNTIME = 1
      # use node.js raw filesystem access, to behave just like a native executable
      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 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

    settings.TARGET_BASENAME = target_basename = unsuffixed_basename(target)

    if settings.EXTRA_EXPORTED_RUNTIME_METHODS:
      diagnostics.warning('deprecated', 'EXTRA_EXPORTED_RUNTIME_METHODS is deprecated, please use EXPORTED_RUNTIME_METHODS instead')
      settings.EXPORTED_RUNTIME_METHODS += settings.EXTRA_EXPORTED_RUNTIME_METHODS

    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 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:
      settings.EXPORT_ES6 = 1
      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 = get_secondary_target(target, '.wasm')

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

    shared.verify_settings()

    if (options.oformat == OFormat.WASM or settings.PURE_WASI) and not 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.
      settings.STANDALONE_WASM = 1

    if settings.LZ4:
      settings.EXPORTED_RUNTIME_METHODS += ['LZ4']

    if settings.WASM2C:
      # wasm2c only makes sense with standalone wasm - there will be no JS,
      # just wasm and then C
      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
      settings.WASM_BIGINT = 1

    if options.no_entry:
      settings.EXPECT_MAIN = 0
    elif settings.STANDALONE_WASM:
      if '_main' in 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_map:
        if '_main' not in settings.USER_EXPORTED_FUNCTIONS:
          settings.EXPECT_MAIN = 0
      else:
        assert not settings.EXPORTED_FUNCTIONS
        settings.EXPORTED_FUNCTIONS = ['_main']

    if settings.STANDALONE_WASM:
      # In STANDALONE_WASM mode we either build a command or a reactor.
      # See https://github.com/WebAssembly/WASI/blob/main/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_map:
        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).')
      settings.EXIT_RUNTIME = 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 settings.MAIN_MODULE:
      dylibs = [i[1] for i in input_files if get_file_suffix(i[1]) in DYNAMICLIB_ENDINGS]
      process_dynamic_libs(dylibs)

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

    # Note the exports the user requested
    building.user_requested_exports = settings.EXPORTED_FUNCTIONS.copy()

    def default_setting(name, new_default):
      if name not in settings_map:
        setattr(settings, name, new_default)

    # -s ASSERTIONS=1 implies basic stack overflow checks, and ASSERTIONS=2
    # implies full stack overflow checks.
    if settings.ASSERTIONS:
      # However, we don't set this default in PURE_WASI, or when we are linking without standard
      # libraries because STACK_OVERFLOW_CHECK depends on emscripten_stack_get_end which is defined
      # in libcompiler-rt.
      if not settings.PURE_WASI and '-nostdlib' not in newargs and '-nodefaultlibs' not in newargs:
        default_setting('STACK_OVERFLOW_CHECK', max(settings.ASSERTIONS, settings.STACK_OVERFLOW_CHECK))

    if settings.LLD_REPORT_UNDEFINED or 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
      settings.IGNORE_MISSING_MAIN = 0

    # It is unlikely that developers targeting "native web" APIs with MINIMAL_RUNTIME need
    # errno support by default.
    if settings.MINIMAL_RUNTIME:
      default_setting('SUPPORT_ERRNO', 0)

    if settings.STRICT:
      default_setting('STRICT_JS', 1)
      default_setting('AUTO_JS_LIBRARIES', 0)
      default_setting('AUTO_NATIVE_LIBRARIES', 0)
      default_setting('AUTO_ARCHIVE_INDEXES', 0)
      default_setting('IGNORE_MISSING_MAIN', 0)
      default_setting('DEFAULT_TO_CXX', 0)

    # Default to TEXTDECODER=2 (always use TextDecoder to decode UTF-8 strings)
    # in -Oz builds, since custom decoder for UTF-8 takes up space.
    # In pthreads enabled builds, TEXTDECODER==2 may not work, see
    # https://github.com/whatwg/encoding/issues/172
    # When supporting shell environments, do not do this as TextDecoder is not
    # widely supported there.
    if settings.SHRINK_LEVEL >= 2 and not settings.USE_PTHREADS and \
       not settings.ENVIRONMENT_MAY_BE_SHELL:
      default_setting('TEXTDECODER', 2)

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

    # Use settings

    if 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 settings.WASM == 2 and settings.SINGLE_FILE:
      exit_with_error('cannot have both WASM=2 and SINGLE_FILE enabled at the same time')

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

    if settings.MINIMAL_RUNTIME_STREAMING_WASM_COMPILATION and 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 settings.MINIMAL_RUNTIME:
        exit_with_error('--emrun is not compatible with -s MINIMAL_RUNTIME=1')
      settings.EXPORTED_RUNTIME_METHODS.append('addOnExit')

    if options.use_closure_compiler:
      settings.USE_CLOSURE_COMPILER = options.use_closure_compiler

    if 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".' % settings.CLOSURE_WARNINGS)

    # Include dynCall() function by default in DYNCALLS builds in classic runtime; in MINIMAL_RUNTIME, must add this explicitly.
    if settings.DYNCALLS and not settings.MINIMAL_RUNTIME:
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$dynCall']

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

    # If we are including the entire JS library then we know for sure we will, by definition,
    # require all the reverse dependencies.
    if settings.INCLUDE_FULL_LIBRARY:
      default_setting('REVERSE_DEPS', 'all')

    if settings.MAIN_MODULE or settings.SIDE_MODULE:
      if settings.MAIN_MODULE == 1 or settings.SIDE_MODULE == 1:
        settings.LINKABLE = 1
        settings.EXPORT_ALL = 1
      settings.RELOCATABLE = 1

    if settings.RELOCATABLE:
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += [
          '$reportUndefinedSymbols',
          '$relocateExports',
          '$GOTHandler',
          '$getDylinkMetadata',
          '__heap_base',
          '__stack_pointer',
      ]
      settings.EXPORTED_FUNCTIONS += [
          # This needs to be exported on the Module object too so it's visible
          # to side modules too.
          '___heap_base',
          # Unconditional dependency in library_dylink.js
          '_setThrew',
      ]
      if settings.MINIMAL_RUNTIME:
        exit_with_error('MINIMAL_RUNTIME is not compatible with relocatable output')
      if settings.WASM2JS:
        exit_with_error('WASM2JS is not compatible with relocatable output')
      # shared modules need memory utilities to allocate their memory
      settings.EXPORTED_RUNTIME_METHODS += ['allocate']
      settings.ALLOW_TABLE_GROWTH = 1

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

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

    if settings.ASYNCIFY_LAZY_LOAD_CODE:
      settings.ASYNCIFY = 1

    if settings.ASYNCIFY:
      # See: https://github.com/emscripten-core/emscripten/issues/12065
      # See: https://github.com/emscripten-core/emscripten/issues/12066
      settings.DYNCALLS = 1
      settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_base',
                                      '_emscripten_stack_get_end',
                                      '_emscripten_stack_set_limits']

    settings.ASYNCIFY_ADD = unmangle_symbols_from_cmdline(settings.ASYNCIFY_ADD)
    settings.ASYNCIFY_REMOVE = unmangle_symbols_from_cmdline(settings.ASYNCIFY_REMOVE)
    settings.ASYNCIFY_ONLY = unmangle_symbols_from_cmdline(settings.ASYNCIFY_ONLY)

    # 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 SIMD_INTEL_FEATURE_TOWER and x not in 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 settings.SUPPORT_BIG_ENDIAN:
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += [
        '$LE_HEAP_STORE_U16',
        '$LE_HEAP_STORE_I16',
        '$LE_HEAP_STORE_U32',
        '$LE_HEAP_STORE_I32',
        '$LE_HEAP_STORE_F32',
        '$LE_HEAP_STORE_F64',
        '$LE_HEAP_LOAD_U16',
        '$LE_HEAP_LOAD_I16',
        '$LE_HEAP_LOAD_U32',
        '$LE_HEAP_LOAD_I32',
        '$LE_HEAP_LOAD_F32',
        '$LE_HEAP_LOAD_F64'
      ]

    if settings.STACK_OVERFLOW_CHECK:
      # The basic writeStackCookie/checkStackCookie mechanism just needs to know where the end
      # of the stack is.
      settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_end', '_emscripten_stack_get_free']
      if settings.STACK_OVERFLOW_CHECK == 2:
        # The full checking done by binaryen's `StackCheck` pass also needs to know the base of the
        # stack.
        settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_base']

      # We call one of these two functions during startup which caches the stack limits
      # in wasm globals allowing get_base/get_free to be super fast.
      # See compiler-rt/stack_limits.S.
      if settings.RELOCATABLE:
        settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_set_limits']
      else:
        settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_init']

    if settings.MODULARIZE:
      if settings.PROXY_TO_WORKER:
        exit_with_error('-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 settings.MINIMAL_RUNTIME and options.oformat == OFormat.HTML and not settings.USE_PTHREADS:
        settings.EXPORT_READY_PROMISE = 0

    if settings.LEGACY_VM_SUPPORT:
      if settings.WASM2JS:
        settings.POLYFILL_OLD_MATH_FUNCTIONS = 1

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

    if settings.MIN_CHROME_VERSION <= 37:
      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 settings.WASM2JS:
      settings.POLYFILL_OLD_MATH_FUNCTIONS = 0
      settings.WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG = 0

    forced_stdlibs = []

    if settings.STB_IMAGE and final_suffix in EXECUTABLE_ENDINGS:
      forced_stdlibs.append('libstb_image')
      settings.EXPORTED_FUNCTIONS += ['_stbi_load', '_stbi_load_from_memory', '_stbi_image_free']

    if settings.USE_WEBGL2:
      settings.MAX_WEBGL_VERSION = 2

    if not settings.GL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS and 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!')

    if settings.ASMFS and final_suffix in EXECUTABLE_ENDINGS:
      forced_stdlibs.append('libasmfs')
      settings.FILESYSTEM = 0
      settings.SYSCALLS_REQUIRE_FILESYSTEM = 0
      settings.FETCH = 1
      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 settings.USES_DYNAMIC_ALLOC:
      settings.MALLOC = 'none'

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

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

    if settings.DEMANGLE_SUPPORT:
      settings.EXPORTED_FUNCTIONS += ['___cxa_demangle']

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

    if settings.EMBIND:
      forced_stdlibs.append('libembind')

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

    if settings.RELOCATABLE and not 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 settings.SIDE_MODULE and settings.GLOBAL_BASE != -1:
      exit_with_error('Cannot set GLOBAL_BASE when building SIDE_MODULE')

    if settings.RELOCATABLE:
      default_setting('ERROR_ON_UNDEFINED_SYMBOLS', 0)
      default_setting('WARN_ON_UNDEFINED_SYMBOLS', 0)

    if 'DISABLE_EXCEPTION_CATCHING' in settings_map and 'EXCEPTION_CATCHING_ALLOWED' in settings_map:
      # If we get here then the user specified both DISABLE_EXCEPTION_CATCHING and EXCEPTION_CATCHING_ALLOWED
      # on the command line.  This is no longer valid so report either an error or a warning (for
      # backwards compat with the old `DISABLE_EXCEPTION_CATCHING=2`
      if settings_map['DISABLE_EXCEPTION_CATCHING'] in ('0', '2'):
        diagnostics.warning('deprecated', 'DISABLE_EXCEPTION_CATCHING=X is no longer needed when specifying EXCEPTION_CATCHING_ALLOWED')
      else:
        exit_with_error('DISABLE_EXCEPTION_CATCHING and EXCEPTION_CATCHING_ALLOWED are mutually exclusive')

    if settings.EXCEPTION_CATCHING_ALLOWED:
      settings.DISABLE_EXCEPTION_CATCHING = 0

    if settings.DISABLE_EXCEPTION_THROWING and not 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.use_preload_plugins or len(options.preload_files) or len(options.embed_files):
      if 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
      settings.FORCE_FILESYSTEM = 1

    if settings.PROXY_TO_WORKER or options.use_preload_plugins:
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$Browser']

    if not 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)
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += [
        '$keepRuntimeAlive',
        '$demangle',
        '$demangleAll',
        '$jsStackTrace',
        '$stackTrace'
      ]

    if 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 settings.EXIT_RUNTIME or settings.ASSERTIONS:
        settings.EXPORTED_FUNCTIONS += ['_fflush']

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

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

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

    if settings.ALLOW_MEMORY_GROWTH:
      # 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.
      default_setting('ABORTING_MALLOC', 0)

    if settings.USE_PTHREADS:
      if settings.USE_PTHREADS == 2:
        exit_with_error('USE_PTHREADS=2 is no longer supported')
      if 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 may not work with a view of a SharedArrayBuffer, see https://github.com/whatwg/encoding/issues/172
      settings.TEXTDECODER = 0
      settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_pthread.js')))
      newargs += ['-pthread']
      settings.EXPORTED_FUNCTIONS += [
        '___emscripten_pthread_data_constructor',
        '___pthread_tsd_run_dtors',
        '__emscripten_call_on_thread',
        '__emscripten_do_dispatch_to_thread',
        '__emscripten_main_thread_futex',
        '__emscripten_thread_init',
        '_emscripten_current_thread_process_queued_calls',
        '__emscripten_allow_main_runtime_queued_calls',
        '_emscripten_futex_wake',
        '_emscripten_get_global_libc',
        '_emscripten_main_browser_thread_id',
        '_emscripten_main_thread_process_queued_calls',
        '_emscripten_register_main_browser_thread_id',
        '_emscripten_run_in_main_runtime_thread_js',
        '_emscripten_stack_set_limits',
        '_emscripten_sync_run_in_main_thread_2',
        '_emscripten_sync_run_in_main_thread_4',
        '_emscripten_tls_init',
        '_pthread_self',
      ]
      # Some of these symbols are using by worker.js but otherwise unreferenced.
      # Because emitDCEGraph only considered the main js file, and not worker.js
      # we have explictly mark these symbols as user-exported so that they will
      # kept alive through DCE.
      # TODO: Find a less hacky way to do this, perhaps by also scanning worker.js
      # for roots.
      building.user_requested_exports.append('_emscripten_tls_init')
      building.user_requested_exports.append('_emscripten_current_thread_process_queued_calls')

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

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

      settings.EXPORTED_RUNTIME_METHODS += [
        'addRunDependency',
        'removeRunDependency',
      ]

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

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

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

      if settings.PROXY_TO_PTHREAD:
        settings.EXPORTED_FUNCTIONS += ['_emscripten_proxy_main']

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

      include_and_export('establishStackSpace')
      include_and_export('invokeEntryPoint')
      if not settings.MINIMAL_RUNTIME:
        # noExitRuntime does not apply to MINIMAL_RUNTIME.
        include_and_export('keepRuntimeAlive')

      if settings.MODULARIZE:
        if 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:
        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 settings.MINIMAL_RUNTIME:
          settings.EXPORTED_RUNTIME_METHODS += ['ExitStatus']

      if settings.SIDE_MODULE:
        diagnostics.warning('experimental', '-s SIDE_MODULE + pthreads is experimental')
      elif settings.MAIN_MODULE:
        diagnostics.warning('experimental', '-s MAIN_MODULE + pthreads is experimental')
      elif settings.LINKABLE:
        diagnostics.warning('experimental', '-s LINKABLE + pthreads is experimental')

      if 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 settings.PROXY_TO_PTHREAD:
        exit_with_error('-s PROXY_TO_PTHREAD=1 requires -s USE_PTHREADS to work!')

    def check_memory_setting(setting):
      if settings[setting] % webassembly.WASM_PAGE_SIZE != 0:
        exit_with_error(f'{setting} must be a multiple of WebAssembly page size (64KiB), was {settings[setting]}')

    check_memory_setting('INITIAL_MEMORY')
    if settings.INITIAL_MEMORY >= 2 * 1024 * 1024 * 1024:
      exit_with_error('INITIAL_MEMORY must be less than 2GB due to current spec limitations')
    if settings.INITIAL_MEMORY < settings.TOTAL_STACK:
      exit_with_error(f'INITIAL_MEMORY must be larger than TOTAL_STACK, was {settings.INITIAL_MEMORY} (TOTAL_STACK={settings.TOTAL_STACK})')
    if settings.MAXIMUM_MEMORY != -1:
      check_memory_setting('MAXIMUM_MEMORY')
    if settings.MEMORY_GROWTH_LINEAR_STEP != -1:
      check_memory_setting('MEMORY_GROWTH_LINEAR_STEP')
    if settings.USE_PTHREADS and settings.ALLOW_MEMORY_GROWTH and settings.MAXIMUM_MEMORY == -1:
      exit_with_error('If pthreads and memory growth are enabled, MAXIMUM_MEMORY must be set')

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

    if settings.MODULARIZE and not 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 wasm module exports in outer scope one by one, disable minifying
    # 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 settings.DECLARE_ASM_MODULE_EXPORTS or 'exports.js' in [x for _, x in libs]:
      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 \
        settings.OPT_LEVEL >= 2 and \
        settings.DEBUG_LEVEL <= 2 and \
        options.oformat not in (OFormat.WASM, OFormat.BARE) and \
        not settings.LINKABLE and \
        not settings.STANDALONE_WASM and \
        not settings.AUTODEBUG and \
        not settings.ASSERTIONS and \
        not settings.RELOCATABLE and \
        not settings.ASYNCIFY_LAZY_LOAD_CODE and \
            settings.MINIFY_ASMJS_EXPORT_NAMES:
      settings.MINIFY_WASM_IMPORTS_AND_EXPORTS = 1
      settings.MINIFY_WASM_IMPORTED_MODULES = 1

    if 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 settings.ASSERTIONS and 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.
        settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$warnOnce']

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

    if settings.MODULARIZE and 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 settings.STANDALONE_WASM:
      if settings.USE_PTHREADS:
        exit_with_error('STANDALONE_WASM does not support pthreads yet')
      if 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')
      # the wasm must be runnable without the JS, so there cannot be anything that
      # requires JS legalization
      settings.LEGALIZE_JS_FFI = 0

    # TODO(sbc): Remove WASM2JS here once the size regression it would introduce has been fixed.
    if settings.USE_PTHREADS or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE or settings.WASM2JS:
      settings.IMPORTED_MEMORY = 1

    if settings.WASM_BIGINT:
      settings.LEGALIZE_JS_FFI = 0

    if settings.SINGLE_FILE:
      settings.GENERATE_SOURCE_MAP = 0

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

    if 'MEM_INIT_METHOD' in settings_map:
      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 settings.WASM2JS:
      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.
      settings.MEM_INIT_IN_WASM = not options.memory_init_file or settings.SINGLE_FILE or 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
      settings.MEM_INIT_IN_WASM = True

    # wasm side modules have suffix .wasm
    if 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:
      settings.USE_OFFSET_CONVERTER = 1
      settings.EXPORTED_FUNCTIONS += [
          '_memalign',
          '_emscripten_builtin_memalign',
          '_emscripten_builtin_malloc',
          '_emscripten_builtin_free',
          '___heap_base',
          '___global_base'
      ]

    if settings.USE_OFFSET_CONVERTER and settings.USE_PTHREADS:
      settings.EXPORTED_RUNTIME_METHODS += ['WasmOffsetConverter']

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

    if 'leak' in sanitize:
      settings.USE_LSAN = 1
      settings.EXIT_RUNTIME = 1

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

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

      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 settings.ASAN_SHADOW_SIZE != -1:
        diagnostics.warning('emcc', 'ASAN_SHADOW_SIZE is ignored and will be removed in a future release')

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

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

      shadow_size = max_mem // 8
      settings.GLOBAL_BASE = shadow_size

      if 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 settings.LINKABLE:
        exit_with_error('ASan does not support dynamic linking')

    if sanitize and settings.GENERATE_SOURCE_MAP:
      settings.LOAD_SOURCE_MAP = 1

    if settings.LOAD_SOURCE_MAP and settings.USE_PTHREADS:
      settings.EXPORTED_RUNTIME_METHODS += ['WasmSourceMap']

    if 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
      settings.GLOBAL_BASE = 1024

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

    if not settings.DISABLE_EXCEPTION_CATCHING:
      # If not for LTO builds, we could handle these by adding deps_info.py
      # entries for __cxa_find_matching_catch_* functions.  However, under
      # LTO these symbols don't exist prior the linking.
      settings.EXPORTED_FUNCTIONS += ['___cxa_is_pointer_type', '___cxa_can_catch']

    if settings.ASYNCIFY:
      if not settings.ASYNCIFY_IGNORE_INDIRECT:
        # 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.
        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 settings.USE_PTHREADS:
        settings.ASYNCIFY_IMPORTS += ['__call_main']
      # add the default imports
      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

      settings.ASYNCIFY_IMPORTS = [get_full_import_name(i) for i in settings.ASYNCIFY_IMPORTS]

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

    if settings.NODE_CODE_CACHING:
      if settings.WASM_ASYNC_COMPILATION:
        exit_with_error('NODE_CODE_CACHING requires sync compilation (WASM_ASYNC_COMPILATION=0)')
      if not shared.target_environment_may_be('node'):
        exit_with_error('NODE_CODE_CACHING only works in node, but target environments do not include it')
      if 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 settings.ALLOW_MEMORY_GROWTH:
      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['emscripten_trace_report_memory_layout']
      settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_current',
                                      '_emscripten_stack_get_base',
                                      '_emscripten_stack_get_end']

    # Any "pointers" passed to JS will now be i64's, in both modes.
    if settings.MEMORY64:
      if settings_map.get('WASM_BIGINT') == '0':
        exit_with_error('MEMORY64 is not compatible with WASM_BIGINT=0')
      settings.WASM_BIGINT = 1

    # 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 settings.INITIAL_MEMORY > 2 * 1024 * 1024 * 1024 or \
       (settings.ALLOW_MEMORY_GROWTH and
        (settings.MAXIMUM_MEMORY < 0 or
         settings.MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024)):
      settings.CAN_ADDRESS_2GB = 1

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

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

  linker_inputs = []
  if options.post_link:
    process_libraries(libs, lib_dirs, linker_inputs)
    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

  ## Compile source code to object files
  logger.debug('compiling inputs')
  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)]
    system_libs.ensure_sysroot()

    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 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):
      return get_compiler(use_cxx(src_file)) + get_cflags(options, args) + compile_args + [src_file]

    def get_clang_command_asm(src_file):
      return get_compiler(use_cxx(src_file)) + get_clang_flags() + 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.check_call(cmd)
      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.check_call(cmd)
        return 0

    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)
      if not compile_only:
        linker_inputs.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)
      if not has_dash_c:
        cmd += ['-c']
      cmd += ['-o', output_file]
      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)
        linker_inputs.append((i, input_file))
      elif building.is_ar(input_file):
        logger.debug('using static library: ' + input_file)
        ensure_archive_index(input_file)
        linker_inputs.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)
        linker_inputs.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])
    for f in linker_inputs:
      diagnostics.warning('unused-command-line-argument', "%s: linker input file unused because linking not done" % f[1])
    return 0

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

  ldflags = emsdk_ldflags(newargs)
  for f in ldflags:
    add_link_flag(sys.maxsize, f)

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

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

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

  if link_to_object:
    with ToolchainProfiler.profile_block('linking to object file'):
      logger.debug('link_to_object: ' + str(linker_arguments) + ' -> ' + target)
      building.link_to_object(linker_arguments, target)
      logger.debug('stopping after linking to object file')
      return 0

  if final_suffix in ('.o', '.bc', '.so', '.dylib') and not 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'):
    extra_files_to_link = []
    # link in ports and system libraries, if necessary
    if not settings.SIDE_MODULE:
      # Ports are always linked into the main module, never the size module.
      extra_files_to_link += system_libs.get_ports_libs(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 settings.STRICT and '-nostdlib++' not in newargs:
        link_as_cxx = True
      extra_files_to_link += system_libs.calculate([f for _, f in sorted(linker_inputs)] + extra_files_to_link, link_as_cxx, forced=forced_stdlibs)
    linker_arguments += 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 settings.EXPORTED_FUNCTIONS to remove any
  # duplication between functions added by the driver/libraries and function
  # specified by the user
  settings.EXPORTED_FUNCTIONS = dedup_list(settings.EXPORTED_FUNCTIONS)

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

    # 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 settings.LLD_REPORT_UNDEFINED and settings.ERROR_ON_UNDEFINED_SYMBOLS:
      js_funcs = get_all_js_syms()
      log_time('JS symbol generation')
    building.link_lld(linker_arguments, 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_arguments:
      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 move_file(src, dst):
  logging.debug('move: %s -> %s', src, dst)
  if os.path.isdir(dst):
    exit_with_error(f'cannot write output file `{dst}`: Is a directory')
  src = os.path.abspath(src)
  dst = os.path.abspath(dst)
  if src == dst:
    return
  if dst == os.devnull:
    return
  shutil.move(src, dst)


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 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:
      settings.MEM_INIT_METHOD = 1
    else:
      assert settings.MEM_INIT_METHOD != 1

    if embed_memfile():
      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=' + 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 settings.LZ4:
        file_args.append('--lz4')
      if options.use_preload_plugins:
        file_args.append('--use-preload-plugins')
      file_code = shared.check_call([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 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 settings.USE_PTHREADS:
      target_dir = os.path.dirname(os.path.abspath(target))
      worker_output = os.path.join(target_dir, 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 (settings.OPT_LEVEL >= 1 or settings.SHRINK_LEVEL >= 1) and not 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 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 settings.MINIMAL_RUNTIME == 2 and settings.USE_CLOSURE_COMPILER and settings.DEBUG_LEVEL == 0 and not 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 = get_secondary_target(target, '.js')

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

    if not 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 settings.PROXY_TO_WORKER:
      generate_worker_js(target, js_target, target_basename)

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

    if settings.SPLIT_MODULE:
      diagnostics.warning('experimental', 'The SPLIT_MODULE setting is experimental and subject to change')
      do_split_module(wasm_target)

    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 version_string():
  return 'emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) %s' % shared.EMSCRIPTEN_VERSION


def parse_args(newargs):
  options = EmccOptions()
  settings_changes = []
  user_js_defines = []
  should_exit = False
  eh_enabled = False
  wasm_eh_enabled = False
  skip = False

  for i in range(len(newargs)):
    if skip:
      skip = False
      continue

    # 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(name):
      nonlocal arg_value
      if arg.startswith(name) and '=' in arg:
        arg_value = arg.split('=', 1)[1]
        newargs[i] = ''
        return True
      if arg == name:
        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

    def consume_arg_file():
      name = consume_arg()
      if not os.path.isfile(name):
        exit_with_error("'%s': file not found: '%s'" % (arg, name))
      return name

    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.requested_level = 2
        settings.SHRINK_LEVEL = 1
        settings_changes.append('INLINING_LIMIT=1')
      elif options.requested_level == 'z':
        options.requested_level = 2
        settings.SHRINK_LEVEL = 2
        settings_changes.append('INLINING_LIMIT=1')
      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'):
      diagnostics.warning('deprecated', '--llvm-opts is deprecated.  All non-emcc args are passed through to clang.')
    elif arg.startswith('-flto'):
      if '=' in arg:
        settings.LTO = arg.split('=')[1]
      else:
        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_file()).read() + '\n'
    elif check_arg('--post-js'):
      options.post_js += open(consume_arg_file()).read() + '\n'
    elif check_arg('--extern-pre-js'):
      options.extern_pre_js += open(consume_arg_file()).read() + '\n'
    elif check_arg('--extern-post-js'):
      options.extern_post_js += open(consume_arg_file()).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')
      settings.DEBUG_LEVEL = max(1, 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.)
        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 settings.DEBUG_LEVEL < 3:
          newargs[i] = ''
        else:
          # for 3+, report -g to clang as -g4 etc. are not accepted
          newargs[i] = '-g'
          if settings.DEBUG_LEVEL == 4:
            settings.GENERATE_SOURCE_MAP = 1
            diagnostics.warning('deprecated', 'please replace -g4 with -gsource-map')
      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')
            settings.SEPARATE_DWARF = requested_level.split('=')[1]
          else:
            settings.SEPARATE_DWARF = True
        elif requested_level == 'source-map':
          settings.GENERATE_SOURCE_MAP = 1
          newargs[i] = '-g'
        # 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).
        settings.DEBUG_LEVEL = 3
    elif check_flag('-profiling') or check_flag('--profiling'):
      settings.DEBUG_LEVEL = max(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")
      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
      settings.EMIT_SYMBOL_MAP = 1
    elif check_flag('--bind'):
      settings.EMBIND = 1
      settings.SYSTEM_JS_LIBRARIES.append((0, shared.path_from_root('src', 'embind', 'emval.js')))
      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
    elif check_arg('--shell-file'):
      options.shell_path = consume_arg_file()
    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'):
      settings.SYSTEM_JS_LIBRARIES.append((i + 1, os.path.abspath(consume_arg_file())))
    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('--check'):
      print(version_string(), file=sys.stderr)
      shared.check_sanity(force=True)
      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'):
      settings_changes.append('PROXY_TO_WORKER=1')
    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':
      settings.DISABLE_EXCEPTION_CATCHING = 1
      settings.DISABLE_EXCEPTION_THROWING = 1
      settings.EXCEPTION_HANDLING = 0
    elif arg == '-fexceptions':
      eh_enabled = True
    elif arg == '-fwasm-exceptions':
      wasm_eh_enabled = True
    elif arg == '-fignore-exceptions':
      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':
      settings.USE_RTTI = 0
    elif arg == '-frtti':
      settings.USE_RTTI = 1
    elif arg.startswith('-jsD'):
      key = arg[4:]
      if '=' in key:
        key, value = key.split('=')
      else:
        value = '1'
      if key in settings.keys():
        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
    elif check_arg('-o'):
      options.output_file = consume_arg()
    elif arg.startswith('-o'):
      options.output_file = arg[2:]
      newargs[i] = ''
    elif arg == '-mllvm':
      # Ignore the next argument rather than trying to parse it.  This is needed
      # because llvm args could, for example, start with `-o` and we don't want
      # to confuse that with a normal `-o` flag.
      skip = 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:
    settings.EXCEPTION_HANDLING = 1
    settings.DISABLE_EXCEPTION_THROWING = 1
    settings.DISABLE_EXCEPTION_CATCHING = 1
  elif eh_enabled:
    settings.EXCEPTION_HANDLING = 0
    settings.DISABLE_EXCEPTION_THROWING = 0
    settings.DISABLE_EXCEPTION_CATCHING = 0

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


def do_binaryen(target, options, wasm_target):
  global final_js
  logger.debug('using binaryen')
  if settings.GENERATE_SOURCE_MAP and not 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 = 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 settings.ASYNCIFY_ONLY or settings.ASYNCIFY_REMOVE or 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 = settings.DEBUG_LEVEL < 3
  strip_producers = not 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)
  passes = get_binaryen_passes()
  if passes or 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:
      passes += ['--strip-debug']
    if strip_producers:
      passes += ['--strip-producers']
    building.save_intermediate(wasm_target, 'pre-byn.wasm')
    building.run_wasm_opt(wasm_target,
                          wasm_target,
                          args=passes,
                          debug=intermediate_debug_info)
  elif strip_debug or strip_producers:
    # 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)
    building.save_intermediate(wasm_target, 'pre-strip.wasm')
    building.strip(wasm_target, wasm_target, debug=strip_debug, producers=strip_producers)

  if 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

  # Add extra dylibs if needed.
  if settings.RUNTIME_LINKED_LIBS:
    webassembly.update_dylink_section(wasm_target, settings.RUNTIME_LINKED_LIBS)

  if 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:
    if settings.SUPPORT_BIG_ENDIAN:
      final_js = building.little_endian_heap(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 settings.CAN_ADDRESS_2GB:
      final_js = building.use_unsigned_pointers_in_js(final_js)

    # pthreads memory growth requires some additional JS fixups.
    # note that we must do this after handling of unsigned pointers. unsigning
    # adds some >>> 0 things, while growth will replace a HEAP8 with a call to
    # a method to get the heap, and that call would not be recognized by the
    # unsigning pass
    if settings.USE_PTHREADS and settings.ALLOW_MEMORY_GROWTH:
      final_js = building.apply_wasm_memory_growth(final_js)

    if settings.USE_ASAN:
      final_js = building.instrument_js_for_asan(final_js)

    if settings.SAFE_HEAP:
      final_js = building.instrument_js_for_safe_heap(final_js)

    if settings.OPT_LEVEL >= 2 and 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 settings.ASYNCIFY_LAZY_LOAD_CODE:
    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 settings.WASM2JS:
    if settings.WASM == 2:
      wasm2js_template = wasm_target + '.js'
      open(wasm2js_template, 'w').write(preprocess_wasm2js_script())
      # generate secondary file for JS symbols
      symbols_file_js = shared.replace_or_append_suffix(wasm2js_template, '.symbols') if options.emit_symbol_map else None
    else:
      wasm2js_template = final_js
      symbols_file_js = shared.replace_or_append_suffix(target, '.symbols') if options.emit_symbol_map else None

    wasm2js = building.wasm2js(wasm2js_template,
                               wasm_target,
                               opt_level=settings.OPT_LEVEL,
                               minify_whitespace=minify_whitespace(),
                               use_closure_compiler=options.use_closure_compiler,
                               debug_info=debug_info,
                               symbols_file=symbols_file,
                               symbols_file_js=symbols_file_js)

    shared.configuration.get_temp_files().note(wasm2js)

    if settings.WASM == 2:
      safe_copy(wasm2js, wasm2js_template)

    if 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 settings.DEBUG_LEVEL >= 3 and settings.SEPARATE_DWARF and os.path.exists(wasm_target):
    building.emit_debug_on_side(wasm_target, settings.SEPARATE_DWARF)

  if settings.WASM2C:
    wasm2c.do_wasm2c(wasm_target)

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

    if 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 ' + settings.EXPORT_NAME)
  src = open(final_js).read()

  return_value = settings.EXPORT_NAME
  if settings.WASM_ASYNC_COMPILATION:
    return_value += '.ready'
  if not 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': settings.EXPORT_NAME,
    'src': src,
    'return_value': return_value
  }

  if settings.MINIMAL_RUNTIME and not 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' % (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 settings.EXPORT_ES6 and settings.USE_ES6_IMPORT_META:
      script_url = "import.meta.url"
    else:
      script_url = "typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined"
      if shared.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': 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 settings.EXPORT_ES6:
      f.write('export default %s;' % settings.EXPORT_NAME)
    elif not 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': settings.EXPORT_NAME})

  shared.configuration.get_temp_files().note(final_js)
  save_intermediate('modularized')


def module_export_name_substitution():
  global final_js
  logger.debug('Private module export name substitution with ' + settings.EXPORT_NAME)
  with open(final_js) as f:
    src = f.read()
  final_js += '.module_export_name_substitution.js'
  if settings.MINIMAL_RUNTIME:
    # In MINIMAL_RUNTIME the Module object is always present to provide the .asm.js/.wasm content
    replacement = settings.EXPORT_NAME
  else:
    replacement = "typeof %(EXPORT_NAME)s !== 'undefined' ? %(EXPORT_NAME)s : {}" % {"EXPORT_NAME": settings.EXPORT_NAME}
  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 settings.MINIMAL_RUNTIME and (shared.target_environment_may_be('node') or shared.target_environment_may_be('shell')):
    src = 'if(typeof Module==="undefined"){var Module={};}\n' + src
  with open(final_js, 'w') as f:
    f.write(src)
  shared.configuration.get_temp_files().note(final_js)
  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 settings.PROXY_TO_WORKER:
    proxy_worker_filename = (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 settings.SINGLE_FILE:
    if memfile and not 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 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 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' % (settings.ASSERTIONS, script.inline)

  # inline script for SINGLE_FILE output
  if 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)

  try:
    with open(target, 'wb') as f:
      # Force UTF-8 output for consistency across platforms and with the web.
      f.write(html_contents.encode('utf-8'))
  except OSError as e:
    exit_with_error(f'cannot write output file: {e}')


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

  opts = []
  # -g1 and greater retain whitespace and comments in source
  if 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 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 settings.EXPORT_NAME != 'Module' and \
     not 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 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 settings.MINIFY_HTML and (settings.OPT_LEVEL >= 1 or settings.SHRINK_LEVEL >= 1):
    minify_html(target)


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

  # compiler output goes in .worker.js file
  else:
    move_file(js_target, unsuffixed(js_target) + '.worker.js')
    worker_target_basename = target_basename + '.worker'
    proxy_worker_filename = (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, linker_inputs):
  libraries = []
  consumed = []
  suffixes = STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS

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

    found = False
    for suff in suffixes:
      name = 'lib' + 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)
          linker_inputs.append((i, path))
          consumed.append(i)
          found = True
          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)

  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.
  settings.SYSTEM_JS_LIBRARIES.sort(key=lambda lib: lib[0])
  settings.SYSTEM_JS_LIBRARIES = [lib[1] for lib in settings.SYSTEM_JS_LIBRARIES]
  return consumed


class ScriptSource:
  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, expect_list):
  # 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 and text[0] == '[':
      if text[-1] != ']':
        exit_with_error('unclosed opened string list. expected final character to be "]" in "%s"' % (text))
      text = text[1:-1]
    if text.strip() == "":
      return []
    return parse_string_list_members(text)

  if expect_list or (text and 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)
