diff --git a/.flake8 b/.flake8
index a430d98..512adc8 100644
--- a/.flake8
+++ b/.flake8
@@ -18,8 +18,4 @@
   ./temp,
   ./upstream,
 
-# E111: Indentation is not a multiple of four
-# E114: Indentation is not a multiple of four (comment)
-extend-ignore = E111, E114
-
 max-line-length = 160
diff --git a/bazel/emscripten_toolchain/link_wrapper.py b/bazel/emscripten_toolchain/link_wrapper.py
index e473206..79a3fa7 100644
--- a/bazel/emscripten_toolchain/link_wrapper.py
+++ b/bazel/emscripten_toolchain/link_wrapper.py
@@ -27,20 +27,20 @@
 
 # Re-write response file if needed.
 if any(' ' in a for a in param_file_args):
-  new_param_filename = param_filename + '.modified'
-  with open(new_param_filename, 'w') as f:
-    for param in param_file_args:
-      if ' ' in param:
-        f.write(f'"{param}"')
-      else:
-        f.write(param)
-      f.write('\n')
-  sys.argv[1] = '@' + new_param_filename
+    new_param_filename = param_filename + '.modified'
+    with open(new_param_filename, 'w') as f:
+        for param in param_file_args:
+            if ' ' in param:
+                f.write(f'"{param}"')
+            else:
+                f.write(param)
+            f.write('\n')
+    sys.argv[1] = '@' + new_param_filename
 
 emxx_py = os.path.join(os.environ['EMSCRIPTEN'], 'em++.py')
 rtn = subprocess.call([sys.executable, emxx_py, *sys.argv[1:]])
 if rtn != 0:
-  sys.exit(1)
+    sys.exit(1)
 
 # Parse the arguments that we gave to the linker to determine what the output
 # file is named and what the output format is.
@@ -56,27 +56,27 @@
 # The output file name is the name of the build rule that was built.
 # Add an appropriate file extension based on --oformat.
 if oformat is not None:
-  base_name_split = os.path.splitext(base_name)
+    base_name_split = os.path.splitext(base_name)
 
-  # If the output name has no extension, give it the appropriate extension.
-  if not base_name_split[1]:
-    os.replace(output_file, output_file + '.' + oformat)
+    # If the output name has no extension, give it the appropriate extension.
+    if not base_name_split[1]:
+        os.replace(output_file, output_file + '.' + oformat)
 
-  # If the output name does have an extension and it matches the output format,
-  # change the base_name so it doesn't have an extension.
-  elif base_name_split[1] == '.' + oformat:
-    base_name = base_name_split[0]
+    # If the output name does have an extension and it matches the output format,
+    # change the base_name so it doesn't have an extension.
+    elif base_name_split[1] == '.' + oformat:
+        base_name = base_name_split[0]
 
-  # If the output name does have an extension and it does not match the output
-  # format, change the base_name so it doesn't have an extension and rename
-  # the output_file so it has the proper extension.
-  # Note that if you do something like name your build rule "foo.js" and pass
-  # "--oformat=html", emscripten will write to the same file for both the js and
-  # html output, overwriting the js output entirely with the html.
-  # Please don't do that.
-  else:
-    base_name = base_name_split[0]
-    os.replace(output_file, os.path.join(outdir, base_name + '.' + oformat))
+    # If the output name does have an extension and it does not match the output
+    # format, change the base_name so it doesn't have an extension and rename
+    # the output_file so it has the proper extension.
+    # Note that if you do something like name your build rule "foo.js" and pass
+    # "--oformat=html", emscripten will write to the same file for both the js and
+    # html output, overwriting the js output entirely with the html.
+    # Please don't do that.
+    else:
+        base_name = base_name_split[0]
+        os.replace(output_file, os.path.join(outdir, base_name + '.' + oformat))
 
 files = []
 extensions = [
@@ -92,69 +92,69 @@
 ]
 
 for ext in extensions:
-  filename = base_name + ext
-  if os.path.exists(os.path.join(outdir, filename)):
-    files.append(filename)
+    filename = base_name + ext
+    if os.path.exists(os.path.join(outdir, filename)):
+        files.append(filename)
 
 wasm_base = os.path.join(outdir, base_name + '.wasm')
 if os.path.exists(wasm_base + '.debug.wasm') and os.path.exists(wasm_base):
-  # If we have a .wasm.debug.wasm file and a .wasm file, we need to rewrite the
-  # section in the .wasm file that refers to it. The path that's in there
-  # is the blaze output path; we want it to be just the filename.
+    # If we have a .wasm.debug.wasm file and a .wasm file, we need to rewrite the
+    # section in the .wasm file that refers to it. The path that's in there
+    # is the blaze output path; we want it to be just the filename.
 
-  llvm_objcopy = os.path.join(
-      os.environ['EM_BIN_PATH'], 'bin/llvm-objcopy')
-  # First, check to make sure the .wasm file has the header that needs to be
-  # rewritten.
-  rtn = subprocess.call([
-      llvm_objcopy,
-      '--dump-section=external_debug_info=/dev/null',
-      wasm_base], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  if rtn == 0:
-    # If llvm-objcopy did not return an error, the external_debug_info section
-    # must exist, so we're good to continue.
-
-    # Next we need to convert length of the filename to LEB128.
-    # Start by converting the length of the filename to a bit string.
-    bit_string = f"{len(base_name + '.wasm.debug.wasm'):b}"
-
-    # Pad the bit string with 0s so that its length is a multiple of 7.
-    while len(bit_string) % 7 != 0:
-      bit_string = '0' + bit_string
-
-    # Break up our bit string into chunks of 7.
-    # We do this backwards because the final format is little-endian.
-    final_bytes = bytearray()
-    for i in reversed(range(0, len(bit_string), 7)):
-      binary_part = bit_string[i:i + 7]
-      if i != 0:
-        # Every chunk except the last one needs to be prepended with '1'.
-        # The length of each chunk is 7, so that one has an implicit '0'.
-        binary_part = '1' + binary_part
-      final_bytes.append(int(binary_part, 2))
-    # Finally, add the actual filename.
-    final_bytes.extend((base_name + '.wasm.debug.wasm').encode())
-
-    # Write our length + filename bytes to a temp file.
-    with open(base_name + '_debugsection.tmp', 'wb+') as f:
-      f.write(final_bytes)
-      f.close()
-
-    # First delete the old section.
-    subprocess.check_call([
+    llvm_objcopy = os.path.join(
+        os.environ['EM_BIN_PATH'], 'bin/llvm-objcopy')
+    # First, check to make sure the .wasm file has the header that needs to be
+    # rewritten.
+    rtn = subprocess.call([
         llvm_objcopy,
-        wasm_base,
-        '--remove-section=external_debug_info'])
-    # Rewrite section with the new size and filename from the temp file.
-    subprocess.check_call([
-        llvm_objcopy,
-        wasm_base,
-        '--add-section=external_debug_info=' + base_name + '_debugsection.tmp'])
+        '--dump-section=external_debug_info=/dev/null',
+        wasm_base], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    if rtn == 0:
+        # If llvm-objcopy did not return an error, the external_debug_info section
+        # must exist, so we're good to continue.
+
+        # Next we need to convert length of the filename to LEB128.
+        # Start by converting the length of the filename to a bit string.
+        bit_string = f"{len(base_name + '.wasm.debug.wasm'):b}"
+
+        # Pad the bit string with 0s so that its length is a multiple of 7.
+        while len(bit_string) % 7 != 0:
+            bit_string = '0' + bit_string
+
+        # Break up our bit string into chunks of 7.
+        # We do this backwards because the final format is little-endian.
+        final_bytes = bytearray()
+        for i in reversed(range(0, len(bit_string), 7)):
+            binary_part = bit_string[i:i + 7]
+            if i != 0:
+                # Every chunk except the last one needs to be prepended with '1'.
+                # The length of each chunk is 7, so that one has an implicit '0'.
+                binary_part = '1' + binary_part
+            final_bytes.append(int(binary_part, 2))
+        # Finally, add the actual filename.
+        final_bytes.extend((base_name + '.wasm.debug.wasm').encode())
+
+        # Write our length + filename bytes to a temp file.
+        with open(base_name + '_debugsection.tmp', 'wb+') as f:
+            f.write(final_bytes)
+            f.close()
+
+        # First delete the old section.
+        subprocess.check_call([
+            llvm_objcopy,
+            wasm_base,
+            '--remove-section=external_debug_info'])
+        # Rewrite section with the new size and filename from the temp file.
+        subprocess.check_call([
+            llvm_objcopy,
+            wasm_base,
+            '--add-section=external_debug_info=' + base_name + '_debugsection.tmp'])
 
 # Make sure we have at least one output file.
 if not files:
-  print('em++.py did not appear to output any known files!')
-  sys.exit(1)
+    print('em++.py did not appear to output any known files!')
+    sys.exit(1)
 
 # cc_binary must output exactly one file; put all the output files in a tarball.
 cmd = ['tar', 'cf', base_name + '.tar', *files]
diff --git a/bazel/emscripten_toolchain/wasm_binary.py b/bazel/emscripten_toolchain/wasm_binary.py
index 6c285f3..b67b88a 100644
--- a/bazel/emscripten_toolchain/wasm_binary.py
+++ b/bazel/emscripten_toolchain/wasm_binary.py
@@ -17,43 +17,43 @@
 
 
 def ensure(f):
-  if not os.path.exists(f):
-    with open(f, 'w'):
-      pass
+    if not os.path.exists(f):
+        with open(f, 'w'):
+            pass
 
 
 def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--archive', help='The archive to extract from.')
-  parser.add_argument('--outputs',
-                      help='Comma separated list of files that should be extracted '
-                           'from the archive. Only the extname has to match a file in the archive.')
-  parser.add_argument('--allow_empty_outputs',
-                      help='If an output listed in --outputs does not exist, create it anyways.', action='store_true')
-  args = parser.parse_args()
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--archive', help='The archive to extract from.')
+    parser.add_argument('--outputs',
+                        help='Comma separated list of files that should be extracted '
+                             'from the archive. Only the extname has to match a file in the archive.')
+    parser.add_argument('--allow_empty_outputs',
+                        help='If an output listed in --outputs does not exist, create it anyways.', action='store_true')
+    args = parser.parse_args()
 
-  args.archive = os.path.normpath(args.archive)
-  args.outputs = args.outputs.split(",")
+    args.archive = os.path.normpath(args.archive)
+    args.outputs = args.outputs.split(",")
 
-  tar = tarfile.open(args.archive)
+    tar = tarfile.open(args.archive)
 
-  for member in tar.getmembers():
-    extname = '.' + member.name.split('.', 1)[1]
-    for idx, output in enumerate(args.outputs):
-      if output.endswith(extname):
-        member_file = tar.extractfile(member)
-        with open(output, "wb") as output_file:
-          output_file.write(member_file.read())
-        args.outputs.pop(idx)
-        break
+    for member in tar.getmembers():
+        extname = '.' + member.name.split('.', 1)[1]
+        for idx, output in enumerate(args.outputs):
+            if output.endswith(extname):
+                member_file = tar.extractfile(member)
+                with open(output, "wb") as output_file:
+                    output_file.write(member_file.read())
+                args.outputs.pop(idx)
+                break
 
-  for output in args.outputs:
-    extname = '.' + output.split('.', 1)[1]
-    if args.allow_empty_outputs:
-      ensure(output)
-    else:
-      print(f"[ERROR] Archive does not contain file with extname: {extname}")
+    for output in args.outputs:
+        extname = '.' + output.split('.', 1)[1]
+        if args.allow_empty_outputs:
+            ensure(output)
+        else:
+            print(f"[ERROR] Archive does not contain file with extname: {extname}")
 
 
 if __name__ == '__main__':
-  main()
+    main()
diff --git a/emsdk.py b/emsdk.py
index 4edf312..bd98b8c 100644
--- a/emsdk.py
+++ b/emsdk.py
@@ -20,15 +20,15 @@
 import zipfile
 
 if os.name == 'nt':
-  import ctypes.wintypes
-  import winreg
+    import ctypes.wintypes
+    import winreg
 
 from urllib.parse import urljoin
 from urllib.request import urlopen
 
 if sys.version_info < (3, 10):  # ruff: ignore[outdated-version-block]
-  print(f'error: emsdk requires python 3.10 or above ({sys.executable} {sys.version})', file=sys.stderr)
-  sys.exit(1)
+    print(f'error: emsdk requires python 3.10 or above ({sys.executable} {sys.version})', file=sys.stderr)
+    sys.exit(1)
 
 emsdk_packages_url = 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/'
 
@@ -47,9 +47,9 @@
 
 
 def get_env_boolean(name):
-  env_var = os.getenv(name)
-  assert env_var in {None, '1', '0'}, f'invalid environment variable setting ${env_var} for ${name}'
-  return env_var == '1'
+    env_var = os.getenv(name)
+    assert env_var in {None, '1', '0'}, f'invalid environment variable setting ${env_var} for ${name}'
+    return env_var == '1'
 
 
 # Enable this to do very verbose printing about the different steps that are
@@ -57,23 +57,23 @@
 VERBOSE = get_env_boolean('EMSDK_VERBOSE')
 QUIET = get_env_boolean('EMSDK_QUIET')
 if get_env_boolean('EMSDK_NOTTY'):
-  TTY_OUTPUT = False
+    TTY_OUTPUT = False
 else:
-  TTY_OUTPUT = sys.stdout.isatty()
+    TTY_OUTPUT = sys.stdout.isatty()
 
 
 def info(msg):
-  if not QUIET:
-    print(msg, file=sys.stderr)
+    if not QUIET:
+        print(msg, file=sys.stderr)
 
 
 def errlog(msg):
-  print(msg, file=sys.stderr)
+    print(msg, file=sys.stderr)
 
 
 def exit_with_error(msg):
-  errlog(f'error: {msg}')
-  sys.exit(1)
+    errlog(f'error: {msg}')
+    sys.exit(1)
 
 
 WINDOWS = False
@@ -84,36 +84,36 @@
 
 os_override = os.environ.get('EMSDK_OS')
 if os_override:
-  if os_override == 'windows':
-    WINDOWS = True
-  elif os_override == 'linux':
-    LINUX = True
-  elif os_override == 'macos':
-    MACOS = True
-  else:
-    assert False, 'EMSDK_OS must be one of: windows, linux, macos'
+    if os_override == 'windows':
+        WINDOWS = True
+    elif os_override == 'linux':
+        LINUX = True
+    elif os_override == 'macos':
+        MACOS = True
+    else:
+        assert False, 'EMSDK_OS must be one of: windows, linux, macos'
 else:
-  if os.name == 'nt' or ('windows' in os.getenv('SYSTEMROOT', '').lower()) or ('windows' in os.getenv('COMSPEC', '').lower()):
-    WINDOWS = True
+    if os.name == 'nt' or ('windows' in os.getenv('SYSTEMROOT', '').lower()) or ('windows' in os.getenv('COMSPEC', '').lower()):
+        WINDOWS = True
 
-  msystem = os.getenv('MSYSTEM')
-  if msystem:
-    MSYS = True
-    # Some functions like os.path.normpath() exhibit different behavior between
-    # different versions of Python, so we need to distinguish between the MinGW
-    # and MSYS versions of Python
-    if sysconfig.get_platform() == 'mingw':
-      MINGW = True
-    if msystem not in {'MSYS', 'MINGW64'}:
-      # https://stackoverflow.com/questions/37460073/msys-vs-mingw-internal-environment-variables
-      errlog(f'Warning: MSYSTEM environment variable is present, and is set to "{msystem}". '
-             'This shell has not been tested with emsdk and may not work.')
+    msystem = os.getenv('MSYSTEM')
+    if msystem:
+        MSYS = True
+        # Some functions like os.path.normpath() exhibit different behavior between
+        # different versions of Python, so we need to distinguish between the MinGW
+        # and MSYS versions of Python
+        if sysconfig.get_platform() == 'mingw':
+            MINGW = True
+        if msystem not in {'MSYS', 'MINGW64'}:
+            # https://stackoverflow.com/questions/37460073/msys-vs-mingw-internal-environment-variables
+            errlog(f'Warning: MSYSTEM environment variable is present, and is set to "{msystem}". '
+                   'This shell has not been tested with emsdk and may not work.')
 
-  if platform.mac_ver()[0]:
-    MACOS = True
+    if platform.mac_ver()[0]:
+        MACOS = True
 
-  if not MACOS and (platform.system() == 'Linux'):
-    LINUX = True
+    if not MACOS and (platform.system() == 'Linux'):
+        LINUX = True
 
 UNIX = (MACOS or LINUX)
 
@@ -126,32 +126,32 @@
 FISH = get_env_boolean('EMSDK_FISH')
 
 if WINDOWS and BASH:
-  MSYS = True
+    MSYS = True
 
 if not CSH and not POWERSHELL and not BASH and not CMD and not FISH:
-  # Fall back to default of `cmd` on windows and `bash` otherwise
-  if WINDOWS and not MSYS:
-    CMD = True
-  else:
-    BASH = True
+    # Fall back to default of `cmd` on windows and `bash` otherwise
+    if WINDOWS and not MSYS:
+        CMD = True
+    else:
+        BASH = True
 
 if WINDOWS:
-  ENVPATH_SEPARATOR = ';'
+    ENVPATH_SEPARATOR = ';'
 else:
-  ENVPATH_SEPARATOR = ':'
+    ENVPATH_SEPARATOR = ':'
 
 # platform.machine() may return AMD64 on windows, so standardize the case.
 machine = os.getenv('EMSDK_ARCH', platform.machine().lower())
 if machine.startswith(('x64', 'amd64', 'x86_64')):
-  ARCH = 'x86_64'
+    ARCH = 'x86_64'
 elif machine.endswith('86'):
-  ARCH = 'x86'
+    ARCH = 'x86'
 elif machine.startswith('aarch64') or machine.lower().startswith('arm64'):
-  ARCH = 'arm64'
+    ARCH = 'arm64'
 elif machine.startswith('arm'):
-  ARCH = 'arm'
+    ARCH = 'arm'
 else:
-  exit_with_error('unknown machine architecture: ' + machine)
+    exit_with_error('unknown machine architecture: ' + machine)
 
 
 # Don't saturate all cores to not steal the whole system, but be aggressive.
@@ -176,1432 +176,1432 @@
 
 
 def os_name_short():
-  if WINDOWS:
-    return 'win'
-  elif LINUX:
-    return 'linux'
-  elif MACOS:
-    return 'mac'
-  assert False, 'unknown OS'
+    if WINDOWS:
+        return 'win'
+    elif LINUX:
+        return 'linux'
+    elif MACOS:
+        return 'mac'
+    assert False, 'unknown OS'
 
 
 def os_name():
-  if WINDOWS:
-    return 'windows'
-  if LINUX:
-    return 'linux'
-  if MACOS:
-    return 'macos'
-  assert False, 'unknown OS'
+    if WINDOWS:
+        return 'windows'
+    if LINUX:
+        return 'linux'
+    if MACOS:
+        return 'macos'
+    assert False, 'unknown OS'
 
 
 def debug_print(msg):
-  if VERBOSE:
-    errlog(msg)
+    if VERBOSE:
+        errlog(msg)
 
 
 def to_unix_path(p):
-  return p.replace('\\', '/')
+    return p.replace('\\', '/')
 
 
 EMSDK_PATH = to_unix_path(os.path.dirname(os.path.realpath(__file__)))
 
 EMSDK_SET_ENV = ""
 if POWERSHELL:
-  EMSDK_SET_ENV = os.path.join(EMSDK_PATH, 'emsdk_set_env.ps1')
+    EMSDK_SET_ENV = os.path.join(EMSDK_PATH, 'emsdk_set_env.ps1')
 else:
-  EMSDK_SET_ENV = os.path.join(EMSDK_PATH, 'emsdk_set_env.bat')
+    EMSDK_SET_ENV = os.path.join(EMSDK_PATH, 'emsdk_set_env.bat')
 
 
 def parse_github_url_and_refspec(url):
-  """Parse a github URL a tuple of its components.
+    """Parse a github URL a tuple of its components.
 
-  Parses https://github.com/emscripten-core/emscripten/tree/d6aced8 to the
-  tuple (https://github.com/emscripten-core/emscripten, d6aced8, emscripten-core)
-  or https://github.com/emscripten-core/emscripten/commit/00b76f81f6474113fcf540db69297cfeb180347e
-  to (https://github.com/emscripten-core/emscripten, 00b76f81f6474113fcf540db69297cfeb180347e, emscripten-core)
-  """
-  if not url:
-    return ('', '', None)
+    Parses https://github.com/emscripten-core/emscripten/tree/d6aced8 to the
+    tuple (https://github.com/emscripten-core/emscripten, d6aced8, emscripten-core)
+    or https://github.com/emscripten-core/emscripten/commit/00b76f81f6474113fcf540db69297cfeb180347e
+    to (https://github.com/emscripten-core/emscripten, 00b76f81f6474113fcf540db69297cfeb180347e, emscripten-core)
+    """
+    if not url:
+        return ('', '', None)
 
-  if url.endswith(('/tree/', '/tree', '/commit/', '/commit')):
-    raise Exception(f'Malformed git URL and refspec {url}!')
+    if url.endswith(('/tree/', '/tree', '/commit/', '/commit')):
+        raise Exception(f'Malformed git URL and refspec {url}!')
 
-  if '/tree/' in url:
-    if url.endswith('/'):
-      raise Exception(f'Malformed git URL and refspec {url}!')
-    url, refspec = url.split('/tree/')
-    remote_name = url.split('/')[-2]
-    return (url, refspec, remote_name)
-  elif '/commit/' in url:
-    if url.endswith('/'):
-      raise Exception(f'Malformed git URL and refspec {url}!')
-    url, refspec = url.split('/commit/')
-    remote_name = url.split('/')[-2]
-    return (url, refspec, remote_name)
-  else:
-    return (url, 'main', None)  # Assume the default branch is main in the absence of a refspec
+    if '/tree/' in url:
+        if url.endswith('/'):
+            raise Exception(f'Malformed git URL and refspec {url}!')
+        url, refspec = url.split('/tree/')
+        remote_name = url.split('/')[-2]
+        return (url, refspec, remote_name)
+    elif '/commit/' in url:
+        if url.endswith('/'):
+            raise Exception(f'Malformed git URL and refspec {url}!')
+        url, refspec = url.split('/commit/')
+        remote_name = url.split('/')[-2]
+        return (url, refspec, remote_name)
+    else:
+        return (url, 'main', None)  # Assume the default branch is main in the absence of a refspec
 
 
 ARCHIVE_SUFFIXES = ('zip', '.tar', '.gz', '.xz', '.tbz2', '.bz2')
 
 
 def vswhere(version):
-  program_files = os.getenv('ProgramFiles(x86)')
-  if not program_files:
-    program_files = os.environ['ProgramFiles']
-  vswhere_path = os.path.join(program_files, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe')
-  # Source: https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2022
-  tools_arch = 'ARM64' if ARCH == 'arm64' else 'x86.x64'
-  try:
-    # The "-products *" allows detection of Build Tools, the "-prerelease" allows detection of Preview version
-    # of Visual Studio and Build Tools.
-    stdout = run_get_output([vswhere_path, '-latest', '-products', '*',
-                             '-prerelease', '-version', f'[{version}.0,{version + 1}.0)',
-                             '-requires', 'Microsoft.VisualStudio.Component.VC.Tools.' + tools_arch,
-                             '-property', 'installationPath', '-format', 'json'])
-    json_output = json.loads(stdout)
-    return str(json_output[0]['installationPath'])
-  except Exception:
-    return ''
+    program_files = os.getenv('ProgramFiles(x86)')
+    if not program_files:
+        program_files = os.environ['ProgramFiles']
+    vswhere_path = os.path.join(program_files, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe')
+    # Source: https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2022
+    tools_arch = 'ARM64' if ARCH == 'arm64' else 'x86.x64'
+    try:
+        # The "-products *" allows detection of Build Tools, the "-prerelease" allows detection of Preview version
+        # of Visual Studio and Build Tools.
+        stdout = run_get_output([vswhere_path, '-latest', '-products', '*',
+                                 '-prerelease', '-version', f'[{version}.0,{version + 1}.0)',
+                                 '-requires', 'Microsoft.VisualStudio.Component.VC.Tools.' + tools_arch,
+                                 '-property', 'installationPath', '-format', 'json'])
+        json_output = json.loads(stdout)
+        return str(json_output[0]['installationPath'])
+    except Exception:
+        return ''
 
 
 CMAKE_GENERATOR = 'Unix Makefiles'
 if WINDOWS:
-  # Detect which CMake generator to use when building on Windows
-  if '--mingw' in sys.argv:
-    CMAKE_GENERATOR = 'MinGW Makefiles'
-  elif '--vs2022' in sys.argv:
-    CMAKE_GENERATOR = 'Visual Studio 17'
-  elif '--vs2019' in sys.argv:
-    CMAKE_GENERATOR = 'Visual Studio 16'
-  elif vswhere(17):
-    CMAKE_GENERATOR = 'Visual Studio 17'
-  elif vswhere(16):
-    CMAKE_GENERATOR = 'Visual Studio 16'
-  elif shutil.which('mingw32-make') is not None and shutil.which('g++') is not None:
-    CMAKE_GENERATOR = 'MinGW Makefiles'
-  else:
-    # No detected generator
-    CMAKE_GENERATOR = ''
+    # Detect which CMake generator to use when building on Windows
+    if '--mingw' in sys.argv:
+        CMAKE_GENERATOR = 'MinGW Makefiles'
+    elif '--vs2022' in sys.argv:
+        CMAKE_GENERATOR = 'Visual Studio 17'
+    elif '--vs2019' in sys.argv:
+        CMAKE_GENERATOR = 'Visual Studio 16'
+    elif vswhere(17):
+        CMAKE_GENERATOR = 'Visual Studio 17'
+    elif vswhere(16):
+        CMAKE_GENERATOR = 'Visual Studio 16'
+    elif shutil.which('mingw32-make') is not None and shutil.which('g++') is not None:
+        CMAKE_GENERATOR = 'MinGW Makefiles'
+    else:
+        # No detected generator
+        CMAKE_GENERATOR = ''
 
 
 sys.argv = [a for a in sys.argv if a not in {'--mingw', '--vs2019', '--vs2022'}]
 
 
 def cmake_generator_prefix():
-  """Computes a suitable path prefix to use when building with a given generator."""
-  if CMAKE_GENERATOR == 'Visual Studio 17':
-    return '_vs2022'
-  if CMAKE_GENERATOR == 'Visual Studio 16':
-    return '_vs2019'
-  elif CMAKE_GENERATOR == 'MinGW Makefiles':
-    return '_mingw'
-  # Unix Makefiles do not specify a path prefix for backwards path compatibility
-  return ''
+    """Computes a suitable path prefix to use when building with a given generator."""
+    if CMAKE_GENERATOR == 'Visual Studio 17':
+        return '_vs2022'
+    if CMAKE_GENERATOR == 'Visual Studio 16':
+        return '_vs2019'
+    elif CMAKE_GENERATOR == 'MinGW Makefiles':
+        return '_mingw'
+    # Unix Makefiles do not specify a path prefix for backwards path compatibility
+    return ''
 
 
 def remove_tree(d):
-  """Removes a directory tree even if it was readonly, and doesn't throw exception
-  on failure.
-  """
-  debug_print(f'remove_tree({d})')
-  if not os.path.exists(d):
-    return
-  try:
-    def remove_readonly_and_try_again(func, path, exc_info):
-      if not (os.stat(path).st_mode & stat.S_IWRITE):
-        os.chmod(path, stat.S_IWRITE)
-        func(path)
-      else:
-        raise exc_info[1]
-    shutil.rmtree(d, onerror=remove_readonly_and_try_again)
-  except Exception as e:
-    debug_print('remove_tree threw an exception, ignoring: ' + str(e))
+    """Removes a directory tree even if it was readonly, and doesn't throw exception
+    on failure.
+    """
+    debug_print(f'remove_tree({d})')
+    if not os.path.exists(d):
+        return
+    try:
+        def remove_readonly_and_try_again(func, path, exc_info):
+            if not (os.stat(path).st_mode & stat.S_IWRITE):
+                os.chmod(path, stat.S_IWRITE)
+                func(path)
+            else:
+                raise exc_info[1]
+        shutil.rmtree(d, onerror=remove_readonly_and_try_again)
+    except Exception as e:
+        debug_print('remove_tree threw an exception, ignoring: ' + str(e))
 
 
 def win_set_environment_variable_direct(key, value, system=True):
-  folder = None
-  try:
-    if system:
-      # Read globally from ALL USERS section.
-      folder = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', 0, winreg.KEY_ALL_ACCESS)
-    else:
-      # Register locally from CURRENT USER section.
-      folder = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_ALL_ACCESS)
-    winreg.SetValueEx(folder, key, 0, winreg.REG_EXPAND_SZ, value)
-    debug_print(f'Set key={key} with value {value} in registry.')
-    return True
-  except Exception as e:
-    # 'Access is denied.'
-    if e.args[3] == 5:
-      exit_with_error(f"failed to set the environment variable '{key}'! "
-                      'Setting environment variables permanently requires administrator access. '
-                      'Please rerun this command with administrative privileges. '
-                      'This can be done for example by holding down the Ctrl and Shift keys '
-                      'while opening a command prompt in start menu.')
-    errlog(f'Failed to write environment variable {key}:')
-    errlog(str(e))
-    return False
-  finally:
-    if folder is not None:
-      folder.Close()
+    folder = None
+    try:
+        if system:
+            # Read globally from ALL USERS section.
+            folder = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', 0, winreg.KEY_ALL_ACCESS)
+        else:
+            # Register locally from CURRENT USER section.
+            folder = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_ALL_ACCESS)
+        winreg.SetValueEx(folder, key, 0, winreg.REG_EXPAND_SZ, value)
+        debug_print(f'Set key={key} with value {value} in registry.')
+        return True
+    except Exception as e:
+        # 'Access is denied.'
+        if e.args[3] == 5:
+            exit_with_error(f"failed to set the environment variable '{key}'! "
+                            'Setting environment variables permanently requires administrator access. '
+                            'Please rerun this command with administrative privileges. '
+                            'This can be done for example by holding down the Ctrl and Shift keys '
+                            'while opening a command prompt in start menu.')
+        errlog(f'Failed to write environment variable {key}:')
+        errlog(str(e))
+        return False
+    finally:
+        if folder is not None:
+            folder.Close()
 
 
 def win_get_environment_variable(key, system=True, user=True, fallback=True):
-  if (not system and not user and fallback):
-    # if no --system or --permanent flag is provided use shell's value
-    return os.environ[key]
-  try:
-    folder = None
-    try:
-      if system:
-        # Read globally from ALL USERS section.
-        folder = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
-      else:
-        # Register locally from CURRENT USER section.
-        folder = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment')
-      value = str(winreg.QueryValueEx(folder, key)[0])
-    except Exception:
-      # If reading registry fails for some reason - read via os.environ. This has the drawback
-      # that expansion items such as %PROGRAMFILES% will have been expanded, so
-      # need to be precise not to set these back to system registry, or
-      # expansion items would be lost.
-      if fallback:
+    if (not system and not user and fallback):
+        # if no --system or --permanent flag is provided use shell's value
         return os.environ[key]
-      return None
-    finally:
-      if folder is not None:
-        folder.Close()
+    try:
+        folder = None
+        try:
+            if system:
+                # Read globally from ALL USERS section.
+                folder = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
+            else:
+                # Register locally from CURRENT USER section.
+                folder = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment')
+            value = str(winreg.QueryValueEx(folder, key)[0])
+        except Exception:
+            # If reading registry fails for some reason - read via os.environ. This has the drawback
+            # that expansion items such as %PROGRAMFILES% will have been expanded, so
+            # need to be precise not to set these back to system registry, or
+            # expansion items would be lost.
+            if fallback:
+                return os.environ[key]
+            return None
+        finally:
+            if folder is not None:
+                folder.Close()
 
-  except Exception as e:
-    # this catch is if both the registry key threw an exception and the key is not in os.environ
-    if e.args[0] != 2:
-      # 'The system cannot find the file specified.'
-      errlog(f'Failed to read environment variable {key}:')
-      errlog(str(e))
-    return None
-  return value
+    except Exception as e:
+        # this catch is if both the registry key threw an exception and the key is not in os.environ
+        if e.args[0] != 2:
+            # 'The system cannot find the file specified.'
+            errlog(f'Failed to read environment variable {key}:')
+            errlog(str(e))
+        return None
+    return value
 
 
 def win_set_environment_variable(key, value, system, user):
-  debug_print(f'set {key}={value}, in system={system}')
-  previous_value = win_get_environment_variable(key, system=system, user=user)
-  if previous_value == value:
-    debug_print('  no need to set, since same value already exists.')
-    # No need to elevate UAC for nothing to set the same value, skip.
-    return False
+    debug_print(f'set {key}={value}, in system={system}')
+    previous_value = win_get_environment_variable(key, system=system, user=user)
+    if previous_value == value:
+        debug_print('  no need to set, since same value already exists.')
+        # No need to elevate UAC for nothing to set the same value, skip.
+        return False
 
-  if not value:
+    if not value:
+        try:
+            if system:
+                cmd = ['REG', 'DELETE', 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', '/V', key, '/f']
+            else:
+                cmd = ['REG', 'DELETE', 'HKCU\\Environment', '/V', key, '/f']
+            debug_print(str(cmd))
+            subprocess.call(cmd, stdout=subprocess.PIPE)
+        except Exception:
+            return False
+        return True
+
     try:
-      if system:
-        cmd = ['REG', 'DELETE', 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', '/V', key, '/f']
-      else:
-        cmd = ['REG', 'DELETE', 'HKCU\\Environment', '/V', key, '/f']
-      debug_print(str(cmd))
-      subprocess.call(cmd, stdout=subprocess.PIPE)
-    except Exception:
-      return False
-    return True
+        if win_set_environment_variable_direct(key, value, system):
+            return True
+        # Escape % signs so that we don't expand references to environment variables.
+        value = value.replace('%', '^%')
+        if len(value) >= 1024:
+            exit_with_error(f'the new environment variable {key} is more than 1024 characters long! '
+                            'A value this long cannot be set via command line: please add the environment variable '
+                            'specified above to system environment manually via Control Panel.')
+        cmd = ['SETX', key, value]
+        debug_print(str(cmd))
+        retcode = subprocess.call(cmd, stdout=subprocess.PIPE)
+        if retcode != 0:
+            errlog(f'ERROR! Failed to set environment variable {key}={value}. You may need to set it manually.')
+        else:
+            return True
+    except Exception as e:
+        errlog(f'ERROR! Failed to set environment variable {key}={value}:')
+        errlog(str(e))
+        errlog('You may need to set it manually.')
 
-  try:
-    if win_set_environment_variable_direct(key, value, system):
-      return True
-    # Escape % signs so that we don't expand references to environment variables.
-    value = value.replace('%', '^%')
-    if len(value) >= 1024:
-      exit_with_error(f'the new environment variable {key} is more than 1024 characters long! '
-                      'A value this long cannot be set via command line: please add the environment variable '
-                      'specified above to system environment manually via Control Panel.')
-    cmd = ['SETX', key, value]
-    debug_print(str(cmd))
-    retcode = subprocess.call(cmd, stdout=subprocess.PIPE)
-    if retcode != 0:
-      errlog(f'ERROR! Failed to set environment variable {key}={value}. You may need to set it manually.')
-    else:
-      return True
-  except Exception as e:
-    errlog(f'ERROR! Failed to set environment variable {key}={value}:')
-    errlog(str(e))
-    errlog('You may need to set it manually.')
-
-  return False
+    return False
 
 
 def win_set_environment_variables(env_vars_to_add, system, user):
-  if not env_vars_to_add:
-    return
+    if not env_vars_to_add:
+        return
 
-  changed = False
+    changed = False
 
-  for key, value in env_vars_to_add:
-    if win_set_environment_variable(key, value, system, user):
-      if not changed:
-        changed = True
-        print('Setting global environment variables:')
+    for key, value in env_vars_to_add:
+        if win_set_environment_variable(key, value, system, user):
+            if not changed:
+                changed = True
+                print('Setting global environment variables:')
 
-      print(f'{key} = {value}')
+            print(f'{key} = {value}')
 
-  if not changed:
-    print('Global environment variables up to date')
-    return
+    if not changed:
+        print('Global environment variables up to date')
+        return
 
-  # if changes were made then we need to notify other processes
-  try:
-    HWND_BROADCAST = ctypes.wintypes.HWND(0xFFFF)  # win32con.HWND_BROADCAST == 65535
-    WM_SETTINGCHANGE = 0x001A  # win32con.WM_SETTINGCHANGE == 26
-    SMTO_BLOCK = 0x0001  # win32con.SMTO_BLOCK == 1
-    ctypes.windll.user32.SendMessageTimeoutA(
-      HWND_BROADCAST,    # hWnd: notify everyone
-      WM_SETTINGCHANGE,  # Msg: registry changed
-      0,                 # wParam: Must be 0 when setting changed is sent by users
-      'Environment',     # lParam: Specifically environment variables changed
-      SMTO_BLOCK,        # fuFlags: Wait for message to be sent or timeout
-      100)               # uTimeout: 100ms
-  except Exception as e:
-    errlog('SendMessageTimeout failed with error: ' + str(e))
+    # if changes were made then we need to notify other processes
+    try:
+        HWND_BROADCAST = ctypes.wintypes.HWND(0xFFFF)  # win32con.HWND_BROADCAST == 65535
+        WM_SETTINGCHANGE = 0x001A  # win32con.WM_SETTINGCHANGE == 26
+        SMTO_BLOCK = 0x0001  # win32con.SMTO_BLOCK == 1
+        ctypes.windll.user32.SendMessageTimeoutA(
+          HWND_BROADCAST,    # hWnd: notify everyone
+          WM_SETTINGCHANGE,  # Msg: registry changed
+          0,                 # wParam: Must be 0 when setting changed is sent by users
+          'Environment',     # lParam: Specifically environment variables changed
+          SMTO_BLOCK,        # fuFlags: Wait for message to be sent or timeout
+          100)               # uTimeout: 100ms
+    except Exception as e:
+        errlog('SendMessageTimeout failed with error: ' + str(e))
 
 
 def win_delete_environment_variable(key, system=True, user=True):
-  debug_print(f'win_delete_environment_variable(key={key}, system={system})')
-  return win_set_environment_variable(key, None, system, user)
+    debug_print(f'win_delete_environment_variable(key={key}, system={system})')
+    return win_set_environment_variable(key, None, system, user)
 
 
 def sdk_path(path):
-  """Returns the absolute pathname to the given path inside the Emscripten SDK."""
-  if os.path.isabs(path):
-    return path
+    """Returns the absolute pathname to the given path inside the Emscripten SDK."""
+    if os.path.isabs(path):
+        return path
 
-  return to_unix_path(os.path.join(EMSDK_PATH, path))
+    return to_unix_path(os.path.join(EMSDK_PATH, path))
 
 
 def rmfile(filename):
-  """Removes a single file, suppressing exceptions on failure."""
-  debug_print(f'rmfile({filename})')
-  if os.path.lexists(filename):
-    os.remove(filename)
+    """Removes a single file, suppressing exceptions on failure."""
+    debug_print(f'rmfile({filename})')
+    if os.path.lexists(filename):
+        os.remove(filename)
 
 
 def mkdir_p(path):
-  debug_print(f'mkdir_p({path})')
-  os.makedirs(path, exist_ok=True)
+    debug_print(f'mkdir_p({path})')
+    os.makedirs(path, exist_ok=True)
 
 
 def is_nonempty_directory(path):
-  if not os.path.isdir(path):
-    return False
-  return len(os.listdir(path)) != 0
+    if not os.path.isdir(path):
+        return False
+    return len(os.listdir(path)) != 0
 
 
 def run(cmd, cwd=None, check=True):
-  debug_print(f'run(cmd={cmd}, cwd={cwd})')
-  returncode = subprocess.call(cmd, cwd=cwd, env=os.environ.copy())
-  if returncode != 0 and check:
-    errlog(f'{cmd} failed with error code {returncode}')
-  return returncode
+    debug_print(f'run(cmd={cmd}, cwd={cwd})')
+    returncode = subprocess.call(cmd, cwd=cwd, env=os.environ.copy())
+    if returncode != 0 and check:
+        errlog(f'{cmd} failed with error code {returncode}')
+    return returncode
 
 
 def untargz(source_filename, dest_dir):
-  print(f"Unpacking '{source_filename}' to '{dest_dir}'")
-  mkdir_p(dest_dir)
-  returncode = run(['tar', '-xvf' if VERBOSE else '-xf', sdk_path(source_filename), '--strip', '1'], cwd=dest_dir)
-  # tfile = tarfile.open(source_filename, 'r:gz')
-  # tfile.extractall(dest_dir)
-  return returncode == 0
+    print(f"Unpacking '{source_filename}' to '{dest_dir}'")
+    mkdir_p(dest_dir)
+    returncode = run(['tar', '-xvf' if VERBOSE else '-xf', sdk_path(source_filename), '--strip', '1'], cwd=dest_dir)
+    # tfile = tarfile.open(source_filename, 'r:gz')
+    # tfile.extractall(dest_dir)
+    return returncode == 0
 
 
 def fix_potentially_long_windows_pathname(pathname):
-  """Convert pathname to use extended-length path prefix on windows.
+    """Convert pathname to use extended-length path prefix on windows.
 
-  On Windows, it is not possible to reference path names that are longer than
-  ~260 characters, unless the path is referenced via a "\\?\" prefix.
-  See https://msdn.microsoft.com/en-us/library/aa365247.aspx#maxpath and
-  http://stackoverflow.com/questions/3555527/python-win32-filename-length-workaround
-  In that mode, forward slashes cannot be used as delimiters.
-  """
-  if (not WINDOWS or MSYS) or os_override:
-    return pathname
-  # Test if emsdk calls fix_potentially_long_windows_pathname() with long
-  # relative paths (which is problematic)
-  if not os.path.isabs(pathname) and len(pathname) > 200:
-    errlog(f'Warning: Seeing a relative path "{pathname}" which is dangerously long '
-           'for being referenced as a short Windows path name. Refactor emsdk to be able to handle this!')
-  if pathname.startswith('\\\\?\\'):
-    return pathname
-  pathname = os.path.normpath(pathname.replace('/', '\\'))
-  if MINGW:
-    # MinGW versions of Python return normalized paths with backslashes
-    # converted to forward slashes, so we must use forward slashes in our
-    # prefix
-    return '//?/' + pathname
-  return '\\\\?\\' + pathname
+    On Windows, it is not possible to reference path names that are longer than
+    ~260 characters, unless the path is referenced via a "\\?\" prefix.
+    See https://msdn.microsoft.com/en-us/library/aa365247.aspx#maxpath and
+    http://stackoverflow.com/questions/3555527/python-win32-filename-length-workaround
+    In that mode, forward slashes cannot be used as delimiters.
+    """
+    if (not WINDOWS or MSYS) or os_override:
+        return pathname
+    # Test if emsdk calls fix_potentially_long_windows_pathname() with long
+    # relative paths (which is problematic)
+    if not os.path.isabs(pathname) and len(pathname) > 200:
+        errlog(f'Warning: Seeing a relative path "{pathname}" which is dangerously long '
+               'for being referenced as a short Windows path name. Refactor emsdk to be able to handle this!')
+    if pathname.startswith('\\\\?\\'):
+        return pathname
+    pathname = os.path.normpath(pathname.replace('/', '\\'))
+    if MINGW:
+        # MinGW versions of Python return normalized paths with backslashes
+        # converted to forward slashes, so we must use forward slashes in our
+        # prefix
+        return '//?/' + pathname
+    return '\\\\?\\' + pathname
 
 
 def move_with_overwrite(src, dest):
-  """On windows, rename/move will fail if the destination exists, and there is no
-  race-free way to do it. This method removes the destination if it exists, so
-  the move always works
-  """
-  if os.path.exists(dest):
-    os.remove(dest)
-  os.rename(src, dest)
+    """On windows, rename/move will fail if the destination exists, and there is no
+    race-free way to do it. This method removes the destination if it exists, so
+    the move always works
+    """
+    if os.path.exists(dest):
+        os.remove(dest)
+    os.rename(src, dest)
 
 
 # http://stackoverflow.com/questions/12886768/simple-way-to-unzip-file-in-python-on-all-oses
 def unzip(source_filename, dest_dir):
-  print(f"Unpacking '{source_filename}' to '{dest_dir}'")
-  mkdir_p(dest_dir)
-  common_subdir = None
-  try:
-    with zipfile.ZipFile(source_filename) as zf:
-      # Implement '--strip 1' behavior to unzipping by testing if all the files
-      # in the zip reside in a common subdirectory, and if so, we move the
-      # output tree at the end of uncompression step.
-      for member in zf.infolist():
-        words = member.filename.split('/')
-        if len(words) > 1:  # If there is a directory component?
-          if common_subdir is None:
-            common_subdir = words[0]
-          elif common_subdir != words[0]:
-            common_subdir = None
-            break
-        else:
-          common_subdir = None
-          break
+    print(f"Unpacking '{source_filename}' to '{dest_dir}'")
+    mkdir_p(dest_dir)
+    common_subdir = None
+    try:
+        with zipfile.ZipFile(source_filename) as zf:
+            # Implement '--strip 1' behavior to unzipping by testing if all the files
+            # in the zip reside in a common subdirectory, and if so, we move the
+            # output tree at the end of uncompression step.
+            for member in zf.infolist():
+                words = member.filename.split('/')
+                if len(words) > 1:  # If there is a directory component?
+                    if common_subdir is None:
+                        common_subdir = words[0]
+                    elif common_subdir != words[0]:
+                        common_subdir = None
+                        break
+                else:
+                    common_subdir = None
+                    break
 
-      unzip_to_dir = dest_dir
-      if common_subdir:
-        unzip_to_dir = os.path.join(os.path.dirname(dest_dir), 'unzip_temp')
+            unzip_to_dir = dest_dir
+            if common_subdir:
+                unzip_to_dir = os.path.join(os.path.dirname(dest_dir), 'unzip_temp')
 
-      # Now do the actual decompress.
-      unzip_to_dir = fix_potentially_long_windows_pathname(unzip_to_dir)
-      for member in zf.infolist():
-        zf.extract(member, unzip_to_dir)
-        dst_filename = os.path.join(unzip_to_dir, os.path.normpath(member.filename))
+            # Now do the actual decompress.
+            unzip_to_dir = fix_potentially_long_windows_pathname(unzip_to_dir)
+            for member in zf.infolist():
+                zf.extract(member, unzip_to_dir)
+                dst_filename = os.path.join(unzip_to_dir, os.path.normpath(member.filename))
 
-        # See: https://stackoverflow.com/questions/42326428/zipfile-in-python-file-permission
-        unix_attributes = member.external_attr >> 16
-        if unix_attributes:
-          os.chmod(dst_filename, unix_attributes)
+                # See: https://stackoverflow.com/questions/42326428/zipfile-in-python-file-permission
+                unix_attributes = member.external_attr >> 16
+                if unix_attributes:
+                    os.chmod(dst_filename, unix_attributes)
 
-        # Move the extracted file to its final location without the base
-        # directory name, if we are stripping that away.
-        if common_subdir:
-          assert member.filename.startswith(common_subdir), f'unexpected filename {member.filename}'
-          stripped_filename = '.' + member.filename[len(common_subdir):]
-          final_dst_filename = os.path.join(dest_dir, stripped_filename)
-          # Check if a directory
-          if stripped_filename.endswith('/'):
-            d = fix_potentially_long_windows_pathname(final_dst_filename)
-            if not os.path.isdir(d):
-              os.mkdir(d)
-          else:
-            parent_dir = os.path.dirname(fix_potentially_long_windows_pathname(final_dst_filename))
-            if parent_dir and not os.path.exists(parent_dir):
-              os.makedirs(parent_dir)
-            move_with_overwrite(fix_potentially_long_windows_pathname(dst_filename), fix_potentially_long_windows_pathname(final_dst_filename))
+                # Move the extracted file to its final location without the base
+                # directory name, if we are stripping that away.
+                if common_subdir:
+                    assert member.filename.startswith(common_subdir), f'unexpected filename {member.filename}'
+                    stripped_filename = '.' + member.filename[len(common_subdir):]
+                    final_dst_filename = os.path.join(dest_dir, stripped_filename)
+                    # Check if a directory
+                    if stripped_filename.endswith('/'):
+                        d = fix_potentially_long_windows_pathname(final_dst_filename)
+                        if not os.path.isdir(d):
+                            os.mkdir(d)
+                    else:
+                        parent_dir = os.path.dirname(fix_potentially_long_windows_pathname(final_dst_filename))
+                        if parent_dir and not os.path.exists(parent_dir):
+                            os.makedirs(parent_dir)
+                        move_with_overwrite(fix_potentially_long_windows_pathname(dst_filename), fix_potentially_long_windows_pathname(final_dst_filename))
 
-      if common_subdir:
-        remove_tree(unzip_to_dir)
-  except zipfile.BadZipfile as e:
-    errlog(f"Unzipping file '{source_filename}' failed due to reason: {e}! Removing the corrupted zip file.")
-    rmfile(source_filename)
-    return False
-  except Exception as e:
-    errlog(f"Unzipping file '{source_filename}' failed due to reason: {e}")
-    return False
+            if common_subdir:
+                remove_tree(unzip_to_dir)
+    except zipfile.BadZipfile as e:
+        errlog(f"Unzipping file '{source_filename}' failed due to reason: {e}! Removing the corrupted zip file.")
+        rmfile(source_filename)
+        return False
+    except Exception as e:
+        errlog(f"Unzipping file '{source_filename}' failed due to reason: {e}")
+        return False
 
-  return True
+    return True
 
 
 def path_points_to_directory(path):
-  """This function interprets whether the given string looks like a path to a
-  directory instead of a file, without looking at the actual filesystem.
-  'a/b/c' points to directory, so does 'a/b/c/', but 'a/b/c.x' is parsed as a
-  filename
-  """
-  if path == '.':
-     return True
-  last_slash = max(path.rfind('/'), path.rfind('\\'))
-  last_dot = path.rfind('.')
-  no_suffix = last_dot < last_slash or last_dot == -1
-  if no_suffix:
-    return True
-  suffix = path[last_dot:]
-  # Very simple logic for the only file suffixes used by emsdk downloader. Other
-  # suffixes, like 'clang-3.2' are treated as dirs.
-  if suffix in {'.exe', '.zip', '.txt'}:
-    return False
-  else:
-    return True
+    """This function interprets whether the given string looks like a path to a
+    directory instead of a file, without looking at the actual filesystem.
+    'a/b/c' points to directory, so does 'a/b/c/', but 'a/b/c.x' is parsed as a
+    filename
+    """
+    if path == '.':
+        return True
+    last_slash = max(path.rfind('/'), path.rfind('\\'))
+    last_dot = path.rfind('.')
+    no_suffix = last_dot < last_slash or last_dot == -1
+    if no_suffix:
+        return True
+    suffix = path[last_dot:]
+    # Very simple logic for the only file suffixes used by emsdk downloader. Other
+    # suffixes, like 'clang-3.2' are treated as dirs.
+    if suffix in {'.exe', '.zip', '.txt'}:
+        return False
+    else:
+        return True
 
 
 def get_content_length(download):
-  try:
-    return int(download.headers.get('Content-Length', 0))
-  except ValueError:
-    return 0
+    try:
+        return int(download.headers.get('Content-Length', 0))
+    except ValueError:
+        return 0
 
 
 def get_download_target(url, dstpath, filename_prefix=''):
-  file_name = filename_prefix + url.split('/')[-1]
-  if path_points_to_directory(dstpath):
-    file_name = os.path.join(dstpath, file_name)
-  else:
-    file_name = dstpath
+    file_name = filename_prefix + url.split('/')[-1]
+    if path_points_to_directory(dstpath):
+        file_name = os.path.join(dstpath, file_name)
+    else:
+        file_name = dstpath
 
-  # Treat all relative destination paths as relative to the SDK root directory,
-  # not the current working directory.
-  file_name = sdk_path(file_name)
+    # Treat all relative destination paths as relative to the SDK root directory,
+    # not the current working directory.
+    file_name = sdk_path(file_name)
 
-  return file_name
+    return file_name
 
 
 def download_with_curl(url, file_name):
-  print(f"Downloading: {file_name} from {url}")
-  if not shutil.which('curl'):
-    exit_with_error('curl not found in PATH')
-  # -#: show progress bar
-  # -L: Follow HTTP 3XX redirections
-  # -f: Fail on HTTP errors
-  subprocess.check_call(['curl', '-#', '-f', '-L', '-o', file_name, url])
+    print(f"Downloading: {file_name} from {url}")
+    if not shutil.which('curl'):
+        exit_with_error('curl not found in PATH')
+    # -#: show progress bar
+    # -L: Follow HTTP 3XX redirections
+    # -f: Fail on HTTP errors
+    subprocess.check_call(['curl', '-#', '-f', '-L', '-o', file_name, url])
 
 
 def download_with_urllib(url, file_name):
-  u = urlopen(url)
-  file_size = get_content_length(u)
-  if file_size > 0:
-    print(f"Downloading: {file_name} from {url}, {file_size} Bytes")
-  else:
-    print(f"Downloading: {file_name} from {url}")
+    u = urlopen(url)
+    file_size = get_content_length(u)
+    if file_size > 0:
+        print(f"Downloading: {file_name} from {url}, {file_size} Bytes")
+    else:
+        print(f"Downloading: {file_name} from {url}")
 
-  file_size_dl = 0
-  # Draw a progress bar 80 chars wide (in non-TTY mode)
-  progress_max = 80 - 4
-  progress_shown = 0
-  block_sz = 256 * 1024
-  if not TTY_OUTPUT:
-      print(' [', end='')
+    file_size_dl = 0
+    # Draw a progress bar 80 chars wide (in non-TTY mode)
+    progress_max = 80 - 4
+    progress_shown = 0
+    block_sz = 256 * 1024
+    if not TTY_OUTPUT:
+        print(' [', end='')
 
-  with open(file_name, 'wb') as f:
-    while True:
-        buffer = u.read(block_sz)
-        if not buffer:
-            break
+    with open(file_name, 'wb') as f:
+        while True:
+            buffer = u.read(block_sz)
+            if not buffer:
+                break
 
-        file_size_dl += len(buffer)
-        f.write(buffer)
-        if file_size:
-            percent = file_size_dl * 100.0 / file_size
-            if TTY_OUTPUT:
-                status = f' {file_size_dl:10d}  [{percent:3.02f}%]'
-                print(status, end='\r')
-            else:
-                while progress_shown < progress_max * percent / 100:
-                    print('-', end='')
-                    sys.stdout.flush()
-                    progress_shown += 1
+            file_size_dl += len(buffer)
+            f.write(buffer)
+            if file_size:
+                percent = file_size_dl * 100.0 / file_size
+                if TTY_OUTPUT:
+                    status = f' {file_size_dl:10d}  [{percent:3.02f}%]'
+                    print(status, end='\r')
+                else:
+                    while progress_shown < progress_max * percent / 100:
+                        print('-', end='')
+                        sys.stdout.flush()
+                        progress_shown += 1
 
-  if not TTY_OUTPUT:
-    print(']')
-    sys.stdout.flush()
+    if not TTY_OUTPUT:
+        print(']')
+        sys.stdout.flush()
 
-  debug_print(f'finished downloading ({file_size_dl} bytes)')
+    debug_print(f'finished downloading ({file_size_dl} bytes)')
 
 
 def download_file(url, dstpath, filename_prefix=''):
-  """On success, returns the filename on the disk pointing to the destination file that was produced
-  On failure, returns None.
-  """
-  debug_print(f'download_file(url={url}, dstpath={dstpath})')
-  file_name = get_download_target(url, dstpath, filename_prefix)
+    """On success, returns the filename on the disk pointing to the destination file that was produced
+    On failure, returns None.
+    """
+    debug_print(f'download_file(url={url}, dstpath={dstpath})')
+    file_name = get_download_target(url, dstpath, filename_prefix)
 
-  if KEEP_DOWNLOADS and os.path.exists(file_name):
-    print(f"File '{file_name}' already downloaded, skipping.")
+    if KEEP_DOWNLOADS and os.path.exists(file_name):
+        print(f"File '{file_name}' already downloaded, skipping.")
+        return file_name
+
+    mkdir_p(os.path.dirname(file_name))
+
+    try:
+        # Use curl on macOS or when EMSDK_USE_CURL is set to avoid
+        # CERTIFICATE_VERIFY_FAILED issue with python's urllib:
+        # https://stackoverflow.com/questions/40684543/how-to-make-python-use-ca-certificates-from-mac-os-truststore
+        # Unlike on linux or windows, curl is always available on macOS systems.
+        if MACOS or 'EMSDK_USE_CURL' in os.environ:
+            download_with_curl(url, file_name)
+        else:
+            download_with_urllib(url, file_name)
+    except Exception as e:
+        errlog(f"Error: Downloading URL '{url}': {e}")
+        return None
+    except KeyboardInterrupt:
+        rmfile(file_name)
+        raise
+
     return file_name
 
-  mkdir_p(os.path.dirname(file_name))
-
-  try:
-    # Use curl on macOS or when EMSDK_USE_CURL is set to avoid
-    # CERTIFICATE_VERIFY_FAILED issue with python's urllib:
-    # https://stackoverflow.com/questions/40684543/how-to-make-python-use-ca-certificates-from-mac-os-truststore
-    # Unlike on linux or windows, curl is always available on macOS systems.
-    if MACOS or 'EMSDK_USE_CURL' in os.environ:
-      download_with_curl(url, file_name)
-    else:
-      download_with_urllib(url, file_name)
-  except Exception as e:
-    errlog(f"Error: Downloading URL '{url}': {e}")
-    return None
-  except KeyboardInterrupt:
-    rmfile(file_name)
-    raise
-
-  return file_name
-
 
 def run_get_output(cmd, cwd=None):
-  debug_print(f'run_get_output(cmd={cmd}, cwd={cwd})')
-  return subprocess.check_output(cmd, cwd=cwd, text=True)
+    debug_print(f'run_get_output(cmd={cmd}, cwd={cwd})')
+    return subprocess.check_output(cmd, cwd=cwd, text=True)
 
 
 def GIT():
-  git = shutil.which('git')
-  if not git:
-    msg = 'git executable was not found. Please install git for this operation!'
-    if WINDOWS:
-      msg += "This can be done from http://git-scm.com/"
-    elif MACOS:
-      msg += "This can be done from http://git-scm.com/, or by installing XCode and then the XCode Command Line Tools"
-    elif LINUX:
-      msg += "This can be probably be done using your package manager, see http://git-scm.com/book/en/Getting-Started-Installing-Git"
-    exit_with_error(msg)
+    git = shutil.which('git')
+    if not git:
+        msg = 'git executable was not found. Please install git for this operation!'
+        if WINDOWS:
+            msg += "This can be done from http://git-scm.com/"
+        elif MACOS:
+            msg += "This can be done from http://git-scm.com/, or by installing XCode and then the XCode Command Line Tools"
+        elif LINUX:
+            msg += "This can be probably be done using your package manager, see http://git-scm.com/book/en/Getting-Started-Installing-Git"
+        exit_with_error(msg)
 
-  return git
+    return git
 
 
 def git_repo_version(repo_path):
-  stdout = run_get_output([GIT(), 'log', '-n', '1', '--pretty="%aD %H"'], cwd=repo_path)
-  return stdout.strip()
+    stdout = run_get_output([GIT(), 'log', '-n', '1', '--pretty="%aD %H"'], cwd=repo_path)
+    return stdout.strip()
 
 
 def git_recent_commits(repo_path, n=20):
-  stdout = run_get_output([GIT(), 'log', '-n', str(n), '--pretty="%H"'], cwd=repo_path)
-  return stdout.strip().replace('\r', '').replace('"', '').split('\n')
+    stdout = run_get_output([GIT(), 'log', '-n', str(n), '--pretty="%H"'], cwd=repo_path)
+    return stdout.strip().replace('\r', '').replace('"', '').split('\n')
 
 
 def get_git_remotes(repo_path):
-  remotes = []
-  output = run_get_output([GIT(), 'remote', '-v'], cwd=repo_path)
-  for line in output.splitlines():
-    remotes += [line.split()[0]]
-  return remotes
+    remotes = []
+    output = run_get_output([GIT(), 'remote', '-v'], cwd=repo_path)
+    for line in output.splitlines():
+        remotes += [line.split()[0]]
+    return remotes
 
 
 def git_clone(url, dstpath, branch, remote_name='origin'):
-  debug_print(f'git_clone(url={url}, dstpath={dstpath})')
-  if os.path.exists(os.path.join(dstpath, '.git')):
-    remotes = get_git_remotes(dstpath)
-    if remote_name in remotes:
-      debug_print(f'Repository {url} with remote "{remote_name}" already cloned to directory {dstpath}, skipping.')
-      return True
-    else:
-      debug_print(f'Repository {url} with remote "{remote_name}" already cloned to directory {dstpath}, but remote has not yet been added. Creating.')
-      return run([GIT(), 'remote', 'add', remote_name, url], cwd=dstpath) == 0
+    debug_print(f'git_clone(url={url}, dstpath={dstpath})')
+    if os.path.exists(os.path.join(dstpath, '.git')):
+        remotes = get_git_remotes(dstpath)
+        if remote_name in remotes:
+            debug_print(f'Repository {url} with remote "{remote_name}" already cloned to directory {dstpath}, skipping.')
+            return True
+        else:
+            debug_print(f'Repository {url} with remote "{remote_name}" already cloned to directory {dstpath}, but remote has not yet been added. Creating.')
+            return run([GIT(), 'remote', 'add', remote_name, url], cwd=dstpath) == 0
 
-  mkdir_p(dstpath)
-  git_clone_args = ['--recurse-submodules', '--branch', branch]  # Do not check out a branch (installer will issue a checkout command right after)
-  if GIT_CLONE_SHALLOW:
-    git_clone_args += ['--depth', '1']
-  print(f'Cloning from {url}...')
-  return run([GIT(), 'clone', '-o', remote_name, *git_clone_args, url, dstpath]) == 0
+    mkdir_p(dstpath)
+    git_clone_args = ['--recurse-submodules', '--branch', branch]  # Do not check out a branch (installer will issue a checkout command right after)
+    if GIT_CLONE_SHALLOW:
+        git_clone_args += ['--depth', '1']
+    print(f'Cloning from {url}...')
+    return run([GIT(), 'clone', '-o', remote_name, *git_clone_args, url, dstpath]) == 0
 
 
 def git_pull(repo_path, branch_or_tag, remote_name='origin'):
-  debug_print(f'git_pull(repo_path={repo_path}, branch/tag={branch_or_tag}, remote_name={remote_name})')
-  ret = run([GIT(), 'fetch', '--quiet', remote_name], repo_path)
-  if ret != 0:
-    return False
-  try:
-    print(f"Fetching latest changes to the branch/tag '{branch_or_tag}' for '{repo_path}'...")
+    debug_print(f'git_pull(repo_path={repo_path}, branch/tag={branch_or_tag}, remote_name={remote_name})')
     ret = run([GIT(), 'fetch', '--quiet', remote_name], repo_path)
     if ret != 0:
-      return False
-    # Test if branch_or_tag is a branch, or if it is a tag that needs to be updated
-    target_is_tag = run([GIT(), 'symbolic-ref', '-q', 'HEAD'], repo_path, check=False)
+        return False
+    try:
+        print(f"Fetching latest changes to the branch/tag '{branch_or_tag}' for '{repo_path}'...")
+        ret = run([GIT(), 'fetch', '--quiet', remote_name], repo_path)
+        if ret != 0:
+            return False
+        # Test if branch_or_tag is a branch, or if it is a tag that needs to be updated
+        target_is_tag = run([GIT(), 'symbolic-ref', '-q', 'HEAD'], repo_path, check=False)
 
-    if target_is_tag:
-      ret = run([GIT(), 'checkout', '--recurse-submodules', '--quiet', branch_or_tag], repo_path)
-    else:
-      local_branch_prefix = (remote_name + '_') if remote_name != 'origin' else ''
-      ret = run([GIT(), 'checkout', '--recurse-submodules', '--quiet', '-B', local_branch_prefix + branch_or_tag,
-                 '--track', remote_name + '/' + branch_or_tag], repo_path)
-    if ret != 0:
-      return False
-    if not target_is_tag:
-      # update branch to latest (not needed for tags)
-      # this line assumes that the user has not gone and made local changes to the repo
-      ret = run([GIT(), 'merge', '--ff-only', remote_name + '/' + branch_or_tag], repo_path)
-    if ret != 0:
-      return False
-    run([GIT(), 'submodule', 'update', '--init'], repo_path, check=False)
-  except Exception:
-    errlog('git operation failed!')
-    return False
-  print(f"Successfully updated and checked out branch/tag '{branch_or_tag}' on repository '{repo_path}'")
-  print("Current repository version: " + git_repo_version(repo_path))
-  return True
+        if target_is_tag:
+            ret = run([GIT(), 'checkout', '--recurse-submodules', '--quiet', branch_or_tag], repo_path)
+        else:
+            local_branch_prefix = (remote_name + '_') if remote_name != 'origin' else ''
+            ret = run([GIT(), 'checkout', '--recurse-submodules', '--quiet', '-B', local_branch_prefix + branch_or_tag,
+                       '--track', remote_name + '/' + branch_or_tag], repo_path)
+        if ret != 0:
+            return False
+        if not target_is_tag:
+            # update branch to latest (not needed for tags)
+            # this line assumes that the user has not gone and made local changes to the repo
+            ret = run([GIT(), 'merge', '--ff-only', remote_name + '/' + branch_or_tag], repo_path)
+        if ret != 0:
+            return False
+        run([GIT(), 'submodule', 'update', '--init'], repo_path, check=False)
+    except Exception:
+        errlog('git operation failed!')
+        return False
+    print(f"Successfully updated and checked out branch/tag '{branch_or_tag}' on repository '{repo_path}'")
+    print("Current repository version: " + git_repo_version(repo_path))
+    return True
 
 
 def git_clone_checkout_and_pull(url, dstpath, branch, override_remote_name='origin'):
-  debug_print(f'git_clone_checkout_and_pull(url={url}, dstpath={dstpath}, branch={branch}, override_remote_name={override_remote_name})')
+    debug_print(f'git_clone_checkout_and_pull(url={url}, dstpath={dstpath}, branch={branch}, override_remote_name={override_remote_name})')
 
-  # Make sure the repository is cloned first
-  success = git_clone(url, dstpath, branch, override_remote_name)
-  if not success:
-    return False
+    # Make sure the repository is cloned first
+    success = git_clone(url, dstpath, branch, override_remote_name)
+    if not success:
+        return False
 
-  # And/or issue a pull/checkout to get to latest code.
-  return git_pull(dstpath, branch, override_remote_name)
+    # And/or issue a pull/checkout to get to latest code.
+    return git_pull(dstpath, branch, override_remote_name)
 
 
 def decide_cmake_build_type(tool):
-  """Each tool can have its own build type, or it can be overridden on the command
-  line.
-  """
-  if CMAKE_BUILD_TYPE_OVERRIDE:
-    return CMAKE_BUILD_TYPE_OVERRIDE
-  else:
-    return tool.cmake_build_type
+    """Each tool can have its own build type, or it can be overridden on the command
+    line.
+    """
+    if CMAKE_BUILD_TYPE_OVERRIDE:
+        return CMAKE_BUILD_TYPE_OVERRIDE
+    else:
+        return tool.cmake_build_type
 
 
 def llvm_build_dir(tool):
-  """The root directory of the build."""
-  generator_suffix = cmake_generator_prefix()
-  bitness_suffix = '_32' if tool.bitness == 32 else '_64'
+    """The root directory of the build."""
+    generator_suffix = cmake_generator_prefix()
+    bitness_suffix = '_32' if tool.bitness == 32 else '_64'
 
-  if tool.git_branch:
-    build_dir = 'build_' + tool.git_branch.replace(os.sep, '-') + generator_suffix + bitness_suffix
-  else:
-    build_dir = 'build_' + tool.version + generator_suffix + bitness_suffix
-  return build_dir
+    if tool.git_branch:
+        build_dir = 'build_' + tool.git_branch.replace(os.sep, '-') + generator_suffix + bitness_suffix
+    else:
+        build_dir = 'build_' + tool.version + generator_suffix + bitness_suffix
+    return build_dir
 
 
 def exe_suffix(filename):
-  if WINDOWS and not filename.endswith('.exe'):
-    filename += '.exe'
-  return filename
+    if WINDOWS and not filename.endswith('.exe'):
+        filename += '.exe'
+    return filename
 
 
 def llvm_build_bin_dir(tool):
-  """The directory where the binaries are produced. (relative to the installation
-  root directory of the tool)
-  """
-  build_dir = llvm_build_dir(tool)
-  if WINDOWS and 'Visual Studio' in CMAKE_GENERATOR:
-    old_llvm_bin_dir = os.path.join(build_dir, 'bin', decide_cmake_build_type(tool))
+    """The directory where the binaries are produced. (relative to the installation
+    root directory of the tool)
+    """
+    build_dir = llvm_build_dir(tool)
+    if WINDOWS and 'Visual Studio' in CMAKE_GENERATOR:
+        old_llvm_bin_dir = os.path.join(build_dir, 'bin', decide_cmake_build_type(tool))
 
-    new_llvm_bin_dir = None
-    default_cmake_build_type = decide_cmake_build_type(tool)
-    cmake_build_types = [default_cmake_build_type, 'Release', 'RelWithDebInfo', 'MinSizeRel', 'Debug']
-    for build_type in cmake_build_types:
-      d = os.path.join(build_dir, build_type, 'bin')
-      if os.path.isfile(os.path.join(tool.installation_path(), d, exe_suffix('clang'))):
-        new_llvm_bin_dir = d
-        break
+        new_llvm_bin_dir = None
+        default_cmake_build_type = decide_cmake_build_type(tool)
+        cmake_build_types = [default_cmake_build_type, 'Release', 'RelWithDebInfo', 'MinSizeRel', 'Debug']
+        for build_type in cmake_build_types:
+            d = os.path.join(build_dir, build_type, 'bin')
+            if os.path.isfile(os.path.join(tool.installation_path(), d, exe_suffix('clang'))):
+                new_llvm_bin_dir = d
+                break
 
-    if new_llvm_bin_dir and os.path.exists(os.path.join(tool.installation_path(), new_llvm_bin_dir)):
-      return new_llvm_bin_dir
-    elif os.path.exists(os.path.join(tool.installation_path(), old_llvm_bin_dir)):
-      return old_llvm_bin_dir
-    return os.path.join(build_dir, default_cmake_build_type, 'bin')
-  else:
-    return os.path.join(build_dir, 'bin')
+        if new_llvm_bin_dir and os.path.exists(os.path.join(tool.installation_path(), new_llvm_bin_dir)):
+            return new_llvm_bin_dir
+        elif os.path.exists(os.path.join(tool.installation_path(), old_llvm_bin_dir)):
+            return old_llvm_bin_dir
+        return os.path.join(build_dir, default_cmake_build_type, 'bin')
+    else:
+        return os.path.join(build_dir, 'bin')
 
 
 def build_env():
-  if WINDOWS and 'Visual Studio' in CMAKE_GENERATOR:
-    env = os.environ.copy()
-    # MSBuild.exe has an internal mechanism to avoid N^2 oversubscription of threads in its two-tier build model, see
-    # https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
-    env['UseMultiToolTask'] = 'true'
-    env['EnforceProcessCountAcrossBuilds'] = 'true'
-    return env
+    if WINDOWS and 'Visual Studio' in CMAKE_GENERATOR:
+        env = os.environ.copy()
+        # MSBuild.exe has an internal mechanism to avoid N^2 oversubscription of threads in its two-tier build model, see
+        # https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
+        env['UseMultiToolTask'] = 'true'
+        env['EnforceProcessCountAcrossBuilds'] = 'true'
+        return env
 
-  # By default, just inherit the parent env
-  return None
+    # By default, just inherit the parent env
+    return None
 
 
 def find_cmake():
-  """Find path to cmake executable, as one of the activated tools, in PATH, or from installed tools."""
-  def locate_cmake_from_tool(tool):
-    tool_path = get_required_path([tool])
-    tool_path = tool_path[-1]
-    cmake_exe = 'cmake.exe' if WINDOWS else 'cmake'
-    cmake_exe = os.path.join(tool_path, cmake_exe)
-    if os.path.isfile(cmake_exe):
-      return cmake_exe
+    """Find path to cmake executable, as one of the activated tools, in PATH, or from installed tools."""
+    def locate_cmake_from_tool(tool):
+        tool_path = get_required_path([tool])
+        tool_path = tool_path[-1]
+        cmake_exe = 'cmake.exe' if WINDOWS else 'cmake'
+        cmake_exe = os.path.join(tool_path, cmake_exe)
+        if os.path.isfile(cmake_exe):
+            return cmake_exe
 
-  # 1. If user has activated a specific cmake tool, then use that tool to configure the build.
-  for tool in reversed(tools):
-    if tool.id == 'cmake' and tool.is_active():
-      cmake_exe = locate_cmake_from_tool(tool)
-      if cmake_exe:
-        info(f'Found installed+activated CMake tool at "{cmake_exe}"')
+    # 1. If user has activated a specific cmake tool, then use that tool to configure the build.
+    for tool in reversed(tools):
+        if tool.id == 'cmake' and tool.is_active():
+            cmake_exe = locate_cmake_from_tool(tool)
+            if cmake_exe:
+                info(f'Found installed+activated CMake tool at "{cmake_exe}"')
+                return cmake_exe
+
+    # 2. If cmake already exists in PATH, then use that cmake to configure the build.
+    cmake_exe = shutil.which('cmake')
+    if cmake_exe:
+        info(f'Found CMake from PATH at "{cmake_exe}"')
         return cmake_exe
 
-  # 2. If cmake already exists in PATH, then use that cmake to configure the build.
-  cmake_exe = shutil.which('cmake')
-  if cmake_exe:
-    info(f'Found CMake from PATH at "{cmake_exe}"')
-    return cmake_exe
+    # 3. Finally, if user has installed a cmake tool, but has not activated that, then use
+    # that tool. This enables a single-liner directive
+    #   "emsdk install cmake-4.2.0-rc3-64bit llvm-git-main-64bit" to first install CMake, and
+    # then use it to configure to build LLVM.
+    for tool in reversed(tools):
+        if tool.id == 'cmake' and tool.is_installed():
+            cmake_exe = locate_cmake_from_tool(tool)
+            if cmake_exe:
+                info(f'Found installed CMake tool at "{cmake_exe}"')
+                return cmake_exe
 
-  # 3. Finally, if user has installed a cmake tool, but has not activated that, then use
-  # that tool. This enables a single-liner directive
-  #   "emsdk install cmake-4.2.0-rc3-64bit llvm-git-main-64bit" to first install CMake, and
-  # then use it to configure to build LLVM.
-  for tool in reversed(tools):
-    if tool.id == 'cmake' and tool.is_installed():
-      cmake_exe = locate_cmake_from_tool(tool)
-      if cmake_exe:
-        info(f'Found installed CMake tool at "{cmake_exe}"')
-        return cmake_exe
-
-  exit_with_error('Unable to find "cmake" in PATH, or as installed/activated tool! Please install CMake first')
+    exit_with_error('Unable to find "cmake" in PATH, or as installed/activated tool! Please install CMake first')
 
 
 def make_build(build_root, build_type):
-  debug_print(f'make_build(build_root={build_root}, build_type={build_type})')
-  if CPU_CORES > 1:
-    print(f'Performing a parallel build with {CPU_CORES} cores.')
-  else:
-    print('Performing a singlethreaded build.')
+    debug_print(f'make_build(build_root={build_root}, build_type={build_type})')
+    if CPU_CORES > 1:
+        print(f'Performing a parallel build with {CPU_CORES} cores.')
+    else:
+        print('Performing a singlethreaded build.')
 
-  make = [find_cmake(), '--build', '.', '--config', build_type]
-  if 'Visual Studio' in CMAKE_GENERATOR:
-    # Visual Studio historically has had a two-tier problem in its build system design. A single MSBuild.exe instance only governs
-    # the build of a single project (.exe/.lib/.dll) in a solution. Passing the -j parameter above will only enable multiple MSBuild.exe
-    # instances to be spawned to build multiple projects in parallel, but each MSBuild.exe is still singlethreaded.
-    # To enable each MSBuild.exe instance to also compile several .cpp files in parallel inside a single project, pass the extra
-    # MSBuild.exe specific "Multi-ToolTask" (MTT) setting /p:CL_MPCount. This enables each MSBuild.exe to parallelize builds wide.
-    # This requires CMake 3.12 or newer.
-    make += ['-j', str(CPU_CORES), '--', '/p:CL_MPCount=' + str(CPU_CORES)]
-  else:
-    # Pass -j to native make, CMake might not support -j option.
-    make += ['--', '-j', str(CPU_CORES)]
+    make = [find_cmake(), '--build', '.', '--config', build_type]
+    if 'Visual Studio' in CMAKE_GENERATOR:
+        # Visual Studio historically has had a two-tier problem in its build system design. A single MSBuild.exe instance only governs
+        # the build of a single project (.exe/.lib/.dll) in a solution. Passing the -j parameter above will only enable multiple MSBuild.exe
+        # instances to be spawned to build multiple projects in parallel, but each MSBuild.exe is still singlethreaded.
+        # To enable each MSBuild.exe instance to also compile several .cpp files in parallel inside a single project, pass the extra
+        # MSBuild.exe specific "Multi-ToolTask" (MTT) setting /p:CL_MPCount. This enables each MSBuild.exe to parallelize builds wide.
+        # This requires CMake 3.12 or newer.
+        make += ['-j', str(CPU_CORES), '--', '/p:CL_MPCount=' + str(CPU_CORES)]
+    else:
+        # Pass -j to native make, CMake might not support -j option.
+        make += ['--', '-j', str(CPU_CORES)]
 
-  # Build
-  print('Running build: ' + str(make))
-  ret = subprocess.call(make, cwd=build_root, env=build_env())
-  if ret != 0:
-    errlog(f'Build failed with exit code {ret}!')
-    errlog('Working directory: ' + build_root)
-    return False
+    # Build
+    print('Running build: ' + str(make))
+    ret = subprocess.call(make, cwd=build_root, env=build_env())
+    if ret != 0:
+        errlog(f'Build failed with exit code {ret}!')
+        errlog('Working directory: ' + build_root)
+        return False
 
-  return True
+    return True
 
 
 def write_file(filename, content):
-  with open(filename, 'w', encoding='utf-8') as f:
-    f.write(content)
+    with open(filename, 'w', encoding='utf-8') as f:
+        f.write(content)
 
 
 def read_file(filename):
-  with open(filename, encoding='utf-8') as f:
-    return f.read()
+    with open(filename, encoding='utf-8') as f:
+        return f.read()
 
 
 def cmake_configure(generator, build_root, src_root, build_type, extra_cmake_args):
-  debug_print(f'cmake_configure(generator={generator}, build_root={build_root}, '
-              f'src_root={src_root}, build_type={build_type}, extra_cmake_args={extra_cmake_args})')
-  # Configure
-  if not os.path.isdir(build_root):
-    # Create build output directory if it doesn't yet exist.
-    os.mkdir(build_root)
-  cmdline = [find_cmake(), '-DCMAKE_BUILD_TYPE=' + build_type, '-DPYTHON_EXECUTABLE=' + sys.executable]
-  if generator:
-    cmdline += ['-G', generator]
-  # Target macOS 11.0 Big Sur at minimum, to support older Mac devices.
-  # See https://en.wikipedia.org/wiki/MacOS#Hardware_compatibility for min-spec details.
-  cmdline += ['-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0']
-  cmdline += [*extra_cmake_args, src_root]
+    debug_print(f'cmake_configure(generator={generator}, build_root={build_root}, '
+                f'src_root={src_root}, build_type={build_type}, extra_cmake_args={extra_cmake_args})')
+    # Configure
+    if not os.path.isdir(build_root):
+        # Create build output directory if it doesn't yet exist.
+        os.mkdir(build_root)
+    cmdline = [find_cmake(), '-DCMAKE_BUILD_TYPE=' + build_type, '-DPYTHON_EXECUTABLE=' + sys.executable]
+    if generator:
+        cmdline += ['-G', generator]
+    # Target macOS 11.0 Big Sur at minimum, to support older Mac devices.
+    # See https://en.wikipedia.org/wiki/MacOS#Hardware_compatibility for min-spec details.
+    cmdline += ['-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0']
+    cmdline += [*extra_cmake_args, src_root]
 
-  print(f'Running CMake: {cmdline}')
+    print(f'Running CMake: {cmdline}')
 
-  # Specify the deployment target also as an env. var, since some Xcode versions
-  # read this instead of the CMake field.
-  os.environ['MACOSX_DEPLOYMENT_TARGET'] = '11.0'
+    # Specify the deployment target also as an env. var, since some Xcode versions
+    # read this instead of the CMake field.
+    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '11.0'
 
-  def quote_parens(x):
-    if ' ' in x:
-      return '"' + x.replace('"', '\\"') + '"'
-    else:
-      return x
+    def quote_parens(x):
+        if ' ' in x:
+            return '"' + x.replace('"', '\\"') + '"'
+        else:
+            return x
 
-  # Create a file 'recmake.bat/sh' in the build root that user can call to
-  # manually recmake the build tree with the previous build params
-  re_cmake_script = os.path.join(build_root, 'recmake.' + ('bat' if WINDOWS else 'sh'))
-  write_file(re_cmake_script, ' '.join(map(quote_parens, cmdline)))
-  try:
-    subprocess.check_call(cmdline, cwd=build_root, env=build_env())
-  except Exception as e:
-    errlog('CMake invocation failed due to exception')
-    errlog(f'Working directory: {build_root}')
-    errlog(str(e))
-    return False
+    # Create a file 'recmake.bat/sh' in the build root that user can call to
+    # manually recmake the build tree with the previous build params
+    re_cmake_script = os.path.join(build_root, 'recmake.' + ('bat' if WINDOWS else 'sh'))
+    write_file(re_cmake_script, ' '.join(map(quote_parens, cmdline)))
+    try:
+        subprocess.check_call(cmdline, cwd=build_root, env=build_env())
+    except Exception as e:
+        errlog('CMake invocation failed due to exception')
+        errlog(f'Working directory: {build_root}')
+        errlog(str(e))
+        return False
 
-  return True
+    return True
 
 
 def xcode_sdk_version():
-  try:
-    output = run_get_output(['xcrun', '--show-sdk-version'])
-    return output.strip().split('.')
-  except Exception:
-    return subprocess.checkplatform.mac_ver()[0].split('.')
+    try:
+        output = run_get_output(['xcrun', '--show-sdk-version'])
+        return output.strip().split('.')
+    except Exception:
+        return subprocess.checkplatform.mac_ver()[0].split('.')
 
 
 def cmake_target_platform(tool):
-  # Source: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html#platform-selection
-  if tool.arch:
-    if tool.arch == 'arm64':
-      return 'ARM64'
-    elif tool.arch == 'x86_64':
-      return 'x64'
-    elif tool.arch == 'x86':
-      return 'Win32'
-  if ARCH == 'arm64':
-    return 'ARM64'
-  else:
-    return 'x64' if tool.bitness == 64 else 'Win32'
+    # Source: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html#platform-selection
+    if tool.arch:
+        if tool.arch == 'arm64':
+            return 'ARM64'
+        elif tool.arch == 'x86_64':
+            return 'x64'
+        elif tool.arch == 'x86':
+            return 'Win32'
+    if ARCH == 'arm64':
+        return 'ARM64'
+    else:
+        return 'x64' if tool.bitness == 64 else 'Win32'
 
 
 def cmake_host_platform():
-  # Source: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html#toolset-selection
-  arch_to_cmake_host_platform = {
-    'arm64': 'ARM64',
-    'arm': 'ARM',
-    'x86_64': 'x64',
-    'x86': 'x86',
-  }
-  return arch_to_cmake_host_platform[ARCH]
+    # Source: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html#toolset-selection
+    arch_to_cmake_host_platform = {
+      'arm64': 'ARM64',
+      'arm': 'ARM',
+      'x86_64': 'x64',
+      'x86': 'x86',
+    }
+    return arch_to_cmake_host_platform[ARCH]
 
 
 def get_generator_and_config_args(tool):
-  args = []
-  cmake_generator = CMAKE_GENERATOR
-  if 'Visual Studio 16' in CMAKE_GENERATOR or 'Visual Studio 17' in CMAKE_GENERATOR:  # VS2019 or VS2022
-    # With Visual Studio 16 2019, CMake changed the way they specify target arch.
-    # Instead of appending it into the CMake generator line, it is specified
-    # with a -A arch parameter.
-    args += ['-A', cmake_target_platform(tool)]
-    args += ['-Thost=' + cmake_host_platform()]
-  elif 'Visual Studio' in CMAKE_GENERATOR and tool.bitness == 64:
-    cmake_generator += ' Win64'
-    args += ['-Thost=x64']
-  return (cmake_generator, args)
+    args = []
+    cmake_generator = CMAKE_GENERATOR
+    if 'Visual Studio 16' in CMAKE_GENERATOR or 'Visual Studio 17' in CMAKE_GENERATOR:  # VS2019 or VS2022
+        # With Visual Studio 16 2019, CMake changed the way they specify target arch.
+        # Instead of appending it into the CMake generator line, it is specified
+        # with a -A arch parameter.
+        args += ['-A', cmake_target_platform(tool)]
+        args += ['-Thost=' + cmake_host_platform()]
+    elif 'Visual Studio' in CMAKE_GENERATOR and tool.bitness == 64:
+        cmake_generator += ' Win64'
+        args += ['-Thost=x64']
+    return (cmake_generator, args)
 
 
 def cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args):
-  success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
-  if success:
-    success = make_build(build_root, build_type)
-
-  if not success and get_env_boolean('EMSDK_RETRY_CLEAN_BUILD'):
-    # Delete the CMake build directory to force a full re-cmake + clean rebuild.
-    shutil.rmtree(build_root)
-
-    # And re-try configure + build again.
     success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
     if success:
-      success = make_build(build_root, build_type)
+        success = make_build(build_root, build_type)
 
-  return success
+    if not success and get_env_boolean('EMSDK_RETRY_CLEAN_BUILD'):
+        # Delete the CMake build directory to force a full re-cmake + clean rebuild.
+        shutil.rmtree(build_root)
+
+        # And re-try configure + build again.
+        success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
+        if success:
+            success = make_build(build_root, build_type)
+
+    return success
 
 
 def build_llvm(tool):
-  debug_print(f'build_llvm({tool})')
-  llvm_root = tool.installation_path()
-  llvm_src_root = os.path.join(llvm_root, 'src')
-  success = git_clone_checkout_and_pull(tool.url, llvm_src_root, tool.git_branch)
-  if not success:
-    return False
+    debug_print(f'build_llvm({tool})')
+    llvm_root = tool.installation_path()
+    llvm_src_root = os.path.join(llvm_root, 'src')
+    success = git_clone_checkout_and_pull(tool.url, llvm_src_root, tool.git_branch)
+    if not success:
+        return False
 
-  build_dir = llvm_build_dir(tool)
-  build_root = os.path.join(llvm_root, build_dir)
+    build_dir = llvm_build_dir(tool)
+    build_root = os.path.join(llvm_root, build_dir)
 
-  build_type = decide_cmake_build_type(tool)
+    build_type = decide_cmake_build_type(tool)
 
-  # Configure
-  tests_arg = 'ON' if BUILD_FOR_TESTING else 'OFF'
+    # Configure
+    tests_arg = 'ON' if BUILD_FOR_TESTING else 'OFF'
 
-  enable_assertions = ENABLE_LLVM_ASSERTIONS.lower() == 'on' or (ENABLE_LLVM_ASSERTIONS == 'auto' and build_type.lower() not in {'release', 'minsizerel'})
+    enable_assertions = ENABLE_LLVM_ASSERTIONS.lower() == 'on' or (ENABLE_LLVM_ASSERTIONS == 'auto' and build_type.lower() not in {'release', 'minsizerel'})
 
-  if ARCH in {'x86', 'x86_64'}:
-    targets_to_build = 'WebAssembly;X86'
-  elif ARCH == 'arm':
-    targets_to_build = 'WebAssembly;ARM'
-  elif ARCH == 'arm64':
-    targets_to_build = 'WebAssembly;AArch64'
-  else:
-    targets_to_build = 'WebAssembly'
-  cmake_generator, args = get_generator_and_config_args(tool)
-  args += ['-DLLVM_TARGETS_TO_BUILD=' + targets_to_build,
-           '-DLLVM_INCLUDE_EXAMPLES=OFF',
-           '-DLLVM_INCLUDE_TESTS=' + tests_arg,
-           '-DCLANG_INCLUDE_TESTS=' + tests_arg,
-           '-DLLVM_ENABLE_ASSERTIONS=' + ('ON' if enable_assertions else 'OFF'),
-           # Disable optional LLVM dependencies, these can cause unwanted .so dependencies
-           # that prevent distributing the generated compiler for end users.
-           '-DLLVM_ENABLE_LIBXML2=OFF', '-DLLDB_ENABLE_LIBEDIT=OFF',
-           '-DLLVM_ENABLE_LIBEDIT=OFF', '-DLLVM_ENABLE_LIBPFM=OFF']
-  # LLVM build system bug: compiler-rt does not build on Windows. It insists on performing a CMake install step that writes to C:\Program Files. Attempting
-  # to reroute that to build_root directory then fails on an error
-  #  file INSTALL cannot find
-  #  "C:/code/emsdk/llvm/git/build_master_vs2017_64/$(Configuration)/lib/clang/10.0.0/lib/windows/clang_rt.ubsan_standalone-x86_64.lib".
-  # (there instead of $(Configuration), one would need ${CMAKE_BUILD_TYPE} ?)
-  # It looks like compiler-rt is not compatible to build on Windows?
-  args += ['-DLLVM_ENABLE_PROJECTS=clang;lld']
-  # To enable widest possible chance of success for building, let the code
-  # compile through with older toolchains that are about to be deprecated by
-  # upstream LLVM.
-  args += ['-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON']
+    if ARCH in {'x86', 'x86_64'}:
+        targets_to_build = 'WebAssembly;X86'
+    elif ARCH == 'arm':
+        targets_to_build = 'WebAssembly;ARM'
+    elif ARCH == 'arm64':
+        targets_to_build = 'WebAssembly;AArch64'
+    else:
+        targets_to_build = 'WebAssembly'
+    cmake_generator, args = get_generator_and_config_args(tool)
+    args += ['-DLLVM_TARGETS_TO_BUILD=' + targets_to_build,
+             '-DLLVM_INCLUDE_EXAMPLES=OFF',
+             '-DLLVM_INCLUDE_TESTS=' + tests_arg,
+             '-DCLANG_INCLUDE_TESTS=' + tests_arg,
+             '-DLLVM_ENABLE_ASSERTIONS=' + ('ON' if enable_assertions else 'OFF'),
+             # Disable optional LLVM dependencies, these can cause unwanted .so dependencies
+             # that prevent distributing the generated compiler for end users.
+             '-DLLVM_ENABLE_LIBXML2=OFF', '-DLLDB_ENABLE_LIBEDIT=OFF',
+             '-DLLVM_ENABLE_LIBEDIT=OFF', '-DLLVM_ENABLE_LIBPFM=OFF']
+    # LLVM build system bug: compiler-rt does not build on Windows. It insists on performing a CMake install step that writes to C:\Program Files. Attempting
+    # to reroute that to build_root directory then fails on an error
+    #  file INSTALL cannot find
+    #  "C:/code/emsdk/llvm/git/build_master_vs2017_64/$(Configuration)/lib/clang/10.0.0/lib/windows/clang_rt.ubsan_standalone-x86_64.lib".
+    # (there instead of $(Configuration), one would need ${CMAKE_BUILD_TYPE} ?)
+    # It looks like compiler-rt is not compatible to build on Windows?
+    args += ['-DLLVM_ENABLE_PROJECTS=clang;lld']
+    # To enable widest possible chance of success for building, let the code
+    # compile through with older toolchains that are about to be deprecated by
+    # upstream LLVM.
+    args += ['-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON']
 
-  if os.getenv('LLVM_CMAKE_ARGS'):
-    extra_args = os.environ['LLVM_CMAKE_ARGS'].split(',')
-    print('Passing the following extra arguments to LLVM CMake configuration: ' + str(extra_args))
-    args += extra_args
+    if os.getenv('LLVM_CMAKE_ARGS'):
+        extra_args = os.environ['LLVM_CMAKE_ARGS'].split(',')
+        print('Passing the following extra arguments to LLVM CMake configuration: ' + str(extra_args))
+        args += extra_args
 
-  cmakelists_dir = os.path.join(llvm_src_root, 'llvm')
+    cmakelists_dir = os.path.join(llvm_src_root, 'llvm')
 
-  success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)
+    success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)
 
-  return success
+    return success
 
 
 def build_ninja(tool):
-  debug_print(f'build_ninja({tool})')
-  root = os.path.normpath(tool.installation_path())
-  src_root = os.path.join(root, 'src')
-  success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
-  if not success:
-    return False
+    debug_print(f'build_ninja({tool})')
+    root = os.path.normpath(tool.installation_path())
+    src_root = os.path.join(root, 'src')
+    success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
+    if not success:
+        return False
 
-  build_dir = llvm_build_dir(tool)
-  build_root = os.path.join(root, build_dir)
+    build_dir = llvm_build_dir(tool)
+    build_root = os.path.join(root, build_dir)
 
-  build_type = decide_cmake_build_type(tool)
+    build_type = decide_cmake_build_type(tool)
 
-  # Configure
-  cmake_generator, args = get_generator_and_config_args(tool)
+    # Configure
+    cmake_generator, args = get_generator_and_config_args(tool)
 
-  cmakelists_dir = os.path.join(src_root)
+    cmakelists_dir = os.path.join(src_root)
 
-  success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)
+    success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)
 
-  if success:
-    bin_dir = os.path.join(root, 'bin')
-    mkdir_p(bin_dir)
-    exe_paths = [os.path.join(build_root, 'Release', 'ninja'), os.path.join(build_root, 'ninja')]
-    for e in exe_paths:
-      for s in ['.exe', '']:
-        ninja = e + s
-        if os.path.isfile(ninja):
-          dst = os.path.join(bin_dir, 'ninja' + s)
-          shutil.copyfile(ninja, dst)
-          os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)
+    if success:
+        bin_dir = os.path.join(root, 'bin')
+        mkdir_p(bin_dir)
+        exe_paths = [os.path.join(build_root, 'Release', 'ninja'), os.path.join(build_root, 'ninja')]
+        for e in exe_paths:
+            for s in ['.exe', '']:
+                ninja = e + s
+                if os.path.isfile(ninja):
+                    dst = os.path.join(bin_dir, 'ninja' + s)
+                    shutil.copyfile(ninja, dst)
+                    os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)
 
-  return success
+    return success
 
 
 def build_ccache(tool):
-  debug_print(f'build_ccache({tool})')
-  root = os.path.normpath(tool.installation_path())
-  src_root = os.path.join(root, 'src')
-  success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
-  if not success:
-    return False
+    debug_print(f'build_ccache({tool})')
+    root = os.path.normpath(tool.installation_path())
+    src_root = os.path.join(root, 'src')
+    success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
+    if not success:
+        return False
 
-  build_dir = llvm_build_dir(tool)
-  build_root = os.path.join(root, build_dir)
+    build_dir = llvm_build_dir(tool)
+    build_root = os.path.join(root, build_dir)
 
-  build_type = decide_cmake_build_type(tool)
+    build_type = decide_cmake_build_type(tool)
 
-  # Configure
-  cmake_generator, args = get_generator_and_config_args(tool)
-  args += ['-DZSTD_FROM_INTERNET=ON']
+    # Configure
+    cmake_generator, args = get_generator_and_config_args(tool)
+    args += ['-DZSTD_FROM_INTERNET=ON']
 
-  cmakelists_dir = os.path.join(src_root)
+    cmakelists_dir = os.path.join(src_root)
 
-  success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)
+    success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)
 
-  if success:
-    bin_dir = os.path.join(root, 'bin')
-    mkdir_p(bin_dir)
-    exe_paths = [os.path.join(build_root, 'Release', 'ccache'), os.path.join(build_root, 'ccache')]
-    for e in exe_paths:
-      for s in ['.exe', '']:
-        ccache = e + s
-        if os.path.isfile(ccache):
-          dst = os.path.join(bin_dir, 'ccache' + s)
-          shutil.copyfile(ccache, dst)
-          os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)
+    if success:
+        bin_dir = os.path.join(root, 'bin')
+        mkdir_p(bin_dir)
+        exe_paths = [os.path.join(build_root, 'Release', 'ccache'), os.path.join(build_root, 'ccache')]
+        for e in exe_paths:
+            for s in ['.exe', '']:
+                ccache = e + s
+                if os.path.isfile(ccache):
+                    dst = os.path.join(bin_dir, 'ccache' + s)
+                    shutil.copyfile(ccache, dst)
+                    os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)
 
-    cache_dir = os.path.join(root, 'cache')
-    write_file(os.path.join(root, 'emcc_ccache.conf'), f'''\
-# Set maximum cache size to 10 GB:
-max_size = 10G
-cache_dir = {cache_dir}
-''')
-    mkdir_p(cache_dir)
+        cache_dir = os.path.join(root, 'cache')
+        write_file(os.path.join(root, 'emcc_ccache.conf'), f'''\
+    # Set maximum cache size to 10 GB:
+    max_size = 10G
+    cache_dir = {cache_dir}
+    ''')
+        mkdir_p(cache_dir)
 
-  return success
+    return success
 
 
 def download_firefox(tool):
-  debug_print(f'download_firefox({tool})')
+    debug_print(f'download_firefox({tool})')
 
-  # Use mozdownload to acquire Firefox versions.
-  try:
-    from mozdownload import FactoryScraper
-  except ImportError:
-    # If mozdownload is not available, invoke pip to install it.
-    subprocess.check_call([sys.executable, "-m", "pip", "install", "mozdownload"])
-    from mozdownload import FactoryScraper
+    # Use mozdownload to acquire Firefox versions.
+    try:
+        from mozdownload import FactoryScraper
+    except ImportError:
+        # If mozdownload is not available, invoke pip to install it.
+        subprocess.check_call([sys.executable, "-m", "pip", "install", "mozdownload"])
+        from mozdownload import FactoryScraper
 
-  if WINDOWS:
-    extension = 'exe'
-  elif MACOS:
-    extension = 'dmg'
-  else:
-    # N.b. on Linux even when we ask .tar.xz, we might sometimes get .tar.bz2,
-    # depending on what is available on Firefox servers for the particular
-    # version. So prepare to handle both further down below.
-    extension = 'tar.xz'
-
-  platform = None
-  if LINUX and 'arm' in ARCH:
-    platform = 'linux-arm64'
-  if WINDOWS and 'arm' in ARCH:
-    platform = 'win64-aarch64'
-
-  if tool.version == 'nightly':
-    scraper = FactoryScraper('daily', extension=extension, locale='en-US', platform=platform)
-  else:
-    scraper = FactoryScraper('release', extension=extension, locale='en-US', platform=platform, version=tool.version)
-
-  if tool.version == 'nightly':
-    firefox_version = os.path.basename(scraper.filename).split(".en-US")[0]
-  else:
-    firefox_version = os.path.basename(scraper.filename).split("firefox-")[1].split(".en-US")[0]
-
-  print('Target Firefox version: ' + firefox_version)
-  if tool.version in {'latest', 'latest-esr', 'latest-beta', 'nightly'}:
-    pretend_version_dir = os.path.normpath(tool.installation_path())
-    orig_version = tool.version
-    tool.version = firefox_version
-    root = os.path.normpath(tool.installation_path())
-    tool.version = orig_version
-  else:
-    pretend_version_dir = None
-    root = os.path.normpath(tool.installation_path())
-
-  def save_actual_version():
-    """For moving installer packages, e.g. "nightly", "latest", "latest-esr",
-    store a text file to specify the actual installation directory.
-    """
-    if os.path.isfile(firefox_exe) and pretend_version_dir:
-      print(pretend_version_dir)
-      os.makedirs(pretend_version_dir, exist_ok=True)
-      write_file(os.path.join(pretend_version_dir, 'actual.txt'), os.path.relpath(root, EMSDK_PATH))
-
-  # Check if already installed
-  print('Firefox installation root directory: ' + root)
-  exe_dir = os.path.join(root, 'Contents', 'MacOS') if MACOS else root
-  firefox_exe = os.path.join(exe_dir, exe_suffix('firefox'))
-  if os.path.isfile(firefox_exe):
-    print(f'{firefox_exe} is already installed, skipping..')
-    save_actual_version()
-    return True
-
-  print('Downloading Firefox from ' + scraper.url)
-  filename = scraper.download()
-  print('Finished downloading ' + filename)
-
-  if not MACOS:
-    os.makedirs(root, exist_ok=True)
-
-  if extension == 'exe':
-    # Uncompress the NSIS installer to 'install' Firefox
-    run(['C:\\Program Files\\7-Zip\\7z.exe', 'x', '-y', filename, '-o' + root])
-
-  if '.tar.' in filename:
-    if filename.endswith('.tar.bz2'):
-      tar_type = 'r:bz2'
-    elif filename.endswith('.tar.xz'):
-      tar_type = 'r:xz'
+    if WINDOWS:
+        extension = 'exe'
+    elif MACOS:
+        extension = 'dmg'
     else:
-      raise Exception('Unknown archive type')
+        # N.b. on Linux even when we ask .tar.xz, we might sometimes get .tar.bz2,
+        # depending on what is available on Firefox servers for the particular
+        # version. So prepare to handle both further down below.
+        extension = 'tar.xz'
 
-    with tarfile.open(filename, tar_type) as tar:
-      tar.extractall(path=root)
-    collapse_subdir = os.path.join(root, 'firefox')
+    platform = None
+    if LINUX and 'arm' in ARCH:
+        platform = 'linux-arm64'
+    if WINDOWS and 'arm' in ARCH:
+        platform = 'win64-aarch64'
 
-  elif filename.endswith('.dmg'):
-    mount_point = '/Volumes/Firefox Nightly' if tool.version == 'nightly' else '/Volumes/Firefox'
-    app_name = 'Firefox Nightly.app' if tool.version == 'nightly' else 'Firefox.app'
+    if tool.version == 'nightly':
+        scraper = FactoryScraper('daily', extension=extension, locale='en-US', platform=platform)
+    else:
+        scraper = FactoryScraper('release', extension=extension, locale='en-US', platform=platform, version=tool.version)
 
-    # If a previous mount point exists, detach it first
-    if os.path.exists(mount_point):
-      run(['hdiutil', 'detach', mount_point])
+    if tool.version == 'nightly':
+        firefox_version = os.path.basename(scraper.filename).split(".en-US")[0]
+    else:
+        firefox_version = os.path.basename(scraper.filename).split("firefox-")[1].split(".en-US")[0]
 
-    # Abort if detaching was not successful
-    if os.path.exists(mount_point):
-      raise Exception(f'Previous mount of Firefox already exists at "{mount_point}", unable to proceed.')
+    print('Target Firefox version: ' + firefox_version)
+    if tool.version in {'latest', 'latest-esr', 'latest-beta', 'nightly'}:
+        pretend_version_dir = os.path.normpath(tool.installation_path())
+        orig_version = tool.version
+        tool.version = firefox_version
+        root = os.path.normpath(tool.installation_path())
+        tool.version = orig_version
+    else:
+        pretend_version_dir = None
+        root = os.path.normpath(tool.installation_path())
 
-    # Mount the archive
-    run(['hdiutil', 'attach', filename])
-    firefox_dir = os.path.join(mount_point, app_name)
-    if not os.path.isdir(firefox_dir):
-      raise Exception(f'Unable to find Firefox directory "{firefox_dir}" inside app image.')
+    def save_actual_version():
+        """For moving installer packages, e.g. "nightly", "latest", "latest-esr",
+        store a text file to specify the actual installation directory.
+        """
+        if os.path.isfile(firefox_exe) and pretend_version_dir:
+            print(pretend_version_dir)
+            os.makedirs(pretend_version_dir, exist_ok=True)
+            write_file(os.path.join(pretend_version_dir, 'actual.txt'), os.path.relpath(root, EMSDK_PATH))
 
-    # And install by copying the files from the archive
-    shutil.copytree(firefox_dir, root)
-    run(['hdiutil', 'detach', mount_point])
-    collapse_subdir = None
+    # Check if already installed
+    print('Firefox installation root directory: ' + root)
+    exe_dir = os.path.join(root, 'Contents', 'MacOS') if MACOS else root
+    firefox_exe = os.path.join(exe_dir, exe_suffix('firefox'))
+    if os.path.isfile(firefox_exe):
+        print(f'{firefox_exe} is already installed, skipping..')
+        save_actual_version()
+        return True
 
-  elif filename.endswith('.exe'):
-    # NSIS installer package has a core/ directory, remove it as redundant.
-    collapse_subdir = os.path.join(root, 'core')
+    print('Downloading Firefox from ' + scraper.url)
+    filename = scraper.download()
+    print('Finished downloading ' + filename)
 
-  # Remove a redundant subdirectory by moving installed files up one directory.
-  if collapse_subdir and os.path.isdir(collapse_subdir):
-    # Rename the parent subdirectory first, since we will be handling a nested `firefox/firefox/`
-    collapse = collapse_subdir + '_temp_renamed'
-    os.rename(collapse_subdir, collapse)
+    if not MACOS:
+        os.makedirs(root, exist_ok=True)
 
-    # Move all files up by one directory
-    for f in os.listdir(collapse):
-      shutil.move(os.path.join(collapse, f), os.path.dirname(collapse))
+    if extension == 'exe':
+        # Uncompress the NSIS installer to 'install' Firefox
+        run(['C:\\Program Files\\7-Zip\\7z.exe', 'x', '-y', filename, '-o' + root])
 
-    # The root directory should now be empty
-    os.rmdir(collapse)
+    if '.tar.' in filename:
+        if filename.endswith('.tar.bz2'):
+            tar_type = 'r:bz2'
+        elif filename.endswith('.tar.xz'):
+            tar_type = 'r:xz'
+        else:
+            raise Exception('Unknown archive type')
 
-  # Original installer is now done.
-  os.remove(filename)
+        with tarfile.open(filename, tar_type) as tar:
+            tar.extractall(path=root)
+        collapse_subdir = os.path.join(root, 'firefox')
 
-  # Write a policy file that prevents Firefox from auto-updating itself.
-  if MACOS:
-    distribution_path = os.path.join(root, 'Contents', 'Resources', 'distribution')
-  else:
-    distribution_path = os.path.join(root, 'distribution')
-  os.makedirs(distribution_path, exist_ok=True)
-  write_file(os.path.join(distribution_path, 'policies.json'), '''\
-{
-  "policies": {
-    "AppAutoUpdate": false,
-    "DisableAppUpdate": true
-  }
-}''')
+    elif filename.endswith('.dmg'):
+        mount_point = '/Volumes/Firefox Nightly' if tool.version == 'nightly' else '/Volumes/Firefox'
+        app_name = 'Firefox Nightly.app' if tool.version == 'nightly' else 'Firefox.app'
 
-  if MACOS:
-    # Disable a macOS feature where if the browser is terminated mid-execution, (e.g. by
-    # CI aborting), then the next time the browser is launched, macOS might bring up a dialog
-    # "The last time you opened Firefox, it unexpectedly quit while reopening windows.
-    #  Do you want to try to reopen its windows again?"
-    # that will block automated CI runs.
-    # Disable this feature by changing the behavior of the program with macOS 'defaults'.
-    run(['defaults', 'write', '-app', root, 'ApplePersistenceIgnoreState', 'YES'])
-    run(['defaults', 'write', '-app', root, 'NSQuitAlwaysKeepsWindows', '-bool', 'false'])
+        # If a previous mount point exists, detach it first
+        if os.path.exists(mount_point):
+            run(['hdiutil', 'detach', mount_point])
 
