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
143
144
145
146
147
148
149
150
151
|
#!/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 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.
#
# In the case that a Rust roll fails and you want to roll Clang alone, reset
# this back to its previous value _AND_ set `OVERRIDE_CLANG_REVISION` below
# to the `CLANG_REVISION` that was in place before the roll.
RUST_REVISION = 'df0295f07175acc7325ce3ca4152eb05752af1f2'
RUST_SUB_REVISION = 5
# If not None, this overrides the `CLANG_REVISION` in
# //tools/clang/scripts/update.py in order to download a Rust toolchain that
# was built against a different LLVM than the latest Clang package.
OVERRIDE_CLANG_REVISION = None
# Trunk on 2022-10-15.
#
# The revision specified below should typically be the same as the
# `crubit_revision` specified in the //DEPS file. More details and roll
# instructions can be found in tools/rust/README.md.
#
# TODO(danakj): This should be included in --print-rust-revision when we want
# code to depend on using crubit rs_to_cc_bindings.
CRUBIT_REVISION = 'f5cbdf4b54b0e6b9f63a4464a2c901c82e0f0209'
CRUBIT_SUB_REVISION = 1
# 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 = '432afb4d9ab10d74d70d735ac01727a6e0d6b8fdd1e651303edec667aec57a0e'
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')
VERSION_STAMP_PATH = os.path.join(RUST_TOOLCHAIN_OUT_DIR, 'INSTALLED_VERSION')
def GetRustClangRevision():
from update import CLANG_REVISION
c = OVERRIDE_CLANG_REVISION if OVERRIDE_CLANG_REVISION else CLANG_REVISION
return (f'{RUST_REVISION}-{RUST_SUB_REVISION}' f'-{c}')
# Get the version of the toolchain package we already have.
def GetStampVersion():
if os.path.exists(VERSION_STAMP_PATH):
with open(VERSION_STAMP_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.
if os.path.exists(RUST_TOOLCHAIN_OUT_DIR):
if version == GetStampVersion():
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, THIRD_PARTY_DIR)
# The archive contains a VERSION file. Copy it to INSTALLED_VERSION as
# the very last step in case the unpack fails after writing VERSION.
shutil.copyfile(VERSION_SRC_PATH, VERSION_STAMP_PATH)
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())
|