about summary refs log tree commit diff
path: root/src/bootstrap/configure.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/configure.py')
-rwxr-xr-xsrc/bootstrap/configure.py519
1 files changed, 350 insertions, 169 deletions
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 70f4e70962a..71750022145 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -6,11 +6,12 @@ from __future__ import absolute_import, division, print_function
 import shlex
 import sys
 import os
+
 rust_dir = os.path.dirname(os.path.abspath(__file__))
 rust_dir = os.path.dirname(rust_dir)
 rust_dir = os.path.dirname(rust_dir)
 sys.path.append(os.path.join(rust_dir, "src", "bootstrap"))
-import bootstrap # noqa: E402
+import bootstrap  # noqa: E402
 
 
 class Option(object):
@@ -32,26 +33,62 @@ def v(*args):
     options.append(Option(*args, value=True))
 
 
-o("debug", "rust.debug", "enables debugging environment; does not affect optimization of bootstrapped code")
+o(
+    "debug",
+    "rust.debug",
+    "enables debugging environment; does not affect optimization of bootstrapped code",
+)
 o("docs", "build.docs", "build standard library documentation")
 o("compiler-docs", "build.compiler-docs", "build compiler documentation")
 o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
 o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests")
-o("ccache", "llvm.ccache", "invoke gcc/clang via ccache to reuse object files between builds")
+o(
+    "ccache",
+    "llvm.ccache",
+    "invoke gcc/clang via ccache to reuse object files between builds",
+)
 o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds")
 o("local-rust", None, "use an installed rustc rather than downloading a snapshot")
 v("local-rust-root", None, "set prefix for local rust binary")
-o("local-rebuild", "build.local-rebuild", "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version")
-o("llvm-static-stdcpp", "llvm.static-libstdcpp", "statically link to libstdc++ for LLVM")
-o("llvm-link-shared", "llvm.link-shared", "prefer shared linking to LLVM (llvm-config --link-shared)")
+o(
+    "local-rebuild",
+    "build.local-rebuild",
+    "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version",
+)
+o(
+    "llvm-static-stdcpp",
+    "llvm.static-libstdcpp",
+    "statically link to libstdc++ for LLVM",
+)
+o(
+    "llvm-link-shared",
+    "llvm.link-shared",
+    "prefer shared linking to LLVM (llvm-config --link-shared)",
+)
 o("rpath", "rust.rpath", "build rpaths into rustc itself")
 o("codegen-tests", "rust.codegen-tests", "run the tests/codegen tests")
-o("ninja", "llvm.ninja", "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)")
+o(
+    "ninja",
+    "llvm.ninja",
+    "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)",
+)
 o("locked-deps", "build.locked-deps", "force Cargo.lock to be up to date")
 o("vendor", "build.vendor", "enable usage of vendored Rust crates")
-o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, dfsan, lsan, msan, tsan, hwasan)")
-o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
-o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
+o(
+    "sanitizers",
+    "build.sanitizers",
+    "build the sanitizer runtimes (asan, dfsan, lsan, msan, tsan, hwasan)",
+)
+o(
+    "dist-src",
+    "rust.dist-src",
+    "when building tarballs enables building a source tarball",
+)
+o(
+    "cargo-native-static",
+    "build.cargo-native-static",
+    "static native libraries in cargo",
+)
 o("profiler", "build.profiler", "build the profiler runtime")
 o("full-tools", None, "enable all tools")
 o("lld", "rust.lld", "build lld")