-  save_actual_version()
+        # Abort if detaching was not successful
+        if os.path.exists(mount_point):
+            raise Exception(f'Previous mount of Firefox already exists at "{mount_point}", unable to proceed.')
 
-  # If we didn't get a Firefox executable, then installation failed.
-  return os.path.isfile(firefox_exe)
+        # Mount the archive
+        run(['hdiutil', 'attach', filename])
+        firefox_dir = os.path.join(mount_point, app_name)
+        if not os.path.isdir(firefox_dir):
+            raise Exception(f'Unable to find Firefox directory "{firefox_dir}" inside app image.')
+
+        # And install by copying the files from the archive
+        shutil.copytree(firefox_dir, root)
+        run(['hdiutil', 'detach', mount_point])
+        collapse_subdir = None
+
+    elif filename.endswith('.exe'):
+        # NSIS installer package has a core/ directory, remove it as redundant.
+        collapse_subdir = os.path.join(root, 'core')
+
+    # Remove a redundant subdirectory by moving installed files up one directory.
+    if collapse_subdir and os.path.isdir(collapse_subdir):
+        # Rename the parent subdirectory first, since we will be handling a nested `firefox/firefox/`
+        collapse = collapse_subdir + '_temp_renamed'
+        os.rename(collapse_subdir, collapse)
+
+        # Move all files up by one directory
+        for f in os.listdir(collapse):
+            shutil.move(os.path.join(collapse, f), os.path.dirname(collapse))
+
+        # The root directory should now be empty
+        os.rmdir(collapse)
+
+    # Original installer is now done.
+    os.remove(filename)
+
+    # Write a policy file that prevents Firefox from auto-updating itself.
+    if MACOS:
+        distribution_path = os.path.join(root, 'Contents', 'Resources', 'distribution')
+    else:
+        distribution_path = os.path.join(root, 'distribution')
+    os.makedirs(distribution_path, exist_ok=True)
+    write_file(os.path.join(distribution_path, 'policies.json'), '''\
+  {
+    "policies": {
+      "AppAutoUpdate": false,
+      "DisableAppUpdate": true
+    }
+  }''')
+
+    if MACOS:
+        # Disable a macOS feature where if the browser is terminated mid-execution, (e.g. by
+        # CI aborting), then the next time the browser is launched, macOS might bring up a dialog
+        # "The last time you opened Firefox, it unexpectedly quit while reopening windows.
+        #  Do you want to try to reopen its windows again?"
+        # that will block automated CI runs.
+        # Disable this feature by changing the behavior of the program with macOS 'defaults'.
+        run(['defaults', 'write', '-app', root, 'ApplePersistenceIgnoreState', 'YES'])
+        run(['defaults', 'write', '-app', root, 'NSQuitAlwaysKeepsWindows', '-bool', 'false'])
+
+    save_actual_version()
+
+    # If we didn't get a Firefox executable, then installation failed.
+    return os.path.isfile(firefox_exe)
 
 
 def is_firefox_installed(tool):
-  actual_file = os.path.join(tool.installation_dir(), 'actual.txt')
-  if not os.path.isfile(actual_file):
-    return False
+    actual_file = os.path.join(tool.installation_dir(), 'actual.txt')
+    if not os.path.isfile(actual_file):
+        return False
 
-  actual_installation_dir = sdk_path(read_file(actual_file))
-  exe_dir = os.path.join(actual_installation_dir, 'Contents', 'MacOS') if MACOS else actual_installation_dir
-  firefox_exe = os.path.join(exe_dir, exe_suffix('firefox'))
-  return os.path.isfile(firefox_exe)
+    actual_installation_dir = sdk_path(read_file(actual_file))
+    exe_dir = os.path.join(actual_installation_dir, 'Contents', 'MacOS') if MACOS else actual_installation_dir
+    firefox_exe = os.path.join(exe_dir, exe_suffix('firefox'))
+    return os.path.isfile(firefox_exe)
 
 
 def find_latest_installed_tool(name):
-  """Finds the newest installed version of a given tool"""
-  for t in reversed(tools):
-    if t.id == name and t.is_installed():
-      return t
+    """Finds the newest installed version of a given tool"""
+    for t in reversed(tools):
+        if t.id == name and t.is_installed():
+            return t
 
 
 def get_node_env():
-  node_tool = find_latest_installed_tool('node')
-  if node_tool:
-    node_path = node_tool.expand_vars(node_tool.activated_path)
-  else:
-    npm_fallback = shutil.which('npm')
-    if not npm_fallback:
-      errlog('Failed to find npm command')
-      errlog('npm is required for Emscripten setup. Please install node.js first')
-      return None, None
-    node_path = os.path.dirname(npm_fallback)
+    node_tool = find_latest_installed_tool('node')
+    if node_tool:
+        node_path = node_tool.expand_vars(node_tool.activated_path)
+    else:
+        npm_fallback = shutil.which('npm')
+        if not npm_fallback:
+            errlog('Failed to find npm command')
+            errlog('npm is required for Emscripten setup. Please install node.js first')
+            return None, None
+        node_path = os.path.dirname(npm_fallback)
 
-  env = os.environ.copy()
-  env["PATH"] = node_path + os.pathsep + env["PATH"]
-  return env, node_path
+    env = os.environ.copy()
+    env["PATH"] = node_path + os.pathsep + env["PATH"]
+    return env, node_path
 
 
 def emscripten_npm_setup(directory):
-  env, node_path = get_node_env()
-  if not env:
-    return False
-  npm = os.path.join(node_path, 'npm' + ('.cmd' if WINDOWS else ''))
-  print('Running post-install step: npm ci ...')
-  try:
-    subprocess.check_call([npm, 'ci', '--production'], cwd=directory, env=env)
-  except subprocess.CalledProcessError as e:
-    errlog(f'Error running {e.cmd}')
-    return False
+    env, node_path = get_node_env()
+    if not env:
+        return False
+    npm = os.path.join(node_path, 'npm' + ('.cmd' if WINDOWS else ''))
+    print('Running post-install step: npm ci ...')
+    try:
+        subprocess.check_call([npm, 'ci', '--production'], cwd=directory, env=env)
+    except subprocess.CalledProcessError as e:
+        errlog(f'Error running {e.cmd}')
+        return False
 
-  print('Done running: npm ci')
-  return True
+    print('Done running: npm ci')
+    return True
 
 
 def sdk_post_install():
-  """Older versions of the sdk did not include the node_modules directory
-  and require `npm ci` to be run post-install
-  """
-  emscripten_dir = os.path.join(EMSDK_PATH, 'upstream', 'emscripten')
-  if os.path.exists(os.path.join(emscripten_dir, 'node_modules')):
-    return True
+    """Older versions of the sdk did not include the node_modules directory
+    and require `npm ci` to be run post-install
+    """
+    emscripten_dir = os.path.join(EMSDK_PATH, 'upstream', 'emscripten')
+    if os.path.exists(os.path.join(emscripten_dir, 'node_modules')):
+        return True
 
-  return emscripten_npm_setup(emscripten_dir)
+    return emscripten_npm_setup(emscripten_dir)
 
 
 def emscripten_install(tool):
-  """Modern versions of emscripten require bootstrap.py to be run before they
-  can be used from a git checkout. On older versions we just run `npm ci`
-  """
-  directory = tool.installation_path()
-  if os.path.isfile(os.path.join(directory, 'bootstrap.py')):
-    env = get_node_env()[0]
-    if not env:
-      return False
-    try:
-      subprocess.check_call([sys.executable, os.path.join(directory, 'bootstrap.py')],
-                            cwd=directory, stdin=subprocess.DEVNULL, env=env, text=True)
-    except subprocess.CalledProcessError as e:
-      errlog(f'Error running {e!s}')
-      return False
+    """Modern versions of emscripten require bootstrap.py to be run before they
+    can be used from a git checkout. On older versions we just run `npm ci`
+    """
+    directory = tool.installation_path()
+    if os.path.isfile(os.path.join(directory, 'bootstrap.py')):
+        env = get_node_env()[0]
+        if not env:
+            return False
+        try:
+            subprocess.check_call([sys.executable, os.path.join(directory, 'bootstrap.py')],
+                                  cwd=directory, stdin=subprocess.DEVNULL, env=env, text=True)
+        except subprocess.CalledProcessError as e:
+            errlog(f'Error running {e!s}')
+            return False
 
-    print('Done running: Emscripten bootstrap')
-  else:
-    return emscripten_npm_setup(directory)
+        print('Done running: Emscripten bootstrap')
+    else:
+        return emscripten_npm_setup(directory)
 
-  return True
+    return True
 
 
 # Binaryen build scripts:
 def binaryen_build_root(tool):
-  build_root = tool.installation_path().strip()
-  if build_root.endswith(('/', '\\')):
-    build_root = build_root[:-1]
-  generator_prefix = cmake_generator_prefix()
-  build_root = f'{build_root}{generator_prefix}_{tool.bitness}bit_binaryen'
-  return build_root
+    build_root = tool.installation_path().strip()
+    if build_root.endswith(('/', '\\')):
+        build_root = build_root[:-1]
+    generator_prefix = cmake_generator_prefix()
+    build_root = f'{build_root}{generator_prefix}_{tool.bitness}bit_binaryen'
+    return build_root
 
 
 def uninstall_binaryen(tool):
-  debug_print(f'uninstall_binaryen({tool})')
-  build_root = binaryen_build_root(tool)
-  print(f"Deleting path '{build_root}'")
-  remove_tree(build_root)
+    debug_print(f'uninstall_binaryen({tool})')
+    build_root = binaryen_build_root(tool)
+    print(f"Deleting path '{build_root}'")
+    remove_tree(build_root)
 
 
 def is_binaryen_installed(tool):
-  build_root = binaryen_build_root(tool)
-  return os.path.exists(build_root)
+    build_root = binaryen_build_root(tool)
+    return os.path.exists(build_root)
 
 
 def build_binaryen_tool(tool):
-  debug_print(f'build_binaryen_tool({tool})')
-  src_root = tool.installation_path()
-  build_root = binaryen_build_root(tool)
-  build_type = decide_cmake_build_type(tool)
+    debug_print(f'build_binaryen_tool({tool})')
+    src_root = tool.installation_path()
+    build_root = binaryen_build_root(tool)
+    build_type = decide_cmake_build_type(tool)
 
-  # Configure
-  cmake_generator, args = get_generator_and_config_args(tool)
-  args += ['-DENABLE_WERROR=0']  # -Werror is not useful for end users
-  args += ['-DBUILD_TESTS=0']  # We don't want to build or run tests
+    # Configure
+    cmake_generator, args = get_generator_and_config_args(tool)
+    args += ['-DENABLE_WERROR=0']  # -Werror is not useful for end users
+    args += ['-DBUILD_TESTS=0']  # We don't want to build or run tests
 
-  if 'Visual Studio' in CMAKE_GENERATOR:
-    if BUILD_FOR_TESTING:
-      args += ['-DRUN_STATIC_ANALYZER=1']
+    if 'Visual Studio' in CMAKE_GENERATOR:
+        if BUILD_FOR_TESTING:
+            args += ['-DRUN_STATIC_ANALYZER=1']
 
-  success = cmake_configure_and_build(cmake_generator, build_root, src_root, build_type, args)
+    success = cmake_configure_and_build(cmake_generator, build_root, src_root, build_type, args)
 
-  if success:
-    # Deploy scripts needed from source repository to build directory
-    remove_tree(os.path.join(build_root, 'scripts'))
-    shutil.copytree(os.path.join(src_root, 'scripts'), os.path.join(build_root, 'scripts'))
-    remove_tree(os.path.join(build_root, 'src', 'js'))
-    shutil.copytree(os.path.join(src_root, 'src', 'js'), os.path.join(build_root, 'src', 'js'))
+    if success:
+        # Deploy scripts needed from source repository to build directory
+        remove_tree(os.path.join(build_root, 'scripts'))
+        shutil.copytree(os.path.join(src_root, 'scripts'), os.path.join(build_root, 'scripts'))
+        remove_tree(os.path.join(build_root, 'src', 'js'))
+        shutil.copytree(os.path.join(src_root, 'src', 'js'), os.path.join(build_root, 'src', 'js'))
 
-  return success
+    return success
 
 
 def download_and_extract(archive, dest_dir, filename_prefix='', clobber=True):
-  debug_print(f'download_and_extract(archive={archive}, dest_dir={dest_dir})')
+    debug_print(f'download_and_extract(archive={archive}, dest_dir={dest_dir})')
 
-  url = urljoin(emsdk_packages_url, archive)
+    url = urljoin(emsdk_packages_url, archive)
 
-  def try_download(url):
-    return download_file(url, download_dir, filename_prefix)
+    def try_download(url):
+        return download_file(url, download_dir, filename_prefix)
 
-  # Special hack for the wasm-binaries we transitioned from `.bzip2` to
-  # `.xz`, but we can't tell from the version/url which one to use, so
-  # try one and then fall back to the other.
-  success = False
-  if 'wasm-binaries' in archive and os.path.splitext(archive)[1] == '.xz':
-    success = try_download(url)
+    # Special hack for the wasm-binaries we transitioned from `.bzip2` to
+    # `.xz`, but we can't tell from the version/url which one to use, so
+    # try one and then fall back to the other.
+    success = False
+    if 'wasm-binaries' in archive and os.path.splitext(archive)[1] == '.xz':
+        success = try_download(url)
+        if not success:
+            alt_url = url.replace('.tar.xz', '.tbz2')
+            success = try_download(alt_url)
+            if success:
+                url = alt_url
+
     if not success:
-      alt_url = url.replace('.tar.xz', '.tbz2')
-      success = try_download(alt_url)
-      if success:
-        url = alt_url
+        success = try_download(url)
 
-  if not success:
-    success = try_download(url)
+    if not success:
+        return False
 
-  if not success:
-    return False
+    # Remove the old directory, since we have some SDKs that install into the
+    # same directory.  If we didn't do this contents of the previous install
+    # could remain.
+    if clobber:
+        remove_tree(dest_dir)
 
-  # Remove the old directory, since we have some SDKs that install into the
-  # same directory.  If we didn't do this contents of the previous install
-  # could remain.
-  if clobber:
-    remove_tree(dest_dir)
-
-  download_target = get_download_target(url, download_dir, filename_prefix)
-  if archive.endswith('.zip'):
-    return unzip(download_target, dest_dir)
-  else:
-    return untargz(download_target, dest_dir)
+    download_target = get_download_target(url, download_dir, filename_prefix)
+    if archive.endswith('.zip'):
+        return unzip(download_target, dest_dir)
+    else:
+        return untargz(download_target, dest_dir)
 
 
 def to_native_path(p):
-  if (WINDOWS and not MSYS) and not os_override:
-    return to_unix_path(p).replace('/', '\\')
-  else:
-    return to_unix_path(p)
+    if (WINDOWS and not MSYS) and not os_override:
+        return to_unix_path(p).replace('/', '\\')
+    else:
+        return to_unix_path(p)
 
 
 def get_required_path(active_tools):
-  """Finds and returns a list of the directories that need to be added to PATH for
-  the given set of tools.
-  """
-  path_add = [to_native_path(EMSDK_PATH)]
-  for tool in active_tools:
-    if tool.activated_path:
-      path = to_native_path(tool.expand_vars(tool.activated_path))
-      # If the tool has an activated_path_skip attribute then we don't add
-      # the tools path to the users path if a program by that name is found
-      # in the existing PATH.  This allows us to, for example, add our version
-      # node to the users PATH if, and only if, they don't already have a
-      # another version of node in their PATH.
-      if tool.activated_path_skip:
-        current_path = shutil.which(tool.activated_path_skip)
-        # We found an executable by this name in the current PATH, but we
-        # ignore our own version for this purpose.
-        if current_path and os.path.dirname(current_path) != path:
-          continue
-      path_add.append(path)
-  return path_add
+    """Finds and returns a list of the directories that need to be added to PATH for
+    the given set of tools.
+    """
+    path_add = [to_native_path(EMSDK_PATH)]
+    for tool in active_tools:
+        if tool.activated_path:
+            path = to_native_path(tool.expand_vars(tool.activated_path))
+            # If the tool has an activated_path_skip attribute then we don't add
+            # the tools path to the users path if a program by that name is found
+            # in the existing PATH.  This allows us to, for example, add our version
+            # node to the users PATH if, and only if, they don't already have a
+            # another version of node in their PATH.
+            if tool.activated_path_skip:
+                current_path = shutil.which(tool.activated_path_skip)
+                # We found an executable by this name in the current PATH, but we
+                # ignore our own version for this purpose.
+                if current_path and os.path.dirname(current_path) != path:
+                    continue
+            path_add.append(path)
+    return path_add
 
 
 # Returns the absolute path to the file '.emscripten' for the current user on
@@ -1611,603 +1611,603 @@
 
 
 def parse_key_value(line):
-  if not line:
-    return ('', '')
-  eq = line.find('=')
-  if eq != -1:
-    key = line[0:eq].strip()
-    value = line[eq + 1:].strip()
-    return (key, value)
-  else:
-    return (key, '')
+    if not line:
+        return ('', '')
+    eq = line.find('=')
+    if eq != -1:
+        key = line[0:eq].strip()
+        value = line[eq + 1:].strip()
+        return (key, value)
+    else:
+        return (key, '')
 
 
 def load_em_config():
-  EM_CONFIG_DICT.clear()
-  lines = []
-  try:
-    lines = read_file(EM_CONFIG_PATH).splitlines()
-  except Exception:
-    pass
-  for line in lines:
+    EM_CONFIG_DICT.clear()
+    lines = []
     try:
-      key, value = parse_key_value(line)
-      if value:
-        EM_CONFIG_DICT[key] = value
+        lines = read_file(EM_CONFIG_PATH).splitlines()
     except Exception:
-      pass
+        pass
+    for line in lines:
+        try:
+            key, value = parse_key_value(line)
+            if value:
+                EM_CONFIG_DICT[key] = value
+        except Exception:
+            pass
 
 
 def find_emscripten_root(active_tools):
-  """Find the currently active emscripten root.
+    """Find the currently active emscripten root.
 
-  If there is more than one tool that defines EMSCRIPTEN_ROOT (this
-  should not happen under normal circumstances), assume the last one takes
-  precedence.
-  """
-  root = None
-  for tool in active_tools:
-    config = tool.activated_config()
-    if 'EMSCRIPTEN_ROOT' in config:
-      root = config['EMSCRIPTEN_ROOT']
-  return root
+    If there is more than one tool that defines EMSCRIPTEN_ROOT (this
+    should not happen under normal circumstances), assume the last one takes
+    precedence.
+    """
+    root = None
+    for tool in active_tools:
+        config = tool.activated_config()
+        if 'EMSCRIPTEN_ROOT' in config:
+            root = config['EMSCRIPTEN_ROOT']
+    return root
 
 
 def fetch_nightly_node_versions():
-  url = "https://nodejs.org/download/nightly/"
-  with urlopen(url) as response:
-    html = response.read().decode("utf-8")
+    url = "https://nodejs.org/download/nightly/"
+    with urlopen(url) as response:
+        html = response.read().decode("utf-8")
 
-  # Regex to capture href values like v7.0.0-nightly2016080175c6d9dd95/
-  pattern = re.compile(r'<a href="(v[0-9]+\.[0-9]+\.[0-9]+-nightly[0-9a-f]+)/">')
-  matches = pattern.findall(html)
-  return matches
+    # Regex to capture href values like v7.0.0-nightly2016080175c6d9dd95/
+    pattern = re.compile(r'<a href="(v[0-9]+\.[0-9]+\.[0-9]+-nightly[0-9a-f]+)/">')
+    matches = pattern.findall(html)
+    return matches
 
 
 def dir_installed_nightly_node_versions():
-  path = os.path.abspath('node')
-  try:
-    return [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name)) and name.startswith("nightly-")]
-  except Exception:
-    return []
+    path = os.path.abspath('node')
+    try:
+        return [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name)) and name.startswith("nightly-")]
+    except Exception:
+        return []
 
 
 def extract_newest_node_nightly_version(versions):
-  def parse(v):
-    # example: v7.0.0-nightly2016080175c6d9dd95
-    m = re.search(r'v(\d+)\.(\d+)\.(\d+)-nightly(\d{8})', v)
-    if m:
-      major, minor, patch, nightly = m.groups()
-      return [int(major), int(minor), int(patch), int(nightly)]
-    else:
-      return []
+    def parse(v):
+        # example: v7.0.0-nightly2016080175c6d9dd95
+        m = re.search(r'v(\d+)\.(\d+)\.(\d+)-nightly(\d{8})', v)
+        if m:
+            major, minor, patch, nightly = m.groups()
+            return [int(major), int(minor), int(patch), int(nightly)]
+        else:
+            return []
 
-  try:
-    return max(versions, key=parse)
-  except Exception:
-    return None
+    try:
+        return max(versions, key=parse)
+    except Exception:
+        return None
 
 
 def download_node_nightly(tool):
-  nightly_versions = fetch_nightly_node_versions()
-  latest_nightly = extract_newest_node_nightly_version(nightly_versions)
-  print(f'Latest Node.js Nightly download available is "{latest_nightly}"')
+    nightly_versions = fetch_nightly_node_versions()
+    latest_nightly = extract_newest_node_nightly_version(nightly_versions)
+    print(f'Latest Node.js Nightly download available is "{latest_nightly}"')
 
-  output_dir = os.path.abspath('node/nightly-' + latest_nightly)
-  # Node.js zip structure quirk: Linux and macOS archives have a /bin,
-  # Windows does not. Unify the file structures.
-  if WINDOWS:
-    output_dir += '/bin'
+    output_dir = os.path.abspath('node/nightly-' + latest_nightly)
+    # Node.js zip structure quirk: Linux and macOS archives have a /bin,
+    # Windows does not. Unify the file structures.
+    if WINDOWS:
+        output_dir += '/bin'
 
-  if os.path.isdir(output_dir):
+    if os.path.isdir(output_dir):
+        return True
+
+    url = tool.url.replace('%version%', latest_nightly)
+    if WINDOWS:
+        os_ = 'win'
+    elif LINUX:
+        os_ = 'linux'
+    elif MACOS:
+        os_ = 'darwin'
+    else:
+        os_ = ''
+    if platform.machine().lower() in {'x86_64', 'amd64'}:
+        arch = 'x64'
+    elif platform.machine().lower() in {'arm64', 'aarch64'}:
+        arch = 'arm64'
+    if WINDOWS:
+        zip_suffix = 'zip'
+    else:
+        zip_suffix = 'tar.gz'
+    url = url.replace('%os%', os_)
+    url = url.replace('%arch%', arch)
+    url = url.replace('%zip_suffix%', zip_suffix)
+    download_and_extract(url, output_dir)
+    write_file(tool.get_version_file_path(), 'node-nightly-64bit')
     return True
 
-  url = tool.url.replace('%version%', latest_nightly)
-  if WINDOWS:
-    os_ = 'win'
-  elif LINUX:
-    os_ = 'linux'
-  elif MACOS:
-    os_ = 'darwin'
-  else:
-    os_ = ''
-  if platform.machine().lower() in {'x86_64', 'amd64'}:
-    arch = 'x64'
-  elif platform.machine().lower() in {'arm64', 'aarch64'}:
-    arch = 'arm64'
-  if WINDOWS:
-    zip_suffix = 'zip'
-  else:
-    zip_suffix = 'tar.gz'
-  url = url.replace('%os%', os_)
-  url = url.replace('%arch%', arch)
-  url = url.replace('%zip_suffix%', zip_suffix)
-  download_and_extract(url, output_dir)
-  write_file(tool.get_version_file_path(), 'node-nightly-64bit')
-  return True
-
 
 def get_emsdk_shell_env_configs():
-  """returns a tuple (string,string) of config files paths that need to used
-  to activate emsdk env depending on $SHELL, defaults to bash.
-  """
-  default_emsdk_env = sdk_path('emsdk_env.sh')
-  default_shell_config_file = '$HOME/.bash_profile'
-  shell = os.getenv('SHELL', '')
-  if 'zsh' in shell:
-    return (default_emsdk_env, '$HOME/.zprofile')
-  elif 'csh' in shell:
-    return (sdk_path('emsdk_env.csh'), '$HOME/.cshrc')
-  elif 'fish' in shell:
-    return (sdk_path('emsdk_env.fish'), '$HOME/.config/fish/config.fish')
-  else:
-    return (default_emsdk_env, default_shell_config_file)
+    """returns a tuple (string,string) of config files paths that need to used
+    to activate emsdk env depending on $SHELL, defaults to bash.
+    """
+    default_emsdk_env = sdk_path('emsdk_env.sh')
+    default_shell_config_file = '$HOME/.bash_profile'
+    shell = os.getenv('SHELL', '')
+    if 'zsh' in shell:
+        return (default_emsdk_env, '$HOME/.zprofile')
+    elif 'csh' in shell:
+        return (sdk_path('emsdk_env.csh'), '$HOME/.cshrc')
+    elif 'fish' in shell:
+        return (sdk_path('emsdk_env.fish'), '$HOME/.config/fish/config.fish')
+    else:
+        return (default_emsdk_env, default_shell_config_file)
 
 
 def generate_em_config(active_tools, permanently_activate, system):
-  emroot = find_emscripten_root(active_tools)
-  version = None
-  if emroot and os.path.exists(os.path.join(emroot, 'emscripten-version.txt')):
-    version = parse_emscripten_version(emroot)
+    emroot = find_emscripten_root(active_tools)
+    version = None
+    if emroot and os.path.exists(os.path.join(emroot, 'emscripten-version.txt')):
+        version = parse_emscripten_version(emroot)
 
-  supports_cfgdir = version and version >= [6, 0, 4]
+    supports_cfgdir = version and version >= [6, 0, 4]
 
-  cfg = ''
-  if not supports_cfgdir:
-    cfg += 'import os\n'
-    cfg += "emsdk_path = os.path.dirname(os.getenv('EM_CONFIG')).replace('\\\\', '/')\n"
+    cfg = ''
+    if not supports_cfgdir:
+        cfg += 'import os\n'
+        cfg += "emsdk_path = os.path.dirname(os.getenv('EM_CONFIG')).replace('\\\\', '/')\n"
 
-  # Different tools may provide the same activated configs; the latest to be
-  # activated is the relevant one.
-  activated_config = {}
-  for tool in active_tools:
-    activated_config.update(tool.activated_config())
+    # Different tools may provide the same activated configs; the latest to be
+    # activated is the relevant one.
+    activated_config = {}
+    for tool in active_tools:
+        activated_config.update(tool.activated_config())
 
-  if 'NODE_JS' not in activated_config:
-    node_fallback = shutil.which('nodejs')
-    if not node_fallback:
-      node_fallback = 'node'
-    activated_config['NODE_JS'] = node_fallback
+    if 'NODE_JS' not in activated_config:
+        node_fallback = shutil.which('nodejs')
+        if not node_fallback:
+            node_fallback = 'node'
+        activated_config['NODE_JS'] = node_fallback
 
-  for name, value in activated_config.items():
-    if value.startswith('['):
-      cfg += f'{name} = {value}\n'
+    for name, value in activated_config.items():
+        if value.startswith('['):
+            cfg += f'{name} = {value}\n'
+        else:
+            cfg += f"{name} = '{value}'\n"
+
+    if version:
+        # Older emscripten versions of emscripten depend on certain config
+        # keys that are no longer used.
+        # See https://github.com/emscripten-core/emscripten/pull/9469
+        if version < [1, 38, 46]:
+            cfg += 'COMPILER_ENGINE = NODE_JS\n'
+        # See https://github.com/emscripten-core/emscripten/pull/9542
+        if version < [1, 38, 48]:
+            cfg += 'JS_ENGINES = [NODE_JS]\n'
+
+    if supports_cfgdir:
+        cfg = cfg.replace(EMSDK_PATH, '$CFGDIR')
     else:
-      cfg += f"{name} = '{value}'\n"
+        cfg = cfg.replace("'" + EMSDK_PATH, "emsdk_path + '")
 
-  if version:
-    # Older emscripten versions of emscripten depend on certain config
-    # keys that are no longer used.
-    # See https://github.com/emscripten-core/emscripten/pull/9469
-    if version < [1, 38, 46]:
-      cfg += 'COMPILER_ENGINE = NODE_JS\n'
-    # See https://github.com/emscripten-core/emscripten/pull/9542
-    if version < [1, 38, 48]:
-      cfg += 'JS_ENGINES = [NODE_JS]\n'
+    if os.path.exists(EM_CONFIG_PATH):
+        backup_path = EM_CONFIG_PATH + ".old"
+        move_with_overwrite(EM_CONFIG_PATH, backup_path)
 
-  if supports_cfgdir:
-    cfg = cfg.replace(EMSDK_PATH, '$CFGDIR')
-  else:
-    cfg = cfg.replace("'" + EMSDK_PATH, "emsdk_path + '")
+    write_file(EM_CONFIG_PATH, cfg)
 
-  if os.path.exists(EM_CONFIG_PATH):
-    backup_path = EM_CONFIG_PATH + ".old"
-    move_with_overwrite(EM_CONFIG_PATH, backup_path)
+    # Clear old emscripten content.
+    rmfile(os.path.join(EMSDK_PATH, ".emscripten_sanity"))
 
-  write_file(EM_CONFIG_PATH, cfg)
+    path_add = get_required_path(active_tools)
 
-  # Clear old emscripten content.
-  rmfile(os.path.join(EMSDK_PATH, ".emscripten_sanity"))
-
-  path_add = get_required_path(active_tools)
-
-  # Give some recommended next step, depending on the platform
-  if WINDOWS:
-    if not permanently_activate and not system:
-      print('Next steps:')
-      print('- Consider running `emsdk activate` with --permanent or --system')
-      print('  to have emsdk settings available on startup.')
-  else:
-    print('Next steps:')
-    print('- To conveniently access emsdk tools from the command line,')
-    print('  consider adding the following directories to your PATH:')
-    for p in path_add:
-      print('    ' + p)
-    print('- This can be done for the current shell by running:')
-    emsdk_env, shell_config_file = get_emsdk_shell_env_configs()
-    print(f'    source "{emsdk_env}"')
-    print('- Configure emsdk in your shell startup scripts by running:')
-    print(f'    echo \'source "{emsdk_env}"\' >> {shell_config_file}')
+    # Give some recommended next step, depending on the platform
+    if WINDOWS:
+        if not permanently_activate and not system:
+            print('Next steps:')
+            print('- Consider running `emsdk activate` with --permanent or --system')
+            print('  to have emsdk settings available on startup.')
+    else:
+        print('Next steps:')
+        print('- To conveniently access emsdk tools from the command line,')
+        print('  consider adding the following directories to your PATH:')
+        for p in path_add:
+            print('    ' + p)
+        print('- This can be done for the current shell by running:')
+        emsdk_env, shell_config_file = get_emsdk_shell_env_configs()
+        print(f'    source "{emsdk_env}"')
+        print('- Configure emsdk in your shell startup scripts by running:')
+        print(f'    echo \'source "{emsdk_env}"\' >> {shell_config_file}')
 
 
 class Tool:
-  os = None
-  bitness = None
-  append_bitness = True
-  is_old = False
-  version = None
-  activated_path = None
-  cmake_build_type = None
-  install_path = None
-  activated_path_skip = False
-  activated_cfg = None
-  activated_env = None
-  arch = None
-  custom_is_installed_script = None
-  custom_install_script = None
-  custom_uninstall_script = None
-  emscripten_releases_hash = None
-  git_branch = None
-  url = None
+    os = None
+    bitness = None
+    append_bitness = True
+    is_old = False
+    version = None
+    activated_path = None
+    cmake_build_type = None
+    install_path = None
+    activated_path_skip = False
+    activated_cfg = None
+    activated_env = None
+    arch = None
+    custom_is_installed_script = None
+    custom_install_script = None
+    custom_uninstall_script = None
+    emscripten_releases_hash = None
+    git_branch = None
+    url = None
 
-  def __init__(self, data):
-    self.deps = []
+    def __init__(self, data):
+        self.deps = []
 
-    # Convert the dictionary representation of the tool in 'data' to members of
-    # this class. Base attributes are assigned first, then host OS-matching suffixed
-    # attributes (e.g. url_windows, activated_path_windows) are applied on top as overrides.
-    # Foreign OS keys are ignored.
-    os_overrides = {}
-    all_os_names = {'windows', 'macos', 'linux'}
+        # Convert the dictionary representation of the tool in 'data' to members of
+        # this class. Base attributes are assigned first, then host OS-matching suffixed
+        # attributes (e.g. url_windows, activated_path_windows) are applied on top as overrides.
+        # Foreign OS keys are ignored.
+        os_overrides = {}
+        all_os_names = {'windows', 'macos', 'linux'}
 
-    for key, value in data.items():
-      if '_' in key:
-        prefix, suffix = key.rsplit('_', 1)
-        if suffix in all_os_names:
-          if suffix == os_name():
-            os_overrides[prefix] = value
-          continue
-      setattr(self, key, value)
+        for key, value in data.items():
+            if '_' in key:
+                prefix, suffix = key.rsplit('_', 1)
+                if suffix in all_os_names:
+                    if suffix == os_name():
+                        os_overrides[prefix] = value
+                    continue
+            setattr(self, key, value)
 
-    for prefix, value in os_overrides.items():
-      setattr(self, prefix, value)
+        for prefix, value in os_overrides.items():
+            setattr(self, prefix, value)
 
-    # Cache the name ID of this Tool (these are read very often)
-    self.name = self.id
-    if self.version:
-      self.name += f'-{self.version}'
-    if self.bitness:
-      self.name += f'-{self.bitness}bit'
+        # Cache the name ID of this Tool (these are read very often)
+        self.name = self.id
+        if self.version:
+            self.name += f'-{self.version}'
+        if self.bitness:
+            self.name += f'-{self.bitness}bit'
 
-  def __str__(self):
-    return self.name
+    def __str__(self):
+        return self.name
 
-  def expand_vars(self, str):
-    if '%installation_dir%' in str:
-      str = str.replace('%installation_dir%', sdk_path(self.installation_dir()))
-    if '%macos_app_bundle_prefix%' in str:
-      str = str.replace('%macos_app_bundle_prefix%', 'Contents/MacOS/' if MACOS else '')
-    if '%actual_installation_dir%' in str:
-      actual_file = os.path.join(self.installation_dir(), 'actual.txt')
-      if os.path.isfile(actual_file):
-        str = str.replace('%actual_installation_dir%', sdk_path(read_file(actual_file)))
-      else:
-        str = str.replace('%actual_installation_dir%', '__NOT_INSTALLED__')
-    if '%generator_prefix%' in str:
-      str = str.replace('%generator_prefix%', cmake_generator_prefix())
-    str = str.replace('%.exe%', '.exe' if WINDOWS else '')
-    if '%llvm_build_bin_dir%' in str:
-      str = str.replace('%llvm_build_bin_dir%', llvm_build_bin_dir(self))
-    if '%latest_downloaded_node_nightly_dir%' in str:
-      installed_node_nightlys = dir_installed_nightly_node_versions()
-      latest_node_nightly = extract_newest_node_nightly_version(installed_node_nightlys)
-      if latest_node_nightly:
-        str = str.replace('%latest_downloaded_node_nightly_dir%', latest_node_nightly)
+    def expand_vars(self, str):
+        if '%installation_dir%' in str:
+            str = str.replace('%installation_dir%', sdk_path(self.installation_dir()))
+        if '%macos_app_bundle_prefix%' in str:
+            str = str.replace('%macos_app_bundle_prefix%', 'Contents/MacOS/' if MACOS else '')
+        if '%actual_installation_dir%' in str:
+            actual_file = os.path.join(self.installation_dir(), 'actual.txt')
+            if os.path.isfile(actual_file):
+                str = str.replace('%actual_installation_dir%', sdk_path(read_file(actual_file)))
+            else:
+                str = str.replace('%actual_installation_dir%', '__NOT_INSTALLED__')
+        if '%generator_prefix%' in str:
+            str = str.replace('%generator_prefix%', cmake_generator_prefix())
+        str = str.replace('%.exe%', '.exe' if WINDOWS else '')
+        if '%llvm_build_bin_dir%' in str:
+            str = str.replace('%llvm_build_bin_dir%', llvm_build_bin_dir(self))
+        if '%latest_downloaded_node_nightly_dir%' in str:
+            installed_node_nightlys = dir_installed_nightly_node_versions()
+            latest_node_nightly = extract_newest_node_nightly_version(installed_node_nightlys)
+            if latest_node_nightly:
+                str = str.replace('%latest_downloaded_node_nightly_dir%', latest_node_nightly)
 
-    return str
+        return str
 
-  def needs_compilation(self):
-    """Return true if this tool requires building from source, and false if this is a precompiled tool."""
-    if self.cmake_build_type:
-      return True
+    def needs_compilation(self):
+        """Return true if this tool requires building from source, and false if this is a precompiled tool."""
+        if self.cmake_build_type:
+            return True
 
-    return any(dep.needs_compilation() for dep in self.dependencies())
+        return any(dep.needs_compilation() for dep in self.dependencies())
 
-  def installation_path(self):
-    """Specifies the target path where this tool will be installed to. This could
-    either be a directory or a filename (e.g. in case of node.js)
-    """
-    if self.install_path:
-      pth = self.expand_vars(self.install_path)
-      return sdk_path(pth)
-    p = self.version
-    if self.bitness and self.append_bitness:
-      p += f'_{self.bitness}bit'
-    return sdk_path(os.path.join(self.id, p))
+    def installation_path(self):
+        """Specifies the target path where this tool will be installed to. This could
+        either be a directory or a filename (e.g. in case of node.js)
+        """
+        if self.install_path:
+            pth = self.expand_vars(self.install_path)
+            return sdk_path(pth)
+        p = self.version
+        if self.bitness and self.append_bitness:
+            p += f'_{self.bitness}bit'
+        return sdk_path(os.path.join(self.id, p))
 
-  def installation_dir(self):
-    """Specifies the target directory this tool will be installed to."""
-    dir = self.installation_path()
-    if path_points_to_directory(dir):
-      return dir
-    else:
-      return os.path.dirname(dir)
+    def installation_dir(self):
+        """Specifies the target directory this tool will be installed to."""
+        dir = self.installation_path()
+        if path_points_to_directory(dir):
+            return dir
+        else:
+            return os.path.dirname(dir)
 
-  def activated_config(self):
-    """Returns the configuration item that needs to be added to .emscripten to make
-    this Tool active for the current user.
-    """
-    if not self.activated_cfg:
-      return {}
+    def activated_config(self):
+        """Returns the configuration item that needs to be added to .emscripten to make
+        this Tool active for the current user.
+        """
+        if not self.activated_cfg:
+            return {}
 
-    config = {}
-    expanded = to_unix_path(self.expand_vars(self.activated_cfg))
-    for specific_cfg in expanded.split(';'):
-      name, value = specific_cfg.split('=')
-      config[name] = value.strip("'")
-    return config
+        config = {}
+        expanded = to_unix_path(self.expand_vars(self.activated_cfg))
+        for specific_cfg in expanded.split(';'):
+            name, value = specific_cfg.split('=')
+            config[name] = value.strip("'")
+        return config
 
-  def activated_environment(self):
-    if not self.activated_env:
-      return []
+    def activated_environment(self):
+        if not self.activated_env:
+            return []
 
-    return self.expand_vars(self.activated_env).split(';')
+        return self.expand_vars(self.activated_env).split(';')
 
-  def compatible_with_this_arch(self):
-    return self.arch == ARCH or not self.arch
+    def compatible_with_this_arch(self):
+        return self.arch == ARCH or not self.arch
 
-  def compatible_with_this_os(self):
-    if not self.compatible_with_this_arch():
-      return False
+    def compatible_with_this_os(self):
+        if not self.compatible_with_this_arch():
+            return False
 
-    if self.os:
-      assert self.os in {'linux', 'windows', 'macos'}
-      return self.os == os_name()
+        if self.os:
+            assert self.os in {'linux', 'windows', 'macos'}
+            return self.os == os_name()
 
-    # Tools without an explicit 'os' are compatible with the current
-    # OS if they have URL for the current OS *or* a set of dependencies
-    # for the current OS.
-    return self.url is not None or bool(self.deps)
+        # Tools without an explicit 'os' are compatible with the current
+        # OS if they have URL for the current OS *or* a set of dependencies
+        # for the current OS.
+        return self.url is not None or bool(self.deps)
 
-  def get_version_file_path(self):
-    """the "version file" is a file inside install dirs that indicates the
-    version installed there. this helps disambiguate when there is more than
-    one version that may be installed to the same directory (which is used
-    to avoid accumulating builds over time in some cases, with new builds
-    overwriting the old)
-    """
-    return os.path.join(self.installation_path(), '.emsdk_version')
+    def get_version_file_path(self):
+        """the "version file" is a file inside install dirs that indicates the
+        version installed there. this helps disambiguate when there is more than
+        one version that may be installed to the same directory (which is used
+        to avoid accumulating builds over time in some cases, with new builds
+        overwriting the old)
+        """
+        return os.path.join(self.installation_path(), '.emsdk_version')
 
-  def is_installed_version(self):
-    version_file_path = self.get_version_file_path()
-    if os.path.isfile(version_file_path):
-      return read_file(version_file_path).strip() == self.name
-    return False
-
-  def update_installed_version(self):
-    write_file(self.get_version_file_path(), self.name + '\n')
-
-  def is_installed(self, skip_version_check=False):
-    # If this tool/sdk depends on other tools, require that all dependencies are
-    # installed for this tool to count as being installed.
-    for dep in self.dependencies():
-      if not dep.is_installed():
+    def is_installed_version(self):
+        version_file_path = self.get_version_file_path()
+        if os.path.isfile(version_file_path):
+            return read_file(version_file_path).strip() == self.name
         return False
 
-    if self.url is None:
-      debug_print(f'{self} has no files to download, so is installed by default.')
-      return True
+    def update_installed_version(self):
+        write_file(self.get_version_file_path(), self.name + '\n')
 
-    content_exists = is_nonempty_directory(self.installation_path())
-    debug_print(f'{self} installation path is {self.installation_path()}, exists: {content_exists}.')
+    def is_installed(self, skip_version_check=False):
+        # If this tool/sdk depends on other tools, require that all dependencies are
+        # installed for this tool to count as being installed.
+        for dep in self.dependencies():
+            if not dep.is_installed():
+                return False
 
-    # For e.g. fastcomp clang from git repo, the activated PATH is the
-    # directory where the compiler is built to, and installation_path is
-    # the directory where the source tree exists. To distinguish between
-    # multiple packages sharing the same source (clang-main-32bit,
-    # clang-main-64bit, clang-main-32bit and clang-main-64bit each
-    # share the same git repo), require that in addition to the installation
-    # directory, each item in the activated PATH must exist.
-    if self.activated_path and not os.path.exists(self.expand_vars(self.activated_path)):
-      content_exists = False
+        if self.url is None:
+            debug_print(f'{self} has no files to download, so is installed by default.')
+            return True
 
-    if self.custom_is_installed_script:
-      if self.custom_is_installed_script == 'is_binaryen_installed':
-        return is_binaryen_installed(self)
-      elif self.custom_is_installed_script == 'is_firefox_installed':
-        return is_firefox_installed(self)
-      else:
-        raise Exception(f'Unknown custom_is_installed_script: "{self.custom_is_installed_script}"')
+        content_exists = is_nonempty_directory(self.installation_path())
+        debug_print(f'{self} installation path is {self.installation_path()}, exists: {content_exists}.')
 
-    return content_exists and (skip_version_check or self.is_installed_version())
+        # For e.g. fastcomp clang from git repo, the activated PATH is the
+        # directory where the compiler is built to, and installation_path is
+        # the directory where the source tree exists. To distinguish between
+        # multiple packages sharing the same source (clang-main-32bit,
+        # clang-main-64bit, clang-main-32bit and clang-main-64bit each
+        # share the same git repo), require that in addition to the installation
+        # directory, each item in the activated PATH must exist.
+        if self.activated_path and not os.path.exists(self.expand_vars(self.activated_path)):
+            content_exists = False
 
-  def is_active(self):
-    if not self.is_installed():
-      return False
+        if self.custom_is_installed_script:
+            if self.custom_is_installed_script == 'is_binaryen_installed':
+                return is_binaryen_installed(self)
+            elif self.custom_is_installed_script == 'is_firefox_installed':
+                return is_firefox_installed(self)
+            else:
+                raise Exception(f'Unknown custom_is_installed_script: "{self.custom_is_installed_script}"')
 
-    # All dependencies of this tool must be active as well.
-    deps = self.dependencies()
-    for tool in deps:
-      if not tool.is_active():
-        return False
+        return content_exists and (skip_version_check or self.is_installed_version())
 
-    activated_cfg = self.activated_config()
-    if not activated_cfg:
-      return len(deps) > 0
+    def is_active(self):
+        if not self.is_installed():
+            return False
 
-    for key, value in activated_cfg.items():
-      if key not in EM_CONFIG_DICT:
-        debug_print(f'{self} is not active, because key="{key}" does not exist in .emscripten')
-        return False
+        # All dependencies of this tool must be active as well.
+        deps = self.dependencies()
+        for tool in deps:
+            if not tool.is_active():
+                return False
 
-      # all paths are stored dynamically relative to the emsdk root, so
-      # normalize those first.
-      config_value = EM_CONFIG_DICT[key].replace("emsdk_path + '", "'" + EMSDK_PATH).replace("$CFGDIR", EMSDK_PATH)
-      config_value = config_value.strip("'")
-      if config_value != value:
-        debug_print(f'{self} is not active, because key="{key}" has value "{config_value}" but should have value "{value}"')
-        return False
-    return True
+        activated_cfg = self.activated_config()
+        if not activated_cfg:
+            return len(deps) > 0
 
-  def is_env_active(self):
-    """Returns true if the system environment variables requires by this tool are currently active."""
-    envs = self.activated_environment()
-    for env in envs:
-      key, value = parse_key_value(env)
-      if key not in os.environ or to_unix_path(os.environ[key]) != to_unix_path(value):
-        debug_print(f'{self} is not active, because environment variable key="{key}" has value "{os.getenv(key)}" but should have value "{value}"')
-        return False
+        for key, value in activated_cfg.items():
+            if key not in EM_CONFIG_DICT:
+                debug_print(f'{self} is not active, because key="{key}" does not exist in .emscripten')
+                return False
 
-    if self.activated_path:
-      path = to_unix_path(self.expand_vars(self.activated_path))
-      for p in path:
-        path_items = os.environ['PATH'].replace('\\', '/').split(ENVPATH_SEPARATOR)
-        if not normalized_contains(path_items, p):
-          debug_print(f'{self} is not active, because environment variable PATH item "{p}" is not present (PATH={os.environ["PATH"]})')
-          return False
-    return True
+            # all paths are stored dynamically relative to the emsdk root, so
+            # normalize those first.
+            config_value = EM_CONFIG_DICT[key].replace("emsdk_path + '", "'" + EMSDK_PATH).replace("$CFGDIR", EMSDK_PATH)
+            config_value = config_value.strip("'")
+            if config_value != value:
+                debug_print(f'{self} is not active, because key="{key}" has value "{config_value}" but should have value "{value}"')
+                return False
+        return True
 
-  def can_be_installed(self):
-    """If this tool can be installed on this system, this function returns True.
-    Otherwise, this function returns a string that describes the reason why this
-    tool is not available.
-    """
-    if self.bitness == 64 and not is_os_64bit():
-        return "this tool is only provided for 64-bit OSes"
-    return True
+    def is_env_active(self):
+        """Returns true if the system environment variables requires by this tool are currently active."""
+        envs = self.activated_environment()
+        for env in envs:
+            key, value = parse_key_value(env)
+            if key not in os.environ or to_unix_path(os.environ[key]) != to_unix_path(value):
+                debug_print(f'{self} is not active, because environment variable key="{key}" has value "{os.getenv(key)}" but should have value "{value}"')
+                return False
 
-  def install(self):
-    """Returns True if the Tool was installed of False if was skipped due to
-    already being installed.
-    """
-    if self.can_be_installed() is not True:
-      exit_with_error(f"The tool '{self}' is not available due to the reason: {self.can_be_installed()}")
+        if self.activated_path:
+            path = to_unix_path(self.expand_vars(self.activated_path))
+            for p in path:
+                path_items = os.environ['PATH'].replace('\\', '/').split(ENVPATH_SEPARATOR)
+                if not normalized_contains(path_items, p):
+                    debug_print(f'{self} is not active, because environment variable PATH item "{p}" is not present (PATH={os.environ["PATH"]})')
+                    return False
+        return True
 
-    if self.id == 'sdk':
-      return self.install_sdk()
-    else:
-      return self.install_tool()
+    def can_be_installed(self):
+        """If this tool can be installed on this system, this function returns True.
+        Otherwise, this function returns a string that describes the reason why this
+        tool is not available.
+        """
+        if self.bitness == 64 and not is_os_64bit():
+            return "this tool is only provided for 64-bit OSes"
+        return True
 
-  def install_sdk(self):
-    """Returns True if any SDK component was installed of False all componented
-    were already installed.
-    """
-    print(f"Installing SDK '{self}'..")
-    installed = False
+    def install(self):
+        """Returns True if the Tool was installed of False if was skipped due to
+        already being installed.
+        """
+        if self.can_be_installed() is not True:
+            exit_with_error(f"The tool '{self}' is not available due to the reason: {self.can_be_installed()}")
 
-    for dep in self.dependencies():
-      installed |= dep.install()
+        if self.id == 'sdk':
+            return self.install_sdk()
+        else:
+            return self.install_tool()
 
-    if not installed:
-      print(f"All SDK components already installed: '{self}'.")
-      return False
+    def install_sdk(self):
+        """Returns True if any SDK component was installed of False all componented
+        were already installed.
+        """
+        print(f"Installing SDK '{self}'..")
+        installed = False
 
-    if self.custom_install_script == 'sdk_post_install':
-      if not sdk_post_install():
-        exit_with_error('post-install step failed: sdk_post_install')
+        for dep in self.dependencies():
+            installed |= dep.install()
 
-    print(f"Done installing SDK '{self}'.")
-    return True
+        if not installed:
+            print(f"All SDK components already installed: '{self}'.")
+            return False
 
-  def install_tool(self):
-    """Returns True if the SDK was installed of False if was skipped due to
-    already being installed.
-    """
-    # Avoid doing a redundant reinstall of the tool, if it has already been installed.
-    # However all tools that are sourced directly from git branches do need to be
-    # installed every time when requested, since the install step is then used to git
-    # pull the tool to a newer version.
-    if self.is_installed() and not self.git_branch:
-      print(f"Skipped installing {self.name}, already installed.")
-      return False
+        if self.custom_install_script == 'sdk_post_install':
+            if not sdk_post_install():
+                exit_with_error('post-install step failed: sdk_post_install')
 
-    print(f"Installing tool '{self}'..")
+        print(f"Done installing SDK '{self}'.")
+        return True
 
-    custom_install_scripts = {
-      'build_llvm': build_llvm,
-      'build_ninja': build_ninja,
-      'build_ccache': build_ccache,
-      'download_node_nightly': download_node_nightly,
-      'download_firefox': download_firefox,
-    }
-    if self.custom_install_script in custom_install_scripts:
-      success = custom_install_scripts[self.custom_install_script](self)
-    elif self.git_branch:
-      success = git_clone_checkout_and_pull(self.url, self.installation_path(), self.git_branch, getattr(self, 'remote_name', 'origin'))
-    elif self.url.endswith(ARCHIVE_SUFFIXES):
-      success = download_and_extract(self.url, self.installation_path(),
-                                     filename_prefix=getattr(self, 'download_prefix', ''))
-    else:
-      assert False, 'unhandled url type: ' + self.url
+    def install_tool(self):
+        """Returns True if the SDK was installed of False if was skipped due to
+        already being installed.
+        """
+        # Avoid doing a redundant reinstall of the tool, if it has already been installed.
+        # However all tools that are sourced directly from git branches do need to be
+        # installed every time when requested, since the install step is then used to git
+        # pull the tool to a newer version.
+        if self.is_installed() and not self.git_branch:
+            print(f"Skipped installing {self.name}, already installed.")
+            return False
 
-    if not success:
-      exit_with_error("installation failed!")
+        print(f"Installing tool '{self}'..")
 
-    if self.custom_install_script:
-      if self.custom_install_script == 'emscripten_install':
-        success = emscripten_install(self)
-      elif self.custom_install_script in {'build_llvm', 'build_ninja', 'build_ccache', 'download_node_nightly', 'download_firefox'}:
-        # 'build_llvm' is a special one that does the download on its
-        # own, others do the download manually.
-        pass
-      elif self.custom_install_script == 'build_binaryen':
-        success = build_binaryen_tool(self)
-      else:
-        raise Exception(f'Unknown custom_install_script: "{self.custom_install_script}"')
+        custom_install_scripts = {
+          'build_llvm': build_llvm,
+          'build_ninja': build_ninja,
+          'build_ccache': build_ccache,
+          'download_node_nightly': download_node_nightly,
+          'download_firefox': download_firefox,
+        }
+        if self.custom_install_script in custom_install_scripts:
+            success = custom_install_scripts[self.custom_install_script](self)
+        elif self.git_branch:
+            success = git_clone_checkout_and_pull(self.url, self.installation_path(), self.git_branch, getattr(self, 'remote_name', 'origin'))
+        elif self.url.endswith(ARCHIVE_SUFFIXES):
+            success = download_and_extract(self.url, self.installation_path(),
+                                           filename_prefix=getattr(self, 'download_prefix', ''))
+        else:
+            assert False, 'unhandled url type: ' + self.url
 
-    if not success:
-      exit_with_error("installation failed!")
+        if not success:
+            exit_with_error("installation failed!")
 
-    # Install an emscripten-version.txt file if told to, and if there is one.
-    # (If this is not an actual release, but some other build, then we do not
-    # write anything.)
-    if self.emscripten_releases_hash:
-      emscripten_version_file_path = os.path.join(to_native_path(self.expand_vars(self.activated_path)), 'emscripten-version.txt')
-      version = get_emscripten_release_version(self.emscripten_releases_hash)
-      if version:
-        write_file(emscripten_version_file_path, f'"{version}"\n')
+        if self.custom_install_script:
+            if self.custom_install_script == 'emscripten_install':
+                success = emscripten_install(self)
+            elif self.custom_install_script in {'build_llvm', 'build_ninja', 'build_ccache', 'download_node_nightly', 'download_firefox'}:
+                # 'build_llvm' is a special one that does the download on its
+                # own, others do the download manually.
+                pass
+            elif self.custom_install_script == 'build_binaryen':
+                success = build_binaryen_tool(self)
+            else:
+                raise Exception(f'Unknown custom_install_script: "{self.custom_install_script}"')
 
-    print(f"Done installing tool '{self}'.")
+        if not success:
+            exit_with_error("installation failed!")
 
-    # Sanity check that the installation succeeded, and if so, remove unneeded
-    # leftover installation files.
-    if not self.is_installed(skip_version_check=True):
-      exit_with_error(f"installation of '{self}' failed, but no error was detected. "
-                      "Either something went wrong with the installation, or this may indicate an internal emsdk error.")
+        # Install an emscripten-version.txt file if told to, and if there is one.
+        # (If this is not an actual release, but some other build, then we do not
+        # write anything.)
+        if self.emscripten_releases_hash:
+            emscripten_version_file_path = os.path.join(to_native_path(self.expand_vars(self.activated_path)), 'emscripten-version.txt')
+            version = get_emscripten_release_version(self.emscripten_releases_hash)
+            if version:
+                write_file(emscripten_version_file_path, f'"{version}"\n')
 
-    self.cleanup_temp_install_files()
-    self.update_installed_version()
-    return True
+        print(f"Done installing tool '{self}'.")
 
-  def cleanup_temp_install_files(self):
-    if KEEP_DOWNLOADS:
-      return
-    if self.url.endswith(ARCHIVE_SUFFIXES):
-      download_target = get_download_target(self.url, download_dir, getattr(self, 'download_prefix', ''))
-      debug_print(f"Deleting temporary download: {download_target}")
-      rmfile(download_target)
+        # Sanity check that the installation succeeded, and if so, remove unneeded
+        # leftover installation files.
+        if not self.is_installed(skip_version_check=True):
+            exit_with_error(f"installation of '{self}' failed, but no error was detected. "
+                            "Either something went wrong with the installation, or this may indicate an internal emsdk error.")
 
-  def uninstall(self):
-    if not self.is_installed():
-      print(f"Tool '{self}' was not installed. No need to uninstall.")
-      return
-    print(f"Uninstalling tool '{self}'..")
-    if self.custom_uninstall_script:
-      if self.custom_uninstall_script == 'uninstall_binaryen':
-        uninstall_binaryen(self)
-      else:
-        raise Exception(f'Unknown custom_uninstall_script directive "{self.custom_uninstall_script}"!')
-    print(f"Deleting path '{self.installation_path()}'")
-    remove_tree(self.installation_path())
-    print(f"Done uninstalling '{self}'.")
+        self.cleanup_temp_install_files()
+        self.update_installed_version()
+        return True
 
-  def dependencies(self):
-    deps = []
+    def cleanup_temp_install_files(self):
+        if KEEP_DOWNLOADS:
+            return
+        if self.url.endswith(ARCHIVE_SUFFIXES):
+            download_target = get_download_target(self.url, download_dir, getattr(self, 'download_prefix', ''))
+            debug_print(f"Deleting temporary download: {download_target}")
+            rmfile(download_target)
 
-    for dep in self.deps:
-      tool = find_tool(dep)
-      assert tool, f"dependency '{dep}' of '{self}' not found"
-      deps += [tool]
-    return deps
+    def uninstall(self):
+        if not self.is_installed():
+            print(f"Tool '{self}' was not installed. No need to uninstall.")
+            return
+        print(f"Uninstalling tool '{self}'..")
+        if self.custom_uninstall_script:
+            if self.custom_uninstall_script == 'uninstall_binaryen':
+                uninstall_binaryen(self)
+            else:
+                raise Exception(f'Unknown custom_uninstall_script directive "{self.custom_uninstall_script}"!')
+        print(f"Deleting path '{self.installation_path()}'")
+        remove_tree(self.installation_path())
+        print(f"Done uninstalling '{self}'.")
 
-  def recursive_dependencies(self):
-    deps = []
-    for dep in self.deps:
-      tool = find_tool(dep)
-      assert tool, f"dependency '{dep}' of '{self}' not found"
-      deps += [tool]
-      deps += tool.recursive_dependencies()
-    return deps
+    def dependencies(self):
+        deps = []
+
+        for dep in self.deps:
+            tool = find_tool(dep)
+            assert tool, f"dependency '{dep}' of '{self}' not found"
+            deps += [tool]
+        return deps
+
+    def recursive_dependencies(self):
+        deps = []
+        for dep in self.deps:
+            tool = find_tool(dep)
+            assert tool, f"dependency '{dep}' of '{self}' not found"
+            deps += [tool]
+            deps += tool.recursive_dependencies()
+        return deps
 
 
 # A global registry of all known Emscripten SDK tools available in the SDK manifest.
@@ -2216,12 +2216,12 @@
 
 
 def add_tool(tool):
-  tool.is_sdk = False
-  existing = find_tool(str(tool))
-  if existing:
-    raise Exception(f'Duplicate tool {tool}! Existing:\n{vars(existing)}, New:\n{vars(tool)}')
-  tools.append(tool)
-  tools_map[str(tool)] = tool
+    tool.is_sdk = False
+    existing = find_tool(str(tool))
+    if existing:
+        raise Exception(f'Duplicate tool {tool}! Existing:\n{vars(existing)}, New:\n{vars(tool)}')
+    tools.append(tool)
+    tools_map[str(tool)] = tool
 
 
 # A global registry of all known SDK toolsets.
@@ -2230,1126 +2230,1126 @@
 
 
 def add_sdk(sdk):
-  sdk.is_sdk = True
-  existing = find_sdk(str(sdk))
-  if existing:
-    raise Exception(f'Duplicate sdk {sdk}! Existing:\n{vars(existing)}, New:\n{vars(sdk)}')
-  sdks.append(sdk)
-  sdks_map[str(sdk)] = sdk
+    sdk.is_sdk = True
+    existing = find_sdk(str(sdk))
+    if existing:
+        raise Exception(f'Duplicate sdk {sdk}! Existing:\n{vars(existing)}, New:\n{vars(sdk)}')
+    sdks.append(sdk)
+    sdks_map[str(sdk)] = sdk
 
 
 # N.B. In both tools and sdks list above, we take the convention that the newest
 # items are at the back of the list (ascending chronological order)
 
 def find_tool(name):
-  return tools_map.get(name)
+    return tools_map.get(name)
 
 
 def find_sdk(name):
-  return sdks_map.get(name)
+    return sdks_map.get(name)
 
 
 def is_os_64bit():
-  return ARCH.endswith('64')
+    return ARCH.endswith('64')
 
 
 def find_latest_version():
-  return resolve_sdk_aliases('latest')
+    return resolve_sdk_aliases('latest')
 
 
 def find_latest_hash():
-  version = find_latest_version()
-  releases_info = load_releases_info()
-  return releases_info['releases'][version]
+    version = find_latest_version()
+    releases_info = load_releases_info()
+    return releases_info['releases'][version]
 
 
 def resolve_sdk_aliases(name, verbose=False):
-  releases_info = load_releases_info()
-  while name in releases_info['aliases']:
-    if verbose:
-      print(f"Resolving SDK alias '{name}' to '{releases_info['aliases'][name]}'")
-    name = releases_info['aliases'][name]
-  return name
+    releases_info = load_releases_info()
+    while name in releases_info['aliases']:
+        if verbose:
+            print(f"Resolving SDK alias '{name}' to '{releases_info['aliases'][name]}'")
+        name = releases_info['aliases'][name]
+    return name
 
 
 def find_latest_sdk():
-  return f'sdk-releases-{find_latest_hash()}-64bit'
+    return f'sdk-releases-{find_latest_hash()}-64bit'
 
 
 def find_tot_sdk():
-  debug_print('Fetching emscripten-releases repository...')
-  global extra_release_tag
-  extra_release_tag = get_emscripten_releases_tot()
-  return f'sdk-releases-{extra_release_tag}-64bit'
+    debug_print('Fetching emscripten-releases repository...')
+    global extra_release_tag
+    extra_release_tag = get_emscripten_releases_tot()
+    return f'sdk-releases-{extra_release_tag}-64bit'
 
 
 def parse_emscripten_version(emscripten_root):
-  version_file = os.path.join(emscripten_root, 'emscripten-version.txt')
-  version = read_file(version_file).strip()
-  version = version.strip('"')
-  suffix = None
-  if '-' in version:
-    version, suffix = version.split('-')
-  version = [int(v) for v in version.split('.')]
-  if suffix == 'git':
-    # Treat 1.2.3-git as 1.2.2 since it doesn't contain all the changes
-    # present in the final 1.2.3 release.
-    version[-1] -= 1
-  return version
+    version_file = os.path.join(emscripten_root, 'emscripten-version.txt')
+    version = read_file(version_file).strip()
+    version = version.strip('"')
+    suffix = None
+    if '-' in version:
+        version, suffix = version.split('-')
+    version = [int(v) for v in version.split('.')]
+    if suffix == 'git':
+        # Treat 1.2.3-git as 1.2.2 since it doesn't contain all the changes
+        # present in the final 1.2.3 release.
+        version[-1] -= 1
+    return version
 
 
 def get_emscripten_release_version(emscripten_releases_hash):
-  """Given a git hash in emscripten-releases, find the emscripten
-  version for it. There may not be one if this is not the hash of
-  a release, in which case we return None.
-  """
-  releases_info = load_releases_info()
-  for key, value in dict(releases_info['releases']).items():
-    if value == emscripten_releases_hash:
-      return key.split('-')[0]
-  return None
+    """Given a git hash in emscripten-releases, find the emscripten
+    version for it. There may not be one if this is not the hash of
+    a release, in which case we return None.
+    """
+    releases_info = load_releases_info()
+    for key, value in dict(releases_info['releases']).items():
+        if value == emscripten_releases_hash:
+            return key.split('-')[0]
+    return None
 
 
 def get_emscripten_releases_tot():
-  """Get the tip-of-tree build identifier."""
-  success = git_clone_checkout_and_pull(emscripten_releases_repo, sdk_path('releases'), 'main')
-  if not success:
-    exit_with_error('error checking out emscripten-releases repo')
-  recent_releases = git_recent_commits(sdk_path('releases'))
-  # The recent releases are the latest hashes in the git repo. There
-  # may not be a build for the most recent ones yet; find the last
-  # that has uploaded binaries for all platforms.
-  all_platforms = [
-    ('linux', '', 'tar.xz'),
-    ('linux', '-arm64', 'tar.xz'),
-    ('mac', '', 'tar.xz'),
-    ('mac', '-arm64', 'tar.xz'),
-    ('win', '', 'zip'),
-  ]
+    """Get the tip-of-tree build identifier."""
+    success = git_clone_checkout_and_pull(emscripten_releases_repo, sdk_path('releases'), 'main')
+    if not success:
+        exit_with_error('error checking out emscripten-releases repo')
+    recent_releases = git_recent_commits(sdk_path('releases'))
+    # The recent releases are the latest hashes in the git repo. There
+    # may not be a build for the most recent ones yet; find the last
+    # that has uploaded binaries for all platforms.
+    all_platforms = [
+      ('linux', '', 'tar.xz'),
+      ('linux', '-arm64', 'tar.xz'),
+      ('mac', '', 'tar.xz'),
+      ('mac', '-arm64', 'tar.xz'),
+      ('win', '', 'zip'),
+    ]
 
-  def check_binary(release, os_name, arch, ext):
-    url = emscripten_releases_download_url_template % (os_name, release, arch, ext)
-    try:
-      urlopen(url)
-      return True
-    except Exception:
-      return False
+    def check_binary(release, os_name, arch, ext):
+        url = emscripten_releases_download_url_template % (os_name, release, arch, ext)
+        try:
+            urlopen(url)
+            return True
+        except Exception:
+            return False
 
-  for release in recent_releases:
-    if all(check_binary(release, os_name, arch, ext) for os_name, arch, ext in all_platforms):
-      return release
+    for release in recent_releases:
+        if all(check_binary(release, os_name, arch, ext) for os_name, arch, ext in all_platforms):
+            return release
 
-  # No recent release has binaries for all platforms
-  exit_with_error('failed to find build of any recent emsdk revision')
+    # No recent release has binaries for all platforms
+    exit_with_error('failed to find build of any recent emsdk revision')
 
 
 def get_release_hash(arg, releases_info):
-  return releases_info.get(arg, None) or releases_info.get(f'sdk-{arg}-64bit')
+    return releases_info.get(arg, None) or releases_info.get(f'sdk-{arg}-64bit')
 
 
 def version_key(ver):
-  return tuple(map(int, re.split('[._-]', ver)[:3]))
+    return tuple(map(int, re.split('[._-]', ver)[:3]))
 
 
 def is_emsdk_sourced_from_github():
-  return os.path.exists(os.path.join(EMSDK_PATH, '.git'))
+    return os.path.exists(os.path.join(EMSDK_PATH, '.git'))
 
 
 def update_emsdk():
-  if is_emsdk_sourced_from_github():
-    errlog('You seem to have bootstrapped Emscripten SDK by cloning from GitHub. '
-           'In this case, use "git pull" instead of "emsdk update" to update emsdk. '
-           '(Not doing that automatically in case you have local changes)')
-    sys.exit(1)
-  if not download_and_extract(emsdk_zip_download_url, EMSDK_PATH, clobber=False):
-    sys.exit(1)
+    if is_emsdk_sourced_from_github():
+        errlog('You seem to have bootstrapped Emscripten SDK by cloning from GitHub. '
+               'In this case, use "git pull" instead of "emsdk update" to update emsdk. '
+               '(Not doing that automatically in case you have local changes)')
+        sys.exit(1)
+    if not download_and_extract(emsdk_zip_download_url, EMSDK_PATH, clobber=False):
+        sys.exit(1)
 
 
 def load_legacy_emscripten_tags():
-  """Lists all legacy (pre-emscripten-releases) tagged versions directly in the Git
-  repositories. These we can pull and compile from source.
-  """
-  return read_file(sdk_path('legacy-emscripten-tags.txt')).splitlines()
+    """Lists all legacy (pre-emscripten-releases) tagged versions directly in the Git
+    repositories. These we can pull and compile from source.
+    """
+    return read_file(sdk_path('legacy-emscripten-tags.txt')).splitlines()
 
 
 def load_legacy_binaryen_tags():
-  return read_file(sdk_path('legacy-binaryen-tags.txt')).splitlines()
+    return read_file(sdk_path('legacy-binaryen-tags.txt')).splitlines()
 
 
 def remove_prefix(s, prefix):
-  if s.startswith(prefix):
-    return s[len(prefix):]
-  else:
-    return s
+    if s.startswith(prefix):
+        return s[len(prefix):]
+    else:
+        return s
 
 
 def remove_suffix(s, suffix):
-  if s.endswith(suffix):
-    return s[:len(s) - len(suffix)]
-  else:
-    return s
+    if s.endswith(suffix):
+        return s[:len(s) - len(suffix)]
+    else:
+        return s
 
 
 def load_file_index_list(filename):
-  """filename should be one of: 'llvm-precompiled-tags-32bit.txt', 'llvm-precompiled-tags-64bit.txt'"""
-  items = read_file(sdk_path(filename)).splitlines()
-  items = [remove_suffix(remove_suffix(remove_prefix(x, 'emscripten-llvm-e'), '.tar.gz'), '.zip').strip() for x in items]
-  items = [x for x in items if 'latest' not in x and len(x) > 0]
+    """filename should be one of: 'llvm-precompiled-tags-32bit.txt', 'llvm-precompiled-tags-64bit.txt'"""
+    items = read_file(sdk_path(filename)).splitlines()
+    items = [remove_suffix(remove_suffix(remove_prefix(x, 'emscripten-llvm-e'), '.tar.gz'), '.zip').strip() for x in items]
+    items = [x for x in items if 'latest' not in x and len(x) > 0]
 
-  # Sort versions from oldest to newest (the default sort would be
-  # lexicographic, i.e. '1.37.1 < 1.37.10 < 1.37.2')
-  return sorted(items, key=version_key)
+    # Sort versions from oldest to newest (the default sort would be
+    # lexicographic, i.e. '1.37.1 < 1.37.10 < 1.37.2')
+    return sorted(items, key=version_key)
 
 
 def load_releases_info():
-  """Load the json info for emscripten-releases."""
-  if not hasattr(load_releases_info, 'cached_info'):
-    try:
-      text = read_file(sdk_path('emscripten-releases-tags.json'))
-      load_releases_info.cached_info = json.loads(text)
-    except Exception as e:
-      print('Error parsing emscripten-releases-tags.json!')
-      exit_with_error(str(e))
+    """Load the json info for emscripten-releases."""
+    if not hasattr(load_releases_info, 'cached_info'):
+        try:
+            text = read_file(sdk_path('emscripten-releases-tags.json'))
+            load_releases_info.cached_info = json.loads(text)
+        except Exception as e:
+            print('Error parsing emscripten-releases-tags.json!')
+            exit_with_error(str(e))
 
-  return load_releases_info.cached_info
+    return load_releases_info.cached_info
 
 
 def get_installed_sdk_version():
-  version_file = sdk_path(os.path.join('upstream', '.emsdk_version'))
-  if not os.path.exists(version_file):
-    return None
-  version = read_file(version_file)
-  return version.split('-')[1]
+    version_file = sdk_path(os.path.join('upstream', '.emsdk_version'))
+    if not os.path.exists(version_file):
+        return None
+    version = read_file(version_file)
+    return version.split('-')[1]
 
 
 def load_releases_tags():
-  """Get a list of tags for emscripten-releases."""
-  tags = []
-  info = load_releases_info()
+    """Get a list of tags for emscripten-releases."""
+    tags = []
+    info = load_releases_info()
 
