Merge inbound to mozilla-central. a=merge
authorNoemi Erli <nerli@mozilla.com>
Wed, 07 Aug 2019 12:56:42 +0300
changeset 486727 b94a6b06c9b9b8e14635e949371582b8fd029308
parent 486726 4ba2efc86669143d4ce3e31c6d8c180a0dbf28bf (current diff)
parent 486725 d28c14caa7cc5fc9c0fcd806d9336570ca12f1cb (diff)
child 486728 5c3693e45bc136db1b1b16ecbd0d3d0265a8cc0e
child 486735 2f9fcfd57416a8424ff12a11c9734ee9a2fb6ed0
push id91892
push usernerli@mozilla.com
push dateWed, 07 Aug 2019 10:09:17 +0000
treeherderautoland@5c3693e45bc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone70.0a1
first release with
nightly linux32
b94a6b06c9b9 / 70.0a1 / 20190807095705 / files
nightly linux64
b94a6b06c9b9 / 70.0a1 / 20190807095705 / files
nightly mac
b94a6b06c9b9 / 70.0a1 / 20190807095705 / files
nightly win32
b94a6b06c9b9 / 70.0a1 / 20190807095705 / files
nightly win64
b94a6b06c9b9 / 70.0a1 / 20190807095705 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
browser/config/tooltool-manifests/win32/build-clang-cl.manifest
browser/config/tooltool-manifests/win32/gn-build.manifest
browser/config/tooltool-manifests/win64/sccache-build.manifest
taskcluster/scripts/misc/build-gcc-6-linux.sh
taskcluster/scripts/misc/build-gcc-7-linux.sh
taskcluster/scripts/misc/build-gcc-8-linux.sh
taskcluster/scripts/misc/build-gcc-9-linux.sh
deleted file mode 100644
--- a/browser/config/tooltool-manifests/win32/gn-build.manifest
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "version": "Visual Studio 2017 15.8.4 / SDK 10.0.17134.0",
-    "digest": "ecf1e03f6f98f86775059a43f9e7dc7e326f6643d7c08962d9f614e4f5a65b1ca63fa1cfeb0f1a3c2474bf0d4318dda960b378beb2a44ecf8a91111207f4ece5",
-    "size": 349626009,
-    "algorithm": "sha512",
-    "filename": "vs2017_15.8.4.zip",
-    "unpack": true
-  },
-  {
-    "version": "Ninja 1.7.1",
-    "size": 184821,
-    "digest": "e4f9a1ae624a2630e75264ba37d396d9c7407d6e6aea3763056210ba6e1387908bd31cf4037a6a3661a418e86c4d2761e0c333e6a3bd0d66549d2b0d72d3f43b",
-    "algorithm": "sha512",
-    "filename": "ninja171.zip",
-    "unpack": true
-  }
-]
deleted file mode 100644
--- a/browser/config/tooltool-manifests/win64/sccache-build.manifest
+++ /dev/null
@@ -1,10 +0,0 @@
-[
-  {
-    "version": "Visual Studio 2017 15.8.4 / SDK 10.0.17134.0",
-    "digest": "ecf1e03f6f98f86775059a43f9e7dc7e326f6643d7c08962d9f614e4f5a65b1ca63fa1cfeb0f1a3c2474bf0d4318dda960b378beb2a44ecf8a91111207f4ece5",
-    "size": 349626009,
-    "algorithm": "sha512",
-    "filename": "vs2017_15.8.4.zip",
-    "unpack": true
-  }
-]
rename from browser/config/tooltool-manifests/win32/build-clang-cl.manifest
rename to browser/config/tooltool-manifests/win64/vs2017.manifest
--- a/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
+++ b/browser/config/tooltool-manifests/win64/vs2017.manifest
@@ -1,34 +1,10 @@
 [
   {
     "version": "Visual Studio 2017 15.8.4 / SDK 10.0.17134.0",
     "digest": "ecf1e03f6f98f86775059a43f9e7dc7e326f6643d7c08962d9f614e4f5a65b1ca63fa1cfeb0f1a3c2474bf0d4318dda960b378beb2a44ecf8a91111207f4ece5",
     "size": 349626009,
     "algorithm": "sha512",
     "filename": "vs2017_15.8.4.zip",
     "unpack": true
-  },
-  {
-    "version": "MinGit-2.13.3-64-bit",
-    "size": 21482885,
-    "digest": "929bb3c07be8487ee519422a312bdbfeec8f4db4b62c49d02f9aad9fd2a66c0ee5fad63d2b06c8744c336dc9d50446fa4457897333ad17ffd783ecabd1e2ddbb",
-    "algorithm": "sha512",
-    "filename": "git.zip",
-    "unpack": true
-  },
-  {
-    "version": "CMake 3.6.2 repack",
-    "size": 19832889,
-    "digest": "39b0508b60f655969d1b54c76753b14b5b2e92dab58613c835aed798a6aeb9077a7df78aebc011c2c753661fdc15007d3353c0c8773a53148380e2ec02afb629",
-    "algorithm": "sha512",
-    "filename": "cmake362.zip",
-    "unpack": true
-  },
-  {
-    "version": "Ninja 1.7.1",
-    "size": 184821,
-    "digest": "e4f9a1ae624a2630e75264ba37d396d9c7407d6e6aea3763056210ba6e1387908bd31cf4037a6a3661a418e86c4d2761e0c333e6a3bd0d66549d2b0d72d3f43b",
-    "algorithm": "sha512",
-    "filename": "ninja171.zip",
-    "unpack": true
   }
 ]
--- a/build/build-clang/build-clang.py
+++ b/build/build-clang/build-clang.py
@@ -32,30 +32,30 @@ def symlink(source, link_name):
         os_symlink(source, link_name)
     else:
         if os.path.isdir(source):
             # Fall back to copying the directory :(
             copy_tree(source, link_name)
 
 
 def check_run(args):
-    print(' '.join(args), file=sys.stderr)
+    print(' '.join(args), file=sys.stderr, flush=True)
     if args[0] == 'cmake':
         # CMake `message(STATUS)` messages, as appearing in failed source code
         # compiles, appear on stdout, so we only capture that.
         p = subprocess.Popen(args, stdout=subprocess.PIPE)
         lines = []
         for line in p.stdout:
             lines.append(line)
             sys.stdout.write(line.decode())
             sys.stdout.flush()
         r = p.wait()
         if r != 0:
-            cmake_output_re = re.compile("See also \"(.*/CMakeOutput.log)\"")
-            cmake_error_re = re.compile("See also \"(.*/CMakeError.log)\"")
+            cmake_output_re = re.compile(b"See also \"(.*/CMakeOutput.log)\"")
+            cmake_error_re = re.compile(b"See also \"(.*/CMakeError.log)\"")
 
             def find_first_match(re):
                 for l in lines:
                     match = re.search(l)
                     if match:
                         return match
 
             output_match = find_first_match(cmake_output_re)