@@ -59,7 +96,11 @@ o("llvm-bitcode-linker", "rust.llvm-bitcode-linker", "build llvm bitcode linker"
 o("clang", "llvm.clang", "build clang")
 o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
 o("control-flow-guard", "rust.control-flow-guard", "Enable Control Flow Guard")
-o("patch-binaries-for-nix", "build.patch-binaries-for-nix", "whether patch binaries for usage with Nix toolchains")
+o(
+    "patch-binaries-for-nix",
+    "build.patch-binaries-for-nix",
+    "whether patch binaries for usage with Nix toolchains",
+)
 o("new-symbol-mangling", "rust.new-symbol-mangling", "use symbol-mangling-version v0")
 
 v("llvm-cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
@@ -76,16 +117,48 @@ o("llvm-enzyme", "llvm.enzyme", "build LLVM with enzyme")
 o("llvm-offload", "llvm.offload", "build LLVM with gpu offload support")
 o("llvm-plugins", "llvm.plugins", "build LLVM with plugin interface")
 o("debug-assertions", "rust.debug-assertions", "build with debugging assertions")
-o("debug-assertions-std", "rust.debug-assertions-std", "build the standard library with debugging assertions")
+o(
+    "debug-assertions-std",
+    "rust.debug-assertions-std",
+    "build the standard library with debugging assertions",
+)
 o("overflow-checks", "rust.overflow-checks", "build with overflow checks")
-o("overflow-checks-std", "rust.overflow-checks-std", "build the standard library with overflow checks")
-o("llvm-release-debuginfo", "llvm.release-debuginfo", "build LLVM with debugger metadata")
+o(
+    "overflow-checks-std",
+    "rust.overflow-checks-std",
+    "build the standard library with overflow checks",
+)
+o(
+    "llvm-release-debuginfo",
+    "llvm.release-debuginfo",
+    "build LLVM with debugger metadata",
+)
 v("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code")
-v("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler")
-v("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library")
-v("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools")
-v("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest")
-v("save-toolstates", "rust.save-toolstates", "save build and test status of external tools into this file")
+v(
+    "debuginfo-level-rustc",
+    "rust.debuginfo-level-rustc",
+    "debuginfo level for the compiler",
+)
+v(
+    "debuginfo-level-std",
+    "rust.debuginfo-level-std",
+    "debuginfo level for the standard library",
+)
+v(
+    "debuginfo-level-tools",
+    "rust.debuginfo-level-tools",
+    "debuginfo level for the tools",
+)
+v(
+    "debuginfo-level-tests",
+    "rust.debuginfo-level-tests",
+    "debuginfo level for the test suites run with compiletest",
+)
+v(
+    "save-toolstates",
+    "rust.save-toolstates",
+    "save build and test status of external tools into this file",
+)
 
 v("prefix", "install.prefix", "set installation prefix")
 v("localstatedir", "install.localstatedir", "local state directory")
@@ -102,50 +175,117 @@ v("llvm-config", None, "set path to llvm-config")
 v("llvm-filecheck", None, "set path to LLVM's FileCheck utility")
 v("python", "build.python", "set path to python")
 v("android-ndk", "build.android-ndk", "set path to Android NDK")
-v("musl-root", "target.x86_64-unknown-linux-musl.musl-root",
-  "MUSL root installation directory (deprecated)")
-v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root",
-  "x86_64-unknown-linux-musl install directory")
-v("musl-root-i586", "target.i586-unknown-linux-musl.musl-root",
-  "i586-unknown-linux-musl install directory")
-v("musl-root-i686", "target.i686-unknown-linux-musl.musl-root",
-  "i686-unknown-linux-musl install directory")
-v("musl-root-arm", "target.arm-unknown-linux-musleabi.musl-root",
-  "arm-unknown-linux-musleabi install directory")
-v("musl-root-armhf", "target.arm-unknown-linux-musleabihf.musl-root",
-  "arm-unknown-linux-musleabihf install directory")
-v("musl-root-armv5te", "target.armv5te-unknown-linux-musleabi.musl-root",
-  "armv5te-unknown-linux-musleabi install directory")
-v("musl-root-armv7", "target.armv7-unknown-linux-musleabi.musl-root",
-  "armv7-unknown-linux-musleabi install directory")
-v("musl-root-armv7hf", "target.armv7-unknown-linux-musleabihf.musl-root",
-  "armv7-unknown-linux-musleabihf install directory")
-v("musl-root-aarch64", "target.aarch64-unknown-linux-musl.musl-root",
-  "aarch64-unknown-linux-musl install directory")
-v("musl-root-mips", "target.mips-unknown-linux-musl.musl-root",
-  "mips-unknown-linux-musl install directory")
-v("musl-root-mipsel", "target.mipsel-unknown-linux-musl.musl-root",
-  "mipsel-unknown-linux-musl install directory")
-v("musl-root-mips64", "target.mips64-unknown-linux-muslabi64.musl-root",
-  "mips64-unknown-linux-muslabi64 install directory")
-v("musl-root-mips64el", "target.mips64el-unknown-linux-muslabi64.musl-root",
-  "mips64el-unknown-linux-muslabi64 install directory")
-v("musl-root-riscv32gc", "target.riscv32gc-unknown-linux-musl.musl-root",
-  "riscv32gc-unknown-linux-musl install directory")
-v("musl-root-riscv64gc", "target.riscv64gc-unknown-linux-musl.musl-root",
-  "riscv64gc-unknown-linux-musl install directory")
-v("musl-root-loongarch64", "target.loongarch64-unknown-linux-musl.musl-root",
-  "loongarch64-unknown-linux-musl install directory")
-v("qemu-armhf-rootfs", "target.arm-unknown-linux-gnueabihf.qemu-rootfs",
-  "rootfs in qemu testing, you probably don't want to use this")
-v("qemu-aarch64-rootfs", "target.aarch64-unknown-linux-gnu.qemu-rootfs",
-  "rootfs in qemu testing, you probably don't want to use this")
-v("qemu-riscv64-rootfs", "target.riscv64gc-unknown-linux-gnu.qemu-rootfs",
-  "rootfs in qemu testing, you probably don't want to use this")
-v("experimental-targets", "llvm.experimental-targets",
-  "experimental LLVM targets to build")
+v(
+    "musl-root",
+    "target.x86_64-unknown-linux-musl.musl-root",
+    "MUSL root installation directory (deprecated)",
+)
+v(
+    "musl-root-x86_64",
+    "target.x86_64-unknown-linux-musl.musl-root",
+    "x86_64-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-i586",
+    "target.i586-unknown-linux-musl.musl-root",
+    "i586-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-i686",
+    "target.i686-unknown-linux-musl.musl-root",
+    "i686-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-arm",
+    "target.arm-unknown-linux-musleabi.musl-root",
+    "arm-unknown-linux-musleabi install directory",
+)
+v(
+    "musl-root-armhf",
+    "target.arm-unknown-linux-musleabihf.musl-root",
+    "arm-unknown-linux-musleabihf install directory",
+)
+v(
+    "musl-root-armv5te",
+    "target.armv5te-unknown-linux-musleabi.musl-root",
+    "armv5te-unknown-linux-musleabi install directory",
+)
+v(
+    "musl-root-armv7",
+    "target.armv7-unknown-linux-musleabi.musl-root",
+    "armv7-unknown-linux-musleabi install directory",
+)
+v(
+    "musl-root-armv7hf",
+    "target.armv7-unknown-linux-musleabihf.musl-root",
+    "armv7-unknown-linux-musleabihf install directory",
+)
+v(
+    "musl-root-aarch64",
+    "target.aarch64-unknown-linux-musl.musl-root",
+    "aarch64-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-mips",
+    "target.mips-unknown-linux-musl.musl-root",
+    "mips-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-mipsel",
+    "target.mipsel-unknown-linux-musl.musl-root",
+    "mipsel-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-mips64",
+    "target.mips64-unknown-linux-muslabi64.musl-root",
+    "mips64-unknown-linux-muslabi64 install directory",
+)
+v(
+    "musl-root-mips64el",
+    "target.mips64el-unknown-linux-muslabi64.musl-root",
+    "mips64el-unknown-linux-muslabi64 install directory",
+)
+v(
+    "musl-root-riscv32gc",
+    "target.riscv32gc-unknown-linux-musl.musl-root",
+    "riscv32gc-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-riscv64gc",
+    "target.riscv64gc-unknown-linux-musl.musl-root",
+    "riscv64gc-unknown-linux-musl install directory",
+)
+v(
+    "musl-root-loongarch64",
+    "target.loongarch64-unknown-linux-musl.musl-root",
+    "loongarch64-unknown-linux-musl install directory",
+)
+v(
+    "qemu-armhf-rootfs",
+    "target.arm-unknown-linux-gnueabihf.qemu-rootfs",
+    "rootfs in qemu testing, you probably don't want to use this",
+)
+v(
+    "qemu-aarch64-rootfs",
+    "target.aarch64-unknown-linux-gnu.qemu-rootfs",
+    "rootfs in qemu testing, you probably don't want to use this",
+)
+v(
+    "qemu-riscv64-rootfs",
+    "target.riscv64gc-unknown-linux-gnu.qemu-rootfs",
+    "rootfs in qemu testing, you probably don't want to use this",
+)
+v(
+    "experimental-targets",
+    "llvm.experimental-targets",
+    "experimental LLVM targets to build",
+)
 v("release-channel", "rust.channel", "the name of the release channel to build")
-v("release-description", "rust.description", "optional descriptive string for version output")
+v(
+    "release-description",
+    "rust.description",
+    "optional descriptive string for version output",
+)
 v("dist-compression-formats", None, "List of compression formats to use")
 
 # Used on systems where "cc" is unavailable
@@ -154,7 +294,11 @@ v("default-linker", "rust.default-linker", "the default linker")
 # Many of these are saved below during the "writing configuration" step
 # (others are conditionally saved).
 o("manage-submodules", "build.submodules", "let the build manage the git submodules")
-o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two (not recommended except for testing reproducible builds)")
+o(
+    "full-bootstrap",
+    "build.full-bootstrap",
+    "build three compilers instead of two (not recommended except for testing reproducible builds)",
+)
 o("extended", "build.extended", "build an extended rust tool set")
 
 v("bootstrap-cache-path", None, "use provided path for the bootstrap cache")
@@ -165,8 +309,16 @@ v("host", None, "List of GNUs ./configure syntax LLVM host triples")
 v("target", None, "List of GNUs ./configure syntax LLVM target triples")
 
 # Options specific to this configure script
-o("option-checking", None, "complain about unrecognized options in this configure script")
-o("verbose-configure", None, "don't truncate options when printing them in this configure script")
+o(
+    "option-checking",
+    None,
+    "complain about unrecognized options in this configure script",
+)
+o(
+    "verbose-configure",
+    None,
+    "don't truncate options when printing them in this configure script",
+)
 v("set", None, "set arbitrary key/value pairs in TOML configuration")
 
 
@@ -178,39 +330,42 @@ def err(msg):
     print("\nconfigure: ERROR: " + msg + "\n")
     sys.exit(1)
 
+
 def is_value_list(key):
     for option in options:
-        if option.name == key and option.desc.startswith('List of'):
+        if option.name == key and option.desc.startswith("List of"):
             return True
     return False
 
-if '--help' in sys.argv or '-h' in sys.argv:
-    print('Usage: ./configure [options]')
-    print('')
-    print('Options')
+
+if "--help" in sys.argv or "-h" in sys.argv:
+    print("Usage: ./configure [options]")
+    print("")
+    print("Options")
     for option in options:
-        if 'android' in option.name:
+        if "android" in option.name:
             # no one needs to know about these obscure options
             continue
         if option.value:
-            print('\t{:30} {}'.format('--{}=VAL'.format(option.name), option.desc))
+            print("\t{:30} {}".format("--{}=VAL".format(option.name), option.desc))
         else:
-            print('\t--enable-{:25} OR --disable-{}'.format(option.name, option.name))
-            print('\t\t' + option.desc)
-    print('')
-    print('This configure script is a thin configuration shim over the true')
-    print('configuration system, `config.toml`. You can explore the comments')
-    print('in `config.example.toml` next to this configure script to see')
-    print('more information about what each option is. Additionally you can')
-    print('pass `--set` as an argument to set arbitrary key/value pairs')
-    print('in the TOML configuration if desired')
-    print('')
-    print('Also note that all options which take `--enable` can similarly')
-    print('be passed with `--disable-foo` to forcibly disable the option')
+            print("\t--enable-{:25} OR --disable-{}".format(option.name, option.name))
+            print("\t\t" + option.desc)
+    print("")
+    print("This configure script is a thin configuration shim over the true")
+    print("configuration system, `config.toml`. You can explore the comments")
+    print("in `config.example.toml` next to this configure script to see")
+    print("more information about what each option is. Additionally you can")
+    print("pass `--set` as an argument to set arbitrary key/value pairs")
+    print("in the TOML configuration if desired")
+    print("")
+    print("Also note that all options which take `--enable` can similarly")
+    print("be passed with `--disable-foo` to forcibly disable the option")
     sys.exit(0)
 
 VERBOSE = False
 
+
 # Parse all command line arguments into one of these three lists, handling
 # boolean and value-based options separately
 def parse_args(args):
@@ -222,7 +377,7 @@ def parse_args(args):
     while i < len(args):
         arg = args[i]
         i += 1
-        if not arg.startswith('--'):
+        if not arg.startswith("--"):
             unknown_args.append(arg)
             continue
 
@@ -230,7 +385,7 @@ def parse_args(args):
         for option in options:
             value = None
             if option.value:
-                keyval = arg[2:].split('=', 1)
+                keyval = arg[2:].split("=", 1)
                 key = keyval[0]
                 if option.name != key:
                     continue
@@ -244,9 +399,9 @@ def parse_args(args):
                     need_value_args.append(arg)
                     continue
             else:
-                if arg[2:] == 'enable-' + option.name:
+                if arg[2:] == "enable-" + option.name:
                     value = True
-                elif arg[2:] == 'disable-' + option.name:
+                elif arg[2:] == "disable-" + option.name:
                     value = False
                 else:
                     continue
@@ -263,8 +418,9 @@ def parse_args(args):
     # NOTE: here and a few other places, we use [-1] to apply the *last* value
     # passed.  But if option-checking is enabled, then the known_args loop will
     # also assert that options are only passed once.
-    option_checking = ('option-checking' not in known_args
-                    or known_args['option-checking'][-1][1])
+    option_checking = (
+        "option-checking" not in known_args or known_args["option-checking"][-1][1]
+    )
     if option_checking:
         if len(unknown_args) > 0:
             err("Option '" + unknown_args[0] + "' is not recognized")
@@ -272,18 +428,18 @@ def parse_args(args):
             err("Option '{0}' needs a value ({0}=val)".format(need_value_args[0]))
 
     global VERBOSE
-    VERBOSE = 'verbose-configure' in known_args
+    VERBOSE = "verbose-configure" in known_args
 
     config = {}
 
-    set('build.configure-args', args, config)
+    set("build.configure-args", args, config)
     apply_args(known_args, option_checking, config)
     return parse_example_config(known_args, config)
 
 
 def build(known_args):
-    if 'build' in known_args:
-        return known_args['build'][-1][1]
+    if "build" in known_args:
+        return known_args["build"][-1][1]
     return bootstrap.default_build_triple(verbose=False)
 
 
@@ -291,7 +447,7 @@ def set(key, value, config):
     if isinstance(value, list):
         # Remove empty values, which value.split(',') tends to generate and
         # replace single quotes for double quotes to ensure correct parsing.
-        value = [v.replace('\'', '"') for v in value if v]
+        value = [v.replace("'", '"') for v in value if v]
 
     s = "{:20} := {}".format(key, value)
     if len(s) < 70 or VERBOSE:
@@ -310,7 +466,7 @@ def set(key, value, config):
     for i, part in enumerate(parts):
         if i == len(parts) - 1:
             if is_value_list(part) and isinstance(value, str):
-                value = value.split(',')
+                value = value.split(",")
             arr[part] = value
         else:
             if part not in arr:
@@ -321,9 +477,9 @@ def set(key, value, config):
 def apply_args(known_args, option_checking, config):
     for key in known_args:
         # The `set` option is special and can be passed a bunch of times
-        if key == 'set':
+        if key == "set":
             for _option, value in known_args[key]:
-                keyval = value.split('=', 1)
+                keyval = value.split("=", 1)
                 if len(keyval) == 1 or keyval[1] == "true":
                     value = True
                 elif keyval[1] == "false":
@@ -348,50 +504,55 @@ def apply_args(known_args, option_checking, config):
         # that here.
         build_triple = build(known_args)
 
-        if option.name == 'sccache':
-            set('llvm.ccache', 'sccache', config)
-        elif option.name == 'local-rust':
-            for path in os.environ['PATH'].split(os.pathsep):
-                if os.path.exists(path + '/rustc'):
-                    set('build.rustc', path + '/rustc', config)
+        if option.name == "sccache":
+            set("llvm.ccache", "sccache", config)
+        elif option.name == "local-rust":
+            for path in os.environ["PATH"].split(os.pathsep):
+                if os.path.exists(path + "/rustc"):
+                    set("build.rustc", path + "/rustc", config)
                     break
-            for path in os.environ['PATH'].split(os.pathsep):
-                if os.path.exists(path + '/cargo'):
-                    set('build.cargo', path + '/cargo', config)
+            for path in os.environ["PATH"].split(os.pathsep):
+                if os.path.exists(path + "/cargo"):
+                    set("build.cargo", path + "/cargo", config)
                     break
-        elif option.name == 'local-rust-root':
-            set('build.rustc', value + '/bin/rustc', config)
-            set('build.cargo', value + '/bin/cargo', config)
-        elif option.name == 'llvm-root':
-            set('target.{}.llvm-config'.format(build_triple), value + '/bin/llvm-config', config)
-        elif option.name == 'llvm-config':
-            set('target.{}.llvm-config'.format(build_triple), value, config)
-        elif option.name == 'llvm-filecheck':
-            set('target.{}.llvm-filecheck'.format(build_triple), value, config)
-        elif option.name == 'tools':
-            set('build.tools', value.split(','), config)
-        elif option.name == 'bootstrap-cache-path':
-            set('build.bootstrap-cache-path', value, config)
-        elif option.name == 'codegen-backends':
-            set('rust.codegen-backends', value.split(','), config)
-        elif option.name == 'host':
-            set('build.host', value.split(','), config)
-        elif option.name == 'target':
-            set('build.target', value.split(','), config)
-        elif option.name == 'full-tools':
-            set('rust.codegen-backends', ['llvm'], config)
-            set('rust.lld', True, config)
-            set('rust.llvm-tools', True, config)
-            set('rust.llvm-bitcode-linker', True, config)
-            set('build.extended', True, config)
-        elif option.name in ['option-checking', 'verbose-configure']:
+        elif option.name == "local-rust-root":
+            set("build.rustc", value + "/bin/rustc", config)
+            set("build.cargo", value + "/bin/cargo", config)
+        elif option.name == "llvm-root":
+            set(
+                "target.{}.llvm-config".format(build_triple),
+                value + "/bin/llvm-config",
+                config,
+            )
+        elif option.name == "llvm-config":
+            set("target.{}.llvm-config".format(build_triple), value, config)
+        elif option.name == "llvm-filecheck":
+            set("target.{}.llvm-filecheck".format(build_triple), value, config)
+        elif option.name == "tools":
+            set("build.tools", value.split(","), config)
+        elif option.name == "bootstrap-cache-path":
+            set("build.bootstrap-cache-path", value, config)
+        elif option.name == "codegen-backends":
+            set("rust.codegen-backends", value.split(","), config)
+        elif option.name == "host":
+            set("build.host", value.split(","), config)
+        elif option.name == "target":
+            set("build.target", value.split(","), config)
+        elif option.name == "full-tools":
+            set("rust.codegen-backends", ["llvm"], config)
+            set("rust.lld", True, config)
+            set("rust.llvm-tools", True, config)
+            set("rust.llvm-bitcode-linker", True, config)
+            set("build.extended", True, config)
+        elif option.name in ["option-checking", "verbose-configure"]:
             # this was handled above
             pass
-        elif option.name == 'dist-compression-formats':
-            set('dist.compression-formats', value.split(','), config)
+        elif option.name == "dist-compression-formats":
+            set("dist.compression-formats", value.split(","), config)
         else:
             raise RuntimeError("unhandled option {}".format(option.name))
 
+
 # "Parse" the `config.example.toml` file into the various sections, and we'll
 # use this as a template of a `config.toml` to write out which preserves
 # all the various comments and whatnot.
@@ -406,20 +567,22 @@ def parse_example_config(known_args, config):
     targets = {}
     top_level_keys = []
 
-    with open(rust_dir + '/config.example.toml') as example_config:
+    with open(rust_dir + "/config.example.toml") as example_config:
         example_lines = example_config.read().split("\n")
     for line in example_lines:
         if cur_section is None:
-            if line.count('=') == 1:
-                top_level_key = line.split('=')[0]
-                top_level_key = top_level_key.strip(' #')
+            if line.count("=") == 1:
+                top_level_key = line.split("=")[0]
+                top_level_key = top_level_key.strip(" #")
                 top_level_keys.append(top_level_key)
-        if line.startswith('['):
+        if line.startswith("["):
             cur_section = line[1:-1]
-            if cur_section.startswith('target'):
-                cur_section = 'target'
-            elif '.' in cur_section:
-                raise RuntimeError("don't know how to deal with section: {}".format(cur_section))
+            if cur_section.startswith("target"):
+                cur_section = "target"
+            elif "." in cur_section:
+                raise RuntimeError(
+                    "don't know how to deal with section: {}".format(cur_section)
+                )
             sections[cur_section] = [line]
             section_order.append(cur_section)
         else:
@@ -428,22 +591,25 @@ def parse_example_config(known_args, config):
     # Fill out the `targets` array by giving all configured targets a copy of the
     # `target` section we just loaded from the example config
     configured_targets = [build(known_args)]
-    if 'build' in config:
-        if 'host' in config['build']:
-            configured_targets += config['build']['host']
-        if 'target' in config['build']:
-            configured_targets += config['build']['target']
-    if 'target' in config:
-        for target in config['target']:
+    if "build" in config:
+        if "host" in config["build"]:
+            configured_targets += config["build"]["host"]
+        if "target" in config["build"]:
+            configured_targets += config["build"]["target"]
+    if "target" in config:
+        for target in config["target"]:
             configured_targets.append(target)
     for target in configured_targets:
-        targets[target] = sections['target'][:]
+        targets[target] = sections["target"][:]
         # For `.` to be valid TOML, it needs to be quoted. But `bootstrap.py` doesn't use a proper TOML parser and fails to parse the target.
         # Avoid using quotes unless it's necessary.
-        targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", "'{}'".format(target) if "." in target else target)
+        targets[target][0] = targets[target][0].replace(
+            "x86_64-unknown-linux-gnu",
+            "'{}'".format(target) if "." in target else target,
+        )
 
-    if 'profile' not in config:
-        set('profile', 'dist', config)
+    if "profile" not in config:
+        set("profile", "dist", config)
     configure_file(sections, top_level_keys, targets, config)
     return section_order, sections, targets
 
@@ -467,7 +633,7 @@ def to_toml(value):
         else:
             return "false"
     elif isinstance(value, list):
-        return '[' + ', '.join(map(to_toml, value)) + ']'
+        return "[" + ", ".join(map(to_toml, value)) + "]"
     elif isinstance(value, str):
         # Don't put quotes around numeric values
         if is_number(value):
@@ -475,9 +641,18 @@ def to_toml(value):
         else:
             return "'" + value + "'"
     elif isinstance(value, dict):
-        return "{" + ", ".join(map(lambda a: "{} = {}".format(to_toml(a[0]), to_toml(a[1])), value.items())) + "}"
+        return (
+            "{"
+            + ", ".join(
+                map(
+                    lambda a: "{} = {}".format(to_toml(a[0]), to_toml(a[1])),
+                    value.items(),
+                )
+            )
+            + "}"
+        )
     else:
-        raise RuntimeError('no toml')
+        raise RuntimeError("no toml")
 
 
 def configure_section(lines, config):
@@ -485,7 +660,7 @@ def configure_section(lines, config):
         value = config[key]
         found = False
         for i, line in enumerate(lines):
-            if not line.startswith('#' + key + ' = '):
+            if not line.startswith("#" + key + " = "):
                 continue
             found = True
             lines[i] = "{} = {}".format(key, to_toml(value))
@@ -501,7 +676,9 @@ def configure_section(lines, config):
 
 def configure_top_level_key(lines, top_level_key, value):
     for i, line in enumerate(lines):
-        if line.startswith('#' + top_level_key + ' = ') or line.startswith(top_level_key + ' = '):
+        if line.startswith("#" + top_level_key + " = ") or line.startswith(
+            top_level_key + " = "
+        ):
             lines[i] = "{} = {}".format(top_level_key, to_toml(value))
             return
 
@@ -512,11 +689,13 @@ def configure_top_level_key(lines, top_level_key, value):
 def configure_file(sections, top_level_keys, targets, config):
     for section_key, section_config in config.items():
         if section_key not in sections and section_key not in top_level_keys:
-            raise RuntimeError("config key {} not in sections or top_level_keys".format(section_key))
+            raise RuntimeError(
+                "config key {} not in sections or top_level_keys".format(section_key)
+            )
         if section_key in top_level_keys:
             configure_top_level_key(sections[None], section_key, section_config)
 
-        elif  section_key == 'target':
+        elif section_key == "target":
             for target in section_config:
                 configure_section(targets[target], section_config[target])
         else:
@@ -536,18 +715,19 @@ def write_uncommented(target, f):
             block = []
             is_comment = True
             continue
-        is_comment = is_comment and line.startswith('#')
+        is_comment = is_comment and line.startswith("#")
     return f
 
 
 def write_config_toml(writer, section_order, targets, sections):
     for section in section_order:
-        if section == 'target':
+        if section == "target":
             for target in targets:
                 writer = write_uncommented(targets[target], writer)
         else:
             writer = write_uncommented(sections[section], writer)
 
+
 def quit_if_file_exists(file):
     if os.path.isfile(file):
         msg = "Existing '{}' detected. Exiting".format(file)
@@ -559,9 +739,10 @@ def quit_if_file_exists(file):
 
         err(msg)
 
+
 if __name__ == "__main__":
     # If 'config.toml' already exists, exit the script at this point
-    quit_if_file_exists('config.toml')
+    quit_if_file_exists("config.toml")
 
     if "GITHUB_ACTIONS" in os.environ:
         print("::group::Configure the build")
@@ -575,13 +756,13 @@ if __name__ == "__main__":
     # order that we read it in.
     p("")
     p("writing `config.toml` in current directory")
-    with bootstrap.output('config.toml') as f:
+    with bootstrap.output("config.toml") as f:
         write_config_toml(f, section_order, targets, sections)
 
-    with bootstrap.output('Makefile') as f:
-        contents = os.path.join(rust_dir, 'src', 'bootstrap', 'mk', 'Makefile.in')
+    with bootstrap.output("Makefile") as f:
+        contents = os.path.join(rust_dir, "src", "bootstrap", "mk", "Makefile.in")
         contents = open(contents).read()
-        contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + '/')
+        contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + "/")
         contents = contents.replace("$(CFG_PYTHON)", sys.executable)
         f.write(contents)