-  for _version, sha in sorted(info['releases'].items(), key=lambda x: version_key(x[0])):
-    tags.append(sha)
+    for _version, sha in sorted(info['releases'].items(), key=lambda x: version_key(x[0])):
+        tags.append(sha)
 
-  if extra_release_tag:
-    tags.append(extra_release_tag)
+    if extra_release_tag:
+        tags.append(extra_release_tag)
 
-  # Explicitly add the currently installed SDK version.  This could be a custom
-  # version (installed explicitly) so it might not be part of the main list
-  # loaded above.
-  installed = get_installed_sdk_version()
-  if installed and installed not in tags:
-    tags.append(installed)
+    # Explicitly add the currently installed SDK version.  This could be a custom
+    # version (installed explicitly) so it might not be part of the main list
+    # loaded above.
+    installed = get_installed_sdk_version()
+    if installed and installed not in tags:
+        tags.append(installed)
 
-  return tags
+    return tags
 
 
 def load_releases_versions():
-  info = load_releases_info()
-  versions = list(info['releases'].keys())
-  return versions
+    info = load_releases_info()
+    versions = list(info['releases'].keys())
+    return versions
 
 
 def load_sdk_manifest():
-  try:
-    manifest = json.loads(read_file(sdk_path('emsdk_manifest.json')))
-  except Exception:
-    errlog('Error parsing emsdk_manifest.json!')
-    raise
+    try:
+        manifest = json.loads(read_file(sdk_path('emsdk_manifest.json')))
+    except Exception:
+        errlog('Error parsing emsdk_manifest.json!')
+        raise
 
-  emscripten_tags = load_legacy_emscripten_tags()
-  llvm_precompiled_tags_32bit = []
-  llvm_precompiled_tags_64bit = load_file_index_list('llvm-tags-64bit.txt')
-  llvm_precompiled_tags = llvm_precompiled_tags_32bit + llvm_precompiled_tags_64bit
-  binaryen_tags = load_legacy_binaryen_tags()
-  releases_tags = load_releases_tags()
+    emscripten_tags = load_legacy_emscripten_tags()
+    llvm_precompiled_tags_32bit = []
+    llvm_precompiled_tags_64bit = load_file_index_list('llvm-tags-64bit.txt')
+    llvm_precompiled_tags = llvm_precompiled_tags_32bit + llvm_precompiled_tags_64bit
+    binaryen_tags = load_legacy_binaryen_tags()
+    releases_tags = load_releases_tags()
 
-  def dependencies_exist(sdk):
-    for dep in sdk.deps:
-      tool = find_tool(dep)
-      if not tool:
-        debug_print('missing dependency: ' + dep)
-        return False
-    return True
+    def dependencies_exist(sdk):
+        for dep in sdk.deps:
+            tool = find_tool(dep)
+            if not tool:
+                debug_print('missing dependency: ' + dep)
+                return False
+        return True
 
-  def cmp_version(ver, cmp_operand, reference):
-    if cmp_operand == '<=':
-      return version_key(ver) <= version_key(reference)
-    if cmp_operand == '<':
-      return version_key(ver) < version_key(reference)
-    if cmp_operand == '>=':
-      return version_key(ver) >= version_key(reference)
-    if cmp_operand == '>':
-      return version_key(ver) > version_key(reference)
-    if cmp_operand == '==':
-      return version_key(ver) == version_key(reference)
-    if cmp_operand == '!=':
-      return version_key(ver) != version_key(reference)
-    raise Exception(f'Invalid cmp_operand "{cmp_operand}"!')
+    def cmp_version(ver, cmp_operand, reference):
+        if cmp_operand == '<=':
+            return version_key(ver) <= version_key(reference)
+        if cmp_operand == '<':
+            return version_key(ver) < version_key(reference)
+        if cmp_operand == '>=':
+            return version_key(ver) >= version_key(reference)
+        if cmp_operand == '>':
+            return version_key(ver) > version_key(reference)
+        if cmp_operand == '==':
+            return version_key(ver) == version_key(reference)
+        if cmp_operand == '!=':
+            return version_key(ver) != version_key(reference)
+        raise Exception(f'Invalid cmp_operand "{cmp_operand}"!')
 
-  def passes_filters(param, ver, filters):
-    for v in filters:
-      if v[0] == param and not cmp_version(ver, v[1], v[2]):
-        return False
-    return True
+    def passes_filters(param, ver, filters):
+        for v in filters:
+            if v[0] == param and not cmp_version(ver, v[1], v[2]):
+                return False
+        return True
 
-  def expand_category_param(param, category_list, t, is_sdk):
-    """A 'category parameter' is a %foo%-encoded identifier that specifies
-    a class of tools instead of just one tool, e.g. %tag%
-    """
-    for i, ver in enumerate(category_list):
-      if not ver.strip():
-        continue
-      t2 = copy.copy(t)
-      found_param = False
-      for p, v in vars(t2).items():
-        if isinstance(v, str) and param in v:
-          t2.__dict__[p] = v.replace(param, ver)
-          found_param = True
-      if not found_param:
-        continue
-      t2.is_old = i < len(category_list) - 2
-      t2.deps = [x.replace(param, ver) for x in t2.deps]
+    def expand_category_param(param, category_list, t, is_sdk):
+        """A 'category parameter' is a %foo%-encoded identifier that specifies
+        a class of tools instead of just one tool, e.g. %tag%
+        """
+        for i, ver in enumerate(category_list):
+            if not ver.strip():
+                continue
+            t2 = copy.copy(t)
+            found_param = False
+            for p, v in vars(t2).items():
+                if isinstance(v, str) and param in v:
+                    t2.__dict__[p] = v.replace(param, ver)
+                    found_param = True
+            if not found_param:
+                continue
+            t2.is_old = i < len(category_list) - 2
+            t2.deps = [x.replace(param, ver) for x in t2.deps]
 
-      if is_sdk:
-        if dependencies_exist(t2):
-          if not find_sdk(t2.name):
-            add_sdk(t2)
-          else:
-            debug_print(f'SDK {t2} already existed in manifest, not adding twice')
-      else:
-        if not find_tool(t2.name):
-          add_tool(t2)
-        else:
-          debug_print(f'Tool {t2} already existed in manifest, not adding twice')
+            if is_sdk:
+                if dependencies_exist(t2):
+                    if not find_sdk(t2.name):
+                        add_sdk(t2)
+                    else:
+                        debug_print(f'SDK {t2} already existed in manifest, not adding twice')
+            else:
+                if not find_tool(t2.name):
+                    add_tool(t2)
+                else:
+                    debug_print(f'Tool {t2} already existed in manifest, not adding twice')
 
-  for tool in manifest['tools']:
-    t = Tool(tool)
-    if t.compatible_with_this_os():
-      # Expand the metapackages that refer to tags
-      if '%tag%' in t.version:
-        expand_category_param('%tag%', emscripten_tags, t, is_sdk=False)
-      elif '%precompiled_tag%' in t.version:
-        expand_category_param('%precompiled_tag%', llvm_precompiled_tags, t, is_sdk=False)
-      elif '%precompiled_tag32%' in t.version:
-        expand_category_param('%precompiled_tag32%', llvm_precompiled_tags_32bit, t, is_sdk=False)
-      elif '%precompiled_tag64%' in t.version:
-        expand_category_param('%precompiled_tag64%', llvm_precompiled_tags_64bit, t, is_sdk=False)
-      elif '%binaryen_tag%' in t.version:
-        expand_category_param('%binaryen_tag%', binaryen_tags, t, is_sdk=False)
-      elif '%releases-tag%' in t.version:
-        expand_category_param('%releases-tag%', releases_tags, t, is_sdk=False)
-      else:
-        add_tool(t)
+    for tool in manifest['tools']:
+        t = Tool(tool)
+        if t.compatible_with_this_os():
+            # Expand the metapackages that refer to tags
+            if '%tag%' in t.version:
+                expand_category_param('%tag%', emscripten_tags, t, is_sdk=False)
+            elif '%precompiled_tag%' in t.version:
+                expand_category_param('%precompiled_tag%', llvm_precompiled_tags, t, is_sdk=False)
+            elif '%precompiled_tag32%' in t.version:
+                expand_category_param('%precompiled_tag32%', llvm_precompiled_tags_32bit, t, is_sdk=False)
+            elif '%precompiled_tag64%' in t.version:
+                expand_category_param('%precompiled_tag64%', llvm_precompiled_tags_64bit, t, is_sdk=False)
+            elif '%binaryen_tag%' in t.version:
+                expand_category_param('%binaryen_tag%', binaryen_tags, t, is_sdk=False)
+            elif '%releases-tag%' in t.version:
+                expand_category_param('%releases-tag%', releases_tags, t, is_sdk=False)
+            else:
+                add_tool(t)
 
-  for sdk_str in manifest['sdks']:
-    sdk_str['id'] = 'sdk'
-    sdk = Tool(sdk_str)
-    if sdk.compatible_with_this_os():
-      if not hasattr(sdk, 'is_old'):
-        sdk.is_old = False
+    for sdk_str in manifest['sdks']:
+        sdk_str['id'] = 'sdk'
+        sdk = Tool(sdk_str)
+        if sdk.compatible_with_this_os():
+            if not hasattr(sdk, 'is_old'):
+                sdk.is_old = False
 
-      if '%tag%' in sdk.version:
-        expand_category_param('%tag%', emscripten_tags, sdk, is_sdk=True)
-      elif '%precompiled_tag%' in sdk.version:
-        expand_category_param('%precompiled_tag%', llvm_precompiled_tags, sdk, is_sdk=True)
-      elif '%precompiled_tag32%' in sdk.version:
-        expand_category_param('%precompiled_tag32%', llvm_precompiled_tags_32bit, sdk, is_sdk=True)
-      elif '%precompiled_tag64%' in sdk.version:
-        expand_category_param('%precompiled_tag64%', llvm_precompiled_tags_64bit, sdk, is_sdk=True)
-      elif '%releases-tag%' in sdk.version:
-        expand_category_param('%releases-tag%', releases_tags, sdk, is_sdk=True)
-      else:
-        add_sdk(sdk)
+            if '%tag%' in sdk.version:
+                expand_category_param('%tag%', emscripten_tags, sdk, is_sdk=True)
+            elif '%precompiled_tag%' in sdk.version:
+                expand_category_param('%precompiled_tag%', llvm_precompiled_tags, sdk, is_sdk=True)
+            elif '%precompiled_tag32%' in sdk.version:
+                expand_category_param('%precompiled_tag32%', llvm_precompiled_tags_32bit, sdk, is_sdk=True)
+            elif '%precompiled_tag64%' in sdk.version:
+                expand_category_param('%precompiled_tag64%', llvm_precompiled_tags_64bit, sdk, is_sdk=True)
+            elif '%releases-tag%' in sdk.version:
+                expand_category_param('%releases-tag%', releases_tags, sdk, is_sdk=True)
+            else:
+                add_sdk(sdk)
 
 
 def can_simultaneously_activate(tool1, tool2):
-  """Tests if the two given tools can be active at the same time.
-  Currently only a simple check for name for same tool with different versions,
-  possibly adds more logic in the future.
-  """
-  return tool1.id != tool2.id
+    """Tests if the two given tools can be active at the same time.
+    Currently only a simple check for name for same tool with different versions,
+    possibly adds more logic in the future.
+    """
+    return tool1.id != tool2.id
 
 
 def process_tool_list(tools_to_activate):
-  """Expands dependencies for each tool, and removes ones that don't exist."""
-  i = 0
-  # Gather dependencies for each tool
-  while i < len(tools_to_activate):
-    tool = tools_to_activate[i]
-    deps = tool.recursive_dependencies()
-    tools_to_activate = tools_to_activate[:i] + deps + tools_to_activate[i:]
-    i += len(deps) + 1
+    """Expands dependencies for each tool, and removes ones that don't exist."""
+    i = 0
+    # Gather dependencies for each tool
+    while i < len(tools_to_activate):
+        tool = tools_to_activate[i]
+        deps = tool.recursive_dependencies()
+        tools_to_activate = tools_to_activate[:i] + deps + tools_to_activate[i:]
+        i += len(deps) + 1
 
-  for tool in tools_to_activate:
-    if not tool.is_installed():
-      exit_with_error(f"error: tool is not installed and therefore cannot be activated: '{tool}'")
+    for tool in tools_to_activate:
+        if not tool.is_installed():
+            exit_with_error(f"error: tool is not installed and therefore cannot be activated: '{tool}'")
 
-  # Remove conflicting tools
-  i = 0
-  while i < len(tools_to_activate):
-    j = 0
-    while j < i:
-      secondary_tool = tools_to_activate[j]
-      primary_tool = tools_to_activate[i]
-      if not can_simultaneously_activate(primary_tool, secondary_tool):
-        tools_to_activate.pop(j)
-        j -= 1
-        i -= 1
-      j += 1
-    i += 1
-  return tools_to_activate
+    # Remove conflicting tools
+    i = 0
+    while i < len(tools_to_activate):
+        j = 0
+        while j < i:
+            secondary_tool = tools_to_activate[j]
+            primary_tool = tools_to_activate[i]
+            if not can_simultaneously_activate(primary_tool, secondary_tool):
+                tools_to_activate.pop(j)
+                j -= 1
+                i -= 1
+            j += 1
+        i += 1
+    return tools_to_activate
 
 
 def write_set_env_script(env_string):
-  assert CMD or POWERSHELL
-  write_file(EMSDK_SET_ENV, env_string)
+    assert CMD or POWERSHELL
+    write_file(EMSDK_SET_ENV, env_string)
 
 
 def set_active_tools(tools_to_activate, permanently_activate, system):
-  """Reconfigure .emscripten to choose the currently activated toolset, set PATH
-  and other environment variables.
-  Returns the full list of deduced tools that are now active.
-  """
-  tools_to_activate = process_tool_list(tools_to_activate)
+    """Reconfigure .emscripten to choose the currently activated toolset, set PATH
+    and other environment variables.
+    Returns the full list of deduced tools that are now active.
+    """
+    tools_to_activate = process_tool_list(tools_to_activate)
 
-  if tools_to_activate:
-    tools = [x for x in tools_to_activate if not x.is_sdk]
-    print('Setting the following tools as active:')
-    for t in tools:
-      print(f'   {t}')
-    print('')
+    if tools_to_activate:
+        tools = [x for x in tools_to_activate if not x.is_sdk]
+        print('Setting the following tools as active:')
+        for t in tools:
+            print(f'   {t}')
+        print('')
 
-  generate_em_config(tools_to_activate, permanently_activate, system)
+    generate_em_config(tools_to_activate, permanently_activate, system)
 
-  # Construct a .bat or .ps1 script that will be invoked to set env. vars and PATH
-  # We only do this on cmd or powershell since emsdk.bat/ps1 is able to modify the
-  # calling shell environment.  On other shell `source emsdk_env.sh` is
-  # required.
-  if CMD or POWERSHELL:
-    # always set local environment variables since permanently activating will only set the registry settings and
-    # will not affect the current session
-    env_vars_to_add = get_env_vars_to_add(tools_to_activate, system, user=permanently_activate)
-    env_string = construct_env_with_vars(env_vars_to_add)
-    write_set_env_script(env_string)
+    # Construct a .bat or .ps1 script that will be invoked to set env. vars and PATH
+    # We only do this on cmd or powershell since emsdk.bat/ps1 is able to modify the
+    # calling shell environment.  On other shell `source emsdk_env.sh` is
+    # required.
+    if CMD or POWERSHELL:
+        # always set local environment variables since permanently activating will only set the registry settings and
+        # will not affect the current session
+        env_vars_to_add = get_env_vars_to_add(tools_to_activate, system, user=permanently_activate)
+        env_string = construct_env_with_vars(env_vars_to_add)
+        write_set_env_script(env_string)
 
-    if WINDOWS and permanently_activate:
-      win_set_environment_variables(env_vars_to_add, system, user=permanently_activate)
+        if WINDOWS and permanently_activate:
+            win_set_environment_variables(env_vars_to_add, system, user=permanently_activate)
 
-  return tools_to_activate
+    return tools_to_activate
 
 
 def currently_active_sdk():
-  for sdk in reversed(sdks):
-    if sdk.is_active():
-      return sdk
-  return None
+    for sdk in reversed(sdks):
+        if sdk.is_active():
+            return sdk
+    return None
 
 
 def currently_active_tools():
-  active_tools = []
-  for tool in tools:
-    if tool.is_active():
-      active_tools += [tool]
-  return active_tools
+    active_tools = []
+    for tool in tools:
+        if tool.is_active():
+            active_tools += [tool]
+    return active_tools
 
 
 # http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order
 def unique_items(seq):
-  seen = set()
-  seen_add = seen.add
-  return [x for x in seq if x not in seen and not seen_add(x)]
+    seen = set()
+    seen_add = seen.add
+    return [x for x in seq if x not in seen and not seen_add(x)]
 
 
 def normalized_contains(lst, elem):
-  """Tests if a path is contained in the given list, but with separators normalized."""
-  elem = to_unix_path(elem)
-  for e in lst:
-    if elem == to_unix_path(e):
-      return True
-  return False
+    """Tests if a path is contained in the given list, but with separators normalized."""
+    elem = to_unix_path(elem)
+    for e in lst:
+        if elem == to_unix_path(e):
+            return True
+    return False
 
 
 def to_msys_path(p):
-  p = to_unix_path(p)
-  new_path = re.sub(r'([a-zA-Z]):/(.*)', r'/\1/\2', p)
-  if len(new_path) > 3 and new_path[0] == '/' and new_path[2] == '/':
-    new_path = new_path[0] + new_path[1].lower() + new_path[2:]
-  return new_path
+    p = to_unix_path(p)
+    new_path = re.sub(r'([a-zA-Z]):/(.*)', r'/\1/\2', p)
+    if len(new_path) > 3 and new_path[0] == '/' and new_path[2] == '/':
+        new_path = new_path[0] + new_path[1].lower() + new_path[2:]
+    return new_path
 
 
 def adjusted_path(tools_to_activate, system=False, user=False):
-  """Looks at the current PATH and adds and removes entries so that the PATH reflects
-  the set of given active tools.
-  """
-  # These directories should be added to PATH
-  path_add = get_required_path(tools_to_activate)
-  # These already exist.
-  if WINDOWS and not MSYS:
-    existing_path = win_get_environment_variable('PATH', system=system, user=user, fallback=True).split(ENVPATH_SEPARATOR)
-  else:
-    existing_path = os.environ['PATH'].split(ENVPATH_SEPARATOR)
-
-  existing_emsdk_tools = []
-  existing_nonemsdk_path = []
-  for entry in existing_path:
-    if to_unix_path(entry).startswith(EMSDK_PATH):
-      existing_emsdk_tools.append(entry)
+    """Looks at the current PATH and adds and removes entries so that the PATH reflects
+    the set of given active tools.
+    """
+    # These directories should be added to PATH
+    path_add = get_required_path(tools_to_activate)
+    # These already exist.
+    if WINDOWS and not MSYS:
+        existing_path = win_get_environment_variable('PATH', system=system, user=user, fallback=True).split(ENVPATH_SEPARATOR)
     else:
-      existing_nonemsdk_path.append(entry)
+        existing_path = os.environ['PATH'].split(ENVPATH_SEPARATOR)
 
-  new_emsdk_tools = []
-  kept_emsdk_tools = []
-  for entry in path_add:
-    if not normalized_contains(existing_emsdk_tools, entry):
-      new_emsdk_tools.append(entry)
-    else:
-      kept_emsdk_tools.append(entry)
+    existing_emsdk_tools = []
+    existing_nonemsdk_path = []
+    for entry in existing_path:
+        if to_unix_path(entry).startswith(EMSDK_PATH):
+            existing_emsdk_tools.append(entry)
+        else:
+            existing_nonemsdk_path.append(entry)
 
-  whole_path = unique_items(new_emsdk_tools + kept_emsdk_tools + existing_nonemsdk_path)
+    new_emsdk_tools = []
+    kept_emsdk_tools = []
+    for entry in path_add:
+        if not normalized_contains(existing_emsdk_tools, entry):
+            new_emsdk_tools.append(entry)
+        else:
+            kept_emsdk_tools.append(entry)
 
-  if MSYS:
-    # XXX Hack: If running native Windows Python in MSYS prompt where PATH
-    # entries look like "/c/Windows/System32", os.environ['PATH']
-    # in Python will transform to show them as "C:\\Windows\\System32", so need
-    # to reconvert path delimiter back to forward slashes.
-    whole_path = [to_msys_path(p) for p in whole_path]
-    new_emsdk_tools = [to_msys_path(p) for p in new_emsdk_tools]
+    whole_path = unique_items(new_emsdk_tools + kept_emsdk_tools + existing_nonemsdk_path)
 
-  separator = ':' if MSYS else ENVPATH_SEPARATOR
-  return (separator.join(whole_path), new_emsdk_tools)
+    if MSYS:
+        # XXX Hack: If running native Windows Python in MSYS prompt where PATH
+        # entries look like "/c/Windows/System32", os.environ['PATH']
+        # in Python will transform to show them as "C:\\Windows\\System32", so need
+        # to reconvert path delimiter back to forward slashes.
+        whole_path = [to_msys_path(p) for p in whole_path]
+        new_emsdk_tools = [to_msys_path(p) for p in new_emsdk_tools]
+
+    separator = ':' if MSYS else ENVPATH_SEPARATOR
+    return (separator.join(whole_path), new_emsdk_tools)
 
 
 def get_env_vars_to_add(tools_to_activate, system, user):
-  env_vars_to_add = []
+    env_vars_to_add = []
 
-  newpath, added_path = adjusted_path(tools_to_activate, system, user)
+    newpath, added_path = adjusted_path(tools_to_activate, system, user)
 
-  # Don't bother setting the path if there are no changes.
-  if os.environ['PATH'] != newpath:
-    env_vars_to_add += [('PATH', newpath)]
+    # Don't bother setting the path if there are no changes.
+    if os.environ['PATH'] != newpath:
+        env_vars_to_add += [('PATH', newpath)]
 
-    if added_path:
-      info('Adding directories to PATH:')
-      for item in added_path:
-        info('PATH += ' + item)
-      info('')
+        if added_path:
+            info('Adding directories to PATH:')
+            for item in added_path:
+                info('PATH += ' + item)
+            info('')
 
-  # A core variable EMSDK points to the root of Emscripten SDK directory.
-  env_vars_to_add += [('EMSDK', EMSDK_PATH)]
+    # A core variable EMSDK points to the root of Emscripten SDK directory.
+    env_vars_to_add += [('EMSDK', EMSDK_PATH)]
 
-  for tool in tools_to_activate:
-    for env in tool.activated_environment():
-      key, value = parse_key_value(env)
-      value = to_native_path(tool.expand_vars(value))
-      env_vars_to_add += [(key, value)]
+    for tool in tools_to_activate:
+        for env in tool.activated_environment():
+            key, value = parse_key_value(env)
+            value = to_native_path(tool.expand_vars(value))
+            env_vars_to_add += [(key, value)]
 
-  emroot = find_emscripten_root(tools_to_activate)
-  if emroot:
-    # For older emscripten versions that don't use an embedded cache by
-    # default we need to export EM_CACHE.
-    #
-    # Sadly, we can't put this in the config file since those older versions
-    # also didn't read the `CACHE` key from the config file:
-    #
-    # History:
-    # - 'CACHE' config started being honored in 1.39.16
-    #   https://github.com/emscripten-core/emscripten/pull/11091
-    # - Default to embedded cache also started in 1.39.16
-    #   https://github.com/emscripten-core/emscripten/pull/11126
-    # - Emscripten supports automatically locating the embedded
-    #   config in 1.39.13:
-    #   https://github.com/emscripten-core/emscripten/pull/10935
-    #
-    # Since setting EM_CACHE in the environment effects the entire machine
-    # we want to avoid this except when installing these older emscripten
-    # versions that really need it.
-    version = parse_emscripten_version(emroot)
-    if version < [1, 39, 16]:
-      em_cache_dir = os.path.join(emroot, 'cache')
-      env_vars_to_add += [('EM_CACHE', em_cache_dir)]
-    if version < [1, 39, 13]:
-      env_vars_to_add += [('EM_CONFIG', os.path.normpath(EM_CONFIG_PATH))]
+    emroot = find_emscripten_root(tools_to_activate)
+    if emroot:
+        # For older emscripten versions that don't use an embedded cache by
+        # default we need to export EM_CACHE.
+        #
+        # Sadly, we can't put this in the config file since those older versions
+        # also didn't read the `CACHE` key from the config file:
+        #
+        # History:
+        # - 'CACHE' config started being honored in 1.39.16
+        #   https://github.com/emscripten-core/emscripten/pull/11091
+        # - Default to embedded cache also started in 1.39.16
+        #   https://github.com/emscripten-core/emscripten/pull/11126
+        # - Emscripten supports automatically locating the embedded
+        #   config in 1.39.13:
+        #   https://github.com/emscripten-core/emscripten/pull/10935
+        #
+        # Since setting EM_CACHE in the environment effects the entire machine
+        # we want to avoid this except when installing these older emscripten
+        # versions that really need it.
+        version = parse_emscripten_version(emroot)
+        if version < [1, 39, 16]:
+            em_cache_dir = os.path.join(emroot, 'cache')
+            env_vars_to_add += [('EM_CACHE', em_cache_dir)]
+        if version < [1, 39, 13]:
+            env_vars_to_add += [('EM_CONFIG', os.path.normpath(EM_CONFIG_PATH))]
 
-  return env_vars_to_add
+    return env_vars_to_add
 
 
 def construct_env(tools_to_activate, system, user):
-  info('Setting up EMSDK environment (suppress these messages with EMSDK_QUIET=1)')
-  return construct_env_with_vars(get_env_vars_to_add(tools_to_activate, system, user))
+    info('Setting up EMSDK environment (suppress these messages with EMSDK_QUIET=1)')
+    return construct_env_with_vars(get_env_vars_to_add(tools_to_activate, system, user))
 
 
 def unset_env(key):
-  if POWERSHELL:
-    return f'Remove-Item env:{key} -ErrorAction SilentlyContinue\n'
-  if CMD:
-    return f'set {key}=\n'
-  if CSH:
-    return f'unsetenv {key};\n'
-  if FISH:
-    return f'set -e {key};\n'
-  if BASH:
-    return f'unset {key};\n'
-  assert False
+    if POWERSHELL:
+        return f'Remove-Item env:{key} -ErrorAction SilentlyContinue\n'
+    if CMD:
+        return f'set {key}=\n'
+    if CSH:
+        return f'unsetenv {key};\n'
+    if FISH:
+        return f'set -e {key};\n'
+    if BASH:
+        return f'unset {key};\n'
+    assert False
 
 
 def construct_env_with_vars(env_vars_to_add):
-  env_string = ''
-  if env_vars_to_add:
-    info('Setting environment variables:')
+    env_string = ''
+    if env_vars_to_add:
+        info('Setting environment variables:')
 
-    for key, value in env_vars_to_add:
-      # Don't set env vars which are already set to the correct value.
-      if key in os.environ and to_unix_path(os.environ[key]) == to_unix_path(value):
-        continue
-      info(f'{key} = {value}')
-      if POWERSHELL:
-        env_string += f'$env:{key}="{value}"\n'
-      elif CMD:
-        env_string += f'SET {key}={value}\n'
-      elif CSH:
-        env_string += f'setenv {key} "{value}";\n'
-      elif FISH:
-        env_string += f'set -gx {key} "{value}";\n'
-      elif BASH:
-        env_string += f'export {key}="{value}";\n'
-      else:
-        assert False
+        for key, value in env_vars_to_add:
+            # Don't set env vars which are already set to the correct value.
+            if key in os.environ and to_unix_path(os.environ[key]) == to_unix_path(value):
+                continue
+            info(f'{key} = {value}')
+            if POWERSHELL:
+                env_string += f'$env:{key}="{value}"\n'
+            elif CMD:
+                env_string += f'SET {key}={value}\n'
+            elif CSH:
+                env_string += f'setenv {key} "{value}";\n'
+            elif FISH:
+                env_string += f'set -gx {key} "{value}";\n'
+            elif BASH:
+                env_string += f'export {key}="{value}";\n'
+            else:
+                assert False
 
-    if 'EMSDK_PYTHON' in env_vars_to_add:
-      # When using our bundled python we never want the user's
-      # PYTHONHOME or PYTHONPATH
-      # See https://github.com/emscripten-core/emsdk/issues/598
-      env_string += unset_env('PYTHONHOME')
-      env_string += unset_env('PYTHONPATH')
+        if 'EMSDK_PYTHON' in env_vars_to_add:
+            # When using our bundled python we never want the user's
+            # PYTHONHOME or PYTHONPATH
+            # See https://github.com/emscripten-core/emsdk/issues/598
+            env_string += unset_env('PYTHONHOME')
+            env_string += unset_env('PYTHONPATH')
 
-  # Remove any environment variables that might have been set by old or
-  # inactive tools/sdks.  For example, we set EM_CACHE for older versions
-  # of the SDK but we want to remove that from the current environment
-  # if no such tool is active.
-  # Ignore certain keys that are inputs to emsdk itself.
-  ignore_keys = {'EMSDK_POWERSHELL', 'EMSDK_CSH', 'EMSDK_CMD', 'EMSDK_BASH', 'EMSDK_FISH',
-                 'EMSDK_NUM_CORES', 'EMSDK_NOTTY', 'EMSDK_KEEP_DOWNLOADS'}
-  env_keys_to_add = {pair[0] for pair in env_vars_to_add}
-  for key in os.environ:
-    if key.startswith('EMSDK_') or key in {'EM_CACHE', 'EM_CONFIG'}:
-      if key not in env_keys_to_add and key not in ignore_keys:
-        info(f'Clearing existing environment variable: {key}')
-        env_string += unset_env(key)
+    # Remove any environment variables that might have been set by old or
+    # inactive tools/sdks.  For example, we set EM_CACHE for older versions
+    # of the SDK but we want to remove that from the current environment
+    # if no such tool is active.
+    # Ignore certain keys that are inputs to emsdk itself.
+    ignore_keys = {'EMSDK_POWERSHELL', 'EMSDK_CSH', 'EMSDK_CMD', 'EMSDK_BASH', 'EMSDK_FISH',
+                   'EMSDK_NUM_CORES', 'EMSDK_NOTTY', 'EMSDK_KEEP_DOWNLOADS'}
+    env_keys_to_add = {pair[0] for pair in env_vars_to_add}
+    for key in os.environ:
+        if key.startswith('EMSDK_') or key in {'EM_CACHE', 'EM_CONFIG'}:
+            if key not in env_keys_to_add and key not in ignore_keys:
+                info(f'Clearing existing environment variable: {key}')
+                env_string += unset_env(key)
 
-  return env_string
+    return env_string
 
 
 def error_on_missing_tool(name):
-  if name.endswith('-64bit') and not is_os_64bit():
-    exit_with_error(f"'{name}' is only provided for 64-bit OSes")
-  else:
-    exit_with_error(f"tool or SDK not found: '{name}'")
+    if name.endswith('-64bit') and not is_os_64bit():
+        exit_with_error(f"'{name}' is only provided for 64-bit OSes")
+    else:
+        exit_with_error(f"tool or SDK not found: '{name}'")
 
 
 def expand_sdk_name(name, activating):
-  if 'upstream-master' in name:
-    errlog('upstream-master SDK has been renamed main')
-    name = name.replace('upstream-master', 'main')
-  if 'fastcomp' in name:
-    exit_with_error('the fastcomp backend is no longer supported. '
-                    'Please use an older version of emsdk (for example 3.1.29) '
-                    'if you want to install the old fastcomp-based SDK')
-  if name in {'tot', 'sdk-tot', 'tot-upstream'}:
-    if activating:
-      # When we are activating a tot release, assume that the currently
-      # installed SDK, if any, is the tot release we want to activate.
-      # Without this `install tot && activate tot` will race with the builders
-      # that are producing new builds.
-      installed = get_installed_sdk_version()
-      if installed:
-        debug_print('activating currently installed SDK; not updating tot version')
-        return f'sdk-releases-{installed}-64bit'
-    return find_tot_sdk()
+    if 'upstream-master' in name:
+        errlog('upstream-master SDK has been renamed main')
+        name = name.replace('upstream-master', 'main')
+    if 'fastcomp' in name:
+        exit_with_error('the fastcomp backend is no longer supported. '
+                        'Please use an older version of emsdk (for example 3.1.29) '
+                        'if you want to install the old fastcomp-based SDK')
+    if name in {'tot', 'sdk-tot', 'tot-upstream'}:
+        if activating:
+            # When we are activating a tot release, assume that the currently
+            # installed SDK, if any, is the tot release we want to activate.
+            # Without this `install tot && activate tot` will race with the builders
+            # that are producing new builds.
+            installed = get_installed_sdk_version()
+            if installed:
+                debug_print('activating currently installed SDK; not updating tot version')
+                return f'sdk-releases-{installed}-64bit'
+        return find_tot_sdk()
 
-  if '-upstream' in name:
-    name = name.replace('-upstream', '')
+    if '-upstream' in name:
+        name = name.replace('-upstream', '')
 
-  name = resolve_sdk_aliases(name, verbose=True)
+    name = resolve_sdk_aliases(name, verbose=True)
 
-  # check if it's a release handled by an emscripten-releases version,
-  # and if so use that by using the right hash. we support a few notations,
-  #   x.y.z
-  #   sdk-x.y.z-64bit
-  # TODO: support short notation for old builds too?
-  fullname = name
-  version = fullname.replace('sdk-', '').replace('releases-', '').replace('-64bit', '').replace('tag-', '')
-  sdk = 'sdk-' if not name.startswith('releases-') else ''
-  releases_info = load_releases_info()['releases']
-  release_hash = get_release_hash(version, releases_info)
-  if release_hash:
-    # Known release hash
-    full_name = f'{sdk}releases-{release_hash}-64bit'
-    print(f"Resolving SDK version '{version}' to '{full_name}'")
-    return full_name
+    # check if it's a release handled by an emscripten-releases version,
+    # and if so use that by using the right hash. we support a few notations,
+    #   x.y.z
+    #   sdk-x.y.z-64bit
+    # TODO: support short notation for old builds too?
+    fullname = name
+    version = fullname.replace('sdk-', '').replace('releases-', '').replace('-64bit', '').replace('tag-', '')
+    sdk = 'sdk-' if not name.startswith('releases-') else ''
+    releases_info = load_releases_info()['releases']
+    release_hash = get_release_hash(version, releases_info)
+    if release_hash:
+        # Known release hash
+        full_name = f'{sdk}releases-{release_hash}-64bit'
+        print(f"Resolving SDK version '{version}' to '{full_name}'")
+        return full_name
 
-  if len(version) == 40:
-    global extra_release_tag
-    extra_release_tag = version
-    return f'{sdk}releases-{version}-64bit'
+    if len(version) == 40:
+        global extra_release_tag
+        extra_release_tag = version
+        return f'{sdk}releases-{version}-64bit'
 
-  return name
+    return name
 
 
 def main(args):  # ruff: ignore[complex-structure, too-many-return-statements, too-many-branches]
