1#!/usr/bin/env python3 2 3import subprocess 4from os.path import abspath 5import hashlib 6import urllib3 7import tarfile 8 9def rustc_url(version): 10 return f"https://static.rust-lang.org/dist/rustc-{version}-src.tar.gz" 11 12version_sequence = ["1.21.0", "1.22.1", "1.23.0", "1.24.1", "1.25.0", "1.26.2", "1.27.2", "1.28.0", "1.29.2", "1.30.1", "1.31.1", "1.32.0", "1.33.0", "1.34.2"] 13 14bootstrap_version = "1.20.0" 15bootstrap_path = abspath("mrustc-bootstrap/mrustc/mrustc-rustc-rustc/rustc-1.20.0-src/") 16clang_prebuilt_path = abspath("mrustc-bootstrap/clang-prebuilt/clang-r353983c/bin") 17cc = clang_prebuilt_path + "/clang" 18cxx = clang_prebuilt_path + "/clang++" 19ar = clang_prebuilt_path + "/llvm-ar" 20 21class RustBuild(object): 22 def __init__(self, version, path, stage0): 23 self.version = version 24 self.stage0 = stage0 25 self.path = path 26 self.built = False 27 28 def configure(self): 29 minor = self.version.split('.')[1] 30 remap = "" 31 if int(minor) > 30: 32 remap = "[rust]\nremap-debuginfo = true" 33 config_toml = f"""\ 34[build] 35cargo = "{self.stage0.cargo()}" 36rustc = "{self.stage0.rustc()}" 37full-bootstrap = true 38vendor = true 39extended = true 40docs = false 41{remap} 42[target.x86_64-unknown-linux-gnu] 43cc = "{cc}" 44cxx = "{cxx}" 45""" 46 with open(self.path + "/config.toml", "w+") as f: 47 f.write(config_toml) 48 49 def build(self): 50 self.configure() 51 subprocess.run(["./x.py", "--stage", "3", "build"], check=True, cwd=self.path) 52 self.built = True 53 54 def rustc(self): 55 if not self.built: 56 self.build() 57 return self.path + "/build/x86_64-unknown-linux-gnu/stage3/bin/rustc" 58 59 def cargo(self): 60 if not self.built: 61 self.build() 62 return self.path + "/build/x86_64-unknown-linux-gnu/stage3-tools/x86_64-unknown-linux-gnu/release/cargo" 63 64 65class RustPrebuilt(RustBuild): 66 def __init__(self, version, path): 67 super().__init__(version, path, None) 68 self.built = True 69 def build(self): pass 70 71 72def fetch_rustc(): 73 http = urllib3.PoolManager() 74 for version in version_sequence: 75 rust_src_resp = http.request("GET", rustc_url(version), preload_content=False) 76 rust_src_tar_path = f"rustc-{version}-src.tar.gz" 77 hasher = hashlib.sha256() 78 with open(rust_src_tar_path, "wb+") as tar_file: 79 for chunk in rust_src_resp.stream(): 80 hasher.update(chunk) 81 tar_file.write(chunk) 82 rust_src_resp.release_conn() 83 print(f"rustc-{version}-src.tar.gz {hasher.hexdigest()}") 84 tarfile.open(rust_src_tar_path).extractall() 85 86 87def main(): 88 fetch_rustc() 89 build = RustPrebuilt(bootstrap_version, bootstrap_path) 90 for version in version_sequence: 91 build = RustBuild(version, abspath(f"rustc-{version}-src"), build) 92 print(f"rustc: {build.rustc()}") 93 print(f"cargo: {build.rustc()}") 94 95 96if __name__ == "__main__": 97 main() 98