1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
#!/usr/bin/env python3
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
'''Update in-tree checkout of Rust toolchain
When run without arguments, it fetches and unzips the Rust toolchain package
specieid by the `RUST_REVISION` and `RUST_SUB_REVISION` along with the clang
version specified in //tools/clang/scripts/update.py.
'''
import argparse
import glob
import os
import re
import shutil
import sys
import time
import urllib
from pathlib import Path
# Add Clang scripts to path so we can import them later (if running within a
# Chromium checkout.)
# Note: Imports cannot be done until after the --print-rust-revision flag
# has been processed, since that needs to work when running this script
# in isolation.
sys.path.append(
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'clang',
'scripts'))
# These fields are written by //tools/clang/scripts/upload_revision.py, and
# should not be changed manually.
# They are also read by build/config/compiler/BUILD.gn.
RUST_REVISION = '4a0969e06dbeaaa43914d2d00b2e843d49aa3886'
RUST_SUB_REVISION = 1
# The revision of Crubit to use from https://github.com/google/crubit
#
# If changing the CRUBIT_REVISION but not the RUST_REVISION, bump the
# RUST_SUB_REVISION to generate a unique package name.
CRUBIT_REVISION = 'fa6caca0969c9d1dec584186eb85ebdd0fe02955'
# The Absl revision used for building Crubit. Can be bumped to the latest when
# rolling Crubit. There's no reason to change this if not rolling Crubit.
ABSL_REVISION = 'ba5fd0979b4e74bd4d1b8da1d84347173bd9f17f'
# Hash of src/stage0.json, which itself contains the stage0 toolchain hashes.
# We trust the Rust build system checks, but to ensure it is not tampered with
# itself check the hash.
STAGE0_JSON_SHA256 = '981bcaeac1c5f7035166cd59941e4a8e2070c9eb977bc9ef881e656b60c79055'
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..'))
THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
RUST_TOOLCHAIN_OUT_DIR = os.path.join(THIRD_PARTY_DIR, 'rust-toolchain')
# Path to the VERSION file stored in the archive.
VERSION_SRC_PATH = os.path.join(RUST_TOOLCHAIN_OUT_DIR, 'VERSION')
def GetRustClangRevision():
from update import CLANG_REVISION
return f'{RUST_REVISION}-{RUST_SUB_REVISION}-{CLANG_REVISION}'
# Get the version of the toolchain package we already have.
def GetStampVersion():
if os.path.exists(VERSION_SRC_PATH):
with open(VERSION_SRC_PATH) as version_file:
existing_stamp = version_file.readline().rstrip()
version_re = re.compile(r'rustc [0-9.]+ [0-9a-f]+ \((.+?) chromium\)')
match = version_re.fullmatch(existing_stamp)
if match is None:
return None
return match.group(1)
return None
def main():
parser = argparse.ArgumentParser(description='Update Rust package')
parser.add_argument(
'--print-rust-revision',
action='store_true',
help='Print Rust revision (without Clang revision) and '
'quit. Can be run outside of a Chromium checkout.')
parser.add_argument('--print-package-version',
action='store_true',
help='Print Rust package version (including both the '
'Rust and Clang revisions) and quit.')
args = parser.parse_args()
if args.print_rust_revision:
print(f'{RUST_REVISION}-{RUST_SUB_REVISION}')
return 0
if args.print_package_version:
stamp_version = GetStampVersion()
if stamp_version != GetRustClangRevision():
print(f'The expected Rust version is {GetRustClangRevision()} '
f'but the actual version is {stamp_version}')
print('Did you run "gclient sync"?')
return 1
print(stamp_version)
return 0
from update import (DownloadAndUnpack, GetDefaultHostOs,
GetPlatformUrlPrefix)
platform_prefix = GetPlatformUrlPrefix(GetDefaultHostOs())
version = GetRustClangRevision()
# Exit early if the existing package is up-to-date. Note that we cannot
# simply call DownloadAndUnpack() every time: aside from unnecessarily
# downloading the toolchain if it hasn't changed, it also leads to multiple
# versions of the same rustlibs. build/rust/std/find_std_rlibs.py chokes in
# this case.
# .*_is_first_class_gcs file is created by first class GCS deps when rust
# hooks are migrated to be first class deps. In case we need to go back to
# using a hook, this file will indicate that the previous download was
# from the first class dep and the dir needs to be cleared.
if os.path.exists(RUST_TOOLCHAIN_OUT_DIR):
if version == GetStampVersion() and not glob.glob(
os.path.join(RUST_TOOLCHAIN_OUT_DIR, '.*_is_first_class_gcs')):
return 0
if os.path.exists(RUST_TOOLCHAIN_OUT_DIR):
shutil.rmtree(RUST_TOOLCHAIN_OUT_DIR)
try:
url = f'{platform_prefix}rust-toolchain-{version}.tar.xz'
DownloadAndUnpack(url, RUST_TOOLCHAIN_OUT_DIR)
except urllib.error.HTTPError as e:
print(f'error: Failed to download Rust package')
return 1
# Ensure the newly extracted package has the correct version.
assert version == GetStampVersion()
if __name__ == '__main__':
sys.exit(main())
|