-  if not args:
-    errlog("Missing command; Type 'emsdk help' to get a list of commands.")
-    return 1
-
-  debug_print(f'emsdk.py running under `{sys.executable}`')
-  cmd = args.pop(0)
-
-  if cmd in {'help', '--help', '-h'}:
-    print(' emsdk: Available commands:')
-
-    print('''
-   emsdk list [--old] [--deps]  - Lists all available SDKs and tools and their
-                                  current installation status. With the --old
-                                  parameter, also historical versions are
-                                  shown. If --deps is passed, displays the
-                                  composition of different SDK packages and
-                                  dependencies.
-
-   emsdk update                 - Updates emsdk to the newest version. If you have
-                                  bootstrapped emsdk via cloning directly from
-                                  GitHub, call "git pull" instead to update emsdk.
-
-   emsdk install [options] <tool 1> <tool 2> <tool 3> ...
-                                - Downloads and installs given tools or SDKs.
-                                  Options can contain:
-
-                         -j<num>: Specifies the number of cores to use when
-                                  building the tool. Default: use one less
-                                  than the # of detected cores.
-
-                  --build=<type>: Controls what kind of build of LLVM to
-                                  perform. Pass either 'Debug', 'Release',
-                                  'MinSizeRel' or 'RelWithDebInfo'. Default:
-                                  'Release'.
-
-              --generator=<type>: Specifies the CMake Generator to be used
-                                  during the build. Possible values are the
-                                  same as what your CMake supports and whether
-                                  the generator is valid depends on the tools
-                                  you have installed. Defaults to 'Unix Makefiles'
-                                  on *nix systems. If generator name is multiple
-                                  words, enclose with single or double quotes.
-
-                       --shallow: When installing tools from one of the git
-                                  development branches, this parameter can be
-                                  passed to perform a shallow git clone instead
-                                  of a full one.  This reduces the amount of
-                                  network transfer that is needed. This option
-                                  should only be used when you are interested in
-                                  downloading one of the development branches,
-                                  but are not looking to develop Emscripten
-                                  yourself.  Default: disabled, i.e. do a full
-                                  clone.
-
-                   --build-tests: If enabled, LLVM is built with internal tests
-                                  included. Pass this to enable running test
-                                  other.test_llvm_lit in the Emscripten test
-                                  suite. Default: disabled.
-             --enable-assertions: If specified, LLVM is built with assert()
-                                  checks enabled. Useful for development
-                                  purposes. Default: Enabled
-            --disable-assertions: Forces assertions off during the build.
-
-               --vs2019/--vs2022: If building from source, overrides to build
-                                  using the specified compiler. When installing
-                                  precompiled packages, this has no effect.
-                                  Note: The same compiler specifier must be
-                                  passed to the emsdk activate command to
-                                  activate the desired version.
-
-                                  Notes on building from source:
-
-                                  To pass custom CMake directives when configuring
-                                  LLVM build, specify the environment variable
-                                  LLVM_CMAKE_ARGS="param1=value1,param2=value2"
-                                  in the environment where the build is invoked.
-                                  See README.md for details.
-
-           --override-repository: Specifies the git URL to use for a given Tool. E.g.
-                                  --override-repository emscripten-main@https://github.com/<fork>/emscripten/tree/<refspec>
-
-
-   emsdk deactivate tool/sdk    - Removes the given tool or SDK from the current set of activated tools.
-
-
-   emsdk uninstall <tool/sdk>   - Removes the given tool or SDK from disk.''')
-
-    if WINDOWS:
-      print('''
-   emsdk activate [--permanent] [--system] [--build=type] [--vs2019/--vs2022] <tool/sdk>
-
-                                - Activates the given tool or SDK in the
-                                  environment of the current shell.
-
-                                - If the `--permanent` option is passed, then the environment
-                                  variables are set permanently for the current user.
-
-                                - If the `--system` option is passed, the registration
-                                  is done for all users of the system.
-                                  This needs admin privileges
-                                  (uses Machine environment variables).
-
-                                - If a custom compiler version was used to override
-                                  the compiler to use, pass the same --vs2019/--vs2022
-                                  parameter here to choose which version to activate.
-
-   emcmdprompt.bat              - Spawns a new command prompt window with the
-                                  Emscripten environment active.''')
-    else:
-      print('''   emsdk activate [--build=type] <tool/sdk>
-
-                                - Activates the given tool or SDK in the
-                                  environment of the current shell.''')
-
-    print('''
-       Both commands 'install' and 'activate' accept an optional parameter
-       '--build=type', which can be used to override what kind of installation
-       or activation to perform. Possible values for type are Debug, Release,
-       MinSizeRel or RelWithDebInfo. Note: When overriding a custom build type,
-       be sure to match the same --build= option to both 'install' and
-       'activate' commands and the invocation of 'emsdk_env', or otherwise
-       these commands will default to operating on the default build type
-       which is RelWithDebInfo.''')
-
-    print('''
-
-   Environment:
-      EMSDK_KEEP_DOWNLOADS=1     - if you want to keep the downloaded archives.
-      EMSDK_NOTTY=1              - override isatty() result (mainly to log progress).
-      EMSDK_NUM_CORES=n          - limit parallelism to n cores.
-      EMSDK_VERBOSE=1            - very verbose output, useful for debugging.
-      EMSDK_RETRY_CLEAN_BUILD=1  - performs a clean rebuild of compiled tools if
-                                   incremental build fails. Useful on CI.''')
-    return 0
-
-  def extract_bool_arg(name):
-    """Extracts a boolean command line argument from args and returns True if it was present"""
-    if name in args:
-      args.remove(name)
-      return True
-    return False
-
-  def extract_string_arg(name):
-    for i in range(len(args)):
-      if args[i] == name:
-        value = args[i + 1]
-        del args[i:i + 2]
-        return value
-
-  arg_old = extract_bool_arg('--old')
-  arg_deps = extract_bool_arg('--deps')
-  arg_permanent = extract_bool_arg('--permanent')
-  arg_global = extract_bool_arg('--global')
-  arg_system = extract_bool_arg('--system')
-  if arg_global:
-    print('--global is deprecated. Use `--system` to set the environment variables for all users')
-    arg_system = True
-  if arg_system:
-    arg_permanent = True
-  if extract_bool_arg('--embedded'):
-    errlog('embedded mode is now the only mode available')
-  if extract_bool_arg('--no-embedded'):
-    errlog('embedded mode is now the only mode available')
-    return 1
-
-  arg_notty = extract_bool_arg('--notty')
-  if arg_notty:
-    global TTY_OUTPUT
-    TTY_OUTPUT = False
-
-  # Replace meta-packages with the real package names.
-  if cmd in {'update', 'install', 'activate'}:
-    activating = cmd == 'activate'
-    args = [expand_sdk_name(a, activating=activating) for a in args]
-
-  load_em_config()
-  load_sdk_manifest()
-
-  # Apply any overrides to git branch names to clone from.
-  forked_url = extract_string_arg('--override-repository')
-  while forked_url:
-    tool_name, url_and_refspec = forked_url.split('@')
-    t = find_tool(tool_name)
-    if not t:
-      errlog(f'Failed to find tool {tool_name}')
-      return False
-    else:
-      t.url, t.git_branch, t.remote_name = parse_github_url_and_refspec(url_and_refspec)
-      debug_print(f'Reading git repository URL "{t.url}" and git branch "{t.git_branch}" for Tool "{tool_name}".')
-
-    forked_url = extract_string_arg('--override-repository')
-
-  # Process global args
-  for i in range(len(args)):
-    if args[i].startswith('--generator='):
-      build_generator = re.match(r'''^--generator=['"]?([^'"]+)['"]?$''', args[i])
-      if build_generator:
-        global CMAKE_GENERATOR
-        CMAKE_GENERATOR = build_generator.group(1)
-        args[i] = ''
-      else:
-        errlog(f"Cannot parse CMake generator string: {args[i]}. Try wrapping generator string with quotes")
+    if not args:
+        errlog("Missing command; Type 'emsdk help' to get a list of commands.")
         return 1
-    elif args[i].startswith('--build='):
-      build_type = re.match(r'^--build=(.+)$', args[i])
-      if build_type:
-        global CMAKE_BUILD_TYPE_OVERRIDE
-        build_type = build_type.group(1)
-        build_types = ['Debug', 'MinSizeRel', 'RelWithDebInfo', 'Release']
-        try:
-          build_type_index = [x.lower() for x in build_types].index(build_type.lower())
-          CMAKE_BUILD_TYPE_OVERRIDE = build_types[build_type_index]
-          args[i] = ''
-        except Exception:
-          errlog(f'Unknown CMake build type "{build_type}" specified! Please specify one of {build_types}')
-          return 1
-      else:
-        errlog(f'Invalid command line parameter {args[i]} specified!')
-        return 1
-  args = [x for x in args if x]
 
-  if cmd == 'list':
-    print('')
+    debug_print(f'emsdk.py running under `{sys.executable}`')
+    cmd = args.pop(0)
 
-    def installed_sdk_text(name):
-      sdk = find_sdk(name)
-      return 'INSTALLED' if sdk and sdk.is_installed() else ''
+    if cmd in {'help', '--help', '-h'}:
+        print(' emsdk: Available commands:')
 
-    if (LINUX or MACOS or WINDOWS) and ARCH in {'x86', 'x86_64'}:
-      print(f'The *recommended* precompiled SDK download is {find_latest_version()} ({find_latest_hash()}).')
-      print()
-      print('To install/activate it use:')
-      print('         latest')
-      print('')
-      print('This is equivalent to installing/activating:')
-      print(f'         {find_latest_version()}             {installed_sdk_text(find_latest_sdk())}')
-      print('')
-    else:
-      print('Warning: your platform does not have precompiled SDKs available.')
-      print('You may install components from source.')
-      print('')
+        print('''
+       emsdk list [--old] [--deps]  - Lists all available SDKs and tools and their
+                                      current installation status. With the --old
+                                      parameter, also historical versions are
+                                      shown. If --deps is passed, displays the
+                                      composition of different SDK packages and
+                                      dependencies.
 
-    print('All recent (non-legacy) installable versions are:')
-    releases_versions = sorted(load_releases_versions(), key=version_key, reverse=True)
-    releases_info = load_releases_info()['releases']
-    for ver in releases_versions:
-      sdk_name = f'sdk-releases-{get_release_hash(ver, releases_info)}-64bit'
-      print(f'         {ver}    {installed_sdk_text(sdk_name)}')
-    print()
+       emsdk update                 - Updates emsdk to the newest version. If you have
+                                      bootstrapped emsdk via cloning directly from
+                                      GitHub, call "git pull" instead to update emsdk.
 
-    # Use array to work around the lack of being able to mutate from enclosing
-    # function.
-    has_partially_active_tools = [False]
+       emsdk install [options] <tool 1> <tool 2> <tool 3> ...
+                                    - Downloads and installs given tools or SDKs.
+                                      Options can contain:
 
-    if sdks:
-      def find_sdks(needs_compilation):
-        s = []
-        for sdk in sdks:
-          if sdk.is_old and not arg_old:
-            continue
-          if sdk.needs_compilation() == needs_compilation:
-            s += [sdk]
-        return s
+                             -j<num>: Specifies the number of cores to use when
+                                      building the tool. Default: use one less
+                                      than the # of detected cores.
 
-      def print_sdks(s):
-        for sdk in s:
-          installed = '\tINSTALLED' if sdk.is_installed() else ''
-          active = '*' if sdk.is_active() else ' '
-          print(f'    {active}    {sdk!s: <25}{installed}')
-          if arg_deps:
-            for dep in sdk.deps:
-              print(f'          - {dep: <25}')
-        print('')
-      print('The additional following precompiled SDKs are also available for download:')
-      print_sdks(find_sdks(False))
+                      --build=<type>: Controls what kind of build of LLVM to
+                                      perform. Pass either 'Debug', 'Release',
+                                      'MinSizeRel' or 'RelWithDebInfo'. Default:
+                                      'Release'.
 
-      print('The following SDKs can be compiled from source:')
-      print_sdks(find_sdks(True))
+                  --generator=<type>: Specifies the CMake Generator to be used
+                                      during the build. Possible values are the
+                                      same as what your CMake supports and whether
+                                      the generator is valid depends on the tools
+                                      you have installed. Defaults to 'Unix Makefiles'
+                                      on *nix systems. If generator name is multiple
+                                      words, enclose with single or double quotes.
 
-    if tools:
-      def find_tools(needs_compilation):
-        t = []
-        for tool in tools:
-          if tool.is_old and not arg_old:
-            continue
-          if tool.needs_compilation() != needs_compilation:
-            continue
-          t += [tool]
-        return t
+                           --shallow: When installing tools from one of the git
+                                      development branches, this parameter can be
+                                      passed to perform a shallow git clone instead
+                                      of a full one.  This reduces the amount of
+                                      network transfer that is needed. This option
+                                      should only be used when you are interested in
+                                      downloading one of the development branches,
+                                      but are not looking to develop Emscripten
+                                      yourself.  Default: disabled, i.e. do a full
+                                      clone.
 
-      def print_tools(t):
-        for tool in t:
-          if tool.is_old and not arg_old:
-            continue
-          if tool.can_be_installed() is True:
-            installed = '\tINSTALLED' if tool.is_installed() else ''
-          else:
-            installed = '\tNot available: ' + tool.can_be_installed()
-          tool_is_active = tool.is_active()
-          tool_is_env_active = tool_is_active and tool.is_env_active()
-          if tool_is_env_active:
-            active = ' * '
-          elif tool_is_active:
-            active = '(*)'
-            has_partially_active_tools[0] = has_partially_active_tools[0] or True
-          else:
-            active = '   '
-          print(f'    {active}    {tool!s: <25}{installed}')
-        print('')
+                       --build-tests: If enabled, LLVM is built with internal tests
+                                      included. Pass this to enable running test
+                                      other.test_llvm_lit in the Emscripten test
+                                      suite. Default: disabled.
+                 --enable-assertions: If specified, LLVM is built with assert()
+                                      checks enabled. Useful for development
+                                      purposes. Default: Enabled
+                --disable-assertions: Forces assertions off during the build.
 
-      print('The following precompiled tool packages are available for download:')
-      print_tools(find_tools(needs_compilation=False))
-      print('The following tools can be compiled from source:')
-      print_tools(find_tools(needs_compilation=True))
-    else:
-      if is_emsdk_sourced_from_github():
-        print("There are no tools available. Run 'git pull' to fetch the latest set of tools.")
-      else:
-        print("There are no tools available. Run 'emsdk update' to fetch the latest set of tools.")
-      print('')
+                   --vs2019/--vs2022: If building from source, overrides to build
+                                      using the specified compiler. When installing
+                                      precompiled packages, this has no effect.
+                                      Note: The same compiler specifier must be
+                                      passed to the emsdk activate command to
+                                      activate the desired version.
 
-    print('Items marked with * are activated for the current user.')
-    if has_partially_active_tools[0]:
-      env_cmd = 'emsdk_env.bat' if WINDOWS else 'source ./emsdk_env.sh'
-      print('Items marked with (*) are selected for use, '
-            'but your current shell environment is not configured to use them. '
-            f'Type "{env_cmd}" to set up your current shell to use them' +
-            (', or call "emsdk activate --permanent <name_of_sdk>" to permanently activate them.' if WINDOWS else '.'))
-    if not arg_old:
-      print('')
-      print("To access the historical archived versions, type 'emsdk list --old'")
+                                      Notes on building from source:
 
-    print('')
-    if is_emsdk_sourced_from_github():
-      print('Run "git pull" to pull in the latest list.')
-    else:
-      print('Run "./emsdk update" to pull in the latest list.')
+                                      To pass custom CMake directives when configuring
+                                      LLVM build, specify the environment variable
+                                      LLVM_CMAKE_ARGS="param1=value1,param2=value2"
+                                      in the environment where the build is invoked.
+                                      See README.md for details.
 
-    return 0
-  elif cmd == 'construct_env':
-    # Clean up old temp file up front, in case of failure later before we get
-    # to write out the new one.
-    tools_to_activate = currently_active_tools()
-    tools_to_activate = process_tool_list(tools_to_activate)
-    env_string = construct_env(tools_to_activate, arg_system, arg_permanent)
-    if CMD or POWERSHELL:
-      write_set_env_script(env_string)
-    else:
-      sys.stdout.write(env_string)
-    return 0
-  elif cmd == 'update':
-    update_emsdk()
-    if WINDOWS:
-      # Clean up litter after old emsdk update which may have left this temp
-      # file around.
-      rmfile(sdk_path(EMSDK_SET_ENV))
-    return 0
-  elif cmd == 'update-tags':
-    errlog('`update-tags` is not longer needed.  To install the latest tot release just run `install tot`')
-    return 0
-  elif cmd in {'activate', 'deactivate'}:
-    if arg_permanent:
-      print('Registering active Emscripten environment permanently')
-      print('')
+               --override-repository: Specifies the git URL to use for a given Tool. E.g.
+                                      --override-repository emscripten-main@https://github.com/<fork>/emscripten/tree/<refspec>
 
-    tools_to_activate = currently_active_tools()
-    for arg in args:
-      tool = find_tool(arg)
-      if tool is None:
-        tool = find_sdk(arg)
-        if tool is None:
-          error_on_missing_tool(arg)
 
-      if cmd == 'activate':
-        tools_to_activate += [tool]
-      elif tool in tools_to_activate:
-        print(f'Deactivating tool {tool}.')
-        tools_to_activate.remove(tool)
-      else:
-        print(f'Tool "{arg}" was not active, no need to deactivate.')
-    if not tools_to_activate:
-      errlog('No tools/SDKs specified to activate! Usage:\n   emsdk activate tool/sdk1 [tool/sdk2] [...]')
-      return 1
-    active_tools = set_active_tools(tools_to_activate, permanently_activate=arg_permanent, system=arg_system)
-    if not active_tools:
-      errlog('No tools/SDKs found to activate! Usage:\n   emsdk activate tool/sdk1 [tool/sdk2] [...]')
-      return 1
-    if WINDOWS and not arg_permanent:
-      errlog('The changes made to environment variables only apply to the currently running shell instance. '
-             'Use the \'emsdk_env.bat\' to re-enter this environment later, '
-             'or if you\'d like to register this environment permanently, rerun this command with the option --permanent.')
-    return 0
-  elif cmd == 'install':
-    global BUILD_FOR_TESTING, ENABLE_LLVM_ASSERTIONS, CPU_CORES, GIT_CLONE_SHALLOW
+       emsdk deactivate tool/sdk    - Removes the given tool or SDK from the current set of activated tools.
 
-    # Process args
-    for i in range(len(args)):
-      if args[i].startswith('-j'):
-        multicore = re.match(r'^-j(\d+)$', args[i])
-        if multicore:
-          CPU_CORES = int(multicore.group(1))
-          args[i] = ''
+
+       emsdk uninstall <tool/sdk>   - Removes the given tool or SDK from disk.''')
+
+        if WINDOWS:
+            print('''
+         emsdk activate [--permanent] [--system] [--build=type] [--vs2019/--vs2022] <tool/sdk>
+
+                                      - Activates the given tool or SDK in the
+                                        environment of the current shell.
+
+                                      - If the `--permanent` option is passed, then the environment
+                                        variables are set permanently for the current user.
+
+                                      - If the `--system` option is passed, the registration
+                                        is done for all users of the system.
+                                        This needs admin privileges
+                                        (uses Machine environment variables).
+
+                                      - If a custom compiler version was used to override
+                                        the compiler to use, pass the same --vs2019/--vs2022
+                                        parameter here to choose which version to activate.
+
+         emcmdprompt.bat              - Spawns a new command prompt window with the
+                                        Emscripten environment active.''')
         else:
-          errlog(f'Invalid command line parameter {args[i]} specified!')
-          return 1
-      elif args[i] == '--shallow':
-        GIT_CLONE_SHALLOW = True
-        args[i] = ''
-      elif args[i] == '--build-tests':
-        BUILD_FOR_TESTING = True
-        args[i] = ''
-      elif args[i] == '--enable-assertions':
-        ENABLE_LLVM_ASSERTIONS = 'ON'
-        args[i] = ''
-      elif args[i] == '--disable-assertions':
-        ENABLE_LLVM_ASSERTIONS = 'OFF'
-        args[i] = ''
+            print('''   emsdk activate [--build=type] <tool/sdk>
+
+                                      - Activates the given tool or SDK in the
+                                        environment of the current shell.''')
+
+        print('''
+           Both commands 'install' and 'activate' accept an optional parameter
+           '--build=type', which can be used to override what kind of installation
+           or activation to perform. Possible values for type are Debug, Release,
+           MinSizeRel or RelWithDebInfo. Note: When overriding a custom build type,
+           be sure to match the same --build= option to both 'install' and
+           'activate' commands and the invocation of 'emsdk_env', or otherwise
+           these commands will default to operating on the default build type
+           which is RelWithDebInfo.''')
+
+        print('''
+
+       Environment:
+          EMSDK_KEEP_DOWNLOADS=1     - if you want to keep the downloaded archives.
+          EMSDK_NOTTY=1              - override isatty() result (mainly to log progress).
+          EMSDK_NUM_CORES=n          - limit parallelism to n cores.
+          EMSDK_VERBOSE=1            - very verbose output, useful for debugging.
+          EMSDK_RETRY_CLEAN_BUILD=1  - performs a clean rebuild of compiled tools if
+                                       incremental build fails. Useful on CI.''')
+        return 0
+
+    def extract_bool_arg(name):
+        """Extracts a boolean command line argument from args and returns True if it was present"""
+        if name in args:
+            args.remove(name)
+            return True
+        return False
+
+    def extract_string_arg(name):
+        for i in range(len(args)):
+            if args[i] == name:
+                value = args[i + 1]
+                del args[i:i + 2]
+                return value
+
+    arg_old = extract_bool_arg('--old')
+    arg_deps = extract_bool_arg('--deps')
+    arg_permanent = extract_bool_arg('--permanent')
+    arg_global = extract_bool_arg('--global')
+    arg_system = extract_bool_arg('--system')
+    if arg_global:
+        print('--global is deprecated. Use `--system` to set the environment variables for all users')
+        arg_system = True
+    if arg_system:
+        arg_permanent = True
+    if extract_bool_arg('--embedded'):
+        errlog('embedded mode is now the only mode available')
+    if extract_bool_arg('--no-embedded'):
+        errlog('embedded mode is now the only mode available')
+        return 1
+
+    arg_notty = extract_bool_arg('--notty')
+    if arg_notty:
+        global TTY_OUTPUT
+        TTY_OUTPUT = False
+
+    # Replace meta-packages with the real package names.
+    if cmd in {'update', 'install', 'activate'}:
+        activating = cmd == 'activate'
+        args = [expand_sdk_name(a, activating=activating) for a in args]
+
+    load_em_config()
+    load_sdk_manifest()
+
+    # Apply any overrides to git branch names to clone from.
+    forked_url = extract_string_arg('--override-repository')
+    while forked_url:
+        tool_name, url_and_refspec = forked_url.split('@')
+        t = find_tool(tool_name)
+        if not t:
+            errlog(f'Failed to find tool {tool_name}')
+            return False
+        else:
+            t.url, t.git_branch, t.remote_name = parse_github_url_and_refspec(url_and_refspec)
+            debug_print(f'Reading git repository URL "{t.url}" and git branch "{t.git_branch}" for Tool "{tool_name}".')
+
+        forked_url = extract_string_arg('--override-repository')
+
+    # Process global args
+    for i in range(len(args)):
+        if args[i].startswith('--generator='):
+            build_generator = re.match(r'''^--generator=['"]?([^'"]+)['"]?$''', args[i])
+            if build_generator:
+                global CMAKE_GENERATOR
+                CMAKE_GENERATOR = build_generator.group(1)
+                args[i] = ''
+            else:
+                errlog(f"Cannot parse CMake generator string: {args[i]}. Try wrapping generator string with quotes")
+                return 1
+        elif args[i].startswith('--build='):
+            build_type = re.match(r'^--build=(.+)$', args[i])
+            if build_type:
+                global CMAKE_BUILD_TYPE_OVERRIDE
+                build_type = build_type.group(1)
+                build_types = ['Debug', 'MinSizeRel', 'RelWithDebInfo', 'Release']
+                try:
+                    build_type_index = [x.lower() for x in build_types].index(build_type.lower())
+                    CMAKE_BUILD_TYPE_OVERRIDE = build_types[build_type_index]
+                    args[i] = ''
+                except Exception:
+                    errlog(f'Unknown CMake build type "{build_type}" specified! Please specify one of {build_types}')
+                    return 1
+            else:
+                errlog(f'Invalid command line parameter {args[i]} specified!')
+                return 1
     args = [x for x in args if x]
-    if not args:
-      errlog("Missing parameter. Type 'emsdk install <tool name>' to install a tool or an SDK. "
-             "Type 'emsdk list' to obtain a list of available tools. "
-             "Type 'emsdk install latest' to automatically install the newest version of the SDK.")
-      return 1
 
-    if LINUX and ARCH == 'arm64' and args != ['latest']:
-      errlog('WARNING: arm64-linux binaries are not available for all releases.')
-      errlog('See https://github.com/emscripten-core/emsdk/issues/547')
+    if cmd == 'list':
+        print('')
 
-    for t in args:
-      tool = find_tool(t)
-      if tool is None:
-        tool = find_sdk(t)
-      if tool is None:
-        error_on_missing_tool(t)
-      tool.install()
-    return 0
-  elif cmd == 'uninstall':
-    if not args:
-      errlog("Syntax error. Call 'emsdk uninstall <tool name>'. Call 'emsdk list' to obtain a list of available tools.")
-      return 1
-    tool = find_tool(args[0])
-    if tool is None:
-      errlog(f"Error: Tool by name '{args[0]}' was not found.")
-      return 1
-    tool.uninstall()
-    return 0
+        def installed_sdk_text(name):
+            sdk = find_sdk(name)
+            return 'INSTALLED' if sdk and sdk.is_installed() else ''
 
-  errlog(f"Unknown command '{cmd}' given! Type 'emsdk help' to get a list of commands.")
-  return 1
+        if (LINUX or MACOS or WINDOWS) and ARCH in {'x86', 'x86_64'}:
+            print(f'The *recommended* precompiled SDK download is {find_latest_version()} ({find_latest_hash()}).')
+            print()
+            print('To install/activate it use:')
+            print('         latest')
+            print('')
+            print('This is equivalent to installing/activating:')
+            print(f'         {find_latest_version()}             {installed_sdk_text(find_latest_sdk())}')
+            print('')
+        else:
+            print('Warning: your platform does not have precompiled SDKs available.')
+            print('You may install components from source.')
+            print('')
+
+        print('All recent (non-legacy) installable versions are:')
+        releases_versions = sorted(load_releases_versions(), key=version_key, reverse=True)
+        releases_info = load_releases_info()['releases']
+        for ver in releases_versions:
+            sdk_name = f'sdk-releases-{get_release_hash(ver, releases_info)}-64bit'
+            print(f'         {ver}    {installed_sdk_text(sdk_name)}')
+        print()
+
+        # Use array to work around the lack of being able to mutate from enclosing
+        # function.
+        has_partially_active_tools = [False]
+
+        if sdks:
+            def find_sdks(needs_compilation):
+                s = []
+                for sdk in sdks:
+                    if sdk.is_old and not arg_old:
+                        continue
+                    if sdk.needs_compilation() == needs_compilation:
+                        s += [sdk]
+                return s
+
+            def print_sdks(s):
+                for sdk in s:
+                    installed = '\tINSTALLED' if sdk.is_installed() else ''
+                    active = '*' if sdk.is_active() else ' '
+                    print(f'    {active}    {sdk!s: <25}{installed}')
+                    if arg_deps:
+                        for dep in sdk.deps:
+                            print(f'          - {dep: <25}')
+                print('')
+            print('The additional following precompiled SDKs are also available for download:')
+            print_sdks(find_sdks(False))
+
+            print('The following SDKs can be compiled from source:')
+            print_sdks(find_sdks(True))
+
+        if tools:
+            def find_tools(needs_compilation):
+                t = []
+                for tool in tools:
+                    if tool.is_old and not arg_old:
+                        continue
+                    if tool.needs_compilation() != needs_compilation:
+                        continue
+                    t += [tool]
+                return t
+
+            def print_tools(t):
+                for tool in t:
+                    if tool.is_old and not arg_old:
+                        continue
+                    if tool.can_be_installed() is True:
+                        installed = '\tINSTALLED' if tool.is_installed() else ''
+                    else:
+                        installed = '\tNot available: ' + tool.can_be_installed()
+                    tool_is_active = tool.is_active()
+                    tool_is_env_active = tool_is_active and tool.is_env_active()
+                    if tool_is_env_active:
+                        active = ' * '
+                    elif tool_is_active:
+                        active = '(*)'
+                        has_partially_active_tools[0] = has_partially_active_tools[0] or True
+                    else:
+                        active = '   '
+                    print(f'    {active}    {tool!s: <25}{installed}')
+                print('')
+
+            print('The following precompiled tool packages are available for download:')
+            print_tools(find_tools(needs_compilation=False))
+            print('The following tools can be compiled from source:')
+            print_tools(find_tools(needs_compilation=True))
+        else:
+            if is_emsdk_sourced_from_github():
+                print("There are no tools available. Run 'git pull' to fetch the latest set of tools.")
+            else:
+                print("There are no tools available. Run 'emsdk update' to fetch the latest set of tools.")
+            print('')
+
+        print('Items marked with * are activated for the current user.')
+        if has_partially_active_tools[0]:
+            env_cmd = 'emsdk_env.bat' if WINDOWS else 'source ./emsdk_env.sh'
+            print('Items marked with (*) are selected for use, '
+                  'but your current shell environment is not configured to use them. '
+                  f'Type "{env_cmd}" to set up your current shell to use them' +
+                  (', or call "emsdk activate --permanent <name_of_sdk>" to permanently activate them.' if WINDOWS else '.'))
+        if not arg_old:
+            print('')
+            print("To access the historical archived versions, type 'emsdk list --old'")
+
+        print('')
+        if is_emsdk_sourced_from_github():
+            print('Run "git pull" to pull in the latest list.')
+        else:
+            print('Run "./emsdk update" to pull in the latest list.')
+
+        return 0
+    elif cmd == 'construct_env':
+        # Clean up old temp file up front, in case of failure later before we get
+        # to write out the new one.
+        tools_to_activate = currently_active_tools()
+        tools_to_activate = process_tool_list(tools_to_activate)
+        env_string = construct_env(tools_to_activate, arg_system, arg_permanent)
+        if CMD or POWERSHELL:
+            write_set_env_script(env_string)
+        else:
+            sys.stdout.write(env_string)
+        return 0
+    elif cmd == 'update':
+        update_emsdk()
+        if WINDOWS:
+            # Clean up litter after old emsdk update which may have left this temp
+            # file around.
+            rmfile(sdk_path(EMSDK_SET_ENV))
+        return 0
+    elif cmd == 'update-tags':
+        errlog('`update-tags` is not longer needed.  To install the latest tot release just run `install tot`')
+        return 0
+    elif cmd in {'activate', 'deactivate'}:
+        if arg_permanent:
+            print('Registering active Emscripten environment permanently')
+            print('')
+
+        tools_to_activate = currently_active_tools()
+        for arg in args:
+            tool = find_tool(arg)
+            if tool is None:
+                tool = find_sdk(arg)
+                if tool is None:
+                    error_on_missing_tool(arg)
+
+            if cmd == 'activate':
+                tools_to_activate += [tool]
+            elif tool in tools_to_activate:
+                print(f'Deactivating tool {tool}.')
+                tools_to_activate.remove(tool)
+            else:
+                print(f'Tool "{arg}" was not active, no need to deactivate.')
+        if not tools_to_activate:
+            errlog('No tools/SDKs specified to activate! Usage:\n   emsdk activate tool/sdk1 [tool/sdk2] [...]')
+            return 1
+        active_tools = set_active_tools(tools_to_activate, permanently_activate=arg_permanent, system=arg_system)
+        if not active_tools:
+            errlog('No tools/SDKs found to activate! Usage:\n   emsdk activate tool/sdk1 [tool/sdk2] [...]')
+            return 1
+        if WINDOWS and not arg_permanent:
+            errlog('The changes made to environment variables only apply to the currently running shell instance. '
+                   'Use the \'emsdk_env.bat\' to re-enter this environment later, '
+                   'or if you\'d like to register this environment permanently, rerun this command with the option --permanent.')
+        return 0
+    elif cmd == 'install':
+        global BUILD_FOR_TESTING, ENABLE_LLVM_ASSERTIONS, CPU_CORES, GIT_CLONE_SHALLOW
+
+        # Process args
+        for i in range(len(args)):
+            if args[i].startswith('-j'):
+                multicore = re.match(r'^-j(\d+)$', args[i])
+                if multicore:
+                    CPU_CORES = int(multicore.group(1))
+                    args[i] = ''
+                else:
+                    errlog(f'Invalid command line parameter {args[i]} specified!')
+                    return 1
+            elif args[i] == '--shallow':
+                GIT_CLONE_SHALLOW = True
+                args[i] = ''
+            elif args[i] == '--build-tests':
+                BUILD_FOR_TESTING = True
+                args[i] = ''
+            elif args[i] == '--enable-assertions':
+                ENABLE_LLVM_ASSERTIONS = 'ON'
+                args[i] = ''
+            elif args[i] == '--disable-assertions':
+                ENABLE_LLVM_ASSERTIONS = 'OFF'
+                args[i] = ''
+        args = [x for x in args if x]
+        if not args:
+            errlog("Missing parameter. Type 'emsdk install <tool name>' to install a tool or an SDK. "
+                   "Type 'emsdk list' to obtain a list of available tools. "
+                   "Type 'emsdk install latest' to automatically install the newest version of the SDK.")
+            return 1
+
+        if LINUX and ARCH == 'arm64' and args != ['latest']:
+            errlog('WARNING: arm64-linux binaries are not available for all releases.')
+            errlog('See https://github.com/emscripten-core/emsdk/issues/547')
+
+        for t in args:
+            tool = find_tool(t)
+            if tool is None:
+                tool = find_sdk(t)
+            if tool is None:
+                error_on_missing_tool(t)
+            tool.install()
+        return 0
+    elif cmd == 'uninstall':
+        if not args:
+            errlog("Syntax error. Call 'emsdk uninstall <tool name>'. Call 'emsdk list' to obtain a list of available tools.")
+            return 1
+        tool = find_tool(args[0])
+        if tool is None:
+            errlog(f"Error: Tool by name '{args[0]}' was not found.")
+            return 1
+        tool.uninstall()
+        return 0
+
+    errlog(f"Unknown command '{cmd}' given! Type 'emsdk help' to get a list of commands.")
+    return 1
 
 
 if __name__ == '__main__':
-  try:
-    sys.exit(main(sys.argv[1:]))
-  except KeyboardInterrupt:
-    exit_with_error('aborted by user, exiting')
-    sys.exit(1)
+    try:
+        sys.exit(main(sys.argv[1:]))
+    except KeyboardInterrupt:
+        exit_with_error('aborted by user, exiting')
+        sys.exit(1)
diff --git a/pyproject.toml b/pyproject.toml
index 7ae8857..6891933 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,6 @@
 [tool.ruff]
 preview = true
 line-length = 160