@@ -209,26 +209,16 @@ def install_asan_symbols(build_dir, clan
         raise Exception("Source path pattern did not resolve uniquely")
 
     if len(src_path) != 1:
         raise Exception("Destination path pattern did not resolve uniquely")
 
     shutil.copy2(src_path[0], dst_path[0])
 
 
-def git_clone(base_dir, url, directory, revision):
-    run_in(base_dir, ["git", "clone", "-n", url, directory])
-    run_in(os.path.join(base_dir, directory), ["git", "checkout", revision])
-
-
-def git_update(directory, revision):
-    run_in(directory, ["git", "remote", "update"])
-    run_in(directory, ["git", "reset", "--hard", revision])
-
-
 def is_darwin():
     return platform.system() == "Darwin"
 
 
 def is_linux():
     return platform.system() == "Linux"
 
 
@@ -546,59 +536,33 @@ def prune_final_dir_for_clang_tidy(final
             delete(f)
 
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser()
     parser.add_argument('-c', '--config', required=True,
                         type=argparse.FileType('r'),
                         help="Clang configuration file")
-    parser.add_argument('-b', '--base-dir', required=False,
-                        help="Base directory for code and build artifacts")
     parser.add_argument('--clean', required=False,
                         action='store_true',
                         help="Clean the build directory")
     parser.add_argument('--skip-tar', required=False,
                         action='store_true',
                         help="Skip tar packaging stage")
     parser.add_argument('--skip-checkout', required=False,
                         action='store_true',
                         help="Do not checkout/revert source")
 
     args = parser.parse_args()
 
-    # The directories end up in the debug info, so the easy way of getting
-    # a reproducible build is to run it in a know absolute directory.
-    # We use a directory that is registered as a volume in the Docker image.
-
-    if args.base_dir:
-        base_dir = args.base_dir
-    elif os.environ.get('MOZ_AUTOMATION') and not is_windows():
-        base_dir = "/builds/worker/workspace/moz-toolchain"
-    else:
-        # Handles both the Windows automation case and the local build case
-        # TODO: Because Windows taskcluster builds are run with distinct
-        # user IDs for each job, we can't store things in some globally
-        # accessible directory: one job will run, checkout LLVM to that
-        # directory, and then if another job runs, the new user won't be
-        # able to access the previously-checked out code--or be able to
-        # delete it.  So on Windows, we build in the task-specific home
-        # directory; we will eventually add -fdebug-prefix-map options
-        # to the LLVM build to bring back reproducibility.
-        base_dir = os.path.join(os.getcwd(), 'build-clang')
-
-    source_dir = base_dir + "/src"
-    build_dir = base_dir + "/build"
-
-    if not os.path.exists(base_dir):
-        os.makedirs(base_dir)
-    elif os.listdir(base_dir) and not os.path.exists(os.path.join(base_dir, '.build-clang')):
-        raise ValueError("Base directory %s exists and is not a build-clang directory. "
-                         "Supply a non-existent or empty directory with --base-dir" % base_dir)
-    open(os.path.join(base_dir, '.build-clang'), 'a').close()
+    if not os.path.exists('llvm/LLVMBuild.txt'):
+        raise Exception('The script must be run from the root directory of the '
+                        'llvm-project tree')
+    source_dir = os.getcwd()
+    build_dir = source_dir + "/build"
 
     if args.clean:
         shutil.rmtree(build_dir)
         os.sys.exit(0)
 
     llvm_source_dir = source_dir + "/llvm"
     extra_source_dir = source_dir + "/clang-tools-extra"
     clang_source_dir = source_dir + "/clang"
@@ -618,19 +582,16 @@ if __name__ == "__main__":
     cxx_name = "clang++"
     if is_windows():
         cc_name = "clang-cl"
         cxx_name = "clang-cl"
 
     config_dir = os.path.dirname(args.config.name)
     config = json.load(args.config)
 
-    llvm_revision = config["llvm_revision"]
-    if not re.match(r'^[0-9a-fA-F]{40}$', llvm_revision):
-        raise ValueError("Incorrect format of the git revision")
     stages = 3
     if "stages" in config:
         stages = int(config["stages"])
         if stages not in (1, 2, 3):
             raise ValueError("We only know how to build 1, 2, or 3 stages")
     build_type = "Release"
     if "build_type" in config:
         build_type = config["build_type"]
@@ -694,23 +655,16 @@ if __name__ == "__main__":
     ranlib = None if is_windows() else get_tool(config, "ranlib")
     libtool = None
     if "libtool" in config:
         libtool = get_tool(config, "libtool")
 
     if not os.path.exists(source_dir):
         os.makedirs(source_dir)
 
-    if not args.skip_checkout:
-        if os.path.exists(os.path.join(source_dir, '.git')):
-            git_update(source_dir, llvm_revision)
-        else:
-            delete(source_dir)
-            git_clone(base_dir, URL_REPO, source_dir, llvm_revision)
-
     for p in config.get("patches", []):
         patch(os.path.join(config_dir, p), source_dir)
 
     compiler_rt_source_link = llvm_source_dir + "/projects/compiler-rt"
 
     symlinks = [(clang_source_dir,
                  llvm_source_dir + "/tools/clang"),
                 (extra_source_dir,
--- a/build/build-clang/clang-4.0-linux64.json
+++ b/build/build-clang/clang-4.0-linux64.json
@@ -1,13 +1,12 @@
 {
-    "llvm_revision": "449c3ef93afc7a668eb35e67a83717453e28b25a",
     "stages": "3",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "patches": []
 }
--- a/build/build-clang/clang-7-linux64.json
+++ b/build/build-clang/clang-7-linux64.json
@@ -1,19 +1,18 @@
 {
-    "llvm_revision": "d0d8eb2e5415b8be29343e3c17a18e49e67b5551",
     "stages": "3",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "patches": [
       "static-llvm-symbolizer.patch",
       "find_symbolizer_linux.patch",
       "rename_gcov_flush_7.patch",
       "r350774.patch",
       "android-mangling-error.patch"
     ]
 }
--- a/build/build-clang/clang-8-android.json
+++ b/build/build-clang/clang-8-android.json
@@ -1,53 +1,52 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "2",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "android_targets": {
       "armv7-linux-android": {
-        "ndk_toolchain": "/builds/worker/workspace/build/src/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64",
-        "ndk_sysroot": "/builds/worker/workspace/build/src/android-ndk/platforms/android-16/arch-arm",
+        "ndk_toolchain": "/builds/worker/workspace/build/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64",
+        "ndk_sysroot": "/builds/worker/workspace/build/android-ndk/platforms/android-16/arch-arm",
         "ndk_includes": [
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include/arm-linux-androideabi",
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include"
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include/arm-linux-androideabi",
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include"
         ],
         "api_level": 16
       },
       "i686-linux-android": {
-        "ndk_toolchain": "/builds/worker/workspace/build/src/android-ndk/toolchains/x86-4.9/prebuilt/linux-x86_64",
-        "ndk_sysroot": "/builds/worker/workspace/build/src/android-ndk/platforms/android-16/arch-x86",
+        "ndk_toolchain": "/builds/worker/workspace/build/android-ndk/toolchains/x86-4.9/prebuilt/linux-x86_64",
+        "ndk_sysroot": "/builds/worker/workspace/build/android-ndk/platforms/android-16/arch-x86",
         "ndk_includes": [
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include/i686-linux-android",
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include"
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include/i686-linux-android",
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include"
         ],
         "api_level": 16
       },
       "aarch64-linux-android": {
-        "ndk_toolchain": "/builds/worker/workspace/build/src/android-ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64",
-        "ndk_sysroot": "/builds/worker/workspace/build/src/android-ndk/platforms/android-21/arch-arm64",
+        "ndk_toolchain": "/builds/worker/workspace/build/android-ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64",
+        "ndk_sysroot": "/builds/worker/workspace/build/android-ndk/platforms/android-21/arch-arm64",
         "ndk_includes": [
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include/aarch64-linux-android",
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include"
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include/aarch64-linux-android",
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include"
         ],
         "api_level": 21
       },
       "x86_64-linux-android": {
-        "ndk_toolchain": "/builds/worker/workspace/build/src/android-ndk/toolchains/x86_64-4.9/prebuilt/linux-x86_64",
-        "ndk_sysroot": "/builds/worker/workspace/build/src/android-ndk/platforms/android-21/arch-x86_64",
+        "ndk_toolchain": "/builds/worker/workspace/build/android-ndk/toolchains/x86_64-4.9/prebuilt/linux-x86_64",
+        "ndk_sysroot": "/builds/worker/workspace/build/android-ndk/platforms/android-21/arch-x86_64",
         "ndk_includes": [
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include/x86_64-linux-android",
-          "/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include"
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include/x86_64-linux-android",
+          "/builds/worker/workspace/build/android-ndk/sysroot/usr/include"
         ],
         "api_level": 21
       }
     },
     "patches": [
       "static-llvm-symbolizer.patch",
       "find_symbolizer_linux.patch",
       "rename_gcov_flush.patch"
--- a/build/build-clang/clang-8-linux64-aarch64-cross.json
+++ b/build/build-clang/clang-8-linux64-aarch64-cross.json
@@ -1,19 +1,18 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "3",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "extra_targets": [
       "aarch64-unknown-linux-gnu"
     ],
     "patches": [
       "static-llvm-symbolizer.patch",
       "find_symbolizer_linux.patch",
       "rename_gcov_flush.patch",
       "android-mangling-error.patch"
--- a/build/build-clang/clang-8-linux64.json
+++ b/build/build-clang/clang-8-linux64.json
@@ -1,18 +1,17 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "3",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "patches": [
       "static-llvm-symbolizer.patch",
       "find_symbolizer_linux.patch",
       "rename_gcov_flush.patch",
       "android-mangling-error.patch"
     ]
 }
--- a/build/build-clang/clang-8-macosx64.json
+++ b/build/build-clang/clang-8-macosx64.json
@@ -1,23 +1,22 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "1",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "osx_cross_compile": true,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "cxx": "/builds/worker/workspace/build/src/clang/bin/clang++",
-    "as": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin-ar",
-    "ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin-ranlib",
-    "libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin-libtool",
-    "ld": "/builds/worker/workspace/build/src/clang/bin/clang",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/clang/bin/clang",
+    "cxx": "/builds/worker/workspace/build/clang/bin/clang++",
+    "as": "/builds/worker/workspace/build/clang/bin/clang",
+    "ar": "/builds/worker/workspace/build/cctools/bin/x86_64-apple-darwin-ar",
+    "ranlib": "/builds/worker/workspace/build/cctools/bin/x86_64-apple-darwin-ranlib",
+    "libtool": "/builds/worker/workspace/build/cctools/bin/x86_64-apple-darwin-libtool",
+    "ld": "/builds/worker/workspace/build/clang/bin/clang",
     "patches": [
       "static-llvm-symbolizer.patch",
       "rename_gcov_flush.patch",
       "compiler-rt-cross-compile.patch",
       "compiler-rt-no-codesign.patch"
     ]
 }
--- a/build/build-clang/clang-8-mingw.json
+++ b/build/build-clang/clang-8-mingw.json
@@ -1,19 +1,18 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "3",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "patches": [
         "mingwclang-llvm-objcopy-COFF-Remove-a-superfluous-namespace-qua.patch",
         "mingwclang-llvm-objcopy-COFF-Add-support-for-removing-sections.patch",
         "mingwclang-llvm-objcopy-COFF-Implement-strip-debug.patch",
         "mingwclang-llvm-objcopy-COFF-Implement-only-keep-debug.patch",
         "mingwclang-llvm-objcopy-COFF-Implement-only-section.patch",
         "mingwclang-llvm-objcopy-Consistently-use-createStringError-inst.patch",
         "mingwclang-llvm-objcopy-COFF-Update-symbol-indices-in-weak-exte.patch",
--- a/build/build-clang/clang-tidy-linux64.json
+++ b/build/build-clang/clang-tidy-linux64.json
@@ -1,16 +1,15 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "1",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "build_clang_tidy": true,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/gcc/bin/gcc",
     "patches": [
       "clang-tidy-8.patch"
     ]
 }
--- a/build/build-clang/clang-tidy-macosx64.json
+++ b/build/build-clang/clang-tidy-macosx64.json
@@ -1,22 +1,21 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "1",
     "build_libcxx": true,
     "build_type": "Release",
     "assertions": false,
     "build_clang_tidy": true,
     "osx_cross_compile": true,
     "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "cxx": "/builds/worker/workspace/build/src/clang/bin/clang++",
-    "as": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin-ar",
-    "ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin-ranlib",
-    "libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin-libtool",
-    "ld": "/builds/worker/workspace/build/src/clang/bin/clang",
+    "gcc_dir": "/builds/worker/workspace/build/gcc",
+    "cc": "/builds/worker/workspace/build/clang/bin/clang",
+    "cxx": "/builds/worker/workspace/build/clang/bin/clang++",
+    "as": "/builds/worker/workspace/build/clang/bin/clang",
+    "ar": "/builds/worker/workspace/build/cctools/bin/x86_64-apple-darwin-ar",
+    "ranlib": "/builds/worker/workspace/build/cctools/bin/x86_64-apple-darwin-ranlib",
+    "libtool": "/builds/worker/workspace/build/cctools/bin/x86_64-apple-darwin-libtool",
+    "ld": "/builds/worker/workspace/build/clang/bin/clang",
     "patches": [
       "clang-tidy-8.patch",
       "compiler-rt-no-codesign.patch"
     ]
 }
--- a/build/build-clang/clang-tidy-win64.json
+++ b/build/build-clang/clang-tidy-win64.json
@@ -1,10 +1,9 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "1",
     "build_libcxx": false,
     "build_type": "Release",
     "assertions": false,
     "build_clang_tidy": true,
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -1,10 +1,9 @@
 {
-    "llvm_revision": "d2298e74235598f15594fe2c99bbac870a507c59",
     "stages": "3",
     "build_libcxx": false,
     "build_type": "Release",
     "assertions": false,
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "ml": "ml64.exe",
--- a/build/unix/build-binutils/build-binutils.sh
+++ b/build/unix/build-binutils/build-binutils.sh
@@ -1,18 +1,15 @@
 #!/bin/bash
 
-binutils_version=2.31.1
 make_flags="-j$(nproc)"
 
 root_dir="$1"
 
-cd $root_dir
-
-cd binutils-$binutils_version
+cd $root_dir/binutils-source
 
 patch -p1 <<'EOF'
 From 4476cc67e657d6b26cd453c555a611f1ab956660 Mon Sep 17 00:00:00 2001
 From: "H.J. Lu" <hjl.tools@gmail.com>
 Date: Thu, 30 Aug 2018 09:21:57 -0700
 Subject: [PATCH] ld: Lookup section in output with the same name
 
 When there are more than one input sections with the same section name,
@@ -68,30 +65,30 @@ TARGETS="aarch64-linux-gnu"
 # Build target-specific GNU as ; build them first so that the few documentation
 # files they install are overwritten by the full binutils build.
 
 for target in $TARGETS; do
 
   mkdir binutils-$target
   cd binutils-$target
 
-  ../binutils-$binutils_version/configure --prefix /tools/binutils/ --disable-gold --disable-ld --disable-binutils --disable-gprof --disable-nls --target=$target || exit 1
+  ../binutils-source/configure --prefix /tools/binutils/ --disable-gold --disable-ld --disable-binutils --disable-gprof --disable-nls --target=$target || exit 1
   make $make_flags || exit 1
   make install $make_flags DESTDIR=$root_dir || exit 1
 
   cd ..
 done
 
 # Build binutils
 mkdir binutils-objdir
 cd binutils-objdir
 
 # --enable-targets builds extra target support in ld.
 # Enabling aarch64 support brings in arm support, so we don't need to specify that too.
-../binutils-$binutils_version/configure --prefix /tools/binutils/ --enable-gold --enable-plugins --disable-nls --enable-targets="$TARGETS" || exit 1
+../binutils-source/configure --prefix /tools/binutils/ --enable-gold --enable-plugins --disable-nls --enable-targets="$TARGETS" || exit 1
 make $make_flags || exit 1
 make install $make_flags DESTDIR=$root_dir || exit 1
 
 cd ..
 
 # Make a package of the built binutils
 cd $root_dir/tools
 tar caf $root_dir/binutils.tar.xz binutils/
--- a/build/unix/build-gcc/build-gcc.sh
+++ b/build/unix/build-gcc/build-gcc.sh
@@ -19,17 +19,17 @@ prepare_mingw() {
   popd
 }
 
 apply_patch() {
   if [ $# -ge 2 ]; then
     pushd $root_dir/$1
     shift
   else
-    pushd $root_dir/gcc-$gcc_version
+    pushd $root_dir/gcc-source
   fi
   patch -p1 < $1
   popd
 }
 
 build_binutils() {
   # if binutils_configure_flags is not set at all, give it the default value
   if [ -z "${binutils_configure_flags+xxx}" ];
@@ -42,45 +42,45 @@ build_binutils() {
     #
     # It is important to have the binutils --target and the gcc --target match,
     # so binutils will install binaries in a place that gcc will look for them.
     binutils_configure_flags="--enable-targets=aarch64-unknown-linux-gnu --build=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu --disable-gold --enable-plugins --disable-nls --with-sysroot=/"
   fi
 
   mkdir $root_dir/binutils-objdir
   pushd $root_dir/binutils-objdir
-  ../binutils-$binutils_version/configure --prefix=${prefix-/tools/gcc}/ $binutils_configure_flags
+  ../binutils-source/configure --prefix=${prefix-/tools/gcc}/ $binutils_configure_flags
   make $make_flags
   make install $make_flags DESTDIR=$root_dir
   export PATH=$root_dir/${prefix-/tools/gcc}/bin:$PATH
   popd
 }
 
 build_gcc() {
   # Be explicit about --build and --target so header and library install
   # directories are consistent.
   local target="${1:-x86_64-unknown-linux-gnu}"
 
   mkdir $root_dir/gcc-objdir
   pushd $root_dir/gcc-objdir
-  ../gcc-$gcc_version/configure --prefix=${prefix-/tools/gcc} --build=x86_64-unknown-linux-gnu --target="${target}" --enable-languages=c,c++  --disable-nls --disable-gnu-unique-object --enable-__cxa_atexit --with-arch-32=pentiumpro --with-sysroot=/
+  ../gcc-source/configure --prefix=${prefix-/tools/gcc} --build=x86_64-unknown-linux-gnu --target="${target}" --enable-languages=c,c++  --disable-nls --disable-gnu-unique-object --enable-__cxa_atexit --with-arch-32=pentiumpro --with-sysroot=/
   make $make_flags
   make $make_flags install DESTDIR=$root_dir
 
   cd $root_dir/tools
   ln -s gcc gcc/bin/cc
 
   tar caf $root_dir/gcc.tar.xz gcc/
   popd
 }
 
 build_gcc_and_mingw() {
   mkdir gcc-objdir
   pushd gcc-objdir
-  ../gcc-$gcc_version/configure --prefix=$install_dir --target=i686-w64-mingw32 --with-gnu-ld --with-gnu-as --disable-multilib --enable-threads=posix
+  ../gcc-source/configure --prefix=$install_dir --target=i686-w64-mingw32 --with-gnu-ld --with-gnu-as --disable-multilib --enable-threads=posix
   make $make_flags all-gcc
   make $make_flags install-gcc
   popd
 
   mkdir mingw-w64-headers32
   pushd mingw-w64-headers32
   ../mingw-w64/mingw-w64-headers/configure --host=i686-w64-mingw32 --prefix=$install_dir/i686-w64-mingw32/ --enable-sdk=all --enable-secure-api --enable-idl
   make $make_flags install
--- a/mobile/android/config/mozconfigs/android-api-16-gradle-dependencies/nightly
+++ b/mobile/android/config/mozconfigs/android-api-16-gradle-dependencies/nightly
@@ -6,16 +6,20 @@ MOZ_AUTOMATION_PACKAGE_TESTS=0
 MOZ_AUTOMATION_UPLOAD=0
 MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0
 
 NO_CACHE=1
 NO_NDK=1
 
 . "$topsrcdir/mobile/android/config/mozconfigs/common"
 
+# Until normal mozconfigs also use MOZ_FETCHES_DIR
+ac_add_options --with-android-sdk="$MOZ_FETCHES_DIR/android-sdk-linux"
+export NODEJS=$MOZ_FETCHES_DIR/node/bin/node
+
 # We want to download Gradle.
 ac_add_options --with-gradle
 # We want to use (and populate!) the local Nexus repositories.
 export GRADLE_MAVEN_REPOSITORIES="http://localhost:8081/nexus/content/repositories/google/","http://localhost:8081/nexus/content/repositories/jcenter/","http://localhost:8081/nexus/content/repositories/gradle-plugins/"
 
 # From here on, just like ../android-api-16-frontend/nightly.
 
 . "$topsrcdir/build/mozconfig.no-compile"
--- a/taskcluster/ci/fetch/toolchains.yml
+++ b/taskcluster/ci/fetch/toolchains.yml
@@ -7,153 +7,195 @@ binutils-2.27:
     fetch:
         type: static-url
         url: ftp://ftp.gnu.org/gnu/binutils/binutils-2.27.tar.bz2
         sha256: 369737ce51587f92466041a97ab7d2358c6d9e1b6490b3940eb09fb0a9a6ac88
         size: 26099568
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/EAF1C276A747E9ED86210CBAC3126D3B4AE55E93.key
+        artifact-name: binutils-source.tar.zst
+        strip-components: 1
+        add-prefix: binutils-source/
 
 binutils-2.31.1:
     description: binutils 2.31.1 source code
     fetch:
         type: static-url
         url: ftp://ftp.gnu.org/gnu/binutils/binutils-2.31.1.tar.xz
         sha256: 5d20086ecf5752cc7d9134246e9588fa201740d540f7eb84d795b1f7a93bca86
         size: 20467996
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-binutils/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F.key
+        artifact-name: binutils-source.tar.zst
+        strip-components: 1
+        add-prefix: binutils-source/
 
 gcc-6.4.0:
     description: GCC 6.4.0 source code
     fetch:
         type: static-url
         url: ftp://ftp.gnu.org/gnu/gcc/gcc-6.4.0/gcc-6.4.0.tar.xz
         sha256: 850bf21eafdfe5cd5f6827148184c08c4a0852a37ccf36ce69855334d2c914d4
         size: 76156220
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/13975A70E63C361C73AE69EF6EEB81F8981C74C7.key
+        artifact-name: gcc-source.tar.zst
+        strip-components: 1
+        add-prefix: gcc-source/
 
 gcc-7.4.0:
     description: GCC 7.4.0 source code
     fetch:
         type: static-url
         url: ftp://ftp.gnu.org/gnu/gcc/gcc-7.4.0/gcc-7.4.0.tar.xz
         sha256: eddde28d04f334aec1604456e536416549e9b1aa137fc69204e65eb0c009fe51
         size: 62601888
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/13975A70E63C361C73AE69EF6EEB81F8981C74C7.key
+        artifact-name: gcc-source.tar.zst
+        strip-components: 1
+        add-prefix: gcc-source/
 
 gcc-8.3.0:
     description: GCC 8.3.0 source code
     fetch:
         type: static-url
         url: ftp://ftp.gnu.org/gnu/gcc/gcc-8.3.0/gcc-8.3.0.tar.xz
         sha256: 64baadfe6cc0f4947a84cb12d7f0dfaf45bb58b7e92461639596c21e02d97d2c
         size: 63694700
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/33C235A34C46AA3FFB293709A328C3A2C3C45C06.key
+        artifact-name: gcc-source.tar.zst
+        strip-components: 1
+        add-prefix: gcc-source/
 
 gcc-9.1.0:
     description: GCC 9.1.0 source code
     fetch:
         type: static-url
         url: ftp://ftp.gnu.org/gnu/gcc/gcc-9.1.0/gcc-9.1.0.tar.xz
         sha256: 79a66834e96a6050d8fe78db2c3b32fb285b230b855d0a66288235bc04b327a0
         size: 70546856
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/33C235A34C46AA3FFB293709A328C3A2C3C45C06.key
+        artifact-name: gcc-source.tar.zst
+        strip-components: 1
+        add-prefix: gcc-source/
 
 gmp-5.1.3:
     description: GMP 5.1.3 source code
     fetch:
         type: static-url
         url: https://ftp.gnu.org/gnu/gmp/gmp-5.1.3.tar.bz2
         sha256: 752079520b4690531171d0f4532e40f08600215feefede70b24fabdc6f1ab160
         size: 2196480
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/343C2FF0FBEE5EC2EDBEF399F3599FF828C67298.key
+        artifact-name: gmp-source.tar.zst
+        strip-components: 1
+        add-prefix: gmp-source/
 
 gmp-6.1.0:
     description: GMP 6.1.0 source code
     fetch:
         type: static-url
         url: https://ftp.gnu.org/gnu/gmp/gmp-6.1.0.tar.bz2
         sha256: 498449a994efeba527885c10405993427995d3f86b8768d8cdf8d9dd7c6b73e8
         size: 2383840
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/343C2FF0FBEE5EC2EDBEF399F3599FF828C67298.key
+        artifact-name: gmp-source.tar.zst
+        strip-components: 1
+        add-prefix: gmp-source/
 
 isl-0.15:
     description: ISL 0.15 source code
     fetch:
         type: static-url
         url: ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.15.tar.bz2
         sha256: 8ceebbf4d9a81afa2b4449113cee4b7cb14a687d7a549a963deb5e2a41458b6b
         size: 1574964
+        artifact-name: isl-source.tar.zst
+        strip-components: 1
+        add-prefix: isl-source/
 
 isl-0.16.1:
     description: ISL 0.16.1 source code
     fetch:
         type: static-url
         url: ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.16.1.tar.bz2
         sha256: 412538bb65c799ac98e17e8cfcdacbb257a57362acfaaff254b0fcae970126d2
         size: 1626446
+        artifact-name: isl-source.tar.zst
+        strip-components: 1
+        add-prefix: isl-source/
 
 mpc-0.8.2:
     description: mpc 0.8.2 source code
     fetch:
         type: static-url
         url: http://www.multiprecision.org/downloads/mpc-0.8.2.tar.gz
         sha256: ae79f8d41d8a86456b68607e9ca398d00f8b7342d1d83bcf4428178ac45380c7
         size: 548401
         gpg-signature:
             sig-url: "{url}.asc"
             key-path: build/unix/build-gcc/AD17A21EF8AED8F1CC02DBD9F7D5C9BF765C61E3.key
+        artifact-name: mpc-source.tar.zst
+        strip-components: 1
+        add-prefix: mpc-source/
 
 mpc-1.0.3:
     description: mpc 1.0.3 source code
     fetch:
         type: static-url
         url: http://www.multiprecision.org/downloads/mpc-1.0.3.tar.gz
         sha256: 617decc6ea09889fb08ede330917a00b16809b8db88c29c31bfbb49cbf88ecc3
         size: 669925
         gpg-signature:
             sig-url: "{url}.sig"
             key-path: build/unix/build-gcc/AD17A21EF8AED8F1CC02DBD9F7D5C9BF765C61E3.key
+        artifact-name: mpc-source.tar.zst
+        strip-components: 1
+        add-prefix: mpc-source/
 
 mpfr-3.1.4:
     description: mpfr 3.1.4 source code
     fetch:
         type: static-url
         url: http://www.mpfr.org/mpfr-3.1.4/mpfr-3.1.4.tar.bz2
         sha256: d3103a80cdad2407ed581f3618c4bed04e0c92d1cf771a65ead662cc397f7775
         size: 1279284
         gpg-signature:
             sig-url: "{url}.asc"
             key-path: build/unix/build-gcc/07F3DBBECC1A39605078094D980C197698C3739D.key
+        artifact-name: mpfr-source.tar.zst
+        strip-components: 1
+        add-prefix: mpfr-source/
 
 mpfr-3.1.5:
     description: mpfr 3.1.5 source code
     fetch:
         type: static-url
         url: http://www.mpfr.org/mpfr-3.1.5/mpfr-3.1.5.tar.bz2
         sha256: ca498c1c7a74dd37a576f353312d1e68d490978de4395fa28f1cbd46a364e658
         size: 1279489
         gpg-signature:
             sig-url: "{url}.asc"
             key-path: build/unix/build-gcc/07F3DBBECC1A39605078094D980C197698C3739D.key
+        artifact-name: mpfr-source.tar.zst
+        strip-components: 1
+        add-prefix: mpfr-source/
 
 nasm-2.14.02:
     description: nasm 2.14.02 source code
     fetch:
         type: static-url
         url: https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.xz
         sha256: e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5
         size: 827620
@@ -331,8 +373,50 @@ llvm-mingw:
         revision: c3a16814bd26aa6702e1e5b482a3d9044bb0f725
 
 android-rs-glue:
     description: android-rs-glue source code
     fetch:
         type: git
         repo: https://github.com/staktrace/android-rs-glue
         revision: 486491e81819c3346d364a93fc1f3c0206d3ece0
+
+clang-4.0:
+    description: clang 4.0 source code
+    fetch:
+        type: git
+        repo: https://github.com/llvm/llvm-project
+        revision: 449c3ef93afc7a668eb35e67a83717453e28b25a
+
+clang-7:
+    description: clang 7 source code
+    fetch:
+        type: git
+        repo: https://github.com/llvm/llvm-project
+        revision: d0d8eb2e5415b8be29343e3c17a18e49e67b5551
+
+clang-8:
+    description: clang 8 source code
+    fetch:
+        type: git
+        repo: https://github.com/llvm/llvm-project
+        revision: d2298e74235598f15594fe2c99bbac870a507c59
+
+ninja:
+    description: ninja 1.9.0
+    fetch:
+        type: static-url
+        url: https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-win.zip
+        sha256: 2d70010633ddaacc3af4ffbd21e22fae90d158674a09e132e06424ba3ab036e9
+        size: 254497
+        artifact-name: ninja.tar.zst
+        add-prefix: ninja/bin/
+
+cmake:
+    description: cmake 3.15.1
+    fetch:
+        type: static-url
+        url: https://github.com/Kitware/CMake/releases/download/v3.15.1/cmake-3.15.1-win64-x64.zip
+        sha256: 82a0edfed4cb0b45b25d2f99e621d3ed4014f66191d8f3c7eadf1d9ccf9c461b
+        size: 32214192
+        artifact-name: cmake.tar.zst
+        strip-components: 1
+        add-prefix: cmake/
--- a/taskcluster/ci/toolchain/android.yml
+++ b/taskcluster/ci/toolchain/android.yml
@@ -46,21 +46,21 @@ linux64-android-gradle-dependencies:
         symbol: TL(gradle-dependencies)
     worker:
         env:
             GRADLE_USER_HOME: "/builds/worker/workspace/build/src/mobile/android/gradle/dotgradle-online"
     run:
         script: android-gradle-dependencies.sh
         sparse-profile: null
         resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
             - 'taskcluster/scripts/misc/android-gradle-dependencies/**'
             - '*.gradle'
             - 'mobile/android/**/*.gradle'
             - 'mobile/android/config/mozconfigs/android-api-16-gradle-dependencies/**'
             - 'mobile/android/config/mozconfigs/common*'
             - 'mobile/android/gradle.configure'
         toolchain-artifact: public/build/android-gradle-dependencies.tar.xz
         toolchain-alias: android-gradle-dependencies
-    toolchains:
-        # Aliases aren't allowed for toolchains depending on toolchains.
-        - linux64-android-sdk-linux-repack
-        - linux64-node
+    fetches:
+        toolchain:
+            # Aliases aren't allowed for toolchains depending on toolchains.
+            - linux64-android-sdk-linux-repack
+            - linux64-node
--- a/taskcluster/ci/toolchain/cbindgen.yml
+++ b/taskcluster/ci/toolchain/cbindgen.yml
@@ -4,57 +4,62 @@
 ---
 job-defaults:
     description: "cbindgen toolchain build"
     worker-type: b-linux
     worker:
         max-run-time: 3600
     run:
         script: build-cbindgen.sh
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/cbindgen.tar.xz
     fetches:
         fetch:
             # If you update this, make sure to update the minimum version in
             # build/moz.configure/bindgen.configure as well.
             - cbindgen-0.9.0
 
 linux64-cbindgen:
     treeherder:
         symbol: TL(cbindgen)
     worker:
         max-run-time: 1800
     run:
         arguments: ['x86_64-unknown-linux-gnu']
-    toolchains:
-        - linux64-rust-1.32
+    fetches:
+        toolchain:
+            - linux64-rust-1.32
 
 macosx64-cbindgen:
     treeherder:
         symbol: TM(cbindgen)
     worker:
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-clang.manifest"
     run-on-projects:
         - trunk
         - try
     run:
         arguments: ['x86_64-apple-darwin']
+        resources:
+            - taskcluster/scripts/misc/tooltool-download.sh
         tooltool-downloads: internal
-    toolchains:
-        - linux64-cctools-port
-        - linux64-clang-8
-        - linux64-llvm-dsymutil
-        - linux64-rust-macos-1.32
+    fetches:
+        toolchain:
+            - linux64-cctools-port
+            - linux64-clang-8
+            - linux64-llvm-dsymutil
+            - linux64-rust-macos-1.32
 
 win64-cbindgen:
     treeherder:
         symbol: TW64(cbindgen)
     worker-type: b-win2012
     worker:
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/sccache-build.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         arguments: ['x86_64-pc-windows-msvc']
+        resources:
+            - taskcluster/scripts/misc/tooltool-download.sh
         toolchain-artifact: public/build/cbindgen.tar.bz2
-    toolchains:
-        - win64-rust-1.34
+    fetches:
+        toolchain:
+            - win64-rust-1.34
--- a/taskcluster/ci/toolchain/cctools-port.yml
+++ b/taskcluster/ci/toolchain/cctools-port.yml
@@ -2,25 +2,23 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 ---
 job-defaults:
     description: "cctools-port toolchain build"
     worker-type: b-linux
     worker:
         max-run-time: 1800
-    run:
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
     fetches:
         fetch:
             - cctools-port
             - libtapi
 
 linux64-cctools-port:
     treeherder:
         symbol: TL(cctools)
     run:
         script: build-cctools-port.sh
         toolchain-artifact: public/build/cctools.tar.xz
-    toolchains:
-        - linux64-clang-8
-        - linux64-binutils
+    fetches:
+        toolchain:
+            - linux64-clang-8
+            - linux64-binutils
--- a/taskcluster/ci/toolchain/clang-tidy.yml
+++ b/taskcluster/ci/toolchain/clang-tidy.yml
@@ -17,31 +17,34 @@ job-defaults:
             - 'build/clang-plugin/*.inc'
             - 'build/clang-plugin/*.py'
             - 'build/clang-plugin/moz.build'
             - 'build/clang-plugin/Makefile.in'
             - 'build/build-clang/build-clang.py'
     run-on-projects:
         - trunk
         - try
+    fetches:
+        fetch:
+            - clang-8
 
 linux64-clang-tidy:
     index:
         job-name: linux64-clang-tidy
     treeherder:
         symbol: TL(clang-tidy)
     run:
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-tidy-linux64.json'
         resources:
             - 'build/build-clang/clang-tidy-linux64.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
-    toolchains:
-        - linux64-gcc-6
+    fetches:
+        toolchain:
+            - linux64-gcc-6
 
 macosx64-clang-tidy:
     index:
         job-name: macosx64-clang-tidy
     treeherder:
         symbol: TM(clang-tidy)
     worker-type: b-linux-large
     worker:
@@ -51,33 +54,38 @@ macosx64-clang-tidy:
         using: toolchain-script
         script: build-clang.sh
         tooltool-downloads: internal
         arguments:
             - 'build/build-clang/clang-tidy-macosx64.json'
         resources:
             - 'build/build-clang/clang-tidy-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
-    toolchains:
-        - linux64-cctools-port
-        - linux64-clang-8
-        - linux64-gcc-6
-        - linux64-node
+    fetches:
+        toolchain:
+            - linux64-cctools-port
+            - linux64-clang-8
+            - linux64-gcc-6
+            - linux64-node
 
 win64-clang-tidy:
     description: "Clang-tidy toolchain build"
     index:
         job-name: win64-clang-tidy
     treeherder:
         symbol: TW64(clang-tidy)
         tier: 2
     worker-type: b-win2012
     worker:
         max-run-time: 7200
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/build-clang-cl.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-tidy-win64.json'
         resources:
             - 'build/build-clang/clang-tidy-win64.json'
         toolchain-artifact: public/build/clang-tidy.tar.bz2
+    fetches:
+        fetch:
+            - cmake
+            - ninja
--- a/taskcluster/ci/toolchain/clang.yml
+++ b/taskcluster/ci/toolchain/clang.yml
@@ -16,144 +16,148 @@ linux64-clang-4.0:
         symbol: TL(clang4.0)
     worker-type: b-linux-large
     run:
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-4.0-linux64.json'
         resources:
             - 'build/build-clang/clang-4.0-linux64.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-gcc-6
+    fetches:
+        fetch:
+            - clang-4.0
+        toolchain:
+            - linux64-gcc-6
 
 linux64-clang-7:
     description: "Clang 7 toolchain build"
     treeherder:
         symbol: TL(clang7)
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-7-linux64.json'
         resources:
             - 'build/build-clang/clang-7-linux64.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-gcc-6
+    fetches:
+        fetch:
+            - clang-7
+        toolchain:
+            - linux64-gcc-6
 
 linux64-clang-8:
     description: "Clang 8 toolchain build"
     treeherder:
         symbol: TL(clang8)
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-8-linux64.json'
         resources:
             - 'build/build-clang/clang-8-linux64.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-clang
         toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-gcc-6
+    fetches:
+        fetch:
+            - clang-8
+        toolchain:
+            - linux64-gcc-6
 
 linux64-clang-8-mingw-x86:
     description: "MinGW-Clang Trunk x86 toolchain build"
     treeherder:
         symbol: TMW(clang-x86)
     run:
         script: build-clang-8-mingw.sh
         arguments:
             - 'x86'
             - 'build/build-clang/clang-8-mingw.json'
         resources:
             - 'build/build-clang/clang-8-mingw.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-clang-mingw-x86
         toolchain-artifact: public/build/clangmingw.tar.xz
-    worker:
-        env:
-            MOZ_FETCHES_DIR: "/builds/worker/workspace/moz-toolchain"
-    toolchains:
-        - linux64-gcc-6
     fetches:
         fetch:
+            - clang-8
             - mingw-w64
             - libunwind
             - llvm-mingw
+        toolchain:
+            - linux64-gcc-6
 
 linux64-clang-8-mingw-x64:
     description: "MinGW-Clang Trunk x64 toolchain build"
     treeherder:
         symbol: TMW(clang-x64)
         tier: 1
     run:
         script: build-clang-8-mingw.sh
         arguments:
             - 'x64'
             - 'build/build-clang/clang-8-mingw.json'
         resources:
             - 'build/build-clang/clang-8-mingw.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-clang-mingw-x64
         toolchain-artifact: public/build/clangmingw.tar.xz
-    worker:
-        env:
-            MOZ_FETCHES_DIR: "/builds/worker/workspace/moz-toolchain"
-    toolchains:
-        - linux64-gcc-6
     fetches:
         fetch:
+            - clang-8
             - mingw-w64
             - libunwind
             - llvm-mingw
+        toolchain:
+            - linux64-gcc-6
 
 linux64-clang-8-android-cross:
     description: "Clang 8 toolchain build"
     treeherder:
         symbol: TL(clang8-android)
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-8-android.json'
         resources:
             - 'build/build-clang/clang-8-android.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-clang-android-cross
         toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-gcc-6
-        - linux64-android-ndk-linux-repack
+    fetches:
+        fetch:
+            - clang-8
+        toolchain:
+            - linux64-gcc-6
+            - linux64-android-ndk-linux-repack
 
 linux64-clang-8-aarch64-cross:
     description: "Clang 8 toolchain build with aarch64 runtime"
     treeherder:
         symbol: TL(clang8-aarch64)
     worker-type: b-linux
     worker:
         max-run-time: 3600
         docker-image: {in-tree: toolchain-arm64-build}
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-8-linux64-aarch64-cross.json'
         resources:
             - 'build/build-clang/clang-8-linux64-aarch64-cross.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-aarch64-cross
         toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-binutils
-        - linux64-gcc-6
+    fetches:
+        fetch:
+            - clang-8
+        toolchain:
+            - linux64-binutils
+            - linux64-gcc-6
 
 linux64-clang-8-macosx-cross:
     description: "Clang 8 toolchain build with MacOS Compiler RT libs"
     treeherder:
         symbol: TL(clang8-macosx-cross)
     worker-type: b-linux
     worker:
         max-run-time: 3600
@@ -164,20 +168,23 @@ linux64-clang-8-macosx-cross:
         arguments:
             - 'build/build-clang/clang-8-macosx64.json'
         resources:
             - 'build/build-clang/clang-8-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-clang-macosx-cross
         toolchain-artifact: public/build/clang.tar.xz
         tooltool-downloads: internal
-    toolchains:
-        - linux64-cctools-port
-        - linux64-clang-8
-        - linux64-gcc-6
+    fetches:
+        fetch:
+            - clang-8
+        toolchain:
+            - linux64-cctools-port
+            - linux64-clang-8
+            - linux64-gcc-6
 
 macosx64-clang:
     description: "Clang toolchain build"
     treeherder:
         symbol: TM(clang)
     worker-type: b-linux-large
     worker:
         max-run-time: 3600
@@ -190,29 +197,38 @@ macosx64-clang:
         script: build-clang.sh
         tooltool-downloads: internal
         arguments:
             - 'build/build-clang/clang-8-macosx64.json'
         resources:
             - 'build/build-clang/clang-8-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-cctools-port
-        - linux64-clang-8
-        - linux64-gcc-6
-        - linux64-node
+    fetches:
+        fetch:
+            - clang-8
+        toolchain:
+            - linux64-cctools-port
+            - linux64-clang-8
+            - linux64-gcc-6
+            - linux64-node
 
 win64-clang-cl:
     description: "Clang-cl toolchain build"
     treeherder:
         symbol: TW64(clang-cl)
     worker-type: b-win2012
     worker:
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/build-clang-cl.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-win64.json'
         resources:
             - 'build/build-clang/clang-win64.json'
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.bz2
+    fetches:
+        fetch:
+            - clang-8
+            - cmake
+            - ninja
--- a/taskcluster/ci/toolchain/dist-toolchains.yml
+++ b/taskcluster/ci/toolchain/dist-toolchains.yml
@@ -6,34 +6,34 @@ job-defaults:
     description: "sccache-dist toolchain archive build"
     worker-type: b-linux
     run-on-projects:
         - trunk
         - try
     run:
         using: toolchain-script
         script: build-dist-toolchains.sh
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
 
 clang-dist-toolchain:
     treeherder:
         symbol: TL(clang-dist)
     worker:
         max-run-time: 1800
     run:
         arguments: ['clang']
         toolchain-artifact: public/build/clang-dist-toolchain.tar.xz
-    toolchains:
-        - linux64-clang-8
-        - linux64-sccache
+    fetches:
+        toolchain:
+            - linux64-clang-8
+            - linux64-sccache
 
 rustc-dist-toolchain:
     treeherder:
         symbol: TL(rustc-dist)
     worker:
         max-run-time: 1800
     run:
         arguments: ['rustc']
         toolchain-artifact: public/build/rustc-dist-toolchain.tar.xz
-    toolchains:
-        - linux64-rust-macos-1.36
-        - linux64-sccache
+    fetches:
+        toolchain:
+            - linux64-rust-macos-1.36
+            - linux64-sccache
--- a/taskcluster/ci/toolchain/gcc.yml
+++ b/taskcluster/ci/toolchain/gcc.yml
@@ -11,63 +11,63 @@ job-defaults:
             - 'build/unix/build-gcc/build-gcc.sh'
         toolchain-artifact: public/build/gcc.tar.xz
 
 linux64-gcc-6:
     description: "GCC 6 toolchain build"
     treeherder:
         symbol: TL(gcc6)
     run:
-        script: build-gcc-6-linux.sh
+        script: build-gcc-linux.sh
         toolchain-alias: linux64-gcc
     fetches:
         fetch:
             - binutils-2.31.1
             - gcc-6.4.0
             - gmp-5.1.3
             - isl-0.15
             - mpc-0.8.2
             - mpfr-3.1.5
 
 linux64-gcc-7:
     description: "GCC 7 toolchain build"
     treeherder:
         symbol: TL(gcc7)
     run:
-        script: build-gcc-7-linux.sh
+        script: build-gcc-linux.sh
     fetches:
         fetch:
             - binutils-2.31.1
             - gcc-7.4.0
             - gmp-6.1.0
             - isl-0.16.1
             - mpc-1.0.3
             - mpfr-3.1.4
 
 linux64-gcc-8:
     description: "GCC 8 toolchain build"
     treeherder:
         symbol: TL(gcc8)
     run:
-        script: build-gcc-8-linux.sh
+        script: build-gcc-linux.sh
     fetches:
         fetch:
             - binutils-2.31.1
             - gcc-8.3.0
             - gmp-6.1.0
             - isl-0.16.1
             - mpc-1.0.3
             - mpfr-3.1.4
 
 linux64-gcc-9:
     description: "GCC 9 toolchain build"
     treeherder:
         symbol: TL(gcc9)
     run:
-        script: build-gcc-9-linux.sh
+        script: build-gcc-linux.sh
     fetches:
         fetch:
             - binutils-2.31.1
             - gcc-9.1.0
             - gmp-6.1.0
             - isl-0.16.1
             - mpc-1.0.3
             - mpfr-3.1.4
@@ -76,18 +76,18 @@ linux64-gcc-sixgill:
     description: "sixgill GCC plugin build"
     treeherder:
         symbol: TL(sixgill)
     run:
         script: build-gcc-sixgill-plugin-linux.sh
         resources:
             - 'taskcluster/scripts/misc/build-gcc-sixgill-plugin-linux.sh'
         toolchain-artifact: public/build/sixgill.tar.xz
-    toolchains:
-        - linux64-gcc-6
     fetches:
         fetch:
             - binutils-2.31.1
             - isl-0.15
             - gcc-6.4.0
             - gmp-5.1.3
             - mpc-0.8.2
             - mpfr-3.1.5
+        toolchain:
+            - linux64-gcc-6
--- a/taskcluster/ci/toolchain/gn.yml
+++ b/taskcluster/ci/toolchain/gn.yml
@@ -6,50 +6,56 @@ job-defaults:
     description: "gn toolchain build"
     worker-type: b-linux
     worker:
         max-run-time: 1800
     run-on-projects:
         - trunk
         - try
     run:
-        tooltool-downloads: public
         resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
             - 'taskcluster/scripts/misc/build-gn-common.sh'
         toolchain-artifact: public/build/gn.tar.xz
     fetches:
         fetch:
             - gn
 
 linux64-gn:
     treeherder:
         symbol: TL(gn)
     run:
         script: build-gn-linux.sh
-    toolchains:
-        - linux64-gcc-6
+    fetches:
+        toolchain:
+            - linux64-gcc-6
 
 macosx64-gn:
     treeherder:
         symbol: TM(gn)
     worker:
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-clang.manifest"
     run:
         script: build-gn-macosx.sh
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
         tooltool-downloads: internal
-    toolchains:
-        - linux64-cctools-port
-        - linux64-clang-8
-        - linux64-node
+    fetches:
+        toolchain:
+            - linux64-cctools-port
+            - linux64-clang-8
 
 win32-gn:
     treeherder:
         symbol: TW64(gn)
     worker-type: b-win2012
     worker:
         max-run-time: 3600
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/gn-build.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         script: build-gn-win32.sh
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/gn.tar.bz2
+    fetches:
+        fetch:
+            - ninja
--- a/taskcluster/ci/toolchain/grcov.yml
+++ b/taskcluster/ci/toolchain/grcov.yml
@@ -4,41 +4,44 @@
 ---
 job-defaults:
     description: "grcov toolchain build"
     worker-type: b-linux
     worker:
         max-run-time: 1800
     run:
         script: build-grcov.sh
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/grcov.tar.xz
     fetches:
         fetch:
             - grcov
 
 linux64-grcov:
     treeherder:
         symbol: TL(grcov)
-    toolchains:
-        - linux64-rust-1.32
+    fetches:
+        toolchain:
+            - linux64-rust-1.32
 
 macosx64-grcov:
     treeherder:
         symbol: TM(grcov)
     run-on-projects:
         - trunk
         - try
-    toolchains:
-        - linux64-rust-1.32
+    fetches:
+        toolchain:
+            - linux64-rust-1.32
 
 win64-grcov:
     treeherder:
         symbol: TW64(grcov)
     worker-type: b-win2012
     worker:
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/sccache-build.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         toolchain-artifact: public/build/grcov.tar.bz2
-    toolchains:
-        - win64-rust-1.34
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+    fetches:
+        toolchain:
+            - win64-rust-1.34
--- a/taskcluster/ci/toolchain/kind.yml
+++ b/taskcluster/ci/toolchain/kind.yml
@@ -4,17 +4,16 @@
 ---
 loader: taskgraph.loader.transform:loader
 
 kind-dependencies:
     - fetch
 
 transforms:
     - taskgraph.transforms.try_job:transforms
-    - taskgraph.transforms.use_toolchains:transforms
     - taskgraph.transforms.job:transforms
     - taskgraph.transforms.cached_tasks:transforms
     - taskgraph.transforms.task:transforms
 
 job-defaults:
     treeherder:
         kind: build
         platform: toolchains/opt
--- a/taskcluster/ci/toolchain/mingw.yml
+++ b/taskcluster/ci/toolchain/mingw.yml
@@ -48,30 +48,30 @@ linux64-mingw32-nsis:
     treeherder:
         symbol: TMW(mingw32-nsis)
     run:
         script: build-mingw32-nsis.sh
         resources:
             - 'build/unix/build-gcc/build-gcc.sh'
             - 'taskcluster/scripts/misc/build-gcc-mingw32.sh'
         toolchain-artifact: public/build/nsis.tar.xz
-    toolchains:
-        - linux64-mingw32-gcc
     fetches:
         fetch:
             - nsis-3.01
             - zlib-1.2.11
+        toolchain:
+            - linux64-mingw32-gcc
 
 linux64-mingw-fxc2-x86:
     description: "fxc2.exe x86 build for MinGW Cross Compile"
     treeherder:
         symbol: TMW(mingw-fxc2-x86)
     worker:
         max-run-time: 1800
     run:
         using: toolchain-script
         script: build-mingw-fxc2-x86.sh
         toolchain-artifact: public/build/fxc2.tar.xz
-    toolchains:
-        - linux64-clang-8-mingw-x86
     fetches:
         fetch:
             - fxc2
+        toolchain:
+            - linux64-clang-8-mingw-x86
--- a/taskcluster/ci/toolchain/minidump_stackwalk.yml
+++ b/taskcluster/ci/toolchain/minidump_stackwalk.yml
@@ -10,52 +10,56 @@ job-defaults:
     run:
         script: build-minidump-stackwalk.sh
         sparse-profile: null
         resources:
             - 'build/moz.configure'
             - 'config/external/zlib'
             - 'mfbt'
             - 'moz.configure'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
             - 'testing/tools/fileid'
             - 'toolkit/crashreporter'
             - 'toolkit/crashreporter/google-breakpad/src/common'
             - 'toolkit/crashreporter/google-breakpad/src/processor'
             - 'toolkit/crashreporter/rust'
             - 'tools/crashreporter/'
         toolchain-artifact: public/build/minidump_stackwalk.tar.xz
     run-on-projects:
         - trunk
         - try
 
 linux64-minidump-stackwalk:
     treeherder:
         symbol: TL(stackwalk)
-    toolchains:
-        - linux64-clang-8
-        - linux64-binutils
-        - linux64-rust-1.31
+    fetches:
+        toolchain:
+            - linux64-clang-8
+            - linux64-binutils
+            - linux64-rust-1.31
 
 macosx64-minidump-stackwalk:
     treeherder:
         symbol: TM(stackwalk)
     worker:
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-clang.manifest"
     run:
         arguments: ['macosx64']
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
         tooltool-downloads: internal
-    toolchains:
-        - linux64-cctools-port
-        - linux64-clang-8
-        - linux64-rust-macos-1.31
+    fetches:
+        toolchain:
+            - linux64-cctools-port
+            - linux64-clang-8
+            - linux64-rust-macos-1.31
 
 win32-minidump-stackwalk:
     treeherder:
         symbol: TW32(stackwalk)
     worker:
         docker-image: {in-tree: mingw32-build}
     run:
         arguments: ['mingw32']
-    toolchains:
-        - linux64-clang-8-mingw-x86
-        - mingw32-rust-1.31
+    fetches:
+        toolchain:
+            - linux64-clang-8-mingw-x86
+            - mingw32-rust-1.31
--- a/taskcluster/ci/toolchain/misc.yml
+++ b/taskcluster/ci/toolchain/misc.yml
@@ -26,21 +26,21 @@ linux64-infer:
 
 linux64-llvm-dsymutil:
     description: "llvm-dsymutil toolchain build"
     treeherder:
         symbol: TL(dsymutil)
     run:
         script: build-llvm-dsymutil.sh
         toolchain-artifact: public/build/llvm-dsymutil.tar.xz
-    toolchains:
-        - linux64-gcc-6
     fetches:
         fetch:
             - llvm-for-dsymutil
+        toolchain:
+            - linux64-gcc-6
 
 linux64-binutils:
     description: "Binutils toolchain build"
     treeherder:
         symbol: TL(binutil)
     worker:
         max-run-time: 3600
     run:
@@ -55,42 +55,42 @@ linux64-binutils:
 linux64-hfsplus:
     description: "hfsplus toolchain build"
     treeherder:
         symbol: TL(hfs+)
     run:
         script: build-hfsplus-linux.sh
         resources:
             - 'build/unix/build-hfsplus/build-hfsplus.sh'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/hfsplus-tools.tar.xz
-    toolchains:
-        - linux64-clang-8
     fetches:
         fetch:
             - hfsplus-tools
+        toolchain:
+            - linux64-clang-8
 
 linux64-libdmg:
     description: "libdmg-hfsplus toolchain build"
     treeherder:
         symbol: TL(libdmg-hfs+)
     run:
         script: build-libdmg-hfsplus.sh
         toolchain-artifact: public/build/dmg.tar.xz
     fetches:
         fetch:
             - libdmg-hfsplus
 
 linux64-mar-tools:
     description: "mar-tools toolchain build"
     treeherder:
         symbol: TL(mar-tools)
-    toolchains:
-        - linux64-clang-7
-        - linux64-binutils
+    fetches:
+        toolchain:
+            - linux64-clang-7
+            - linux64-binutils
     run:
         script: build-mar-tools.sh
         sparse-profile: null
         toolchain-artifact: public/build/mar-tools.tar.xz
         resources:
             - build/moz.configure
             - mfbt
             - modules/libmar/
@@ -103,27 +103,25 @@ linux64-mar-tools:
 linux64-tup:
     description: "tup toolchain build"
     treeherder:
         symbol: TL(tup)
     worker:
         max-run-time: 3600
     run:
         script: build-tup-linux.sh
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/tup.tar.xz
     run-on-projects:
         - trunk
         - try
-    toolchains:
-        - linux64-gcc-6
     fetches:
         fetch:
             - tup
+        toolchain:
+            - linux64-gcc-6
 
 linux64-upx:
     description: "UPX build"
     treeherder:
         symbol: TL(upx)
         tier: 1
     run:
         script: build-upx.sh
@@ -144,39 +142,36 @@ linux64-custom-v8:
             target_cpu="x64"
         ]
         toolchain-artifact: public/build/d8.zip
 
 browsertime:
     description: "npm install browsertime node_modules"
     treeherder:
         symbol: TL(browsertime)
-    worker:
-        env:
-            NODEJS: "/builds/worker/workspace/build/src/node/bin/node"
     run:
         script: browsertime.sh
         sparse-profile: null
         resources:
             - 'tools/browsertime/package.json'
             - 'tools/browsertime/mach_commands.py'
         toolchain-artifact: public/build/browsertime.zip
-    toolchains:
-        - linux64-node
+    fetches:
+        toolchain:
+            - linux64-node
 
 wrench-deps:
     description: "Downloads all the crates needed for building wrench"
     treeherder:
         symbol: WR(wrench-deps)
     worker:
         docker-image: {in-tree: webrender}
     run:
         script: wrench-deps-vendoring.sh
         sparse-profile: null  # need all of gfx/wr checked out for this script
         resources:
             - 'gfx/wr/Cargo.lock'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/wrench-deps.tar.bz2
-    toolchains:
-        - linux64-rust-1.36  # whatever m-c is built with
     fetches:
         fetch:
             - android-rs-glue
+        toolchain:
+            - linux64-rust-1.36  # whatever m-c is built with
--- a/taskcluster/ci/toolchain/nasm.yml
+++ b/taskcluster/ci/toolchain/nasm.yml
@@ -2,34 +2,32 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 ---
 job-defaults:
     worker-type: b-linux
     worker:
         max-run-time: 1800
     run:
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/nasm.tar.bz2
 
 win64-nasm:
     description: "nasm win64 build"
     treeherder:
         symbol: TW64(nasm)
     worker:
         docker-image: {in-tree: mingw32-build}
     run:
         script: build-nasm.sh
         arguments: ['win64']
-    toolchains:
-        - linux64-clang-8-mingw-x64
     fetches:
         fetch:
             - nasm-2.14.02
+        toolchain:
+            - linux64-clang-8-mingw-x64
 
 linux64-nasm:
     description: "nasm linux64 build"
     treeherder:
         symbol: TL(nasm)
     run:
         script: build-nasm.sh
         arguments: ['linux64']
--- a/taskcluster/ci/toolchain/rust-size.yml
+++ b/taskcluster/ci/toolchain/rust-size.yml
@@ -3,34 +3,36 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 ---
 job-defaults:
     description: "rust-size toolchain build"
     worker:
         max-run-time: 1800
     run:
         script: build-rust-size.sh
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
     fetches:
         fetch:
             - rust-size
 
 linux64-rust-size:
     treeherder:
         symbol: TL(rust-size)
     worker-type: b-linux
     run:
         toolchain-artifact: public/build/rust-size.tar.xz
-    toolchains:
-        - linux64-rust-1.28
+    fetches:
+        toolchain:
+            - linux64-rust-1.28
 
 win64-rust-size:
     treeherder:
         symbol: TW64(rust-size)
     worker-type: b-win2012
     worker:
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/sccache-build.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         toolchain-artifact: public/build/rust-size.tar.bz2
-    toolchains:
-        - win64-rust-1.28
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+    fetches:
+        toolchain:
+            - win64-rust-1.28
--- a/taskcluster/ci/toolchain/sccache.yml
+++ b/taskcluster/ci/toolchain/sccache.yml
@@ -4,63 +4,67 @@
 ---
 job-defaults:
     description: "sccache toolchain build"
     treeherder:
         symbol: TL(sccache)
     run:
         using: toolchain-script
         script: build-sccache.sh
-        resources:
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
     fetches:
         fetch:
             - sccache
 
 linux64-sccache:
     treeherder:
         symbol: TL(sccache)
     worker-type: b-linux
     worker:
         max-run-time: 1800
     run:
         toolchain-artifact: public/build/sccache.tar.xz
-    toolchains:
-        - linux64-rust-1.34
-        - linux64-binutils
     fetches:
         fetch:
             - openssl-1.1.0g
+        toolchain:
+            - linux64-rust-1.34
+            - linux64-binutils
 
 macosx64-sccache:
     treeherder:
         symbol: TM(sccache)
     worker-type: b-linux
     worker:
         max-run-time: 1800
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-clang.manifest"
     run-on-projects:
         - trunk
         - try
     run:
         arguments: ['x86_64-apple-darwin']
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
         tooltool-downloads: internal
         toolchain-artifact: public/build/sccache.tar.xz
-    toolchains:
-        - linux64-rust-macos-1.34
-        - linux64-clang-8
-        - linux64-cctools-port
-        - linux64-llvm-dsymutil
-        - linux64-binutils
+    fetches:
+        toolchain:
+            - linux64-rust-macos-1.34
+            - linux64-clang-8
+            - linux64-cctools-port
+            - linux64-llvm-dsymutil
+            - linux64-binutils
 
 win64-sccache:
     treeherder:
         symbol: TW64(sccache)
     worker-type: b-win2012
     worker:
         max-run-time: 3600
         env:
-            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/sccache-build.manifest"
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/vs2017.manifest"
     run:
         toolchain-artifact: public/build/sccache.tar.bz2
-    toolchains:
-        - win64-rust-1.34
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+    fetches:
+        toolchain:
+            - win64-rust-1.34
--- a/taskcluster/ci/webrender/kind.yml
+++ b/taskcluster/ci/webrender/kind.yml
@@ -92,17 +92,17 @@ jobs:
                 - 'gfx/wr/**'
 
     wrench-macos-build:
         description: Cross compilation of wrench for macOS on Linux
         worker-type: b-linux
         worker:
             docker-image: {in-tree: webrender}
             env:
-                TOOLTOOL_MANIFEST: "/builds/worker/checkouts/gecko/browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
+                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
             chain-of-trust: true
             artifacts:
                 - type: file
                   name: public/build/wrench-macos.tar.bz2
                   path: /builds/worker/artifacts/wrench-macos.tar.bz2
                 - type: file
                   name: public/build/wrench-macos-headless.tar.bz2
                   path: /builds/worker/artifacts/wrench-macos-headless.tar.bz2
@@ -155,17 +155,17 @@ jobs:
                 - 'gfx/wr/**'
 
     cargotest-macos-build:
         description: Cross compilation of cargo tests for macOS on Linux
         worker-type: b-linux
         worker:
             docker-image: {in-tree: webrender}
             env:
-                TOOLTOOL_MANIFEST: "/builds/worker/checkouts/gecko/browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
+                TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
             chain-of-trust: true
             artifacts:
                 - type: file
                   name: public/build/cargo-test-binaries.tar.bz2
                   path: /builds/worker/artifacts/cargo-test-binaries.tar.bz2
         fetches:
             toolchain:
                 - linux64-rust-macos
--- a/taskcluster/scripts/misc/android-gradle-dependencies.sh
+++ b/taskcluster/scripts/misc/android-gradle-dependencies.sh
@@ -3,18 +3,15 @@
 set -x -e
 
 echo "running as" $(id)
 
 set -v
 
 cd $GECKO_PATH
 
-# Download toolchain artifacts.
-. taskcluster/scripts/misc/tooltool-download.sh
-
 . taskcluster/scripts/misc/android-gradle-dependencies/before.sh
 
 export MOZCONFIG=mobile/android/config/mozconfigs/android-api-16-gradle-dependencies/nightly
 ./mach build
 ./mach android gradle-dependencies
 
 . taskcluster/scripts/misc/android-gradle-dependencies/after.sh
--- a/taskcluster/scripts/misc/browsertime.sh
+++ b/taskcluster/scripts/misc/browsertime.sh
@@ -3,21 +3,17 @@
 set -x -e
 
 echo "running as" $(id)
 
 set -v
 
 cd $GECKO_PATH
 
-# Download toolchain artifacts.
-. taskcluster/scripts/misc/tooltool-download.sh
-
-# We can't set the path to npm directly, but it's sibling to NODEJS.
-export PATH=$PATH:`dirname $NODEJS`
+export PATH=$PATH:$MOZ_FETCHES_DIR/node/bin
 
 # We don't install ImageMagick, so this will fail.  Continue.
 ./mach browsertime --setup || true
 
 # We have tools/browsertime/{package.json,node_modules,...} and want
 # browsertime/{package.json,node_modules}.  ZIP because generic-worker
 # doesn't support .tar.xz.
 mkdir -p  /builds/worker/artifacts
--- a/taskcluster/scripts/misc/build-cbindgen.sh
+++ b/taskcluster/scripts/misc/build-cbindgen.sh
@@ -14,36 +14,38 @@ MINGW*)
     . $GECKO_PATH/taskcluster/scripts/misc/vs-setup.sh
 
     export CC=clang-cl
     ;;
 esac
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
+if [ -n "$TOOLTOOL_MANIFEST" ]; then
+  . taskcluster/scripts/misc/tooltool-download.sh
+fi
 
 # OSX cross builds are a bit harder
 if [ "$TARGET" == "x86_64-apple-darwin" ]; then
-  export PATH="$GECKO_PATH/llvm-dsymutil/bin:$PATH"
-  export PATH="$GECKO_PATH/cctools/bin:$PATH"
+  export PATH="$MOZ_FETCHES_DIR/llvm-dsymutil/bin:$PATH"
+  export PATH="$MOZ_FETCHES_DIR/cctools/bin:$PATH"
   cat >cross-linker <<EOF
-exec $GECKO_PATH/clang/bin/clang -v \
-  -fuse-ld=$GECKO_PATH/cctools/bin/x86_64-apple-darwin-ld \
+exec $MOZ_FETCHES_DIR/clang/bin/clang -v \
+  -fuse-ld=$MOZ_FETCHES_DIR/cctools/bin/x86_64-apple-darwin-ld \
   -mmacosx-version-min=10.11 \
   -target $TARGET \
-  -B $GECKO_PATH/cctools/bin \
-  -isysroot $GECKO_PATH/MacOSX10.11.sdk \
+  -B $MOZ_FETCHES_DIR/cctools/bin \
+  -isysroot $MOZ_FETCHES_DIR/MacOSX10.11.sdk \
   "\$@"
 EOF
   chmod +x cross-linker
   export RUSTFLAGS="-C linker=$PWD/cross-linker"
 fi
 
-export PATH="$(cd $GECKO_PATH && pwd)/rustc/bin:$PATH"
+export PATH="$(cd $MOZ_FETCHES_DIR && pwd)/rustc/bin:$PATH"
 
 cd $MOZ_FETCHES_DIR/cbindgen
 
 cargo build --verbose --release --target "$TARGET"
 
 mkdir cbindgen
 cp target/$TARGET/release/cbindgen* cbindgen/
 tar -acf cbindgen.tar.$COMPRESS_EXT cbindgen
--- a/taskcluster/scripts/misc/build-cctools-port.sh
+++ b/taskcluster/scripts/misc/build-cctools-port.sh
@@ -11,26 +11,24 @@ set -x -e -v
 WORKSPACE=$HOME/workspace
 
 # Set some crosstools-port and libtapi directories
 CROSSTOOLS_SOURCE_DIR=$MOZ_FETCHES_DIR/cctools-port
 CROSSTOOLS_CCTOOLS_DIR=$CROSSTOOLS_SOURCE_DIR/cctools
 CROSSTOOLS_BUILD_DIR=$WORKSPACE/cctools
 LIBTAPI_SOURCE_DIR=$MOZ_FETCHES_DIR/apple-libtapi
 LIBTAPI_BUILD_DIR=$WORKSPACE/libtapi-build
-CLANG_DIR=$GECKO_PATH/clang
+CLANG_DIR=$MOZ_FETCHES_DIR/clang
 
 # Create our directories
 mkdir -p $CROSSTOOLS_BUILD_DIR $LIBTAPI_BUILD_DIR
 
-# Fetch clang from tooltool
 cd $GECKO_PATH
-. taskcluster/scripts/misc/tooltool-download.sh
 
-export PATH="$GECKO_PATH/binutils/bin:$PATH"
+export PATH="$MOZ_FETCHES_DIR/binutils/bin:$PATH"
 
 # Common setup for libtapi and cctools
 export CC=$CLANG_DIR/bin/clang
 export CXX=$CLANG_DIR/bin/clang++
 # We also need this LD_LIBRARY_PATH at build time, since tapi builds bits of
 # clang build tools, and then executes those tools.
 export LD_LIBRARY_PATH=$CLANG_DIR/lib
 
--- a/taskcluster/scripts/misc/build-clang-8-linux-macosx-cross.sh
+++ b/taskcluster/scripts/misc/build-clang-8-linux-macosx-cross.sh
@@ -1,37 +1,37 @@
 #!/bin/bash
 set -x -e -v
 
 # This script is for building clang for Mac OS X targets on a Linux host,
 # including native Mac OS X Compiler-RT libraries and llvm-symbolizer.
-WORKSPACE=$HOME/workspace
 
 cd $GECKO_PATH
 
 . taskcluster/scripts/misc/tooltool-download.sh
 
 # these variables are used in build-clang.py
-export CROSS_CCTOOLS_PATH=$GECKO_PATH/cctools
-export CROSS_SYSROOT=$GECKO_PATH/MacOSX10.11.sdk
+export CROSS_CCTOOLS_PATH=$MOZ_FETCHES_DIR/cctools
+export CROSS_SYSROOT=$MOZ_FETCHES_DIR/MacOSX10.11.sdk
 export PATH=$PATH:$CROSS_CCTOOLS_PATH/bin
 
 # gets a bit too verbose here
 set +x
 
-python3 build/build-clang/build-clang.py -c $1 --skip-tar
+cd $MOZ_FETCHES_DIR/llvm-project
+python3 $GECKO_PATH/build/build-clang/build-clang.py -c $GECKO_PATH/$1 --skip-tar
 
 # We now have a native macosx64 toolchain.
 # What we want is a native linux64 toolchain which can target macosx64 and use the sanitizer dylibs.
 # Overlay the linux64 toolchain that we used for this build (except llvm-symbolizer).
 (
-cd "$WORKSPACE/moz-toolchain/build/stage1"
+cd build/stage1
 # Need the macosx64 native llvm-symbolizer since this gets shipped with sanitizer builds
-mv clang/bin/llvm-symbolizer $GECKO_PATH/clang/bin/
-cp --remove-destination -lr $GECKO_PATH/clang/* clang/
-tar -c -J -f $GECKO_PATH/clang.tar.xz clang
+mv clang/bin/llvm-symbolizer $MOZ_FETCHES_DIR/clang/bin/
+cp --remove-destination -lr $MOZ_FETCHES_DIR/clang/* clang/
+tar -c -J -f $MOZ_FETCHES_DIR/llvm-project/clang.tar.xz clang
 )
 
 set -x
 
 # Put a tarball in the artifacts dir
 mkdir -p $UPLOAD_DIR
 cp clang.tar.* $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-clang-8-mingw.sh
+++ b/taskcluster/scripts/misc/build-clang-8-mingw.sh
@@ -16,38 +16,31 @@ elif [ "$1" == "x64" ]; then
   compiler_rt_machine="x86_64"
   crt_flags="--disable-lib32 --enable-lib64"
   WRAPPER_FLAGS=""
 else
   echo "Provide either x86 or x64 to specify a toolchain."
   exit 1;
 fi
 
-WORKSPACE=$HOME/workspace
-
-TOOLCHAIN_DIR=$WORKSPACE/moz-toolchain
+TOOLCHAIN_DIR=$MOZ_FETCHES_DIR/llvm-project
 INSTALL_DIR=$TOOLCHAIN_DIR/build/stage3/clang
 CROSS_PREFIX_DIR=$INSTALL_DIR/$machine-w64-mingw32
-SRC_DIR=$TOOLCHAIN_DIR/src
 
 make_flags="-j$(nproc)"
 
 # This is default value of _WIN32_WINNT. Gecko configure script explicitly sets this,
 # so this is not used to build Gecko itself. We default to 0x601, which is Windows 7.
 default_win32_winnt=0x601
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
 patch_file="$(pwd)/taskcluster/scripts/misc/mingw-winrt.patch"
 
 prepare() {
-  mkdir -p $TOOLCHAIN_DIR
-  touch $TOOLCHAIN_DIR/.build-clang
-
   pushd $MOZ_FETCHES_DIR/mingw-w64
   patch -p1 <$patch_file
   popd
 }
 
 install_wrappers() {
   pushd $INSTALL_DIR/bin
 
@@ -117,17 +110,17 @@ build_compiler_rt() {
       -DCMAKE_BUILD_TYPE=Release \
       -DCMAKE_C_COMPILER=$CC \
       -DCMAKE_SYSTEM_NAME=Windows \
       -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
       -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
       -DCMAKE_C_COMPILER_WORKS=1 \
       -DCMAKE_C_COMPILER_TARGET=$compiler_rt_machine-windows-gnu \
       -DCOMPILER_RT_DEFAULT_TARGET_ONLY=TRUE \
-      $SRC_DIR/compiler-rt/lib/builtins
+      $TOOLCHAIN_DIR/compiler-rt/lib/builtins
   make $make_flags
   mkdir -p $INSTALL_DIR/lib/clang/$CLANG_VERSION/lib/windows
   cp lib/windows/libclang_rt.builtins-$compiler_rt_machine.a $INSTALL_DIR/lib/clang/$CLANG_VERSION/lib/windows/
   popd
 }
 
 merge_libs() {
   cat <<EOF |llvm-ar -M
@@ -165,17 +158,17 @@ build_libcxx() {
       -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
       -DLLVM_NO_OLD_LIBSTDCXX=TRUE \
       -DCXX_SUPPORTS_CXX11=TRUE \
       -DCXX_SUPPORTS_CXX_STD=TRUE \
       -DLIBUNWIND_USE_COMPILER_RT=TRUE \
       -DLIBUNWIND_ENABLE_THREADS=TRUE \
       -DLIBUNWIND_ENABLE_SHARED=FALSE \
       -DLIBUNWIND_ENABLE_CROSS_UNWINDING=FALSE \
-      -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -Wno-dll-attribute-on-redeclaration -nostdinc++ -I$SRC_DIR/libcxx/include -DPSAPI_VERSION=2" \
+      -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -Wno-dll-attribute-on-redeclaration -nostdinc++ -I$TOOLCHAIN_DIR/libcxx/include -DPSAPI_VERSION=2" \
       -DCMAKE_C_FLAGS="-Wno-dll-attribute-on-redeclaration" \
       $MOZ_FETCHES_DIR/libunwind
   make $make_flags
   make $make_flags install
   popd
 
   mkdir libcxxabi
   pushd libcxxabi
@@ -192,22 +185,22 @@ build_libcxx() {
       -DLLVM_COMPILER_CHECKED=TRUE \
       -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
       -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
       -DLIBCXXABI_USE_COMPILER_RT=ON \
       -DLIBCXXABI_ENABLE_EXCEPTIONS=ON \
       -DLIBCXXABI_ENABLE_THREADS=ON \
       -DLIBCXXABI_TARGET_TRIPLE=$machine-w64-mingw32 \
       -DLIBCXXABI_ENABLE_SHARED=OFF \
-      -DLIBCXXABI_LIBCXX_INCLUDES=$SRC_DIR/libcxx/include \
+      -DLIBCXXABI_LIBCXX_INCLUDES=$TOOLCHAIN_DIR/libcxx/include \
       -DLLVM_NO_OLD_LIBSTDCXX=TRUE \
       -DCXX_SUPPORTS_CXX11=TRUE \
       -DCXX_SUPPORTS_CXX_STD=TRUE \
       -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_HAS_THREAD_API_WIN32" \
-      $SRC_DIR/libcxxabi
+      $TOOLCHAIN_DIR/libcxxabi
   make $make_flags VERBOSE=1
   popd
 
   mkdir libcxx
   pushd libcxx
   cmake \
       -DCMAKE_BUILD_TYPE=Release \
       -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \
@@ -228,20 +221,20 @@ build_libcxx() {
       -DLIBCXX_ENABLE_MONOTONIC_CLOCK=ON \
       -DLIBCXX_ENABLE_SHARED=OFF \
       -DLIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG=TRUE \
       -DLIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB=TRUE \
       -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \
       -DLIBCXX_ENABLE_FILESYSTEM=OFF \
       -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE \
       -DLIBCXX_CXX_ABI=libcxxabi \
-      -DLIBCXX_CXX_ABI_INCLUDE_PATHS=$SRC_DIR/libcxxabi/include \
+      -DLIBCXX_CXX_ABI_INCLUDE_PATHS=$TOOLCHAIN_DIR/libcxxabi/include \
       -DLIBCXX_CXX_ABI_LIBRARY_PATH=../libcxxabi/lib \
       -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS" \
-      $SRC_DIR/libcxx
+      $TOOLCHAIN_DIR/libcxx
   make $make_flags VERBOSE=1
   make $make_flags install
 
   # libc++.a depends on libunwind.a. Whild linker will automatically link
   # to libc++.a in C++ mode, it won't pick libunwind.a, requiring caller
   # to explicitly pass -lunwind. Wo work around that, we merge libunwind.a
   # into libc++.a.
   merge_libs $CROSS_PREFIX_DIR/lib/libc++.a $CROSS_PREFIX_DIR/lib/libunwind.a
@@ -260,17 +253,18 @@ build_utils() {
 
 export PATH=$INSTALL_DIR/bin:$PATH
 
 prepare
 
 # gets a bit too verbose here
 set +x
 
-python3 build/build-clang/build-clang.py -c $2 --skip-tar
+cd $TOOLCHAIN_DIR
+python3 $GECKO_PATH/build/build-clang/build-clang.py -c $GECKO_PATH/$2 --skip-tar
 
 set -x
 
 pushd $TOOLCHAIN_DIR/build
 
 install_wrappers
 build_mingw
 build_compiler_rt
--- a/taskcluster/scripts/misc/build-clang.sh
+++ b/taskcluster/scripts/misc/build-clang.sh
@@ -3,53 +3,54 @@ set -x -e -v
 
 # This script is for building clang.
 
 ORIGPWD="$PWD"
 JSON_CONFIG="$1"
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
+if [ -n "$TOOLTOOL_MANIFEST" ]; then
+  . taskcluster/scripts/misc/tooltool-download.sh
+fi
 
-if [ -d "$GECKO_PATH/binutils/bin" ]; then
-  export PATH="$GECKO_PATH/binutils/bin:$PATH"
+if [ -d "$MOZ_FETCHES_DIR/binutils/bin" ]; then
+  export PATH="$MOZ_FETCHES_DIR/binutils/bin:$PATH"
 fi
 
 case "$JSON_CONFIG" in
 *macosx64*)
   # these variables are used in build-clang.py
-  export CROSS_CCTOOLS_PATH=$GECKO_PATH/cctools
-  export CROSS_SYSROOT=$GECKO_PATH/MacOSX10.11.sdk
+  export CROSS_CCTOOLS_PATH=$MOZ_FETCHES_DIR/cctools
+  export CROSS_SYSROOT=$MOZ_FETCHES_DIR/MacOSX10.11.sdk
   export PATH=$PATH:$CROSS_CCTOOLS_PATH/bin
   ;;
 *win64*)
   UPLOAD_DIR=$ORIGPWD/public/build
   # Set up all the Visual Studio paths.
   . taskcluster/scripts/misc/vs-setup.sh
 
   # LLVM_ENABLE_DIA_SDK is set if the directory "$ENV{VSINSTALLDIR}DIA SDK"
   # exists.
   export VSINSTALLDIR="${VSPATH}/"
 
-  # Add git.exe to the path
-  export PATH="$(pwd)/cmd:${PATH}"
-  export PATH="$(cd cmake && pwd)/bin:${PATH}"
-  export PATH="$(cd ninja && pwd)/bin:${PATH}"
+  export PATH="$(cd $MOZ_FETCHES_DIR/cmake && pwd)/bin:${PATH}"
+  export PATH="$(cd $MOZ_FETCHES_DIR/ninja && pwd)/bin:${PATH}"
   ;;
 *linux64*|*android*)
   ;;
 *)
   echo Cannot figure out build configuration for $JSON_CONFIG
   exit 1
   ;;
 esac
 
 # gets a bit too verbose here
 set +x
 
-python3 build/build-clang/build-clang.py -c $1
+cd $MOZ_FETCHES_DIR/llvm-project
+python3 $GECKO_PATH/build/build-clang/build-clang.py -c $GECKO_PATH/$1
 
 set -x
 
 # Put a tarball in the artifacts dir
 mkdir -p $UPLOAD_DIR
 cp clang*.tar.* $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-dist-toolchains.sh
+++ b/taskcluster/scripts/misc/build-dist-toolchains.sh
@@ -1,11 +1,9 @@
 #!/bin/bash
 set -x -e -v
 
 # This script is for packaging toolchains suitable for use by distributed sccache.
 TL_NAME="$1"
 
-cd $GECKO_PATH
+mkdir -p $HOME/artifacts
 
-. taskcluster/scripts/misc/tooltool-download.sh
-
-sccache/sccache --package-toolchain $GECKO_PATH/$TL_NAME/bin/$TL_NAME $HOME/artifacts/$TL_NAME-dist-toolchain.tar.xz
+$MOZ_FETCHES_DIR/sccache/sccache --package-toolchain $MOZ_FETCHES_DIR/$TL_NAME/bin/$TL_NAME $HOME/artifacts/$TL_NAME-dist-toolchain.tar.xz
deleted file mode 100755
--- a/taskcluster/scripts/misc/build-gcc-6-linux.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-set -e
-
-# This script is for building GCC 6 for Linux.
-
-root_dir=$MOZ_FETCHES_DIR
-data_dir=$GECKO_PATH/build/unix/build-gcc
-
-. $data_dir/build-gcc.sh
-
-gcc_version=6.4.0
-gcc_ext=xz
-binutils_version=2.31.1
-binutils_ext=xz
-
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../gmp-5.1.3 gmp
-ln -sf ../isl-0.15 isl
-ln -sf ../mpc-0.8.2 mpc
-ln -sf ../mpfr-3.1.5 mpfr
-popd
-
-build_binutils
-build_gcc
-
-# Put a tarball in the artifacts dir
-mkdir -p $UPLOAD_DIR
-cp $MOZ_FETCHES_DIR/gcc.tar.* $UPLOAD_DIR
deleted file mode 100755
--- a/taskcluster/scripts/misc/build-gcc-7-linux.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-set -e
-
-# This script is for building GCC 7 for Linux.
-
-root_dir=$MOZ_FETCHES_DIR
-data_dir=$GECKO_PATH/build/unix/build-gcc
-
-. $data_dir/build-gcc.sh
-
-gcc_version=7.4.0
-gcc_ext=xz
-binutils_version=2.31.1
-binutils_ext=xz
-
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../gmp-6.1.0 gmp
-ln -sf ../isl-0.16.1 isl
-ln -sf ../mpc-1.0.3 mpc
-ln -sf ../mpfr-3.1.4 mpfr
-popd
-
-build_binutils
-build_gcc
-
-# Put a tarball in the artifacts dir
-mkdir -p $UPLOAD_DIR
-cp $MOZ_FETCHES_DIR/gcc.tar.* $UPLOAD_DIR
deleted file mode 100755
--- a/taskcluster/scripts/misc/build-gcc-8-linux.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-set -e
-
-# This script is for building GCC 7 for Linux.
-
-root_dir=$MOZ_FETCHES_DIR
-data_dir=$GECKO_PATH/build/unix/build-gcc
-
-. $data_dir/build-gcc.sh
-
-gcc_version=8.3.0
-gcc_ext=xz
-binutils_version=2.31.1
-binutils_ext=xz
-
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../gmp-6.1.0 gmp
-ln -sf ../isl-0.16.1 isl
-ln -sf ../mpc-1.0.3 mpc
-ln -sf ../mpfr-3.1.4 mpfr
-popd
-
-build_binutils
-build_gcc
-
-# Put a tarball in the artifacts dir
-mkdir -p $UPLOAD_DIR
-cp $MOZ_FETCHES_DIR/gcc.tar.* $UPLOAD_DIR
deleted file mode 100755
--- a/taskcluster/scripts/misc/build-gcc-9-linux.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-set -e
-
-# This script is for building GCC 7 for Linux.
-
-root_dir=$MOZ_FETCHES_DIR
-data_dir=$GECKO_PATH/build/unix/build-gcc
-
-. $data_dir/build-gcc.sh
-
-gcc_version=9.1.0
-gcc_ext=xz
-binutils_version=2.31.1
-binutils_ext=xz
-
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../gmp-6.1.0 gmp
-ln -sf ../isl-0.16.1 isl
-ln -sf ../mpc-1.0.3 mpc
-ln -sf ../mpfr-3.1.4 mpfr
-popd
-
-build_binutils
-build_gcc
-
-# Put a tarball in the artifacts dir
-mkdir -p $UPLOAD_DIR
-cp $MOZ_FETCHES_DIR/gcc.tar.* $UPLOAD_DIR
new file mode 100755
--- /dev/null
+++ b/taskcluster/scripts/misc/build-gcc-linux.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -e
+
+# This script is for building GCC for Linux.
+
+root_dir=$MOZ_FETCHES_DIR
+data_dir=$GECKO_PATH/build/unix/build-gcc
+
+. $data_dir/build-gcc.sh
+
+pushd $root_dir/gcc-source
+ln -sf ../gmp-source gmp
+ln -sf ../isl-source isl
+ln -sf ../mpc-source mpc
+ln -sf ../mpfr-source mpfr
+popd
+
+build_binutils
+build_gcc
+
+# Put a tarball in the artifacts dir
+mkdir -p $UPLOAD_DIR
+cp $MOZ_FETCHES_DIR/gcc.tar.* $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-gcc-mingw32.sh
+++ b/taskcluster/scripts/misc/build-gcc-mingw32.sh
@@ -3,28 +3,24 @@ set -e
 
 # This script is for building a MinGW GCC (and headers) to be used on Linux to compile for Windows.
 
 root_dir=$MOZ_FETCHES_DIR
 data_dir=$GECKO_PATH/build/unix/build-gcc
 
 . $data_dir/build-gcc.sh
 
-gcc_version=6.4.0
-gcc_ext=xz
-binutils_version=2.27
-binutils_ext=bz2
 binutils_configure_flags="--target=i686-w64-mingw32"
 mingw_version=bcf1f29d6dc80b6025b416bef104d2314fa9be57
 
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../gmp-5.1.3 gmp
-ln -sf ../isl-0.15 isl
-ln -sf ../mpc-0.8.2 mpc
-ln -sf ../mpfr-3.1.5 mpfr
+pushd $root_dir/gcc-source
+ln -sf ../gmp-source gmp
+ln -sf ../isl-source isl
+ln -sf ../mpc-source mpc
+ln -sf ../mpfr-source mpfr
 popd
 
 prepare_mingw
 build_binutils
 build_gcc_and_mingw
 
 # Put a tarball in the artifacts dir
 mkdir -p $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-gcc-sixgill-plugin-linux.sh
+++ b/taskcluster/scripts/misc/build-gcc-sixgill-plugin-linux.sh
@@ -6,38 +6,31 @@ set -x
 # This script is for building the sixgill GCC plugin for Linux. It relies on
 # the gcc checkout because it needs to recompile gmp and the gcc build script
 # determines the version of gmp to download.
 
 root_dir=$MOZ_FETCHES_DIR
 build_dir=$GECKO_PATH/build
 data_dir=$GECKO_PATH/build/unix/build-gcc
 
-# Download and unpack upstream toolchain artifacts (ie, the gcc binary).
-. $(dirname $0)/tooltool-download.sh
-
-gcc_version=6.4.0
-gcc_ext=xz
-binutils_version=2.28.1
-binutils_ext=xz
 sixgill_rev=bc0ef9258470
 sixgill_repo=https://hg.mozilla.org/users/sfink_mozilla.com/sixgill
 
 . $data_dir/build-gcc.sh
 
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../binutils-2.31.1 binutils
-ln -sf ../gmp-5.1.3 gmp
-ln -sf ../isl-0.15 isl
-ln -sf ../mpc-0.8.2 mpc
-ln -sf ../mpfr-3.1.5 mpfr
+pushd $root_dir/gcc-source
+ln -sf ../binutils-source binutils
+ln -sf ../gmp-source gmp
+ln -sf ../isl-source isl
+ln -sf ../mpc-source mpc
+ln -sf ../mpfr-source mpfr
 popd
 
 export TMPDIR=${TMPDIR:-/tmp/}
-export gcc_bindir=$root_dir/src/gcc/bin
+export gcc_bindir=$MOZ_FETCHES_DIR/gcc/bin
 export gmp_prefix=/tools/gmp
 export gmp_dir=$root_dir$gmp_prefix
 
 prepare_sixgill() {(
     cd $root_dir
     hg clone -r $sixgill_rev $sixgill_repo || ( cd sixgill && hg update -r $sixgill_rev )
 )}
 
@@ -46,22 +39,22 @@ build_gmp() {
         echo "GCC not found in $gcc_bindir/gcc" >&2
         exit 1
     fi
 
     # The sixgill plugin uses some gmp symbols, including some not exported by
     # cc1/cc1plus. So link the plugin statically to libgmp. Except that the
     # default static build does not have -fPIC, and will result in a relocation
     # error, so build our own. This requires the gcc and related source to be
-    # in $root_dir/gcc-$gcc_version.
+    # in $root_dir/gcc-source.
 
     mkdir $root_dir/gmp-objdir || true
     (
         cd $root_dir/gmp-objdir
-        $root_dir/gcc-$gcc_version/gmp/configure --disable-shared --with-pic --prefix=$gmp_prefix
+        $root_dir/gcc-source/gmp/configure --disable-shared --with-pic --prefix=$gmp_prefix
         make -j8
         make install DESTDIR=$root_dir
     )
 }
 
 build_sixgill() {(
     cd $root_dir/sixgill
     export CC=$gcc_bindir/gcc
--- a/taskcluster/scripts/misc/build-gn-linux.sh
+++ b/taskcluster/scripts/misc/build-gn-linux.sh
@@ -1,22 +1,21 @@
 #!/bin/bash
 set -e -v
 
 # This script is for building GN on Linux.
 
 WORKSPACE=$HOME/workspace
 COMPRESS_EXT=xz
-export CC=$GECKO_PATH/gcc/bin/gcc
-export CXX=$GECKO_PATH/gcc/bin/g++
+export CC=$MOZ_FETCHES_DIR/gcc/bin/gcc
+export CXX=$MOZ_FETCHES_DIR/gcc/bin/g++
 export LDFLAGS=-lrt
 
 # Gn build scripts use #!/usr/bin/env python, which will be python 2.6 on
 # the worker and cause failures. Work around this by putting python2.7
 # ahead of it in PATH.
 mkdir -p $WORKSPACE/python_bin
 ln -s /usr/bin/python2.7 $WORKSPACE/python_bin/python
 export PATH=$WORKSPACE/python_bin:$PATH
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
 . taskcluster/scripts/misc/build-gn-common.sh
--- a/taskcluster/scripts/misc/build-gn-macosx.sh
+++ b/taskcluster/scripts/misc/build-gn-macosx.sh
@@ -1,22 +1,22 @@
 #!/bin/bash
 set -e -v
 
 # This script is for building GN.
 
 WORKSPACE=$HOME/workspace
 COMPRESS_EXT=xz
 
-CROSS_CCTOOLS_PATH=$GECKO_PATH/cctools
-CROSS_SYSROOT=$GECKO_PATH/MacOSX10.11.sdk
+CROSS_CCTOOLS_PATH=$MOZ_FETCHES_DIR/cctools
+CROSS_SYSROOT=$MOZ_FETCHES_DIR/MacOSX10.11.sdk
 
-export CC=$GECKO_PATH/clang/bin/clang
-export CXX=$GECKO_PATH/clang/bin/clang++
-export AR=$GECKO_PATH/clang/bin/llvm-ar
+export CC=$MOZ_FETCHES_DIR/clang/bin/clang
+export CXX=$MOZ_FETCHES_DIR/clang/bin/clang++
+export AR=$MOZ_FETCHES_DIR/clang/bin/llvm-ar
 export CFLAGS="-target x86_64-apple-darwin -mlinker-version=137 -B ${CROSS_CCTOOLS_PATH}/bin -isysroot ${CROSS_SYSROOT} -I${CROSS_SYSROOT}/usr/include -iframework ${CROSS_SYSROOT}/System/Library/Frameworks"
 export CXXFLAGS="-stdlib=libc++ ${CFLAGS}"
 export LDFLAGS="${CXXFLAGS} -Wl,-syslibroot,${CROSS_SYSROOT} -Wl,-dead_strip"
 
 # We patch tools/gn/bootstrap/bootstrap.py to detect this.
 export MAC_CROSS=1
 
 # Gn build scripts use #!/usr/bin/env python, which will be python 2.6 on
--- a/taskcluster/scripts/misc/build-gn-win32.sh
+++ b/taskcluster/scripts/misc/build-gn-win32.sh
@@ -3,18 +3,18 @@ set -e -v
 
 # This script is for building GN on Windows.
 
 UPLOAD_DIR=$PWD/public/build
 COMPRESS_EXT=bz2
 
 cd $GECKO_PATH
 
-export PATH="$GECKO_PATH/ninja/bin:$PATH"
-export PATH="$GECKO_PATH/mingw64/bin:$PATH"
+export PATH="$MOZ_FETCHES_DIR/ninja/bin:$PATH"
+export PATH="$MOZ_FETCHES_DIR/mingw64/bin:$PATH"
 
 . taskcluster/scripts/misc/vs-setup.sh
 . taskcluster/scripts/misc/tooltool-download.sh
 . taskcluster/scripts/misc/build-gn-common.sh
 
 # Building with MSVC spawns a mspdbsrv process that keeps a dll open in the MSVC directory.
 # This prevents the taskcluster worker from unmounting cleanly, and fails the build.
 # So we kill it.
--- a/taskcluster/scripts/misc/build-grcov.sh
+++ b/taskcluster/scripts/misc/build-grcov.sh
@@ -15,24 +15,26 @@ MINGW*)
     COMPRESS_EXT=bz2
 
     . $GECKO_PATH/taskcluster/scripts/misc/vs-setup.sh
     ;;
 esac
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
+if [ -n "$TOOLTOOL_MANIFEST" ]; then
+  . taskcluster/scripts/misc/tooltool-download.sh
+fi
 
 # cargo gets mad if the parent directory has a Cargo.toml file in it
 if [ -e Cargo.toml ]; then
   mv Cargo.toml Cargo.toml.back
 fi
 
-PATH="$(cd $GECKO_PATH && pwd)/rustc/bin:$PATH"
+PATH="$(cd $MOZ_FETCHES_DIR && pwd)/rustc/bin:$PATH"
 
 pushd $MOZ_FETCHES_DIR/$PROJECT
 
 cargo build --verbose --release
 
 mkdir $PROJECT
 cp target/release/${PROJECT}* ${PROJECT}/
 pushd $PROJECT
--- a/taskcluster/scripts/misc/build-hfsplus-linux.sh
+++ b/taskcluster/scripts/misc/build-hfsplus-linux.sh
@@ -1,16 +1,14 @@
 #!/bin/bash
 set -x -e -v
 
 # This script is for building hfsplus for Linux.
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
-
-export PATH=$PATH:$GECKO_PATH/clang/bin
+export PATH=$PATH:$MOZ_FETCHES_DIR/clang/bin
 
 build/unix/build-hfsplus/build-hfsplus.sh $MOZ_FETCHES_DIR
 
 # Put a tarball in the artifacts dir
 mkdir -p $UPLOAD_DIR
 cp $MOZ_FETCHES_DIR/hfsplus-tools.tar.* $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-llvm-dsymutil.sh
+++ b/taskcluster/scripts/misc/build-llvm-dsymutil.sh
@@ -1,29 +1,27 @@
 #!/bin/bash
 set -x -e -v
 
 # This script is for building clang for Linux.
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
-
 cd $MOZ_FETCHES_DIR/llvm-project/llvm
 
 mkdir build
 cd build
 
 cmake \
   -GNinja \
   -DCMAKE_BUILD_TYPE=Release \
   -DLLVM_TARGETS_TO_BUILD=X86 \
-  -DCMAKE_C_COMPILER=$GECKO_PATH/gcc/bin/gcc \
+  -DCMAKE_C_COMPILER=$MOZ_FETCHES_DIR/gcc/bin/gcc \
   ..
 
-export LD_LIBRARY_PATH=$GECKO_PATH/gcc/lib64
+export LD_LIBRARY_PATH=$MOZ_FETCHES_DIR/gcc/lib64
 
 ninja dsymutil llvm-symbolizer
 
 tar --xform='s,^,llvm-dsymutil/,' -Jcf llvm-dsymutil.tar.xz bin/dsymutil bin/llvm-symbolizer
 
 mkdir -p $UPLOAD_DIR
 cp llvm-dsymutil.tar.xz $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-mar-tools.sh
+++ b/taskcluster/scripts/misc/build-mar-tools.sh
@@ -2,26 +2,24 @@
 set -x -e -v
 
 # This script is for building mar and mbsdiff
 
 COMPRESS_EXT=xz
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
-
 export MOZ_OBJDIR=obj-mar
 
 echo ac_add_options --enable-project=tools/update-packaging > .mozconfig
 
 TOOLCHAINS="binutils clang"
 
 for t in $TOOLCHAINS; do
-    PATH="$GECKO_PATH/$t/bin:$PATH"
+    PATH="$MOZ_FETCHES_DIR/$t/bin:$PATH"
 done
 
 ./mach build -v
 
 mkdir mar-tools
 cp $MOZ_OBJDIR/dist/host/bin/{mar,mbsdiff} mar-tools/
 
 tar -acf mar-tools.tar.$COMPRESS_EXT mar-tools/
--- a/taskcluster/scripts/misc/build-mingw-fxc2-x86.sh
+++ b/taskcluster/scripts/misc/build-mingw-fxc2-x86.sh
@@ -1,19 +1,17 @@
 #!/bin/bash
 set -x -e -v
 
 WORKSPACE=$HOME/workspace
 INSTALL_DIR=$WORKSPACE/fxc2
 
 mkdir -p $INSTALL_DIR/bin
 
-cd $GECKO_PATH
-. taskcluster/scripts/misc/tooltool-download.sh
-export PATH="$GECKO_PATH/clang/bin:$PATH"
+export PATH="$MOZ_FETCHES_DIR/clang/bin:$PATH"
 
 # --------------
 
 cd $MOZ_FETCHES_DIR/fxc2
 make -j$(nproc) x86
 
 cp fxc2.exe $INSTALL_DIR/bin/
 cp dll/d3dcompiler_47_32.dll $INSTALL_DIR/bin/d3dcompiler_47.dll
--- a/taskcluster/scripts/misc/build-mingw32-nsis.sh
+++ b/taskcluster/scripts/misc/build-mingw32-nsis.sh
@@ -10,26 +10,23 @@ set -x -e -v
 #   DEBUG: | Error: opening stub "/home/worker/workspace/mingw32/
 #   DEBUG: | Error initalizing CEXEBuild: error setting
 #   ERROR: Failed to get nsis version.
 
 INSTALL_DIR=$GECKO_PATH/mingw32
 
 mkdir -p $INSTALL_DIR
 
-cd $GECKO_PATH
-. taskcluster/scripts/misc/tooltool-download.sh
-# After tooltool runs, we move the stuff we just downloaded.
 # As explained above, we have to build nsis to the directory it
 # will eventually be run from, which is the same place we just
 # installed our compiler. But at the end of the script we want
 # to package up what we just built. If we don't move the compiler,
 # we will package up the compiler we downloaded along with the
 # stuff we just built.
-mv mingw32 mingw32-gcc
+mv $MOZ_FETCHES_DIR/mingw32 $GECKO_PATH/mingw32-gcc
 export PATH="$GECKO_PATH/mingw32-gcc/bin:$PATH"
 
 cd $MOZ_FETCHES_DIR
 
 # --------------
 
 cd zlib-1.2.11
 make -f win32/Makefile.gcc PREFIX=i686-w64-mingw32-
--- a/taskcluster/scripts/misc/build-minidump-stackwalk.sh
+++ b/taskcluster/scripts/misc/build-minidump-stackwalk.sh
@@ -2,44 +2,46 @@
 set -x -e -v
 
 # This script is for building minidump_stackwalk
 
 COMPRESS_EXT=xz
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
+if [ -n "$TOOLTOOL_MANIFEST" ]; then
+  . taskcluster/scripts/misc/tooltool-download.sh
+fi
 
 export MOZ_OBJDIR=obj-minidump
 
 echo ac_add_options --enable-project=tools/crashreporter > .mozconfig
 
 MINIDUMP_STACKWALK=minidump_stackwalk
 
 case "$1" in
 macosx64)
     TOOLCHAINS="cctools rustc clang"
     echo ac_add_options --target=x86_64-apple-darwin >> .mozconfig
-    echo ac_add_options --with-macos-sdk=$GECKO_PATH/MacOSX10.11.sdk >> .mozconfig
+    echo ac_add_options --with-macos-sdk=$MOZ_FETCHES_DIR/MacOSX10.11.sdk >> .mozconfig
     ;;
 mingw32)
     TOOLCHAINS="binutils rustc clang"
     echo ac_add_options --target=i686-w64-mingw32 >> .mozconfig
     echo export CC=i686-w64-mingw32-clang >> .mozconfig
     echo export HOST_CC=clang >> .mozconfig
     MINIDUMP_STACKWALK=minidump_stackwalk.exe
     ;;
 *)
     TOOLCHAINS="binutils rustc clang"
     ;;
 esac
 
 for t in $TOOLCHAINS; do
-    PATH="$GECKO_PATH/$t/bin:$PATH"
+    PATH="$MOZ_FETCHES_DIR/$t/bin:$PATH"
 done
 
 ./mach build -v
 
 mkdir minidump_stackwalk
 cp $MOZ_OBJDIR/dist/bin/$MINIDUMP_STACKWALK minidump_stackwalk/
 
 tar -acf minidump_stackwalk.tar.$COMPRESS_EXT minidump_stackwalk/
--- a/taskcluster/scripts/misc/build-nasm.sh
+++ b/taskcluster/scripts/misc/build-nasm.sh
@@ -1,21 +1,17 @@
 #!/bin/bash
 set -x -e -v
 
 COMPRESS_EXT=bz2
 
-cd $GECKO_PATH
-
-. taskcluster/scripts/misc/tooltool-download.sh
-
 cd $MOZ_FETCHES_DIR/nasm-*
 case "$1" in
     win64)
-        export PATH="$GECKO_PATH/clang/bin:$PATH"
+        export PATH="$MOZ_FETCHES_DIR/clang/bin:$PATH"
         ./configure CC=x86_64-w64-mingw32-clang AR=llvm-ar RANLIB=llvm-ranlib --host=x86_64-w64-mingw32
         EXE=.exe
         ;;
     *)
         ./configure
         EXE=
         ;;
 esac
--- a/taskcluster/scripts/misc/build-rust-size.sh
+++ b/taskcluster/scripts/misc/build-rust-size.sh
@@ -13,24 +13,26 @@ MINGW*)
     COMPRESS_EXT=bz2
 
     . $GECKO_PATH/taskcluster/scripts/misc/vs-setup.sh
     ;;
 esac
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
+if [ -n "$TOOLTOOL_MANIFEST" ]; then
+  . taskcluster/scripts/misc/tooltool-download.sh
+fi
 
 # cargo gets mad if the parent directory has a Cargo.toml file in it
 if [ -e Cargo.toml ]; then
   mv Cargo.toml Cargo.toml.back
 fi
 
-PATH="$(cd $GECKO_PATH && pwd)/rustc/bin:$PATH"
+PATH="$(cd $MOZ_FETCHES_DIR && pwd)/rustc/bin:$PATH"
 
 cd $MOZ_FETCHES_DIR/$PROJECT
 
 cargo build --verbose --release
 
 mkdir $PROJECT
 cp target/release/${PROJECT}* ${PROJECT}/
 tar -acf ${PROJECT}.tar.$COMPRESS_EXT $PROJECT
--- a/taskcluster/scripts/misc/build-sccache.sh
+++ b/taskcluster/scripts/misc/build-sccache.sh
@@ -3,51 +3,53 @@ set -x -e -v
 
 TARGET="$1"
 
 # This script is for building sccache
 
 case "$(uname -s)" in
 Linux)
     COMPRESS_EXT=xz
-    PATH="$GECKO_PATH/binutils/bin:$PATH"
+    PATH="$MOZ_FETCHES_DIR/binutils/bin:$PATH"
     ;;
 MINGW*)
     UPLOAD_DIR=$PWD/public/build
     COMPRESS_EXT=bz2
 
     . $GECKO_PATH/taskcluster/scripts/misc/vs-setup.sh
     ;;
 esac
 
 cd $GECKO_PATH
 
-. taskcluster/scripts/misc/tooltool-download.sh
+if [ -n "$TOOLTOOL_MANIFEST" ]; then
+  . taskcluster/scripts/misc/tooltool-download.sh
+fi
 
-PATH="$(cd $GECKO_PATH && pwd)/rustc/bin:$PATH"
+PATH="$(cd $MOZ_FETCHES_DIR && pwd)/rustc/bin:$PATH"
 
 cd $MOZ_FETCHES_DIR/sccache
 
 case "$(uname -s)" in
 Linux)
     if [ "$TARGET" == "x86_64-apple-darwin" ]; then
-        export PATH="$GECKO_PATH/llvm-dsymutil/bin:$PATH"
-        export PATH="$GECKO_PATH/cctools/bin:$PATH"
-        cat >$GECKO_PATH/cross-linker <<EOF
-exec $GECKO_PATH/clang/bin/clang -v \
-  -fuse-ld=$GECKO_PATH/cctools/bin/x86_64-apple-darwin-ld \
+        export PATH="$MOZ_FETCHES_DIR/llvm-dsymutil/bin:$PATH"
+        export PATH="$MOZ_FETCHES_DIR/cctools/bin:$PATH"
+        cat >cross-linker <<EOF
+exec $MOZ_FETCHES_DIR/clang/bin/clang -v \
+  -fuse-ld=$MOZ_FETCHES_DIR/cctools/bin/x86_64-apple-darwin-ld \
   -mmacosx-version-min=10.11 \
   -target $TARGET \
-  -B $GECKO_PATH/cctools/bin \
-  -isysroot $GECKO_PATH/MacOSX10.11.sdk \
+  -B $MOZ_FETCHES_DIR/cctools/bin \
+  -isysroot $MOZ_FETCHES_DIR/MacOSX10.11.sdk \
   "\$@"
 EOF
-        chmod +x $GECKO_PATH/cross-linker
-        export RUSTFLAGS="-C linker=$GECKO_PATH/cross-linker"
-        export CC="$GECKO_PATH/clang/bin/clang"
+        chmod +x cross-linker
+        export RUSTFLAGS="-C linker=$PWD/cross-linker"
+        export CC="$MOZ_FETCHES_DIR/clang/bin/clang"
         cargo build --features "all" --verbose --release --target $TARGET
     else
         # We can't use the system openssl; see the sad story in
         # https://bugzilla.mozilla.org/show_bug.cgi?id=1163171#c26.
         OPENSSL_BUILD_DIRECTORY=$PWD/ourssl
         pushd $MOZ_FETCHES_DIR/openssl-1.1.0g
         ./Configure --prefix=$OPENSSL_BUILD_DIRECTORY no-shared linux-x86_64
         make -j `nproc --all`
--- a/taskcluster/scripts/misc/build-tup-linux.sh
+++ b/taskcluster/scripts/misc/build-tup-linux.sh
@@ -1,19 +1,15 @@
 #!/bin/bash
 set -e -v
 
 # This script is for building tup on Linux.
 
 COMPRESS_EXT=xz
-export PATH=$GECKO_PATH/gcc/bin:$PATH
-
-cd $GECKO_PATH
-
-. taskcluster/scripts/misc/tooltool-download.sh
+export PATH=$MOZ_FETCHES_DIR/gcc/bin:$PATH
 
 cd $MOZ_FETCHES_DIR/tup
 
 patch -p1 <<'EOF'
 diff --git a/src/tup/link.sh b/src/tup/link.sh
 index ed9a01c6..4ecc6d7d 100755
 --- a/src/tup/link.sh
 +++ b/src/tup/link.sh
--- a/taskcluster/scripts/misc/fetch-content
+++ b/taskcluster/scripts/misc/fetch-content
@@ -1,29 +1,35 @@
 #!/usr/bin/python3 -u
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import argparse
 import bz2
 import concurrent.futures
+import contextlib
+import datetime
 import gzip
 import hashlib
 import json
 import lzma
 import multiprocessing
 import os
 import pathlib
 import random
+import stat
 import subprocess
 import sys
+import tarfile
 import tempfile
 import time
+import urllib.parse
 import urllib.request
+import zipfile
 
 try:
     import zstandard
 except ImportError:
     zstandard = None
 
 
 CONCURRENCY = multiprocessing.cpu_count()
@@ -33,16 +39,50 @@ def log(msg):
     print(msg, file=sys.stderr)
     sys.stderr.flush()
 
 
 class IntegrityError(Exception):
     """Represents an integrity error when downloading a URL."""
 
 
+def ZstdCompressor(*args, **kwargs):
+    if not zstandard:
+        raise ValueError('zstandard Python package not available')
+    return zstandard.ZstdCompressor(*args, **kwargs)
+
+
+def ZstdDecompressor(*args, **kwargs):
+    if not zstandard:
+        raise ValueError('zstandard Python package not available')
+    return zstandard.ZstdDecompressor(*args, **kwargs)
+
+
+@contextlib.contextmanager
+def rename_after_close(fname, *args, **kwargs):
+    """
+    Context manager that opens a temporary file to use as a writer,
+    and closes the file on context exit, renaming it to the expected
+    file name in case of success, or removing it in case of failure.
+
+    Takes the same options as open(), but must be used as a context
+    manager.
+    """
+    path = pathlib.Path(fname)
+    tmp = path.with_name('%s.tmp' % path.name)
+    try:
+        with tmp.open(*args, **kwargs) as fh:
+            yield fh
+    except Exception:
+        tmp.unlink()
+        raise
+    else:
+        tmp.rename(fname)
+
+
 # The following is copied from
 # https://github.com/mozilla-releng/redo/blob/6d07678a014e0c525e54a860381a165d34db10ff/redo/__init__.py#L15-L85
 def retrier(attempts=5, sleeptime=10, max_sleeptime=300, sleepscale=1.5, jitter=1):
     """
     A generator function that sleeps between retries, handles exponential
     backoff and jitter. The action you are retrying is meant to run after
     retrier yields.
 
@@ -175,30 +215,22 @@ def download_to_path(url, path, sha256=N
     # bad data.
     try:
         path.unlink()
     except FileNotFoundError:
         pass
 
     for _ in retrier(attempts=5, sleeptime=60):
         try:
-            tmp = path.with_name('%s.tmp' % path.name)
-
-            log('Downloading %s to %s' % (url, tmp))
+            log('Downloading %s to %s' % (url, path))
 
-            try:
-                with tmp.open('wb') as fh:
-                    for chunk in stream_download(url, sha256=sha256, size=size):
-                        fh.write(chunk)
-            except IntegrityError:
-                tmp.unlink()
-                raise
+            with rename_after_close(path, 'wb') as fh:
+                for chunk in stream_download(url, sha256=sha256, size=size):
+                    fh.write(chunk)
 
-            log('Renaming to %s' % path)
-            tmp.rename(path)
             return
         except IntegrityError:
             raise
         except Exception as e:
             log("Download failed: {}".format(e))
             continue
 
     raise Exception("Download failed, no more retries!")
@@ -235,16 +267,33 @@ def gpg_verify_path(path: pathlib.Path, 
             # There is a race between the agent self-terminating and
             # shutil.rmtree() from the temporary directory cleanup that can
             # lead to exceptions. Kill the agent before cleanup to prevent this.
             env = dict(os.environ)
             env['GNUPGHOME'] = td
             subprocess.run(['gpgconf', '--kill', 'gpg-agent'], env=env)
 
 
+def open_tar_stream(path: pathlib.Path):
+    """"""
+    if path.suffix == '.bz2':
+        return bz2.open(str(path), 'rb')
+    elif path.suffix == '.gz':
+        return gzip.open(str(path), 'rb')
+    elif path.suffix == '.xz':
+        return lzma.open(str(path), 'rb')
+    elif path.suffix == '.zst':
+        dctx = ZstdDecompressor()
+        return dctx.stream_reader(path.open('rb'))
+    elif path.suffix == '.tar':
+        return path.open('rb')
+    else:
+        raise ValueError('unknown archive format for tar file: %s' % path)
+
+
 def archive_type(path: pathlib.Path):
     """Attempt to identify a path as an extractable archive."""
     if path.suffixes[-2:-1] == ['.tar']:
         return 'tar'
     elif path.suffix == '.zip':
         return 'zip'
     else:
         return None
@@ -252,75 +301,161 @@ def archive_type(path: pathlib.Path):
 
 def extract_archive(path, dest_dir, typ):
     """Extract an archive to a destination directory."""
 
     # Resolve paths to absolute variants.
     path = path.resolve()
     dest_dir = dest_dir.resolve()
 
+    log('Extracting %s to %s' % (path, dest_dir))
+    t0 = time.time()
+
     # We pipe input to the decompressor program so that we can apply
     # custom decompressors that the program may not know about.
     if typ == 'tar':
-        if path.suffix == '.bz2':
-            ifh = bz2.open(str(path), 'rb')
-        elif path.suffix == '.gz':
-            ifh = gzip.open(str(path), 'rb')
-        elif path.suffix == '.xz':
-            ifh = lzma.open(str(path), 'rb')
-        elif path.suffix == '.zst':
-            if not zstandard:
-                raise ValueError('zstandard Python package not available')
-            dctx = zstandard.ZstdDecompressor()
-            ifh = dctx.stream_reader(path.open('rb'))
-        elif path.suffix == '.tar':
-            ifh = path.open('rb')
+        ifh = open_tar_stream(path)
+        # On Windows, the tar program doesn't support things like symbolic
+        # links, while Windows actually support them. The tarfile module in
+        # python does. So use that. But since it's significantly slower than
+        # the tar program on Linux, only use tarfile on Windows (tarfile is
+        # also not much slower on Windows, presumably because of the
+        # notoriously bad I/O).
+        if sys.platform == 'win32':
+            tar = tarfile.open(fileobj=ifh, mode='r|')
+            tar.extractall(str(dest_dir))
+            args = []
         else:
-            raise ValueError('unknown archive format for tar file: %s' % path)
-
-        args = ['tar', 'xf', '-']
-        pipe_stdin = True
+            args = ['tar', 'xf', '-']
+            pipe_stdin = True
     elif typ == 'zip':
         # unzip from stdin has wonky behavior. We don't use a pipe for it.
         ifh = open(os.devnull, 'rb')
         args = ['unzip', '-o', str(path)]
         pipe_stdin = False
     else:
         raise ValueError('unknown archive format: %s' % path)
 
-    log('Extracting %s to %s using %r' % (path, dest_dir, args))
-    t0 = time.time()
-
-    with ifh, subprocess.Popen(args, cwd=str(dest_dir), bufsize=0,
-                               stdin=subprocess.PIPE) as p:
-        while True:
-            if not pipe_stdin:
-                break
+    if args:
+        with ifh, subprocess.Popen(args, cwd=str(dest_dir), bufsize=0,
+                                   stdin=subprocess.PIPE) as p:
+            while True:
+                if not pipe_stdin:
+                    break
 
-            chunk = ifh.read(131072)
-            if not chunk:
-                break
+                chunk = ifh.read(131072)
+                if not chunk:
+                    break
 
-            p.stdin.write(chunk)
+                p.stdin.write(chunk)
 
-    if p.returncode:
-        raise Exception('%r exited %d' % (args, p.returncode))
+        if p.returncode:
+            raise Exception('%r exited %d' % (args, p.returncode))
 
     log('%s extracted in %.3fs' % (path, time.time() - t0))
 
 
+def repack_archive(orig: pathlib.Path, dest: pathlib.Path,
+                   strip_components=0, prefix=''):
+    assert orig != dest
+    log('Repacking as %s' % dest)
+    orig_typ = archive_type(orig)
+    typ = archive_type(dest)
+    if not orig_typ:
+        raise Exception('Archive type not supported for %s' % orig.name)
+    if not typ:
+        raise Exception('Archive type not supported for %s' % dest.name)
+
+    if dest.suffixes[-2:] != ['.tar', '.zst']:
+        raise Exception('Only producing .tar.zst archives is supported.')
+
+    if strip_components or prefix:
+        def filter(name):
+            if strip_components:
+                stripped = '/'.join(name.split('/')[strip_components:])
+                if not stripped:
+                    raise Exception(
+                        'Stripping %d components would remove files'
+                        % strip_components)
+                name = stripped
+            return prefix + name
+    else:
+        filter = None
+
+    with rename_after_close(dest, 'wb') as fh:
+        ctx = ZstdCompressor()
+        if orig_typ == 'zip':
+            assert typ == 'tar'
+            zip = zipfile.ZipFile(orig)
+            # Convert the zip stream to a tar on the fly.
+            with ctx.stream_writer(fh) as compressor, \
+                    tarfile.open(fileobj=compressor, mode='w:') as tar:
+                for zipinfo in zip.infolist():
+                    if zipinfo.is_dir():
+                        continue
+                    tarinfo = tarfile.TarInfo()
+                    filename = zipinfo.filename
+                    tarinfo.name = filter(filename) if filter else filename
+                    tarinfo.size = zipinfo.file_size
+                    # Zip files don't have any knowledge of the timezone
+                    # they were created in. Which is not really convenient to
+                    # reliably convert to a timestamp. But we don't really
+                    # care about accuracy, but rather about reproducibility,
+                    # so we pick UTC.
+                    time = datetime.datetime(
+                        *zipinfo.date_time, tzinfo=datetime.timezone.utc)
+                    tarinfo.mtime = time.timestamp()
+                    # 0 is MS-DOS, 3 is UNIX. Only in the latter case do we
+                    # get anything useful for the tar file mode.
+                    if zipinfo.create_system == 3:
+                        mode = zipinfo.external_attr >> 16
+                    else:
+                        mode = 0o0644
+                    tarinfo.mode = stat.S_IMODE(mode)
+                    if stat.S_ISLNK(mode):
+                        tarinfo.type = tarfile.SYMTYPE
+                        tarinfo.linkname = zip.read(filename).decode()
+                        tar.addfile(tarinfo, zip.open(filename))
+                    elif stat.S_ISREG(mode) or stat.S_IFMT(mode) == 0:
+                        tar.addfile(tarinfo, zip.open(filename))
+                    else:
+                        raise Exception('Unsupported file mode %o'
+                                        % stat.S_IFMT(mode))
+
+        elif orig_typ == 'tar':
+            if typ == 'zip':
+                raise Exception('Repacking a tar to zip is not supported')
+            assert typ == 'tar'
+
+            ifh = open_tar_stream(orig)
+            if filter:
+                # To apply the filter, we need to open the tar stream and
+                # tweak it.
+                origtar = tarfile.open(fileobj=ifh, mode='r|')
+                with ctx.stream_writer(fh) as compressor, \
+                        tarfile.open(fileobj=compressor, mode='w:') as tar:
+                    for tarinfo in origtar:
+                        if tarinfo.isdir():
+                            continue
+                        tarinfo.name = filter(tarinfo.name)
+                        tar.addfile(tarinfo, origtar.extractfile(tarinfo))
+            else:
+                # We only change compression here. The tar stream is unchanged.
+                ctx.copy_stream(ifh, fh)
+
+
 def fetch_and_extract(url, dest_dir, extract=True, sha256=None, size=None):
     """Fetch a URL and extract it to a destination path.
 
     If the downloaded URL is an archive, it is extracted automatically
     and the archive is deleted. Otherwise the file remains in place in
     the destination directory.
     """
 
-    basename = url.split('/')[-1]
+    basename = urllib.parse.urlparse(url).path.split('/')[-1]
     dest_path = dest_dir / basename
 
     download_to_path(url, dest_path, sha256=sha256, size=size)
 
     if not extract:
         return
 
     typ = archive_type(dest_path)
@@ -345,19 +480,16 @@ def fetch_urls(downloads):
 def git_checkout_archive(dest_path: pathlib.Path, repo: str, commit: str,
                          prefix=None):
     """Produce an archive of the files comprising a Git checkout."""
     dest_path.parent.mkdir(parents=True, exist_ok=True)
 
     if dest_path.suffixes[-2:] != ['.tar', '.zst']:
         raise Exception('Only producing .tar.zst archives is supported.')
 
-    if not zstandard:
-        raise ValueError('zstandard Python package not available')
-
     with tempfile.TemporaryDirectory() as td:
         temp_dir = pathlib.Path(td)
 
         git_dir = temp_dir / 'git_dir'
         if not prefix:
             prefix = repo.rstrip('/').rsplit('/', 1)[-1]
 
         # This could be faster with a shallow clone. However, Git requires a ref
@@ -368,18 +500,18 @@ def git_checkout_archive(dest_path: path
                        check=True)
 
         print('creating archive %s of commit %s' % (dest_path, commit))
         proc = subprocess.Popen([
             'git', '--git-dir={}'.format(git_dir), 'archive',
             '--format=tar', '--prefix=%s/' % prefix, commit
         ], stdout=subprocess.PIPE)
 
-        with open(dest_path, 'wb') as out:
-            ctx = zstandard.ZstdCompressor()
+        with rename_after_close(dest_path, 'wb') as out:
+            ctx = ZstdCompressor()
             ctx.copy_stream(proc.stdout, out)
 
         proc.wait()
 
 
 def command_git_checkout_archive(args):
     dest = pathlib.Path(args.dest)
 
@@ -405,30 +537,42 @@ def command_static_url(args):
 
     if gpg_sig_url:
         gpg_signature = b''.join(stream_download(gpg_sig_url))
         gpg_key = os.environb[gpg_env_key.encode('ascii')]
 
     dest = pathlib.Path(args.dest)
     dest.parent.mkdir(parents=True, exist_ok=True)
 
+    basename = urllib.parse.urlparse(args.url).path.split('/')[-1]
+    if basename.endswith(''.join(dest.suffixes)):
+        dl_dest = dest
+    else:
+        dl_dest = dest.parent / basename
+
     try:
-        download_to_path(args.url, dest, sha256=args.sha256, size=args.size)
+        download_to_path(args.url, dl_dest, sha256=args.sha256, size=args.size)
 
         if gpg_sig_url:
-            gpg_verify_path(dest, gpg_key, gpg_signature)
+            gpg_verify_path(dl_dest, gpg_key, gpg_signature)
 
+        if dl_dest != dest or args.strip_components or args.add_prefix:
+            repack_archive(dl_dest, dest, args.strip_components, args.add_prefix)
     except Exception:
         try:
-            dest.unlink()
+            dl_dest.unlink()
         except FileNotFoundError:
             pass
 
         raise
 
+    if dl_dest != dest:
+        log('Removing %s' % dl_dest)
+        dl_dest.unlink()
+
 
 def api(root_url, service, version, path):
     # taskcluster-lib-urls is not available when this script runs, so
     # simulate its behavior:
     if root_url == 'https://taskcluster.net':
         return 'https://{service}.taskcluster.net/{version}/{path}'.format(
                 service=service, version=version, path=path)
     return 'https://{root_url}/api/{service}/{version}/{path}'.format(
@@ -481,16 +625,22 @@ def main():
                      help='SHA-256 of downloaded content')
     url.add_argument('--size', required=True, type=int,
                      help='Size of downloaded content, in bytes')
     url.add_argument('--gpg-sig-url',
                      help='URL containing signed GPG document validating '
                           'URL to fetch')
     url.add_argument('--gpg-key-env',
                      help='Environment variable containing GPG key to validate')
+    url.add_argument('--strip-components', type=int, default=0,
+                     help='Number of leading components to strip from file '
+                          'names in the downloaded archive')
+    url.add_argument('--add-prefix', default='',
+                     help='Prefix to add to file names in the downloaded '
+                          'archive')
     url.add_argument('url', help='URL to fetch')
     url.add_argument('dest', help='Destination path')
 
     artifacts = subparsers.add_parser('task-artifacts',
                                       help='Fetch task artifacts')
     artifacts.set_defaults(func=command_task_artifacts)
     artifacts.add_argument('-d', '--dest', default=os.environ.get('MOZ_FETCHES_DIR'),
                            help='Destination directory which will contain all '
--- a/taskcluster/scripts/misc/tooltool-download.sh
+++ b/taskcluster/scripts/misc/tooltool-download.sh
@@ -1,11 +1,11 @@
 # Fetch a tooltool manifest.
 
-cd $GECKO_PATH
+cd $MOZ_FETCHES_DIR
 
 case "`uname -s`" in
 Linux)
     TOOLTOOL_AUTH_FILE=/builds/relengapi.tok
     ;;
 MINGW*)
     TOOLTOOL_AUTH_FILE=c:/builds/relengapi.tok
     ;;
@@ -25,11 +25,22 @@ fi
 
 if [ -n "$UPLOAD_DIR" ]; then
     TOOLTOOL_DL_FLAGS="${TOOLTOOL_DL_FLAGS=} --artifact-manifest $UPLOAD_DIR/toolchains.json"
 fi
 
 : TOOLTOOL_CACHE                ${TOOLTOOL_CACHE:=/builds/worker/tooltool-cache}
 export TOOLTOOL_CACHE
 
-./mach artifact toolchain -v${TOOLTOOL_DL_FLAGS}${TOOLTOOL_MANIFEST:+ --tooltool-manifest "${TOOLTOOL_MANIFEST}"}${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}} --retry 5${MOZ_TOOLCHAINS:+ ${MOZ_TOOLCHAINS}}
+if [ -n "$MOZ_TOOLCHAINS" ]; then
+    echo This script should not be used for toolchain downloads anymore
+    echo Use fetches
+    exit 1
+fi
+
+if [ -z "$TOOLTOOL_MANIFEST" ]; then
+    echo This script should not be used when there is no tooltool manifest set
+    exit 1
+fi
+
+${GECKO_PATH}/mach artifact toolchain -v${TOOLTOOL_DL_FLAGS} --tooltool-manifest "${GECKO_PATH}/${TOOLTOOL_MANIFEST}"${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}} --retry 5
 
 cd $OLDPWD
--- a/taskcluster/scripts/misc/vs-setup.sh
+++ b/taskcluster/scripts/misc/vs-setup.sh
@@ -1,8 +1,8 @@
 VSDIR=vs2017_15.8.4
-VSPATH="${GECKO_PATH}/${VSDIR}"
-UNIX_VSPATH="$(cd ${GECKO_PATH} && pwd)/${VSDIR}"
+VSPATH="${MOZ_FETCHES_DIR}/${VSDIR}"
+UNIX_VSPATH="$(cd ${MOZ_FETCHES_DIR} && pwd)/${VSDIR}"
 SDK_VERSION=10.0.17134.0
 
 export INCLUDE="${VSPATH}/VC/include;${VSPATH}/VC/atlmfc/include;${VSPATH}/SDK/Include/${SDK_VERSION}/ucrt;${VSPATH}/SDK/Include/${SDK_VERSION}/shared;${VSPATH}/SDK/Include/${SDK_VERSION}/um;${VSPATH}/SDK/Include/${SDK_VERSION}/winrt;${VSPATH}/DIA SDK/include"
 export LIB="${VSPATH}/VC/lib/x64;${VSPATH}/VC/atlmfc/lib/x64;${VSPATH}/SDK/lib/${SDK_VERSION}/um/x64;${VSPATH}/SDK/lib/${SDK_VERSION}/ucrt/x64;${VSPATH}/DIA SDK/lib/amd64"
 export PATH="${UNIX_VSPATH}/VC/bin/Hostx64/x64:${UNIX_VSPATH}/VC/bin/Hostx86/x86:${UNIX_VSPATH}/SDK/bin/${SDK_VERSION}/x64:${UNIX_VSPATH}/redist/x64/Microsoft.VC141.CRT:${UNIX_VSPATH}/SDK/Redist/ucrt/DLLs/x64:${UNIX_VSPATH}/DIA SDK/bin/amd64:$PATH"
--- a/taskcluster/scripts/misc/wr-macos-cross-build-setup.sh
+++ b/taskcluster/scripts/misc/wr-macos-cross-build-setup.sh
@@ -1,16 +1,16 @@
 #!/bin/bash
 set -x -e -v
 
 export TARGET_TRIPLE="x86_64-apple-darwin"
 
 source "${GECKO_PATH}/taskcluster/scripts/misc/tooltool-download.sh"
 
-MACOS_SYSROOT="${GECKO_PATH}/MacOSX10.11.sdk"
+MACOS_SYSROOT="${MOZ_FETCHES_DIR}/MacOSX10.11.sdk"
 CLANGDIR="${MOZ_FETCHES_DIR}/clang"
 
 # Deploy the wrench dependencies
 mv ${MOZ_FETCHES_DIR}/wrench-deps/{vendor,.cargo} "${GECKO_PATH}/gfx/wr/"
 
 # Building wrench with the `headless` feature also builds the osmesa-src crate,
 # which includes building C++ code. We have to do a bunch of shenanigans
 # to make this cross-compile properly.
--- a/taskcluster/scripts/misc/wrench-deps-vendoring.sh
+++ b/taskcluster/scripts/misc/wrench-deps-vendoring.sh
@@ -4,18 +4,17 @@ set -x -e -v
 # This scripts uses `cargo-vendor` to download all the dependencies needed
 # to build `wrench` (a tool used for standalone testing of webrender), and
 # exports those dependencies as a tarball. This avoids having to download
 # these dependencies on every test job that uses `wrench`.
 
 UPLOAD_DIR=$HOME/artifacts
 
 cd $GECKO_PATH
-. taskcluster/scripts/misc/tooltool-download.sh
-export PATH=$PATH:$GECKO_PATH/rustc/bin
+export PATH=$PATH:$MOZ_FETCHES_DIR/rustc/bin
 cargo install --version 0.1.23 cargo-vendor
 cd gfx/wr/
 mkdir .cargo
 cargo vendor --relative-path --sync ./Cargo.lock > .cargo/config
 mkdir wrench-deps
 mv vendor .cargo wrench-deps/
 mkdir wrench-deps/cargo-apk
 # Until there's a version of cargo-apk published on crates.io that has
--- a/taskcluster/scripts/misc/wrench-windows-tests.sh
+++ b/taskcluster/scripts/misc/wrench-windows-tests.sh
@@ -7,23 +7,26 @@ set -x -e -v
 # tool in the WebRender repository.
 # The builds involved require a number of dependencies to be available,
 # which is all handled below.
 
 cd $GECKO_PATH
 
 # This will download the rustc, cmake, ninja, MSVC, and wrench-deps artifacts.
 . taskcluster/scripts/misc/tooltool-download.sh
-export PATH=$PATH:$MOZ_FETCHES_DIR/rustc/bin:$GECKO_PATH/cmake/bin:$GECKO_PATH/ninja/bin
+export PATH=$PATH:$MOZ_FETCHES_DIR/rustc/bin:$MOZ_FETCHES_DIR/cmake/bin:$MOZ_FETCHES_DIR/ninja/bin
 
 .  taskcluster/scripts/misc/vs-setup.sh
 
 # Move the wrench-deps vendored crates into place
 mv ${MOZ_FETCHES_DIR}/wrench-deps/{vendor,.cargo} gfx/wr
 cd gfx/wr
 
 # This is needed for the WebRender standalone reftests
 powershell.exe 'iex (Get-Content -Raw ci-scripts\set-screenresolution.ps1); Set-ScreenResolution 1920 1080'
 
 # Run the CI scripts
 export CARGOFLAGS='--verbose --frozen'
 export FREETYPE_CMAKE_GENERATOR=Ninja
 cmd.exe /c 'ci-scripts\windows-tests.cmd'
+
+# Diagnostic for bug 1571986.
+tasklist -M
--- a/taskcluster/taskgraph/transforms/fetch.py
+++ b/taskcluster/taskgraph/transforms/fetch.py
@@ -66,19 +66,31 @@ FETCH_SCHEMA = Schema({
                 # value ``{url}``, which will be substituted with the value from
                 # ``url``.
                 Required('sig-url'): basestring,
                 # Path to file containing GPG public key(s) used to validate
                 # download.
                 Required('key-path'): basestring,
             },
 
-            # The name to give to the generated artifact.
+            # The name to give to the generated artifact. Defaults to the file
+            # portion of the URL. Using a different extension converts the
+            # archive to the given type. Only conversion to .tar.zst is
+            # supported.
             Optional('artifact-name'): basestring,
 
+            # Strip the given number of path components at the beginning of
+            # each file entry in the archive.
+            # Requires an artifact-name ending with .tar.zst.
+            Optional('strip-components'): int,
+
+            # Add the given prefix to each file entry in the archive.
+            # Requires an artifact-name ending with .tar.zst.
+            Optional('add-prefix'): basestring,
+
             # IMPORTANT: when adding anything that changes the behavior of the task,
             # it is important to update the digest data used to compute cache hits.
         },
         {
             'type': 'chromium-fetch',
 
             Required('script'): basestring,
 
@@ -163,43 +175,55 @@ def make_base_task(config, name, descrip
 def create_fetch_url_task(config, job):
     name = job['name']
     fetch = job['fetch']
 
     artifact_name = fetch.get('artifact-name')
     if not artifact_name:
         artifact_name = fetch['url'].split('/')[-1]
 
+    command = [
+        '/builds/worker/bin/fetch-content', 'static-url',
+    ]
+
+    # Arguments that matter to the cache digest
     args = [
-        '/builds/worker/bin/fetch-content', 'static-url',
         '--sha256', fetch['sha256'],
         '--size', '%d' % fetch['size'],
     ]
 
+    if fetch.get('strip-components'):
+        args.extend(['--strip-components', '%d' % fetch['strip-components']])
+
+    if fetch.get('add-prefix'):
+        args.extend(['--add-prefix', fetch['add-prefix']])
+
+    command.extend(args)
+
     env = {}
 
     if 'gpg-signature' in fetch:
         sig_url = fetch['gpg-signature']['sig-url'].format(url=fetch['url'])
         key_path = os.path.join(taskgraph.GECKO, fetch['gpg-signature'][
             'key-path'])
 
         with open(key_path, 'rb') as fh:
             gpg_key = fh.read()
 
         env['FETCH_GPG_KEY'] = gpg_key
-        args.extend([
+        command.extend([
             '--gpg-sig-url', sig_url,
             '--gpg-key-env', 'FETCH_GPG_KEY',
         ])
 
-    args.extend([
+    command.extend([
         fetch['url'], '/builds/worker/artifacts/%s' % artifact_name,
     ])
 
-    task = make_base_task(config, name, job['description'], args)
+    task = make_base_task(config, name, job['description'], command)
     task['treeherder']['symbol'] = join_symbol('Fetch', name)
     task['worker']['artifacts'] = [{
         'type': 'directory',
         'name': 'public',
         'path': '/builds/worker/artifacts',
     }]
     task['worker']['env'] = env
     task['attributes']['fetch-artifact'] = 'public/%s' % artifact_name
@@ -211,17 +235,17 @@ def create_fetch_url_task(config, job):
         add_optimization(
             config,
             task,
             cache_type=CACHE_TYPE,
             cache_name=cache_name,
             # We don't include the GPG signature in the digest because it isn't
             # materially important for caching: GPG signatures are supplemental
             # trust checking beyond what the shasum already provides.
-            digest_data=[fetch['sha256'], '%d' % fetch['size'], artifact_name],
+            digest_data=args + [artifact_name],
         )
 
     return task
 
 
 def create_git_fetch_task(config, job):
     name = job['name']
     fetch = job['fetch']
--- a/taskcluster/taskgraph/transforms/job/__init__.py
+++ b/taskcluster/taskgraph/transforms/job/__init__.py
@@ -156,16 +156,27 @@ def get_attribute(dict, key, attributes,
         dict[key] = value
 
 
 @transforms.add
 def use_fetches(config, jobs):
     artifact_names = {}
     aliases = {}
 
+    if config.kind == 'toolchain':
+        jobs = list(jobs)
+        for job in jobs:
+            run = job.get('run', {})
+            label = 'toolchain-{}'.format(job['name'])
+            get_attribute(
+                artifact_names, label, run, 'toolchain-artifact')
+            value = run.get('toolchain-alias')
+            if value:
+                aliases['toolchain-{}'.format(value)] = label
+
     for task in config.kind_dependencies_tasks:
         if task.kind in ('fetch', 'toolchain'):
             get_attribute(
                 artifact_names, task.label, task.attributes,
                 '{kind}-artifact'.format(kind=task.kind),
             )
             value = task.attributes.get('{}-alias'.format(task.kind))
             if value:
--- a/taskcluster/taskgraph/transforms/job/common.py
+++ b/taskcluster/taskgraph/transforms/job/common.py
@@ -80,17 +80,17 @@ def add_artifacts(config, job, taskdesc,
         'path': path,
         'type': 'directory',
     })
 
 
 def docker_worker_add_artifacts(config, job, taskdesc):
     """ Adds an artifact directory to the task """
     path = '{workdir}/artifacts/'.format(**job['run'])
-    taskdesc['worker']['env']['UPLOAD_DIR'] = path
+    taskdesc['worker'].setdefault('env', {})['UPLOAD_DIR'] = path
     add_artifacts(config, job, taskdesc, path)
 
 
 def generic_worker_add_artifacts(config, job, taskdesc):
     """ Adds an artifact directory to the task """
     # The path is the location on disk; it doesn't necessarily
     # mean the artifacts will be public or private; that is set via the name
     # attribute in add_artifacts.
--- a/taskcluster/taskgraph/transforms/job/toolchain.py
+++ b/taskcluster/taskgraph/transforms/job/toolchain.py
@@ -127,22 +127,19 @@ def docker_worker_toolchain(config, job,
     # Toolchain checkouts don't live under {workdir}/checkouts
     workspace = '{workdir}/workspace/build'.format(**run)
     gecko_path = '{}/src'.format(workspace)
 
     env = worker['env']
     env.update({
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
+        'MOZ_FETCHES_DIR': workspace,
         'GECKO_PATH': gecko_path,
     })
-    # If the task definition hasn't overridden the default value, set to
-    # the workspace.
-    if env.get('MOZ_FETCHES_DIR') == 'fetches':
-        env['MOZ_FETCHES_DIR'] = workspace
 
     attributes = taskdesc.setdefault('attributes', {})
     attributes['toolchain-artifact'] = run.pop('toolchain-artifact')
     if 'toolchain-alias' in run:
         attributes['toolchain-alias'] = run.pop('toolchain-alias')
 
     if not taskgraph.fast:
         name = taskdesc['label'].replace('{}-'.format(config.kind), '', 1)