'''Assembles a Rust toolchain in-tree linked against in-tree LLVM.
Builds a Rust toolchain bootstrapped from an untrusted rustc build.
Rust has an official boostrapping build. At a high level:
1. A "stage 0" Rust is downloaded from Rust's official server. This
is one major release before the version being built. E.g. if building trunk
the latest beta is downloaded. If building stable 1.57.0, stage0 is stable
1.56.1.
2. Stage 0 libstd is built. This is different than the libstd downloaded above.
3. Stage 1 rustc is built with rustc from (1) and libstd from (2)
2. Stage 1 libstd is built with stage 1 rustc. Later artifacts built with
stage 1 rustc are built with stage 1 libstd.
Further stages are possible and continue as expected. Additionally, the build
can be extensively customized. See for details:
https://rustc-dev-guide.rust-lang.org/building/bootstrapping.html
This script clones the Rust repository, checks it out to a defined revision,
then builds stage 1 rustc and libstd using the LLVM build from
//tools/clang/scripts/build.py or clang-libs fetched from
//tools/clang/scripts/update.py.
Ideally our build would begin with our own trusted stage0 rustc. As it is
simpler, for now we use an official build.
TODO(https://crbug.com/1245714): Do a proper 3-stage build
'''
import argparse
import base64
import collections
import hashlib
import json
import platform
import os
import shutil
import string
import subprocess
import sys
import urllib
from pathlib import Path
sys.path.append(
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'clang',
'scripts'))
from build import (AddCMakeToPath, AddZlibToPath, CheckoutGitRepo,
GetLibXml2Dirs, LLVM_BUILD_TOOLS_DIR, MaybeDownloadHostGcc,
RunCommand)
from update import (CHROMIUM_DIR, DownloadAndUnpack, EnsureDirExists,
GetDefaultHostOs, RmTree, UpdatePackage)
from update_rust import (RUST_REVISION, RUST_TOOLCHAIN_OUT_DIR,
STAGE0_JSON_SHA256, THIRD_PARTY_DIR, THIS_DIR,
VERSION_STAMP_PATH, GetLatestRevision)
EXCLUDED_TESTS = [
os.path.join('tests', 'codegen', 'issue-45222.rs'),
os.path.join('tests', 'codegen', 'issue-96497-slice-size-nowrap.rs'),
os.path.join('tests', 'codegen', 'sanitizer-cfi-emit-type-checks.rs'),
os.path.join('tests', 'codegen',
'sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs'),
os.path.join('tests', 'ui', 'abi', 'stack-protector.rs'),
os.path.join('tests', 'ui', 'backtrace.rs'),
os.path.join('tests', 'ui', 'numeric', 'numeric-cast.rs'),
]
EXCLUDED_TESTS_WINDOWS = [
os.path.join('tests', 'codegen', 'vec-shrink-panik.rs'),
]
CLANG_SCRIPTS_DIR = os.path.join(THIS_DIR, '..', 'clang', 'scripts')
RUST_GIT_URL = ('https://chromium.googlesource.com/external/' +
'github.com/rust-lang/rust')
RUST_SRC_DIR = os.path.join(THIRD_PARTY_DIR, 'rust_src', 'src')
STAGE0_JSON_PATH = os.path.join(RUST_SRC_DIR, 'src', 'stage0.json')
CARGO_HOME_DIR = os.path.join(RUST_SRC_DIR, 'cargo-home')
RUST_SRC_VERSION_FILE_PATH = os.path.join(RUST_SRC_DIR, 'src', 'version')
RUST_SRC_GIT_COMMIT_INFO_FILE_PATH = os.path.join(RUST_SRC_DIR,
'git-commit-info')
RUST_TOOLCHAIN_LIB_DIR = os.path.join(RUST_TOOLCHAIN_OUT_DIR, 'lib')
RUST_TOOLCHAIN_SRC_DIST_DIR = os.path.join(RUST_TOOLCHAIN_LIB_DIR, 'rustlib',
'src', 'rust')
RUST_TOOLCHAIN_SRC_DIST_VENDOR_DIR = os.path.join(RUST_TOOLCHAIN_SRC_DIST_DIR,
'vendor')
RUST_CONFIG_TEMPLATE_PATH = os.path.join(
os.path.dirname(os.path.abspath(__file__)), 'config.toml.template')
RUST_CARGO_CONFIG_TEMPLATE_PATH = os.path.join(
os.path.dirname(os.path.abspath(__file__)), 'cargo-config.toml.template')
RUST_SRC_VENDOR_DIR = os.path.join(RUST_SRC_DIR, 'vendor')
RUST_HOST_LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party',
'rust-toolchain-intermediate',
'llvm-host-build')
RUST_HOST_LLVM_INSTALL_DIR = os.path.join(CHROMIUM_DIR, 'third_party',
'rust-toolchain-intermediate',
'llvm-host-install')
RUST_CROSS_TARGET_LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party',
'rust-toolchain-intermediate',
'llvm-target-build')
RUST_CROSS_TARGET_LLVM_INSTALL_DIR = os.path.join(
CHROMIUM_DIR, 'third_party', 'rust-toolchain-intermediate',
'llvm-target-install')
CIPD_DOWNLOAD_URL = f'https://chrome-infra-packages.appspot.com/dl'
OPENSSL_CIPD_LINUX_AMD_PATH = 'infra/3pp/static_libs/openssl/linux-amd64'
OPENSSL_CIPD_LINUX_AMD_VERSION = '1.1.1j.chromium.2'
OPENSSL_CIPD_MAC_AMD_PATH = 'infra/3pp/static_libs/openssl/mac-amd64'
OPENSSL_CIPD_MAC_AMD_VERSION = '1.1.1j.chromium.2'
OPENSSL_CIPD_MAC_ARM_PATH = 'infra/3pp/static_libs/openssl/mac-amd64'
OPENSSL_CIPD_MAC_ARM_VERSION = '1.1.1j.chromium.2'
if sys.platform == 'win32':
LD_PATH_FLAG = '/LIBPATH:'
else:
LD_PATH_FLAG = '-L'
BUILD_TARGETS = [
'library/proc_macro', 'library/std', 'src/tools/cargo', 'src/tools/clippy',
'src/tools/rustfmt'
]
DISTRIBUTION_ARTIFACTS = [
'cargo', 'clippy', 'compiler/rustc', 'library/std', 'rust-analyzer',
'rustfmt', 'src'
]
DISTRIBUTION_ARTIFACTS_SKIPPED_CROSS_COMPILE = [
'cargo',
'rust-analyzer',
]
TEST_SUITES = [
'library/std',
'tests/codegen',
'tests/ui',
]
def AddOpenSSLToEnv(build_mac_arm):
"""Download OpenSSL, and add to OPENSSL_DIR."""
ssl_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'openssl')
if sys.platform == 'darwin':
if platform.machine() == 'arm64' or build_mac_arm:
ssl_url = (f'{CIPD_DOWNLOAD_URL}/{OPENSSL_CIPD_MAC_ARM_PATH}'
f'/+/version:2@{OPENSSL_CIPD_MAC_ARM_VERSION}')
else:
ssl_url = (f'{CIPD_DOWNLOAD_URL}/{OPENSSL_CIPD_MAC_AMD_PATH}'
f'/+/version:2@{OPENSSL_CIPD_MAC_AMD_VERSION}')
elif sys.platform == 'win32':
ssl_url = (f'{CIPD_DOWNLOAD_URL}/{OPENSSL_CIPD_WIN_AMD_PATH}'
f'/+/version:2@{OPENSSL_CIPD_WIN_AMD_VERSION}')
else:
ssl_url = (f'{CIPD_DOWNLOAD_URL}/{OPENSSL_CIPD_LINUX_AMD_PATH}'
f'/+/version:2@{OPENSSL_CIPD_LINUX_AMD_VERSION}')
if os.path.exists(ssl_dir):
RmTree(ssl_dir)
DownloadAndUnpack(ssl_url, ssl_dir, is_known_zip=True)
os.environ['OPENSSL_DIR'] = ssl_dir
return ssl_dir
def VerifyStage0JsonHash():
hasher = hashlib.sha256()
with open(STAGE0_JSON_PATH, 'rb') as input:
hasher.update(input.read())
actual_hash = hasher.hexdigest()
if actual_hash == STAGE0_JSON_SHA256:
return
print('src/stage0.json hash is different than expected!')
print('Expected hash: ' + STAGE0_JSON_SHA256)
print('Actual hash: ' + actual_hash)
sys.exit(1)
def FetchBetaPackage(name, rust_git_hash, triple=None):
'''Downloads the beta package specified for the compiler build
If `triple` is not specified, it downloads a package for the current
machine's architecture.
Unpacks the package and returns the path to root of the package.
'''
triple = triple if triple else RustTargetTriple(False)
filename = f'{name}-beta-{triple}'
STAGE0_JSON_URL = (
'https://chromium.googlesource.com/external/github.com/'
'rust-lang/rust/+/{GIT_HASH}/src/stage0.json?format=TEXT')
base64_text = urllib.request.urlopen(
STAGE0_JSON_URL.format(GIT_HASH=rust_git_hash)).read().decode("utf-8")
stage0 = json.loads(base64.b64decode(base64_text))
for k in stage0['checksums_sha256'].keys():
if k.endswith(filename + '.tar.gz'):
package_tgz = k
server = stage0['config']['dist_server']
DownloadAndUnpack(f'{server}/{package_tgz}', LLVM_BUILD_TOOLS_DIR)
return os.path.join(LLVM_BUILD_TOOLS_DIR, filename)
def InstallBetaPackage(package_dir, install_dir):
RunCommand([
os.path.join(package_dir, 'install.sh'), f'--destdir={install_dir}',
f'--prefix='
])
def CargoVendor(cargo_bin):
'''Runs `cargo vendor` to pull down dependencies.'''
os.chdir(RUST_SRC_DIR)
for i in range(0, 3):
submod_cmd = [
'git', 'submodule', 'update', '--init', '--recursive', '--depth',
'1'
]
if RunCommand(submod_cmd, fail_hard=False):
pass
elif i < 2:
print('Failed git submodule, retrying...')
continue
else:
sys.exit(1)
vendor_cmd = [
cargo_bin,
'vendor',
'--locked',
'--versioned-dirs',
'--sync',
'src/tools/rust-analyzer/Cargo.toml',
'--sync',
'compiler/rustc_codegen_cranelift/Cargo.toml',
'--sync',
'src/bootstrap/Cargo.toml',
]
if RunCommand(vendor_cmd, fail_hard=False):
break
elif i < 2:
print('Failed cargo vendor, retrying...')
continue
else:
sys.exit(1)
try:
os.mkdir(os.path.join(RUST_SRC_DIR, '.cargo'))
except FileExistsError:
pass
shutil.copyfile(RUST_CARGO_CONFIG_TEMPLATE_PATH,
os.path.join(RUST_SRC_DIR, '.cargo', 'config.toml'))
os.chdir(CHROMIUM_DIR)
class XPy:
''' Runner for x.py, Rust's build script. Holds shared state between x.py
runs. '''
def __init__(self, zlib_path, libxml2_dirs, build_mac_arm,
gcc_toolchain_path, verbose):
self._env = collections.defaultdict(str, os.environ)
self._build_mac_arm = build_mac_arm
self._verbose = verbose
self._llvm_bins_path = os.path.join(RUST_HOST_LLVM_INSTALL_DIR, 'bin')
ENV_FLAGS = [
'CFLAGS',
'CXXFLAGS',
'LDFLAGS',
'RUSTFLAGS_BOOTSTRAP',
'RUSTFLAGS_NOT_BOOTSTRAP',
'RUSTDOCFLAGS',
]
self._env = collections.defaultdict(str, os.environ)
for f in ENV_FLAGS:
self._env.setdefault(f, '')
if sys.platform == 'win32':
self._env['AR'] = os.path.join(self._llvm_bins_path,
'llvm-lib.exe')
self._env['CC'] = os.path.join(self._llvm_bins_path,
'clang-cl.exe')
self._env['CXX'] = os.path.join(self._llvm_bins_path,
'clang-cl.exe')
self._env['LD'] = os.path.join(self._llvm_bins_path,
'lld-link.exe')
else:
self._env['AR'] = os.path.join(self._llvm_bins_path, 'llvm-ar')
self._env['CC'] = os.path.join(self._llvm_bins_path, 'clang')
self._env['CXX'] = os.path.join(self._llvm_bins_path, 'clang++')
self._env['LD'] = os.path.join(self._llvm_bins_path, 'clang')
if sys.platform == 'darwin':
sdk_path = subprocess.check_output(['xcrun', '--show-sdk-path'],
text=True).rstrip()
self._env['CFLAGS'] += f' -isysroot {sdk_path}'
self._env['CXXFLAGS'] += f' -isysroot {sdk_path}'
self._env['LDFLAGS'] += f' -isysroot {sdk_path}'
self._env['RUSTFLAGS_BOOTSTRAP'] += (
f' -Clink-arg=-isysroot -Clink-arg={sdk_path}')
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += (
f' -Clink-arg=-isysroot -Clink-arg={sdk_path}')
self._env['SDKROOT'] = sdk_path
if zlib_path:
self._env['CFLAGS'] += f' -I{zlib_path}'
self._env['CXXFLAGS'] += f' -I{zlib_path}'
self._env['LDFLAGS'] += f' {LD_PATH_FLAG}{zlib_path}'
self._env['RUSTFLAGS_BOOTSTRAP'] += (
f' -Clink-arg={LD_PATH_FLAG}{zlib_path}')
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += (
f' -Clink-arg={LD_PATH_FLAG}{zlib_path}')
if libxml2_dirs:
self._env['CFLAGS'] += f' -I{libxml2_dirs.include_dir}'
self._env['CXXFLAGS'] += f' -I{libxml2_dirs.include_dir}'
self._env['LDFLAGS'] += f' {LD_PATH_FLAG}{libxml2_dirs.lib_dir}'
self._env['RUSTFLAGS_BOOTSTRAP'] += (
f' -Clink-arg={LD_PATH_FLAG}{libxml2_dirs.lib_dir}')
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += (
f' -Clink-arg={LD_PATH_FLAG}{libxml2_dirs.lib_dir}')
if gcc_toolchain_path:
gcc_toolchain_flag = f'--gcc-toolchain={gcc_toolchain_path}'
self._env['CFLAGS'] += f' {gcc_toolchain_flag}'
self._env['CXXFLAGS'] += f' {gcc_toolchain_flag}'
self._env['LDFLAGS'] += f' {gcc_toolchain_flag}'
self._env['RUSTFLAGS_BOOTSTRAP'] += (
f' -Clink-arg={gcc_toolchain_flag}')
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += (
f' -Clink-arg={gcc_toolchain_flag}')
self._env['RUSTFLAGS_BOOTSTRAP'] += (
f' -L native={gcc_toolchain_path}/lib64')
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += (
f' -L native={gcc_toolchain_path}/lib64')
if sys.platform != 'win32':
self._env['RUSTFLAGS_BOOTSTRAP'] += ' -Clink-arg=-fuse-ld=lld'
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += ' -Clink-arg=-fuse-ld=lld'
if sys.platform.startswith('linux'):
self._env['RUSTFLAGS_BOOTSTRAP'] += (
' -Clink-arg=-Wl,--undefined-version')
self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += (
' -Clink-arg=-Wl,--undefined-version')
self._env['RUSTDOCFLAGS'] += f' -Clinker={self._env["LD"]}'
self._env['CARGO_HOME'] = CARGO_HOME_DIR
def configure(self, build_mac_arm, x86_64_llvm_config,
aarch64_llvm_config):
with open(RUST_CONFIG_TEMPLATE_PATH, 'r') as input:
template = string.Template(input.read())
def quote_string(s: str):
return s.replace('\\', '\\\\').replace('"', '\\"')
subs = {}
subs['INSTALL_DIR'] = quote_string(str(RUST_TOOLCHAIN_OUT_DIR))
subs['LLVM_BIN'] = quote_string(str(self._llvm_bins_path))
subs['PACKAGE_VERSION'] = GetLatestRevision()
subs["LLVM_CONFIG_WINDOWS_x86_64"] = quote_string(
str(x86_64_llvm_config))
subs["LLVM_CONFIG_APPLE_AARCH64"] = quote_string(
str(aarch64_llvm_config))
subs["LLVM_CONFIG_APPLE_X86_64"] = quote_string(
str(x86_64_llvm_config))
subs["LLVM_CONFIG_LINUX_X86_64"] = quote_string(
str(x86_64_llvm_config))
with open(os.path.join(RUST_SRC_DIR, 'config.toml'), 'w') as output:
output.write(template.substitute(subs))
def run(self, sub, args):
''' Run x.py subcommand with specified args. '''
os.chdir(RUST_SRC_DIR)
cmd = [sys.executable, 'x.py', sub]
if self._verbose and self._verbose > 0:
cmd.append('-' + self._verbose * 'v')
RunCommand(cmd + args, msvc_arch='x64', env=self._env)
os.chdir(CHROMIUM_DIR)
def GetTestArgs():
args = TEST_SUITES
for excluded in EXCLUDED_TESTS:
args.append('--exclude')
args.append(excluded)
if sys.platform == 'win32':
for excluded in EXCLUDED_TESTS_WINDOWS:
args.append('--exclude')
args.append(excluded)
return args
def MakeVersionStamp(git_hash):
with open(RUST_SRC_VERSION_FILE_PATH) as version_file:
rust_version = version_file.readline().rstrip()
return (f'rustc {rust_version} {git_hash}'
f' ({GetLatestRevision()} chromium)\n')
def GetLatestRustCommit():
"""Get the latest commit hash in the LLVM monorepo."""
main = json.loads(
urllib.request.urlopen('https://chromium.googlesource.com/external/' +
'github.com/rust-lang/rust/' +
'+/refs/heads/main?format=JSON').read().decode(
"utf-8").replace(")]}'", ""))
return main['commit']
def RustTargetTriple(build_mac_arm):
if sys.platform == 'darwin':
if platform.machine() == 'arm64' or build_mac_arm:
return 'aarch64-apple-darwin'
else:
return 'x86_64-apple-darwin'
elif sys.platform == 'win32':
return 'x86_64-pc-windows-msvc'
else:
return 'x86_64-unknown-linux-gnu'
def BuildLLVMLibraries(skip_build, build_mac_arm, gcc_toolchain):
if build_mac_arm:
target_llvm_build_dir = RUST_CROSS_TARGET_LLVM_BUILD_DIR
target_llvm_install_dir = RUST_CROSS_TARGET_LLVM_INSTALL_DIR
else:
target_llvm_build_dir = RUST_HOST_LLVM_BUILD_DIR
target_llvm_install_dir = RUST_HOST_LLVM_INSTALL_DIR
print(f'Building the host LLVM in {RUST_HOST_LLVM_BUILD_DIR}...')
build_cmd = [
sys.executable,
os.path.join(CLANG_SCRIPTS_DIR, 'build.py'),
'--disable-asserts',
'--no-tools',
'--with-ml-inliner-model=',
]
if sys.platform.startswith('linux'):
build_cmd.append('--without-android')
build_cmd.append('--without-fuchsia')
if sys.platform == 'darwin':
build_cmd.append('--without-fuchsia')
if gcc_toolchain:
build_cmd.extend(['--gcc-toolchain', gcc_toolchain])
if not skip_build:
RunCommand(build_cmd + [
'--build-dir', RUST_HOST_LLVM_BUILD_DIR, '--install-dir',
RUST_HOST_LLVM_INSTALL_DIR
])
if build_mac_arm:
print(f'Building the target cross-compile LLVM in '
f'{target_llvm_build_dir}...')
build_cmd.append('--build-mac-arm')
if not skip_build:
RunCommand(build_cmd + [
'--build-dir', target_llvm_build_dir, '--install-dir',
target_llvm_install_dir
])
print(
f'Copying the target-but-native llvm-config to LLVM install dir...'
)
shutil.copy(
os.path.join(target_llvm_install_dir, 'bin', 'llvm-config'),
os.path.join(target_llvm_install_dir, 'bin', 'llvm-config.bak'))
shutil.copy(
os.path.join(target_llvm_build_dir, 'NATIVE', 'bin',
'llvm-config'),
os.path.join(target_llvm_install_dir, 'bin', 'llvm-config'))
x86_64_llvm_config = os.path.join(RUST_HOST_LLVM_BUILD_DIR, 'bin',
'llvm-config')
aarch64_llvm_config = os.path.join(RUST_HOST_LLVM_BUILD_DIR, 'bin',
'llvm-config')
if build_mac_arm:
aarch64_llvm_config = os.path.join(target_llvm_install_dir, 'bin',
'llvm-config')
return (x86_64_llvm_config, aarch64_llvm_config, target_llvm_install_dir)
def main():
parser = argparse.ArgumentParser(
description='Build and package Rust toolchain')
parser.add_argument('-v',
'--verbose',
action='count',
help='run subcommands with verbosity')
parser.add_argument('--build-mac-arm',
action='store_true',
help='Build arm binaries. Only valid on macOS.')
parser.add_argument(
'--verify-stage0-hash',
action='store_true',
help=
'checkout Rust, verify the stage0 hash, then quit without building. '
'Will print the actual hash if different than expected.')
parser.add_argument('--skip-checkout',
action='store_true',
help='do not create or update any checkouts')
parser.add_argument('--skip-clean',
action='store_true',
help='skip x.py clean step')
parser.add_argument(
'--skip-llvm-build',
action='store_true',
help='do not build LLVM, presuming build_rust.py was '
'already run and the LLVM libs are thus already present.')
parser.add_argument('--skip-test',
action='store_true',
help='skip running rustc and libstd tests')
parser.add_argument('--skip-install',
action='store_true',
help='do not install to RUST_TOOLCHAIN_OUT_DIR')
parser.add_argument('--rust-force-head-revision',
action='store_true',
help='build the latest revision')
parser.add_argument(
'--run-xpy',
action='store_true',
help='run x.py command in configured Rust checkout. Quits after '
'running specified command, skipping all normal build steps. For '
'debugging. Running x.py directly will not set the appropriate env '
'variables nor update config.toml')
args, rest = parser.parse_known_args()
if args.build_mac_arm and sys.platform != 'darwin':
print('--build-mac-arm only valid on macOS')
return 1
if args.build_mac_arm and platform.machine() == 'arm64':
print('--build-mac-arm only valid on intel to cross-build arm')
return 1
if args.rust_force_head_revision:
checkout_revision = GetLatestRustCommit()
else:
checkout_revision = RUST_REVISION
building_on_host_triple = RustTargetTriple(False)
building_for_host_triple = RustTargetTriple(args.build_mac_arm)
args.gcc_toolchain = None
if sys.platform.startswith('linux'):
MaybeDownloadHostGcc(args)
if not args.skip_checkout:
CheckoutGitRepo('Rust', RUST_GIT_URL, checkout_revision, RUST_SRC_DIR)
VerifyStage0JsonHash()
if args.verify_stage0_hash:
return 0
(x86_64_llvm_config, aarch64_llvm_config,
target_llvm_dir) = BuildLLVMLibraries(args.skip_llvm_build,
args.build_mac_arm,
args.gcc_toolchain)
AddCMakeToPath()
if sys.platform == 'win32':
zlib_path = AddZlibToPath()
else:
zlib_path = None
if sys.platform == 'win32':
libxml2_dirs = GetLibXml2Dirs()
else:
libxml2_dirs = None
if sys.platform != 'win32' and not args.build_mac_arm:
AddOpenSSLToEnv(args.build_mac_arm)
xpy = XPy(zlib_path, libxml2_dirs, args.build_mac_arm, args.gcc_toolchain,
args.verbose)
xpy.configure(args.build_mac_arm, x86_64_llvm_config, aarch64_llvm_config)
if not args.skip_checkout or True:
path = FetchBetaPackage('cargo', checkout_revision)
if sys.platform == 'win32':
cargo_bin = os.path.join(path, 'cargo', 'bin', 'cargo.exe')
else:
cargo_bin = os.path.join(path, 'cargo', 'bin', 'cargo')
CargoVendor(cargo_bin)
if args.run_xpy:
if rest[0] == '--':
rest = rest[1:]
xpy.run(rest[0], rest[1:])
return 0
else:
assert not rest
xpy_args = ['--build', building_on_host_triple]
if args.build_mac_arm:
xpy_args.extend([
'--host', building_for_host_triple, '--target',
building_for_host_triple
])
if not args.skip_clean:
print('Cleaning build artifacts...')
xpy.run('clean', xpy_args)
if not args.build_mac_arm and not args.skip_install:
if not args.skip_test and not args.build_mac_arm:
print(f'Running stage 2 tests...')
xpy.run('test', ['--stage', '2'] + xpy_args + GetTestArgs())
print('Building stage 2 artifacts...')
xpy.run('build', xpy_args + ['--stage', '2'] + BUILD_TARGETS)
if args.skip_install:
return 0
print(f'Installing Rust to {RUST_TOOLCHAIN_OUT_DIR} ...')
if os.path.exists(RUST_TOOLCHAIN_OUT_DIR):
RmTree(RUST_TOOLCHAIN_OUT_DIR)
artifacts = DISTRIBUTION_ARTIFACTS
if args.build_mac_arm:
for a in DISTRIBUTION_ARTIFACTS_SKIPPED_CROSS_COMPILE:
artifacts.remove(a)
xpy.run('install', xpy_args + artifacts)
print(f'Copying vendored dependencies to {RUST_TOOLCHAIN_OUT_DIR} ...')
shutil.copytree(RUST_SRC_VENDOR_DIR, RUST_TOOLCHAIN_SRC_DIST_VENDOR_DIR)
with open(VERSION_STAMP_PATH, 'w') as stamp:
stamp.write(MakeVersionStamp(checkout_revision))
return 0
if __name__ == '__main__':
sys.exit(main())