-indent-width = 2
 
 lint.select = [
   "ARG",
@@ -29,8 +28,6 @@
 lint.ignore = [
   "assert-false", # See https://github.com/PyCQA/flake8-bugbear/issues/66
   "module-import-not-at-top-of-file",
-  "indentation-with-invalid-multiple", # Does not seem to honor `indent-width = 2` above
-  "indentation-with-invalid-multiple-comment", # Does not seem to honor `indent-width = 2` above
   "try-except-in-loop",
   "import-outside-top-level",
   "too-many-public-methods",
diff --git a/scripts/create_release.py b/scripts/create_release.py
index 03af2ee..81ffa8a 100755
--- a/scripts/create_release.py
+++ b/scripts/create_release.py
@@ -16,77 +16,77 @@
 
 
 def version_key(version_string):
-  parts = re.split('[.-]', version_string)
-  key = [[int(part) for part in parts[:3]], -len(parts), parts[3:]]
-  return key
+    parts = re.split('[.-]', version_string)
+    key = [[int(part) for part in parts[:3]], -len(parts), parts[3:]]
+    return key
 
 
 def main():
-  if subprocess.check_output(['git', 'status', '--porcelain'], cwd=root_dir).strip():
-    print('tree is not clean')
-    sys.exit(1)
+    if subprocess.check_output(['git', 'status', '--porcelain'], cwd=root_dir).strip():
+        print('tree is not clean')
+        sys.exit(1)
 
-  parser = argparse.ArgumentParser()
-  parser.add_argument('-r', '--release-hash')
-  parser.add_argument('-a', '--asserts-hash')
-  parser.add_argument('-v', '--new-version')
-  parser.add_argument('--gh-action', action='store_true')
-  options = parser.parse_args()
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-r', '--release-hash')
+    parser.add_argument('-a', '--asserts-hash')
+    parser.add_argument('-v', '--new-version')
+    parser.add_argument('--gh-action', action='store_true')
+    options = parser.parse_args()
 
-  release_info = emsdk.load_releases_info()
-  if options.new_version:
-    new_version = options.new_version
-  else:
-    new_version = version_key(release_info['aliases']['latest'])[0]
-    new_version[-1] += 1
-    new_version = '.'.join(str(part) for part in new_version)
+    release_info = emsdk.load_releases_info()
+    if options.new_version:
+        new_version = options.new_version
+    else:
+        new_version = version_key(release_info['aliases']['latest'])[0]
+        new_version[-1] += 1
+        new_version = '.'.join(str(part) for part in new_version)
 
-  asserts_hash = None
-  if options.release_hash:
-    new_hash = options.release_hash
-    asserts_hash = options.asserts_hash
-  else:
-    new_hash = emsdk.get_emscripten_releases_tot()
+    asserts_hash = None
+    if options.release_hash:
+        new_hash = options.release_hash
+        asserts_hash = options.asserts_hash
+    else:
+        new_hash = emsdk.get_emscripten_releases_tot()
 
-  print(f'Creating new release: {new_version} -> {new_hash}')
-  release_info['releases'][new_version] = new_hash
-  if asserts_hash:
-    asserts_name = new_version + '-asserts'
-    release_info['releases'][asserts_name] = asserts_hash
+    print(f'Creating new release: {new_version} -> {new_hash}')
+    release_info['releases'][new_version] = new_hash
+    if asserts_hash:
+        asserts_name = new_version + '-asserts'
+        release_info['releases'][asserts_name] = asserts_hash
 
-  releases = [(k, v) for k, v in release_info['releases'].items()]
-  releases.sort(key=lambda pair: version_key(pair[0]))
+    releases = [(k, v) for k, v in release_info['releases'].items()]
+    releases.sort(key=lambda pair: version_key(pair[0]))
 
-  release_info['releases'] = OrderedDict(reversed(releases))
-  release_info['aliases']['latest'] = new_version
+    release_info['releases'] = OrderedDict(reversed(releases))
+    release_info['aliases']['latest'] = new_version
 
-  with open(os.path.join(root_dir, 'emscripten-releases-tags.json'), 'w') as f:
-    f.write(json.dumps(release_info, indent=2))
-    f.write('\n')
+    with open(os.path.join(root_dir, 'emscripten-releases-tags.json'), 'w') as f:
+        f.write(json.dumps(release_info, indent=2))
+        f.write('\n')
 
-  subprocess.check_call(
-    [sys.executable, os.path.join(script_dir, 'update_bazel_workspace.py')],
-    cwd=root_dir)
+    subprocess.check_call(
+      [sys.executable, os.path.join(script_dir, 'update_bazel_workspace.py')],
+      cwd=root_dir)
 
-  branch_name = 'version_' + new_version
+    branch_name = 'version_' + new_version
 
-  if options.gh_action:  # For GitHub Actions workflows
-    with open(os.environ['GITHUB_ENV'], 'a') as f:
-      f.write(f'RELEASE_VERSION={new_version}')
-  else:  # Local use
-    # Create a new git branch
-    subprocess.check_call(['git', 'checkout', '-b', branch_name, 'origin/main'], cwd=root_dir)
+    if options.gh_action:  # For GitHub Actions workflows
+        with open(os.environ['GITHUB_ENV'], 'a') as f:
+            f.write(f'RELEASE_VERSION={new_version}')
+    else:  # Local use
+        # Create a new git branch
+        subprocess.check_call(['git', 'checkout', '-b', branch_name, 'origin/main'], cwd=root_dir)
 
-    # Create auto-generated changes to the new git branch
-    subprocess.check_call(['git', 'add', '-u', '.'], cwd=root_dir)
-    subprocess.check_call(['git', 'commit', '-m', new_version], cwd=root_dir)
-    print(f'New release created in branch: `{branch_name}`')
+        # Create auto-generated changes to the new git branch
+        subprocess.check_call(['git', 'add', '-u', '.'], cwd=root_dir)
+        subprocess.check_call(['git', 'commit', '-m', new_version], cwd=root_dir)
+        print(f'New release created in branch: `{branch_name}`')
 
-    # Push new branch to origin
-    subprocess.check_call(['git', 'push', 'origin', branch_name], cwd=root_dir)
+        # Push new branch to origin
+        subprocess.check_call(['git', 'push', 'origin', branch_name], cwd=root_dir)
 
-  return 0
+    return 0
 
 
 if __name__ == '__main__':
-  sys.exit(main())
+    sys.exit(main())
diff --git a/scripts/update_node.py b/scripts/update_node.py
index 2f99d02..b0d1ada 100755
--- a/scripts/update_node.py
+++ b/scripts/update_node.py
@@ -33,24 +33,24 @@
 
 
 def main():
-  parser = argparse.ArgumentParser(description=__doc__)
-  parser.add_argument('--upload', action='store_true', help='Upload binaries to Google Cloud Storage')
-  args = parser.parse_args()
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('--upload', action='store_true', help='Upload binaries to Google Cloud Storage')
+    args = parser.parse_args()
 
-  for suffix in suffixes:
-    filename = f'node-v{version}{suffix}'
-    download_url = base + filename
-    print('Downloading: ' + download_url)
-    urllib.request.urlretrieve(download_url, filename)
+    for suffix in suffixes:
+        filename = f'node-v{version}{suffix}'
+        download_url = base + filename
+        print('Downloading: ' + download_url)
+        urllib.request.urlretrieve(download_url, filename)
 
-    if args.upload:
-      upload_url = upload_base + filename
-      print('Uploading: ' + upload_url)
-      cmd = ['gsutil', 'cp', '-n', filename, upload_url]
-      print(' '.join(cmd))
-      subprocess.check_call(cmd)
-      os.remove(filename)
+        if args.upload:
+            upload_url = upload_base + filename
+            print('Uploading: ' + upload_url)
+            cmd = ['gsutil', 'cp', '-n', filename, upload_url]
+            print(' '.join(cmd))
+            subprocess.check_call(cmd)
+            os.remove(filename)
 
 
 if __name__ == '__main__':
-  main()
+    main()
diff --git a/scripts/update_python.py b/scripts/update_python.py
index 70bf7d1..d69c51f 100755
--- a/scripts/update_python.py
+++ b/scripts/update_python.py
@@ -84,11 +84,11 @@
     shutil.rmtree('python-nuget')
 
     if '--upload' in sys.argv:
-      upload_url = upload_base + out_filename
-      print('Uploading: ' + upload_url)
-      cmd = ['gsutil', 'cp', '-n', out_filename, upload_url]
-      print(' '.join(cmd))
-      check_call(cmd)
+        upload_url = upload_base + out_filename
+        print('Uploading: ' + upload_url)
+        cmd = ['gsutil', 'cp', '-n', out_filename, upload_url]
+        print(' '.join(cmd))
+        check_call(cmd)
 
 
 def build_python():
@@ -119,23 +119,23 @@
 
     src_dir = 'cpython'
     if os.path.exists(src_dir):
-      check_call(['git', 'fetch'], cwd=src_dir)
+        check_call(['git', 'fetch'], cwd=src_dir)
     else:
-      check_call(['git', 'clone', 'https://github.com/python/cpython'])
+        check_call(['git', 'clone', 'https://github.com/python/cpython'])
     check_call(['git', 'checkout', 'v' + version], cwd=src_dir)
 
     env = os.environ
     if sys.platform.startswith('darwin'):
-      # Specify the min OS version we want the build to work on
-      min_macos_version = '11.0'
-      min_macos_version_line = '-mmacosx-version-min=' + min_macos_version
-      build_flags = min_macos_version_line + ' -Werror=partial-availability'
-      # Build against latest SDK, but issue an error if using any API that would not work on the min OS version
-      env = env.copy()
-      env['MACOSX_DEPLOYMENT_TARGET'] = min_macos_version
-      configure_args = ['CFLAGS=' + build_flags, 'CXXFLAGS=' + build_flags, 'LDFLAGS=' + min_macos_version_line]
+        # Specify the min OS version we want the build to work on
+        min_macos_version = '11.0'
+        min_macos_version_line = '-mmacosx-version-min=' + min_macos_version
+        build_flags = min_macos_version_line + ' -Werror=partial-availability'
+        # Build against latest SDK, but issue an error if using any API that would not work on the min OS version
+        env = env.copy()
+        env['MACOSX_DEPLOYMENT_TARGET'] = min_macos_version
+        configure_args = ['CFLAGS=' + build_flags, 'CXXFLAGS=' + build_flags, 'LDFLAGS=' + min_macos_version_line]
     else:
-      configure_args = []
+        configure_args = []
     check_call(['./configure', *configure_args], cwd=src_dir, env=env)
     check_call(['make', '-j', str(multiprocessing.cpu_count())], cwd=src_dir, env=env)
     check_call(['make', 'install', 'DESTDIR=install'], cwd=src_dir, env=env)
@@ -167,8 +167,8 @@
 
     print(f'Created: {tarball}')
     if '--upload' in sys.argv:
-      print('Uploading: ' + upload_base + tarball)
-      check_call(['gsutil', 'cp', '-n', tarball, upload_base + tarball])
+        print('Uploading: ' + upload_base + tarball)
+        check_call(['gsutil', 'cp', '-n', tarball, upload_base + tarball])
 
 
 def main():
@@ -180,4 +180,4 @@
 
 
 if __name__ == '__main__':
-  sys.exit(main())
+    sys.exit(main())
diff --git a/test/test.py b/test/test.py
index 91d6e8e..5b2d601 100755
--- a/test/test.py
+++ b/test/test.py
@@ -18,98 +18,98 @@
 assert os.path.exists(emconfig)
 
 if WINDOWS:
-  emsdk = 'emsdk.bat'
+    emsdk = 'emsdk.bat'
 else:
-  emsdk = './emsdk'
+    emsdk = './emsdk'
 
 # Utilities
 
 
 def listify(x):
-  if type(x) in {list, tuple}:
-    return x
-  return [x]
+    if type(x) in {list, tuple}:
+        return x
+    return [x]
 
 
 def copy_emsdk_to(targetdir):
-  for filename in os.listdir('.'):
-    if not filename.startswith('.') and not os.path.isdir(filename):
-      shutil.copy2(filename, os.path.join(targetdir, filename))
+    for filename in os.listdir('.'):
+        if not filename.startswith('.') and not os.path.isdir(filename):
+            shutil.copy2(filename, os.path.join(targetdir, filename))
 
 
 def check_call(cmd, **kwargs):
-  if type(cmd) is not list:
-    cmd = cmd.split()
-  print(f'running: {cmd}')
-  subprocess.run(cmd, check=True, text=True, **kwargs)
+    if type(cmd) is not list:
+        cmd = cmd.split()
+    print(f'running: {cmd}')
+    subprocess.run(cmd, check=True, text=True, **kwargs)
 
 
 def checked_call_with_output(cmd, expected=None, unexpected=None, stderr=None, env=None):
-  cmd = cmd.split(' ')
-  print(f'running: {cmd}')
-  try:
-    stdout = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=stderr, check=True, text=True, env=env).stdout
-  except subprocess.CalledProcessError as e:
-    print(e.stderr)
-    print(e.stdout)
-    raise e
+    cmd = cmd.split(' ')
+    print(f'running: {cmd}')
+    try:
+        stdout = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=stderr, check=True, text=True, env=env).stdout
+    except subprocess.CalledProcessError as e:
+        print(e.stderr)
+        print(e.stdout)
+        raise e
 
-  if expected:
-    for x in listify(expected):
-      assert x in stdout, 'expected output missing: ' + stdout + '\n[[[' + x + ']]]'
-  if unexpected:
-    for x in listify(unexpected):
-      assert x not in stdout, 'unexpected output present: ' + stdout + '\n[[[' + x + ']]]'
+    if expected:
+        for x in listify(expected):
+            assert x in stdout, 'expected output missing: ' + stdout + '\n[[[' + x + ']]]'
+    if unexpected:
+        for x in listify(unexpected):
+            assert x not in stdout, 'unexpected output present: ' + stdout + '\n[[[' + x + ']]]'
 
 
 def failing_call_with_output(cmd, expected, env=None):
-  proc = subprocess.run(cmd.split(' '), capture_output=True, text=True, env=env)
-  stdout = proc.stdout
-  stderr = proc.stderr
-  if WINDOWS:
-    print('warning: skipping part of failing_call_with_output() due to error codes not being propagated (see #592)')
-  else:
-    assert proc.returncode, 'call must have failed: ' + str([stdout, '\n========\n', stderr])
-  assert expected in stdout or expected in stderr, 'call did not have the expected output: {}: {}'.format(expected, str([stdout, '\n========\n', stderr]))
+    proc = subprocess.run(cmd.split(' '), capture_output=True, text=True, env=env)
+    stdout = proc.stdout
+    stderr = proc.stderr
+    if WINDOWS:
+        print('warning: skipping part of failing_call_with_output() due to error codes not being propagated (see #592)')
+    else:
+        assert proc.returncode, 'call must have failed: ' + str([stdout, '\n========\n', stderr])
+    assert expected in stdout or expected in stderr, 'call did not have the expected output: {}: {}'.format(expected, str([stdout, '\n========\n', stderr]))
 
 
 def hack_emsdk(marker, replacement):
-  with open('emsdk.py') as f:
-    src = f.read()
-  assert marker in src
-  src = src.replace(marker, replacement)
-  name = '__test_emsdk'
-  with open(name, 'w') as f:
-    f.write(src)
-  return name
+    with open('emsdk.py') as f:
+        src = f.read()
+    assert marker in src
+    src = src.replace(marker, replacement)
+    name = '__test_emsdk'
+    with open(name, 'w') as f:
+        f.write(src)
+    return name
 
 
 def get_longest_path_in_dir(dirname):
-  longest = ''
-  for root, _dirs, files in os.walk(dirname):
-    for f in files:
-      fullname = os.path.join(root, f)
-      if len(fullname) > len(longest):
-        longest = fullname
-  return longest
+    longest = ''
+    for root, _dirs, files in os.walk(dirname):
+        for f in files:
+            fullname = os.path.join(root, f)
+            if len(fullname) > len(longest):
+                longest = fullname
+    return longest
 
 
 def remove_file(filename):
-  if os.path.exists(filename):
-    os.remove(filename)
+    if os.path.exists(filename):
+        os.remove(filename)
 
 
 def remove_tree(path):
-  if not os.path.exists(path):
-    return
-  if WINDOWS:
-    path = '\\\\?\\' + path
+    if not os.path.exists(path):
+        return
+    if WINDOWS:
+        path = '\\\\?\\' + path
 
-  def remove_readonly(func, path2, _):
-    os.chmod(path2, stat.S_IRWXU)
-    func(path2)
+    def remove_readonly(func, path2, _):
+        os.chmod(path2, stat.S_IRWXU)
+        func(path2)
 
-  shutil.rmtree(path, onerror=remove_readonly)
+    shutil.rmtree(path, onerror=remove_readonly)
 
 
 # Set up
@@ -120,281 +120,281 @@
 
 
 def do_lib_building(emcc):
-  cache_building_messages = ['generating system library: ']
+    cache_building_messages = ['generating system library: ']
 
-  def do_build(args, is_expected=None):
-    unexpected = None
-    expected = None
-    if is_expected is True:
-      expected = cache_building_messages
-    elif is_expected is False:
-      unexpected = cache_building_messages
-    checked_call_with_output(emcc + ' hello_world.c' + args,
-                             expected=expected,
-                             unexpected=unexpected,
-                             stderr=subprocess.STDOUT)
+    def do_build(args, is_expected=None):
+        unexpected = None
+        expected = None
+        if is_expected is True:
+            expected = cache_building_messages
+        elif is_expected is False:
+            unexpected = cache_building_messages
+        checked_call_with_output(emcc + ' hello_world.c' + args,
+                                 expected=expected,
+                                 unexpected=unexpected,
+                                 stderr=subprocess.STDOUT)
 
-  # The emsdk ships all system libraries so we don't expect to see any
-  # cache population unless we explicly --clear-cache.
-  do_build('', is_expected=False)
-  check_call(emcc + ' --clear-cache')
-  do_build(' -O2', is_expected=True)
-  # Do another build at -O0.  In nwers SDK versions this generates
-  # different libs, but not in older ones so don't assert here.
-  do_build('')
-  # Now verify that libs are *not* build
-  do_build(' -s WASM=0', is_expected=False)
-  do_build(' -O2 -s WASM=0', is_expected=False)
+    # The emsdk ships all system libraries so we don't expect to see any
+    # cache population unless we explicly --clear-cache.
+    do_build('', is_expected=False)
+    check_call(emcc + ' --clear-cache')
+    do_build(' -O2', is_expected=True)
+    # Do another build at -O0.  In nwers SDK versions this generates
+    # different libs, but not in older ones so don't assert here.
+    do_build('')
+    # Now verify that libs are *not* build
+    do_build(' -s WASM=0', is_expected=False)
+    do_build(' -O2 -s WASM=0', is_expected=False)
 
 
 def run_emsdk(cmd):
-  if type(cmd) is not list:
-    cmd = cmd.split()
-  check_call([emsdk, *cmd])
+    if type(cmd) is not list:
+        cmd = cmd.split()
+    check_call([emsdk, *cmd])
 
 
 def upstream_emcc(root='.'):
-  emcc = os.path.join(root, 'upstream', 'emscripten', 'emcc')
-  if WINDOWS:
-    if os.path.exists(emcc + '.exe'):
-      return emcc + '.exe'
-    else:
-      return emcc + '.bat'
-  return emcc
+    emcc = os.path.join(root, 'upstream', 'emscripten', 'emcc')
+    if WINDOWS:
+        if os.path.exists(emcc + '.exe'):
+            return emcc + '.exe'
+        else:
+            return emcc + '.bat'
+    return emcc
 
 
 class Emsdk(unittest.TestCase):
-  def setUp(self):
-    run_emsdk('install latest')
-    run_emsdk('activate latest')
-    with open('hello_world.c', 'w') as f:
-      f.write('''\
-#include <stdio.h>
+    def setUp(self):
+        run_emsdk('install latest')
+        run_emsdk('activate latest')
+        with open('hello_world.c', 'w') as f:
+            f.write('''\
+      #include <stdio.h>
 
-int main() {
-   printf("Hello, world!\\n");
-   return 0;
-}
-''')
-    self.addCleanup(remove_file, 'hello_world.c')
+      int main() {
+         printf("Hello, world!\\n");
+         return 0;
+      }
+      ''')
+        self.addCleanup(remove_file, 'hello_world.c')
 
-  def tearDown(self):
-    for f in glob.glob('a.out*'):
-      os.remove(f)
+    def tearDown(self):
+        for f in glob.glob('a.out*'):
+            os.remove(f)
 
-  def test_extrememly_long_filenames(self):
-    # We have special support for filenames longer than 256 on windows. This
-    # test installs emsdk in path that exceeds this limit in order to test
-    # this handling.
-    longpath = os.path.abspath('very_long_filename_indeed')
+    def test_extrememly_long_filenames(self):
+        # We have special support for filenames longer than 256 on windows. This
+        # test installs emsdk in path that exceeds this limit in order to test
+        # this handling.
+        longpath = os.path.abspath('very_long_filename_indeed')
 
-    additional = 140 - len(longpath)
-    longpath += 'x' * additional
+        additional = 140 - len(longpath)
+        longpath += 'x' * additional
 
-    remove_tree(longpath)
-    self.addCleanup(remove_tree, longpath)
+        remove_tree(longpath)
+        self.addCleanup(remove_tree, longpath)
 
-    os.makedirs(longpath)
-    copy_emsdk_to(longpath)
+        os.makedirs(longpath)
+        copy_emsdk_to(longpath)
 
-    emsdk = os.path.join(longpath, 'emsdk')
-    if WINDOWS:
-      emsdk += '.bat'
-    self.assertTrue(os.path.exists(emsdk))
+        emsdk = os.path.join(longpath, 'emsdk')
+        if WINDOWS:
+            emsdk += '.bat'
+        self.assertTrue(os.path.exists(emsdk))
 
-    check_call([emsdk, 'install', 'latest'])
-    check_call([emsdk, 'activate', 'latest'])
+        check_call([emsdk, 'install', 'latest'])
+        check_call([emsdk, 'activate', 'latest'])
 
-    # Check that emcc exists in the expected location
-    emcc = upstream_emcc(longpath)
-    print(emcc)
-    self.assertTrue(os.path.exists(emcc))
+        # Check that emcc exists in the expected location
+        emcc = upstream_emcc(longpath)
+        print(emcc)
+        self.assertTrue(os.path.exists(emcc))
 
-    # Find the longest installed path and assert this is longer than 256
-    longest_path = get_longest_path_in_dir(longpath)
-    print(f'longest ({len(longest_path)}: {longest_path})')
-    self.assertGreater(len(longest_path), 256)
+        # Find the longest installed path and assert this is longer than 256
+        longest_path = get_longest_path_in_dir(longpath)
+        print(f'longest ({len(longest_path)}: {longest_path})')
+        self.assertGreater(len(longest_path), 256)
 
-    # Finally make sure we can actaully compile something
-    check_call([emcc, 'hello_world.c'])
+        # Finally make sure we can actaully compile something
+        check_call([emcc, 'hello_world.c'])
 
-  def test_unknown_arch(self):
-    env = os.environ.copy()
-    env['EMSDK_ARCH'] = 'mips'
-    failing_call_with_output(emsdk + ' install latest',
-                             expected='unknown machine architecture: mips',
-                             env=env)
+    def test_unknown_arch(self):
+        env = os.environ.copy()
+        env['EMSDK_ARCH'] = 'mips'
+        failing_call_with_output(emsdk + ' install latest',
+                                 expected='unknown machine architecture: mips',
+                                 env=env)
 
-  def test_wrong_bitness(self):
-    env = os.environ.copy()
-    env['EMSDK_ARCH'] = 'x86'
-    failing_call_with_output(emsdk + ' install sdk-latest-64bit',
-                             expected='is only provided for 64-bit OSe',
-                             env=env)
+    def test_wrong_bitness(self):
+        env = os.environ.copy()
+        env['EMSDK_ARCH'] = 'x86'
+        failing_call_with_output(emsdk + ' install sdk-latest-64bit',
+                                 expected='is only provided for 64-bit OSe',
+                                 env=env)
 
-  def test_already_installed(self):
-    # Test we don't re-download unnecessarily
-    checked_call_with_output(emsdk + ' install latest', expected='already installed', unexpected='Downloading:')
+    def test_already_installed(self):
+        # Test we don't re-download unnecessarily
+        checked_call_with_output(emsdk + ' install latest', expected='already installed', unexpected='Downloading:')
 
-  def test_list(self):
-    # Test we report installed tools properly. The latest version should be
-    # installed, but not some random old one.
-    checked_call_with_output(emsdk + ' list', expected=TAGS['aliases']['latest'] + '    INSTALLED', unexpected='1.39.15    INSTALLED:')
+    def test_list(self):
+        # Test we report installed tools properly. The latest version should be
+        # installed, but not some random old one.
+        checked_call_with_output(emsdk + ' list', expected=TAGS['aliases']['latest'] + '    INSTALLED', unexpected='1.39.15    INSTALLED:')
 
-  def test_config_contents(self):
-    print('test .emscripten contents')
-    run_emsdk('install 6.0.3')
-    run_emsdk('activate 6.0.3')
-    with open(emconfig) as f:
-      config = f.read()
-    self.assertIn('upstream', config)
+    def test_config_contents(self):
+        print('test .emscripten contents')
+        run_emsdk('install 6.0.3')
+        run_emsdk('activate 6.0.3')
+        with open(emconfig) as f:
+            config = f.read()
+        self.assertIn('upstream', config)
 
-    # Older version of emscripten (prior to 6.0.3) don't support $CFGDIR
-    self.assertIn('import os', config)
-    self.assertIn('emsdk_path + ', config)
-    self.assertNotIn('$CFGDIR', config)
+        # Older version of emscripten (prior to 6.0.3) don't support $CFGDIR
+        self.assertIn('import os', config)
+        self.assertIn('emsdk_path + ', config)
+        self.assertNotIn('$CFGDIR', config)
 
-    # For newer versions we use $CFGDIR
-    version_file = os.path.join('upstream', 'emscripten', 'emscripten-version.txt')
-    with open(version_file) as f:
-      old_ver = f.read()
-    try:
-      # Hack the version file to contain 6.0.4
-      with open(version_file, 'w') as f:
-        f.write('6.0.4\n')
-      # Re-activate 6.0.3 but with the hacked version file which makes it
-      # appear to contain 6.0.4.
-      run_emsdk('activate 6.0.3')
-      with open(emconfig) as f:
-        config = f.read()
-      self.assertNotIn('import os', config)
-      self.assertNotIn('emsdk_path', config)
-      self.assertIn('$CFGDIR', config)
-    finally:
-      with open(version_file, 'w') as f:
-        f.write(old_ver)
-      run_emsdk('activate 6.0.3')
+        # For newer versions we use $CFGDIR
+        version_file = os.path.join('upstream', 'emscripten', 'emscripten-version.txt')
+        with open(version_file) as f:
+            old_ver = f.read()
+        try:
+            # Hack the version file to contain 6.0.4
+            with open(version_file, 'w') as f:
+                f.write('6.0.4\n')
+            # Re-activate 6.0.3 but with the hacked version file which makes it
+            # appear to contain 6.0.4.
+            run_emsdk('activate 6.0.3')
+            with open(emconfig) as f:
+                config = f.read()
+            self.assertNotIn('import os', config)
+            self.assertNotIn('emsdk_path', config)
+            self.assertIn('$CFGDIR', config)
+        finally:
+            with open(version_file, 'w') as f:
+                f.write(old_ver)
+            run_emsdk('activate 6.0.3')
 
-  def test_lib_building(self):
-    print('building proper system libraries')
-    do_lib_building(upstream_emcc())
+    def test_lib_building(self):
+        print('building proper system libraries')
+        do_lib_building(upstream_emcc())
 
-  def test_redownload(self):
-    print('go back to using upstream')
-    run_emsdk('activate latest')
+    def test_redownload(self):
+        print('go back to using upstream')
+        run_emsdk('activate latest')
 
-    # Test the normal tools like node don't re-download on re-install
-    print('another install must re-download')
-    checked_call_with_output(emsdk + ' uninstall node-24.19.0-64bit')
-    checked_call_with_output(emsdk + ' install node-24.19.0-64bit', expected='Downloading:', unexpected='already installed')
-    checked_call_with_output(emsdk + ' install node-24.19.0-64bit', unexpected='Downloading:', expected='already installed')
+        # Test the normal tools like node don't re-download on re-install
+        print('another install must re-download')
+        checked_call_with_output(emsdk + ' uninstall node-24.19.0-64bit')
+        checked_call_with_output(emsdk + ' install node-24.19.0-64bit', expected='Downloading:', unexpected='already installed')
+        checked_call_with_output(emsdk + ' install node-24.19.0-64bit', unexpected='Downloading:', expected='already installed')
 
-  def test_tot_upstream(self):
-    print('test tot-upstream')
-    run_emsdk('install tot-upstream')
-    with open(emconfig) as f:
-      config = f.read()
-    run_emsdk('activate tot-upstream')
-    self.addCleanup(remove_file, emconfig + '.old')
-    with open(emconfig + '.old') as f:
-      old_config = f.read()
-    self.assertEqual(config, old_config)
-    # TODO; test on latest as well
-    check_call(upstream_emcc() + ' hello_world.c')
+    def test_tot_upstream(self):
+        print('test tot-upstream')
+        run_emsdk('install tot-upstream')
+        with open(emconfig) as f:
+            config = f.read()
+        run_emsdk('activate tot-upstream')
+        self.addCleanup(remove_file, emconfig + '.old')
+        with open(emconfig + '.old') as f:
+            old_config = f.read()
+        self.assertEqual(config, old_config)
+        # TODO; test on latest as well
+        check_call(upstream_emcc() + ' hello_world.c')
 
-  def test_closure(self):
-    # Specifically test with `--closure` so we know that node_modules is working
-    check_call(upstream_emcc() + ' hello_world.c --closure=1')
+    def test_closure(self):
+        # Specifically test with `--closure` so we know that node_modules is working
+        check_call(upstream_emcc() + ' hello_world.c --closure=1')
 
-  def test_specific_version(self):
-    if MACOS_ARM64:
-      self.skipTest('Old sdk versions do not have ARM64 binaries')
-    print('test specific release (new, short name)')
-    run_emsdk('install 1.38.33')
-    print('another install, but no need for re-download')
-    checked_call_with_output(emsdk + ' install 1.38.33', expected='Skipped', unexpected='Downloading:')
-    run_emsdk('activate 1.38.33')
+    def test_specific_version(self):
+        if MACOS_ARM64:
+            self.skipTest('Old sdk versions do not have ARM64 binaries')
+        print('test specific release (new, short name)')
+        run_emsdk('install 1.38.33')
+        print('another install, but no need for re-download')
+        checked_call_with_output(emsdk + ' install 1.38.33', expected='Skipped', unexpected='Downloading:')
+        run_emsdk('activate 1.38.33')
 
-  def test_specific_version_full(self):
-    if MACOS_ARM64:
-      self.skipTest('Old sdk versions do not have ARM64 binaries')
-    print('test specific release (new, full name)')
-    run_emsdk('install sdk-1.38.33-64bit')
-    run_emsdk('activate sdk-1.38.33-64bit')
-    print('test specific release (new, tag name)')
-    run_emsdk('install sdk-tag-1.38.33-64bit')
-    run_emsdk('activate sdk-tag-1.38.33-64bit')
+    def test_specific_version_full(self):
+        if MACOS_ARM64:
+            self.skipTest('Old sdk versions do not have ARM64 binaries')
+        print('test specific release (new, full name)')
+        run_emsdk('install sdk-1.38.33-64bit')
+        run_emsdk('activate sdk-1.38.33-64bit')
+        print('test specific release (new, tag name)')
+        run_emsdk('install sdk-tag-1.38.33-64bit')
+        run_emsdk('activate sdk-tag-1.38.33-64bit')
 
-  def test_binaryen_from_source(self):
-    if WINDOWS:
-      # It takes over 30 mins to build binaryen using Visual Studio in CI
-      self.skipTest('test is too slow under windows')
-    run_emsdk(['install', '--build=Release', 'binaryen-main-64bit'])
+    def test_binaryen_from_source(self):
+        if WINDOWS:
+            # It takes over 30 mins to build binaryen using Visual Studio in CI
+            self.skipTest('test is too slow under windows')
+        run_emsdk(['install', '--build=Release', 'binaryen-main-64bit'])
 
-  def test_no_32bit(self):
-    print('test 32-bit error')
-    emsdk_hacked = hack_emsdk('not is_os_64bit()', 'True')
-    self.addCleanup(remove_file, emsdk_hacked)
-    failing_call_with_output(f'{sys.executable} {emsdk_hacked} install latest',
-                             'this tool is only provided for 64-bit OSes')
+    def test_no_32bit(self):
+        print('test 32-bit error')
+        emsdk_hacked = hack_emsdk('not is_os_64bit()', 'True')
+        self.addCleanup(remove_file, emsdk_hacked)
+        failing_call_with_output(f'{sys.executable} {emsdk_hacked} install latest',
+                                 'this tool is only provided for 64-bit OSes')
 
-  def test_update_no_git(self):
-    print('test non-git update')
+    def test_update_no_git(self):
+        print('test non-git update')
 
-    temp_dir = tempfile.mkdtemp()
-    self.addCleanup(remove_tree, temp_dir)
-    copy_emsdk_to(temp_dir)
+        temp_dir = tempfile.mkdtemp()
+        self.addCleanup(remove_tree, temp_dir)
+        copy_emsdk_to(temp_dir)
 
-    olddir = os.getcwd()
-    try:
-      os.chdir(temp_dir)
-      run_emsdk('update')
+        olddir = os.getcwd()
+        try:
+            os.chdir(temp_dir)
+            run_emsdk('update')
 
-      print('second time')
-      run_emsdk('update')
-    finally:
-      os.chdir(olddir)
+            print('second time')
+            run_emsdk('update')
+        finally:
+            os.chdir(olddir)
 
-  def test_install_arbitrary(self):
-    # Test that its possible to install arbrary emscripten-releases SDKs
-    run_emsdk('install 1b7f7bc6002a3ca73647f41fc10e1fac7f06f804')
+    def test_install_arbitrary(self):
+        # Test that its possible to install arbrary emscripten-releases SDKs
+        run_emsdk('install 1b7f7bc6002a3ca73647f41fc10e1fac7f06f804')
 
-    # Check that its not re-downloaded
-    checked_call_with_output(emsdk + ' install 1b7f7bc6002a3ca73647f41fc10e1fac7f06f804', expected='Skipped', unexpected='Downloading:')
+        # Check that its not re-downloaded
+        checked_call_with_output(emsdk + ' install 1b7f7bc6002a3ca73647f41fc10e1fac7f06f804', expected='Skipped', unexpected='Downloading:')
 
-  def test_install_tool(self):
-    # Test that its possible to install emscripten as tool instead of SDK
-    checked_call_with_output(emsdk + ' install releases-77b065ace39e6ab21446e13f92897f956c80476a', unexpected='Installing SDK')
+    def test_install_tool(self):
+        # Test that its possible to install emscripten as tool instead of SDK
+        checked_call_with_output(emsdk + ' install releases-77b065ace39e6ab21446e13f92897f956c80476a', unexpected='Installing SDK')
 
-  def test_activate_missing(self):
-    run_emsdk('install latest')
-    expected = "error: tool is not installed and therefore cannot be activated: 'releases-13e29bd55185e3c12802bc090b4507901856b2ba-64bit'"
-    failing_call_with_output(emsdk + ' activate 2.0.1', expected=expected)
+    def test_activate_missing(self):
+        run_emsdk('install latest')
+        expected = "error: tool is not installed and therefore cannot be activated: 'releases-13e29bd55185e3c12802bc090b4507901856b2ba-64bit'"
+        failing_call_with_output(emsdk + ' activate 2.0.1', expected=expected)
 
-  def test_keep_downloads(self):
-    env = os.environ.copy()
-    env['EMSDK_KEEP_DOWNLOADS'] = '1'
-    # With EMSDK_KEEP_DOWNLOADS the downloading should happen on the first
-    # install of 2.0.28, and again when we install 2.0.29, but not on the
-    # second install of 2.0.28 because the zip should already be local.
-    shutil.rmtree('downloads')
-    checked_call_with_output(emsdk + ' install 3.1.54', expected='Downloading:', env=env)
-    checked_call_with_output(emsdk + ' install 3.1.55', expected='Downloading:', env=env)
-    checked_call_with_output(emsdk + ' install 3.1.54', expected='already downloaded, skipping', unexpected='Downloading:', env=env)
+    def test_keep_downloads(self):
+        env = os.environ.copy()
+        env['EMSDK_KEEP_DOWNLOADS'] = '1'
+        # With EMSDK_KEEP_DOWNLOADS the downloading should happen on the first
+        # install of 2.0.28, and again when we install 2.0.29, but not on the
+        # second install of 2.0.28 because the zip should already be local.
+        shutil.rmtree('downloads')
+        checked_call_with_output(emsdk + ' install 3.1.54', expected='Downloading:', env=env)
+        checked_call_with_output(emsdk + ' install 3.1.55', expected='Downloading:', env=env)
+        checked_call_with_output(emsdk + ' install 3.1.54', expected='already downloaded, skipping', unexpected='Downloading:', env=env)
 
-  def test_unicode_path(self):
-    temp_dir = tempfile.mkdtemp(prefix='test_työpöytä_')
-    self.addCleanup(remove_tree, temp_dir)
-    copy_emsdk_to(temp_dir)
+    def test_unicode_path(self):
+        temp_dir = tempfile.mkdtemp(prefix='test_työpöytä_')
+        self.addCleanup(remove_tree, temp_dir)
+        copy_emsdk_to(temp_dir)
 
-    olddir = os.getcwd()
-    try:
-      os.chdir(temp_dir)
-      run_emsdk('list')
-      run_emsdk('construct_env')
-    finally:
-      os.chdir(olddir)
+        olddir = os.getcwd()
+        try:
+            os.chdir(temp_dir)
+            run_emsdk('list')
+            run_emsdk('construct_env')
+        finally:
+            os.chdir(olddir)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
