mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-05 11:32:43 +00:00
New upstream version 1.20.0+dfsg1
This commit is contained in:
parent
8341ceaecd
commit
041b39d230
@ -232,6 +232,7 @@ Some common invocations of `x.py` are:
|
|||||||
guidelines as of yet, but basic rules like 4 spaces for indentation and no
|
guidelines as of yet, but basic rules like 4 spaces for indentation and no
|
||||||
more than 99 characters in a single line should be kept in mind when writing
|
more than 99 characters in a single line should be kept in mind when writing
|
||||||
code.
|
code.
|
||||||
|
- `rustup toolchain link <name> build/<host-triple>/<stage>` - Use the custom compiler build via [rustup](https://github.com/rust-lang-nursery/rustup.rs#working-with-custom-toolchains-and-local-builds).
|
||||||
|
|
||||||
## Pull Requests
|
## Pull Requests
|
||||||
|
|
||||||
|
@ -22,12 +22,6 @@ The Rust Project includes packages written by third parties.
|
|||||||
The following third party packages are included, and carry
|
The following third party packages are included, and carry
|
||||||
their own copyright notices and license terms:
|
their own copyright notices and license terms:
|
||||||
|
|
||||||
* The src/rt/miniz.c file, carrying an implementation of
|
|
||||||
RFC1950/RFC1951 DEFLATE, by Rich Geldreich
|
|
||||||
<richgel99@gmail.com>. All uses of this file are
|
|
||||||
permitted by the embedded "unlicense" notice
|
|
||||||
(effectively: public domain with warranty disclaimer).
|
|
||||||
|
|
||||||
* LLVM. Code for this package is found in src/llvm.
|
* LLVM. Code for this package is found in src/llvm.
|
||||||
|
|
||||||
Copyright (c) 2003-2013 University of Illinois at
|
Copyright (c) 2003-2013 University of Illinois at
|
||||||
|
@ -7,9 +7,9 @@ standard library, and documentation.
|
|||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
Read ["Installing Rust"] from [The Book].
|
Read ["Installation"] from [The Book].
|
||||||
|
|
||||||
["Installing Rust"]: https://doc.rust-lang.org/book/getting-started.html#installing-rust
|
["Installation"]: https://doc.rust-lang.org/book/second-edition/ch01-01-installation.html
|
||||||
[The Book]: https://doc.rust-lang.org/book/index.html
|
[The Book]: https://doc.rust-lang.org/book/index.html
|
||||||
|
|
||||||
## Building from Source
|
## Building from Source
|
||||||
@ -40,8 +40,9 @@ Read ["Installing Rust"] from [The Book].
|
|||||||
|
|
||||||
> ***Note:*** Install locations can be adjusted by copying the config file
|
> ***Note:*** Install locations can be adjusted by copying the config file
|
||||||
> from `./src/bootstrap/config.toml.example` to `./config.toml`, and
|
> from `./src/bootstrap/config.toml.example` to `./config.toml`, and
|
||||||
> adjusting the `prefix` option under `[install]`. Various other options are
|
> adjusting the `prefix` option under `[install]`. Various other options, such
|
||||||
> also supported, and are documented in the config file.
|
> as enabling debug information, are also supported, and are documented in
|
||||||
|
> the config file.
|
||||||
|
|
||||||
When complete, `sudo ./x.py install` will place several programs into
|
When complete, `sudo ./x.py install` will place several programs into
|
||||||
`/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
|
`/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
|
||||||
|
2
configure
vendored
2
configure
vendored
@ -452,6 +452,7 @@ opt vendor 0 "enable usage of vendored Rust crates"
|
|||||||
opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)"
|
opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)"
|
||||||
opt dist-src 1 "when building tarballs enables building a source tarball"
|
opt dist-src 1 "when building tarballs enables building a source tarball"
|
||||||
opt cargo-openssl-static 0 "static openssl in cargo"
|
opt cargo-openssl-static 0 "static openssl in cargo"
|
||||||
|
opt profiler 0 "build the profiler runtime"
|
||||||
|
|
||||||
# Optimization and debugging options. These may be overridden by the release channel, etc.
|
# Optimization and debugging options. These may be overridden by the release channel, etc.
|
||||||
opt_nosave optimize 1 "build optimized rust code"
|
opt_nosave optimize 1 "build optimized rust code"
|
||||||
@ -489,6 +490,7 @@ valopt musl-root-armhf "" "arm-unknown-linux-musleabihf install directory"
|
|||||||
valopt musl-root-armv7 "" "armv7-unknown-linux-musleabihf install directory"
|
valopt musl-root-armv7 "" "armv7-unknown-linux-musleabihf install directory"
|
||||||
valopt extra-filename "" "Additional data that is hashed and passed to the -C extra-filename flag"
|
valopt extra-filename "" "Additional data that is hashed and passed to the -C extra-filename flag"
|
||||||
valopt qemu-armhf-rootfs "" "rootfs in qemu testing, you probably don't want to use this"
|
valopt qemu-armhf-rootfs "" "rootfs in qemu testing, you probably don't want to use this"
|
||||||
|
valopt experimental-targets "" "experimental LLVM targets to build"
|
||||||
|
|
||||||
if [ -e ${CFG_SRC_DIR}.git ]
|
if [ -e ${CFG_SRC_DIR}.git ]
|
||||||
then
|
then
|
||||||
|
759
src/Cargo.lock
generated
759
src/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@ members = [
|
|||||||
"tools/error_index_generator",
|
"tools/error_index_generator",
|
||||||
"tools/linkchecker",
|
"tools/linkchecker",
|
||||||
"tools/rustbook",
|
"tools/rustbook",
|
||||||
|
"tools/unstable-book-gen",
|
||||||
"tools/tidy",
|
"tools/tidy",
|
||||||
"tools/build-manifest",
|
"tools/build-manifest",
|
||||||
"tools/remote-test-client",
|
"tools/remote-test-client",
|
||||||
|
@ -75,16 +75,11 @@ fn main() {
|
|||||||
Err(_) => 0,
|
Err(_) => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build scripts always use the snapshot compiler which is guaranteed to be
|
// Use a different compiler for build scripts, since there may not yet be a
|
||||||
// able to produce an executable, whereas intermediate compilers may not
|
// libstd for the real compiler to use. However, if Cargo is attempting to
|
||||||
// have the standard library built yet and may not be able to produce an
|
// determine the version of the compiler, the real compiler needs to be
|
||||||
// executable. Otherwise we just use the standard compiler we're
|
// used. Currently, these two states are differentiated based on whether
|
||||||
// bootstrapping with.
|
// --target and -vV is/isn't passed.
|
||||||
//
|
|
||||||
// Also note that cargo will detect the version of the compiler to trigger
|
|
||||||
// a rebuild when the compiler changes. If this happens, we want to make
|
|
||||||
// sure to use the actual compiler instead of the snapshot compiler becase
|
|
||||||
// that's the one that's actually changing.
|
|
||||||
let (rustc, libdir) = if target.is_none() && version.is_none() {
|
let (rustc, libdir) = if target.is_none() && version.is_none() {
|
||||||
("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
|
("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
|
||||||
} else {
|
} else {
|
||||||
@ -118,13 +113,6 @@ fn main() {
|
|||||||
cmd.arg("-Cprefer-dynamic");
|
cmd.arg("-Cprefer-dynamic");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the `rustbuild` feature flag to crates which rustbuild is
|
|
||||||
// building. See the comment in bootstrap/lib.rs where this env var is
|
|
||||||
// set for more details.
|
|
||||||
if env::var_os("RUSTBUILD_UNSTABLE").is_some() {
|
|
||||||
cmd.arg("--cfg").arg("rustbuild");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Help the libc crate compile by assisting it in finding the MUSL
|
// Help the libc crate compile by assisting it in finding the MUSL
|
||||||
// native libraries.
|
// native libraries.
|
||||||
if let Some(s) = env::var_os("MUSL_ROOT") {
|
if let Some(s) = env::var_os("MUSL_ROOT") {
|
||||||
@ -149,6 +137,11 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let crate_name = args.windows(2)
|
||||||
|
.find(|a| &*a[0] == "--crate-name")
|
||||||
|
.unwrap();
|
||||||
|
let crate_name = &*crate_name[1];
|
||||||
|
|
||||||
// If we're compiling specifically the `panic_abort` crate then we pass
|
// If we're compiling specifically the `panic_abort` crate then we pass
|
||||||
// the `-C panic=abort` option. Note that we do not do this for any
|
// the `-C panic=abort` option. Note that we do not do this for any
|
||||||
// other crate intentionally as this is the only crate for now that we
|
// other crate intentionally as this is the only crate for now that we
|
||||||
@ -157,9 +150,12 @@ fn main() {
|
|||||||
// This... is a bit of a hack how we detect this. Ideally this
|
// This... is a bit of a hack how we detect this. Ideally this
|
||||||
// information should be encoded in the crate I guess? Would likely
|
// information should be encoded in the crate I guess? Would likely
|
||||||
// require an RFC amendment to RFC 1513, however.
|
// require an RFC amendment to RFC 1513, however.
|
||||||
let is_panic_abort = args.windows(2)
|
//
|
||||||
.any(|a| &*a[0] == "--crate-name" && &*a[1] == "panic_abort");
|
// `compiler_builtins` are unconditionally compiled with panic=abort to
|
||||||
if is_panic_abort {
|
// workaround undefined references to `rust_eh_unwind_resume` generated
|
||||||
|
// otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
|
||||||
|
if crate_name == "panic_abort" ||
|
||||||
|
crate_name == "compiler_builtins" && stage != "0" {
|
||||||
cmd.arg("-C").arg("panic=abort");
|
cmd.arg("-C").arg("panic=abort");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +170,15 @@ fn main() {
|
|||||||
Ok(s) => if s == "true" { "y" } else { "n" },
|
Ok(s) => if s == "true" { "y" } else { "n" },
|
||||||
Err(..) => "n",
|
Err(..) => "n",
|
||||||
};
|
};
|
||||||
cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
|
|
||||||
|
// The compiler builtins are pretty sensitive to symbols referenced in
|
||||||
|
// libcore and such, so we never compile them with debug assertions.
|
||||||
|
if crate_name == "compiler_builtins" {
|
||||||
|
cmd.arg("-C").arg("debug-assertions=no");
|
||||||
|
} else {
|
||||||
|
cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
|
if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
|
||||||
cmd.arg("-C").arg(format!("codegen-units={}", s));
|
cmd.arg("-C").arg(format!("codegen-units={}", s));
|
||||||
}
|
}
|
||||||
@ -218,11 +222,7 @@ fn main() {
|
|||||||
// do that we pass a weird flag to the compiler to get it to do
|
// do that we pass a weird flag to the compiler to get it to do
|
||||||
// so. Note that this is definitely a hack, and we should likely
|
// so. Note that this is definitely a hack, and we should likely
|
||||||
// flesh out rpath support more fully in the future.
|
// flesh out rpath support more fully in the future.
|
||||||
//
|
cmd.arg("-Z").arg("osx-rpath-install-name");
|
||||||
// FIXME: remove condition after next stage0
|
|
||||||
if stage != "0" {
|
|
||||||
cmd.arg("-Z").arg("osx-rpath-install-name");
|
|
||||||
}
|
|
||||||
Some("-Wl,-rpath,@loader_path/../lib")
|
Some("-Wl,-rpath,@loader_path/../lib")
|
||||||
} else if !target.contains("windows") {
|
} else if !target.contains("windows") {
|
||||||
Some("-Wl,-rpath,$ORIGIN/../lib")
|
Some("-Wl,-rpath,$ORIGIN/../lib")
|
||||||
@ -242,15 +242,20 @@ fn main() {
|
|||||||
// Force all crates compiled by this compiler to (a) be unstable and (b)
|
// Force all crates compiled by this compiler to (a) be unstable and (b)
|
||||||
// allow the `rustc_private` feature to link to other unstable crates
|
// allow the `rustc_private` feature to link to other unstable crates
|
||||||
// also in the sysroot.
|
// also in the sysroot.
|
||||||
//
|
|
||||||
// FIXME: remove condition after next stage0
|
|
||||||
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
|
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
|
||||||
if stage != "0" {
|
cmd.arg("-Z").arg("force-unstable-if-unmarked");
|
||||||
cmd.arg("-Z").arg("force-unstable-if-unmarked");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let color = match env::var("RUSTC_COLOR") {
|
||||||
|
Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
|
||||||
|
Err(_) => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if color != 0 {
|
||||||
|
cmd.arg("--color=always");
|
||||||
|
}
|
||||||
|
|
||||||
if verbose > 1 {
|
if verbose > 1 {
|
||||||
writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap();
|
writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -41,11 +41,11 @@ fn main() {
|
|||||||
.env(bootstrap::util::dylib_path_var(),
|
.env(bootstrap::util::dylib_path_var(),
|
||||||
env::join_paths(&dylib_path).unwrap());
|
env::join_paths(&dylib_path).unwrap());
|
||||||
|
|
||||||
// Pass the `rustbuild` feature flag to crates which rustbuild is
|
// Force all crates compiled by this compiler to (a) be unstable and (b)
|
||||||
// building. See the comment in bootstrap/lib.rs where this env var is
|
// allow the `rustc_private` feature to link to other unstable crates
|
||||||
// set for more details.
|
// also in the sysroot.
|
||||||
if env::var_os("RUSTBUILD_UNSTABLE").is_some() {
|
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
|
||||||
cmd.arg("--cfg").arg("rustbuild");
|
cmd.arg("-Z").arg("force-unstable-if-unmarked");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::process::exit(match cmd.status() {
|
std::process::exit(match cmd.status() {
|
||||||
|
@ -25,10 +25,11 @@ from time import time
|
|||||||
|
|
||||||
|
|
||||||
def get(url, path, verbose=False):
|
def get(url, path, verbose=False):
|
||||||
sha_url = url + ".sha256"
|
suffix = '.sha256'
|
||||||
|
sha_url = url + suffix
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
||||||
temp_path = temp_file.name
|
temp_path = temp_file.name
|
||||||
with tempfile.NamedTemporaryFile(suffix=".sha256", delete=False) as sha_file:
|
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as sha_file:
|
||||||
sha_path = sha_file.name
|
sha_path = sha_file.name
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -55,6 +56,7 @@ def get(url, path, verbose=False):
|
|||||||
|
|
||||||
|
|
||||||
def delete_if_present(path, verbose):
|
def delete_if_present(path, verbose):
|
||||||
|
"""Remove the given file if present"""
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
if verbose:
|
if verbose:
|
||||||
print("removing " + path)
|
print("removing " + path)
|
||||||
@ -92,12 +94,13 @@ def _download(path, url, probably_big, verbose, exception):
|
|||||||
|
|
||||||
|
|
||||||
def verify(path, sha_path, verbose):
|
def verify(path, sha_path, verbose):
|
||||||
|
"""Check if the sha256 sum of the given path is valid"""
|
||||||
if verbose:
|
if verbose:
|
||||||
print("verifying " + path)
|
print("verifying " + path)
|
||||||
with open(path, "rb") as f:
|
with open(path, "rb") as source:
|
||||||
found = hashlib.sha256(f.read()).hexdigest()
|
found = hashlib.sha256(source.read()).hexdigest()
|
||||||
with open(sha_path, "r") as f:
|
with open(sha_path, "r") as sha256sum:
|
||||||
expected = f.readline().split()[0]
|
expected = sha256sum.readline().split()[0]
|
||||||
verified = found == expected
|
verified = found == expected
|
||||||
if not verified:
|
if not verified:
|
||||||
print("invalid checksum:\n"
|
print("invalid checksum:\n"
|
||||||
@ -107,6 +110,7 @@ def verify(path, sha_path, verbose):
|
|||||||
|
|
||||||
|
|
||||||
def unpack(tarball, dst, verbose=False, match=None):
|
def unpack(tarball, dst, verbose=False, match=None):
|
||||||
|
"""Unpack the given tarball file"""
|
||||||
print("extracting " + tarball)
|
print("extracting " + tarball)
|
||||||
fname = os.path.basename(tarball).replace(".tar.gz", "")
|
fname = os.path.basename(tarball).replace(".tar.gz", "")
|
||||||
with contextlib.closing(tarfile.open(tarball)) as tar:
|
with contextlib.closing(tarfile.open(tarball)) as tar:
|
||||||
@ -128,6 +132,7 @@ def unpack(tarball, dst, verbose=False, match=None):
|
|||||||
shutil.move(tp, fp)
|
shutil.move(tp, fp)
|
||||||
shutil.rmtree(os.path.join(dst, fname))
|
shutil.rmtree(os.path.join(dst, fname))
|
||||||
|
|
||||||
|
|
||||||
def run(args, verbose=False, exception=False, **kwargs):
|
def run(args, verbose=False, exception=False, **kwargs):
|
||||||
if verbose:
|
if verbose:
|
||||||
print("running: " + ' '.join(args))
|
print("running: " + ' '.join(args))
|
||||||
@ -245,7 +250,8 @@ class RustBuild(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# At this point we're pretty sure the user is running NixOS
|
# At this point we're pretty sure the user is running NixOS
|
||||||
print("info: you seem to be running NixOS. Attempting to patch " + fname)
|
nix_os_msg = "info: you seem to be running NixOS. Attempting to patch"
|
||||||
|
print(nix_os_msg, fname)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
interpreter = subprocess.check_output(
|
interpreter = subprocess.check_output(
|
||||||
@ -293,18 +299,22 @@ class RustBuild(object):
|
|||||||
return self._cargo_channel
|
return self._cargo_channel
|
||||||
|
|
||||||
def rustc_stamp(self):
|
def rustc_stamp(self):
|
||||||
|
"""Return the path for .rustc-stamp"""
|
||||||
return os.path.join(self.bin_root(), '.rustc-stamp')
|
return os.path.join(self.bin_root(), '.rustc-stamp')
|
||||||
|
|
||||||
def cargo_stamp(self):
|
def cargo_stamp(self):
|
||||||
|
"""Return the path for .cargo-stamp"""
|
||||||
return os.path.join(self.bin_root(), '.cargo-stamp')
|
return os.path.join(self.bin_root(), '.cargo-stamp')
|
||||||
|
|
||||||
def rustc_out_of_date(self):
|
def rustc_out_of_date(self):
|
||||||
|
"""Check if rustc is out of date"""
|
||||||
if not os.path.exists(self.rustc_stamp()) or self.clean:
|
if not os.path.exists(self.rustc_stamp()) or self.clean:
|
||||||
return True
|
return True
|
||||||
with open(self.rustc_stamp(), 'r') as f:
|
with open(self.rustc_stamp(), 'r') as f:
|
||||||
return self.stage0_date() != f.read()
|
return self.stage0_date() != f.read()
|
||||||
|
|
||||||
def cargo_out_of_date(self):
|
def cargo_out_of_date(self):
|
||||||
|
"""Check if cargo is out of date"""
|
||||||
if not os.path.exists(self.cargo_stamp()) or self.clean:
|
if not os.path.exists(self.cargo_stamp()) or self.clean:
|
||||||
return True
|
return True
|
||||||
with open(self.cargo_stamp(), 'r') as f:
|
with open(self.cargo_stamp(), 'r') as f:
|
||||||
@ -357,8 +367,7 @@ class RustBuild(object):
|
|||||||
def exe_suffix(self):
|
def exe_suffix(self):
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
return '.exe'
|
return '.exe'
|
||||||
else:
|
return ''
|
||||||
return ''
|
|
||||||
|
|
||||||
def print_what_it_means_to_bootstrap(self):
|
def print_what_it_means_to_bootstrap(self):
|
||||||
if hasattr(self, 'printed'):
|
if hasattr(self, 'printed'):
|
||||||
@ -366,7 +375,7 @@ class RustBuild(object):
|
|||||||
self.printed = True
|
self.printed = True
|
||||||
if os.path.exists(self.bootstrap_binary()):
|
if os.path.exists(self.bootstrap_binary()):
|
||||||
return
|
return
|
||||||
if not '--help' in sys.argv or len(sys.argv) == 1:
|
if '--help' not in sys.argv or len(sys.argv) == 1:
|
||||||
return
|
return
|
||||||
|
|
||||||
print('info: the build system for Rust is written in Rust, so this')
|
print('info: the build system for Rust is written in Rust, so this')
|
||||||
@ -385,6 +394,7 @@ class RustBuild(object):
|
|||||||
if self.clean and os.path.exists(build_dir):
|
if self.clean and os.path.exists(build_dir):
|
||||||
shutil.rmtree(build_dir)
|
shutil.rmtree(build_dir)
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
|
env["RUSTC_BOOTSTRAP"] = '1'
|
||||||
env["CARGO_TARGET_DIR"] = build_dir
|
env["CARGO_TARGET_DIR"] = build_dir
|
||||||
env["RUSTC"] = self.rustc()
|
env["RUSTC"] = self.rustc()
|
||||||
env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
|
env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
|
||||||
@ -460,8 +470,8 @@ class RustBuild(object):
|
|||||||
# always emit 'i386' on x86/amd64 systems). As such, isainfo -k
|
# always emit 'i386' on x86/amd64 systems). As such, isainfo -k
|
||||||
# must be used instead.
|
# must be used instead.
|
||||||
try:
|
try:
|
||||||
cputype = subprocess.check_output(['isainfo',
|
cputype = subprocess.check_output(
|
||||||
'-k']).strip().decode(default_encoding)
|
['isainfo', '-k']).strip().decode(default_encoding)
|
||||||
except (subprocess.CalledProcessError, OSError):
|
except (subprocess.CalledProcessError, OSError):
|
||||||
err = "isainfo not found"
|
err = "isainfo not found"
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
@ -561,21 +571,26 @@ class RustBuild(object):
|
|||||||
default_encoding = sys.getdefaultencoding()
|
default_encoding = sys.getdefaultencoding()
|
||||||
run(["git", "submodule", "-q", "sync"], cwd=self.rust_root)
|
run(["git", "submodule", "-q", "sync"], cwd=self.rust_root)
|
||||||
submodules = [s.split(' ', 1)[1] for s in subprocess.check_output(
|
submodules = [s.split(' ', 1)[1] for s in subprocess.check_output(
|
||||||
["git", "config", "--file", os.path.join(self.rust_root, ".gitmodules"),
|
["git", "config", "--file",
|
||||||
|
os.path.join(self.rust_root, ".gitmodules"),
|
||||||
"--get-regexp", "path"]
|
"--get-regexp", "path"]
|
||||||
).decode(default_encoding).splitlines()]
|
).decode(default_encoding).splitlines()]
|
||||||
submodules = [module for module in submodules
|
submodules = [module for module in submodules
|
||||||
if not ((module.endswith("llvm") and
|
if not ((module.endswith("llvm") and
|
||||||
(self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT'))) or
|
(self.get_toml('llvm-config') or
|
||||||
|
self.get_mk('CFG_LLVM_ROOT'))) or
|
||||||
(module.endswith("jemalloc") and
|
(module.endswith("jemalloc") and
|
||||||
(self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT'))))
|
(self.get_toml('jemalloc') or
|
||||||
]
|
self.get_mk('CFG_JEMALLOC_ROOT'))))]
|
||||||
run(["git", "submodule", "update",
|
run(["git", "submodule", "update",
|
||||||
"--init"] + submodules, cwd=self.rust_root, verbose=self.verbose)
|
"--init", "--recursive"] + submodules,
|
||||||
|
cwd=self.rust_root, verbose=self.verbose)
|
||||||
run(["git", "submodule", "-q", "foreach", "git",
|
run(["git", "submodule", "-q", "foreach", "git",
|
||||||
"reset", "-q", "--hard"], cwd=self.rust_root, verbose=self.verbose)
|
"reset", "-q", "--hard"],
|
||||||
|
cwd=self.rust_root, verbose=self.verbose)
|
||||||
run(["git", "submodule", "-q", "foreach", "git",
|
run(["git", "submodule", "-q", "foreach", "git",
|
||||||
"clean", "-qdfx"], cwd=self.rust_root, verbose=self.verbose)
|
"clean", "-qdfx"],
|
||||||
|
cwd=self.rust_root, verbose=self.verbose)
|
||||||
|
|
||||||
|
|
||||||
def bootstrap():
|
def bootstrap():
|
||||||
@ -667,6 +682,7 @@ def bootstrap():
|
|||||||
env["BUILD"] = rb.build
|
env["BUILD"] = rb.build
|
||||||
env["SRC"] = rb.rust_root
|
env["SRC"] = rb.rust_root
|
||||||
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
|
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
|
||||||
|
env["BOOTSTRAP_PYTHON"] = sys.executable
|
||||||
run(args, env=env, verbose=rb.verbose)
|
run(args, env=env, verbose=rb.verbose)
|
||||||
|
|
||||||
|
|
||||||
@ -690,5 +706,6 @@ def main():
|
|||||||
format_build_time(time() - start_time))
|
format_build_time(time() - start_time))
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -42,10 +42,13 @@ use config::Target;
|
|||||||
pub fn find(build: &mut Build) {
|
pub fn find(build: &mut Build) {
|
||||||
// For all targets we're going to need a C compiler for building some shims
|
// For all targets we're going to need a C compiler for building some shims
|
||||||
// and such as well as for being a linker for Rust code.
|
// and such as well as for being a linker for Rust code.
|
||||||
for target in build.config.target.iter() {
|
//
|
||||||
|
// This includes targets that aren't necessarily passed on the commandline
|
||||||
|
// (FIXME: Perhaps it shouldn't?)
|
||||||
|
for target in &build.config.target {
|
||||||
let mut cfg = gcc::Config::new();
|
let mut cfg = gcc::Config::new();
|
||||||
cfg.cargo_metadata(false).opt_level(0).debug(false)
|
cfg.cargo_metadata(false).opt_level(0).debug(false)
|
||||||
.target(target).host(&build.config.build);
|
.target(target).host(&build.build);
|
||||||
|
|
||||||
let config = build.config.target_config.get(target);
|
let config = build.config.target_config.get(target);
|
||||||
if let Some(cc) = config.and_then(|c| c.cc.as_ref()) {
|
if let Some(cc) = config.and_then(|c| c.cc.as_ref()) {
|
||||||
@ -64,10 +67,13 @@ pub fn find(build: &mut Build) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For all host triples we need to find a C++ compiler as well
|
// For all host triples we need to find a C++ compiler as well
|
||||||
for host in build.config.host.iter() {
|
//
|
||||||
|
// This includes hosts that aren't necessarily passed on the commandline
|
||||||
|
// (FIXME: Perhaps it shouldn't?)
|
||||||
|
for host in &build.config.host {
|
||||||
let mut cfg = gcc::Config::new();
|
let mut cfg = gcc::Config::new();
|
||||||
cfg.cargo_metadata(false).opt_level(0).debug(false).cpp(true)
|
cfg.cargo_metadata(false).opt_level(0).debug(false).cpp(true)
|
||||||
.target(host).host(&build.config.build);
|
.target(host).host(&build.build);
|
||||||
let config = build.config.target_config.get(host);
|
let config = build.config.target_config.get(host);
|
||||||
if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
|
if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
|
||||||
cfg.compiler(cxx);
|
cfg.compiler(cxx);
|
||||||
|
@ -23,12 +23,12 @@ use build_helper::output;
|
|||||||
use Build;
|
use Build;
|
||||||
|
|
||||||
// The version number
|
// The version number
|
||||||
pub const CFG_RELEASE_NUM: &'static str = "1.19.0";
|
pub const CFG_RELEASE_NUM: &str = "1.20.0";
|
||||||
|
|
||||||
// An optional number to put after the label, e.g. '.2' -> '-beta.2'
|
// An optional number to put after the label, e.g. '.2' -> '-beta.2'
|
||||||
// Be sure to make this starts with a dot to conform to semver pre-release
|
// Be sure to make this starts with a dot to conform to semver pre-release
|
||||||
// versions (section 9)
|
// versions (section 9)
|
||||||
pub const CFG_PRERELEASE_VERSION: &'static str = ".4";
|
pub const CFG_PRERELEASE_VERSION: &str = ".3";
|
||||||
|
|
||||||
pub struct GitInfo {
|
pub struct GitInfo {
|
||||||
inner: Option<Info>,
|
inner: Option<Info>,
|
||||||
@ -99,6 +99,10 @@ impl GitInfo {
|
|||||||
version.push_str(&inner.commit_date);
|
version.push_str(&inner.commit_date);
|
||||||
version.push_str(")");
|
version.push_str(")");
|
||||||
}
|
}
|
||||||
return version
|
version
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_git(&self) -> bool {
|
||||||
|
self.inner.is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,22 +13,23 @@
|
|||||||
//! This file implements the various regression test suites that we execute on
|
//! This file implements the various regression test suites that we execute on
|
||||||
//! our CI.
|
//! our CI.
|
||||||
|
|
||||||
extern crate build_helper;
|
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::iter;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs;
|
use std::fs::{self, File};
|
||||||
use std::path::{PathBuf, Path};
|
use std::path::{PathBuf, Path};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
use build_helper::output;
|
use build_helper::{self, output};
|
||||||
|
|
||||||
use {Build, Compiler, Mode};
|
use {Build, Compiler, Mode};
|
||||||
use dist;
|
use dist;
|
||||||
use util::{self, dylib_path, dylib_path_var, exe};
|
use util::{self, dylib_path, dylib_path_var, exe};
|
||||||
|
|
||||||
const ADB_TEST_DIR: &'static str = "/data/tmp/work";
|
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
||||||
|
|
||||||
/// The two modes of the test runner; tests or benchmarks.
|
/// The two modes of the test runner; tests or benchmarks.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -59,7 +60,7 @@ impl fmt::Display for TestKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_run(build: &Build, cmd: &mut Command) {
|
fn try_run(build: &Build, cmd: &mut Command) {
|
||||||
if build.flags.cmd.no_fail_fast() {
|
if !build.fail_fast {
|
||||||
if !build.try_run(cmd) {
|
if !build.try_run(cmd) {
|
||||||
let failures = build.delayed_failures.get();
|
let failures = build.delayed_failures.get();
|
||||||
build.delayed_failures.set(failures + 1);
|
build.delayed_failures.set(failures + 1);
|
||||||
@ -70,7 +71,7 @@ fn try_run(build: &Build, cmd: &mut Command) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_run_quiet(build: &Build, cmd: &mut Command) {
|
fn try_run_quiet(build: &Build, cmd: &mut Command) {
|
||||||
if build.flags.cmd.no_fail_fast() {
|
if !build.fail_fast {
|
||||||
if !build.try_run_quiet(cmd) {
|
if !build.try_run_quiet(cmd) {
|
||||||
let failures = build.delayed_failures.get();
|
let failures = build.delayed_failures.get();
|
||||||
build.delayed_failures.set(failures + 1);
|
build.delayed_failures.set(failures + 1);
|
||||||
@ -98,7 +99,7 @@ pub fn linkcheck(build: &Build, host: &str) {
|
|||||||
/// This tool in `src/tools` will check out a few Rust projects and run `cargo
|
/// This tool in `src/tools` will check out a few Rust projects and run `cargo
|
||||||
/// test` to ensure that we don't regress the test suites there.
|
/// test` to ensure that we don't regress the test suites there.
|
||||||
pub fn cargotest(build: &Build, stage: u32, host: &str) {
|
pub fn cargotest(build: &Build, stage: u32, host: &str) {
|
||||||
let ref compiler = Compiler::new(stage, host);
|
let compiler = Compiler::new(stage, host);
|
||||||
|
|
||||||
// Note that this is a short, cryptic, and not scoped directory name. This
|
// Note that this is a short, cryptic, and not scoped directory name. This
|
||||||
// is currently to minimize the length of path on Windows where we otherwise
|
// is currently to minimize the length of path on Windows where we otherwise
|
||||||
@ -108,28 +109,20 @@ pub fn cargotest(build: &Build, stage: u32, host: &str) {
|
|||||||
|
|
||||||
let _time = util::timeit();
|
let _time = util::timeit();
|
||||||
let mut cmd = Command::new(build.tool(&Compiler::new(0, host), "cargotest"));
|
let mut cmd = Command::new(build.tool(&Compiler::new(0, host), "cargotest"));
|
||||||
build.prepare_tool_cmd(compiler, &mut cmd);
|
build.prepare_tool_cmd(&compiler, &mut cmd);
|
||||||
try_run(build, cmd.arg(&build.cargo)
|
try_run(build, cmd.arg(&build.initial_cargo)
|
||||||
.arg(&out_dir)
|
.arg(&out_dir)
|
||||||
.env("RUSTC", build.compiler_path(compiler))
|
.env("RUSTC", build.compiler_path(&compiler))
|
||||||
.env("RUSTDOC", build.rustdoc(compiler)));
|
.env("RUSTDOC", build.rustdoc(&compiler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs `cargo test` for `cargo` packaged with Rust.
|
/// Runs `cargo test` for `cargo` packaged with Rust.
|
||||||
pub fn cargo(build: &Build, stage: u32, host: &str) {
|
pub fn cargo(build: &Build, stage: u32, host: &str) {
|
||||||
let ref compiler = Compiler::new(stage, host);
|
let compiler = &Compiler::new(stage, host);
|
||||||
|
|
||||||
// Configure PATH to find the right rustc. NB. we have to use PATH
|
|
||||||
// and not RUSTC because the Cargo test suite has tests that will
|
|
||||||
// fail if rustc is not spelled `rustc`.
|
|
||||||
let path = build.sysroot(compiler).join("bin");
|
|
||||||
let old_path = ::std::env::var("PATH").expect("");
|
|
||||||
let sep = if cfg!(windows) { ";" } else {":" };
|
|
||||||
let ref newpath = format!("{}{}{}", path.display(), sep, old_path);
|
|
||||||
|
|
||||||
let mut cargo = build.cargo(compiler, Mode::Tool, host, "test");
|
let mut cargo = build.cargo(compiler, Mode::Tool, host, "test");
|
||||||
cargo.arg("--manifest-path").arg(build.src.join("src/tools/cargo/Cargo.toml"));
|
cargo.arg("--manifest-path").arg(build.src.join("src/tools/cargo/Cargo.toml"));
|
||||||
if build.flags.cmd.no_fail_fast() {
|
if !build.fail_fast {
|
||||||
cargo.arg("--no-fail-fast");
|
cargo.arg("--no-fail-fast");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +133,31 @@ pub fn cargo(build: &Build, stage: u32, host: &str) {
|
|||||||
// available.
|
// available.
|
||||||
cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
|
cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
|
||||||
|
|
||||||
try_run(build, cargo.env("PATH", newpath));
|
try_run(build, cargo.env("PATH", &path_for_cargo(build, compiler)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs `cargo test` for the rls.
|
||||||
|
pub fn rls(build: &Build, stage: u32, host: &str) {
|
||||||
|
let compiler = &Compiler::new(stage, host);
|
||||||
|
|
||||||
|
let mut cargo = build.cargo(compiler, Mode::Tool, host, "test");
|
||||||
|
cargo.arg("--manifest-path").arg(build.src.join("src/tools/rls/Cargo.toml"));
|
||||||
|
|
||||||
|
// Don't build tests dynamically, just a pain to work with
|
||||||
|
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
||||||
|
|
||||||
|
build.add_rustc_lib_path(compiler, &mut cargo);
|
||||||
|
|
||||||
|
try_run(build, &mut cargo);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_for_cargo(build: &Build, compiler: &Compiler) -> OsString {
|
||||||
|
// Configure PATH to find the right rustc. NB. we have to use PATH
|
||||||
|
// and not RUSTC because the Cargo test suite has tests that will
|
||||||
|
// fail if rustc is not spelled `rustc`.
|
||||||
|
let path = build.sysroot(compiler).join("bin");
|
||||||
|
let old_path = env::var_os("PATH").unwrap_or_default();
|
||||||
|
env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
|
/// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
|
||||||
@ -197,9 +214,9 @@ pub fn compiletest(build: &Build,
|
|||||||
cmd.arg("--mode").arg(mode);
|
cmd.arg("--mode").arg(mode);
|
||||||
cmd.arg("--target").arg(target);
|
cmd.arg("--target").arg(target);
|
||||||
cmd.arg("--host").arg(compiler.host);
|
cmd.arg("--host").arg(compiler.host);
|
||||||
cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build));
|
cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.build));
|
||||||
|
|
||||||
if let Some(nodejs) = build.config.nodejs.as_ref() {
|
if let Some(ref nodejs) = build.config.nodejs {
|
||||||
cmd.arg("--nodejs").arg(nodejs);
|
cmd.arg("--nodejs").arg(nodejs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +240,7 @@ pub fn compiletest(build: &Build,
|
|||||||
|
|
||||||
cmd.arg("--docck-python").arg(build.python());
|
cmd.arg("--docck-python").arg(build.python());
|
||||||
|
|
||||||
if build.config.build.ends_with("apple-darwin") {
|
if build.build.ends_with("apple-darwin") {
|
||||||
// Force /usr/bin/python on macOS for LLDB tests because we're loading the
|
// Force /usr/bin/python on macOS for LLDB tests because we're loading the
|
||||||
// LLDB plugin's compiled module which only works with the system python
|
// LLDB plugin's compiled module which only works with the system python
|
||||||
// (namely not Homebrew-installed python)
|
// (namely not Homebrew-installed python)
|
||||||
@ -244,10 +261,13 @@ pub fn compiletest(build: &Build,
|
|||||||
let llvm_config = build.llvm_config(target);
|
let llvm_config = build.llvm_config(target);
|
||||||
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
|
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
|
||||||
cmd.arg("--llvm-version").arg(llvm_version);
|
cmd.arg("--llvm-version").arg(llvm_version);
|
||||||
|
if !build.is_rust_llvm(target) {
|
||||||
|
cmd.arg("--system-llvm");
|
||||||
|
}
|
||||||
|
|
||||||
cmd.args(&build.flags.cmd.test_args());
|
cmd.args(&build.flags.cmd.test_args());
|
||||||
|
|
||||||
if build.config.verbose() || build.flags.verbose() {
|
if build.is_verbose() {
|
||||||
cmd.arg("--verbose");
|
cmd.arg("--verbose");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +281,7 @@ pub fn compiletest(build: &Build,
|
|||||||
let llvm_components = output(Command::new(&llvm_config).arg("--components"));
|
let llvm_components = output(Command::new(&llvm_config).arg("--components"));
|
||||||
let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
|
let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
|
||||||
cmd.arg("--cc").arg(build.cc(target))
|
cmd.arg("--cc").arg(build.cc(target))
|
||||||
.arg("--cxx").arg(build.cxx(target))
|
.arg("--cxx").arg(build.cxx(target).unwrap())
|
||||||
.arg("--cflags").arg(build.cflags(target).join(" "))
|
.arg("--cflags").arg(build.cflags(target).join(" "))
|
||||||
.arg("--llvm-components").arg(llvm_components.trim())
|
.arg("--llvm-components").arg(llvm_components.trim())
|
||||||
.arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
|
.arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
|
||||||
@ -275,7 +295,7 @@ pub fn compiletest(build: &Build,
|
|||||||
|
|
||||||
if build.remote_tested(target) {
|
if build.remote_tested(target) {
|
||||||
cmd.arg("--remote-test-client")
|
cmd.arg("--remote-test-client")
|
||||||
.arg(build.tool(&Compiler::new(0, &build.config.build),
|
.arg(build.tool(&Compiler::new(0, &build.build),
|
||||||
"remote-test-client"));
|
"remote-test-client"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +318,10 @@ pub fn compiletest(build: &Build,
|
|||||||
cmd.env("SANITIZER_SUPPORT", "1");
|
cmd.env("SANITIZER_SUPPORT", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if build.config.profiler {
|
||||||
|
cmd.env("PROFILER_SUPPORT", "1");
|
||||||
|
}
|
||||||
|
|
||||||
cmd.arg("--adb-path").arg("adb");
|
cmd.arg("--adb-path").arg("adb");
|
||||||
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
|
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
|
||||||
if target.contains("android") {
|
if target.contains("android") {
|
||||||
@ -333,20 +357,15 @@ pub fn docs(build: &Build, compiler: &Compiler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p.extension().and_then(|s| s.to_str()) != Some("md") {
|
if p.extension().and_then(|s| s.to_str()) != Some("md") {
|
||||||
continue
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The nostarch directory in the book is for no starch, and so isn't guaranteed to build.
|
// The nostarch directory in the book is for no starch, and so isn't
|
||||||
// we don't care if it doesn't build, so skip it.
|
// guaranteed to build. We don't care if it doesn't build, so skip it.
|
||||||
use std::ffi::OsStr;
|
if p.to_str().map_or(false, |p| p.contains("nostarch")) {
|
||||||
let path: &OsStr = p.as_ref();
|
continue;
|
||||||
if let Some(path) = path.to_str() {
|
|
||||||
if path.contains("nostarch") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("doc tests for: {}", p.display());
|
|
||||||
markdown_test(build, compiler, &p);
|
markdown_test(build, compiler, &p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,12 +389,20 @@ pub fn error_index(build: &Build, compiler: &Compiler) {
|
|||||||
"error_index_generator")
|
"error_index_generator")
|
||||||
.arg("markdown")
|
.arg("markdown")
|
||||||
.arg(&output)
|
.arg(&output)
|
||||||
.env("CFG_BUILD", &build.config.build));
|
.env("CFG_BUILD", &build.build));
|
||||||
|
|
||||||
markdown_test(build, compiler, &output);
|
markdown_test(build, compiler, &output);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
|
fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
|
||||||
|
let mut file = t!(File::open(markdown));
|
||||||
|
let mut contents = String::new();
|
||||||
|
t!(file.read_to_string(&mut contents));
|
||||||
|
if !contents.contains("```") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("doc tests for: {}", markdown.display());
|
||||||
let mut cmd = Command::new(build.rustdoc(compiler));
|
let mut cmd = Command::new(build.rustdoc(compiler));
|
||||||
build.add_rustc_lib_path(compiler, &mut cmd);
|
build.add_rustc_lib_path(compiler, &mut cmd);
|
||||||
build.add_rust_test_threads(&mut cmd);
|
build.add_rust_test_threads(&mut cmd);
|
||||||
@ -444,7 +471,7 @@ pub fn krate(build: &Build,
|
|||||||
cargo.arg("--manifest-path")
|
cargo.arg("--manifest-path")
|
||||||
.arg(build.src.join(path).join("Cargo.toml"))
|
.arg(build.src.join(path).join("Cargo.toml"))
|
||||||
.arg("--features").arg(features);
|
.arg("--features").arg(features);
|
||||||
if test_kind.subcommand() == "test" && build.flags.cmd.no_fail_fast() {
|
if test_kind.subcommand() == "test" && !build.fail_fast {
|
||||||
cargo.arg("--no-fail-fast");
|
cargo.arg("--no-fail-fast");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,16 +541,14 @@ fn krate_emscripten(build: &Build,
|
|||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
target: &str,
|
target: &str,
|
||||||
mode: Mode) {
|
mode: Mode) {
|
||||||
let mut tests = Vec::new();
|
|
||||||
let out_dir = build.cargo_out(compiler, mode, target);
|
let out_dir = build.cargo_out(compiler, mode, target);
|
||||||
find_tests(&out_dir.join("deps"), target, &mut tests);
|
let tests = find_tests(&out_dir.join("deps"), target);
|
||||||
|
|
||||||
|
let nodejs = build.config.nodejs.as_ref().expect("nodejs not configured");
|
||||||
for test in tests {
|
for test in tests {
|
||||||
let test_file_name = test.to_string_lossy().into_owned();
|
println!("running {}", test.display());
|
||||||
println!("running {}", test_file_name);
|
|
||||||
let nodejs = build.config.nodejs.as_ref().expect("nodejs not configured");
|
|
||||||
let mut cmd = Command::new(nodejs);
|
let mut cmd = Command::new(nodejs);
|
||||||
cmd.arg(&test_file_name);
|
cmd.arg(&test);
|
||||||
if build.config.quiet_tests {
|
if build.config.quiet_tests {
|
||||||
cmd.arg("--quiet");
|
cmd.arg("--quiet");
|
||||||
}
|
}
|
||||||
@ -535,11 +560,10 @@ fn krate_remote(build: &Build,
|
|||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
target: &str,
|
target: &str,
|
||||||
mode: Mode) {
|
mode: Mode) {
|
||||||
let mut tests = Vec::new();
|
|
||||||
let out_dir = build.cargo_out(compiler, mode, target);
|
let out_dir = build.cargo_out(compiler, mode, target);
|
||||||
find_tests(&out_dir.join("deps"), target, &mut tests);
|
let tests = find_tests(&out_dir.join("deps"), target);
|
||||||
|
|
||||||
let tool = build.tool(&Compiler::new(0, &build.config.build),
|
let tool = build.tool(&Compiler::new(0, &build.build),
|
||||||
"remote-test-client");
|
"remote-test-client");
|
||||||
for test in tests {
|
for test in tests {
|
||||||
let mut cmd = Command::new(&tool);
|
let mut cmd = Command::new(&tool);
|
||||||
@ -553,9 +577,8 @@ fn krate_remote(build: &Build,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_tests(dir: &Path,
|
fn find_tests(dir: &Path, target: &str) -> Vec<PathBuf> {
|
||||||
target: &str,
|
let mut dst = Vec::new();
|
||||||
dst: &mut Vec<PathBuf>) {
|
|
||||||
for e in t!(dir.read_dir()).map(|e| t!(e)) {
|
for e in t!(dir.read_dir()).map(|e| t!(e)) {
|
||||||
let file_type = t!(e.file_type());
|
let file_type = t!(e.file_type());
|
||||||
if !file_type.is_file() {
|
if !file_type.is_file() {
|
||||||
@ -564,10 +587,13 @@ fn find_tests(dir: &Path,
|
|||||||
let filename = e.file_name().into_string().unwrap();
|
let filename = e.file_name().into_string().unwrap();
|
||||||
if (target.contains("windows") && filename.ends_with(".exe")) ||
|
if (target.contains("windows") && filename.ends_with(".exe")) ||
|
||||||
(!target.contains("windows") && !filename.contains(".")) ||
|
(!target.contains("windows") && !filename.contains(".")) ||
|
||||||
(target.contains("emscripten") && filename.ends_with(".js")) {
|
(target.contains("emscripten") &&
|
||||||
|
filename.ends_with(".js") &&
|
||||||
|
!filename.ends_with(".asm.js")) {
|
||||||
dst.push(e.path());
|
dst.push(e.path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
|
pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
|
||||||
@ -582,7 +608,7 @@ pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
|
|||||||
.join(exe("remote-test-server", target));
|
.join(exe("remote-test-server", target));
|
||||||
|
|
||||||
// Spawn the emulator and wait for it to come online
|
// Spawn the emulator and wait for it to come online
|
||||||
let tool = build.tool(&Compiler::new(0, &build.config.build),
|
let tool = build.tool(&Compiler::new(0, &build.build),
|
||||||
"remote-test-client");
|
"remote-test-client");
|
||||||
let mut cmd = Command::new(&tool);
|
let mut cmd = Command::new(&tool);
|
||||||
cmd.arg("spawn-emulator")
|
cmd.arg("spawn-emulator")
|
||||||
@ -608,7 +634,7 @@ pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
|
|||||||
|
|
||||||
/// Run "distcheck", a 'make check' from a tarball
|
/// Run "distcheck", a 'make check' from a tarball
|
||||||
pub fn distcheck(build: &Build) {
|
pub fn distcheck(build: &Build) {
|
||||||
if build.config.build != "x86_64-unknown-linux-gnu" {
|
if build.build != "x86_64-unknown-linux-gnu" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !build.config.host.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
if !build.config.host.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
||||||
@ -633,7 +659,7 @@ pub fn distcheck(build: &Build) {
|
|||||||
.args(&build.config.configure_args)
|
.args(&build.config.configure_args)
|
||||||
.arg("--enable-vendor")
|
.arg("--enable-vendor")
|
||||||
.current_dir(&dir));
|
.current_dir(&dir));
|
||||||
build.run(Command::new(build_helper::make(&build.config.build))
|
build.run(Command::new(build_helper::make(&build.build))
|
||||||
.arg("check")
|
.arg("check")
|
||||||
.current_dir(&dir));
|
.current_dir(&dir));
|
||||||
|
|
||||||
@ -651,7 +677,7 @@ pub fn distcheck(build: &Build) {
|
|||||||
build.run(&mut cmd);
|
build.run(&mut cmd);
|
||||||
|
|
||||||
let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
|
let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
|
||||||
build.run(Command::new(&build.cargo)
|
build.run(Command::new(&build.initial_cargo)
|
||||||
.arg("generate-lockfile")
|
.arg("generate-lockfile")
|
||||||
.arg("--manifest-path")
|
.arg("--manifest-path")
|
||||||
.arg(&toml)
|
.arg(&toml)
|
||||||
@ -660,12 +686,13 @@ pub fn distcheck(build: &Build) {
|
|||||||
|
|
||||||
/// Test the build system itself
|
/// Test the build system itself
|
||||||
pub fn bootstrap(build: &Build) {
|
pub fn bootstrap(build: &Build) {
|
||||||
let mut cmd = Command::new(&build.cargo);
|
let mut cmd = Command::new(&build.initial_cargo);
|
||||||
cmd.arg("test")
|
cmd.arg("test")
|
||||||
.current_dir(build.src.join("src/bootstrap"))
|
.current_dir(build.src.join("src/bootstrap"))
|
||||||
.env("CARGO_TARGET_DIR", build.out.join("bootstrap"))
|
.env("CARGO_TARGET_DIR", build.out.join("bootstrap"))
|
||||||
.env("RUSTC", &build.rustc);
|
.env("RUSTC_BOOTSTRAP", "1")
|
||||||
if build.flags.cmd.no_fail_fast() {
|
.env("RUSTC", &build.initial_rustc);
|
||||||
|
if !build.fail_fast {
|
||||||
cmd.arg("--no-fail-fast");
|
cmd.arg("--no-fail-fast");
|
||||||
}
|
}
|
||||||
cmd.arg("--").args(&build.flags.cmd.test_args());
|
cmd.arg("--").args(&build.flags.cmd.test_args());
|
||||||
|
@ -50,7 +50,7 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) {
|
|||||||
let mut cargo = build.cargo(compiler, Mode::Libstd, target, "build");
|
let mut cargo = build.cargo(compiler, Mode::Libstd, target, "build");
|
||||||
let mut features = build.std_features();
|
let mut features = build.std_features();
|
||||||
|
|
||||||
if let Ok(target) = env::var("MACOSX_STD_DEPLOYMENT_TARGET") {
|
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
|
||||||
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
|
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ pub fn build_startup_objects(build: &Build, for_compiler: &Compiler, target: &st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let compiler = Compiler::new(0, &build.config.build);
|
let compiler = Compiler::new(0, &build.build);
|
||||||
let compiler_path = build.compiler_path(&compiler);
|
let compiler_path = build.compiler_path(&compiler);
|
||||||
let src_dir = &build.src.join("src/rtstartup");
|
let src_dir = &build.src.join("src/rtstartup");
|
||||||
let dst_dir = &build.native_dir(target).join("rtstartup");
|
let dst_dir = &build.native_dir(target).join("rtstartup");
|
||||||
@ -199,7 +199,7 @@ pub fn test(build: &Build, target: &str, compiler: &Compiler) {
|
|||||||
let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
|
let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
|
||||||
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
|
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
|
||||||
let mut cargo = build.cargo(compiler, Mode::Libtest, target, "build");
|
let mut cargo = build.cargo(compiler, Mode::Libtest, target, "build");
|
||||||
if let Ok(target) = env::var("MACOSX_STD_DEPLOYMENT_TARGET") {
|
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
|
||||||
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
|
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
|
||||||
}
|
}
|
||||||
cargo.arg("--manifest-path")
|
cargo.arg("--manifest-path")
|
||||||
@ -247,7 +247,7 @@ pub fn rustc(build: &Build, target: &str, compiler: &Compiler) {
|
|||||||
cargo.env("CFG_RELEASE", build.rust_release())
|
cargo.env("CFG_RELEASE", build.rust_release())
|
||||||
.env("CFG_RELEASE_CHANNEL", &build.config.channel)
|
.env("CFG_RELEASE_CHANNEL", &build.config.channel)
|
||||||
.env("CFG_VERSION", build.rust_version())
|
.env("CFG_VERSION", build.rust_version())
|
||||||
.env("CFG_PREFIX", build.config.prefix.clone().unwrap_or(PathBuf::new()));
|
.env("CFG_PREFIX", build.config.prefix.clone().unwrap_or_default());
|
||||||
|
|
||||||
if compiler.stage == 0 {
|
if compiler.stage == 0 {
|
||||||
cargo.env("CFG_LIBDIR_RELATIVE", "lib");
|
cargo.env("CFG_LIBDIR_RELATIVE", "lib");
|
||||||
@ -287,7 +287,7 @@ pub fn rustc(build: &Build, target: &str, compiler: &Compiler) {
|
|||||||
!target.contains("windows") &&
|
!target.contains("windows") &&
|
||||||
!target.contains("apple") {
|
!target.contains("apple") {
|
||||||
cargo.env("LLVM_STATIC_STDCPP",
|
cargo.env("LLVM_STATIC_STDCPP",
|
||||||
compiler_file(build.cxx(target), "libstdc++.a"));
|
compiler_file(build.cxx(target).unwrap(), "libstdc++.a"));
|
||||||
}
|
}
|
||||||
if build.config.llvm_link_shared {
|
if build.config.llvm_link_shared {
|
||||||
cargo.env("LLVM_LINK_SHARED", "1");
|
cargo.env("LLVM_LINK_SHARED", "1");
|
||||||
@ -351,7 +351,7 @@ pub fn create_sysroot(build: &Build, compiler: &Compiler) {
|
|||||||
/// Prepare a new compiler from the artifacts in `stage`
|
/// Prepare a new compiler from the artifacts in `stage`
|
||||||
///
|
///
|
||||||
/// This will assemble a compiler in `build/$host/stage$stage`. The compiler
|
/// This will assemble a compiler in `build/$host/stage$stage`. The compiler
|
||||||
/// must have been previously produced by the `stage - 1` build.config.build
|
/// must have been previously produced by the `stage - 1` build.build
|
||||||
/// compiler.
|
/// compiler.
|
||||||
pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
|
pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
|
||||||
// nothing to do in stage0
|
// nothing to do in stage0
|
||||||
@ -365,7 +365,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
|
|||||||
let target_compiler = Compiler::new(stage, host);
|
let target_compiler = Compiler::new(stage, host);
|
||||||
|
|
||||||
// The compiler that compiled the compiler we're assembling
|
// The compiler that compiled the compiler we're assembling
|
||||||
let build_compiler = Compiler::new(stage - 1, &build.config.build);
|
let build_compiler = Compiler::new(stage - 1, &build.build);
|
||||||
|
|
||||||
// Link in all dylibs to the libdir
|
// Link in all dylibs to the libdir
|
||||||
let sysroot = build.sysroot(&target_compiler);
|
let sysroot = build.sysroot(&target_compiler);
|
||||||
@ -385,7 +385,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
|
|||||||
let rustc = out_dir.join(exe("rustc", host));
|
let rustc = out_dir.join(exe("rustc", host));
|
||||||
let bindir = sysroot.join("bin");
|
let bindir = sysroot.join("bin");
|
||||||
t!(fs::create_dir_all(&bindir));
|
t!(fs::create_dir_all(&bindir));
|
||||||
let compiler = build.compiler_path(&Compiler::new(stage, host));
|
let compiler = build.compiler_path(&target_compiler);
|
||||||
let _ = fs::remove_file(&compiler);
|
let _ = fs::remove_file(&compiler);
|
||||||
copy(&rustc, &compiler);
|
copy(&rustc, &compiler);
|
||||||
|
|
||||||
@ -407,6 +407,8 @@ fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
|
|||||||
t!(fs::create_dir_all(&sysroot_dst));
|
t!(fs::create_dir_all(&sysroot_dst));
|
||||||
let mut contents = Vec::new();
|
let mut contents = Vec::new();
|
||||||
t!(t!(File::open(stamp)).read_to_end(&mut contents));
|
t!(t!(File::open(stamp)).read_to_end(&mut contents));
|
||||||
|
// This is the method we use for extracting paths from the stamp file passed to us. See
|
||||||
|
// run_cargo for more information (in this file).
|
||||||
for part in contents.split(|b| *b == 0) {
|
for part in contents.split(|b| *b == 0) {
|
||||||
if part.is_empty() {
|
if part.is_empty() {
|
||||||
continue
|
continue
|
||||||
@ -421,7 +423,7 @@ fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
|
|||||||
/// This will build the specified tool with the specified `host` compiler in
|
/// This will build the specified tool with the specified `host` compiler in
|
||||||
/// `stage` into the normal cargo output directory.
|
/// `stage` into the normal cargo output directory.
|
||||||
pub fn maybe_clean_tools(build: &Build, stage: u32, target: &str, mode: Mode) {
|
pub fn maybe_clean_tools(build: &Build, stage: u32, target: &str, mode: Mode) {
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
|
|
||||||
let stamp = match mode {
|
let stamp = match mode {
|
||||||
Mode::Libstd => libstd_stamp(build, &compiler, target),
|
Mode::Libstd => libstd_stamp(build, &compiler, target),
|
||||||
@ -441,7 +443,7 @@ pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) {
|
|||||||
let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
|
let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
|
||||||
println!("Building stage{} tool {} ({})", stage, tool, target);
|
println!("Building stage{} tool {} ({})", stage, tool, target);
|
||||||
|
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
|
|
||||||
let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build");
|
let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build");
|
||||||
let dir = build.src.join("src/tools").join(tool);
|
let dir = build.src.join("src/tools").join(tool);
|
||||||
@ -473,11 +475,43 @@ pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) {
|
|||||||
build.run(&mut cargo);
|
build.run(&mut cargo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Avoiding a dependency on winapi to keep compile times down
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn stderr_isatty() -> bool {
|
||||||
|
use libc;
|
||||||
|
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn stderr_isatty() -> bool {
|
||||||
|
type DWORD = u32;
|
||||||
|
type BOOL = i32;
|
||||||
|
type HANDLE = *mut u8;
|
||||||
|
const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
|
||||||
|
extern "system" {
|
||||||
|
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||||
|
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
let mut out = 0;
|
||||||
|
GetConsoleMode(handle, &mut out) != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
|
fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
|
||||||
// Instruct Cargo to give us json messages on stdout, critically leaving
|
// Instruct Cargo to give us json messages on stdout, critically leaving
|
||||||
// stderr as piped so we can get those pretty colors.
|
// stderr as piped so we can get those pretty colors.
|
||||||
cargo.arg("--message-format").arg("json")
|
cargo.arg("--message-format").arg("json")
|
||||||
.stdout(Stdio::piped());
|
.stdout(Stdio::piped());
|
||||||
|
|
||||||
|
if stderr_isatty() {
|
||||||
|
// since we pass message-format=json to cargo, we need to tell the rustc
|
||||||
|
// wrapper to give us colored output if necessary. This is because we
|
||||||
|
// only want Cargo's JSON output, not rustcs.
|
||||||
|
cargo.env("RUSTC_COLOR", "1");
|
||||||
|
}
|
||||||
|
|
||||||
build.verbose(&format!("running: {:?}", cargo));
|
build.verbose(&format!("running: {:?}", cargo));
|
||||||
let mut child = match cargo.spawn() {
|
let mut child = match cargo.spawn() {
|
||||||
Ok(child) => child,
|
Ok(child) => child,
|
||||||
@ -525,23 +559,24 @@ fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
|
|||||||
// If this was an output file in the "host dir" we don't actually
|
// If this was an output file in the "host dir" we don't actually
|
||||||
// worry about it, it's not relevant for us.
|
// worry about it, it's not relevant for us.
|
||||||
if filename.starts_with(&host_root_dir) {
|
if filename.starts_with(&host_root_dir) {
|
||||||
continue
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If this was output in the `deps` dir then this is a precise file
|
// If this was output in the `deps` dir then this is a precise file
|
||||||
// name (hash included) so we start tracking it.
|
// name (hash included) so we start tracking it.
|
||||||
} else if filename.starts_with(&target_deps_dir) {
|
if filename.starts_with(&target_deps_dir) {
|
||||||
deps.push(filename.to_path_buf());
|
deps.push(filename.to_path_buf());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise this was a "top level artifact" which right now doesn't
|
// Otherwise this was a "top level artifact" which right now doesn't
|
||||||
// have a hash in the name, but there's a version of this file in
|
// have a hash in the name, but there's a version of this file in
|
||||||
// the `deps` folder which *does* have a hash in the name. That's
|
// the `deps` folder which *does* have a hash in the name. That's
|
||||||
// the one we'll want to we'll probe for it later.
|
// the one we'll want to we'll probe for it later.
|
||||||
} else {
|
toplevel.push((filename.file_stem().unwrap()
|
||||||
toplevel.push((filename.file_stem().unwrap()
|
.to_str().unwrap().to_string(),
|
||||||
.to_str().unwrap().to_string(),
|
filename.extension().unwrap().to_owned()
|
||||||
filename.extension().unwrap().to_owned()
|
.to_str().unwrap().to_string()));
|
||||||
.to_str().unwrap().to_string()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ pub struct Config {
|
|||||||
pub full_bootstrap: bool,
|
pub full_bootstrap: bool,
|
||||||
pub extended: bool,
|
pub extended: bool,
|
||||||
pub sanitizers: bool,
|
pub sanitizers: bool,
|
||||||
|
pub profiler: bool,
|
||||||
|
|
||||||
// llvm codegen options
|
// llvm codegen options
|
||||||
pub llvm_assertions: bool,
|
pub llvm_assertions: bool,
|
||||||
@ -59,6 +60,7 @@ pub struct Config {
|
|||||||
pub llvm_static_stdcpp: bool,
|
pub llvm_static_stdcpp: bool,
|
||||||
pub llvm_link_shared: bool,
|
pub llvm_link_shared: bool,
|
||||||
pub llvm_targets: Option<String>,
|
pub llvm_targets: Option<String>,
|
||||||
|
pub llvm_experimental_targets: Option<String>,
|
||||||
pub llvm_link_jobs: Option<u32>,
|
pub llvm_link_jobs: Option<u32>,
|
||||||
pub llvm_clean_rebuild: bool,
|
pub llvm_clean_rebuild: bool,
|
||||||
|
|
||||||
@ -79,8 +81,6 @@ pub struct Config {
|
|||||||
pub build: String,
|
pub build: String,
|
||||||
pub host: Vec<String>,
|
pub host: Vec<String>,
|
||||||
pub target: Vec<String>,
|
pub target: Vec<String>,
|
||||||
pub rustc: Option<PathBuf>,
|
|
||||||
pub cargo: Option<PathBuf>,
|
|
||||||
pub local_rebuild: bool,
|
pub local_rebuild: bool,
|
||||||
|
|
||||||
// dist misc
|
// dist misc
|
||||||
@ -112,11 +112,18 @@ pub struct Config {
|
|||||||
pub python: Option<PathBuf>,
|
pub python: Option<PathBuf>,
|
||||||
pub configure_args: Vec<String>,
|
pub configure_args: Vec<String>,
|
||||||
pub openssl_static: bool,
|
pub openssl_static: bool,
|
||||||
|
|
||||||
|
|
||||||
|
// These are either the stage0 downloaded binaries or the locally installed ones.
|
||||||
|
pub initial_cargo: PathBuf,
|
||||||
|
pub initial_rustc: PathBuf,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Per-target configuration stored in the global configuration structure.
|
/// Per-target configuration stored in the global configuration structure.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Target {
|
pub struct Target {
|
||||||
|
/// Some(path to llvm-config) if using an external LLVM.
|
||||||
pub llvm_config: Option<PathBuf>,
|
pub llvm_config: Option<PathBuf>,
|
||||||
pub jemalloc: Option<PathBuf>,
|
pub jemalloc: Option<PathBuf>,
|
||||||
pub cc: Option<PathBuf>,
|
pub cc: Option<PathBuf>,
|
||||||
@ -162,6 +169,7 @@ struct Build {
|
|||||||
extended: Option<bool>,
|
extended: Option<bool>,
|
||||||
verbose: Option<usize>,
|
verbose: Option<usize>,
|
||||||
sanitizers: Option<bool>,
|
sanitizers: Option<bool>,
|
||||||
|
profiler: Option<bool>,
|
||||||
openssl_static: Option<bool>,
|
openssl_static: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +195,7 @@ struct Llvm {
|
|||||||
version_check: Option<bool>,
|
version_check: Option<bool>,
|
||||||
static_libstdcpp: Option<bool>,
|
static_libstdcpp: Option<bool>,
|
||||||
targets: Option<String>,
|
targets: Option<String>,
|
||||||
|
experimental_targets: Option<String>,
|
||||||
link_jobs: Option<u32>,
|
link_jobs: Option<u32>,
|
||||||
clean_rebuild: Option<bool>,
|
clean_rebuild: Option<bool>,
|
||||||
}
|
}
|
||||||
@ -303,8 +312,6 @@ impl Config {
|
|||||||
config.target.push(target.clone());
|
config.target.push(target.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.rustc = build.rustc.map(PathBuf::from);
|
|
||||||
config.cargo = build.cargo.map(PathBuf::from);
|
|
||||||
config.nodejs = build.nodejs.map(PathBuf::from);
|
config.nodejs = build.nodejs.map(PathBuf::from);
|
||||||
config.gdb = build.gdb.map(PathBuf::from);
|
config.gdb = build.gdb.map(PathBuf::from);
|
||||||
config.python = build.python.map(PathBuf::from);
|
config.python = build.python.map(PathBuf::from);
|
||||||
@ -318,6 +325,7 @@ impl Config {
|
|||||||
set(&mut config.extended, build.extended);
|
set(&mut config.extended, build.extended);
|
||||||
set(&mut config.verbose, build.verbose);
|
set(&mut config.verbose, build.verbose);
|
||||||
set(&mut config.sanitizers, build.sanitizers);
|
set(&mut config.sanitizers, build.sanitizers);
|
||||||
|
set(&mut config.profiler, build.profiler);
|
||||||
set(&mut config.openssl_static, build.openssl_static);
|
set(&mut config.openssl_static, build.openssl_static);
|
||||||
|
|
||||||
if let Some(ref install) = toml.install {
|
if let Some(ref install) = toml.install {
|
||||||
@ -347,6 +355,7 @@ impl Config {
|
|||||||
set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
|
set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
|
||||||
set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild);
|
set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild);
|
||||||
config.llvm_targets = llvm.targets.clone();
|
config.llvm_targets = llvm.targets.clone();
|
||||||
|
config.llvm_experimental_targets = llvm.experimental_targets.clone();
|
||||||
config.llvm_link_jobs = llvm.link_jobs;
|
config.llvm_link_jobs = llvm.link_jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,13 +413,25 @@ impl Config {
|
|||||||
set(&mut config.rust_dist_src, t.src_tarball);
|
set(&mut config.rust_dist_src, t.src_tarball);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cwd = t!(env::current_dir());
|
||||||
|
let out = cwd.join("build");
|
||||||
|
|
||||||
|
let stage0_root = out.join(&config.build).join("stage0/bin");
|
||||||
|
config.initial_rustc = match build.rustc {
|
||||||
|
Some(s) => PathBuf::from(s),
|
||||||
|
None => stage0_root.join(exe("rustc", &config.build)),
|
||||||
|
};
|
||||||
|
config.initial_cargo = match build.cargo {
|
||||||
|
Some(s) => PathBuf::from(s),
|
||||||
|
None => stage0_root.join(exe("cargo", &config.build)),
|
||||||
|
};
|
||||||
|
|
||||||
// compat with `./configure` while we're still using that
|
// compat with `./configure` while we're still using that
|
||||||
if fs::metadata("config.mk").is_ok() {
|
if fs::metadata("config.mk").is_ok() {
|
||||||
config.update_with_config_mk();
|
config.update_with_config_mk();
|
||||||
}
|
}
|
||||||
|
|
||||||
return config
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "Temporary" routine to parse `config.mk` into this configuration.
|
/// "Temporary" routine to parse `config.mk` into this configuration.
|
||||||
@ -477,6 +498,7 @@ impl Config {
|
|||||||
("FULL_BOOTSTRAP", self.full_bootstrap),
|
("FULL_BOOTSTRAP", self.full_bootstrap),
|
||||||
("EXTENDED", self.extended),
|
("EXTENDED", self.extended),
|
||||||
("SANITIZERS", self.sanitizers),
|
("SANITIZERS", self.sanitizers),
|
||||||
|
("PROFILER", self.profiler),
|
||||||
("DIST_SRC", self.rust_dist_src),
|
("DIST_SRC", self.rust_dist_src),
|
||||||
("CARGO_OPENSSL_STATIC", self.openssl_static),
|
("CARGO_OPENSSL_STATIC", self.openssl_static),
|
||||||
}
|
}
|
||||||
@ -490,6 +512,9 @@ impl Config {
|
|||||||
"CFG_TARGET" if value.len() > 0 => {
|
"CFG_TARGET" if value.len() > 0 => {
|
||||||
self.target.extend(value.split(" ").map(|s| s.to_string()));
|
self.target.extend(value.split(" ").map(|s| s.to_string()));
|
||||||
}
|
}
|
||||||
|
"CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => {
|
||||||
|
self.llvm_experimental_targets = Some(value.to_string());
|
||||||
|
}
|
||||||
"CFG_MUSL_ROOT" if value.len() > 0 => {
|
"CFG_MUSL_ROOT" if value.len() > 0 => {
|
||||||
self.musl_root = Some(parse_configure_path(value));
|
self.musl_root = Some(parse_configure_path(value));
|
||||||
}
|
}
|
||||||
@ -599,8 +624,8 @@ impl Config {
|
|||||||
}
|
}
|
||||||
"CFG_LOCAL_RUST_ROOT" if value.len() > 0 => {
|
"CFG_LOCAL_RUST_ROOT" if value.len() > 0 => {
|
||||||
let path = parse_configure_path(value);
|
let path = parse_configure_path(value);
|
||||||
self.rustc = Some(push_exe_path(path.clone(), &["bin", "rustc"]));
|
self.initial_rustc = push_exe_path(path.clone(), &["bin", "rustc"]);
|
||||||
self.cargo = Some(push_exe_path(path, &["bin", "cargo"]));
|
self.initial_cargo = push_exe_path(path, &["bin", "cargo"]);
|
||||||
}
|
}
|
||||||
"CFG_PYTHON" if value.len() > 0 => {
|
"CFG_PYTHON" if value.len() > 0 => {
|
||||||
let path = parse_configure_path(value);
|
let path = parse_configure_path(value);
|
||||||
|
@ -53,6 +53,14 @@
|
|||||||
# Rust team and file an issue if you need assistance in porting!
|
# Rust team and file an issue if you need assistance in porting!
|
||||||
#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon"
|
#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon"
|
||||||
|
|
||||||
|
# LLVM experimental targets to build support for. These targets are specified in
|
||||||
|
# the same format as above, but since these targets are experimental, they are
|
||||||
|
# not built by default and the experimental Rust compilation targets that depend
|
||||||
|
# on them will not work unless the user opts in to building them. Possible
|
||||||
|
# experimental LLVM targets include WebAssembly for the
|
||||||
|
# wasm32-experimental-emscripten Rust target.
|
||||||
|
#experimental-targets = ""
|
||||||
|
|
||||||
# Cap the number of parallel linker invocations when compiling LLVM.
|
# Cap the number of parallel linker invocations when compiling LLVM.
|
||||||
# This can be useful when building LLVM with debug info, which significantly
|
# This can be useful when building LLVM with debug info, which significantly
|
||||||
# increases the size of binaries and consequently the memory required by
|
# increases the size of binaries and consequently the memory required by
|
||||||
@ -147,6 +155,9 @@
|
|||||||
# Build the sanitizer runtimes
|
# Build the sanitizer runtimes
|
||||||
#sanitizers = false
|
#sanitizers = false
|
||||||
|
|
||||||
|
# Build the profiler runtime
|
||||||
|
#profiler = false
|
||||||
|
|
||||||
# Indicates whether the OpenSSL linked into Cargo will be statically linked or
|
# Indicates whether the OpenSSL linked into Cargo will be statically linked or
|
||||||
# not. If static linkage is specified then the build system will download a
|
# not. If static linkage is specified then the build system will download a
|
||||||
# known-good version of OpenSSL, compile it, and link it to Cargo.
|
# known-good version of OpenSSL, compile it, and link it to Cargo.
|
||||||
|
@ -50,7 +50,7 @@ pub fn tmpdir(build: &Build) -> PathBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rust_installer(build: &Build) -> Command {
|
fn rust_installer(build: &Build) -> Command {
|
||||||
build.tool_cmd(&Compiler::new(0, &build.config.build), "rust-installer")
|
build.tool_cmd(&Compiler::new(0, &build.build), "rust-installer")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the `rust-docs` installer component.
|
/// Builds the `rust-docs` installer component.
|
||||||
@ -89,7 +89,7 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
|
|||||||
|
|
||||||
// As part of this step, *also* copy the docs directory to a directory which
|
// As part of this step, *also* copy the docs directory to a directory which
|
||||||
// buildbot typically uploads.
|
// buildbot typically uploads.
|
||||||
if host == build.config.build {
|
if host == build.build {
|
||||||
let dst = distdir(build).join("doc").join(build.rust_package_vers());
|
let dst = distdir(build).join("doc").join(build.rust_package_vers());
|
||||||
t!(fs::create_dir_all(&dst));
|
t!(fs::create_dir_all(&dst));
|
||||||
cp_r(&src, &dst);
|
cp_r(&src, &dst);
|
||||||
@ -97,7 +97,7 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
|
fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
|
||||||
let mut found = Vec::new();
|
let mut found = Vec::with_capacity(files.len());
|
||||||
|
|
||||||
for file in files {
|
for file in files {
|
||||||
let file_path =
|
let file_path =
|
||||||
@ -119,17 +119,9 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
|||||||
//Ask gcc where it keeps its stuff
|
//Ask gcc where it keeps its stuff
|
||||||
let mut cmd = Command::new(build.cc(target_triple));
|
let mut cmd = Command::new(build.cc(target_triple));
|
||||||
cmd.arg("-print-search-dirs");
|
cmd.arg("-print-search-dirs");
|
||||||
build.run_quiet(&mut cmd);
|
let gcc_out = output(&mut cmd);
|
||||||
let gcc_out =
|
|
||||||
String::from_utf8(
|
|
||||||
cmd
|
|
||||||
.output()
|
|
||||||
.expect("failed to execute gcc")
|
|
||||||
.stdout).expect("gcc.exe output was not utf8");
|
|
||||||
|
|
||||||
let mut bin_path: Vec<_> =
|
let mut bin_path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect();
|
||||||
env::split_paths(&env::var_os("PATH").unwrap_or_default())
|
|
||||||
.collect();
|
|
||||||
let mut lib_path = Vec::new();
|
let mut lib_path = Vec::new();
|
||||||
|
|
||||||
for line in gcc_out.lines() {
|
for line in gcc_out.lines() {
|
||||||
@ -140,7 +132,7 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
|||||||
line[(idx + 1)..]
|
line[(idx + 1)..]
|
||||||
.trim_left_matches(trim_chars)
|
.trim_left_matches(trim_chars)
|
||||||
.split(';')
|
.split(';')
|
||||||
.map(|s| PathBuf::from(s));
|
.map(PathBuf::from);
|
||||||
|
|
||||||
if key == "programs" {
|
if key == "programs" {
|
||||||
bin_path.extend(value);
|
bin_path.extend(value);
|
||||||
@ -149,7 +141,7 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_tools = vec!["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe", "libwinpthread-1.dll"];
|
let target_tools = ["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe", "libwinpthread-1.dll"];
|
||||||
let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
|
let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
|
||||||
if target_triple.starts_with("i686-") {
|
if target_triple.starts_with("i686-") {
|
||||||
rustc_dlls.push("libgcc_s_dw2-1.dll");
|
rustc_dlls.push("libgcc_s_dw2-1.dll");
|
||||||
@ -157,7 +149,7 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
|||||||
rustc_dlls.push("libgcc_s_seh-1.dll");
|
rustc_dlls.push("libgcc_s_seh-1.dll");
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_libs = vec![ //MinGW libs
|
let target_libs = [ //MinGW libs
|
||||||
"libgcc.a",
|
"libgcc.a",
|
||||||
"libgcc_eh.a",
|
"libgcc_eh.a",
|
||||||
"libgcc_s.a",
|
"libgcc_s.a",
|
||||||
@ -203,7 +195,7 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
|||||||
let target_libs = find_files(&target_libs, &lib_path);
|
let target_libs = find_files(&target_libs, &lib_path);
|
||||||
|
|
||||||
fn copy_to_folder(src: &Path, dest_folder: &Path) {
|
fn copy_to_folder(src: &Path, dest_folder: &Path) {
|
||||||
let file_name = src.file_name().unwrap().to_os_string();
|
let file_name = src.file_name().unwrap();
|
||||||
let dest = dest_folder.join(file_name);
|
let dest = dest_folder.join(file_name);
|
||||||
copy(src, &dest);
|
copy(src, &dest);
|
||||||
}
|
}
|
||||||
@ -234,8 +226,6 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
|||||||
///
|
///
|
||||||
/// This contains all the bits and pieces to run the MinGW Windows targets
|
/// This contains all the bits and pieces to run the MinGW Windows targets
|
||||||
/// without any extra installed software (e.g. we bundle gcc, libraries, etc).
|
/// without any extra installed software (e.g. we bundle gcc, libraries, etc).
|
||||||
/// Currently just shells out to a python script, but that should be rewritten
|
|
||||||
/// in Rust.
|
|
||||||
pub fn mingw(build: &Build, host: &str) {
|
pub fn mingw(build: &Build, host: &str) {
|
||||||
println!("Dist mingw ({})", host);
|
println!("Dist mingw ({})", host);
|
||||||
let name = pkgname(build, "rust-mingw");
|
let name = pkgname(build, "rust-mingw");
|
||||||
@ -366,9 +356,9 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
|
|||||||
pub fn debugger_scripts(build: &Build,
|
pub fn debugger_scripts(build: &Build,
|
||||||
sysroot: &Path,
|
sysroot: &Path,
|
||||||
host: &str) {
|
host: &str) {
|
||||||
|
let dst = sysroot.join("lib/rustlib/etc");
|
||||||
|
t!(fs::create_dir_all(&dst));
|
||||||
let cp_debugger_script = |file: &str| {
|
let cp_debugger_script = |file: &str| {
|
||||||
let dst = sysroot.join("lib/rustlib/etc");
|
|
||||||
t!(fs::create_dir_all(&dst));
|
|
||||||
install(&build.src.join("src/etc/").join(file), &dst, 0o644);
|
install(&build.src.join("src/etc/").join(file), &dst, 0o644);
|
||||||
};
|
};
|
||||||
if host.contains("windows-msvc") {
|
if host.contains("windows-msvc") {
|
||||||
@ -376,8 +366,8 @@ pub fn debugger_scripts(build: &Build,
|
|||||||
install(&build.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"),
|
install(&build.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"),
|
||||||
0o755);
|
0o755);
|
||||||
|
|
||||||
|
cp_debugger_script("natvis/liballoc.natvis");
|
||||||
cp_debugger_script("natvis/libcore.natvis");
|
cp_debugger_script("natvis/libcore.natvis");
|
||||||
cp_debugger_script("natvis/libcollections.natvis");
|
|
||||||
} else {
|
} else {
|
||||||
cp_debugger_script("debugger_pretty_printers_common.py");
|
cp_debugger_script("debugger_pretty_printers_common.py");
|
||||||
|
|
||||||
@ -404,7 +394,7 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
|
|||||||
|
|
||||||
// The only true set of target libraries came from the build triple, so
|
// The only true set of target libraries came from the build triple, so
|
||||||
// let's reduce redundant work by only producing archives from that host.
|
// let's reduce redundant work by only producing archives from that host.
|
||||||
if compiler.host != build.config.build {
|
if compiler.host != build.build {
|
||||||
println!("\tskipping, not a build host");
|
println!("\tskipping, not a build host");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -415,8 +405,9 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
|
|||||||
|
|
||||||
let dst = image.join("lib/rustlib").join(target);
|
let dst = image.join("lib/rustlib").join(target);
|
||||||
t!(fs::create_dir_all(&dst));
|
t!(fs::create_dir_all(&dst));
|
||||||
let src = build.sysroot(compiler).join("lib/rustlib");
|
let mut src = build.sysroot_libdir(compiler, target);
|
||||||
cp_r(&src.join(target), &dst);
|
src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
|
||||||
|
cp_r(&src, &dst);
|
||||||
|
|
||||||
let mut cmd = rust_installer(build);
|
let mut cmd = rust_installer(build);
|
||||||
cmd.arg("generate")
|
cmd.arg("generate")
|
||||||
@ -450,7 +441,7 @@ pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
|
|||||||
assert!(build.config.extended);
|
assert!(build.config.extended);
|
||||||
println!("Dist analysis");
|
println!("Dist analysis");
|
||||||
|
|
||||||
if compiler.host != build.config.build {
|
if compiler.host != build.build {
|
||||||
println!("\tskipping, not a build host");
|
println!("\tskipping, not a build host");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -498,12 +489,11 @@ fn copy_src_dirs(build: &Build, src_dirs: &[&str], exclude_dirs: &[&str], dst_di
|
|||||||
if spath.ends_with("~") || spath.ends_with(".pyc") {
|
if spath.ends_with("~") || spath.ends_with(".pyc") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if spath.contains("llvm/test") || spath.contains("llvm\\test") {
|
if (spath.contains("llvm/test") || spath.contains("llvm\\test")) &&
|
||||||
if spath.ends_with(".ll") ||
|
(spath.ends_with(".ll") ||
|
||||||
spath.ends_with(".td") ||
|
spath.ends_with(".td") ||
|
||||||
spath.ends_with(".s") {
|
spath.ends_with(".s")) {
|
||||||
return false
|
return false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let full_path = Path::new(dir).join(path);
|
let full_path = Path::new(dir).join(path);
|
||||||
@ -564,12 +554,12 @@ pub fn rust_src(build: &Build) {
|
|||||||
"src/libstd",
|
"src/libstd",
|
||||||
"src/libstd_unicode",
|
"src/libstd_unicode",
|
||||||
"src/libunwind",
|
"src/libunwind",
|
||||||
|
"src/rustc/compiler_builtins_shim",
|
||||||
"src/rustc/libc_shim",
|
"src/rustc/libc_shim",
|
||||||
"src/libtest",
|
"src/libtest",
|
||||||
"src/libterm",
|
"src/libterm",
|
||||||
"src/libgetopts",
|
|
||||||
"src/compiler-rt",
|
|
||||||
"src/jemalloc",
|
"src/jemalloc",
|
||||||
|
"src/libprofiler_builtins",
|
||||||
];
|
];
|
||||||
let std_src_dirs_exclude = [
|
let std_src_dirs_exclude = [
|
||||||
"src/compiler-rt/test",
|
"src/compiler-rt/test",
|
||||||
@ -595,7 +585,7 @@ pub fn rust_src(build: &Build) {
|
|||||||
t!(fs::remove_dir_all(&image));
|
t!(fs::remove_dir_all(&image));
|
||||||
}
|
}
|
||||||
|
|
||||||
const CARGO_VENDOR_VERSION: &'static str = "0.1.4";
|
const CARGO_VENDOR_VERSION: &str = "0.1.4";
|
||||||
|
|
||||||
/// Creates the plain source tarball
|
/// Creates the plain source tarball
|
||||||
pub fn plain_source_tarball(build: &Build) {
|
pub fn plain_source_tarball(build: &Build) {
|
||||||
@ -634,26 +624,26 @@ pub fn plain_source_tarball(build: &Build) {
|
|||||||
write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes());
|
write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes());
|
||||||
|
|
||||||
// If we're building from git sources, we need to vendor a complete distribution.
|
// If we're building from git sources, we need to vendor a complete distribution.
|
||||||
if build.src_is_git {
|
if build.rust_info.is_git() {
|
||||||
// Get cargo-vendor installed, if it isn't already.
|
// Get cargo-vendor installed, if it isn't already.
|
||||||
let mut has_cargo_vendor = false;
|
let mut has_cargo_vendor = false;
|
||||||
let mut cmd = Command::new(&build.cargo);
|
let mut cmd = Command::new(&build.initial_cargo);
|
||||||
for line in output(cmd.arg("install").arg("--list")).lines() {
|
for line in output(cmd.arg("install").arg("--list")).lines() {
|
||||||
has_cargo_vendor |= line.starts_with("cargo-vendor ");
|
has_cargo_vendor |= line.starts_with("cargo-vendor ");
|
||||||
}
|
}
|
||||||
if !has_cargo_vendor {
|
if !has_cargo_vendor {
|
||||||
let mut cmd = Command::new(&build.cargo);
|
let mut cmd = Command::new(&build.initial_cargo);
|
||||||
cmd.arg("install")
|
cmd.arg("install")
|
||||||
.arg("--force")
|
.arg("--force")
|
||||||
.arg("--debug")
|
.arg("--debug")
|
||||||
.arg("--vers").arg(CARGO_VENDOR_VERSION)
|
.arg("--vers").arg(CARGO_VENDOR_VERSION)
|
||||||
.arg("cargo-vendor")
|
.arg("cargo-vendor")
|
||||||
.env("RUSTC", &build.rustc);
|
.env("RUSTC", &build.initial_rustc);
|
||||||
build.run(&mut cmd);
|
build.run(&mut cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vendor all Cargo dependencies
|
// Vendor all Cargo dependencies
|
||||||
let mut cmd = Command::new(&build.cargo);
|
let mut cmd = Command::new(&build.initial_cargo);
|
||||||
cmd.arg("vendor")
|
cmd.arg("vendor")
|
||||||
.current_dir(&plain_dst_src.join("src"));
|
.current_dir(&plain_dst_src.join("src"));
|
||||||
build.run(&mut cmd);
|
build.run(&mut cmd);
|
||||||
@ -716,7 +706,7 @@ fn write_file(path: &Path, data: &[u8]) {
|
|||||||
|
|
||||||
pub fn cargo(build: &Build, stage: u32, target: &str) {
|
pub fn cargo(build: &Build, stage: u32, target: &str) {
|
||||||
println!("Dist cargo stage{} ({})", stage, target);
|
println!("Dist cargo stage{} ({})", stage, target);
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
|
|
||||||
let src = build.src.join("src/tools/cargo");
|
let src = build.src.join("src/tools/cargo");
|
||||||
let etc = src.join("src/etc");
|
let etc = src.join("src/etc");
|
||||||
@ -777,7 +767,7 @@ pub fn cargo(build: &Build, stage: u32, target: &str) {
|
|||||||
pub fn rls(build: &Build, stage: u32, target: &str) {
|
pub fn rls(build: &Build, stage: u32, target: &str) {
|
||||||
assert!(build.config.extended);
|
assert!(build.config.extended);
|
||||||
println!("Dist RLS stage{} ({})", stage, target);
|
println!("Dist RLS stage{} ({})", stage, target);
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
|
|
||||||
let src = build.src.join("src/tools/rls");
|
let src = build.src.join("src/tools/rls");
|
||||||
let release_num = build.release_num("rls");
|
let release_num = build.release_num("rls");
|
||||||
@ -1160,7 +1150,7 @@ fn add_env(build: &Build, cmd: &mut Command, target: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_and_sign(build: &Build) {
|
pub fn hash_and_sign(build: &Build) {
|
||||||
let compiler = Compiler::new(0, &build.config.build);
|
let compiler = Compiler::new(0, &build.build);
|
||||||
let mut cmd = build.tool_cmd(&compiler, "build-manifest");
|
let mut cmd = build.tool_cmd(&compiler, "build-manifest");
|
||||||
let sign = build.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
|
let sign = build.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
|
||||||
panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
|
panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
|
||||||
|
@ -27,18 +27,26 @@ use {Build, Compiler, Mode};
|
|||||||
use util::{cp_r, symlink_dir};
|
use util::{cp_r, symlink_dir};
|
||||||
use build_helper::up_to_date;
|
use build_helper::up_to_date;
|
||||||
|
|
||||||
/// Invoke `rustbook` as compiled in `stage` for `target` for the doc book
|
/// Invoke `rustbook` for `target` for the doc book `name`.
|
||||||
/// `name` into the `out` path.
|
|
||||||
///
|
///
|
||||||
/// This will not actually generate any documentation if the documentation has
|
/// This will not actually generate any documentation if the documentation has
|
||||||
/// already been generated.
|
/// already been generated.
|
||||||
pub fn rustbook(build: &Build, target: &str, name: &str) {
|
pub fn rustbook(build: &Build, target: &str, name: &str) {
|
||||||
|
let src = build.src.join("src/doc");
|
||||||
|
rustbook_src(build, target, name, &src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoke `rustbook` for `target` for the doc book `name` from the `src` path.
|
||||||
|
///
|
||||||
|
/// This will not actually generate any documentation if the documentation has
|
||||||
|
/// already been generated.
|
||||||
|
pub fn rustbook_src(build: &Build, target: &str, name: &str, src: &Path) {
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
|
|
||||||
let out = out.join(name);
|
let out = out.join(name);
|
||||||
let compiler = Compiler::new(0, &build.config.build);
|
let compiler = Compiler::new(0, &build.build);
|
||||||
let src = build.src.join("src/doc").join(name);
|
let src = src.join(name);
|
||||||
let index = out.join("index.html");
|
let index = out.join("index.html");
|
||||||
let rustbook = build.tool(&compiler, "rustbook");
|
let rustbook = build.tool(&compiler, "rustbook");
|
||||||
if up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
|
if up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
|
||||||
@ -87,7 +95,7 @@ pub fn book(build: &Build, target: &str, name: &str) {
|
|||||||
fn invoke_rustdoc(build: &Build, target: &str, markdown: &str) {
|
fn invoke_rustdoc(build: &Build, target: &str, markdown: &str) {
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
|
|
||||||
let compiler = Compiler::new(0, &build.config.build);
|
let compiler = Compiler::new(0, &build.build);
|
||||||
|
|
||||||
let path = build.src.join("src/doc").join(markdown);
|
let path = build.src.join("src/doc").join(markdown);
|
||||||
|
|
||||||
@ -142,7 +150,7 @@ pub fn standalone(build: &Build, target: &str) {
|
|||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
|
|
||||||
let compiler = Compiler::new(0, &build.config.build);
|
let compiler = Compiler::new(0, &build.build);
|
||||||
|
|
||||||
let favicon = build.src.join("src/doc/favicon.inc");
|
let favicon = build.src.join("src/doc/favicon.inc");
|
||||||
let footer = build.src.join("src/doc/footer.inc");
|
let footer = build.src.join("src/doc/footer.inc");
|
||||||
@ -209,7 +217,7 @@ pub fn std(build: &Build, stage: u32, target: &str) {
|
|||||||
println!("Documenting stage{} std ({})", stage, target);
|
println!("Documenting stage{} std ({})", stage, target);
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
let compiler = if build.force_use_stage1(&compiler, target) {
|
let compiler = if build.force_use_stage1(&compiler, target) {
|
||||||
Compiler::new(1, compiler.host)
|
Compiler::new(1, compiler.host)
|
||||||
} else {
|
} else {
|
||||||
@ -268,7 +276,7 @@ pub fn test(build: &Build, stage: u32, target: &str) {
|
|||||||
println!("Documenting stage{} test ({})", stage, target);
|
println!("Documenting stage{} test ({})", stage, target);
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
let compiler = if build.force_use_stage1(&compiler, target) {
|
let compiler = if build.force_use_stage1(&compiler, target) {
|
||||||
Compiler::new(1, compiler.host)
|
Compiler::new(1, compiler.host)
|
||||||
} else {
|
} else {
|
||||||
@ -298,7 +306,7 @@ pub fn rustc(build: &Build, stage: u32, target: &str) {
|
|||||||
println!("Documenting stage{} compiler ({})", stage, target);
|
println!("Documenting stage{} compiler ({})", stage, target);
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = Compiler::new(stage, &build.config.build);
|
let compiler = Compiler::new(stage, &build.build);
|
||||||
let compiler = if build.force_use_stage1(&compiler, target) {
|
let compiler = if build.force_use_stage1(&compiler, target) {
|
||||||
Compiler::new(1, compiler.host)
|
Compiler::new(1, compiler.host)
|
||||||
} else {
|
} else {
|
||||||
@ -343,17 +351,30 @@ pub fn error_index(build: &Build, target: &str) {
|
|||||||
println!("Documenting error index ({})", target);
|
println!("Documenting error index ({})", target);
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = Compiler::new(0, &build.config.build);
|
let compiler = Compiler::new(0, &build.build);
|
||||||
let mut index = build.tool_cmd(&compiler, "error_index_generator");
|
let mut index = build.tool_cmd(&compiler, "error_index_generator");
|
||||||
index.arg("html");
|
index.arg("html");
|
||||||
index.arg(out.join("error-index.html"));
|
index.arg(out.join("error-index.html"));
|
||||||
|
|
||||||
// FIXME: shouldn't have to pass this env var
|
// FIXME: shouldn't have to pass this env var
|
||||||
index.env("CFG_BUILD", &build.config.build);
|
index.env("CFG_BUILD", &build.build);
|
||||||
|
|
||||||
build.run(&mut index);
|
build.run(&mut index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unstable_book_gen(build: &Build, target: &str) {
|
||||||
|
println!("Generating unstable book md files ({})", target);
|
||||||
|
let out = build.md_doc_out(target).join("unstable-book");
|
||||||
|
t!(fs::create_dir_all(&out));
|
||||||
|
t!(fs::remove_dir_all(&out));
|
||||||
|
let compiler = Compiler::new(0, &build.build);
|
||||||
|
let mut cmd = build.tool_cmd(&compiler, "unstable-book-gen");
|
||||||
|
cmd.arg(build.src.join("src"));
|
||||||
|
cmd.arg(out);
|
||||||
|
|
||||||
|
build.run(&mut cmd);
|
||||||
|
}
|
||||||
|
|
||||||
fn symlink_dir_force(src: &Path, dst: &Path) -> io::Result<()> {
|
fn symlink_dir_force(src: &Path, dst: &Path) -> io::Result<()> {
|
||||||
if let Ok(m) = fs::symlink_metadata(dst) {
|
if let Ok(m) = fs::symlink_metadata(dst) {
|
||||||
if m.file_type().is_dir() {
|
if m.file_type().is_dir() {
|
||||||
|
@ -35,22 +35,12 @@ pub struct Flags {
|
|||||||
pub host: Vec<String>,
|
pub host: Vec<String>,
|
||||||
pub target: Vec<String>,
|
pub target: Vec<String>,
|
||||||
pub config: Option<PathBuf>,
|
pub config: Option<PathBuf>,
|
||||||
pub src: Option<PathBuf>,
|
pub src: PathBuf,
|
||||||
pub jobs: Option<u32>,
|
pub jobs: Option<u32>,
|
||||||
pub cmd: Subcommand,
|
pub cmd: Subcommand,
|
||||||
pub incremental: bool,
|
pub incremental: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Flags {
|
|
||||||
pub fn verbose(&self) -> bool {
|
|
||||||
self.verbose > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn very_verbose(&self) -> bool {
|
|
||||||
self.verbose > 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Subcommand {
|
pub enum Subcommand {
|
||||||
Build {
|
Build {
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
@ -61,7 +51,7 @@ pub enum Subcommand {
|
|||||||
Test {
|
Test {
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
test_args: Vec<String>,
|
test_args: Vec<String>,
|
||||||
no_fail_fast: bool,
|
fail_fast: bool,
|
||||||
},
|
},
|
||||||
Bench {
|
Bench {
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
@ -122,16 +112,15 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
|||||||
// the subcommand. Therefore we must manually identify the subcommand first, so that we can
|
// the subcommand. Therefore we must manually identify the subcommand first, so that we can
|
||||||
// complete the definition of the options. Then we can use the getopt::Matches object from
|
// complete the definition of the options. Then we can use the getopt::Matches object from
|
||||||
// there on out.
|
// there on out.
|
||||||
let mut possible_subcommands = args.iter().collect::<Vec<_>>();
|
let subcommand = args.iter().find(|&s|
|
||||||
possible_subcommands.retain(|&s|
|
(s == "build")
|
||||||
(s == "build")
|
|| (s == "test")
|
||||||
|| (s == "test")
|
|| (s == "bench")
|
||||||
|| (s == "bench")
|
|| (s == "doc")
|
||||||
|| (s == "doc")
|
|| (s == "clean")
|
||||||
|| (s == "clean")
|
|| (s == "dist")
|
||||||
|| (s == "dist")
|
|| (s == "install"));
|
||||||
|| (s == "install"));
|
let subcommand = match subcommand {
|
||||||
let subcommand = match possible_subcommands.first() {
|
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
// No subcommand -- show the general usage and subcommand help
|
// No subcommand -- show the general usage and subcommand help
|
||||||
@ -164,7 +153,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
|||||||
let mut pass_sanity_check = true;
|
let mut pass_sanity_check = true;
|
||||||
match matches.free.get(0) {
|
match matches.free.get(0) {
|
||||||
Some(check_subcommand) => {
|
Some(check_subcommand) => {
|
||||||
if &check_subcommand != subcommand {
|
if check_subcommand != subcommand {
|
||||||
pass_sanity_check = false;
|
pass_sanity_check = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -196,9 +185,14 @@ Arguments:
|
|||||||
./x.py build
|
./x.py build
|
||||||
./x.py build --stage 1
|
./x.py build --stage 1
|
||||||
|
|
||||||
For a quick build with a usable compile, you can pass:
|
For a quick build of a usable compiler, you can pass:
|
||||||
|
|
||||||
./x.py build --stage 1 src/libtest");
|
./x.py build --stage 1 src/libtest
|
||||||
|
|
||||||
|
This will first build everything once (like --stage 0 without further
|
||||||
|
arguments would), and then use the compiler built in stage 0 to build
|
||||||
|
src/libtest and its dependencies.
|
||||||
|
Once this is done, build/$ARCH/stage1 contains a usable compiler.");
|
||||||
}
|
}
|
||||||
"test" => {
|
"test" => {
|
||||||
subcommand_help.push_str("\n
|
subcommand_help.push_str("\n
|
||||||
@ -274,7 +268,7 @@ Arguments:
|
|||||||
Subcommand::Test {
|
Subcommand::Test {
|
||||||
paths: paths,
|
paths: paths,
|
||||||
test_args: matches.opt_strs("test-args"),
|
test_args: matches.opt_strs("test-args"),
|
||||||
no_fail_fast: matches.opt_present("no-fail-fast"),
|
fail_fast: !matches.opt_present("no-fail-fast"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"bench" => {
|
"bench" => {
|
||||||
@ -311,12 +305,15 @@ Arguments:
|
|||||||
|
|
||||||
let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());
|
let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());
|
||||||
|
|
||||||
if matches.opt_present("incremental") {
|
if matches.opt_present("incremental") && stage.is_none() {
|
||||||
if stage.is_none() {
|
stage = Some(1);
|
||||||
stage = Some(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cwd = t!(env::current_dir());
|
||||||
|
let src = matches.opt_str("src").map(PathBuf::from)
|
||||||
|
.or_else(|| env::var_os("SRC").map(PathBuf::from))
|
||||||
|
.unwrap_or(cwd);
|
||||||
|
|
||||||
Flags {
|
Flags {
|
||||||
verbose: matches.opt_count("verbose"),
|
verbose: matches.opt_count("verbose"),
|
||||||
stage: stage,
|
stage: stage,
|
||||||
@ -328,7 +325,7 @@ Arguments:
|
|||||||
host: split(matches.opt_strs("host")),
|
host: split(matches.opt_strs("host")),
|
||||||
target: split(matches.opt_strs("target")),
|
target: split(matches.opt_strs("target")),
|
||||||
config: cfg_file,
|
config: cfg_file,
|
||||||
src: matches.opt_str("src").map(PathBuf::from),
|
src: src,
|
||||||
jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
|
jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
incremental: matches.opt_present("incremental"),
|
incremental: matches.opt_present("incremental"),
|
||||||
@ -347,9 +344,9 @@ impl Subcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn no_fail_fast(&self) -> bool {
|
pub fn fail_fast(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Subcommand::Test { no_fail_fast, .. } => no_fail_fast,
|
Subcommand::Test { fail_fast, .. } => fail_fast,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,5 +146,5 @@ fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -161,25 +161,35 @@ pub struct Build {
|
|||||||
flags: Flags,
|
flags: Flags,
|
||||||
|
|
||||||
// Derived properties from the above two configurations
|
// Derived properties from the above two configurations
|
||||||
cargo: PathBuf,
|
|
||||||
rustc: PathBuf,
|
|
||||||
src: PathBuf,
|
src: PathBuf,
|
||||||
out: PathBuf,
|
out: PathBuf,
|
||||||
rust_info: channel::GitInfo,
|
rust_info: channel::GitInfo,
|
||||||
cargo_info: channel::GitInfo,
|
cargo_info: channel::GitInfo,
|
||||||
rls_info: channel::GitInfo,
|
rls_info: channel::GitInfo,
|
||||||
local_rebuild: bool,
|
local_rebuild: bool,
|
||||||
|
fail_fast: bool,
|
||||||
|
verbosity: usize,
|
||||||
|
|
||||||
|
// Targets for which to build.
|
||||||
|
build: String,
|
||||||
|
hosts: Vec<String>,
|
||||||
|
targets: Vec<String>,
|
||||||
|
|
||||||
|
// Stage 0 (downloaded) compiler and cargo or their local rust equivalents.
|
||||||
|
initial_rustc: PathBuf,
|
||||||
|
initial_cargo: PathBuf,
|
||||||
|
|
||||||
// Probed tools at runtime
|
// Probed tools at runtime
|
||||||
lldb_version: Option<String>,
|
lldb_version: Option<String>,
|
||||||
lldb_python_dir: Option<String>,
|
lldb_python_dir: Option<String>,
|
||||||
|
|
||||||
// Runtime state filled in later on
|
// Runtime state filled in later on
|
||||||
|
// target -> (cc, ar)
|
||||||
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
|
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
|
||||||
|
// host -> (cc, ar)
|
||||||
cxx: HashMap<String, gcc::Tool>,
|
cxx: HashMap<String, gcc::Tool>,
|
||||||
crates: HashMap<String, Crate>,
|
crates: HashMap<String, Crate>,
|
||||||
is_sudo: bool,
|
is_sudo: bool,
|
||||||
src_is_git: bool,
|
|
||||||
ci_env: CiEnv,
|
ci_env: CiEnv,
|
||||||
delayed_failures: Cell<usize>,
|
delayed_failures: Cell<usize>,
|
||||||
}
|
}
|
||||||
@ -202,20 +212,16 @@ struct Crate {
|
|||||||
/// build system, with each mod generating output in a different directory.
|
/// build system, with each mod generating output in a different directory.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
/// This cargo is going to build the standard library, placing output in the
|
/// Build the standard library, placing output in the "stageN-std" directory.
|
||||||
/// "stageN-std" directory.
|
|
||||||
Libstd,
|
Libstd,
|
||||||
|
|
||||||
/// This cargo is going to build libtest, placing output in the
|
/// Build libtest, placing output in the "stageN-test" directory.
|
||||||
/// "stageN-test" directory.
|
|
||||||
Libtest,
|
Libtest,
|
||||||
|
|
||||||
/// This cargo is going to build librustc and compiler libraries, placing
|
/// Build librustc and compiler libraries, placing output in the "stageN-rustc" directory.
|
||||||
/// output in the "stageN-rustc" directory.
|
|
||||||
Librustc,
|
Librustc,
|
||||||
|
|
||||||
/// This cargo is going to build some tool, placing output in the
|
/// Build some tool, placing output in the "stageN-tools" directory.
|
||||||
/// "stageN-tools" directory.
|
|
||||||
Tool,
|
Tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,22 +232,9 @@ impl Build {
|
|||||||
/// By default all build output will be placed in the current directory.
|
/// By default all build output will be placed in the current directory.
|
||||||
pub fn new(flags: Flags, config: Config) -> Build {
|
pub fn new(flags: Flags, config: Config) -> Build {
|
||||||
let cwd = t!(env::current_dir());
|
let cwd = t!(env::current_dir());
|
||||||
let src = flags.src.clone().or_else(|| {
|
let src = flags.src.clone();
|
||||||
env::var_os("SRC").map(|x| x.into())
|
|
||||||
}).unwrap_or(cwd.clone());
|
|
||||||
let out = cwd.join("build");
|
let out = cwd.join("build");
|
||||||
|
|
||||||
let stage0_root = out.join(&config.build).join("stage0/bin");
|
|
||||||
let rustc = match config.rustc {
|
|
||||||
Some(ref s) => PathBuf::from(s),
|
|
||||||
None => stage0_root.join(exe("rustc", &config.build)),
|
|
||||||
};
|
|
||||||
let cargo = match config.cargo {
|
|
||||||
Some(ref s) => PathBuf::from(s),
|
|
||||||
None => stage0_root.join(exe("cargo", &config.build)),
|
|
||||||
};
|
|
||||||
let local_rebuild = config.local_rebuild;
|
|
||||||
|
|
||||||
let is_sudo = match env::var_os("SUDO_USER") {
|
let is_sudo = match env::var_os("SUDO_USER") {
|
||||||
Some(sudo_user) => {
|
Some(sudo_user) => {
|
||||||
match env::var_os("USER") {
|
match env::var_os("USER") {
|
||||||
@ -254,32 +247,64 @@ impl Build {
|
|||||||
let rust_info = channel::GitInfo::new(&src);
|
let rust_info = channel::GitInfo::new(&src);
|
||||||
let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo"));
|
let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo"));
|
||||||
let rls_info = channel::GitInfo::new(&src.join("src/tools/rls"));
|
let rls_info = channel::GitInfo::new(&src.join("src/tools/rls"));
|
||||||
let src_is_git = src.join(".git").exists();
|
|
||||||
|
let hosts = if !flags.host.is_empty() {
|
||||||
|
for host in flags.host.iter() {
|
||||||
|
if !config.host.contains(host) {
|
||||||
|
panic!("specified host `{}` is not in configuration", host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flags.host.clone()
|
||||||
|
} else {
|
||||||
|
config.host.clone()
|
||||||
|
};
|
||||||
|
let targets = if !flags.target.is_empty() {
|
||||||
|
for target in flags.target.iter() {
|
||||||
|
if !config.target.contains(target) {
|
||||||
|
panic!("specified target `{}` is not in configuration", target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flags.target.clone()
|
||||||
|
} else {
|
||||||
|
config.target.clone()
|
||||||
|
};
|
||||||
|
|
||||||
Build {
|
Build {
|
||||||
|
initial_rustc: config.initial_rustc.clone(),
|
||||||
|
initial_cargo: config.initial_cargo.clone(),
|
||||||
|
local_rebuild: config.local_rebuild,
|
||||||
|
fail_fast: flags.cmd.fail_fast(),
|
||||||
|
verbosity: cmp::max(flags.verbose, config.verbose),
|
||||||
|
|
||||||
|
build: config.host[0].clone(),
|
||||||
|
hosts: hosts,
|
||||||
|
targets: targets,
|
||||||
|
|
||||||
flags: flags,
|
flags: flags,
|
||||||
config: config,
|
config: config,
|
||||||
cargo: cargo,
|
|
||||||
rustc: rustc,
|
|
||||||
src: src,
|
src: src,
|
||||||
out: out,
|
out: out,
|
||||||
|
|
||||||
rust_info: rust_info,
|
rust_info: rust_info,
|
||||||
cargo_info: cargo_info,
|
cargo_info: cargo_info,
|
||||||
rls_info: rls_info,
|
rls_info: rls_info,
|
||||||
local_rebuild: local_rebuild,
|
|
||||||
cc: HashMap::new(),
|
cc: HashMap::new(),
|
||||||
cxx: HashMap::new(),
|
cxx: HashMap::new(),
|
||||||
crates: HashMap::new(),
|
crates: HashMap::new(),
|
||||||
lldb_version: None,
|
lldb_version: None,
|
||||||
lldb_python_dir: None,
|
lldb_python_dir: None,
|
||||||
is_sudo: is_sudo,
|
is_sudo: is_sudo,
|
||||||
src_is_git: src_is_git,
|
|
||||||
ci_env: CiEnv::current(),
|
ci_env: CiEnv::current(),
|
||||||
delayed_failures: Cell::new(0),
|
delayed_failures: Cell::new(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_slice(&self) -> &[String] {
|
||||||
|
unsafe {
|
||||||
|
std::slice::from_raw_parts(&self.build, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Executes the entire build, as configured by the flags and configuration.
|
/// Executes the entire build, as configured by the flags and configuration.
|
||||||
pub fn build(&mut self) {
|
pub fn build(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -296,7 +321,7 @@ impl Build {
|
|||||||
sanity::check(self);
|
sanity::check(self);
|
||||||
// If local-rust is the same major.minor as the current version, then force a local-rebuild
|
// If local-rust is the same major.minor as the current version, then force a local-rebuild
|
||||||
let local_version_verbose = output(
|
let local_version_verbose = output(
|
||||||
Command::new(&self.rustc).arg("--version").arg("--verbose"));
|
Command::new(&self.initial_rustc).arg("--version").arg("--verbose"));
|
||||||
let local_release = local_version_verbose
|
let local_release = local_version_verbose
|
||||||
.lines().filter(|x| x.starts_with("release:"))
|
.lines().filter(|x| x.starts_with("release:"))
|
||||||
.next().unwrap().trim_left_matches("release:").trim();
|
.next().unwrap().trim_left_matches("release:").trim();
|
||||||
@ -338,7 +363,7 @@ impl Build {
|
|||||||
mode: Mode,
|
mode: Mode,
|
||||||
target: &str,
|
target: &str,
|
||||||
cmd: &str) -> Command {
|
cmd: &str) -> Command {
|
||||||
let mut cargo = Command::new(&self.cargo);
|
let mut cargo = Command::new(&self.initial_cargo);
|
||||||
let out_dir = self.stage_out(compiler, mode);
|
let out_dir = self.stage_out(compiler, mode);
|
||||||
cargo.env("CARGO_TARGET_DIR", out_dir)
|
cargo.env("CARGO_TARGET_DIR", out_dir)
|
||||||
.arg(cmd)
|
.arg(cmd)
|
||||||
@ -422,36 +447,13 @@ impl Build {
|
|||||||
// library up and running, so we can use the normal compiler to compile
|
// library up and running, so we can use the normal compiler to compile
|
||||||
// build scripts in that situation.
|
// build scripts in that situation.
|
||||||
if mode == Mode::Libstd {
|
if mode == Mode::Libstd {
|
||||||
cargo.env("RUSTC_SNAPSHOT", &self.rustc)
|
cargo.env("RUSTC_SNAPSHOT", &self.initial_rustc)
|
||||||
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
|
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
|
||||||
} else {
|
} else {
|
||||||
cargo.env("RUSTC_SNAPSHOT", self.compiler_path(compiler))
|
cargo.env("RUSTC_SNAPSHOT", self.compiler_path(compiler))
|
||||||
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler));
|
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler));
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are two invariants we must maintain:
|
|
||||||
// * stable crates cannot depend on unstable crates (general Rust rule),
|
|
||||||
// * crates that end up in the sysroot must be unstable (rustbuild rule).
|
|
||||||
//
|
|
||||||
// In order to do enforce the latter, we pass the env var
|
|
||||||
// `RUSTBUILD_UNSTABLE` down the line for any crates which will end up
|
|
||||||
// in the sysroot. We read this in bootstrap/bin/rustc.rs and if it is
|
|
||||||
// set, then we pass the `rustbuild` feature to rustc when building the
|
|
||||||
// the crate.
|
|
||||||
//
|
|
||||||
// In turn, crates that can be used here should recognise the `rustbuild`
|
|
||||||
// feature and opt-in to `rustc_private`.
|
|
||||||
//
|
|
||||||
// We can't always pass `rustbuild` because crates which are outside of
|
|
||||||
// the compiler, libs, and tests are stable and we don't want to make
|
|
||||||
// their deps unstable (since this would break the first invariant
|
|
||||||
// above).
|
|
||||||
//
|
|
||||||
// FIXME: remove this after next stage0
|
|
||||||
if mode != Mode::Tool && stage == 0 {
|
|
||||||
cargo.env("RUSTBUILD_UNSTABLE", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore incremental modes except for stage0, since we're
|
// Ignore incremental modes except for stage0, since we're
|
||||||
// not guaranteeing correctness across builds if the compiler
|
// not guaranteeing correctness across builds if the compiler
|
||||||
// is changing under your feet.`
|
// is changing under your feet.`
|
||||||
@ -464,8 +466,7 @@ impl Build {
|
|||||||
cargo.env("RUSTC_ON_FAIL", on_fail);
|
cargo.env("RUSTC_ON_FAIL", on_fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
let verbose = cmp::max(self.config.verbose, self.flags.verbose);
|
cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
|
||||||
cargo.env("RUSTC_VERBOSE", format!("{}", verbose));
|
|
||||||
|
|
||||||
// Specify some various options for build scripts used throughout
|
// Specify some various options for build scripts used throughout
|
||||||
// the build.
|
// the build.
|
||||||
@ -475,9 +476,15 @@ impl Build {
|
|||||||
cargo.env(format!("CC_{}", target), self.cc(target))
|
cargo.env(format!("CC_{}", target), self.cc(target))
|
||||||
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
|
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
|
||||||
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
|
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
|
||||||
|
|
||||||
|
if let Ok(cxx) = self.cxx(target) {
|
||||||
|
cargo.env(format!("CXX_{}", target), cxx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.config.extended && compiler.is_final_stage(self) {
|
if mode == Mode::Libstd &&
|
||||||
|
self.config.extended &&
|
||||||
|
compiler.is_final_stage(self) {
|
||||||
cargo.env("RUSTC_SAVE_ANALYSIS", "api".to_string());
|
cargo.env("RUSTC_SAVE_ANALYSIS", "api".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,7 +506,7 @@ impl Build {
|
|||||||
// FIXME: should update code to not require this env var
|
// FIXME: should update code to not require this env var
|
||||||
cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
|
cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
|
||||||
|
|
||||||
if self.config.verbose() || self.flags.verbose() {
|
if self.is_verbose() {
|
||||||
cargo.arg("-v");
|
cargo.arg("-v");
|
||||||
}
|
}
|
||||||
// FIXME: cargo bench does not accept `--release`
|
// FIXME: cargo bench does not accept `--release`
|
||||||
@ -515,13 +522,13 @@ impl Build {
|
|||||||
|
|
||||||
self.ci_env.force_coloring_in_ci(&mut cargo);
|
self.ci_env.force_coloring_in_ci(&mut cargo);
|
||||||
|
|
||||||
return cargo
|
cargo
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a path to the compiler specified.
|
/// Get a path to the compiler specified.
|
||||||
fn compiler_path(&self, compiler: &Compiler) -> PathBuf {
|
fn compiler_path(&self, compiler: &Compiler) -> PathBuf {
|
||||||
if compiler.is_snapshot(self) {
|
if compiler.is_snapshot(self) {
|
||||||
self.rustc.clone()
|
self.initial_rustc.clone()
|
||||||
} else {
|
} else {
|
||||||
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
|
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
|
||||||
}
|
}
|
||||||
@ -538,7 +545,7 @@ impl Build {
|
|||||||
let mut rustdoc = self.compiler_path(compiler);
|
let mut rustdoc = self.compiler_path(compiler);
|
||||||
rustdoc.pop();
|
rustdoc.pop();
|
||||||
rustdoc.push(exe("rustdoc", compiler.host));
|
rustdoc.push(exe("rustdoc", compiler.host));
|
||||||
return rustdoc
|
rustdoc
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a `Command` which is ready to run `tool` in `stage` built for
|
/// Get a `Command` which is ready to run `tool` in `stage` built for
|
||||||
@ -546,7 +553,7 @@ impl Build {
|
|||||||
fn tool_cmd(&self, compiler: &Compiler, tool: &str) -> Command {
|
fn tool_cmd(&self, compiler: &Compiler, tool: &str) -> Command {
|
||||||
let mut cmd = Command::new(self.tool(&compiler, tool));
|
let mut cmd = Command::new(self.tool(&compiler, tool));
|
||||||
self.prepare_tool_cmd(compiler, &mut cmd);
|
self.prepare_tool_cmd(compiler, &mut cmd);
|
||||||
return cmd
|
cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepares the `cmd` provided to be able to run the `compiler` provided.
|
/// Prepares the `cmd` provided to be able to run the `compiler` provided.
|
||||||
@ -594,7 +601,10 @@ impl Build {
|
|||||||
if self.config.backtrace {
|
if self.config.backtrace {
|
||||||
features.push_str(" backtrace");
|
features.push_str(" backtrace");
|
||||||
}
|
}
|
||||||
return features
|
if self.config.profiler {
|
||||||
|
features.push_str(" profiler");
|
||||||
|
}
|
||||||
|
features
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the space-separated set of activated features for the compiler.
|
/// Get the space-separated set of activated features for the compiler.
|
||||||
@ -603,7 +613,7 @@ impl Build {
|
|||||||
if self.config.use_jemalloc {
|
if self.config.use_jemalloc {
|
||||||
features.push_str(" jemalloc");
|
features.push_str(" jemalloc");
|
||||||
}
|
}
|
||||||
return features
|
features
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component directory that Cargo will produce output into (e.g.
|
/// Component directory that Cargo will produce output into (e.g.
|
||||||
@ -635,8 +645,14 @@ impl Build {
|
|||||||
/// Returns the libdir where the standard library and other artifacts are
|
/// Returns the libdir where the standard library and other artifacts are
|
||||||
/// found for a compiler's sysroot.
|
/// found for a compiler's sysroot.
|
||||||
fn sysroot_libdir(&self, compiler: &Compiler, target: &str) -> PathBuf {
|
fn sysroot_libdir(&self, compiler: &Compiler, target: &str) -> PathBuf {
|
||||||
self.sysroot(compiler).join("lib").join("rustlib")
|
if compiler.stage >= 2 {
|
||||||
.join(target).join("lib")
|
if let Some(ref libdir_relative) = self.config.libdir_relative {
|
||||||
|
return self.sysroot(compiler).join(libdir_relative)
|
||||||
|
.join("rustlib").join(target).join("lib")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.sysroot(compiler).join("lib").join("rustlib")
|
||||||
|
.join(target).join("lib")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the root directory for all output generated in a particular
|
/// Returns the root directory for all output generated in a particular
|
||||||
@ -677,6 +693,11 @@ impl Build {
|
|||||||
self.out.join(target).join("doc")
|
self.out.join(target).join("doc")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Output directory for some generated md crate documentation for a target (temporary)
|
||||||
|
fn md_doc_out(&self, target: &str) -> PathBuf {
|
||||||
|
self.out.join(target).join("md-doc")
|
||||||
|
}
|
||||||
|
|
||||||
/// Output directory for all crate documentation for a target (temporary)
|
/// Output directory for all crate documentation for a target (temporary)
|
||||||
///
|
///
|
||||||
/// The artifacts here are then copied into `doc_out` above.
|
/// The artifacts here are then copied into `doc_out` above.
|
||||||
@ -771,7 +792,7 @@ impl Build {
|
|||||||
|
|
||||||
/// Returns the libdir of the snapshot compiler.
|
/// Returns the libdir of the snapshot compiler.
|
||||||
fn rustc_snapshot_libdir(&self) -> PathBuf {
|
fn rustc_snapshot_libdir(&self) -> PathBuf {
|
||||||
self.rustc.parent().unwrap().parent().unwrap()
|
self.initial_rustc.parent().unwrap().parent().unwrap()
|
||||||
.join(libdir(&self.config.build))
|
.join(libdir(&self.config.build))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,9 +824,17 @@ impl Build {
|
|||||||
try_run_suppressed(cmd)
|
try_run_suppressed(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_verbose(&self) -> bool {
|
||||||
|
self.verbosity > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_very_verbose(&self) -> bool {
|
||||||
|
self.verbosity > 1
|
||||||
|
}
|
||||||
|
|
||||||
/// Prints a message if this build is configured in verbose mode.
|
/// Prints a message if this build is configured in verbose mode.
|
||||||
fn verbose(&self, msg: &str) {
|
fn verbose(&self, msg: &str) {
|
||||||
if self.flags.verbose() || self.config.verbose() {
|
if self.is_verbose() {
|
||||||
println!("{}", msg);
|
println!("{}", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -813,7 +842,7 @@ impl Build {
|
|||||||
/// Returns the number of parallel jobs that have been configured for this
|
/// Returns the number of parallel jobs that have been configured for this
|
||||||
/// build.
|
/// build.
|
||||||
fn jobs(&self) -> u32 {
|
fn jobs(&self) -> u32 {
|
||||||
self.flags.jobs.unwrap_or(num_cpus::get() as u32)
|
self.flags.jobs.unwrap_or_else(|| num_cpus::get() as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the C compiler for the target specified.
|
/// Returns the path to the C compiler for the target specified.
|
||||||
@ -845,7 +874,7 @@ impl Build {
|
|||||||
if target == "i686-pc-windows-gnu" {
|
if target == "i686-pc-windows-gnu" {
|
||||||
base.push("-fno-omit-frame-pointer".into());
|
base.push("-fno-omit-frame-pointer".into());
|
||||||
}
|
}
|
||||||
return base
|
base
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the `ar` archive utility for the target specified.
|
/// Returns the path to the `ar` archive utility for the target specified.
|
||||||
@ -853,13 +882,13 @@ impl Build {
|
|||||||
self.cc[target].1.as_ref().map(|p| &**p)
|
self.cc[target].1.as_ref().map(|p| &**p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the C++ compiler for the target specified, may panic
|
/// Returns the path to the C++ compiler for the target specified.
|
||||||
/// if no C++ compiler was configured for the target.
|
fn cxx(&self, target: &str) -> Result<&Path, String> {
|
||||||
fn cxx(&self, target: &str) -> &Path {
|
|
||||||
match self.cxx.get(target) {
|
match self.cxx.get(target) {
|
||||||
Some(p) => p.path(),
|
Some(p) => Ok(p.path()),
|
||||||
None => panic!("\n\ntarget `{}` is not configured as a host,
|
None => Err(format!(
|
||||||
only as a target\n\n", target),
|
"target `{}` is not configured as a host, only as a target",
|
||||||
|
target))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,7 +906,7 @@ impl Build {
|
|||||||
!target.contains("emscripten") {
|
!target.contains("emscripten") {
|
||||||
base.push(format!("-Clinker={}", self.cc(target).display()));
|
base.push(format!("-Clinker={}", self.cc(target).display()));
|
||||||
}
|
}
|
||||||
return base
|
base
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the "musl root" for this `target`, if defined
|
/// Returns the "musl root" for this `target`, if defined
|
||||||
@ -1058,7 +1087,7 @@ impl<'a> Compiler<'a> {
|
|||||||
|
|
||||||
/// Returns whether this is a snapshot compiler for `build`'s configuration
|
/// Returns whether this is a snapshot compiler for `build`'s configuration
|
||||||
fn is_snapshot(&self, build: &Build) -> bool {
|
fn is_snapshot(&self, build: &Build) -> bool {
|
||||||
self.stage == 0 && self.host == build.config.build
|
self.stage == 0 && self.host == build.build
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns if this compiler should be treated as a final stage one in the
|
/// Returns if this compiler should be treated as a final stage one in the
|
||||||
|
@ -56,7 +56,7 @@ fn build_krate(build: &mut Build, krate: &str) {
|
|||||||
// of packages we're going to have to know what `-p` arguments to pass it
|
// of packages we're going to have to know what `-p` arguments to pass it
|
||||||
// to know what crates to test. Here we run `cargo metadata` to learn about
|
// to know what crates to test. Here we run `cargo metadata` to learn about
|
||||||
// the dependency graph and what `-p` arguments there are.
|
// the dependency graph and what `-p` arguments there are.
|
||||||
let mut cargo = Command::new(&build.cargo);
|
let mut cargo = Command::new(&build.initial_cargo);
|
||||||
cargo.arg("metadata")
|
cargo.arg("metadata")
|
||||||
.arg("--format-version").arg("1")
|
.arg("--format-version").arg("1")
|
||||||
.arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml"));
|
.arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml"));
|
||||||
|
@ -55,7 +55,7 @@ check:
|
|||||||
check-aux:
|
check-aux:
|
||||||
$(Q)$(BOOTSTRAP) test \
|
$(Q)$(BOOTSTRAP) test \
|
||||||
src/tools/cargotest \
|
src/tools/cargotest \
|
||||||
cargo \
|
src/tools/cargo \
|
||||||
src/test/pretty \
|
src/test/pretty \
|
||||||
src/test/run-pass/pretty \
|
src/test/run-pass/pretty \
|
||||||
src/test/run-fail/pretty \
|
src/test/run-fail/pretty \
|
||||||
|
@ -86,14 +86,20 @@ pub fn llvm(build: &Build, target: &str) {
|
|||||||
None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon",
|
None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let llvm_exp_targets = match build.config.llvm_experimental_targets {
|
||||||
|
Some(ref s) => s,
|
||||||
|
None => "",
|
||||||
|
};
|
||||||
|
|
||||||
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
|
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
|
||||||
|
|
||||||
cfg.target(target)
|
cfg.target(target)
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.out_dir(&out_dir)
|
.out_dir(&out_dir)
|
||||||
.profile(profile)
|
.profile(profile)
|
||||||
.define("LLVM_ENABLE_ASSERTIONS", assertions)
|
.define("LLVM_ENABLE_ASSERTIONS", assertions)
|
||||||
.define("LLVM_TARGETS_TO_BUILD", llvm_targets)
|
.define("LLVM_TARGETS_TO_BUILD", llvm_targets)
|
||||||
|
.define("LLVM_EXPERIMENTAL_TARGETS_TO_BUILD", llvm_exp_targets)
|
||||||
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
|
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
|
||||||
.define("LLVM_INCLUDE_TESTS", "OFF")
|
.define("LLVM_INCLUDE_TESTS", "OFF")
|
||||||
.define("LLVM_INCLUDE_DOCS", "OFF")
|
.define("LLVM_INCLUDE_DOCS", "OFF")
|
||||||
@ -123,11 +129,11 @@ pub fn llvm(build: &Build, target: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// http://llvm.org/docs/HowToCrossCompileLLVM.html
|
// http://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||||
if target != build.config.build {
|
if target != build.build {
|
||||||
// FIXME: if the llvm root for the build triple is overridden then we
|
// FIXME: if the llvm root for the build triple is overridden then we
|
||||||
// should use llvm-tblgen from there, also should verify that it
|
// should use llvm-tblgen from there, also should verify that it
|
||||||
// actually exists most of the time in normal installs of LLVM.
|
// actually exists most of the time in normal installs of LLVM.
|
||||||
let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
|
let host = build.llvm_out(&build.build).join("bin/llvm-tblgen");
|
||||||
cfg.define("CMAKE_CROSSCOMPILING", "True")
|
cfg.define("CMAKE_CROSSCOMPILING", "True")
|
||||||
.define("LLVM_TABLEGEN", &host);
|
.define("LLVM_TABLEGEN", &host);
|
||||||
}
|
}
|
||||||
@ -149,7 +155,7 @@ pub fn llvm(build: &Build, target: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let cc = build.cc(target);
|
let cc = build.cc(target);
|
||||||
let cxx = build.cxx(target);
|
let cxx = build.cxx(target).unwrap();
|
||||||
|
|
||||||
// Handle msvc + ninja + ccache specially (this is what the bots use)
|
// Handle msvc + ninja + ccache specially (this is what the bots use)
|
||||||
if target.contains("msvc") &&
|
if target.contains("msvc") &&
|
||||||
@ -237,7 +243,7 @@ pub fn test_helpers(build: &Build, target: &str) {
|
|||||||
cfg.cargo_metadata(false)
|
cfg.cargo_metadata(false)
|
||||||
.out_dir(&dst)
|
.out_dir(&dst)
|
||||||
.target(target)
|
.target(target)
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.opt_level(0)
|
.opt_level(0)
|
||||||
.debug(false)
|
.debug(false)
|
||||||
.file(build.src.join("src/rt/rust_test_helpers.c"))
|
.file(build.src.join("src/rt/rust_test_helpers.c"))
|
||||||
|
@ -18,55 +18,70 @@
|
|||||||
//! In theory if we get past this phase it's a bug if a build fails, but in
|
//! In theory if we get past this phase it's a bug if a build fails, but in
|
||||||
//! practice that's likely not true!
|
//! practice that's likely not true!
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsString, OsStr};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use build_helper::output;
|
use build_helper::output;
|
||||||
|
|
||||||
use Build;
|
use Build;
|
||||||
|
|
||||||
|
struct Finder {
|
||||||
|
cache: HashMap<OsString, Option<PathBuf>>,
|
||||||
|
path: OsString,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Finder {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
cache: HashMap::new(),
|
||||||
|
path: env::var_os("PATH").unwrap_or_default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> {
|
||||||
|
let cmd: OsString = cmd.as_ref().into();
|
||||||
|
let path = self.path.clone();
|
||||||
|
self.cache.entry(cmd.clone()).or_insert_with(|| {
|
||||||
|
for path in env::split_paths(&path) {
|
||||||
|
let target = path.join(&cmd);
|
||||||
|
let mut cmd_alt = cmd.clone();
|
||||||
|
cmd_alt.push(".exe");
|
||||||
|
if target.is_file() || // some/path/git
|
||||||
|
target.with_extension("exe").exists() || // some/path/git.exe
|
||||||
|
target.join(&cmd_alt).exists() { // some/path/git/git.exe
|
||||||
|
return Some(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}).clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn must_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> PathBuf {
|
||||||
|
self.maybe_have(&cmd).unwrap_or_else(|| {
|
||||||
|
panic!("\n\ncouldn't find required command: {:?}\n\n", cmd.as_ref());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check(build: &mut Build) {
|
pub fn check(build: &mut Build) {
|
||||||
let mut checked = HashSet::new();
|
let path = env::var_os("PATH").unwrap_or_default();
|
||||||
let path = env::var_os("PATH").unwrap_or(OsString::new());
|
|
||||||
// On Windows, quotes are invalid characters for filename paths, and if
|
// On Windows, quotes are invalid characters for filename paths, and if
|
||||||
// one is present as part of the PATH then that can lead to the system
|
// one is present as part of the PATH then that can lead to the system
|
||||||
// being unable to identify the files properly. See
|
// being unable to identify the files properly. See
|
||||||
// https://github.com/rust-lang/rust/issues/34959 for more details.
|
// https://github.com/rust-lang/rust/issues/34959 for more details.
|
||||||
if cfg!(windows) {
|
if cfg!(windows) && path.to_string_lossy().contains("\"") {
|
||||||
if path.to_string_lossy().contains("\"") {
|
panic!("PATH contains invalid character '\"'");
|
||||||
panic!("PATH contains invalid character '\"'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let have_cmd = |cmd: &OsStr| {
|
|
||||||
for path in env::split_paths(&path) {
|
|
||||||
let target = path.join(cmd);
|
|
||||||
let mut cmd_alt = cmd.to_os_string();
|
|
||||||
cmd_alt.push(".exe");
|
|
||||||
if target.is_file() ||
|
|
||||||
target.with_extension("exe").exists() ||
|
|
||||||
target.join(cmd_alt).exists() {
|
|
||||||
return Some(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut need_cmd = |cmd: &OsStr| {
|
|
||||||
if !checked.insert(cmd.to_owned()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if have_cmd(cmd).is_none() {
|
|
||||||
panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let mut cmd_finder = Finder::new();
|
||||||
// If we've got a git directory we're gona need git to update
|
// If we've got a git directory we're gona need git to update
|
||||||
// submodules and learn about various other aspects.
|
// submodules and learn about various other aspects.
|
||||||
if build.src_is_git {
|
if build.rust_info.is_git() {
|
||||||
need_cmd("git".as_ref());
|
cmd_finder.must_have("git");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need cmake, but only if we're actually building LLVM or sanitizers.
|
// We need cmake, but only if we're actually building LLVM or sanitizers.
|
||||||
@ -74,51 +89,32 @@ pub fn check(build: &mut Build) {
|
|||||||
.filter_map(|host| build.config.target_config.get(host))
|
.filter_map(|host| build.config.target_config.get(host))
|
||||||
.any(|config| config.llvm_config.is_none());
|
.any(|config| config.llvm_config.is_none());
|
||||||
if building_llvm || build.config.sanitizers {
|
if building_llvm || build.config.sanitizers {
|
||||||
need_cmd("cmake".as_ref());
|
cmd_finder.must_have("cmake");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ninja is currently only used for LLVM itself.
|
// Ninja is currently only used for LLVM itself.
|
||||||
if building_llvm && build.config.ninja {
|
// Some Linux distros rename `ninja` to `ninja-build`.
|
||||||
// Some Linux distros rename `ninja` to `ninja-build`.
|
// CMake can work with either binary name.
|
||||||
// CMake can work with either binary name.
|
if building_llvm && build.config.ninja && cmd_finder.maybe_have("ninja-build").is_none() {
|
||||||
if have_cmd("ninja-build".as_ref()).is_none() {
|
cmd_finder.must_have("ninja");
|
||||||
need_cmd("ninja".as_ref());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if build.config.python.is_none() {
|
build.config.python = build.config.python.take().map(|p| cmd_finder.must_have(p))
|
||||||
build.config.python = have_cmd("python2.7".as_ref());
|
.or_else(|| env::var_os("BOOTSTRAP_PYTHON").map(PathBuf::from)) // set by bootstrap.py
|
||||||
}
|
.or_else(|| cmd_finder.maybe_have("python2.7"))
|
||||||
if build.config.python.is_none() {
|
.or_else(|| cmd_finder.maybe_have("python2"))
|
||||||
build.config.python = have_cmd("python2".as_ref());
|
.or_else(|| Some(cmd_finder.must_have("python")));
|
||||||
}
|
|
||||||
if build.config.python.is_none() {
|
|
||||||
need_cmd("python".as_ref());
|
|
||||||
build.config.python = Some("python".into());
|
|
||||||
}
|
|
||||||
need_cmd(build.config.python.as_ref().unwrap().as_ref());
|
|
||||||
|
|
||||||
|
build.config.nodejs = build.config.nodejs.take().map(|p| cmd_finder.must_have(p))
|
||||||
|
.or_else(|| cmd_finder.maybe_have("node"))
|
||||||
|
.or_else(|| cmd_finder.maybe_have("nodejs"));
|
||||||
|
|
||||||
if let Some(ref s) = build.config.nodejs {
|
build.config.gdb = build.config.gdb.take().map(|p| cmd_finder.must_have(p))
|
||||||
need_cmd(s.as_ref());
|
.or_else(|| cmd_finder.maybe_have("gdb"));
|
||||||
} else {
|
|
||||||
// Look for the nodejs command, needed for emscripten testing
|
|
||||||
if let Some(node) = have_cmd("node".as_ref()) {
|
|
||||||
build.config.nodejs = Some(node);
|
|
||||||
} else if let Some(node) = have_cmd("nodejs".as_ref()) {
|
|
||||||
build.config.nodejs = Some(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref gdb) = build.config.gdb {
|
|
||||||
need_cmd(gdb.as_ref());
|
|
||||||
} else {
|
|
||||||
build.config.gdb = have_cmd("gdb".as_ref());
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're gonna build some custom C code here and there, host triples
|
// We're gonna build some custom C code here and there, host triples
|
||||||
// also build some C++ shims for LLVM so we need a C++ compiler.
|
// also build some C++ shims for LLVM so we need a C++ compiler.
|
||||||
for target in build.config.target.iter() {
|
for target in &build.config.target {
|
||||||
// On emscripten we don't actually need the C compiler to just
|
// On emscripten we don't actually need the C compiler to just
|
||||||
// build the target artifacts, only for testing. For the sake
|
// build the target artifacts, only for testing. For the sake
|
||||||
// of easier bot configuration, just skip detection.
|
// of easier bot configuration, just skip detection.
|
||||||
@ -126,33 +122,32 @@ pub fn check(build: &mut Build) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
need_cmd(build.cc(target).as_ref());
|
cmd_finder.must_have(build.cc(target));
|
||||||
if let Some(ar) = build.ar(target) {
|
if let Some(ar) = build.ar(target) {
|
||||||
need_cmd(ar.as_ref());
|
cmd_finder.must_have(ar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for host in build.config.host.iter() {
|
|
||||||
need_cmd(build.cxx(host).as_ref());
|
|
||||||
}
|
|
||||||
|
|
||||||
// The msvc hosts don't use jemalloc, turn it off globally to
|
|
||||||
// avoid packaging the dummy liballoc_jemalloc on that platform.
|
|
||||||
for host in build.config.host.iter() {
|
for host in build.config.host.iter() {
|
||||||
|
cmd_finder.must_have(build.cxx(host).unwrap());
|
||||||
|
|
||||||
|
// The msvc hosts don't use jemalloc, turn it off globally to
|
||||||
|
// avoid packaging the dummy liballoc_jemalloc on that platform.
|
||||||
if host.contains("msvc") {
|
if host.contains("msvc") {
|
||||||
build.config.use_jemalloc = false;
|
build.config.use_jemalloc = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Externally configured LLVM requires FileCheck to exist
|
// Externally configured LLVM requires FileCheck to exist
|
||||||
let filecheck = build.llvm_filecheck(&build.config.build);
|
let filecheck = build.llvm_filecheck(&build.build);
|
||||||
if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
|
if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
|
||||||
panic!("FileCheck executable {:?} does not exist", filecheck);
|
panic!("FileCheck executable {:?} does not exist", filecheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
for target in build.config.target.iter() {
|
for target in &build.config.target {
|
||||||
// Can't compile for iOS unless we're on macOS
|
// Can't compile for iOS unless we're on macOS
|
||||||
if target.contains("apple-ios") &&
|
if target.contains("apple-ios") &&
|
||||||
!build.config.build.contains("apple-darwin") {
|
!build.build.contains("apple-darwin") {
|
||||||
panic!("the iOS target is only supported on macOS");
|
panic!("the iOS target is only supported on macOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,18 +194,6 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for host in build.flags.host.iter() {
|
|
||||||
if !build.config.host.contains(host) {
|
|
||||||
panic!("specified host `{}` is not in the ./configure list", host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for target in build.flags.target.iter() {
|
|
||||||
if !build.config.target.contains(target) {
|
|
||||||
panic!("specified target `{}` is not in the ./configure list",
|
|
||||||
target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let run = |cmd: &mut Command| {
|
let run = |cmd: &mut Command| {
|
||||||
cmd.output().map(|output| {
|
cmd.output().map(|output| {
|
||||||
String::from_utf8_lossy(&output.stdout)
|
String::from_utf8_lossy(&output.stdout)
|
||||||
@ -224,6 +207,6 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref s) = build.config.ccache {
|
if let Some(ref s) = build.config.ccache {
|
||||||
need_cmd(s.as_ref());
|
cmd_finder.must_have(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
use std::collections::{BTreeMap, HashSet, HashMap};
|
use std::collections::{BTreeMap, HashSet, HashMap};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
|
||||||
use check::{self, TestKind};
|
use check::{self, TestKind};
|
||||||
@ -104,10 +105,10 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.build("llvm", "src/llvm")
|
rules.build("llvm", "src/llvm")
|
||||||
.host(true)
|
.host(true)
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
if s.target == build.config.build {
|
if s.target == build.build {
|
||||||
Step::noop()
|
Step::noop()
|
||||||
} else {
|
} else {
|
||||||
s.target(&build.config.build)
|
s.target(&build.build)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.run(move |s| native::llvm(build, s.target));
|
.run(move |s| native::llvm(build, s.target));
|
||||||
@ -124,7 +125,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
Step::noop()
|
Step::noop()
|
||||||
} else {
|
} else {
|
||||||
s.name("librustc")
|
s.name("librustc")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.stage(s.stage - 1)
|
.stage(s.stage - 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -148,7 +149,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret
|
ret
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
@ -215,29 +216,29 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
let mut rule = rules.build(&krate, "path/to/nowhere");
|
let mut rule = rules.build(&krate, "path/to/nowhere");
|
||||||
rule.dep(move |s| {
|
rule.dep(move |s| {
|
||||||
if build.force_use_stage1(&s.compiler(), s.target) {
|
if build.force_use_stage1(&s.compiler(), s.target) {
|
||||||
s.host(&build.config.build).stage(1)
|
s.host(&build.build).stage(1)
|
||||||
} else if s.host == build.config.build {
|
} else if s.host == build.build {
|
||||||
s.name(dep)
|
s.name(dep)
|
||||||
} else {
|
} else {
|
||||||
s.host(&build.config.build)
|
s.host(&build.build)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.run(move |s| {
|
.run(move |s| {
|
||||||
if build.force_use_stage1(&s.compiler(), s.target) {
|
if build.force_use_stage1(&s.compiler(), s.target) {
|
||||||
link(build,
|
link(build,
|
||||||
&s.stage(1).host(&build.config.build).compiler(),
|
&s.stage(1).host(&build.build).compiler(),
|
||||||
&s.compiler(),
|
&s.compiler(),
|
||||||
s.target)
|
s.target)
|
||||||
} else if s.host == build.config.build {
|
} else if s.host == build.build {
|
||||||
link(build, &s.compiler(), &s.compiler(), s.target)
|
link(build, &s.compiler(), &s.compiler(), s.target)
|
||||||
} else {
|
} else {
|
||||||
link(build,
|
link(build,
|
||||||
&s.host(&build.config.build).compiler(),
|
&s.host(&build.build).compiler(),
|
||||||
&s.compiler(),
|
&s.compiler(),
|
||||||
s.target)
|
s.target)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return rule
|
rule
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to the `libstd`, `libtest`, and `librustc` rules above, except
|
// Similar to the `libstd`, `libtest`, and `librustc` rules above, except
|
||||||
@ -269,7 +270,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
for (krate, path, _default) in krates("std") {
|
for (krate, path, _default) in krates("std") {
|
||||||
rules.build(&krate.build_step, path)
|
rules.build(&krate.build_step, path)
|
||||||
.dep(|s| s.name("startup-objects"))
|
.dep(|s| s.name("startup-objects"))
|
||||||
.dep(move |s| s.name("rustc").host(&build.config.build).target(s.host))
|
.dep(move |s| s.name("rustc").host(&build.build).target(s.host))
|
||||||
.run(move |s| compile::std(build, s.target, &s.compiler()));
|
.run(move |s| compile::std(build, s.target, &s.compiler()));
|
||||||
}
|
}
|
||||||
for (krate, path, _default) in krates("test") {
|
for (krate, path, _default) in krates("test") {
|
||||||
@ -280,7 +281,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
for (krate, path, _default) in krates("rustc-main") {
|
for (krate, path, _default) in krates("rustc-main") {
|
||||||
rules.build(&krate.build_step, path)
|
rules.build(&krate.build_step, path)
|
||||||
.dep(|s| s.name("libtest-link"))
|
.dep(|s| s.name("libtest-link"))
|
||||||
.dep(move |s| s.name("llvm").host(&build.config.build).stage(0))
|
.dep(move |s| s.name("llvm").host(&build.build).stage(0))
|
||||||
.dep(|s| s.name("may-run-build-script"))
|
.dep(|s| s.name("may-run-build-script"))
|
||||||
.run(move |s| compile::rustc(build, s.target, &s.compiler()));
|
.run(move |s| compile::rustc(build, s.target, &s.compiler()));
|
||||||
}
|
}
|
||||||
@ -291,8 +292,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.build("may-run-build-script", "path/to/nowhere")
|
rules.build("may-run-build-script", "path/to/nowhere")
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
s.name("libstd-link")
|
s.name("libstd-link")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
});
|
});
|
||||||
rules.build("startup-objects", "src/rtstartup")
|
rules.build("startup-objects", "src/rtstartup")
|
||||||
.dep(|s| s.name("create-sysroot").target(s.host))
|
.dep(|s| s.name("create-sysroot").target(s.host))
|
||||||
@ -332,7 +333,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
"incremental");
|
"incremental");
|
||||||
}
|
}
|
||||||
|
|
||||||
if build.config.build.contains("msvc") {
|
if build.build.contains("msvc") {
|
||||||
// nothing to do for debuginfo tests
|
// nothing to do for debuginfo tests
|
||||||
} else {
|
} else {
|
||||||
rules.test("check-debuginfo-lldb", "src/test/debuginfo-lldb")
|
rules.test("check-debuginfo-lldb", "src/test/debuginfo-lldb")
|
||||||
@ -352,7 +353,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
"debuginfo-gdb", "debuginfo"));
|
"debuginfo-gdb", "debuginfo"));
|
||||||
let mut rule = rules.test("check-debuginfo", "src/test/debuginfo");
|
let mut rule = rules.test("check-debuginfo", "src/test/debuginfo");
|
||||||
rule.default(true);
|
rule.default(true);
|
||||||
if build.config.build.contains("apple") {
|
if build.build.contains("apple") {
|
||||||
rule.dep(|s| s.name("check-debuginfo-lldb"));
|
rule.dep(|s| s.name("check-debuginfo-lldb"));
|
||||||
} else {
|
} else {
|
||||||
rule.dep(|s| s.name("check-debuginfo-gdb"));
|
rule.dep(|s| s.name("check-debuginfo-gdb"));
|
||||||
@ -463,7 +464,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.test("check-linkchecker", "src/tools/linkchecker")
|
rules.test("check-linkchecker", "src/tools/linkchecker")
|
||||||
.dep(|s| s.name("tool-linkchecker").stage(0))
|
.dep(|s| s.name("tool-linkchecker").stage(0))
|
||||||
.dep(|s| s.name("default:doc"))
|
.dep(|s| s.name("default:doc"))
|
||||||
.default(true)
|
.default(build.config.docs)
|
||||||
.host(true)
|
.host(true)
|
||||||
.run(move |s| check::linkcheck(build, s.target));
|
.run(move |s| check::linkcheck(build, s.target));
|
||||||
rules.test("check-cargotest", "src/tools/cargotest")
|
rules.test("check-cargotest", "src/tools/cargotest")
|
||||||
@ -471,10 +472,14 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
.dep(|s| s.name("librustc"))
|
.dep(|s| s.name("librustc"))
|
||||||
.host(true)
|
.host(true)
|
||||||
.run(move |s| check::cargotest(build, s.stage, s.target));
|
.run(move |s| check::cargotest(build, s.stage, s.target));
|
||||||
rules.test("check-cargo", "cargo")
|
rules.test("check-cargo", "src/tools/cargo")
|
||||||
.dep(|s| s.name("tool-cargo"))
|
.dep(|s| s.name("tool-cargo"))
|
||||||
.host(true)
|
.host(true)
|
||||||
.run(move |s| check::cargo(build, s.stage, s.target));
|
.run(move |s| check::cargo(build, s.stage, s.target));
|
||||||
|
rules.test("check-rls", "src/tools/rls")
|
||||||
|
.dep(|s| s.name("tool-rls"))
|
||||||
|
.host(true)
|
||||||
|
.run(move |s| check::rls(build, s.stage, s.target));
|
||||||
rules.test("check-tidy", "src/tools/tidy")
|
rules.test("check-tidy", "src/tools/tidy")
|
||||||
.dep(|s| s.name("tool-tidy").stage(0))
|
.dep(|s| s.name("tool-tidy").stage(0))
|
||||||
.default(true)
|
.default(true)
|
||||||
@ -548,6 +553,10 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
.dep(|s| s.name("maybe-clean-tools"))
|
.dep(|s| s.name("maybe-clean-tools"))
|
||||||
.dep(|s| s.name("librustc-tool"))
|
.dep(|s| s.name("librustc-tool"))
|
||||||
.run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
|
.run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
|
||||||
|
rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
|
||||||
|
.dep(|s| s.name("maybe-clean-tools"))
|
||||||
|
.dep(|s| s.name("libstd-tool"))
|
||||||
|
.run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
|
||||||
rules.build("tool-tidy", "src/tools/tidy")
|
rules.build("tool-tidy", "src/tools/tidy")
|
||||||
.dep(|s| s.name("maybe-clean-tools"))
|
.dep(|s| s.name("maybe-clean-tools"))
|
||||||
.dep(|s| s.name("libstd-tool"))
|
.dep(|s| s.name("libstd-tool"))
|
||||||
@ -590,8 +599,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
// Cargo depends on procedural macros, which requires a full host
|
// Cargo depends on procedural macros, which requires a full host
|
||||||
// compiler to be available, so we need to depend on that.
|
// compiler to be available, so we need to depend on that.
|
||||||
s.name("librustc-link")
|
s.name("librustc-link")
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
})
|
})
|
||||||
.run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
|
.run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
|
||||||
rules.build("tool-rls", "src/tools/rls")
|
rules.build("tool-rls", "src/tools/rls")
|
||||||
@ -601,8 +610,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
// rls, like cargo, uses procedural macros
|
// rls, like cargo, uses procedural macros
|
||||||
s.name("librustc-link")
|
s.name("librustc-link")
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
})
|
})
|
||||||
.run(move |s| compile::tool(build, s.stage, s.target, "rls"));
|
.run(move |s| compile::tool(build, s.stage, s.target, "rls"));
|
||||||
|
|
||||||
@ -630,8 +639,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.doc("doc-book", "src/doc/book")
|
rules.doc("doc-book", "src/doc/book")
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
s.name("tool-rustbook")
|
s.name("tool-rustbook")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.stage(0)
|
.stage(0)
|
||||||
})
|
})
|
||||||
.default(build.config.docs)
|
.default(build.config.docs)
|
||||||
@ -639,8 +648,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.doc("doc-nomicon", "src/doc/nomicon")
|
rules.doc("doc-nomicon", "src/doc/nomicon")
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
s.name("tool-rustbook")
|
s.name("tool-rustbook")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.stage(0)
|
.stage(0)
|
||||||
})
|
})
|
||||||
.default(build.config.docs)
|
.default(build.config.docs)
|
||||||
@ -648,8 +657,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.doc("doc-reference", "src/doc/reference")
|
rules.doc("doc-reference", "src/doc/reference")
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
s.name("tool-rustbook")
|
s.name("tool-rustbook")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.stage(0)
|
.stage(0)
|
||||||
})
|
})
|
||||||
.default(build.config.docs)
|
.default(build.config.docs)
|
||||||
@ -657,27 +666,42 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
rules.doc("doc-unstable-book", "src/doc/unstable-book")
|
rules.doc("doc-unstable-book", "src/doc/unstable-book")
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
s.name("tool-rustbook")
|
s.name("tool-rustbook")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.stage(0)
|
.stage(0)
|
||||||
})
|
})
|
||||||
|
.dep(move |s| s.name("doc-unstable-book-gen"))
|
||||||
.default(build.config.docs)
|
.default(build.config.docs)
|
||||||
.run(move |s| doc::rustbook(build, s.target, "unstable-book"));
|
.run(move |s| doc::rustbook_src(build,
|
||||||
|
s.target,
|
||||||
|
"unstable-book",
|
||||||
|
&build.md_doc_out(s.target)));
|
||||||
rules.doc("doc-standalone", "src/doc")
|
rules.doc("doc-standalone", "src/doc")
|
||||||
.dep(move |s| {
|
.dep(move |s| {
|
||||||
s.name("rustc")
|
s.name("rustc")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.stage(0)
|
.stage(0)
|
||||||
})
|
})
|
||||||
.default(build.config.docs)
|
.default(build.config.docs)
|
||||||
.run(move |s| doc::standalone(build, s.target));
|
.run(move |s| doc::standalone(build, s.target));
|
||||||
rules.doc("doc-error-index", "src/tools/error_index_generator")
|
rules.doc("doc-error-index", "src/tools/error_index_generator")
|
||||||
.dep(move |s| s.name("tool-error-index").target(&build.config.build).stage(0))
|
.dep(move |s| s.name("tool-error-index").target(&build.build).stage(0))
|
||||||
.dep(move |s| s.name("librustc-link"))
|
.dep(move |s| s.name("librustc-link"))
|
||||||
.default(build.config.docs)
|
.default(build.config.docs)
|
||||||
.host(true)
|
.host(true)
|
||||||
.run(move |s| doc::error_index(build, s.target));
|
.run(move |s| doc::error_index(build, s.target));
|
||||||
|
rules.doc("doc-unstable-book-gen", "src/tools/unstable-book-gen")
|
||||||
|
.dep(move |s| {
|
||||||
|
s.name("tool-unstable-book-gen")
|
||||||
|
.host(&build.build)
|
||||||
|
.target(&build.build)
|
||||||
|
.stage(0)
|
||||||
|
})
|
||||||
|
.dep(move |s| s.name("libstd-link"))
|
||||||
|
.default(build.config.docs)
|
||||||
|
.host(true)
|
||||||
|
.run(move |s| doc::unstable_book_gen(build, s.target));
|
||||||
for (krate, path, default) in krates("std") {
|
for (krate, path, default) in krates("std") {
|
||||||
rules.doc(&krate.doc_step, path)
|
rules.doc(&krate.doc_step, path)
|
||||||
.dep(|s| s.name("libstd-link"))
|
.dep(|s| s.name("libstd-link"))
|
||||||
@ -705,7 +729,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Distribution targets
|
// Distribution targets
|
||||||
rules.dist("dist-rustc", "src/librustc")
|
rules.dist("dist-rustc", "src/librustc")
|
||||||
.dep(move |s| s.name("rustc").host(&build.config.build))
|
.dep(move |s| s.name("rustc").host(&build.build))
|
||||||
.host(true)
|
.host(true)
|
||||||
.only_host_build(true)
|
.only_host_build(true)
|
||||||
.default(true)
|
.default(true)
|
||||||
@ -790,7 +814,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
.host(true)
|
.host(true)
|
||||||
.only_build(true)
|
.only_build(true)
|
||||||
.only_host_build(true)
|
.only_host_build(true)
|
||||||
.dep(move |s| s.name("tool-build-manifest").target(&build.config.build).stage(0))
|
.dep(move |s| s.name("tool-build-manifest").target(&build.build).stage(0))
|
||||||
.run(move |_| dist::hash_and_sign(build));
|
.run(move |_| dist::hash_and_sign(build));
|
||||||
|
|
||||||
rules.install("install-docs", "src/doc")
|
rules.install("install-docs", "src/doc")
|
||||||
@ -839,8 +863,8 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
|||||||
/// Helper to depend on a stage0 build-only rust-installer tool.
|
/// Helper to depend on a stage0 build-only rust-installer tool.
|
||||||
fn tool_rust_installer<'a>(build: &'a Build, step: &Step<'a>) -> Step<'a> {
|
fn tool_rust_installer<'a>(build: &'a Build, step: &Step<'a>) -> Step<'a> {
|
||||||
step.name("tool-rust-installer")
|
step.name("tool-rust-installer")
|
||||||
.host(&build.config.build)
|
.host(&build.build)
|
||||||
.target(&build.config.build)
|
.target(&build.build)
|
||||||
.stage(0)
|
.stage(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1036,8 +1060,8 @@ impl<'a> Rules<'a> {
|
|||||||
build: build,
|
build: build,
|
||||||
sbuild: Step {
|
sbuild: Step {
|
||||||
stage: build.flags.stage.unwrap_or(2),
|
stage: build.flags.stage.unwrap_or(2),
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
name: "",
|
name: "",
|
||||||
},
|
},
|
||||||
rules: BTreeMap::new(),
|
rules: BTreeMap::new(),
|
||||||
@ -1187,25 +1211,26 @@ invalid rule dependency graph detected, was a rule added and maybe typo'd?
|
|||||||
if paths.len() == 0 && rule.default {
|
if paths.len() == 0 && rule.default {
|
||||||
Some((rule, 0))
|
Some((rule, 0))
|
||||||
} else {
|
} else {
|
||||||
paths.iter().position(|path| path.ends_with(rule.path))
|
paths.iter()
|
||||||
|
.position(|path| path.ends_with(rule.path))
|
||||||
.map(|priority| (rule, priority))
|
.map(|priority| (rule, priority))
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
if rules.is_empty() &&
|
||||||
|
!paths.get(0).unwrap_or(&PathBuf::new())
|
||||||
|
.ends_with("nonexistent/path/to/trigger/cargo/metadata") {
|
||||||
|
println!("\nNothing to run...\n");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
rules.sort_by_key(|&(_, priority)| priority);
|
rules.sort_by_key(|&(_, priority)| priority);
|
||||||
|
|
||||||
rules.into_iter().flat_map(|(rule, _)| {
|
rules.into_iter().flat_map(|(rule, _)| {
|
||||||
let hosts = if rule.only_host_build || rule.only_build {
|
let hosts = if rule.only_host_build || rule.only_build {
|
||||||
&self.build.config.host[..1]
|
self.build.build_slice()
|
||||||
} else if self.build.flags.host.len() > 0 {
|
|
||||||
&self.build.flags.host
|
|
||||||
} else {
|
} else {
|
||||||
&self.build.config.host
|
&self.build.hosts
|
||||||
};
|
|
||||||
let targets = if self.build.flags.target.len() > 0 {
|
|
||||||
&self.build.flags.target
|
|
||||||
} else {
|
|
||||||
&self.build.config.target
|
|
||||||
};
|
};
|
||||||
// Determine the actual targets participating in this rule.
|
// Determine the actual targets participating in this rule.
|
||||||
// NOTE: We should keep the full projection from build triple to
|
// NOTE: We should keep the full projection from build triple to
|
||||||
@ -1214,19 +1239,18 @@ invalid rule dependency graph detected, was a rule added and maybe typo'd?
|
|||||||
// the original non-shadowed hosts array is used below.
|
// the original non-shadowed hosts array is used below.
|
||||||
let arr = if rule.host {
|
let arr = if rule.host {
|
||||||
// If --target was specified but --host wasn't specified,
|
// If --target was specified but --host wasn't specified,
|
||||||
// don't run any host-only tests. Also, respect any `--host`
|
// don't run any host-only tests.
|
||||||
// overrides as done for `hosts`.
|
|
||||||
if self.build.flags.host.len() > 0 {
|
if self.build.flags.host.len() > 0 {
|
||||||
&self.build.flags.host[..]
|
&self.build.hosts
|
||||||
} else if self.build.flags.target.len() > 0 {
|
} else if self.build.flags.target.len() > 0 {
|
||||||
&[]
|
&[]
|
||||||
} else if rule.only_build {
|
} else if rule.only_build {
|
||||||
&self.build.config.host[..1]
|
self.build.build_slice()
|
||||||
} else {
|
} else {
|
||||||
&self.build.config.host[..]
|
&self.build.hosts
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targets
|
&self.build.targets
|
||||||
};
|
};
|
||||||
|
|
||||||
hosts.iter().flat_map(move |host| {
|
hosts.iter().flat_map(move |host| {
|
||||||
@ -1304,7 +1328,7 @@ invalid rule dependency graph detected, was a rule added and maybe typo'd?
|
|||||||
for idx in 0..nodes.len() {
|
for idx in 0..nodes.len() {
|
||||||
self.topo_sort(idx, &idx_to_node, &edges, &mut visited, &mut order);
|
self.topo_sort(idx, &idx_to_node, &edges, &mut visited, &mut order);
|
||||||
}
|
}
|
||||||
return order
|
order
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the dependency graph rooted at `step`.
|
/// Builds the dependency graph rooted at `step`.
|
||||||
@ -1343,7 +1367,7 @@ invalid rule dependency graph detected, was a rule added and maybe typo'd?
|
|||||||
}
|
}
|
||||||
|
|
||||||
edges.entry(idx).or_insert(HashSet::new()).extend(deps);
|
edges.entry(idx).or_insert(HashSet::new()).extend(deps);
|
||||||
return idx
|
idx
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a dependency graph with a finished list of `nodes`, fill out more
|
/// Given a dependency graph with a finished list of `nodes`, fill out more
|
||||||
@ -1404,13 +1428,20 @@ mod tests {
|
|||||||
fn build(args: &[&str],
|
fn build(args: &[&str],
|
||||||
extra_host: &[&str],
|
extra_host: &[&str],
|
||||||
extra_target: &[&str]) -> Build {
|
extra_target: &[&str]) -> Build {
|
||||||
|
build_(args, extra_host, extra_target, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_(args: &[&str],
|
||||||
|
extra_host: &[&str],
|
||||||
|
extra_target: &[&str],
|
||||||
|
docs: bool) -> Build {
|
||||||
let mut args = args.iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
let mut args = args.iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||||
args.push("--build".to_string());
|
args.push("--build".to_string());
|
||||||
args.push("A".to_string());
|
args.push("A".to_string());
|
||||||
let flags = Flags::parse(&args);
|
let flags = Flags::parse(&args);
|
||||||
|
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.docs = true;
|
config.docs = docs;
|
||||||
config.build = "A".to_string();
|
config.build = "A".to_string();
|
||||||
config.host = vec![config.build.clone()];
|
config.host = vec![config.build.clone()];
|
||||||
config.host.extend(extra_host.iter().map(|s| s.to_string()));
|
config.host.extend(extra_host.iter().map(|s| s.to_string()));
|
||||||
@ -1465,8 +1496,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(plan.contains(&step.name("dist-docs")));
|
assert!(plan.contains(&step.name("dist-docs")));
|
||||||
@ -1488,8 +1519,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(plan.contains(&step.name("dist-docs")));
|
assert!(plan.contains(&step.name("dist-docs")));
|
||||||
@ -1516,8 +1547,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!plan.iter().any(|s| s.host == "B"));
|
assert!(!plan.iter().any(|s| s.host == "B"));
|
||||||
@ -1546,8 +1577,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!plan.iter().any(|s| s.host == "B"));
|
assert!(!plan.iter().any(|s| s.host == "B"));
|
||||||
@ -1583,8 +1614,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!plan.iter().any(|s| s.target == "A"));
|
assert!(!plan.iter().any(|s| s.target == "A"));
|
||||||
@ -1610,8 +1641,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!plan.iter().any(|s| s.target == "A"));
|
assert!(!plan.iter().any(|s| s.target == "A"));
|
||||||
@ -1654,8 +1685,8 @@ mod tests {
|
|||||||
let step = super::Step {
|
let step = super::Step {
|
||||||
name: "",
|
name: "",
|
||||||
stage: 2,
|
stage: 2,
|
||||||
host: &build.config.build,
|
host: &build.build,
|
||||||
target: &build.config.build,
|
target: &build.build,
|
||||||
};
|
};
|
||||||
|
|
||||||
// rustc built for all for of (A, B) x (A, B)
|
// rustc built for all for of (A, B) x (A, B)
|
||||||
@ -1765,4 +1796,22 @@ mod tests {
|
|||||||
assert!(!plan.iter().any(|s| s.name.contains("tidy")));
|
assert!(!plan.iter().any(|s| s.name.contains("tidy")));
|
||||||
assert!(plan.iter().any(|s| s.name.contains("valgrind")));
|
assert!(plan.iter().any(|s| s.name.contains("valgrind")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_disable_docs() {
|
||||||
|
let build = build_(&["test"], &[], &[], false);
|
||||||
|
let rules = super::build_rules(&build);
|
||||||
|
let plan = rules.plan();
|
||||||
|
println!("rules: {:#?}", plan);
|
||||||
|
assert!(!plan.iter().any(|s| {
|
||||||
|
s.name.contains("doc-") || s.name.contains("default:doc")
|
||||||
|
}));
|
||||||
|
// none of the dependencies should be a doc rule either
|
||||||
|
assert!(!plan.iter().any(|s| {
|
||||||
|
rules.rules[s.name].deps.iter().any(|dep| {
|
||||||
|
let dep = dep(&rules.sbuild.name(s.name));
|
||||||
|
dep.name.contains("doc-") || dep.name.contains("default:doc")
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
//! not a lot of interesting happenings here unfortunately.
|
//! not a lot of interesting happenings here unfortunately.
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@ -32,16 +31,9 @@ pub fn staticlib(name: &str, target: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies a file from `src` to `dst`, attempting to use hard links and then
|
/// Copies a file from `src` to `dst`
|
||||||
/// falling back to an actually filesystem copy if necessary.
|
|
||||||
pub fn copy(src: &Path, dst: &Path) {
|
pub fn copy(src: &Path, dst: &Path) {
|
||||||
// A call to `hard_link` will fail if `dst` exists, so remove it if it
|
|
||||||
// already exists so we can try to help `hard_link` succeed.
|
|
||||||
let _ = fs::remove_file(&dst);
|
let _ = fs::remove_file(&dst);
|
||||||
|
|
||||||
// Attempt to "easy copy" by creating a hard link (symlinks don't work on
|
|
||||||
// windows), but if that fails just fall back to a slow `copy` operation.
|
|
||||||
// let res = fs::hard_link(src, dst);
|
|
||||||
let res = fs::copy(src, dst);
|
let res = fs::copy(src, dst);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
panic!("failed to copy `{}` to `{}`: {}", src.display(),
|
panic!("failed to copy `{}` to `{}`: {}", src.display(),
|
||||||
@ -149,8 +141,7 @@ pub fn dylib_path_var() -> &'static str {
|
|||||||
/// Parses the `dylib_path_var()` environment variable, returning a list of
|
/// Parses the `dylib_path_var()` environment variable, returning a list of
|
||||||
/// paths that are members of this lookup path.
|
/// paths that are members of this lookup path.
|
||||||
pub fn dylib_path() -> Vec<PathBuf> {
|
pub fn dylib_path() -> Vec<PathBuf> {
|
||||||
env::split_paths(&env::var_os(dylib_path_var()).unwrap_or(OsString::new()))
|
env::split_paths(&env::var_os(dylib_path_var()).unwrap_or_default()).collect()
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `push` all components to `buf`. On windows, append `.exe` to the last component.
|
/// `push` all components to `buf`. On windows, append `.exe` to the last component.
|
||||||
@ -422,4 +413,4 @@ impl CiEnv {
|
|||||||
cmd.env("TERM", "xterm").args(&["--color", "always"]);
|
cmd.env("TERM", "xterm").args(&["--color", "always"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,10 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) -> Result<NativeLibBoiler
|
|||||||
),
|
),
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
};
|
};
|
||||||
native_lib_boilerplate("compiler-rt", sanitizer_name, &link_name, search_path)
|
native_lib_boilerplate("libcompiler_builtins/compiler-rt",
|
||||||
|
sanitizer_name,
|
||||||
|
&link_name,
|
||||||
|
search_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool {
|
fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool {
|
||||||
|
@ -1,31 +1,15 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
COPY scripts/android-base-apt-get.sh /scripts/
|
||||||
apt-get install -y --no-install-recommends \
|
RUN sh /scripts/android-base-apt-get.sh
|
||||||
ca-certificates \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
pkg-config \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
unzip \
|
|
||||||
xz-utils
|
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
# ndk
|
|
||||||
COPY scripts/android-ndk.sh /scripts/
|
COPY scripts/android-ndk.sh /scripts/
|
||||||
RUN . /scripts/android-ndk.sh && \
|
RUN . /scripts/android-ndk.sh && \
|
||||||
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm 9
|
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm 9
|
||||||
|
|
||||||
# sdk
|
|
||||||
RUN dpkg --add-architecture i386 && \
|
RUN dpkg --add-architecture i386 && \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
@ -39,7 +23,6 @@ COPY scripts/android-sdk.sh /scripts/
|
|||||||
RUN . /scripts/android-sdk.sh && \
|
RUN . /scripts/android-sdk.sh && \
|
||||||
download_and_create_avd tools_r25.2.5-linux.zip armeabi-v7a 18
|
download_and_create_avd tools_r25.2.5-linux.zip armeabi-v7a 18
|
||||||
|
|
||||||
# env
|
|
||||||
ENV PATH=$PATH:/android/sdk/tools
|
ENV PATH=$PATH:/android/sdk/tools
|
||||||
ENV PATH=$PATH:/android/sdk/platform-tools
|
ENV PATH=$PATH:/android/sdk/platform-tools
|
||||||
|
|
||||||
@ -51,10 +34,8 @@ ENV RUST_CONFIGURE_ARGS \
|
|||||||
|
|
||||||
ENV SCRIPT python2.7 ../x.py test --target $TARGETS
|
ENV SCRIPT python2.7 ../x.py test --target $TARGETS
|
||||||
|
|
||||||
# sccache
|
|
||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
COPY scripts/android-start-emulator.sh /scripts/
|
COPY scripts/android-start-emulator.sh /scripts/
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/scripts/android-start-emulator.sh"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/scripts/android-start-emulator.sh"]
|
||||||
|
@ -73,13 +73,12 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
|
|||||||
# TODO: What is this?!
|
# TODO: What is this?!
|
||||||
RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
|
RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
|
39
src/ci/docker/asmjs/Dockerfile
Normal file
39
src/ci/docker/asmjs/Dockerfile
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
g++ \
|
||||||
|
make \
|
||||||
|
file \
|
||||||
|
curl \
|
||||||
|
ca-certificates \
|
||||||
|
python \
|
||||||
|
git \
|
||||||
|
cmake \
|
||||||
|
sudo \
|
||||||
|
gdb \
|
||||||
|
xz-utils
|
||||||
|
|
||||||
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
|
COPY scripts/emscripten.sh /scripts/
|
||||||
|
RUN bash /scripts/emscripten.sh
|
||||||
|
|
||||||
|
ENV PATH=$PATH:/emsdk-portable
|
||||||
|
ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
|
||||||
|
ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
|
||||||
|
ENV PATH=$PATH:/emsdk-portable/node/4.1.1_64bit/bin/
|
||||||
|
ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
|
||||||
|
ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
|
||||||
|
ENV EM_CONFIG=/emsdk-portable/.emscripten
|
||||||
|
|
||||||
|
ENV TARGETS=asmjs-unknown-emscripten
|
||||||
|
|
||||||
|
ENV RUST_CONFIGURE_ARGS --target=$TARGETS
|
||||||
|
|
||||||
|
ENV SCRIPT python2.7 ../x.py test --target $TARGETS
|
||||||
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
@ -21,7 +21,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libssl-dev \
|
libssl-dev \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
@ -68,5 +67,4 @@ ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
|
|||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
@ -1,31 +1,15 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
COPY scripts/android-base-apt-get.sh /scripts/
|
||||||
apt-get install -y --no-install-recommends \
|
RUN sh /scripts/android-base-apt-get.sh
|
||||||
ca-certificates \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
pkg-config \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
unzip \
|
|
||||||
xz-utils
|
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
# ndk
|
|
||||||
COPY scripts/android-ndk.sh /scripts/
|
COPY scripts/android-ndk.sh /scripts/
|
||||||
RUN . /scripts/android-ndk.sh && \
|
RUN . /scripts/android-ndk.sh && \
|
||||||
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm64 21
|
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm64 21
|
||||||
|
|
||||||
# env
|
|
||||||
ENV PATH=$PATH:/android/ndk/arm64-21/bin
|
ENV PATH=$PATH:/android/ndk/arm64-21/bin
|
||||||
|
|
||||||
ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/
|
ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/
|
||||||
@ -42,9 +26,7 @@ ENV RUST_CONFIGURE_ARGS \
|
|||||||
|
|
||||||
ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
|
ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
|
||||||
|
|
||||||
# sccache
|
|
||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
@ -1,26 +1,11 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
COPY scripts/android-base-apt-get.sh /scripts/
|
||||||
apt-get install -y --no-install-recommends \
|
RUN sh /scripts/android-base-apt-get.sh
|
||||||
ca-certificates \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
pkg-config \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
unzip \
|
|
||||||
xz-utils
|
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
# ndk
|
|
||||||
COPY scripts/android-ndk.sh /scripts/
|
COPY scripts/android-ndk.sh /scripts/
|
||||||
RUN . /scripts/android-ndk.sh && \
|
RUN . /scripts/android-ndk.sh && \
|
||||||
download_ndk android-ndk-r13b-linux-x86_64.zip && \
|
download_ndk android-ndk-r13b-linux-x86_64.zip && \
|
||||||
@ -31,7 +16,6 @@ RUN . /scripts/android-ndk.sh && \
|
|||||||
RUN chmod 777 /android/ndk && \
|
RUN chmod 777 /android/ndk && \
|
||||||
ln -s /android/ndk/arm-21 /android/ndk/arm
|
ln -s /android/ndk/arm-21 /android/ndk/arm
|
||||||
|
|
||||||
# env
|
|
||||||
ENV PATH=$PATH:/android/ndk/arm-9/bin
|
ENV PATH=$PATH:/android/ndk/arm-9/bin
|
||||||
|
|
||||||
ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/
|
ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/
|
||||||
@ -60,9 +44,7 @@ ENV SCRIPT \
|
|||||||
ln -s /android/ndk/arm-9 /android/ndk/arm && \
|
ln -s /android/ndk/arm-9 /android/ndk/arm && \
|
||||||
python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
|
python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
|
||||||
|
|
||||||
# sccache
|
|
||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
@ -1,26 +1,11 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
COPY scripts/android-base-apt-get.sh /scripts/
|
||||||
apt-get install -y --no-install-recommends \
|
RUN sh /scripts/android-base-apt-get.sh
|
||||||
ca-certificates \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
pkg-config \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
unzip \
|
|
||||||
xz-utils
|
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
# ndk
|
|
||||||
COPY scripts/android-ndk.sh /scripts/
|
COPY scripts/android-ndk.sh /scripts/
|
||||||
RUN . /scripts/android-ndk.sh && \
|
RUN . /scripts/android-ndk.sh && \
|
||||||
download_ndk android-ndk-r13b-linux-x86_64.zip && \
|
download_ndk android-ndk-r13b-linux-x86_64.zip && \
|
||||||
@ -31,7 +16,6 @@ RUN . /scripts/android-ndk.sh && \
|
|||||||
RUN chmod 777 /android/ndk && \
|
RUN chmod 777 /android/ndk && \
|
||||||
ln -s /android/ndk/x86-21 /android/ndk/x86
|
ln -s /android/ndk/x86-21 /android/ndk/x86
|
||||||
|
|
||||||
# env
|
|
||||||
ENV PATH=$PATH:/android/ndk/x86-9/bin
|
ENV PATH=$PATH:/android/ndk/x86-9/bin
|
||||||
|
|
||||||
ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/
|
ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/
|
||||||
@ -60,9 +44,7 @@ ENV SCRIPT \
|
|||||||
ln -s /android/ndk/x86-9 /android/ndk/x86 && \
|
ln -s /android/ndk/x86-9 /android/ndk/x86 && \
|
||||||
python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
|
python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
|
||||||
|
|
||||||
# sccache
|
|
||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
@ -1,31 +1,15 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
COPY scripts/android-base-apt-get.sh /scripts/
|
||||||
apt-get install -y --no-install-recommends \
|
RUN sh /scripts/android-base-apt-get.sh
|
||||||
ca-certificates \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
pkg-config \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
unzip \
|
|
||||||
xz-utils
|
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
# ndk
|
|
||||||
COPY scripts/android-ndk.sh /scripts/
|
COPY scripts/android-ndk.sh /scripts/
|
||||||
RUN . /scripts/android-ndk.sh && \
|
RUN . /scripts/android-ndk.sh && \
|
||||||
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip x86_64 21
|
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip x86_64 21
|
||||||
|
|
||||||
# env
|
|
||||||
ENV PATH=$PATH:/android/ndk/x86_64-21/bin
|
ENV PATH=$PATH:/android/ndk/x86_64-21/bin
|
||||||
|
|
||||||
ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/
|
ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/
|
||||||
@ -42,9 +26,7 @@ ENV RUST_CONFIGURE_ARGS \
|
|||||||
|
|
||||||
ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
|
ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
|
||||||
|
|
||||||
# sccache
|
|
||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
42
src/ci/docker/disabled/wasm32-exp/Dockerfile
Normal file
42
src/ci/docker/disabled/wasm32-exp/Dockerfile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
g++ \
|
||||||
|
make \
|
||||||
|
file \
|
||||||
|
curl \
|
||||||
|
ca-certificates \
|
||||||
|
python \
|
||||||
|
git \
|
||||||
|
cmake \
|
||||||
|
sudo \
|
||||||
|
gdb \
|
||||||
|
xz-utils \
|
||||||
|
jq \
|
||||||
|
bzip2
|
||||||
|
|
||||||
|
# dumb-init
|
||||||
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
|
# emscripten
|
||||||
|
COPY scripts/emscripten-wasm.sh /scripts/
|
||||||
|
COPY disabled/wasm32-exp/node.sh /usr/local/bin/node
|
||||||
|
RUN bash /scripts/emscripten-wasm.sh
|
||||||
|
|
||||||
|
# cache
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
|
# env
|
||||||
|
ENV PATH=/wasm-install/emscripten:/wasm-install/bin:$PATH
|
||||||
|
ENV EM_CONFIG=/root/.emscripten
|
||||||
|
|
||||||
|
ENV TARGETS=wasm32-experimental-emscripten
|
||||||
|
|
||||||
|
ENV RUST_CONFIGURE_ARGS --target=$TARGETS --experimental-targets=WebAssembly
|
||||||
|
|
||||||
|
ENV SCRIPT python2.7 ../x.py test --target $TARGETS
|
||||||
|
|
||||||
|
# init
|
||||||
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
18
src/ci/docker/disabled/wasm32-exp/node.sh
Executable file
18
src/ci/docker/disabled/wasm32-exp/node.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
path="$(dirname $1)"
|
||||||
|
file="$(basename $1)"
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
cd "$path"
|
||||||
|
exec /node-v8.0.0-linux-x64/bin/node "$file" "$@"
|
40
src/ci/docker/disabled/wasm32/Dockerfile
Normal file
40
src/ci/docker/disabled/wasm32/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
g++ \
|
||||||
|
make \
|
||||||
|
file \
|
||||||
|
curl \
|
||||||
|
ca-certificates \
|
||||||
|
python \
|
||||||
|
git \
|
||||||
|
cmake \
|
||||||
|
sudo \
|
||||||
|
gdb \
|
||||||
|
xz-utils
|
||||||
|
|
||||||
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
|
# emscripten
|
||||||
|
COPY scripts/emscripten.sh /scripts/
|
||||||
|
RUN bash /scripts/emscripten.sh
|
||||||
|
COPY disabled/wasm32/node.sh /usr/local/bin/node
|
||||||
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
|
ENV PATH=$PATH:/emsdk-portable
|
||||||
|
ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
|
||||||
|
ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
|
||||||
|
ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
|
||||||
|
ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
|
||||||
|
ENV EM_CONFIG=/emsdk-portable/.emscripten
|
||||||
|
|
||||||
|
ENV TARGETS=wasm32-unknown-emscripten
|
||||||
|
|
||||||
|
ENV RUST_CONFIGURE_ARGS --target=$TARGETS
|
||||||
|
|
||||||
|
ENV SCRIPT python2.7 ../x.py test --target $TARGETS
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
18
src/ci/docker/disabled/wasm32/node.sh
Executable file
18
src/ci/docker/disabled/wasm32/node.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
path="$(dirname $1)"
|
||||||
|
file="$(basename $1)"
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
cd "$path"
|
||||||
|
exec /node-v8.0.0-linux-x64/bin/node "$file" "$@"
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -61,9 +26,8 @@ RUN ./build-toolchains.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
|
ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
|
||||||
|
|
||||||
|
@ -1,22 +1,8 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
COPY scripts/android-base-apt-get.sh /scripts/
|
||||||
apt-get install -y --no-install-recommends \
|
RUN sh /scripts/android-base-apt-get.sh
|
||||||
ca-certificates \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
pkg-config \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
unzip \
|
|
||||||
xz-utils
|
|
||||||
|
|
||||||
# dumb-init
|
|
||||||
COPY scripts/dumb-init.sh /scripts/
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
RUN sh /scripts/dumb-init.sh
|
RUN sh /scripts/dumb-init.sh
|
||||||
|
|
||||||
@ -48,9 +34,7 @@ ENV RUST_CONFIGURE_ARGS \
|
|||||||
|
|
||||||
ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
|
ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
|
||||||
|
|
||||||
# cache
|
|
||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
# init
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -61,9 +26,8 @@ RUN ./build-toolchains.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
|
ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
|
||||||
|
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -61,9 +26,8 @@ RUN ./build-toolchains.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabihf/bin
|
ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabihf/bin
|
||||||
|
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -61,9 +26,8 @@ RUN ./build-toolchains.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/armv7-unknown-linux-gnueabihf/bin
|
ENV PATH=$PATH:/x-tools/armv7-unknown-linux-gnueabihf/bin
|
||||||
|
|
||||||
|
@ -24,14 +24,13 @@ WORKDIR /tmp
|
|||||||
COPY dist-fuchsia/shared.sh dist-fuchsia/build-toolchain.sh dist-fuchsia/compiler-rt-dso-handle.patch /tmp/
|
COPY dist-fuchsia/shared.sh dist-fuchsia/build-toolchain.sh dist-fuchsia/compiler-rt-dso-handle.patch /tmp/
|
||||||
RUN /tmp/build-toolchain.sh
|
RUN /tmp/build-toolchain.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \
|
AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \
|
||||||
|
@ -20,14 +20,13 @@ WORKDIR /build/
|
|||||||
COPY dist-i586-gnu-i686-musl/musl-libunwind-patch.patch dist-i586-gnu-i686-musl/build-musl.sh /build/
|
COPY dist-i586-gnu-i686-musl/musl-libunwind-patch.patch dist-i586-gnu-i686-musl/build-musl.sh /build/
|
||||||
RUN sh /build/build-musl.sh && rm -rf /build
|
RUN sh /build/build-musl.sh && rm -rf /build
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
--target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
|
--target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
|
||||||
|
@ -19,14 +19,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
COPY dist-i686-freebsd/build-toolchain.sh /tmp/
|
COPY dist-i686-freebsd/build-toolchain.sh /tmp/
|
||||||
RUN /tmp/build-toolchain.sh i686
|
RUN /tmp/build-toolchain.sh i686
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
AR_i686_unknown_freebsd=i686-unknown-freebsd10-ar \
|
AR_i686_unknown_freebsd=i686-unknown-freebsd10-ar \
|
||||||
|
@ -81,16 +81,16 @@ RUN curl -Lo /rustroot/dumb-init \
|
|||||||
chmod +x /rustroot/dumb-init
|
chmod +x /rustroot/dumb-init
|
||||||
ENTRYPOINT ["/rustroot/dumb-init", "--"]
|
ENTRYPOINT ["/rustroot/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV HOSTS=i686-unknown-linux-gnu
|
ENV HOSTS=i686-unknown-linux-gnu
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
--host=$HOSTS \
|
--host=$HOSTS \
|
||||||
--enable-extended \
|
--enable-extended \
|
||||||
--enable-sanitizers
|
--enable-sanitizers \
|
||||||
|
--enable-profiler
|
||||||
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
|
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
|
||||||
|
|
||||||
# This is the only builder which will create source tarballs
|
# This is the only builder which will create source tarballs
|
||||||
|
@ -16,13 +16,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libssl-dev \
|
libssl-dev \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV HOSTS=mips-unknown-linux-gnu
|
ENV HOSTS=mips-unknown-linux-gnu
|
||||||
|
@ -16,13 +16,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libssl-dev \
|
libssl-dev \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV HOSTS=mips64-unknown-linux-gnuabi64
|
ENV HOSTS=mips64-unknown-linux-gnuabi64
|
||||||
|
@ -16,13 +16,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libssl-dev \
|
libssl-dev \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV HOSTS=mips64el-unknown-linux-gnuabi64
|
ENV HOSTS=mips64el-unknown-linux-gnuabi64
|
||||||
|
@ -16,13 +16,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libssl-dev \
|
libssl-dev \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV HOSTS=mipsel-unknown-linux-gnu
|
ENV HOSTS=mipsel-unknown-linux-gnu
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -62,9 +27,8 @@ RUN ./build-powerpc-toolchain.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
|
ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
|
||||||
|
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -62,9 +27,8 @@ RUN ./build-powerpc64-toolchain.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
|
ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
|
||||||
|
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -62,9 +27,8 @@ RUN apt-get install -y --no-install-recommends rpm2cpio cpio
|
|||||||
COPY dist-powerpc64le-linux/shared.sh dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /tmp/
|
COPY dist-powerpc64le-linux/shared.sh dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /tmp/
|
||||||
RUN ./build-powerpc64le-toolchain.sh
|
RUN ./build-powerpc64le-toolchain.sh
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
AR_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-ar \
|
AR_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-ar \
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -62,9 +27,8 @@ RUN ./build-s390x-toolchain.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin
|
ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin
|
||||||
|
|
||||||
|
@ -19,14 +19,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
COPY dist-x86_64-freebsd/build-toolchain.sh /tmp/
|
COPY dist-x86_64-freebsd/build-toolchain.sh /tmp/
|
||||||
RUN /tmp/build-toolchain.sh x86_64
|
RUN /tmp/build-toolchain.sh x86_64
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-ar \
|
AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-ar \
|
||||||
|
@ -81,16 +81,16 @@ RUN curl -Lo /rustroot/dumb-init \
|
|||||||
chmod +x /rustroot/dumb-init
|
chmod +x /rustroot/dumb-init
|
||||||
ENTRYPOINT ["/rustroot/dumb-init", "--"]
|
ENTRYPOINT ["/rustroot/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV HOSTS=x86_64-unknown-linux-gnu
|
ENV HOSTS=x86_64-unknown-linux-gnu
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
--host=$HOSTS \
|
--host=$HOSTS \
|
||||||
--enable-extended \
|
--enable-extended \
|
||||||
--enable-sanitizers
|
--enable-sanitizers \
|
||||||
|
--enable-profiler
|
||||||
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
|
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
|
||||||
|
|
||||||
# This is the only builder which will create source tarballs
|
# This is the only builder which will create source tarballs
|
||||||
|
@ -20,14 +20,13 @@ WORKDIR /build/
|
|||||||
COPY dist-x86_64-musl/build-musl.sh /build/
|
COPY dist-x86_64-musl/build-musl.sh /build/
|
||||||
RUN sh /build/build-musl.sh && rm -rf /build
|
RUN sh /build/build-musl.sh && rm -rf /build
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
--target=x86_64-unknown-linux-musl \
|
--target=x86_64-unknown-linux-musl \
|
||||||
|
@ -1,58 +1,23 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
COPY scripts/cross-apt-packages.sh /scripts/
|
||||||
automake \
|
RUN sh /scripts/cross-apt-packages.sh
|
||||||
bison \
|
|
||||||
bzip2 \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
ca-certificates \
|
RUN sh /scripts/dumb-init.sh
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
flex \
|
|
||||||
g++ \
|
|
||||||
gawk \
|
|
||||||
gdb \
|
|
||||||
git \
|
|
||||||
gperf \
|
|
||||||
help2man \
|
|
||||||
libncurses-dev \
|
|
||||||
libtool-bin \
|
|
||||||
make \
|
|
||||||
patch \
|
|
||||||
python2.7 \
|
|
||||||
sudo \
|
|
||||||
texinfo \
|
|
||||||
wget \
|
|
||||||
xz-utils \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
# Ubuntu 16.04 (this contianer) ships with make 4, but something in the
|
# Ubuntu 16.04 (this container) ships with make 4, but something in the
|
||||||
# toolchains we build below chokes on that, so go back to make 3
|
# toolchains we build below chokes on that, so go back to make 3
|
||||||
RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \
|
COPY scripts/make3.sh /scripts/
|
||||||
cd make-3.81 && \
|
RUN sh /scripts/make3.sh
|
||||||
./configure --prefix=/usr && \
|
|
||||||
make && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf make-3.81
|
|
||||||
|
|
||||||
RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \
|
COPY scripts/crosstool-ng.sh /scripts/
|
||||||
tar xjf - && \
|
RUN sh /scripts/crosstool-ng.sh
|
||||||
cd crosstool-ng && \
|
|
||||||
./configure --prefix=/usr/local && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf crosstool-ng
|
|
||||||
|
|
||||||
RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
COPY scripts/rustbuild-setup.sh /scripts/
|
||||||
RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
RUN sh /scripts/rustbuild-setup.sh
|
||||||
USER rustbuild
|
USER rustbuild
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
@ -61,9 +26,8 @@ RUN ./build-netbsd-toolchain.sh
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/sccache.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/sccache.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
|
ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
|
||||||
|
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
FROM ubuntu:16.04
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
g++ \
|
|
||||||
make \
|
|
||||||
file \
|
|
||||||
curl \
|
|
||||||
ca-certificates \
|
|
||||||
python \
|
|
||||||
git \
|
|
||||||
cmake \
|
|
||||||
sudo \
|
|
||||||
gdb \
|
|
||||||
xz-utils \
|
|
||||||
lib32stdc++6
|
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
|
||||||
|
|
||||||
WORKDIR /tmp
|
|
||||||
COPY emscripten/build-emscripten.sh /tmp/
|
|
||||||
RUN ./build-emscripten.sh
|
|
||||||
ENV PATH=$PATH:/tmp/emsdk_portable
|
|
||||||
ENV PATH=$PATH:/tmp/emsdk_portable/clang/tag-e1.37.10/build_tag-e1.37.10_32/bin
|
|
||||||
ENV PATH=$PATH:/tmp/emsdk_portable/node/4.1.1_32bit/bin
|
|
||||||
ENV PATH=$PATH:/tmp/emsdk_portable/emscripten/tag-1.37.10
|
|
||||||
ENV EMSCRIPTEN=/tmp/emsdk_portable/emscripten/tag-1.37.10
|
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --target=asmjs-unknown-emscripten
|
|
||||||
|
|
||||||
# Run `emcc` first as it's got a prompt and doesn't actually do anything, after
|
|
||||||
# that's done with do the real build.
|
|
||||||
ENV SCRIPT emcc && \
|
|
||||||
python2.7 ../x.py test --target asmjs-unknown-emscripten
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
# file at the top-level directory of this distribution and at
|
|
||||||
# http://rust-lang.org/COPYRIGHT.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
# option. This file may not be copied, modified, or distributed
|
|
||||||
# except according to those terms.
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
hide_output() {
|
|
||||||
set +x
|
|
||||||
on_err="
|
|
||||||
echo ERROR: An error was encountered with the build.
|
|
||||||
cat /tmp/build.log
|
|
||||||
exit 1
|
|
||||||
"
|
|
||||||
trap "$on_err" ERR
|
|
||||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
|
||||||
PING_LOOP_PID=$!
|
|
||||||
$@ &> /tmp/build.log
|
|
||||||
trap - ERR
|
|
||||||
kill $PING_LOOP_PID
|
|
||||||
rm /tmp/build.log
|
|
||||||
set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
curl https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | \
|
|
||||||
tar xzf -
|
|
||||||
|
|
||||||
# Some versions of the EMSDK archive have their contents in .emsdk-portable
|
|
||||||
# and others in emsdk_portable. Make sure the EMSDK ends up in a fixed path.
|
|
||||||
if [ -d emsdk-portable ]; then
|
|
||||||
mv emsdk-portable emsdk_portable
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d emsdk_portable ]; then
|
|
||||||
echo "ERROR: Invalid emsdk archive. Dumping working directory." >&2
|
|
||||||
ls -l
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Some versions of the EMSDK set the permissions of the root directory to
|
|
||||||
# 0700. Ensure the directory is readable by all users.
|
|
||||||
chmod 755 emsdk_portable
|
|
||||||
|
|
||||||
source emsdk_portable/emsdk_env.sh
|
|
||||||
hide_output emsdk update
|
|
||||||
hide_output emsdk install --build=Release sdk-tag-1.37.10-32bit
|
|
||||||
hide_output emsdk activate --build=Release sdk-tag-1.37.10-32bit
|
|
@ -13,13 +13,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests
|
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests
|
||||||
|
@ -13,13 +13,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
dpkg -i dumb-init_*.deb && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
rm dumb-init_*.deb
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu
|
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu
|
||||||
|
@ -82,7 +82,6 @@ exec docker \
|
|||||||
--env TRAVIS_BRANCH \
|
--env TRAVIS_BRANCH \
|
||||||
--volume "$HOME/.cargo:/cargo" \
|
--volume "$HOME/.cargo:/cargo" \
|
||||||
--volume "$HOME/rustsrc:$HOME/rustsrc" \
|
--volume "$HOME/rustsrc:$HOME/rustsrc" \
|
||||||
--privileged \
|
|
||||||
--rm \
|
--rm \
|
||||||
rust-ci \
|
rust-ci \
|
||||||
/checkout/src/ci/run.sh
|
/checkout/src/ci/run.sh
|
||||||
|
27
src/ci/docker/scripts/android-base-apt-get.sh
Normal file
27
src/ci/docker/scripts/android-base-apt-get.sh
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
cmake \
|
||||||
|
curl \
|
||||||
|
file \
|
||||||
|
g++ \
|
||||||
|
git \
|
||||||
|
libssl-dev \
|
||||||
|
make \
|
||||||
|
pkg-config \
|
||||||
|
python2.7 \
|
||||||
|
sudo \
|
||||||
|
unzip \
|
||||||
|
xz-utils
|
36
src/ci/docker/scripts/cross-apt-packages.sh
Normal file
36
src/ci/docker/scripts/cross-apt-packages.sh
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
automake \
|
||||||
|
bison \
|
||||||
|
bzip2 \
|
||||||
|
ca-certificates \
|
||||||
|
cmake \
|
||||||
|
curl \
|
||||||
|
file \
|
||||||
|
flex \
|
||||||
|
g++ \
|
||||||
|
gawk \
|
||||||
|
gdb \
|
||||||
|
git \
|
||||||
|
gperf \
|
||||||
|
help2man \
|
||||||
|
libncurses-dev \
|
||||||
|
libssl-dev \
|
||||||
|
libtool-bin \
|
||||||
|
make \
|
||||||
|
patch \
|
||||||
|
pkg-config \
|
||||||
|
python2.7 \
|
||||||
|
sudo \
|
||||||
|
texinfo \
|
||||||
|
wget \
|
||||||
|
xz-utils
|
20
src/ci/docker/scripts/crosstool-ng.sh
Normal file
20
src/ci/docker/scripts/crosstool-ng.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
url="http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2"
|
||||||
|
curl $url | tar xjf -
|
||||||
|
cd crosstool-ng
|
||||||
|
./configure --prefix=/usr/local
|
||||||
|
make -j$(nproc)
|
||||||
|
make install
|
||||||
|
cd ..
|
||||||
|
rm -rf crosstool-ng
|
47
src/ci/docker/scripts/emscripten-wasm.sh
Normal file
47
src/ci/docker/scripts/emscripten-wasm.sh
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
hide_output() {
|
||||||
|
set +x
|
||||||
|
on_err="
|
||||||
|
echo ERROR: An error was encountered with the build.
|
||||||
|
cat /tmp/build.log
|
||||||
|
exit 1
|
||||||
|
"
|
||||||
|
trap "$on_err" ERR
|
||||||
|
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||||
|
PING_LOOP_PID=$!
|
||||||
|
$@ &> /tmp/build.log
|
||||||
|
trap - ERR
|
||||||
|
kill $PING_LOOP_PID
|
||||||
|
rm -f /tmp/build.log
|
||||||
|
set -x
|
||||||
|
}
|
||||||
|
|
||||||
|
# Download last known good emscripten from WebAssembly waterfall
|
||||||
|
BUILD=$(curl -L https://storage.googleapis.com/wasm-llvm/builds/linux/lkgr.json | \
|
||||||
|
jq '.build | tonumber')
|
||||||
|
curl -L https://storage.googleapis.com/wasm-llvm/builds/linux/$BUILD/wasm-binaries.tbz2 | \
|
||||||
|
hide_output tar xvkj
|
||||||
|
|
||||||
|
# node 8 is required to run wasm
|
||||||
|
cd /
|
||||||
|
curl -L https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
|
||||||
|
tar -xJ
|
||||||
|
|
||||||
|
# Make emscripten use wasm-ready node and LLVM tools
|
||||||
|
echo "EMSCRIPTEN_ROOT = '/wasm-install/emscripten'" >> /root/.emscripten
|
||||||
|
echo "NODE_JS='/usr/local/bin/node'" >> /root/.emscripten
|
||||||
|
echo "LLVM_ROOT='/wasm-install/bin'" >> /root/.emscripten
|
||||||
|
echo "BINARYEN_ROOT = '/wasm-install'" >> /root/.emscripten
|
||||||
|
echo "COMPILER_ENGINE = NODE_JS" >> /root/.emscripten
|
||||||
|
echo "JS_ENGINES = [NODE_JS]" >> /root/.emscripten
|
53
src/ci/docker/scripts/emscripten.sh
Normal file
53
src/ci/docker/scripts/emscripten.sh
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
hide_output() {
|
||||||
|
set +x
|
||||||
|
on_err="
|
||||||
|
echo ERROR: An error was encountered with the build.
|
||||||
|
cat /tmp/build.log
|
||||||
|
exit 1
|
||||||
|
"
|
||||||
|
trap "$on_err" ERR
|
||||||
|
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||||
|
PING_LOOP_PID=$!
|
||||||
|
$@ &> /tmp/build.log
|
||||||
|
trap - ERR
|
||||||
|
kill $PING_LOOP_PID
|
||||||
|
rm -f /tmp/build.log
|
||||||
|
set -x
|
||||||
|
}
|
||||||
|
|
||||||
|
cd /
|
||||||
|
curl -L https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | \
|
||||||
|
tar -xz
|
||||||
|
|
||||||
|
cd /emsdk-portable
|
||||||
|
./emsdk update
|
||||||
|
hide_output ./emsdk install sdk-1.37.13-64bit
|
||||||
|
./emsdk activate sdk-1.37.13-64bit
|
||||||
|
|
||||||
|
# Compile and cache libc
|
||||||
|
source ./emsdk_env.sh
|
||||||
|
echo "main(){}" > a.c
|
||||||
|
HOME=/emsdk-portable/ emcc a.c
|
||||||
|
HOME=/emsdk-portable/ emcc -s BINARYEN=1 a.c
|
||||||
|
rm -f a.*
|
||||||
|
|
||||||
|
# Make emsdk usable by any user
|
||||||
|
cp /root/.emscripten /emsdk-portable
|
||||||
|
chmod a+rxw -R /emsdk-portable
|
||||||
|
|
||||||
|
# node 8 is required to run wasm
|
||||||
|
cd /
|
||||||
|
curl -L https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
|
||||||
|
tar -xJ
|
19
src/ci/docker/scripts/make3.sh
Normal file
19
src/ci/docker/scripts/make3.sh
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf -
|
||||||
|
cd make-3.81
|
||||||
|
./configure --prefix=/usr
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
cd ..
|
||||||
|
rm -rf make-3.81
|
14
src/ci/docker/scripts/rustbuild-setup.sh
Normal file
14
src/ci/docker/scripts/rustbuild-setup.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
||||||
|
mkdir /x-tools && chown rustbuild:rustbuild /x-tools
|
@ -14,13 +14,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
xz-utils \
|
xz-utils \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
||||||
|
@ -13,13 +13,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
|
@ -15,13 +15,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libssl-dev \
|
libssl-dev \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
||||||
|
@ -13,13 +13,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
|
@ -13,13 +13,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
||||||
|
@ -16,13 +16,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
|
@ -13,13 +13,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --disable-optimize-tests
|
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --disable-optimize-tests
|
||||||
|
@ -13,14 +13,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gdb \
|
gdb \
|
||||||
xz-utils
|
xz-utils
|
||||||
|
|
||||||
RUN curl -o /usr/local/bin/sccache \
|
COPY scripts/dumb-init.sh /scripts/
|
||||||
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
|
RUN sh /scripts/dumb-init.sh
|
||||||
chmod +x /usr/local/bin/sccache
|
|
||||||
|
COPY scripts/sccache.sh /scripts/
|
||||||
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
|
|
||||||
dpkg -i dumb-init_*.deb && \
|
|
||||||
rm dumb-init_*.deb
|
|
||||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||||
|
|
||||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers
|
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers --enable-profiler
|
||||||
ENV SCRIPT python2.7 ../x.py test
|
ENV SCRIPT python2.7 ../x.py test
|
||||||
|
@ -22,9 +22,6 @@ REPO_DIR="$1"
|
|||||||
CACHE_DIR="$2"
|
CACHE_DIR="$2"
|
||||||
|
|
||||||
cache_src_dir="$CACHE_DIR/src"
|
cache_src_dir="$CACHE_DIR/src"
|
||||||
# If the layout of the cache directory changes, bump the number here
|
|
||||||
# (and anywhere else this file is referenced) so the cache is wiped
|
|
||||||
cache_valid_file="$CACHE_DIR/cache_valid1"
|
|
||||||
|
|
||||||
if [ ! -d "$REPO_DIR" -o ! -d "$REPO_DIR/.git" ]; then
|
if [ ! -d "$REPO_DIR" -o ! -d "$REPO_DIR/.git" ]; then
|
||||||
echo "Error: $REPO_DIR does not exist or is not a git repo"
|
echo "Error: $REPO_DIR does not exist or is not a git repo"
|
||||||
@ -36,47 +33,19 @@ if [ ! -d "$CACHE_DIR" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Wipe the cache if it's not valid, or mark it as invalid while we update it
|
rm -rf "$CACHE_DIR"
|
||||||
if [ ! -f "$cache_valid_file" ]; then
|
mkdir "$CACHE_DIR"
|
||||||
echo "Invalid cache, wiping ($cache_valid_file missing)"
|
|
||||||
rm -rf "$CACHE_DIR"
|
|
||||||
mkdir "$CACHE_DIR"
|
|
||||||
else
|
|
||||||
# Ignore errors while gathering information about the possible brokenness
|
|
||||||
# of the git repo since our gathered info will tell us something is wrong
|
|
||||||
set +o errexit
|
|
||||||
stat_lines=$(cd "$cache_src_dir" && git status --porcelain | wc -l)
|
|
||||||
stat_ec=$(cd "$cache_src_dir" && git status >/dev/null 2>&1; echo $?)
|
|
||||||
set -o errexit
|
|
||||||
if [ ! -d "$cache_src_dir/.git" -o $stat_lines != 0 -o $stat_ec != 0 ]; then
|
|
||||||
# Something is badly wrong - the cache valid file is here, but something
|
|
||||||
# about the git repo is fishy. Nuke it all, just in case
|
|
||||||
echo "WARNING: $cache_valid_file exists but bad repo: l:$stat_lines, ec:$stat_ec"
|
|
||||||
rm -rf "$CACHE_DIR"
|
|
||||||
mkdir "$CACHE_DIR"
|
|
||||||
else
|
|
||||||
echo "Valid cache ($cache_valid_file exists)"
|
|
||||||
rm "$cache_valid_file"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
travis_fold start update_cache
|
travis_fold start update_cache
|
||||||
travis_time_start
|
travis_time_start
|
||||||
|
|
||||||
# Update the cache (a pristine copy of the rust source master)
|
# Update the cache (a pristine copy of the rust source master)
|
||||||
if [ ! -d "$cache_src_dir/.git" ]; then
|
retry sh -c "rm -rf $cache_src_dir && mkdir -p $cache_src_dir && \
|
||||||
retry sh -c "rm -rf $cache_src_dir && mkdir -p $cache_src_dir && \
|
git clone --depth 1 https://github.com/rust-lang/rust.git $cache_src_dir"
|
||||||
git clone https://github.com/rust-lang/rust.git $cache_src_dir"
|
|
||||||
fi
|
|
||||||
retry sh -c "cd $cache_src_dir && git reset --hard && git pull"
|
|
||||||
(cd $cache_src_dir && git rm src/llvm)
|
(cd $cache_src_dir && git rm src/llvm)
|
||||||
retry sh -c "cd $cache_src_dir && \
|
retry sh -c "cd $cache_src_dir && \
|
||||||
git submodule deinit -f . && git submodule sync && git submodule update --init"
|
git submodule deinit -f . && git submodule sync && git submodule update --init"
|
||||||
|
|
||||||
# Cache was updated without errors, mark it as valid
|
|
||||||
echo "Refreshed cache (touch $cache_valid_file)"
|
|
||||||
touch "$cache_valid_file"
|
|
||||||
|
|
||||||
travis_fold end update_cache
|
travis_fold end update_cache
|
||||||
travis_time_finish
|
travis_time_finish
|
||||||
|
|
||||||
@ -92,19 +61,21 @@ for module in $modules; do
|
|||||||
if [ "$module" = src/llvm ]; then
|
if [ "$module" = src/llvm ]; then
|
||||||
commit="$(git ls-tree HEAD src/llvm | awk '{print $3}')"
|
commit="$(git ls-tree HEAD src/llvm | awk '{print $3}')"
|
||||||
git rm src/llvm
|
git rm src/llvm
|
||||||
curl -sSL -O "https://github.com/rust-lang/llvm/archive/$commit.tar.gz"
|
retry sh -c "rm -f $commit.tar.gz && \
|
||||||
|
curl -sSL -O https://github.com/rust-lang/llvm/archive/$commit.tar.gz"
|
||||||
tar -C src/ -xf "$commit.tar.gz"
|
tar -C src/ -xf "$commit.tar.gz"
|
||||||
rm "$commit.tar.gz"
|
rm "$commit.tar.gz"
|
||||||
mv "src/llvm-$commit" src/llvm
|
mv "src/llvm-$commit" src/llvm
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [ ! -d "$cache_src_dir/$module" ]; then
|
if [ ! -e "$cache_src_dir/$module/.git" ]; then
|
||||||
echo "WARNING: $module not found in pristine repo"
|
echo "WARNING: $module not found in pristine repo"
|
||||||
retry sh -c "git submodule deinit -f $module && git submodule update --init $module"
|
retry sh -c "git submodule deinit -f $module && \
|
||||||
|
git submodule update --init --recursive $module"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
retry sh -c "git submodule deinit -f $module && \
|
retry sh -c "git submodule deinit -f $module && \
|
||||||
git submodule update --init --reference $cache_src_dir/$module $module"
|
git submodule update --init --recursive --reference $cache_src_dir/$module $module"
|
||||||
done
|
done
|
||||||
|
|
||||||
travis_fold end update_submodules
|
travis_fold end update_submodules
|
||||||
|
@ -102,6 +102,7 @@ Enum
|
|||||||
enums
|
enums
|
||||||
enum's
|
enum's
|
||||||
Enums
|
Enums
|
||||||
|
eprintln
|
||||||
ErrorKind
|
ErrorKind
|
||||||
Executables
|
Executables
|
||||||
extern
|
extern
|
||||||
@ -127,7 +128,6 @@ GitHub
|
|||||||
gitignore
|
gitignore
|
||||||
grapheme
|
grapheme
|
||||||
Grapheme
|
Grapheme
|
||||||
greprs
|
|
||||||
growable
|
growable
|
||||||
gzip
|
gzip
|
||||||
hardcode
|
hardcode
|
||||||
@ -192,6 +192,7 @@ Metadata
|
|||||||
metaprogramming
|
metaprogramming
|
||||||
mibbit
|
mibbit
|
||||||
Mibbit
|
Mibbit
|
||||||
|
minigrep
|
||||||
mixup
|
mixup
|
||||||
mkdir
|
mkdir
|
||||||
modifiability
|
modifiability
|
||||||
|
@ -62,14 +62,27 @@ Listing 5-2: Creating an instance of the `User` struct
|
|||||||
To get a specific value from a struct, we can use dot notation. If we wanted
|
To get a specific value from a struct, we can use dot notation. If we wanted
|
||||||
just this user’s email address, we can use `user1.email` wherever we want to
|
just this user’s email address, we can use `user1.email` wherever we want to
|
||||||
use this value. To change a value in a struct, if the instance is mutable, we
|
use this value. To change a value in a struct, if the instance is mutable, we
|
||||||
can use the dot notation and assign into a particular field, such as
|
can use the dot notation and assign into a particular field. Listing 5-3 shows
|
||||||
`user1.email = String::from("someone-else@example.com");`.
|
how to change the value in the `email` field of a mutable `User` instance:
|
||||||
|
|
||||||
|
```
|
||||||
|
let mut user1 = User {
|
||||||
|
email: String::from("someone@example.com"),
|
||||||
|
username: String::from("someusername123"),
|
||||||
|
active: true,
|
||||||
|
sign_in_count: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
user1.email = String::from("anotheremail@example.com");
|
||||||
|
```
|
||||||
|
|
||||||
|
Listing 5-3: Changing the value in the `email` field of a `User` instance
|
||||||
|
|
||||||
### Field Init Shorthand when Variables Have the Same Name as Fields
|
### Field Init Shorthand when Variables Have the Same Name as Fields
|
||||||
|
|
||||||
If you have variables with the same names as struct fields, you can use *field
|
If you have variables with the same names as struct fields, you can use *field
|
||||||
init shorthand*. This can make functions that create new instances of structs
|
init shorthand*. This can make functions that create new instances of structs
|
||||||
more concise. The function named `build_user` shown here in Listing 5-3 has
|
more concise. The function named `build_user` shown here in Listing 5-4 has
|
||||||
parameters named `email` and `username`. The function creates and returns a
|
parameters named `email` and `username`. The function creates and returns a
|
||||||
`User` instance:
|
`User` instance:
|
||||||
|
|
||||||
@ -84,13 +97,13 @@ fn build_user(email: String, username: String) -> User {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-3: A `build_user` function that takes an email and username and
|
Listing 5-4: A `build_user` function that takes an email and username and
|
||||||
returns a `User` instance
|
returns a `User` instance
|
||||||
|
|
||||||
Because the parameter names `email` and `username` are the same as the `User`
|
Because the parameter names `email` and `username` are the same as the `User`
|
||||||
struct's field names `email` and `username`, we can write `build_user` without
|
struct's field names `email` and `username`, we can write `build_user` without
|
||||||
the repetition of `email` and `username` as shown in Listing 5-4. This version
|
the repetition of `email` and `username` as shown in Listing 5-5. This version
|
||||||
of `build_user` behaves the same way as the one in Listing 5-3. The field init
|
of `build_user` behaves the same way as the one in Listing 5-4. The field init
|
||||||
syntax can make cases like this shorter to write, especially when structs have
|
syntax can make cases like this shorter to write, especially when structs have
|
||||||
many fields.
|
many fields.
|
||||||
|
|
||||||
@ -105,13 +118,13 @@ fn build_user(email: String, username: String) -> User {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-4: A `build_user` function that uses field init syntax since the
|
Listing 5-5: A `build_user` function that uses field init syntax since the
|
||||||
`email` and `username` parameters have the same name as struct fields
|
`email` and `username` parameters have the same name as struct fields
|
||||||
|
|
||||||
### Creating Instances From Other Instances With Struct Update Syntax
|
### Creating Instances From Other Instances With Struct Update Syntax
|
||||||
|
|
||||||
It's often useful to create a new instance from an old instance, using most of
|
It's often useful to create a new instance from an old instance, using most of
|
||||||
the old instance's values but changing some. Listing 5-5 shows an example of
|
the old instance's values but changing some. Listing 5-6 shows an example of
|
||||||
creating a new `User` instance in `user2` by setting the values of `email` and
|
creating a new `User` instance in `user2` by setting the values of `email` and
|
||||||
`username` but using the same values for the rest of the fields from the
|
`username` but using the same values for the rest of the fields from the
|
||||||
`user1` instance we created in Listing 5-2:
|
`user1` instance we created in Listing 5-2:
|
||||||
@ -125,13 +138,13 @@ let user2 = User {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-5: Creating a new `User` instance, `user2`, and setting some fields
|
Listing 5-6: Creating a new `User` instance, `user2`, and setting some fields
|
||||||
to the values of the same fields from `user1`
|
to the values of the same fields from `user1`
|
||||||
|
|
||||||
The *struct update syntax* achieves the same effect as the code in Listing
|
The *struct update syntax* achieves the same effect as the code in Listing
|
||||||
5-5 using less code. The struct update syntax uses `..` to specify that the
|
5-6 using less code. The struct update syntax uses `..` to specify that the
|
||||||
remaining fields not set explicitly should have the same value as the fields in
|
remaining fields not set explicitly should have the same value as the fields in
|
||||||
the given instance. The code in Listing 5-6 also creates an instance in `user2`
|
the given instance. The code in Listing 5-7 also creates an instance in `user2`
|
||||||
that has a different value for `email` and `username` but has the same values
|
that has a different value for `email` and `username` but has the same values
|
||||||
for the `active` and `sign_in_count` fields that `user1` has:
|
for the `active` and `sign_in_count` fields that `user1` has:
|
||||||
|
|
||||||
@ -143,7 +156,7 @@ let user2 = User {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-6: Using struct update syntax to set a new `email` and `username`
|
Listing 5-7: Using struct update syntax to set a new `email` and `username`
|
||||||
values for a `User` instance but use the rest of the values from the fields of
|
values for a `User` instance but use the rest of the values from the fields of
|
||||||
the instance in the `user1` variable
|
the instance in the `user1` variable
|
||||||
|
|
||||||
@ -242,7 +255,7 @@ refactor the program until we’re using structs instead.
|
|||||||
|
|
||||||
Let’s make a new binary project with Cargo called *rectangles* that will take
|
Let’s make a new binary project with Cargo called *rectangles* that will take
|
||||||
the length and width of a rectangle specified in pixels and will calculate the
|
the length and width of a rectangle specified in pixels and will calculate the
|
||||||
area of the rectangle. Listing 5-7 shows a short program with one way of doing
|
area of the rectangle. Listing 5-8 shows a short program with one way of doing
|
||||||
just that in our project’s *src/main.rs*:
|
just that in our project’s *src/main.rs*:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
@ -263,7 +276,7 @@ fn area(length: u32, width: u32) -> u32 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-7: Calculating the area of a rectangle specified by its length and
|
Listing 5-8: Calculating the area of a rectangle specified by its length and
|
||||||
width in separate variables
|
width in separate variables
|
||||||
|
|
||||||
Now, run this program using `cargo run`:
|
Now, run this program using `cargo run`:
|
||||||
@ -274,7 +287,7 @@ The area of the rectangle is 1500 square pixels.
|
|||||||
|
|
||||||
### Refactoring with Tuples
|
### Refactoring with Tuples
|
||||||
|
|
||||||
Even though Listing 5-7 works and figures out the area of the rectangle by
|
Even though Listing 5-8 works and figures out the area of the rectangle by
|
||||||
calling the `area` function with each dimension, we can do better. The length
|
calling the `area` function with each dimension, we can do better. The length
|
||||||
and the width are related to each other because together they describe one
|
and the width are related to each other because together they describe one
|
||||||
rectangle.
|
rectangle.
|
||||||
@ -290,7 +303,7 @@ function we wrote has two parameters. The parameters are related, but that’s
|
|||||||
not expressed anywhere in our program. It would be more readable and more
|
not expressed anywhere in our program. It would be more readable and more
|
||||||
manageable to group length and width together. We’ve already discussed one way
|
manageable to group length and width together. We’ve already discussed one way
|
||||||
we might do that in the Grouping Values into Tuples section of Chapter 3 on
|
we might do that in the Grouping Values into Tuples section of Chapter 3 on
|
||||||
page XX: by using tuples. Listing 5-8 shows another version of our program that
|
page XX: by using tuples. Listing 5-9 shows another version of our program that
|
||||||
uses tuples:
|
uses tuples:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
@ -329,7 +342,7 @@ our code.
|
|||||||
|
|
||||||
We use structs to add meaning by labeling the data. We can transform the tuple
|
We use structs to add meaning by labeling the data. We can transform the tuple
|
||||||
we’re using into a data type with a name for the whole as well as names for the
|
we’re using into a data type with a name for the whole as well as names for the
|
||||||
parts, as shown in Listing 5-9:
|
parts, as shown in Listing 5-10:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
|
|
||||||
@ -353,7 +366,7 @@ fn area(rectangle: &Rectangle) -> u32 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-9: Defining a `Rectangle` struct
|
Listing 5-10: Defining a `Rectangle` struct
|
||||||
|
|
||||||
Here we’ve defined a struct and named it `Rectangle`. Inside the `{}` we
|
Here we’ve defined a struct and named it `Rectangle`. Inside the `{}` we
|
||||||
defined the fields as `length` and `width`, both of which have type `u32`. Then
|
defined the fields as `length` and `width`, both of which have type `u32`. Then
|
||||||
@ -378,7 +391,7 @@ of `0` and `1`—a win for clarity.
|
|||||||
|
|
||||||
It would be helpful to be able to print out an instance of the `Rectangle`
|
It would be helpful to be able to print out an instance of the `Rectangle`
|
||||||
while we’re debugging our program in order to see the values for all its
|
while we’re debugging our program in order to see the values for all its
|
||||||
fields. Listing 5-10 uses the `println!` macro as we have been in earlier
|
fields. Listing 5-11 uses the `println!` macro as we have been in earlier
|
||||||
chapters:
|
chapters:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
@ -396,7 +409,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-10: Attempting to print a `Rectangle` instance
|
Listing 5-11: Attempting to print a `Rectangle` instance
|
||||||
|
|
||||||
When we run this code, we get an error with this core message:
|
When we run this code, we get an error with this core message:
|
||||||
|
|
||||||
@ -443,7 +456,7 @@ crate, add `#[derive(Debug)]` or manually implement it
|
|||||||
Rust *does* include functionality to print out debugging information, but we
|
Rust *does* include functionality to print out debugging information, but we
|
||||||
have to explicitly opt-in to make that functionality available for our struct.
|
have to explicitly opt-in to make that functionality available for our struct.
|
||||||
To do that, we add the annotation `#[derive(Debug)]` just before the struct
|
To do that, we add the annotation `#[derive(Debug)]` just before the struct
|
||||||
definition, as shown in Listing 5-11:
|
definition, as shown in Listing 5-12:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
|
|
||||||
@ -461,7 +474,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-11: Adding the annotation to derive the `Debug` trait and printing
|
Listing 5-12: Adding the annotation to derive the `Debug` trait and printing
|
||||||
the `Rectangle` instance using debug formatting
|
the `Rectangle` instance using debug formatting
|
||||||
|
|
||||||
Now when we run the program, we won’t get any errors and we’ll see the
|
Now when we run the program, we won’t get any errors and we’ll see the
|
||||||
@ -498,7 +511,7 @@ continue to refactor this code by turning the `area` function into an `area`
|
|||||||
## Method Syntax
|
## Method Syntax
|
||||||
|
|
||||||
*Methods* are similar to functions: they’re declared with the `fn` keyword and
|
*Methods* are similar to functions: they’re declared with the `fn` keyword and
|
||||||
their name, they can have parameters and return values, and they contain some
|
their name, they can have parameters and a return value, and they contain some
|
||||||
code that is run when they’re called from somewhere else. However, methods are
|
code that is run when they’re called from somewhere else. However, methods are
|
||||||
different from functions in that they’re defined within the context of a struct
|
different from functions in that they’re defined within the context of a struct
|
||||||
(or an enum or a trait object, which we cover in Chapters 6 and 17,
|
(or an enum or a trait object, which we cover in Chapters 6 and 17,
|
||||||
@ -509,7 +522,7 @@ instance of the struct the method is being called on.
|
|||||||
|
|
||||||
Let’s change the `area` function that has a `Rectangle` instance as a parameter
|
Let’s change the `area` function that has a `Rectangle` instance as a parameter
|
||||||
and instead make an `area` method defined on the `Rectangle` struct, as shown
|
and instead make an `area` method defined on the `Rectangle` struct, as shown
|
||||||
in Listing 5-12:
|
in Listing 5-13:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
|
|
||||||
@ -536,7 +549,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-12: Defining an `area` method on the `Rectangle` struct
|
Listing 5-13: Defining an `area` method on the `Rectangle` struct
|
||||||
|
|
||||||
To define the function within the context of `Rectangle`, we start an `impl`
|
To define the function within the context of `Rectangle`, we start an `impl`
|
||||||
(*implementation*) block. Then we move the `area` function within the `impl`
|
(*implementation*) block. Then we move the `area` function within the `impl`
|
||||||
@ -608,7 +621,7 @@ Let’s practice using methods by implementing a second method on the `Rectangle
|
|||||||
struct. This time, we want an instance of `Rectangle` to take another instance
|
struct. This time, we want an instance of `Rectangle` to take another instance
|
||||||
of `Rectangle` and return `true` if the second `Rectangle` can fit completely
|
of `Rectangle` and return `true` if the second `Rectangle` can fit completely
|
||||||
within `self`; otherwise it should return `false`. That is, we want to be able
|
within `self`; otherwise it should return `false`. That is, we want to be able
|
||||||
to write the program shown in Listing 5-13, once we’ve defined the `can_hold`
|
to write the program shown in Listing 5-14, once we’ve defined the `can_hold`
|
||||||
method:
|
method:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
@ -624,7 +637,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-13: Demonstration of using the as-yet-unwritten `can_hold` method
|
Listing 5-14: Demonstration of using the as-yet-unwritten `can_hold` method
|
||||||
|
|
||||||
And the expected output would look like the following, because both dimensions
|
And the expected output would look like the following, because both dimensions
|
||||||
of `rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider
|
of `rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider
|
||||||
@ -647,7 +660,7 @@ calling the `can_hold` method. The return value of `can_hold` will be a
|
|||||||
boolean, and the implementation will check whether the length and width of
|
boolean, and the implementation will check whether the length and width of
|
||||||
`self` are both greater than the length and width of the other `Rectangle`,
|
`self` are both greater than the length and width of the other `Rectangle`,
|
||||||
respectively. Let’s add the new `can_hold` method to the `impl` block from
|
respectively. Let’s add the new `can_hold` method to the `impl` block from
|
||||||
Listing 5-12, shown in Listing 5-14:
|
Listing 5-13, shown in Listing 5-15:
|
||||||
|
|
||||||
Filename: src/main.rs
|
Filename: src/main.rs
|
||||||
|
|
||||||
@ -663,10 +676,10 @@ impl Rectangle {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Listing 5-14: Implementing the `can_hold` method on `Rectangle` that takes
|
Listing 5-15: Implementing the `can_hold` method on `Rectangle` that takes
|
||||||
another `Rectangle` instance as a parameter
|
another `Rectangle` instance as a parameter
|
||||||
|
|
||||||
When we run this code with the `main` function in Listing 5-13, we’ll get our
|
When we run this code with the `main` function in Listing 5-14, we’ll get our
|
||||||
desired output. Methods can take multiple parameters that we add to the
|
desired output. Methods can take multiple parameters that we add to the
|
||||||
signature after the `self` parameter, and those parameters work just like
|
signature after the `self` parameter, and those parameters work just like
|
||||||
parameters in functions.
|
parameters in functions.
|
||||||
|
@ -1,53 +1,52 @@
|
|||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
# Testing
|
# Writing Automated Tests
|
||||||
|
|
||||||
> Program testing can be a very effective way to show the presence of bugs, but
|
> Program testing can be a very effective way to show the presence of bugs, but
|
||||||
> it is hopelessly inadequate for showing their absence.
|
> it is hopelessly inadequate for showing their absence.
|
||||||
>
|
> Edsger W. Dijkstra, “The Humble Programmer” (1972)
|
||||||
> Edsger W. Dijkstra, "The Humble Programmer" (1972)
|
|
||||||
|
|
||||||
Correctness in our programs means that our code does what we intend for it to
|
Correctness in our programs means that our code does what we intend for it to
|
||||||
do. Rust is a programming language that cares a lot about correctness, but
|
do. Rust is a programming language that cares a lot about correctness, but
|
||||||
correctness is a complex topic and isn't easy to prove. Rust's type system
|
correctness is a complex topic and isn’t easy to prove. Rust’s type system
|
||||||
shoulders a huge part of this burden, but the type system cannot catch every
|
shoulders a huge part of this burden, but the type system cannot catch every
|
||||||
kind of incorrectness. As such, Rust includes support for writing software
|
kind of incorrectness. As such, Rust includes support for writing software
|
||||||
tests within the language itself.
|
tests within the language itself.
|
||||||
|
|
||||||
As an example, say we write a function called `add_two` that adds two to a
|
As an example, say we write a function called `add_two` that adds two to
|
||||||
number passed to it. This function's signature accepts an integer as a
|
whatever number is passed to it. This function’s signature accepts an integer
|
||||||
parameter and returns an integer as a result. When we implement and compile
|
as a parameter and returns an integer as a result. When we implement and
|
||||||
that function, Rust will do all the type checking and borrow checking that
|
compile that function, Rust will do all the type checking and borrow checking
|
||||||
we've seen so far. Those checks will make sure that, for instance, we aren't
|
that we’ve seen so far to make sure that, for instance, we aren’t passing a
|
||||||
passing a `String` value or an invalid reference to this function. What Rust
|
`String` value or an invalid reference to this function. What Rust *can’t*
|
||||||
*can't* check is that this function will do precisely what we intend: return
|
check is that this function will do precisely what we intend: return the
|
||||||
the parameter plus two, rather than, say, the parameter plus 10 or the
|
parameter plus two, rather than, say, the parameter plus 10 or the parameter
|
||||||
parameter minus 50! That's where tests come in.
|
minus 50! That’s where tests come in.
|
||||||
|
|
||||||
We can write tests that assert, for example, that when we pass `3` to the
|
We can write tests that assert, for example, that when we pass `3` to the
|
||||||
`add_two` function, we get `5` back. We can run these tests whenever we make
|
`add_two` function, we get `5` back. We can run these tests whenever we make
|
||||||
changes to our code to make sure any existing correct behavior has not changed.
|
changes to our code to make sure any existing correct behavior has not changed.
|
||||||
|
|
||||||
Testing is a complex skill, and we cannot hope to cover everything about how to
|
Testing is a complex skill, and we cannot hope to cover everything about how to
|
||||||
write good tests in one chapter of a book, so here we'll just discuss the
|
write good tests in one chapter of a book, so here we’ll just discuss the
|
||||||
mechanics of Rust's testing facilities. We'll talk about the annotations and
|
mechanics of Rust’s testing facilities. We’ll talk about the annotations and
|
||||||
macros available to you when writing your tests, the default behavior and
|
macros available to you when writing your tests, the default behavior and
|
||||||
options provided for running your tests, and how to organize tests into unit
|
options provided for running your tests, and how to organize tests into unit
|
||||||
tests and integration tests.
|
tests and integration tests.
|
||||||
|
|
||||||
## How to Write Tests
|
## How to Write Tests
|
||||||
|
|
||||||
Tests are Rust functions that verify non-test code is functioning in the
|
Tests are Rust functions that verify that the non-test code in the program is
|
||||||
program in the expected manner. The bodies of test functions typically contain
|
functioning in the expected manner. The bodies of test functions typically run
|
||||||
some setup, running the code we want to test, then asserting that the results
|
some setup code, then run the code we want to test, then assert whether the
|
||||||
are what we expect. Let's look at the features Rust provides specifically for
|
results are what we expect. Let’s look at the features Rust provides
|
||||||
writing tests: the `test` attribute, a few macros, and the `should_panic`
|
specifically for writing tests: the `test` attribute, a few macros, and the
|
||||||
attribute.
|
`should_panic` attribute.
|
||||||
|
|
||||||
### The Anatomy of a Test Function
|
### The Anatomy of a Test Function
|
||||||
|
|
||||||
At its simplest, a test in Rust is a function that's annotated with the `test`
|
At its simplest, a test in Rust is a function that’s annotated with the `test`
|
||||||
attribute. Attributes are metadata about pieces of Rust code: the `derive`
|
attribute. Attributes are metadata about pieces of Rust code: the `derive`
|
||||||
attribute that we used with structs in Chapter 5 is one example. To make a
|
attribute that we used with structs in Chapter 5 is one example. To make a
|
||||||
function into a test function, we add `#[test]` on the line before `fn`. When
|
function into a test function, we add `#[test]` on the line before `fn`. When
|
||||||
@ -55,28 +54,19 @@ we run our tests with the `cargo test` command, Rust will build a test runner
|
|||||||
binary that runs the functions annotated with the `test` attribute and reports
|
binary that runs the functions annotated with the `test` attribute and reports
|
||||||
on whether each test function passes or fails.
|
on whether each test function passes or fails.
|
||||||
|
|
||||||
<!-- is it annotated with `test` by the user, or only automatically? I think
|
|
||||||
it's the latter, and has edited with a more active tone to make that clear, but
|
|
||||||
please change if I'm wrong -->
|
|
||||||
<!-- What do you mean by "only automatically"? The reader should be typing in
|
|
||||||
`#test on their own when they add new test functions; there's nothing special
|
|
||||||
about that text. I'm not sure what part of this chapter implied "only
|
|
||||||
automatically", can you point out where that's happening if we haven't taken
|
|
||||||
care of it? /Carol -->
|
|
||||||
|
|
||||||
We saw in Chapter 7 that when you make a new library project with Cargo, a test
|
We saw in Chapter 7 that when you make a new library project with Cargo, a test
|
||||||
module with a test function in it is automatically generated for us. This is to
|
module with a test function in it is automatically generated for us. This is to
|
||||||
help us get started writing our tests, since we don't have to go look up the
|
help us get started writing our tests, since we don’t have to go look up the
|
||||||
exact structure and syntax of test functions every time we start a new project.
|
exact structure and syntax of test functions every time we start a new project.
|
||||||
We can add as many additional test functions and as many test modules as we
|
We can add as many additional test functions and as many test modules as we
|
||||||
want, though!
|
want, though!
|
||||||
|
|
||||||
We're going to explore some aspects of how tests work by experimenting with the
|
We’re going to explore some aspects of how tests work by experimenting with the
|
||||||
template test generated for us, without actually testing any code. Then we'll
|
template test generated for us, without actually testing any code. Then we’ll
|
||||||
write some real-world tests that call some code that we've written and assert
|
write some real-world tests that call some code that we’ve written and assert
|
||||||
that its behavior is correct.
|
that its behavior is correct.
|
||||||
|
|
||||||
Let's create a new library project called `adder`:
|
Let’s create a new library project called `adder`:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cargo new adder
|
$ cargo new adder
|
||||||
@ -101,7 +91,7 @@ mod tests {
|
|||||||
Listing 11-1: The test module and function generated automatically for us by
|
Listing 11-1: The test module and function generated automatically for us by
|
||||||
`cargo new`
|
`cargo new`
|
||||||
|
|
||||||
For now, let's ignore the top two lines and focus on the function to see how it
|
For now, let’s ignore the top two lines and focus on the function to see how it
|
||||||
works. Note the `#[test]` annotation before the `fn` line: this attribute
|
works. Note the `#[test]` annotation before the `fn` line: this attribute
|
||||||
indicates this is a test function, so that the test runner knows to treat this
|
indicates this is a test function, so that the test runner knows to treat this
|
||||||
function as a test. We could also have non-test functions in the `tests` module
|
function as a test. We could also have non-test functions in the `tests` module
|
||||||
@ -109,7 +99,7 @@ to help set up common scenarios or perform common operations, so we need to
|
|||||||
indicate which functions are tests with the `#[test]` attribute.
|
indicate which functions are tests with the `#[test]` attribute.
|
||||||
|
|
||||||
The function currently has no body, which means there is no code to fail the
|
The function currently has no body, which means there is no code to fail the
|
||||||
test; an empty test is a passing test! Let's run it and see that this test
|
test; an empty test is a passing test! Let’s run it and see that this test
|
||||||
passes.
|
passes.
|
||||||
|
|
||||||
The `cargo test` command runs all tests we have in our project, as shown in
|
The `cargo test` command runs all tests we have in our project, as shown in
|
||||||
@ -118,7 +108,7 @@ Listing 11-2:
|
|||||||
```
|
```
|
||||||
$ cargo test
|
$ cargo test
|
||||||
Compiling adder v0.1.0 (file:///projects/adder)
|
Compiling adder v0.1.0 (file:///projects/adder)
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.22 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.22 secs
|
||||||
Running target/debug/deps/adder-ce99bcc2479f4607
|
Running target/debug/deps/adder-ce99bcc2479f4607
|
||||||
|
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -142,30 +132,21 @@ that test, `ok`. Then we see the overall summary of running the tests: `test
|
|||||||
result: ok.` means all the tests passed. `1 passed; 0 failed` adds up the
|
result: ok.` means all the tests passed. `1 passed; 0 failed` adds up the
|
||||||
number of tests that passed or failed.
|
number of tests that passed or failed.
|
||||||
|
|
||||||
We don't have any tests we've marked as ignored, so the summary says `0
|
We don’t have any tests we’ve marked as ignored, so the summary says `0
|
||||||
ignored`. We're going to talk about ignoring tests in the next section on
|
ignored`. We’re going to talk about ignoring tests in the next section on
|
||||||
different ways to run tests. The `0 measured` statistic is for benchmark tests
|
different ways to run tests. The `0 measured` statistic is for benchmark tests
|
||||||
that measure performance. Benchmark tests are, as of this writing, only
|
that measure performance. Benchmark tests are, as of this writing, only
|
||||||
available in nightly Rust. See Appendix D for more information about nightly
|
available in nightly Rust. See Appendix D for more information about nightly
|
||||||
Rust.
|
Rust.
|
||||||
|
|
||||||
The next part of the test output that starts with `Doc-tests adder` is for the
|
The next part of the test output that starts with `Doc-tests adder` is for the
|
||||||
results of any documentation tests. We don't have any documentation tests yet,
|
results of any documentation tests. We don’t have any documentation tests yet,
|
||||||
but Rust can compile any code examples that appear in our API documentation.
|
but Rust can compile any code examples that appear in our API documentation.
|
||||||
This feature helps us keep our docs and our code in sync! We'll be talking
|
This feature helps us keep our docs and our code in sync! We’ll be talking
|
||||||
about how to write documentation tests in the "Documentation Comments" section
|
about how to write documentation tests in the “Documentation Comments” section
|
||||||
of Chapter 14. We're going to ignore the `Doc-tests` output for now.
|
of Chapter 14. We’re going to ignore the `Doc-tests` output for now.
|
||||||
|
|
||||||
<!-- I might suggest changing the name of the function, could be misconstrued
|
Let’s change the name of our test and see how that changes the test output.
|
||||||
as part of the test output! -->
|
|
||||||
<!-- `it_works` is always the name that `cargo new` generates for the first
|
|
||||||
test function, though. We wanted to show the reader what happens when you run
|
|
||||||
the tests immediately after generating a new project; they pass without you
|
|
||||||
needing to change anything. I've added a bit to walk through changing the
|
|
||||||
function name and seeing how the output changes; I hope that's sufficient.
|
|
||||||
/Carol -->
|
|
||||||
|
|
||||||
Let's change the name of our test and see how that changes the test output.
|
|
||||||
Give the `it_works` function a different name, such as `exploration`, like so:
|
Give the `it_works` function a different name, such as `exploration`, like so:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -179,7 +160,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
And run `cargo test` again. In the output, we'll now see `exploration` instead
|
And run `cargo test` again. In the output, we’ll now see `exploration` instead
|
||||||
of `it_works`:
|
of `it_works`:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -189,7 +170,7 @@ test tests::exploration ... ok
|
|||||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
Let's add another test, but this time we'll make a test that fails! Tests fail
|
Let’s add another test, but this time we’ll make a test that fails! Tests fail
|
||||||
when something in the test function panics. We talked about the simplest way to
|
when something in the test function panics. We talked about the simplest way to
|
||||||
cause a panic in Chapter 9: call the `panic!` macro! Type in the new test so
|
cause a panic in Chapter 9: call the `panic!` macro! Type in the new test so
|
||||||
that your `src/lib.rs` now looks like Listing 11-3:
|
that your `src/lib.rs` now looks like Listing 11-3:
|
||||||
@ -244,14 +225,14 @@ failed because it `panicked at 'Make this test fail'`, which happened on
|
|||||||
*src/lib.rs* line 9. The next section lists just the names of all the failing
|
*src/lib.rs* line 9. The next section lists just the names of all the failing
|
||||||
tests, which is useful when there are lots of tests and lots of detailed
|
tests, which is useful when there are lots of tests and lots of detailed
|
||||||
failing test output. We can use the name of a failing test to run just that
|
failing test output. We can use the name of a failing test to run just that
|
||||||
test in order to more easily debug it; we'll talk more about ways to run tests
|
test in order to more easily debug it; we’ll talk more about ways to run tests
|
||||||
in the next section.
|
in the next section.
|
||||||
|
|
||||||
Finally, we have the summary line: overall, our test result is `FAILED`. We had
|
Finally, we have the summary line: overall, our test result is `FAILED`. We had
|
||||||
1 test pass and 1 test fail.
|
1 test pass and 1 test fail.
|
||||||
|
|
||||||
Now that we've seen what the test results look like in different scenarios,
|
Now that we’ve seen what the test results look like in different scenarios,
|
||||||
let's look at some macros other than `panic!` that are useful in tests.
|
let’s look at some macros other than `panic!` that are useful in tests.
|
||||||
|
|
||||||
### Checking Results with the `assert!` Macro
|
### Checking Results with the `assert!` Macro
|
||||||
|
|
||||||
@ -262,24 +243,11 @@ to ensure that some condition in a test evaluates to `true`. We give the
|
|||||||
calls the `panic!` macro, which causes the test to fail. This is one macro that
|
calls the `panic!` macro, which causes the test to fail. This is one macro that
|
||||||
helps us check that our code is functioning in the way we intend.
|
helps us check that our code is functioning in the way we intend.
|
||||||
|
|
||||||
<!-- what kind of thing can be passed as an argument? Presumably when we use it
|
|
||||||
for real we won't pass it `true` or `false` as an argument, but some condition
|
|
||||||
that will evaluate to true or false? In which case, should below be phrased "If
|
|
||||||
the argument evaluates to true" and an exaplanation of that? Or maybe even a
|
|
||||||
working example would be better, this could be misleading -->
|
|
||||||
<!-- We were trying to really break it down, to show just how the `assert!`
|
|
||||||
macro works and what it looks like for it to pass or fail, before we got into
|
|
||||||
calling actual code. We've changed this section to move a bit faster and just
|
|
||||||
write actual tests instead. /Carol -->
|
|
||||||
|
|
||||||
Remember all the way back in Chapter 5, Listing 5-9, where we had a `Rectangle`
|
Remember all the way back in Chapter 5, Listing 5-9, where we had a `Rectangle`
|
||||||
struct and a `can_hold` method, repeated here in Listing 11-5. Let's put this
|
struct and a `can_hold` method, repeated here in Listing 11-5. Let’s put this
|
||||||
code in *src/lib.rs* instead of *src/main.rs* and write some tests for it using
|
code in *src/lib.rs* instead of *src/main.rs* and write some tests for it using
|
||||||
the `assert!` macro.
|
the `assert!` macro.
|
||||||
|
|
||||||
<!-- Listing 5-9 wasn't marked as such; I'll fix it the next time I get Chapter
|
|
||||||
5 for editing. /Carol -->
|
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -298,8 +266,8 @@ impl Rectangle {
|
|||||||
|
|
||||||
Listing 11-5: The `Rectangle` struct and its `can_hold` method from Chapter 5
|
Listing 11-5: The `Rectangle` struct and its `can_hold` method from Chapter 5
|
||||||
|
|
||||||
The `can_hold` method returns a boolean, which means it's a perfect use case
|
The `can_hold` method returns a boolean, which means it’s a perfect use case
|
||||||
for the `assert!` macro. In Listing 11-6, let's write a test that exercises the
|
for the `assert!` macro. In Listing 11-6, let’s write a test that exercises the
|
||||||
`can_hold` method by creating a `Rectangle` instance that has a length of 8 and
|
`can_hold` method by creating a `Rectangle` instance that has a length of 8 and
|
||||||
a width of 7, and asserting that it can hold another `Rectangle` instance that
|
a width of 7, and asserting that it can hold another `Rectangle` instance that
|
||||||
has a length of 5 and a width of 1:
|
has a length of 5 and a width of 1:
|
||||||
@ -324,17 +292,17 @@ mod tests {
|
|||||||
Listing 11-6: A test for `can_hold` that checks that a larger rectangle indeed
|
Listing 11-6: A test for `can_hold` that checks that a larger rectangle indeed
|
||||||
holds a smaller rectangle
|
holds a smaller rectangle
|
||||||
|
|
||||||
Note that we've added a new line inside the `tests` module: `use super::*;`.
|
Note that we’ve added a new line inside the `tests` module: `use super::*;`.
|
||||||
The `tests` module is a regular module that follows the usual visibility rules
|
The `tests` module is a regular module that follows the usual visibility rules
|
||||||
we covered in Chapter 7. Because we're in an inner module, we need to bring the
|
we covered in Chapter 7. Because we’re in an inner module, we need to bring the
|
||||||
code under test in the outer module into the scope of the inner module. We've
|
code under test in the outer module into the scope of the inner module. We’ve
|
||||||
chosen to use a glob here so that anything we define in the outer module is
|
chosen to use a glob here so that anything we define in the outer module is
|
||||||
available to this `tests` module.
|
available to this `tests` module.
|
||||||
|
|
||||||
We've named our test `larger_can_hold_smaller`, and we've created the two
|
We’ve named our test `larger_can_hold_smaller`, and we’ve created the two
|
||||||
`Rectangle` instances that we need. Then we called the `assert!` macro and
|
`Rectangle` instances that we need. Then we called the `assert!` macro and
|
||||||
passed it the result of calling `larger.can_hold(&smaller)`. This expression is
|
passed it the result of calling `larger.can_hold(&smaller)`. This expression is
|
||||||
supposed to return `true`, so our test should pass. Let's find out!
|
supposed to return `true`, so our test should pass. Let’s find out!
|
||||||
|
|
||||||
```
|
```
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -343,7 +311,7 @@ test tests::larger_can_hold_smaller ... ok
|
|||||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
It does pass! Let's add another test, this time asserting that a smaller
|
It does pass! Let’s add another test, this time asserting that a smaller
|
||||||
rectangle cannot hold a larger rectangle:
|
rectangle cannot hold a larger rectangle:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -362,7 +330,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smaller_can_hold_larger() {
|
fn smaller_cannot_hold_larger() {
|
||||||
let larger = Rectangle { length: 8, width: 7 };
|
let larger = Rectangle { length: 8, width: 7 };
|
||||||
let smaller = Rectangle { length: 5, width: 1 };
|
let smaller = Rectangle { length: 5, width: 1 };
|
||||||
|
|
||||||
@ -377,15 +345,15 @@ way, our test will pass if `can_hold` returns `false`:
|
|||||||
|
|
||||||
```
|
```
|
||||||
running 2 tests
|
running 2 tests
|
||||||
test tests::smaller_can_hold_larger ... ok
|
test tests::smaller_cannot_hold_larger ... ok
|
||||||
test tests::larger_can_hold_smaller ... ok
|
test tests::larger_can_hold_smaller ... ok
|
||||||
|
|
||||||
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
Two passing tests! Now let's see what happens to our test results if we
|
Two passing tests! Now let’s see what happens to our test results if we
|
||||||
introduce a bug in our code. Let's change the implementation of the `can_hold`
|
introduce a bug in our code. Let’s change the implementation of the `can_hold`
|
||||||
method to have a less-than sign when it compares the lengths where it's
|
method to have a less-than sign when it compares the lengths where it’s
|
||||||
supposed to have a greater-than sign:
|
supposed to have a greater-than sign:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -406,7 +374,7 @@ Running the tests now produces:
|
|||||||
|
|
||||||
```
|
```
|
||||||
running 2 tests
|
running 2 tests
|
||||||
test tests::smaller_can_hold_larger ... ok
|
test tests::smaller_cannot_hold_larger ... ok
|
||||||
test tests::larger_can_hold_smaller ... FAILED
|
test tests::larger_can_hold_smaller ... FAILED
|
||||||
|
|
||||||
failures:
|
failures:
|
||||||
@ -429,18 +397,18 @@ less than 5.
|
|||||||
### Testing Equality with the `assert_eq!` and `assert_ne!` Macros
|
### Testing Equality with the `assert_eq!` and `assert_ne!` Macros
|
||||||
|
|
||||||
A common way to test functionality is to take the result of the code under test
|
A common way to test functionality is to take the result of the code under test
|
||||||
and the value we expect the code to return and check that they're equal. We
|
and the value we expect the code to return and check that they’re equal. We
|
||||||
could do this using the `assert!` macro and passing it an expression using the
|
could do this using the `assert!` macro and passing it an expression using the
|
||||||
`==` operator. However, this is such a common test that the standard library
|
`==` operator. However, this is such a common test that the standard library
|
||||||
provides a pair of macros to perform this test more conveniently: `assert_eq!`
|
provides a pair of macros to perform this test more conveniently: `assert_eq!`
|
||||||
and `assert_ne!`. These macros compare two arguments for equality or
|
and `assert_ne!`. These macros compare two arguments for equality or
|
||||||
inequality, respectively. They'll also print out the two values if the
|
inequality, respectively. They’ll also print out the two values if the
|
||||||
assertion fails, so that it's easier to see *why* the test failed, while the
|
assertion fails, so that it’s easier to see *why* the test failed, while the
|
||||||
`assert!` macro only tells us that it got a `false` value for the `==`
|
`assert!` macro only tells us that it got a `false` value for the `==`
|
||||||
expression, not the values that lead to the `false` value.
|
expression, not the values that lead to the `false` value.
|
||||||
|
|
||||||
In Listing 11-7, let's write a function named `add_two` that adds two to its
|
In Listing 11-7, let’s write a function named `add_two` that adds two to its
|
||||||
parameter and returns the result. Then let's test this function using the
|
parameter and returns the result. Then let’s test this function using the
|
||||||
`assert_eq!` macro:
|
`assert_eq!` macro:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -463,7 +431,7 @@ mod tests {
|
|||||||
|
|
||||||
Listing 11-7: Testing the function `add_two` using the `assert_eq!` macro
|
Listing 11-7: Testing the function `add_two` using the `assert_eq!` macro
|
||||||
|
|
||||||
Let's check that it passes!
|
Let’s check that it passes!
|
||||||
|
|
||||||
```
|
```
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -476,7 +444,7 @@ The first argument we gave to the `assert_eq!` macro, 4, is equal to the result
|
|||||||
of calling `add_two(2)`. We see a line for this test that says `test
|
of calling `add_two(2)`. We see a line for this test that says `test
|
||||||
tests::it_adds_two ... ok`, and the `ok` text indicates that our test passed!
|
tests::it_adds_two ... ok`, and the `ok` text indicates that our test passed!
|
||||||
|
|
||||||
Let's introduce a bug into our code to see what it looks like when a test that
|
Let’s introduce a bug into our code to see what it looks like when a test that
|
||||||
uses `assert_eq!` fails. Change the implementation of the `add_two` function to
|
uses `assert_eq!` fails. Change the implementation of the `add_two` function to
|
||||||
instead add 3:
|
instead add 3:
|
||||||
|
|
||||||
@ -513,16 +481,16 @@ useful and helps us get started debugging: it says the `left` argument to
|
|||||||
Note that in some languages and test frameworks, the parameters to the
|
Note that in some languages and test frameworks, the parameters to the
|
||||||
functions that assert two values are equal are called `expected` and `actual`
|
functions that assert two values are equal are called `expected` and `actual`
|
||||||
and the order in which we specify the arguments matters. However, in Rust,
|
and the order in which we specify the arguments matters. However, in Rust,
|
||||||
they're called `left` and `right` instead, and the order in which we specify
|
they’re called `left` and `right` instead, and the order in which we specify
|
||||||
the value we expect and the value that the code under test produces doesn't
|
the value we expect and the value that the code under test produces doesn’t
|
||||||
matter. We could have written the assertion in this test as
|
matter. We could have written the assertion in this test as
|
||||||
`assert_eq!(add_two(2), 4)`, which would result in a failure message that says
|
`assert_eq!(add_two(2), 4)`, which would result in a failure message that says
|
||||||
`` assertion failed: `(left == right)` (left: `5`, right: `4`) ``.
|
`` assertion failed: `(left == right)` (left: `5`, right: `4`) ``.
|
||||||
|
|
||||||
The `assert_ne!` macro will pass if the two values we give to it are not equal
|
The `assert_ne!` macro will pass if the two values we give to it are not equal
|
||||||
and fail if they are equal. This macro is most useful for cases when we're not
|
and fail if they are equal. This macro is most useful for cases when we’re not
|
||||||
sure exactly what a value *will* be, but we know what the value definitely
|
sure exactly what a value *will* be, but we know what the value definitely
|
||||||
*won't* be, if our code is functioning as we intend. For example, if we have a
|
*won’t* be, if our code is functioning as we intend. For example, if we have a
|
||||||
function that is guaranteed to change its input in some way, but the way in
|
function that is guaranteed to change its input in some way, but the way in
|
||||||
which the input is changed depends on the day of the week that we run our
|
which the input is changed depends on the day of the week that we run our
|
||||||
tests, the best thing to assert might be that the output of the function is not
|
tests, the best thing to assert might be that the output of the function is not
|
||||||
@ -533,8 +501,8 @@ Under the surface, the `assert_eq!` and `assert_ne!` macros use the operators
|
|||||||
arguments using debug formatting, which means the values being compared must
|
arguments using debug formatting, which means the values being compared must
|
||||||
implement the `PartialEq` and `Debug` traits. All of the primitive types and
|
implement the `PartialEq` and `Debug` traits. All of the primitive types and
|
||||||
most of the standard library types implement these traits. For structs and
|
most of the standard library types implement these traits. For structs and
|
||||||
enums that you define, you'll need to implement `PartialEq` in order to be able
|
enums that you define, you’ll need to implement `PartialEq` in order to be able
|
||||||
to assert that values of those types are equal or not equal. You'll need to
|
to assert that values of those types are equal or not equal. You’ll need to
|
||||||
implement `Debug` in order to be able to print out the values in the case that
|
implement `Debug` in order to be able to print out the values in the case that
|
||||||
the assertion fails. Because both of these traits are derivable traits, as we
|
the assertion fails. Because both of these traits are derivable traits, as we
|
||||||
mentioned in Chapter 5, this is usually as straightforward as adding the
|
mentioned in Chapter 5, this is usually as straightforward as adding the
|
||||||
@ -552,7 +520,7 @@ contains `{}` placeholders and values to go in the placeholders. Custom
|
|||||||
messages are useful in order to document what an assertion means, so that when
|
messages are useful in order to document what an assertion means, so that when
|
||||||
the test fails, we have a better idea of what the problem is with the code.
|
the test fails, we have a better idea of what the problem is with the code.
|
||||||
|
|
||||||
For example, let's say we have a function that greets people by name, and we
|
For example, let’s say we have a function that greets people by name, and we
|
||||||
want to test that the name we pass into the function appears in the output:
|
want to test that the name we pass into the function appears in the output:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -574,14 +542,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The requirements for this program haven't been agreed upon yet, and we're
|
The requirements for this program haven’t been agreed upon yet, and we’re
|
||||||
pretty sure the `Hello` text at the beginning of the greeting will change. We
|
pretty sure the `Hello` text at the beginning of the greeting will change. We
|
||||||
decided we don't want to have to update the test for the name when that
|
decided we don’t want to have to update the test for the name when that
|
||||||
happens, so instead of checking for exact equality to the value returned from
|
happens, so instead of checking for exact equality to the value returned from
|
||||||
the `greeting` function, we're just going to assert that the output contains
|
the `greeting` function, we’re just going to assert that the output contains
|
||||||
the text of the input parameter.
|
the text of the input parameter.
|
||||||
|
|
||||||
Let's introduce a bug into this code to see what this test failure looks like,
|
Let’s introduce a bug into this code to see what this test failure looks like,
|
||||||
by changing `greeting` to not include `name`:
|
by changing `greeting` to not include `name`:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -609,7 +577,7 @@ failures:
|
|||||||
|
|
||||||
This just tells us that the assertion failed and which line the assertion is
|
This just tells us that the assertion failed and which line the assertion is
|
||||||
on. A more useful failure message in this case would print the value we did get
|
on. A more useful failure message in this case would print the value we did get
|
||||||
from the `greeting` function. Let's change the test function to have a custom
|
from the `greeting` function. Let’s change the test function to have a custom
|
||||||
failure message made from a format string with a placeholder filled in with the
|
failure message made from a format string with a placeholder filled in with the
|
||||||
actual value we got from the `greeting` function:
|
actual value we got from the `greeting` function:
|
||||||
|
|
||||||
@ -624,11 +592,11 @@ fn greeting_contains_name() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Now if we run the test again, we'll get a much more informative error message:
|
Now if we run the test again, we’ll get a much more informative error message:
|
||||||
|
|
||||||
```
|
```
|
||||||
---- tests::greeting_contains_name stdout ----
|
---- tests::greeting_contains_name stdout ----
|
||||||
thread 'tests::greeting_contains_name' panicked at 'Result did not contain
|
thread 'tests::greeting_contains_name' panicked at 'Greeting did not contain
|
||||||
name, value was `Hello`', src/lib.rs:12
|
name, value was `Hello`', src/lib.rs:12
|
||||||
note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
||||||
```
|
```
|
||||||
@ -639,7 +607,7 @@ debug what happened instead of what we were expecting to happen.
|
|||||||
### Checking for Panics with `should_panic`
|
### Checking for Panics with `should_panic`
|
||||||
|
|
||||||
In addition to checking that our code returns the correct values we expect,
|
In addition to checking that our code returns the correct values we expect,
|
||||||
it's also important to check that our code handles error conditions as we
|
it’s also important to check that our code handles error conditions as we
|
||||||
expect. For example, consider the `Guess` type that we created in Chapter 9 in
|
expect. For example, consider the `Guess` type that we created in Chapter 9 in
|
||||||
Listing 9-8. Other code that uses `Guess` is depending on the guarantee that
|
Listing 9-8. Other code that uses `Guess` is depending on the guarantee that
|
||||||
`Guess` instances will only contain values between 1 and 100. We can write a
|
`Guess` instances will only contain values between 1 and 100. We can write a
|
||||||
@ -648,9 +616,9 @@ outside that range panics.
|
|||||||
|
|
||||||
We can do this by adding another attribute, `should_panic`, to our test
|
We can do this by adding another attribute, `should_panic`, to our test
|
||||||
function. This attribute makes a test pass if the code inside the function
|
function. This attribute makes a test pass if the code inside the function
|
||||||
panics, and the test will fail if the code inside the function does non panic.
|
panics, and the test will fail if the code inside the function doesn't panic.
|
||||||
|
|
||||||
Listing 11-8 shows how we'd write a test that checks the error conditions of
|
Listing 11-8 shows how we’d write a test that checks the error conditions of
|
||||||
`Guess::new` happen when we expect:
|
`Guess::new` happen when we expect:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -667,7 +635,7 @@ impl Guess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Guess {
|
Guess {
|
||||||
value: value,
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,7 +655,7 @@ mod tests {
|
|||||||
Listing 11-8: Testing that a condition will cause a `panic!`
|
Listing 11-8: Testing that a condition will cause a `panic!`
|
||||||
|
|
||||||
The `#[should_panic]` attribute goes after the `#[test]` attribute and before
|
The `#[should_panic]` attribute goes after the `#[test]` attribute and before
|
||||||
the test function it applies to. Let's see what it looks like when this test
|
the test function it applies to. Let’s see what it looks like when this test
|
||||||
passes:
|
passes:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -697,7 +665,7 @@ test tests::greater_than_100 ... ok
|
|||||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
Looks good! Now let's introduce a bug in our code, by removing the condition
|
Looks good! Now let’s introduce a bug in our code, by removing the condition
|
||||||
that the `new` function will panic if the value is greater than 100:
|
that the `new` function will panic if the value is greater than 100:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -708,7 +676,7 @@ impl Guess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Guess {
|
Guess {
|
||||||
value: value,
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -728,8 +696,8 @@ failures:
|
|||||||
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
|
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
We don't get a very helpful message in this case, but once we look at the test
|
We don’t get a very helpful message in this case, but once we look at the test
|
||||||
function, we can see that it's annotated with `#[should_panic]`. The failure we
|
function, we can see that it’s annotated with `#[should_panic]`. The failure we
|
||||||
got means that the code in the function, `Guess::new(200)`, did not cause a
|
got means that the code in the function, `Guess::new(200)`, did not cause a
|
||||||
panic.
|
panic.
|
||||||
|
|
||||||
@ -760,7 +728,7 @@ impl Guess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Guess {
|
Guess {
|
||||||
value: value,
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -790,7 +758,7 @@ substring of the panic message is enough to ensure that the code in the
|
|||||||
function that gets run is the `else if value > 100` case.
|
function that gets run is the `else if value > 100` case.
|
||||||
|
|
||||||
To see what happens when a `should_panic` test with an `expected` message
|
To see what happens when a `should_panic` test with an `expected` message
|
||||||
fails, let's again introduce a bug into our code by swapping the bodies of the
|
fails, let’s again introduce a bug into our code by swapping the bodies of the
|
||||||
`if value < 1` and the `else if value > 100` blocks:
|
`if value < 1` and the `else if value > 100` blocks:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -828,7 +796,7 @@ less than or equal to 100'`. We can see the panic message that we did get,
|
|||||||
which in this case was `Guess value must be greater than or equal to 1, got
|
which in this case was `Guess value must be greater than or equal to 1, got
|
||||||
200.` We could then start figuring out where our bug was!
|
200.` We could then start figuring out where our bug was!
|
||||||
|
|
||||||
Now that we've gone over ways to write tests, let's look at what is happening
|
Now that we’ve gone over ways to write tests, let’s look at what is happening
|
||||||
when we run our tests and talk about the different options we can use with
|
when we run our tests and talk about the different options we can use with
|
||||||
`cargo test`.
|
`cargo test`.
|
||||||
|
|
||||||
@ -853,10 +821,6 @@ separator `--`.
|
|||||||
|
|
||||||
### Running Tests in Parallel or Consecutively
|
### Running Tests in Parallel or Consecutively
|
||||||
|
|
||||||
<!-- Are we safe assuming the reader will know enough about threads in this
|
|
||||||
context? -->
|
|
||||||
<!-- Yes /Carol -->
|
|
||||||
|
|
||||||
When multiple tests are run, by default they run in parallel using threads.
|
When multiple tests are run, by default they run in parallel using threads.
|
||||||
This means the tests will finish running faster, so that we can get faster
|
This means the tests will finish running faster, so that we can get faster
|
||||||
feedback on whether or not our code is working. Since the tests are running at
|
feedback on whether or not our code is working. Since the tests are running at
|
||||||
@ -868,13 +832,13 @@ For example, say each of your tests runs some code that creates a file on disk
|
|||||||
named `test-output.txt` and writes some data to that file. Then each test reads
|
named `test-output.txt` and writes some data to that file. Then each test reads
|
||||||
the data in that file and asserts that the file contains a particular value,
|
the data in that file and asserts that the file contains a particular value,
|
||||||
which is different in each test. Because the tests are all run at the same
|
which is different in each test. Because the tests are all run at the same
|
||||||
time, one test might overrwrite the file between when another test writes and
|
time, one test might overwrite the file between when another test writes and
|
||||||
reads the file. The second test will then fail, not because the code is
|
reads the file. The second test will then fail, not because the code is
|
||||||
incorrect, but because the tests have interfered with each other while running
|
incorrect, but because the tests have interfered with each other while running
|
||||||
in parallel. One solution would be to make sure each test writes to a different
|
in parallel. One solution would be to make sure each test writes to a different
|
||||||
file; another solution is to run the tests one at a time.
|
file; another solution is to run the tests one at a time.
|
||||||
|
|
||||||
If you don't want to run the tests in parallel, or if you want more
|
If you don’t want to run the tests in parallel, or if you want more
|
||||||
fine-grained control over the number of threads used, you can send the
|
fine-grained control over the number of threads used, you can send the
|
||||||
`--test-threads` flag and the number of threads you want to use to the test
|
`--test-threads` flag and the number of threads you want to use to the test
|
||||||
binary. For example:
|
binary. For example:
|
||||||
@ -885,14 +849,14 @@ $ cargo test -- --test-threads=1
|
|||||||
|
|
||||||
We set the number of test threads to 1, telling the program not to use any
|
We set the number of test threads to 1, telling the program not to use any
|
||||||
parallelism. This will take longer than running them in parallel, but the tests
|
parallelism. This will take longer than running them in parallel, but the tests
|
||||||
won't be potentially interfering with each other if they share state.
|
won’t be potentially interfering with each other if they share state.
|
||||||
|
|
||||||
### Showing Function Output
|
### Showing Function Output
|
||||||
|
|
||||||
By default, if a test passes, Rust's test library captures anything printed to
|
By default, if a test passes, Rust’s test library captures anything printed to
|
||||||
standard output. For example, if we call `println!` in a test and the test
|
standard output. For example, if we call `println!` in a test and the test
|
||||||
passes, we won't see the `println!` output in the terminal: we'll only see the
|
passes, we won’t see the `println!` output in the terminal: we’ll only see the
|
||||||
line that says the test passed. If a test fails, we'll see whatever was printed
|
line that says the test passed. If a test fails, we’ll see whatever was printed
|
||||||
to standard output with the rest of the failure message.
|
to standard output with the rest of the failure message.
|
||||||
|
|
||||||
For example, Listing 11-10 has a silly function that prints out the value of
|
For example, Listing 11-10 has a silly function that prints out the value of
|
||||||
@ -927,7 +891,7 @@ mod tests {
|
|||||||
|
|
||||||
Listing 11-10: Tests for a function that calls `println!`
|
Listing 11-10: Tests for a function that calls `println!`
|
||||||
|
|
||||||
The output we'll see when we run these tests with `cargo test` is:
|
The output we’ll see when we run these tests with `cargo test` is:
|
||||||
|
|
||||||
```
|
```
|
||||||
running 2 tests
|
running 2 tests
|
||||||
@ -988,12 +952,12 @@ function and see what the output looks like then!
|
|||||||
|
|
||||||
### Running a Subset of Tests by Name
|
### Running a Subset of Tests by Name
|
||||||
|
|
||||||
Sometimes, running a full test suite can take a long time. If you're working on
|
Sometimes, running a full test suite can take a long time. If you’re working on
|
||||||
code in a particular area, you might want to run only the tests pertaining to
|
code in a particular area, you might want to run only the tests pertaining to
|
||||||
that code. You can choose which tests to run by passing `cargo test` the name
|
that code. You can choose which tests to run by passing `cargo test` the name
|
||||||
or names of the test/s you want to run as an argument.
|
or names of the test/s you want to run as an argument.
|
||||||
|
|
||||||
To demonstrate how to run a subset of tests, we'll create three tests for our
|
To demonstrate how to run a subset of tests, we’ll create three tests for our
|
||||||
`add_two` function as shown in Listing 11-11 and choose which ones to run:
|
`add_two` function as shown in Listing 11-11 and choose which ones to run:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -1026,7 +990,7 @@ mod tests {
|
|||||||
|
|
||||||
Listing 11-11: Three tests with a variety of names
|
Listing 11-11: Three tests with a variety of names
|
||||||
|
|
||||||
If we run the tests without passing any arguments, as we've already seen, all
|
If we run the tests without passing any arguments, as we’ve already seen, all
|
||||||
the tests will run in parallel:
|
the tests will run in parallel:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -1044,7 +1008,7 @@ We can pass the name of any test function to `cargo test` to run only that test:
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ cargo test one_hundred
|
$ cargo test one_hundred
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
|
||||||
Running target/debug/deps/adder-06a75b4a1f2515e9
|
Running target/debug/deps/adder-06a75b4a1f2515e9
|
||||||
|
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -1053,18 +1017,18 @@ test tests::one_hundred ... ok
|
|||||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
We can't specify the names of multiple tests in this way, only the first value
|
We can’t specify the names of multiple tests in this way, only the first value
|
||||||
given to `cargo test` will be used.
|
given to `cargo test` will be used.
|
||||||
|
|
||||||
#### Filtering to Run Multiple Tests
|
#### Filtering to Run Multiple Tests
|
||||||
|
|
||||||
However, we can specify part of a test name, and any test whose name matches
|
However, we can specify part of a test name, and any test whose name matches
|
||||||
that value will get run. For example, since two of our tests' names contain
|
that value will get run. For example, since two of our tests’ names contain
|
||||||
`add`, we can run those two by running `cargo test add`:
|
`add`, we can run those two by running `cargo test add`:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cargo test add
|
$ cargo test add
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
|
||||||
Running target/debug/deps/adder-06a75b4a1f2515e9
|
Running target/debug/deps/adder-06a75b4a1f2515e9
|
||||||
|
|
||||||
running 2 tests
|
running 2 tests
|
||||||
@ -1075,16 +1039,8 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
|
|||||||
```
|
```
|
||||||
|
|
||||||
This ran all tests with `add` in the name. Also note that the module in which
|
This ran all tests with `add` in the name. Also note that the module in which
|
||||||
tests appear becomes part of the test's name, so we can run all the tests in a
|
tests appear becomes part of the test’s name, so we can run all the tests in a
|
||||||
module by filtering on the module's name.
|
module by filtering on the module’s name.
|
||||||
|
|
||||||
<!-- in what kind of situation might you need to run only some tests, when you
|
|
||||||
have lots and lots in a program? -->
|
|
||||||
<!-- We covered this in the first paragraph of the "Running a Subset of Tests
|
|
||||||
by Name" section, do you think it should be repeated so soon? Most people who
|
|
||||||
use tests have sufficient motivation for wanting to run a subset of the tests,
|
|
||||||
they just need to know how to do it with Rust, so we don't think this is a
|
|
||||||
point that needs to be emphasized multiple times. /Carol -->
|
|
||||||
|
|
||||||
### Ignore Some Tests Unless Specifically Requested
|
### Ignore Some Tests Unless Specifically Requested
|
||||||
|
|
||||||
@ -1109,13 +1065,13 @@ fn expensive_test() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
We add the `#[ignore]` line to the test we want to exclude, after `#[test]`.
|
We add the `#[ignore]` line to the test we want to exclude, after `#[test]`.
|
||||||
Now if we run our tests, we'll see `it_works` runs, but `expensive_test` does
|
Now if we run our tests, we’ll see `it_works` runs, but `expensive_test` does
|
||||||
not:
|
not:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cargo test
|
$ cargo test
|
||||||
Compiling adder v0.1.0 (file:///projects/adder)
|
Compiling adder v0.1.0 (file:///projects/adder)
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.24 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.24 secs
|
||||||
Running target/debug/deps/adder-ce99bcc2479f4607
|
Running target/debug/deps/adder-ce99bcc2479f4607
|
||||||
|
|
||||||
running 2 tests
|
running 2 tests
|
||||||
@ -1134,20 +1090,9 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
|
|||||||
`expensive_test` is listed as `ignored`. If we want to run only the ignored
|
`expensive_test` is listed as `ignored`. If we want to run only the ignored
|
||||||
tests, we can ask for them to be run with `cargo test -- --ignored`:
|
tests, we can ask for them to be run with `cargo test -- --ignored`:
|
||||||
|
|
||||||
<!-- what does the double `-- --` mean? That seems interesting -->
|
|
||||||
<!-- We covered that in the second paragraph after the "Controlling How Tests
|
|
||||||
are Run" heading, and this section is beneath that heading, so I don't think a
|
|
||||||
back reference is needed /Carol -->
|
|
||||||
|
|
||||||
<!-- is that right, this way the program knows to run only the test with
|
|
||||||
`ignore` if we add this, or it knows to run all tests? -->
|
|
||||||
<!-- Is this unclear from the output that shows `expensive_test` was run and
|
|
||||||
the `it_works` test does not appear? I'm not sure how to make this clearer.
|
|
||||||
/Carol -->
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cargo test -- --ignored
|
$ cargo test -- --ignored
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
|
||||||
Running target/debug/deps/adder-ce99bcc2479f4607
|
Running target/debug/deps/adder-ce99bcc2479f4607
|
||||||
|
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -1157,7 +1102,7 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
|||||||
```
|
```
|
||||||
|
|
||||||
By controlling which tests run, you can make sure your `cargo test` results
|
By controlling which tests run, you can make sure your `cargo test` results
|
||||||
will be fast. When you're at a point that it makes sense to check the results
|
will be fast. When you’re at a point that it makes sense to check the results
|
||||||
of the `ignored` tests and you have time to wait for the results, you can
|
of the `ignored` tests and you have time to wait for the results, you can
|
||||||
choose to run `cargo test -- --ignored` instead.
|
choose to run `cargo test -- --ignored` instead.
|
||||||
|
|
||||||
@ -1180,7 +1125,7 @@ doing what you expect them to separately and together.
|
|||||||
The purpose of unit tests is to test each unit of code in isolation from the
|
The purpose of unit tests is to test each unit of code in isolation from the
|
||||||
rest of the code, in order to be able to quickly pinpoint where code is and is
|
rest of the code, in order to be able to quickly pinpoint where code is and is
|
||||||
not working as expected. We put unit tests in the *src* directory, in each file
|
not working as expected. We put unit tests in the *src* directory, in each file
|
||||||
with the code that they're testing. The convention is that we create a module
|
with the code that they’re testing. The convention is that we create a module
|
||||||
named `tests` in each file to contain the test functions, and we annotate the
|
named `tests` in each file to contain the test functions, and we annotate the
|
||||||
module with `cfg(test)`.
|
module with `cfg(test)`.
|
||||||
|
|
||||||
@ -1189,8 +1134,8 @@ module with `cfg(test)`.
|
|||||||
The `#[cfg(test)]` annotation on the tests module tells Rust to compile and run
|
The `#[cfg(test)]` annotation on the tests module tells Rust to compile and run
|
||||||
the test code only when we run `cargo test`, and not when we run `cargo build`.
|
the test code only when we run `cargo test`, and not when we run `cargo build`.
|
||||||
This saves compile time when we only want to build the library, and saves space
|
This saves compile time when we only want to build the library, and saves space
|
||||||
in the resulting compiled artifact since the tests are not included. We'll see
|
in the resulting compiled artifact since the tests are not included. We’ll see
|
||||||
that since integration tests go in a different directory, they don't need the
|
that since integration tests go in a different directory, they don’t need the
|
||||||
`#[cfg(test)]` annotation. Because unit tests go in the same files as the code,
|
`#[cfg(test)]` annotation. Because unit tests go in the same files as the code,
|
||||||
though, we use `#[cfg(test)]`to specify that they should not be included in the
|
though, we use `#[cfg(test)]`to specify that they should not be included in the
|
||||||
compiled result.
|
compiled result.
|
||||||
@ -1210,19 +1155,19 @@ mod tests {
|
|||||||
```
|
```
|
||||||
|
|
||||||
This is the automatically generated test module. The attribute `cfg` stands for
|
This is the automatically generated test module. The attribute `cfg` stands for
|
||||||
*configruation*, and tells Rust that the following item should only be included
|
*configuration*, and tells Rust that the following item should only be included
|
||||||
given a certain configuration. In this case, the configuration is `test`,
|
given a certain configuration option. In this case, the configuration option is
|
||||||
provided by Rust for compiling and running tests. By using this attribute,
|
`test`, provided by Rust for compiling and running tests. By using this
|
||||||
Cargo only compiles our test code if we actively run the tests with `cargo
|
attribute, Cargo only compiles our test code if we actively run the tests with
|
||||||
test`. This includes any helper functions that might be within this module, in
|
`cargo test`. This includes any helper functions that might be within this
|
||||||
addition to the functions annotated with `#[test]`.
|
module, in addition to the functions annotated with `#[test]`.
|
||||||
|
|
||||||
#### Testing Private Functions
|
#### Testing Private Functions
|
||||||
|
|
||||||
There's debate within the testing community about whether private functions
|
There’s debate within the testing community about whether private functions
|
||||||
should be tested directly or not, and other languages make it difficult or
|
should be tested directly or not, and other languages make it difficult or
|
||||||
impossible to test private functions. Regardless of which testing ideology you
|
impossible to test private functions. Regardless of which testing ideology you
|
||||||
adhere to, Rust's privacy rules do allow you to test private functions.
|
adhere to, Rust’s privacy rules do allow you to test private functions.
|
||||||
Consider the code in Listing 11-12 with the private function `internal_adder`:
|
Consider the code in Listing 11-12 with the private function `internal_adder`:
|
||||||
|
|
||||||
Filename: src/lib.rs
|
Filename: src/lib.rs
|
||||||
@ -1249,25 +1194,17 @@ mod tests {
|
|||||||
|
|
||||||
Listing 11-12: Testing a private function
|
Listing 11-12: Testing a private function
|
||||||
|
|
||||||
<!-- I'm not clear on why we would assume this might not be fine, why are we
|
|
||||||
highlighting this specifically? -->
|
|
||||||
<!-- We're addressing experience that the reader might bring with them from
|
|
||||||
other languages where this is not allowed; I added a sentence mentioning "other
|
|
||||||
languages" at the beginning of this section. Also testing private functions
|
|
||||||
from integration tests is not allowed, so if you did want to do this, you'd
|
|
||||||
have to do it in unit tests. /Carol -->
|
|
||||||
|
|
||||||
Note that the `internal_adder` function is not marked as `pub`, but because
|
Note that the `internal_adder` function is not marked as `pub`, but because
|
||||||
tests are just Rust code and the `tests` module is just another module, we can
|
tests are just Rust code and the `tests` module is just another module, we can
|
||||||
import and call `internal_adder` in a test just fine. If you don't think
|
import and call `internal_adder` in a test just fine. If you don’t think
|
||||||
private functions should be tested, there's nothing in Rust that will compel
|
private functions should be tested, there’s nothing in Rust that will compel
|
||||||
you to do so.
|
you to do so.
|
||||||
|
|
||||||
### Integration Tests
|
### Integration Tests
|
||||||
|
|
||||||
In Rust, integration tests are entirely external to your library. They use your
|
In Rust, integration tests are entirely external to your library. They use your
|
||||||
library in the same way any other code would, which means they can only call
|
library in the same way any other code would, which means they can only call
|
||||||
functions that are part of your library's public API. Their purpose is to test
|
functions that are part of your library’s public API. Their purpose is to test
|
||||||
that many parts of your library work correctly together. Units of code that
|
that many parts of your library work correctly together. Units of code that
|
||||||
work correctly by themselves could have problems when integrated, so test
|
work correctly by themselves could have problems when integrated, so test
|
||||||
coverage of the integrated code is important as well. To create integration
|
coverage of the integrated code is important as well. To create integration
|
||||||
@ -1278,10 +1215,10 @@ tests, you first need a *tests* directory.
|
|||||||
To write integration tests for our code, we need to make a *tests* directory at
|
To write integration tests for our code, we need to make a *tests* directory at
|
||||||
the top level of our project directory, next to *src*. Cargo knows to look for
|
the top level of our project directory, next to *src*. Cargo knows to look for
|
||||||
integration test files in this directory. We can then make as many test files
|
integration test files in this directory. We can then make as many test files
|
||||||
as we'd like in this directory, and Cargo will compile each of the files as an
|
as we’d like in this directory, and Cargo will compile each of the files as an
|
||||||
individual crate.
|
individual crate.
|
||||||
|
|
||||||
Let's give it a try! Keep the code from Listing 11-12 in *src/lib.rs*. Make a
|
Let’s give it a try! Keep the code from Listing 11-12 in *src/lib.rs*. Make a
|
||||||
*tests* directory, then make a new file named *tests/integration_test.rs*, and
|
*tests* directory, then make a new file named *tests/integration_test.rs*, and
|
||||||
enter the code in Listing 11-13.
|
enter the code in Listing 11-13.
|
||||||
|
|
||||||
@ -1298,21 +1235,21 @@ fn it_adds_two() {
|
|||||||
|
|
||||||
Listing 11-13: An integration test of a function in the `adder` crate
|
Listing 11-13: An integration test of a function in the `adder` crate
|
||||||
|
|
||||||
We've added `extern crate adder` at the top, which we didn't need in the unit
|
We’ve added `extern crate adder` at the top, which we didn’t need in the unit
|
||||||
tests. This is because each test in the `tests` directory is an entirely
|
tests. This is because each test in the `tests` directory is an entirely
|
||||||
separate crate, so we need to import our library into each of them. Integration
|
separate crate, so we need to import our library into each of them. Integration
|
||||||
tests use the library like any other consumer of it would, by importing the
|
tests use the library like any other consumer of it would, by importing the
|
||||||
crate and using only the public API.
|
crate and using only the public API.
|
||||||
|
|
||||||
We don't need to annotate any code in *tests/integration_test.rs* with
|
We don’t need to annotate any code in *tests/integration_test.rs* with
|
||||||
`#[cfg(test)]`. Cargo treats the `tests` directory specially and will only
|
`#[cfg(test)]`. Cargo treats the `tests` directory specially and will only
|
||||||
compile files in this directory if we run `cargo test`. Let's try running
|
compile files in this directory if we run `cargo test`. Let’s try running
|
||||||
`cargo test` now:
|
`cargo test` now:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo test
|
cargo test
|
||||||
Compiling adder v0.1.0 (file:///projects/adder)
|
Compiling adder v0.1.0 (file:///projects/adder)
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.31 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs
|
||||||
Running target/debug/deps/adder-abcabcabc
|
Running target/debug/deps/adder-abcabcabc
|
||||||
|
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -1334,11 +1271,6 @@ running 0 tests
|
|||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- what are the doc tests? How do we tell the difference between unit and
|
|
||||||
integration tests here? -->
|
|
||||||
<!-- We mentioned documentation tests in the beginning of this chapter /Carol
|
|
||||||
-->
|
|
||||||
|
|
||||||
Now we have three sections of output: the unit tests, the integration test, and
|
Now we have three sections of output: the unit tests, the integration test, and
|
||||||
the doc tests. The first section for the unit tests is the same as we have been
|
the doc tests. The first section for the unit tests is the same as we have been
|
||||||
seeing: one line for each unit test (we have one named `internal` that we added
|
seeing: one line for each unit test (we have one named `internal` that we added
|
||||||
@ -1346,7 +1278,7 @@ in Listing 11-12), then a summary line for the unit tests.
|
|||||||
|
|
||||||
The integration tests section starts with the line that says `Running
|
The integration tests section starts with the line that says `Running
|
||||||
target/debug/deps/integration-test-ce99bcc2479f4607` (the hash at the end of
|
target/debug/deps/integration-test-ce99bcc2479f4607` (the hash at the end of
|
||||||
your output will be different). Then there's a line for each test function in
|
your output will be different). Then there’s a line for each test function in
|
||||||
that integration test, and a summary line for the results of the integration
|
that integration test, and a summary line for the results of the integration
|
||||||
test just before the `Doc-tests adder` section starts.
|
test just before the `Doc-tests adder` section starts.
|
||||||
|
|
||||||
@ -1357,13 +1289,13 @@ section. Each integration test file gets its own section, so if we add more
|
|||||||
files in the *tests* directory, there will be more integration test sections.
|
files in the *tests* directory, there will be more integration test sections.
|
||||||
|
|
||||||
We can still run a particular integration test function by specifying the test
|
We can still run a particular integration test function by specifying the test
|
||||||
function's name as an argument to `cargo test`. To run all of the tests in a
|
function’s name as an argument to `cargo test`. To run all of the tests in a
|
||||||
particular integration test file, use the `--test` argument of `cargo test`
|
particular integration test file, use the `--test` argument of `cargo test`
|
||||||
followed by the name of the file:
|
followed by the name of the file:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cargo test --test integration_test
|
$ cargo test --test integration_test
|
||||||
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
|
||||||
Running target/debug/integration_test-952a27e0126bb565
|
Running target/debug/integration_test-952a27e0126bb565
|
||||||
|
|
||||||
running 1 test
|
running 1 test
|
||||||
@ -1378,12 +1310,12 @@ This tests only the file that we specified from the *tests* directory.
|
|||||||
|
|
||||||
As you add more integration tests, you may want to make more than one file in
|
As you add more integration tests, you may want to make more than one file in
|
||||||
the *tests* directory to help organize them; for example, to group the test
|
the *tests* directory to help organize them; for example, to group the test
|
||||||
functions by the functionality they're testing. As we mentioned, each file in
|
functions by the functionality they’re testing. As we mentioned, each file in
|
||||||
the *tests* directory is compiled as its own separate crate.
|
the *tests* directory is compiled as its own separate crate.
|
||||||
|
|
||||||
Treating each integration test file as its own crate is useful to create
|
Treating each integration test file as its own crate is useful to create
|
||||||
separate scopes that are more like the way end users will be using your crate.
|
separate scopes that are more like the way end users will be using your crate.
|
||||||
However, this means files in the *tests* directory don't share the same
|
However, this means files in the *tests* directory don’t share the same
|
||||||
behavior as files in *src* do that we learned about in Chapter 7 regarding how
|
behavior as files in *src* do that we learned about in Chapter 7 regarding how
|
||||||
to separate code into modules and files.
|
to separate code into modules and files.
|
||||||
|
|
||||||
@ -1403,8 +1335,8 @@ pub fn setup() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If we run the tests again, we'll see a new section in the test output for the
|
If we run the tests again, we’ll see a new section in the test output for the
|
||||||
*common.rs* file, even though this file doesn't contain any test functions, nor
|
*common.rs* file, even though this file doesn’t contain any test functions, nor
|
||||||
are we calling the `setup` function from anywhere:
|
are we calling the `setup` function from anywhere:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -1433,23 +1365,20 @@ running 0 tests
|
|||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
|
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- The new section is lines 6-10, will ghost everything else in libreoffice
|
|
||||||
/Carol -->
|
|
||||||
|
|
||||||
Having `common` show up in the test results with `running 0 tests` displayed
|
Having `common` show up in the test results with `running 0 tests` displayed
|
||||||
for it is not what we wanted; we just wanted to be able to share some code with
|
for it is not what we wanted; we just wanted to be able to share some code with
|
||||||
the other integration test files.
|
the other integration test files.
|
||||||
|
|
||||||
In order to not have `common` show up in the test output, we need to use the
|
In order to not have `common` show up in the test output, we need to use the
|
||||||
other method of extracting code into a file that we learned about in Chapter 7:
|
other method of extracting code into a file that we learned about in Chapter 7:
|
||||||
instead of creating *tests/common.rs*, we'll create *tests/common/mod.rs*. When
|
instead of creating *tests/common.rs*, we’ll create *tests/common/mod.rs*. When
|
||||||
we move the `setup` function code into *tests/common/mod.rs* and get rid of the
|
we move the `setup` function code into *tests/common/mod.rs* and get rid of the
|
||||||
*tests/common.rs* file, the section in the test output will no longer show up.
|
*tests/common.rs* file, the section in the test output will no longer show up.
|
||||||
Files in subdirectories of the *tests* directory do not get compiled as
|
Files in subdirectories of the *tests* directory do not get compiled as
|
||||||
separate crates or have sections in the test output.
|
separate crates or have sections in the test output.
|
||||||
|
|
||||||
Once we have *tests/common/mod.rs*, we can use it from any of the integration
|
Once we have *tests/common/mod.rs*, we can use it from any of the integration
|
||||||
test files as a module. Here's an example of calling the `setup` function from
|
test files as a module. Here’s an example of calling the `setup` function from
|
||||||
the `it_adds_two` test in *tests/integration_test.rs*:
|
the `it_adds_two` test in *tests/integration_test.rs*:
|
||||||
|
|
||||||
Filename: tests/integration_test.rs
|
Filename: tests/integration_test.rs
|
||||||
@ -1473,7 +1402,7 @@ function.
|
|||||||
#### Integration Tests for Binary Crates
|
#### Integration Tests for Binary Crates
|
||||||
|
|
||||||
If our project is a binary crate that only contains a *src/main.rs* and does
|
If our project is a binary crate that only contains a *src/main.rs* and does
|
||||||
not have a *src/lib.rs*, we aren't able to create integration tests in the
|
not have a *src/lib.rs*, we aren’t able to create integration tests in the
|
||||||
*tests* directory and use `extern crate` to import functions defined in
|
*tests* directory and use `extern crate` to import functions defined in
|
||||||
*src/main.rs*. Only library crates expose functions that other crates are able
|
*src/main.rs*. Only library crates expose functions that other crates are able
|
||||||
to call and use; binary crates are meant to be run on their own.
|
to call and use; binary crates are meant to be run on their own.
|
||||||
@ -1487,14 +1416,14 @@ small amount of code does not need to be tested.
|
|||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
Rust's testing features provide a way to specify how code should function to
|
Rust’s testing features provide a way to specify how code should function to
|
||||||
ensure it continues to work as we expect even as we make changes. Unit tests
|
ensure it continues to work as we expect even as we make changes. Unit tests
|
||||||
exercise different parts of a library separately and can test private
|
exercise different parts of a library separately and can test private
|
||||||
implementation details. Integration tests cover the use of many parts of the
|
implementation details. Integration tests cover the use of many parts of the
|
||||||
library working together, and they use the library's public API to test the
|
library working together, and they use the library’s public API to test the
|
||||||
code in the same way external code will use it. Even though Rust's type system
|
code in the same way external code will use it. Even though Rust’s type system
|
||||||
and ownership rules help prevent some kinds of bugs, tests are still important
|
and ownership rules help prevent some kinds of bugs, tests are still important
|
||||||
to help reduce logic bugs having to do with how your code is expected to behave.
|
to help reduce logic bugs having to do with how your code is expected to behave.
|
||||||
|
|
||||||
Let's put together the knowledge from this chapter and other previous chapters
|
Let’s put together the knowledge from this chapter and other previous chapters
|
||||||
and work on a project in the next chapter!
|
and work on a project in the next chapter!
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -57,13 +57,13 @@
|
|||||||
- [Running tests](ch11-02-running-tests.md)
|
- [Running tests](ch11-02-running-tests.md)
|
||||||
- [Test Organization](ch11-03-test-organization.md)
|
- [Test Organization](ch11-03-test-organization.md)
|
||||||
|
|
||||||
- [An I/O Project](ch12-00-an-io-project.md)
|
- [An I/O Project: Building a Command Line Program](ch12-00-an-io-project.md)
|
||||||
- [Accepting Command Line Arguments](ch12-01-accepting-command-line-arguments.md)
|
- [Accepting Command Line Arguments](ch12-01-accepting-command-line-arguments.md)
|
||||||
- [Reading a File](ch12-02-reading-a-file.md)
|
- [Reading a File](ch12-02-reading-a-file.md)
|
||||||
- [Improving Error Handling and Modularity](ch12-03-improving-error-handling-and-modularity.md)
|
- [Refactoring to Improve Modularity and Error Handling](ch12-03-improving-error-handling-and-modularity.md)
|
||||||
- [Testing the Library's Functionality](ch12-04-testing-the-librarys-functionality.md)
|
- [Testing the Library's Functionality](ch12-04-testing-the-librarys-functionality.md)
|
||||||
- [Working with Environment Variables](ch12-05-working-with-environment-variables.md)
|
- [Working with Environment Variables](ch12-05-working-with-environment-variables.md)
|
||||||
- [Writing to `stderr` instead of `stdout`](ch12-06-writing-to-stderr-instead-of-stdout.md)
|
- [Writing Error Messages to `stderr` Instead of `stdout`](ch12-06-writing-to-stderr-instead-of-stdout.md)
|
||||||
|
|
||||||
## Thinking in Rust
|
## Thinking in Rust
|
||||||
|
|
||||||
|
@ -6,8 +6,12 @@ For resources in languages other than English. Most are still in progress; see
|
|||||||
[label]: https://github.com/rust-lang/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations
|
[label]: https://github.com/rust-lang/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations
|
||||||
|
|
||||||
- [Português](https://coreh.github.io/rust-book-pt-br/)
|
- [Português](https://coreh.github.io/rust-book-pt-br/)
|
||||||
- [Tiếng việt](https://rust-vietnam.github.io/book/)
|
- [Tiếng việt](https://github.com/hngnaig/rust-lang-book/tree/vi-VN)
|
||||||
- [简体中文](http://www.broadview.com.cn/article/144), [alternate](https://github.com/KaiserY/trpl-zh-cn)
|
- [简体中文](http://www.broadview.com.cn/article/144), [alternate](https://github.com/KaiserY/trpl-zh-cn)
|
||||||
- [українська мова](https://github.com/pavloslav/rust-book-uk-ua)
|
- [українська мова](https://github.com/pavloslav/rust-book-uk-ua)
|
||||||
- [Español](https://github.com/z1mvader/book)
|
- [Español](https://github.com/z1mvader/book)
|
||||||
- [Italiano](https://github.com/CodelessFuture/trpl2-it)
|
- [Italiano](https://github.com/CodelessFuture/trpl2-it)
|
||||||
|
- [Русский](https://github.com/iDeBugger/rust-book-ru)
|
||||||
|
- [한국어](https://github.com/rinthel/rust-lang-book-ko)
|
||||||
|
- [日本語](https://github.com/hazama-yuinyan/book)
|
||||||
|
- [Français](https://github.com/quadrifoglio/rust-book-fr)
|
||||||
|
@ -30,6 +30,19 @@ Rust is installed now. Great!
|
|||||||
Of course, if you disapprove of the `curl | sh` pattern, you can download, inspect
|
Of course, if you disapprove of the `curl | sh` pattern, you can download, inspect
|
||||||
and run the script however you like.
|
and run the script however you like.
|
||||||
|
|
||||||
|
The installation script automatically adds Rust to your system PATH after your next login.
|
||||||
|
If you want to start using Rust right away, run the following command in your shell:
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ source $HOME/.cargo/env
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, add the following line to your `~/.bash_profile`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
|
```
|
||||||
|
|
||||||
### Installing on Windows
|
### Installing on Windows
|
||||||
|
|
||||||
On Windows, go to [https://rustup.rs](https://rustup.rs/)<!-- ignore --> and
|
On Windows, go to [https://rustup.rs](https://rustup.rs/)<!-- ignore --> and
|
||||||
|
@ -327,7 +327,7 @@ use `s1` after `s2` is created:
|
|||||||
let s1 = String::from("hello");
|
let s1 = String::from("hello");
|
||||||
let s2 = s1;
|
let s2 = s1;
|
||||||
|
|
||||||
println!("{}", s1);
|
println!("{}, world!", s1);
|
||||||
```
|
```
|
||||||
|
|
||||||
You’ll get an error like this because Rust prevents you from using the
|
You’ll get an error like this because Rust prevents you from using the
|
||||||
|
@ -55,14 +55,35 @@ struct</span>
|
|||||||
To get a specific value from a struct, we can use dot notation. If we wanted
|
To get a specific value from a struct, we can use dot notation. If we wanted
|
||||||
just this user’s email address, we can use `user1.email` wherever we want to
|
just this user’s email address, we can use `user1.email` wherever we want to
|
||||||
use this value. To change a value in a struct, if the instance is mutable, we
|
use this value. To change a value in a struct, if the instance is mutable, we
|
||||||
can use the dot notation and assign into a particular field, such as
|
can use the dot notation and assign into a particular field. Listing 5-3 shows
|
||||||
`user1.email = String::from("someone-else@example.com");`.
|
how to change the value in the `email` field of a mutable `User` instance:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
# struct User {
|
||||||
|
# username: String,
|
||||||
|
# email: String,
|
||||||
|
# sign_in_count: u64,
|
||||||
|
# active: bool,
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
let mut user1 = User {
|
||||||
|
email: String::from("someone@example.com"),
|
||||||
|
username: String::from("someusername123"),
|
||||||
|
active: true,
|
||||||
|
sign_in_count: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
user1.email = String::from("anotheremail@example.com");
|
||||||
|
```
|
||||||
|
|
||||||
|
<span class="caption">Listing 5-3: Changing the value in the `email` field of a
|
||||||
|
`User` instance</span>
|
||||||
|
|
||||||
### Field Init Shorthand when Variables Have the Same Name as Fields
|
### Field Init Shorthand when Variables Have the Same Name as Fields
|
||||||
|
|
||||||
If you have variables with the same names as struct fields, you can use *field
|
If you have variables with the same names as struct fields, you can use *field
|
||||||
init shorthand*. This can make functions that create new instances of structs
|
init shorthand*. This can make functions that create new instances of structs
|
||||||
more concise. The function named `build_user` shown here in Listing 5-3 has
|
more concise. The function named `build_user` shown here in Listing 5-4 has
|
||||||
parameters named `email` and `username`. The function creates and returns a
|
parameters named `email` and `username`. The function creates and returns a
|
||||||
`User` instance:
|
`User` instance:
|
||||||
|
|
||||||
@ -84,13 +105,13 @@ fn build_user(email: String, username: String) -> User {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-3: A `build_user` function that takes an email
|
<span class="caption">Listing 5-4: A `build_user` function that takes an email
|
||||||
and username and returns a `User` instance</span>
|
and username and returns a `User` instance</span>
|
||||||
|
|
||||||
Because the parameter names `email` and `username` are the same as the `User`
|
Because the parameter names `email` and `username` are the same as the `User`
|
||||||
struct's field names `email` and `username`, we can write `build_user` without
|
struct's field names `email` and `username`, we can write `build_user` without
|
||||||
the repetition of `email` and `username` as shown in Listing 5-4. This version
|
the repetition of `email` and `username` as shown in Listing 5-5. This version
|
||||||
of `build_user` behaves the same way as the one in Listing 5-3. The field init
|
of `build_user` behaves the same way as the one in Listing 5-4. The field init
|
||||||
syntax can make cases like this shorter to write, especially when structs have
|
syntax can make cases like this shorter to write, especially when structs have
|
||||||
many fields.
|
many fields.
|
||||||
|
|
||||||
@ -112,14 +133,14 @@ fn build_user(email: String, username: String) -> User {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-4: A `build_user` function that uses field init
|
<span class="caption">Listing 5-5: A `build_user` function that uses field init
|
||||||
syntax since the `email` and `username` parameters have the same name as struct
|
syntax since the `email` and `username` parameters have the same name as struct
|
||||||
fields</span>
|
fields</span>
|
||||||
|
|
||||||
### Creating Instances From Other Instances With Struct Update Syntax
|
### Creating Instances From Other Instances With Struct Update Syntax
|
||||||
|
|
||||||
It's often useful to create a new instance from an old instance, using most of
|
It's often useful to create a new instance from an old instance, using most of
|
||||||
the old instance's values but changing some. Listing 5-5 shows an example of
|
the old instance's values but changing some. Listing 5-6 shows an example of
|
||||||
creating a new `User` instance in `user2` by setting the values of `email` and
|
creating a new `User` instance in `user2` by setting the values of `email` and
|
||||||
`username` but using the same values for the rest of the fields from the
|
`username` but using the same values for the rest of the fields from the
|
||||||
`user1` instance we created in Listing 5-2:
|
`user1` instance we created in Listing 5-2:
|
||||||
@ -147,13 +168,13 @@ let user2 = User {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-5: Creating a new `User` instance, `user2`, and
|
<span class="caption">Listing 5-6: Creating a new `User` instance, `user2`, and
|
||||||
setting some fields to the values of the same fields from `user1`</span>
|
setting some fields to the values of the same fields from `user1`</span>
|
||||||
|
|
||||||
The *struct update syntax* achieves the same effect as the code in Listing
|
The *struct update syntax* achieves the same effect as the code in Listing 5-6
|
||||||
5-5 using less code. The struct update syntax uses `..` to specify that the
|
using less code. The struct update syntax uses `..` to specify that the
|
||||||
remaining fields not set explicitly should have the same value as the fields in
|
remaining fields not set explicitly should have the same value as the fields in
|
||||||
the given instance. The code in Listing 5-6 also creates an instance in `user2`
|
the given instance. The code in Listing 5-7 also creates an instance in `user2`
|
||||||
that has a different value for `email` and `username` but has the same values
|
that has a different value for `email` and `username` but has the same values
|
||||||
for the `active` and `sign_in_count` fields that `user1` has:
|
for the `active` and `sign_in_count` fields that `user1` has:
|
||||||
|
|
||||||
@ -179,7 +200,7 @@ let user2 = User {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing5-6: Using struct update syntax to set a new
|
<span class="caption">Listing 5-7: Using struct update syntax to set a new
|
||||||
`email` and `username` values for a `User` instance but use the rest of the
|
`email` and `username` values for a `User` instance but use the rest of the
|
||||||
values from the fields of the instance in the `user1` variable</span>
|
values from the fields of the instance in the `user1` variable</span>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ refactor the program until we’re using structs instead.
|
|||||||
|
|
||||||
Let’s make a new binary project with Cargo called *rectangles* that will take
|
Let’s make a new binary project with Cargo called *rectangles* that will take
|
||||||
the length and width of a rectangle specified in pixels and will calculate the
|
the length and width of a rectangle specified in pixels and will calculate the
|
||||||
area of the rectangle. Listing 5-7 shows a short program with one way of doing
|
area of the rectangle. Listing 5-8 shows a short program with one way of doing
|
||||||
just that in our project’s *src/main.rs*:
|
just that in our project’s *src/main.rs*:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
@ -27,7 +27,7 @@ fn area(length: u32, width: u32) -> u32 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-7: Calculating the area of a rectangle
|
<span class="caption">Listing 5-8: Calculating the area of a rectangle
|
||||||
specified by its length and width in separate variables</span>
|
specified by its length and width in separate variables</span>
|
||||||
|
|
||||||
Now, run this program using `cargo run`:
|
Now, run this program using `cargo run`:
|
||||||
@ -38,7 +38,7 @@ The area of the rectangle is 1500 square pixels.
|
|||||||
|
|
||||||
### Refactoring with Tuples
|
### Refactoring with Tuples
|
||||||
|
|
||||||
Even though Listing 5-7 works and figures out the area of the rectangle by
|
Even though Listing 5-8 works and figures out the area of the rectangle by
|
||||||
calling the `area` function with each dimension, we can do better. The length
|
calling the `area` function with each dimension, we can do better. The length
|
||||||
and the width are related to each other because together they describe one
|
and the width are related to each other because together they describe one
|
||||||
rectangle.
|
rectangle.
|
||||||
@ -54,7 +54,7 @@ function we wrote has two parameters. The parameters are related, but that’s
|
|||||||
not expressed anywhere in our program. It would be more readable and more
|
not expressed anywhere in our program. It would be more readable and more
|
||||||
manageable to group length and width together. We’ve already discussed one way
|
manageable to group length and width together. We’ve already discussed one way
|
||||||
we might do that in the Grouping Values into Tuples section of Chapter 3 on
|
we might do that in the Grouping Values into Tuples section of Chapter 3 on
|
||||||
page XX: by using tuples. Listing 5-8 shows another version of our program that
|
page XX: by using tuples. Listing 5-9 shows another version of our program that
|
||||||
uses tuples:
|
uses tuples:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
@ -94,7 +94,7 @@ our code.
|
|||||||
|
|
||||||
We use structs to add meaning by labeling the data. We can transform the tuple
|
We use structs to add meaning by labeling the data. We can transform the tuple
|
||||||
we’re using into a data type with a name for the whole as well as names for the
|
we’re using into a data type with a name for the whole as well as names for the
|
||||||
parts, as shown in Listing 5-9:
|
parts, as shown in Listing 5-10:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ fn area(rectangle: &Rectangle) -> u32 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-9: Defining a `Rectangle` struct</span>
|
<span class="caption">Listing 5-10: Defining a `Rectangle` struct</span>
|
||||||
|
|
||||||
Here we’ve defined a struct and named it `Rectangle`. Inside the `{}` we
|
Here we’ve defined a struct and named it `Rectangle`. Inside the `{}` we
|
||||||
defined the fields as `length` and `width`, both of which have type `u32`. Then
|
defined the fields as `length` and `width`, both of which have type `u32`. Then
|
||||||
@ -143,7 +143,7 @@ and `1`—a win for clarity.
|
|||||||
|
|
||||||
It would be helpful to be able to print out an instance of the `Rectangle`
|
It would be helpful to be able to print out an instance of the `Rectangle`
|
||||||
while we’re debugging our program in order to see the values for all its
|
while we’re debugging our program in order to see the values for all its
|
||||||
fields. Listing 5-10 uses the `println!` macro as we have been in earlier
|
fields. Listing 5-11 uses the `println!` macro as we have been in earlier
|
||||||
chapters:
|
chapters:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
@ -161,7 +161,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-10: Attempting to print a `Rectangle`
|
<span class="caption">Listing 5-11: Attempting to print a `Rectangle`
|
||||||
instance</span>
|
instance</span>
|
||||||
|
|
||||||
When we run this code, we get an error with this core message:
|
When we run this code, we get an error with this core message:
|
||||||
@ -209,7 +209,7 @@ crate, add `#[derive(Debug)]` or manually implement it
|
|||||||
Rust *does* include functionality to print out debugging information, but we
|
Rust *does* include functionality to print out debugging information, but we
|
||||||
have to explicitly opt-in to make that functionality available for our struct.
|
have to explicitly opt-in to make that functionality available for our struct.
|
||||||
To do that, we add the annotation `#[derive(Debug)]` just before the struct
|
To do that, we add the annotation `#[derive(Debug)]` just before the struct
|
||||||
definition, as shown in Listing 5-11:
|
definition, as shown in Listing 5-12:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing5-11: Adding the annotation to derive the `Debug`
|
<span class="caption">Listing 5-12: Adding the annotation to derive the `Debug`
|
||||||
trait and printing the `Rectangle` instance using debug formatting</span>
|
trait and printing the `Rectangle` instance using debug formatting</span>
|
||||||
|
|
||||||
Now when we run the program, we won’t get any errors and we’ll see the
|
Now when we run the program, we won’t get any errors and we’ll see the
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
## Method Syntax
|
## Method Syntax
|
||||||
|
|
||||||
*Methods* are similar to functions: they’re declared with the `fn` keyword and
|
*Methods* are similar to functions: they’re declared with the `fn` keyword and
|
||||||
their name, they can have parameters and return values, and they contain some
|
their name, they can have parameters and a return value, and they contain some
|
||||||
code that is run when they’re called from somewhere else. However, methods are
|
code that is run when they’re called from somewhere else. However, methods are
|
||||||
different from functions in that they’re defined within the context of a struct
|
different from functions in that they’re defined within the context of a struct
|
||||||
(or an enum or a trait object, which we cover in Chapters 6 and 17,
|
(or an enum or a trait object, which we cover in Chapters 6 and 17,
|
||||||
@ -12,7 +12,7 @@ instance of the struct the method is being called on.
|
|||||||
|
|
||||||
Let’s change the `area` function that has a `Rectangle` instance as a parameter
|
Let’s change the `area` function that has a `Rectangle` instance as a parameter
|
||||||
and instead make an `area` method defined on the `Rectangle` struct, as shown
|
and instead make an `area` method defined on the `Rectangle` struct, as shown
|
||||||
in Listing 5-12:
|
in Listing 5-13:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-12: Defining an `area` method on the
|
<span class="caption">Listing 5-13: Defining an `area` method on the
|
||||||
`Rectangle` struct</span>
|
`Rectangle` struct</span>
|
||||||
|
|
||||||
To define the function within the context of `Rectangle`, we start an `impl`
|
To define the function within the context of `Rectangle`, we start an `impl`
|
||||||
@ -124,7 +124,7 @@ Let’s practice using methods by implementing a second method on the `Rectangle
|
|||||||
struct. This time, we want an instance of `Rectangle` to take another instance
|
struct. This time, we want an instance of `Rectangle` to take another instance
|
||||||
of `Rectangle` and return `true` if the second `Rectangle` can fit completely
|
of `Rectangle` and return `true` if the second `Rectangle` can fit completely
|
||||||
within `self`; otherwise it should return `false`. That is, we want to be able
|
within `self`; otherwise it should return `false`. That is, we want to be able
|
||||||
to write the program shown in Listing 5-13, once we’ve defined the `can_hold`
|
to write the program shown in Listing 5-14, once we’ve defined the `can_hold`
|
||||||
method:
|
method:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
@ -140,7 +140,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-13: Demonstration of using the as-yet-unwritten
|
<span class="caption">Listing 5-14: Demonstration of using the as-yet-unwritten
|
||||||
`can_hold` method</span>
|
`can_hold` method</span>
|
||||||
|
|
||||||
And the expected output would look like the following, because both dimensions
|
And the expected output would look like the following, because both dimensions
|
||||||
@ -164,7 +164,7 @@ calling the `can_hold` method. The return value of `can_hold` will be a
|
|||||||
boolean, and the implementation will check whether the length and width of
|
boolean, and the implementation will check whether the length and width of
|
||||||
`self` are both greater than the length and width of the other `Rectangle`,
|
`self` are both greater than the length and width of the other `Rectangle`,
|
||||||
respectively. Let’s add the new `can_hold` method to the `impl` block from
|
respectively. Let’s add the new `can_hold` method to the `impl` block from
|
||||||
Listing 5-12, shown in Listing 5-14:
|
Listing 5-13, shown in Listing 5-15:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
|
|
||||||
@ -186,10 +186,10 @@ impl Rectangle {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="caption">Listing 5-14: Implementing the `can_hold` method on
|
<span class="caption">Listing 5-15: Implementing the `can_hold` method on
|
||||||
`Rectangle` that takes another `Rectangle` instance as a parameter</span>
|
`Rectangle` that takes another `Rectangle` instance as a parameter</span>
|
||||||
|
|
||||||
When we run this code with the `main` function in Listing 5-13, we’ll get our
|
When we run this code with the `main` function in Listing 5-14, we’ll get our
|
||||||
desired output. Methods can take multiple parameters that we add to the
|
desired output. Methods can take multiple parameters that we add to the
|
||||||
signature after the `self` parameter, and those parameters work just like
|
signature after the `self` parameter, and those parameters work just like
|
||||||
parameters in functions.
|
parameters in functions.
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user