mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
parent
6dff251e35
commit
365a139716
11 changed files with 125 additions and 362 deletions
|
@ -19,6 +19,8 @@ matrix:
|
||||||
- sudo apt-get install clang-3.9 llvm-3.9 llvm-3.9-runtime -y
|
- sudo apt-get install clang-3.9 llvm-3.9 llvm-3.9-runtime -y
|
||||||
- export LLVM_CONFIG=/usr/lib/llvm-3.9/bin/llvm-config
|
- export LLVM_CONFIG=/usr/lib/llvm-3.9/bin/llvm-config
|
||||||
- export CC=gcc-5 CXX=g++-5
|
- export CC=gcc-5 CXX=g++-5
|
||||||
|
- curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain none -y
|
||||||
|
- source ~/.profile
|
||||||
script:
|
script:
|
||||||
- ./mach build -d --verbose
|
- ./mach build -d --verbose
|
||||||
- ./mach test-unit
|
- ./mach test-unit
|
||||||
|
|
|
@ -41,6 +41,13 @@ cache:
|
||||||
- .cargo -> rust-toolchain
|
- .cargo -> rust-toolchain
|
||||||
- .ccache
|
- .ccache
|
||||||
|
|
||||||
|
install:
|
||||||
|
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||||
|
- rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain none
|
||||||
|
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||||
|
- mach rustc --version
|
||||||
|
- mach cargo --version
|
||||||
|
|
||||||
# Uncomment these lines to expose RDP access information to the build machine in the build log.
|
# Uncomment these lines to expose RDP access information to the build machine in the build log.
|
||||||
#init:
|
#init:
|
||||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
|
|
@ -14,7 +14,6 @@ import json
|
||||||
import os
|
import os
|
||||||
import os.path as path
|
import os.path as path
|
||||||
import re
|
import re
|
||||||
import shutil
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import urllib2
|
import urllib2
|
||||||
|
@ -27,9 +26,8 @@ from mach.decorators import (
|
||||||
)
|
)
|
||||||
|
|
||||||
import servo.bootstrap as bootstrap
|
import servo.bootstrap as bootstrap
|
||||||
from servo.command_base import CommandBase, BIN_SUFFIX, cd
|
from servo.command_base import CommandBase, cd, check_call
|
||||||
from servo.util import delete, download_bytes, download_file, extract, host_triple
|
from servo.util import delete, download_bytes
|
||||||
from servo.util import STATIC_RUST_LANG_ORG_DIST
|
|
||||||
|
|
||||||
|
|
||||||
@CommandProvider
|
@CommandProvider
|
||||||
|
@ -39,6 +37,7 @@ class MachCommands(CommandBase):
|
||||||
category='bootstrap')
|
category='bootstrap')
|
||||||
def env(self):
|
def env(self):
|
||||||
env = self.build_env()
|
env = self.build_env()
|
||||||
|
print("export RUSTFLAGS=%s" % env["RUSTFLAGS"])
|
||||||
print("export PATH=%s" % env["PATH"])
|
print("export PATH=%s" % env["PATH"])
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
print("export DYLD_LIBRARY_PATH=%s" % env["DYLD_LIBRARY_PATH"])
|
print("export DYLD_LIBRARY_PATH=%s" % env["DYLD_LIBRARY_PATH"])
|
||||||
|
@ -54,161 +53,6 @@ class MachCommands(CommandBase):
|
||||||
def bootstrap(self, force=False):
|
def bootstrap(self, force=False):
|
||||||
return bootstrap.bootstrap(self.context, force=force)
|
return bootstrap.bootstrap(self.context, force=force)
|
||||||
|
|
||||||
@Command('bootstrap-rust',
|
|
||||||
description='Download the Rust compiler',
|
|
||||||
category='bootstrap')
|
|
||||||
@CommandArgument('--force', '-f',
|
|
||||||
action='store_true',
|
|
||||||
help='Force download even if a copy already exists')
|
|
||||||
@CommandArgument('--target',
|
|
||||||
action='append',
|
|
||||||
default=[],
|
|
||||||
help='Download rust stdlib for specified target')
|
|
||||||
@CommandArgument('--stable',
|
|
||||||
action='store_true',
|
|
||||||
help='Use stable rustc version')
|
|
||||||
def bootstrap_rustc(self, force=False, target=[], stable=False):
|
|
||||||
self.set_use_stable_rust(stable)
|
|
||||||
rust_dir = path.join(self.context.sharedir, "rust", self.rust_path())
|
|
||||||
install_dir = path.join(self.context.sharedir, "rust", self.rust_install_dir())
|
|
||||||
version = self.rust_stable_version() if stable else "nightly"
|
|
||||||
|
|
||||||
nightly_dist = STATIC_RUST_LANG_ORG_DIST + "/" + self.rust_nightly_date()
|
|
||||||
|
|
||||||
if not force and path.exists(path.join(rust_dir, "rustc", "bin", "rustc" + BIN_SUFFIX)):
|
|
||||||
print("Rust compiler already downloaded.", end=" ")
|
|
||||||
print("Use |bootstrap-rust --force| to download again.")
|
|
||||||
else:
|
|
||||||
if path.isdir(rust_dir):
|
|
||||||
shutil.rmtree(rust_dir)
|
|
||||||
os.makedirs(rust_dir)
|
|
||||||
|
|
||||||
# The nightly Rust compiler is hosted on the nightly server under the date with a name
|
|
||||||
# rustc-nightly-HOST-TRIPLE.tar.gz, whereas the stable compiler is named
|
|
||||||
# rustc-VERSION-HOST-TRIPLE.tar.gz. We just need to pull down and extract it,
|
|
||||||
# giving a directory name that will be the same as the tarball name (rustc is
|
|
||||||
# in that directory).
|
|
||||||
if stable:
|
|
||||||
base_url = STATIC_RUST_LANG_ORG_DIST
|
|
||||||
else:
|
|
||||||
base_url = nightly_dist
|
|
||||||
|
|
||||||
rustc_url = base_url + "/rustc-%s-%s.tar.gz" % (version, host_triple())
|
|
||||||
tgz_file = rust_dir + '-rustc.tar.gz'
|
|
||||||
download_file("Rust compiler", rustc_url, tgz_file)
|
|
||||||
|
|
||||||
print("Extracting Rust compiler...")
|
|
||||||
extract(tgz_file, install_dir)
|
|
||||||
print("Rust compiler ready.")
|
|
||||||
|
|
||||||
# Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz` for the nightly
|
|
||||||
# releases, or rust-std-VERSION-TRIPLE.tar.gz for stable releases, with
|
|
||||||
# a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory.
|
|
||||||
# This `lib` directory needs to be extracted and merged with the `rustc/lib`
|
|
||||||
# directory from the host compiler above.
|
|
||||||
lib_dir = path.join(install_dir,
|
|
||||||
"rustc-%s-%s" % (version, host_triple()),
|
|
||||||
"rustc", "lib", "rustlib")
|
|
||||||
|
|
||||||
# ensure that the libs for the host's target is downloaded
|
|
||||||
host_target = host_triple()
|
|
||||||
if host_target not in target:
|
|
||||||
target.append(host_target)
|
|
||||||
|
|
||||||
for target_triple in target:
|
|
||||||
target_lib_dir = path.join(lib_dir, target_triple)
|
|
||||||
if path.exists(target_lib_dir):
|
|
||||||
# No need to check for force. If --force the directory is already deleted
|
|
||||||
print("Rust lib for target {} already downloaded.".format(target_triple), end=" ")
|
|
||||||
print("Use |bootstrap-rust --force| to download again.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
tarball = "rust-std-%s-%s.tar.gz" % (version, target_triple)
|
|
||||||
tgz_file = path.join(install_dir, tarball)
|
|
||||||
if self.use_stable_rust():
|
|
||||||
std_url = STATIC_RUST_LANG_ORG_DIST + "/" + tarball
|
|
||||||
else:
|
|
||||||
std_url = nightly_dist + "/" + tarball
|
|
||||||
|
|
||||||
download_file("Host rust library for target %s" % target_triple, std_url, tgz_file)
|
|
||||||
print("Extracting Rust stdlib for target %s..." % target_triple)
|
|
||||||
extract(tgz_file, install_dir)
|
|
||||||
shutil.copytree(path.join(install_dir,
|
|
||||||
"rust-std-%s-%s" % (version, target_triple),
|
|
||||||
"rust-std-%s" % target_triple,
|
|
||||||
"lib", "rustlib", target_triple),
|
|
||||||
path.join(install_dir,
|
|
||||||
"rustc-%s-%s" % (version, host_triple()),
|
|
||||||
"rustc",
|
|
||||||
"lib", "rustlib", target_triple))
|
|
||||||
shutil.rmtree(path.join(install_dir, "rust-std-%s-%s" % (version, target_triple)))
|
|
||||||
|
|
||||||
print("Rust {} libs ready.".format(target_triple))
|
|
||||||
|
|
||||||
@Command('bootstrap-rust-docs',
|
|
||||||
description='Download the Rust documentation',
|
|
||||||
category='bootstrap')
|
|
||||||
@CommandArgument('--force', '-f',
|
|
||||||
action='store_true',
|
|
||||||
help='Force download even if docs already exist')
|
|
||||||
def bootstrap_rustc_docs(self, force=False):
|
|
||||||
self.ensure_bootstrapped()
|
|
||||||
rust_root = self.config["tools"]["rust-root"]
|
|
||||||
docs_dir = path.join(rust_root, "doc")
|
|
||||||
if not force and path.exists(docs_dir):
|
|
||||||
print("Rust docs already downloaded.", end=" ")
|
|
||||||
print("Use |bootstrap-rust-docs --force| to download again.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if path.isdir(docs_dir):
|
|
||||||
shutil.rmtree(docs_dir)
|
|
||||||
docs_name = self.rust_path().replace("rustc-", "rust-docs-")
|
|
||||||
docs_url = "%s/%s/rust-docs-nightly-%s.tar.gz" % (
|
|
||||||
STATIC_RUST_LANG_ORG_DIST, self.rust_nightly_date(), host_triple()
|
|
||||||
)
|
|
||||||
tgz_file = path.join(rust_root, 'doc.tar.gz')
|
|
||||||
|
|
||||||
download_file("Rust docs", docs_url, tgz_file)
|
|
||||||
|
|
||||||
print("Extracting Rust docs...")
|
|
||||||
temp_dir = path.join(rust_root, "temp_docs")
|
|
||||||
if path.isdir(temp_dir):
|
|
||||||
shutil.rmtree(temp_dir)
|
|
||||||
extract(tgz_file, temp_dir)
|
|
||||||
shutil.move(path.join(temp_dir, docs_name.split("/")[1],
|
|
||||||
"rust-docs", "share", "doc", "rust", "html"),
|
|
||||||
docs_dir)
|
|
||||||
shutil.rmtree(temp_dir)
|
|
||||||
print("Rust docs ready.")
|
|
||||||
|
|
||||||
@Command('bootstrap-cargo',
|
|
||||||
description='Download the Cargo build tool',
|
|
||||||
category='bootstrap')
|
|
||||||
@CommandArgument('--force', '-f',
|
|
||||||
action='store_true',
|
|
||||||
help='Force download even if cargo already exists')
|
|
||||||
def bootstrap_cargo(self, force=False):
|
|
||||||
cargo_dir = path.join(self.context.sharedir, "cargo", self.rust_nightly_date())
|
|
||||||
if not force and path.exists(path.join(cargo_dir, "cargo", "bin", "cargo" + BIN_SUFFIX)):
|
|
||||||
print("Cargo already downloaded.", end=" ")
|
|
||||||
print("Use |bootstrap-cargo --force| to download again.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if path.isdir(cargo_dir):
|
|
||||||
shutil.rmtree(cargo_dir)
|
|
||||||
os.makedirs(cargo_dir)
|
|
||||||
|
|
||||||
tgz_file = "cargo-nightly-%s.tar.gz" % host_triple()
|
|
||||||
nightly_url = "%s/%s/%s" % (STATIC_RUST_LANG_ORG_DIST, self.rust_nightly_date(), tgz_file)
|
|
||||||
|
|
||||||
download_file("Cargo nightly", nightly_url, tgz_file)
|
|
||||||
|
|
||||||
print("Extracting Cargo nightly...")
|
|
||||||
nightly_dir = path.join(cargo_dir,
|
|
||||||
path.basename(tgz_file).replace(".tar.gz", ""))
|
|
||||||
extract(tgz_file, cargo_dir, movedir=nightly_dir)
|
|
||||||
print("Cargo ready.")
|
|
||||||
|
|
||||||
@Command('update-hsts-preload',
|
@Command('update-hsts-preload',
|
||||||
description='Download the HSTS preload list',
|
description='Download the HSTS preload list',
|
||||||
category='bootstrap')
|
category='bootstrap')
|
||||||
|
@ -282,51 +126,31 @@ class MachCommands(CommandBase):
|
||||||
default='1',
|
default='1',
|
||||||
help='Keep up to this many most recent nightlies')
|
help='Keep up to this many most recent nightlies')
|
||||||
def clean_nightlies(self, force=False, keep=None):
|
def clean_nightlies(self, force=False, keep=None):
|
||||||
rust_current_nightly = self.rust_nightly_date()
|
default_toolchain = self.default_toolchain()
|
||||||
rust_current_stable = self.rust_stable_version()
|
geckolib_toolchain = self.geckolib_toolchain()
|
||||||
print("Current Rust nightly version: {}".format(rust_current_nightly))
|
print("Current Rust version for Servo: {}".format(default_toolchain))
|
||||||
print("Current Rust stable version: {}".format(rust_current_stable))
|
print("Current Rust version for geckolib: {}".format(geckolib_toolchain))
|
||||||
to_keep = set()
|
old_toolchains = []
|
||||||
if int(keep) == 1:
|
keep = int(keep)
|
||||||
# Optimize keep=1 case to not invoke git
|
for toolchain_file in ['rust-toolchain', 'geckolib-rust-toolchain']:
|
||||||
to_keep.add(rust_current_nightly)
|
stdout = subprocess.check_output(['git', 'log', '--format=%H', toolchain_file])
|
||||||
to_keep.add(rust_current_stable)
|
for i, commit_hash in enumerate(stdout.split(), 1):
|
||||||
else:
|
if i > keep:
|
||||||
for version_file in ['rust-toolchain', 'rust-stable-version']:
|
toolchain = subprocess.check_output(
|
||||||
cmd = subprocess.Popen(
|
['git', 'show', '%s:%s' % (commit_hash, toolchain_file)])
|
||||||
['git', 'log', '--oneline', '--no-color', '-n', keep, '--patch', version_file],
|
old_toolchains.append(toolchain.strip())
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
universal_newlines=True
|
|
||||||
)
|
|
||||||
stdout, _ = cmd.communicate()
|
|
||||||
for line in stdout.splitlines():
|
|
||||||
if line.startswith(b"+") and not line.startswith(b"+++"):
|
|
||||||
line = line[len(b"+"):]
|
|
||||||
if line.startswith(b"nightly-"):
|
|
||||||
line = line[len(b"nightly-"):]
|
|
||||||
to_keep.add(line)
|
|
||||||
|
|
||||||
removing_anything = False
|
removing_anything = False
|
||||||
for tool in ["rust", "cargo"]:
|
stdout = subprocess.check_output(['rustup', 'toolchain', 'list'])
|
||||||
base = path.join(self.context.sharedir, tool)
|
for toolchain_with_host in stdout.split():
|
||||||
if not path.isdir(base):
|
for old in old_toolchains:
|
||||||
continue
|
if toolchain_with_host.startswith(old):
|
||||||
for name in os.listdir(base):
|
|
||||||
full_path = path.join(base, name)
|
|
||||||
if name.startswith("rust-"):
|
|
||||||
name = name[len("rust-"):]
|
|
||||||
if name.endswith("-alt"):
|
|
||||||
name = name[:-len("-alt")]
|
|
||||||
if name not in to_keep:
|
|
||||||
removing_anything = True
|
removing_anything = True
|
||||||
if force:
|
if force:
|
||||||
print("Removing {}".format(full_path))
|
print("Removing {}".format(toolchain_with_host))
|
||||||
try:
|
check_call(["rustup", "uninstall", toolchain_with_host])
|
||||||
delete(full_path)
|
|
||||||
except OSError as e:
|
|
||||||
print("Removal failed with error {}".format(e))
|
|
||||||
else:
|
else:
|
||||||
print("Would remove {}".format(full_path))
|
print("Would remove {}".format(toolchain_with_host))
|
||||||
if not removing_anything:
|
if not removing_anything:
|
||||||
print("Nothing to remove.")
|
print("Nothing to remove.")
|
||||||
elif not force:
|
elif not force:
|
||||||
|
|
|
@ -233,6 +233,13 @@ class MachCommands(CommandBase):
|
||||||
target = self.config["android"]["target"]
|
target = self.config["android"]["target"]
|
||||||
|
|
||||||
if target:
|
if target:
|
||||||
|
if self.config["tools"]["use-rustup"]:
|
||||||
|
# 'rustup target add' fails if the toolchain is not installed at all.
|
||||||
|
self.call_rustup_run(["rustc", "--version"])
|
||||||
|
|
||||||
|
check_call(["rustup" + BIN_SUFFIX, "target", "add",
|
||||||
|
"--toolchain", self.toolchain(), target])
|
||||||
|
|
||||||
opts += ["--target", target]
|
opts += ["--target", target]
|
||||||
if not android:
|
if not android:
|
||||||
android = self.handle_android_target(target)
|
android = self.handle_android_target(target)
|
||||||
|
@ -340,10 +347,7 @@ class MachCommands(CommandBase):
|
||||||
os.makedirs(aar_out_dir)
|
os.makedirs(aar_out_dir)
|
||||||
env["AAR_OUT_DIR"] = aar_out_dir
|
env["AAR_OUT_DIR"] = aar_out_dir
|
||||||
|
|
||||||
cargo_binary = "cargo" + BIN_SUFFIX
|
status = self.call_rustup_run(["cargo", "build"] + opts, env=env, verbose=verbose)
|
||||||
|
|
||||||
status = call(
|
|
||||||
[cargo_binary, "build"] + opts, env=env, verbose=verbose)
|
|
||||||
elapsed = time() - build_start
|
elapsed = time() - build_start
|
||||||
|
|
||||||
# Do some additional things if the build succeeded
|
# Do some additional things if the build succeeded
|
||||||
|
@ -430,9 +434,9 @@ class MachCommands(CommandBase):
|
||||||
# Unlike RUSTFLAGS, these are only passed in the final rustc invocation
|
# Unlike RUSTFLAGS, these are only passed in the final rustc invocation
|
||||||
# so that `./mach build` followed by `./mach build-cef` both build
|
# so that `./mach build` followed by `./mach build-cef` both build
|
||||||
# common dependencies with the same flags.
|
# common dependencies with the same flags.
|
||||||
opts += ["--", "-C", "link-args=-Xlinker -undefined -Xlinker dynamic_lookup"]
|
opts += ["--", "-Clink-args=-Xlinker -undefined -Xlinker dynamic_lookup"]
|
||||||
|
|
||||||
ret = call(["cargo", "rustc"] + opts, env=env, verbose=verbose)
|
ret = self.call_rustup_run(["cargo", "rustc"] + opts, env=env, verbose=verbose)
|
||||||
elapsed = time() - build_start
|
elapsed = time() - build_start
|
||||||
|
|
||||||
# Generate Desktop Notification if elapsed-time > some threshold value
|
# Generate Desktop Notification if elapsed-time > some threshold value
|
||||||
|
@ -455,7 +459,7 @@ class MachCommands(CommandBase):
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Build in release mode')
|
help='Build in release mode')
|
||||||
def build_geckolib(self, jobs=None, verbose=False, release=False):
|
def build_geckolib(self, jobs=None, verbose=False, release=False):
|
||||||
self.set_use_stable_rust()
|
self.set_use_geckolib_toolchain()
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
self.ensure_clobbered()
|
self.ensure_clobbered()
|
||||||
|
|
||||||
|
@ -475,7 +479,7 @@ class MachCommands(CommandBase):
|
||||||
opts += ["--features", ' '.join(features)]
|
opts += ["--features", ' '.join(features)]
|
||||||
|
|
||||||
build_start = time()
|
build_start = time()
|
||||||
ret = call(["cargo", "build"] + opts, env=env, verbose=verbose)
|
ret = self.call_rustup_run(["cargo", "build"] + opts, env=env, verbose=verbose)
|
||||||
elapsed = time() - build_start
|
elapsed = time() - build_start
|
||||||
|
|
||||||
# Generate Desktop Notification if elapsed-time > some threshold value
|
# Generate Desktop Notification if elapsed-time > some threshold value
|
||||||
|
|
|
@ -138,6 +138,18 @@ def call(*args, **kwargs):
|
||||||
return subprocess.call(*args, shell=sys.platform == 'win32', **kwargs)
|
return subprocess.call(*args, shell=sys.platform == 'win32', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def check_output(*args, **kwargs):
|
||||||
|
"""Wrap `subprocess.call`, printing the command if verbose=True."""
|
||||||
|
verbose = kwargs.pop('verbose', False)
|
||||||
|
if verbose:
|
||||||
|
print(' '.join(args[0]))
|
||||||
|
if 'env' in kwargs:
|
||||||
|
kwargs['env'] = normalize_env(kwargs['env'])
|
||||||
|
# we have to use shell=True in order to get PATH handling
|
||||||
|
# when looking for the binary on Windows
|
||||||
|
return subprocess.check_output(*args, shell=sys.platform == 'win32', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def check_call(*args, **kwargs):
|
def check_call(*args, **kwargs):
|
||||||
"""Wrap `subprocess.check_call`, printing the command if verbose=True.
|
"""Wrap `subprocess.check_call`, printing the command if verbose=True.
|
||||||
|
|
||||||
|
@ -254,10 +266,7 @@ class CommandBase(object):
|
||||||
|
|
||||||
context.sharedir = self.config["tools"]["cache-dir"]
|
context.sharedir = self.config["tools"]["cache-dir"]
|
||||||
|
|
||||||
self.config["tools"].setdefault("system-rust", False)
|
self.config["tools"].setdefault("use-rustup", True)
|
||||||
self.config["tools"].setdefault("system-cargo", False)
|
|
||||||
self.config["tools"].setdefault("rust-root", "")
|
|
||||||
self.config["tools"].setdefault("cargo-root", "")
|
|
||||||
self.config["tools"].setdefault("rustc-with-gold", get_env_bool("SERVO_RUSTC_WITH_GOLD", True))
|
self.config["tools"].setdefault("rustc-with-gold", get_env_bool("SERVO_RUSTC_WITH_GOLD", True))
|
||||||
|
|
||||||
self.config.setdefault("build", {})
|
self.config.setdefault("build", {})
|
||||||
|
@ -276,63 +285,46 @@ class CommandBase(object):
|
||||||
# Set default android target
|
# Set default android target
|
||||||
self.handle_android_target("armv7-linux-androideabi")
|
self.handle_android_target("armv7-linux-androideabi")
|
||||||
|
|
||||||
self.set_cargo_root()
|
self.set_use_geckolib_toolchain(False)
|
||||||
self.set_use_stable_rust(False)
|
|
||||||
|
|
||||||
_use_stable_rust = False
|
_use_geckolib_toolchain = False
|
||||||
_rust_stable_version = None
|
_geckolib_toolchain = None
|
||||||
_rust_nightly_date = None
|
_default_toolchain = None
|
||||||
|
|
||||||
def set_cargo_root(self):
|
def set_use_geckolib_toolchain(self, use_geckolib_toolchain=True):
|
||||||
if not self.config["tools"]["system-cargo"]:
|
self._use_geckolib_toolchain = use_geckolib_toolchain
|
||||||
self.config["tools"]["cargo-root"] = path.join(
|
if use_geckolib_toolchain:
|
||||||
self.context.sharedir, "cargo", self.rust_nightly_date())
|
|
||||||
|
|
||||||
def set_use_stable_rust(self, use_stable_rust=True):
|
|
||||||
self._use_stable_rust = use_stable_rust
|
|
||||||
if not self.config["tools"]["system-rust"]:
|
|
||||||
self.config["tools"]["rust-root"] = path.join(
|
|
||||||
self.context.sharedir, "rust", self.rust_path())
|
|
||||||
if use_stable_rust:
|
|
||||||
# Cargo maintainer's position is that CARGO_INCREMENTAL is a nightly-only feature
|
# Cargo maintainer's position is that CARGO_INCREMENTAL is a nightly-only feature
|
||||||
# and should not be used on the stable channel.
|
# and should not be used on the stable channel.
|
||||||
# https://github.com/rust-lang/cargo/issues/3835
|
# https://github.com/rust-lang/cargo/issues/3835
|
||||||
self.config["build"]["incremental"] = False
|
self.config["build"]["incremental"] = False
|
||||||
|
|
||||||
def use_stable_rust(self):
|
def toolchain(self):
|
||||||
return self._use_stable_rust
|
if self._use_geckolib_toolchain:
|
||||||
|
return self.geckolib_toolchain()
|
||||||
def rust_install_dir(self):
|
|
||||||
if self._use_stable_rust:
|
|
||||||
return self.rust_stable_version()
|
|
||||||
else:
|
else:
|
||||||
return self.rust_nightly_date()
|
return self.default_toolchain()
|
||||||
|
|
||||||
def rust_path(self):
|
def geckolib_toolchain(self):
|
||||||
if self._use_stable_rust:
|
if self._geckolib_toolchain is None:
|
||||||
version = self.rust_stable_version()
|
filename = path.join(self.context.topdir, "geckolib-rust-toolchain")
|
||||||
else:
|
|
||||||
version = "nightly"
|
|
||||||
|
|
||||||
subdir = "rustc-%s-%s" % (version, host_triple())
|
|
||||||
return os.path.join(self.rust_install_dir(), subdir)
|
|
||||||
|
|
||||||
def rust_stable_version(self):
|
|
||||||
if self._rust_stable_version is None:
|
|
||||||
filename = path.join("rust-stable-version")
|
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
self._rust_stable_version = f.read().strip()
|
self._geckolib_toolchain = f.read().strip()
|
||||||
return self._rust_stable_version
|
return self._geckolib_toolchain
|
||||||
|
|
||||||
def rust_nightly_date(self):
|
def default_toolchain(self):
|
||||||
if self._rust_nightly_date is None:
|
if self._default_toolchain is None:
|
||||||
filename = path.join(self.context.topdir, "rust-toolchain")
|
filename = path.join(self.context.topdir, "rust-toolchain")
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
toolchain = f.read().strip()
|
self._default_toolchain = f.read().strip()
|
||||||
prefix = "nightly-"
|
return self._default_toolchain
|
||||||
assert toolchain.startswith(prefix)
|
|
||||||
self._rust_nightly_date = toolchain[len(prefix):]
|
def call_rustup_run(self, args, **kwargs):
|
||||||
return self._rust_nightly_date
|
if self.config["tools"]["use-rustup"]:
|
||||||
|
args = ["rustup" + BIN_SUFFIX, "run", "--install", self.toolchain()] + args
|
||||||
|
else:
|
||||||
|
args[0] += BIN_SUFFIX
|
||||||
|
return call(args, **kwargs)
|
||||||
|
|
||||||
def get_top_dir(self):
|
def get_top_dir(self):
|
||||||
return self.context.topdir
|
return self.context.topdir
|
||||||
|
@ -423,29 +415,9 @@ class CommandBase(object):
|
||||||
# Always build harfbuzz from source
|
# Always build harfbuzz from source
|
||||||
env["HARFBUZZ_SYS_NO_PKG_CONFIG"] = "true"
|
env["HARFBUZZ_SYS_NO_PKG_CONFIG"] = "true"
|
||||||
|
|
||||||
if not self.config["tools"]["system-rust"] \
|
|
||||||
or self.config["tools"]["rust-root"]:
|
|
||||||
env["RUST_ROOT"] = self.config["tools"]["rust-root"]
|
|
||||||
# These paths are for when rust-root points to an unpacked installer
|
|
||||||
extra_path += [path.join(self.config["tools"]["rust-root"], "rustc", "bin")]
|
|
||||||
extra_lib += [path.join(self.config["tools"]["rust-root"], "rustc", "lib")]
|
|
||||||
# These paths are for when rust-root points to a rustc sysroot
|
|
||||||
extra_path += [path.join(self.config["tools"]["rust-root"], "bin")]
|
|
||||||
extra_lib += [path.join(self.config["tools"]["rust-root"], "lib")]
|
|
||||||
|
|
||||||
if not self.config["tools"]["system-cargo"] \
|
|
||||||
or self.config["tools"]["cargo-root"]:
|
|
||||||
# This path is for when rust-root points to an unpacked installer
|
|
||||||
extra_path += [
|
|
||||||
path.join(self.config["tools"]["cargo-root"], "cargo", "bin")]
|
|
||||||
# This path is for when rust-root points to a rustc sysroot
|
|
||||||
extra_path += [
|
|
||||||
path.join(self.config["tools"]["cargo-root"], "bin")]
|
|
||||||
|
|
||||||
if extra_path:
|
if extra_path:
|
||||||
env["PATH"] = "%s%s%s" % (os.pathsep.join(extra_path), os.pathsep, env["PATH"])
|
env["PATH"] = "%s%s%s" % (os.pathsep.join(extra_path), os.pathsep, env["PATH"])
|
||||||
|
|
||||||
env["CARGO_HOME"] = self.config["tools"]["cargo-home-dir"]
|
|
||||||
if self.config["build"]["incremental"]:
|
if self.config["build"]["incremental"]:
|
||||||
env["CARGO_INCREMENTAL"] = "1"
|
env["CARGO_INCREMENTAL"] = "1"
|
||||||
|
|
||||||
|
@ -591,33 +563,10 @@ class CommandBase(object):
|
||||||
|
|
||||||
target_platform = target or host_triple()
|
target_platform = target or host_triple()
|
||||||
|
|
||||||
rust_root = self.config["tools"]["rust-root"]
|
|
||||||
rustc_path = path.join(
|
|
||||||
rust_root, "rustc", "bin", "rustc" + BIN_SUFFIX
|
|
||||||
)
|
|
||||||
rustc_binary_exists = path.exists(rustc_path)
|
|
||||||
|
|
||||||
base_target_path = path.join(rust_root, "rustc", "lib", "rustlib")
|
|
||||||
|
|
||||||
target_path = path.join(base_target_path, target_platform)
|
|
||||||
target_exists = path.exists(target_path)
|
|
||||||
|
|
||||||
# Always check if all needed MSVC dependencies are installed
|
# Always check if all needed MSVC dependencies are installed
|
||||||
if "msvc" in target_platform:
|
if "msvc" in target_platform:
|
||||||
Registrar.dispatch("bootstrap", context=self.context)
|
Registrar.dispatch("bootstrap", context=self.context)
|
||||||
|
|
||||||
if not (self.config['tools']['system-rust'] or (rustc_binary_exists and target_exists)):
|
|
||||||
print("Looking for rustc at %s" % (rustc_path))
|
|
||||||
Registrar.dispatch("bootstrap-rust", context=self.context, target=filter(None, [target]),
|
|
||||||
stable=self._use_stable_rust)
|
|
||||||
|
|
||||||
cargo_path = path.join(self.config["tools"]["cargo-root"], "cargo", "bin",
|
|
||||||
"cargo" + BIN_SUFFIX)
|
|
||||||
cargo_binary_exists = path.exists(cargo_path)
|
|
||||||
|
|
||||||
if not self.config["tools"]["system-cargo"] and not cargo_binary_exists:
|
|
||||||
Registrar.dispatch("bootstrap-cargo", context=self.context)
|
|
||||||
|
|
||||||
self.context.bootstrapped = True
|
self.context.bootstrapped = True
|
||||||
|
|
||||||
def ensure_clobbered(self, target_dir=None):
|
def ensure_clobbered(self, target_dir=None):
|
||||||
|
|
|
@ -21,7 +21,7 @@ from mach.decorators import (
|
||||||
Command,
|
Command,
|
||||||
)
|
)
|
||||||
|
|
||||||
from servo.command_base import CommandBase, cd, call
|
from servo.command_base import CommandBase, cd, call, BIN_SUFFIX
|
||||||
from servo.build_commands import notify_build_done
|
from servo.build_commands import notify_build_done
|
||||||
from servo.util import STATIC_RUST_LANG_ORG_DIST, URLOPEN_KWARGS
|
from servo.util import STATIC_RUST_LANG_ORG_DIST, URLOPEN_KWARGS
|
||||||
|
|
||||||
|
@ -43,16 +43,16 @@ class MachCommands(CommandBase):
|
||||||
# for c in $(cargo --list | tail -$(($(cargo --list | wc -l) - 1))); do
|
# for c in $(cargo --list | tail -$(($(cargo --list | wc -l) - 1))); do
|
||||||
# (cargo help $c 2>&1 | grep "\\--package" >/dev/null 2>&1) && echo $c
|
# (cargo help $c 2>&1 | grep "\\--package" >/dev/null 2>&1) && echo $c
|
||||||
# done
|
# done
|
||||||
if params[0] and params[0] in [
|
if params and params[0] in [
|
||||||
'bench', 'build', 'check', 'clean', 'doc', 'fmt', 'pkgid',
|
'bench', 'build', 'check', 'clean', 'doc', 'fmt', 'pkgid',
|
||||||
'run', 'rustc', 'rustdoc', 'test', 'update',
|
'run', 'rustc', 'rustdoc', 'test', 'update',
|
||||||
]:
|
]:
|
||||||
params[1:1] = ['--package', 'geckoservo']
|
params[1:1] = ['--package', 'geckoservo']
|
||||||
|
|
||||||
self.set_use_stable_rust()
|
self.set_use_geckolib_toolchain()
|
||||||
|
|
||||||
build_start = time()
|
build_start = time()
|
||||||
status = call(['cargo'] + params, env=env)
|
status = self.call_rustup_run(["cargo"] + params, env=env)
|
||||||
elapsed = time() - build_start
|
elapsed = time() - build_start
|
||||||
|
|
||||||
notify_build_done(self.config, elapsed, status == 0)
|
notify_build_done(self.config, elapsed, status == 0)
|
||||||
|
@ -197,8 +197,7 @@ class MachCommands(CommandBase):
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
|
|
||||||
with cd(self.context.topdir):
|
with cd(self.context.topdir):
|
||||||
call(["cargo", "update"] + params,
|
self.call_rustup_run(["cargo", "update"] + params, env=self.build_env())
|
||||||
env=self.build_env())
|
|
||||||
|
|
||||||
@Command('rustc',
|
@Command('rustc',
|
||||||
description='Run the Rust compiler',
|
description='Run the Rust compiler',
|
||||||
|
@ -211,8 +210,7 @@ class MachCommands(CommandBase):
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
|
return self.call_rustup_run(["rustc"] + params, env=self.build_env())
|
||||||
return call(["rustc"] + params, env=self.build_env())
|
|
||||||
|
|
||||||
@Command('rustc-geckolib',
|
@Command('rustc-geckolib',
|
||||||
description='Run the Rust compiler with the same compiler version and root crate as build-geckolib',
|
description='Run the Rust compiler with the same compiler version and root crate as build-geckolib',
|
||||||
|
@ -224,17 +222,11 @@ class MachCommands(CommandBase):
|
||||||
if params is None:
|
if params is None:
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
self.set_use_stable_rust()
|
self.set_use_geckolib_toolchain()
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
env = self.build_env(geckolib=True)
|
env = self.build_env(geckolib=True)
|
||||||
|
|
||||||
return call(["rustc"] + params, env=env)
|
return self.call_rustup_run(["rustc"] + params, env=env)
|
||||||
|
|
||||||
@Command('rust-root',
|
|
||||||
description='Print the path to the root of the Rust compiler',
|
|
||||||
category='devenv')
|
|
||||||
def rust_root(self):
|
|
||||||
print(self.config["tools"]["rust-root"])
|
|
||||||
|
|
||||||
@Command('grep',
|
@Command('grep',
|
||||||
description='`git grep` for selected directories.',
|
description='`git grep` for selected directories.',
|
||||||
|
@ -267,24 +259,17 @@ class MachCommands(CommandBase):
|
||||||
def rustup(self):
|
def rustup(self):
|
||||||
url = STATIC_RUST_LANG_ORG_DIST + "/channel-rust-nightly-date.txt"
|
url = STATIC_RUST_LANG_ORG_DIST + "/channel-rust-nightly-date.txt"
|
||||||
nightly_date = urllib2.urlopen(url, **URLOPEN_KWARGS).read()
|
nightly_date = urllib2.urlopen(url, **URLOPEN_KWARGS).read()
|
||||||
|
toolchain = "nightly-" + nightly_date
|
||||||
filename = path.join(self.context.topdir, "rust-toolchain")
|
filename = path.join(self.context.topdir, "rust-toolchain")
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
f.write("nightly-%s\n" % nightly_date)
|
f.write(toolchain + "\n")
|
||||||
|
return call(["rustup" + BIN_SUFFIX, "install", toolchain])
|
||||||
# Reset self.config["tools"]["rust-root"] and self.config["tools"]["cargo-root"]
|
|
||||||
self._rust_nightly_date = None
|
|
||||||
self.set_use_stable_rust(False)
|
|
||||||
self.set_cargo_root()
|
|
||||||
|
|
||||||
self.fetch()
|
|
||||||
|
|
||||||
@Command('fetch',
|
@Command('fetch',
|
||||||
description='Fetch Rust, Cargo and Cargo dependencies',
|
description='Fetch Rust, Cargo and Cargo dependencies',
|
||||||
category='devenv')
|
category='devenv')
|
||||||
def fetch(self):
|
def fetch(self):
|
||||||
# Fetch Rust and Cargo
|
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
|
|
||||||
# Fetch Cargo dependencies
|
|
||||||
with cd(self.context.topdir):
|
with cd(self.context.topdir):
|
||||||
call(["cargo", "fetch"], env=self.build_env())
|
return self.call_rustup_run(["cargo", "fetch"], env=self.build_env())
|
||||||
|
|
|
@ -14,8 +14,6 @@ import os.path as path
|
||||||
import subprocess
|
import subprocess
|
||||||
from shutil import copytree, rmtree, copy2
|
from shutil import copytree, rmtree, copy2
|
||||||
|
|
||||||
from mach.registrar import Registrar
|
|
||||||
|
|
||||||
from mach.decorators import (
|
from mach.decorators import (
|
||||||
CommandArgument,
|
CommandArgument,
|
||||||
CommandProvider,
|
CommandProvider,
|
||||||
|
@ -24,7 +22,7 @@ from mach.decorators import (
|
||||||
|
|
||||||
from servo.command_base import (
|
from servo.command_base import (
|
||||||
CommandBase,
|
CommandBase,
|
||||||
call, check_call,
|
check_call, check_output, BIN_SUFFIX,
|
||||||
is_linux, is_windows, is_macosx, set_osmesa_env,
|
is_linux, is_windows, is_macosx, set_osmesa_env,
|
||||||
get_browserhtml_path,
|
get_browserhtml_path,
|
||||||
)
|
)
|
||||||
|
@ -211,10 +209,14 @@ class PostBuildCommands(CommandBase):
|
||||||
'params', nargs='...',
|
'params', nargs='...',
|
||||||
help="Command-line arguments to be passed through to cargo doc")
|
help="Command-line arguments to be passed through to cargo doc")
|
||||||
def doc(self, params):
|
def doc(self, params):
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["RUSTUP_TOOLCHAIN"] = self.toolchain()
|
||||||
|
rustc_path = check_output(["rustup" + BIN_SUFFIX, "which", "rustc"], env=env)
|
||||||
|
assert path.basename(path.dirname(rustc_path)) == "bin"
|
||||||
|
toolchain_path = path.dirname(path.dirname(rustc_path))
|
||||||
|
rust_docs = path.join(toolchain_path, "share", "doc", "rust", "html")
|
||||||
|
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
if not path.exists(path.join(self.config["tools"]["rust-root"], "doc")):
|
|
||||||
Registrar.dispatch("bootstrap-rust-docs", context=self.context)
|
|
||||||
rust_docs = path.join(self.config["tools"]["rust-root"], "doc")
|
|
||||||
docs = path.join(self.get_target_dir(), "doc")
|
docs = path.join(self.get_target_dir(), "doc")
|
||||||
if not path.exists(docs):
|
if not path.exists(docs):
|
||||||
os.makedirs(docs)
|
os.makedirs(docs)
|
||||||
|
@ -234,8 +236,10 @@ class PostBuildCommands(CommandBase):
|
||||||
else:
|
else:
|
||||||
copy2(full_name, destination)
|
copy2(full_name, destination)
|
||||||
|
|
||||||
return call(["cargo", "doc"] + params,
|
return self.call_rustup_run(
|
||||||
env=self.build_env(), cwd=self.servo_crate())
|
["cargo", "doc", "--manifest-path", self.servo_manifest()] + params,
|
||||||
|
env=self.build_env()
|
||||||
|
)
|
||||||
|
|
||||||
@Command('browse-doc',
|
@Command('browse-doc',
|
||||||
description='Generate documentation and open it in a web browser',
|
description='Generate documentation and open it in a web browser',
|
||||||
|
|
|
@ -34,7 +34,7 @@ from mach.decorators import (
|
||||||
|
|
||||||
from servo.command_base import (
|
from servo.command_base import (
|
||||||
BuildNotFound, CommandBase,
|
BuildNotFound, CommandBase,
|
||||||
call, cd, check_call, set_osmesa_env,
|
call, check_call, set_osmesa_env,
|
||||||
)
|
)
|
||||||
from servo.util import host_triple
|
from servo.util import host_triple
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ class MachCommands(CommandBase):
|
||||||
|
|
||||||
features = self.servo_features()
|
features = self.servo_features()
|
||||||
if len(packages) > 0:
|
if len(packages) > 0:
|
||||||
args = ["cargo", "bench" if bench else "test"]
|
args = ["cargo", "bench" if bench else "test", "--manifest-path", self.servo_manifest()]
|
||||||
for crate in packages:
|
for crate in packages:
|
||||||
args += ["-p", "%s_tests" % crate]
|
args += ["-p", "%s_tests" % crate]
|
||||||
for crate in in_crate_packages:
|
for crate in in_crate_packages:
|
||||||
|
@ -278,7 +278,7 @@ class MachCommands(CommandBase):
|
||||||
if nocapture:
|
if nocapture:
|
||||||
args += ["--", "--nocapture"]
|
args += ["--", "--nocapture"]
|
||||||
|
|
||||||
err = call(args, env=env, cwd=self.servo_crate())
|
err = self.call_rustup_run(args, env=env)
|
||||||
if err is not 0:
|
if err is not 0:
|
||||||
return err
|
return err
|
||||||
|
|
||||||
|
@ -290,17 +290,19 @@ class MachCommands(CommandBase):
|
||||||
@CommandArgument('--release', default=False, action="store_true",
|
@CommandArgument('--release', default=False, action="store_true",
|
||||||
help="Run with a release build of servo")
|
help="Run with a release build of servo")
|
||||||
def test_stylo(self, release=False, test_name=None):
|
def test_stylo(self, release=False, test_name=None):
|
||||||
self.set_use_stable_rust()
|
self.set_use_geckolib_toolchain()
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
|
|
||||||
env = self.build_env()
|
env = self.build_env()
|
||||||
env["RUST_BACKTRACE"] = "1"
|
env["RUST_BACKTRACE"] = "1"
|
||||||
env["CARGO_TARGET_DIR"] = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
|
env["CARGO_TARGET_DIR"] = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
|
||||||
|
|
||||||
args = (["cargo", "test", "-p", "stylo_tests"] +
|
args = (
|
||||||
(["--release"] if release else []) + (test_name or []))
|
["cargo", "test", "--manifest-path", self.geckolib_manifest(), "-p", "stylo_tests"] +
|
||||||
with cd(path.join("ports", "geckolib")):
|
(["--release"] if release else []) +
|
||||||
return call(args, env=env)
|
(test_name or [])
|
||||||
|
)
|
||||||
|
return self.call_rustup_run(args, env=env)
|
||||||
|
|
||||||
@Command('test-content',
|
@Command('test-content',
|
||||||
description='Run the content tests',
|
description='Run the content tests',
|
||||||
|
|
|
@ -16,7 +16,6 @@ import shutil
|
||||||
from socket import error as socket_error
|
from socket import error as socket_error
|
||||||
import StringIO
|
import StringIO
|
||||||
import sys
|
import sys
|
||||||
import tarfile
|
|
||||||
import zipfile
|
import zipfile
|
||||||
import urllib2
|
import urllib2
|
||||||
import certifi
|
import certifi
|
||||||
|
@ -148,10 +147,8 @@ def download_file(desc, src, dst):
|
||||||
|
|
||||||
|
|
||||||
def extract(src, dst, movedir=None):
|
def extract(src, dst, movedir=None):
|
||||||
if src.endswith(".zip"):
|
assert src.endswith(".zip")
|
||||||
zipfile.ZipFile(src).extractall(dst)
|
zipfile.ZipFile(src).extractall(dst)
|
||||||
else:
|
|
||||||
tarfile.open(src).extractall(dst)
|
|
||||||
|
|
||||||
if movedir:
|
if movedir:
|
||||||
for f in os.listdir(movedir):
|
for f in os.listdir(movedir):
|
||||||
|
|
|
@ -6,22 +6,11 @@
|
||||||
|
|
||||||
# Tool options
|
# Tool options
|
||||||
[tools]
|
[tools]
|
||||||
# Where Rust compiler and other downloads will be stored. Can be
|
# If use-rustup is set to false, mach will run for example "cargo build"
|
||||||
# shared by multiple Servo repositories. Defaults to <servo-repo>/.servo
|
# instead of "rustup run --install <toolchain> cargo build"
|
||||||
cache-dir = "./.servo"
|
# It is then the user’s responsibility to ensure that cargo and especially rustc
|
||||||
|
# in $PATH are versions compatible with Servo.
|
||||||
# Where Cargo stores all of its clones Defaults to <servo-repo>/.cargo
|
use-rustup = true
|
||||||
cargo-home-dir = "./.cargo"
|
|
||||||
|
|
||||||
# If system-rust is true, will use rustc/rustdoc from the path, or if
|
|
||||||
# rust-root is specified, will make sure that rust-root is in the path
|
|
||||||
# when building. Similarly for Cargo. This takes care of PATH as well as
|
|
||||||
# [DY]LD_LIBRARY_PATH.
|
|
||||||
# rust-root and cargo-root default to <servo-repo>/
|
|
||||||
system-rust = false
|
|
||||||
#rust-root = "/path/to/rust"
|
|
||||||
system-cargo = false
|
|
||||||
#cargo-root = "/path/to/cargo"
|
|
||||||
|
|
||||||
# If rustc-with-gold is true, will try to find and use gold linker with rustc.
|
# If rustc-with-gold is true, will try to find and use gold linker with rustc.
|
||||||
# Defaults to true
|
# Defaults to true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue