diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs index 0cd96881b5874..f12b0dadeacc1 100644 --- a/src/bootstrap/build/check.rs +++ b/src/bootstrap/build/check.rs @@ -13,13 +13,16 @@ //! This file implements the various regression test suites that we execute on //! our CI. -use std::fs; +use std::env; +use std::fs::{self, File}; +use std::io::prelude::*; use std::path::{PathBuf, Path}; use std::process::Command; use build_helper::output; +use bootstrap::{dylib_path, dylib_path_var}; -use build::{Build, Compiler}; +use build::{Build, Compiler, Mode}; /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler. /// @@ -222,3 +225,75 @@ fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) { cmd.arg("--test-args").arg(build.flags.args.join(" ")); build.run(&mut cmd); } + +/// Run all unit tests plus documentation tests for an entire crate DAG defined +/// by a `Cargo.toml` +/// +/// This is what runs tests for crates like the standard library, compiler, etc. +/// It essentially is the driver for running `cargo test`. +/// +/// Currently this runs all tests for a DAG by passing a bunch of `-p foo` +/// arguments, and those arguments are discovered from `Cargo.lock`. +pub fn krate(build: &Build, + compiler: &Compiler, + target: &str, + mode: Mode) { + let (name, path, features) = match mode { + Mode::Libstd => ("libstd", "src/rustc/std_shim", build.std_features()), + Mode::Libtest => ("libtest", "src/rustc/test_shim", String::new()), + Mode::Librustc => ("librustc", "src/rustc", build.rustc_features()), + _ => panic!("can only test libraries"), + }; + println!("Testing {} stage{} ({} -> {})", name, compiler.stage, + compiler.host, target); + + // Build up the base `cargo test` command. + let mut cargo = build.cargo(compiler, mode, target, "test"); + cargo.arg("--manifest-path") + .arg(build.src.join(path).join("Cargo.toml")) + .arg("--features").arg(features); + + // Generate a list of `-p` arguments to pass to the `cargo test` invocation + // by crawling the corresponding Cargo.lock file. + let lockfile = build.src.join(path).join("Cargo.lock"); + let mut contents = String::new(); + t!(t!(File::open(&lockfile)).read_to_string(&mut contents)); + let mut lines = contents.lines(); + while let Some(line) = lines.next() { + let prefix = "name = \""; + if !line.starts_with(prefix) { + continue + } + lines.next(); // skip `version = ...` + + // skip crates.io or otherwise non-path crates + if let Some(line) = lines.next() { + if line.starts_with("source") { + continue + } + } + + let crate_name = &line[prefix.len()..line.len() - 1]; + + // Right now jemalloc is our only target-specific crate in the sense + // that it's not present on all platforms. Custom skip it here for now, + // but if we add more this probably wants to get more generalized. + if crate_name.contains("jemalloc") { + continue + } + + cargo.arg("-p").arg(crate_name); + } + + // The tests are going to run with the *target* libraries, so we need to + // ensure that those libraries show up in the LD_LIBRARY_PATH equivalent. + // + // Note that to run the compiler we need to run with the *host* libraries, + // but our wrapper scripts arrange for that to be the case anyway. + let mut dylib_path = dylib_path(); + dylib_path.insert(0, build.sysroot_libdir(compiler, target)); + cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); + cargo.args(&build.flags.args); + + build.run(&mut cargo); +} diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index b38532fb3dfa7..44f161fb487f4 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -380,6 +380,15 @@ impl Build { check::compiletest(self, &compiler, target.target, "run-make", "run-make") } + CheckCrateStd { compiler } => { + check::krate(self, &compiler, target.target, Mode::Libstd) + } + CheckCrateTest { compiler } => { + check::krate(self, &compiler, target.target, Mode::Libtest) + } + CheckCrateRustc { compiler } => { + check::krate(self, &compiler, target.target, Mode::Librustc) + } DistDocs { stage } => dist::docs(self, stage, target.target), DistMingw { _dummy } => dist::mingw(self, target.target), @@ -485,6 +494,7 @@ impl Build { self.config.rust_debug_assertions.to_string()) .env("RUSTC_SNAPSHOT", &self.rustc) .env("RUSTC_SYSROOT", self.sysroot(compiler)) + .env("RUSTC_LIBDIR", self.rustc_libdir(compiler)) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()) .env("RUSTC_RPATH", self.config.rust_rpath.to_string()) .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) @@ -520,7 +530,6 @@ impl Build { if self.config.rust_optimize { cargo.arg("--release"); } - self.add_rustc_lib_path(compiler, &mut cargo); return cargo } diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index 4a336589b44c5..c494d965a19c3 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -120,6 +120,9 @@ macro_rules! targets { (check_docs, CheckDocs { compiler: Compiler<'a> }), (check_error_index, CheckErrorIndex { compiler: Compiler<'a> }), (check_rmake, CheckRMake { compiler: Compiler<'a> }), + (check_crate_std, CheckCrateStd { compiler: Compiler<'a> }), + (check_crate_test, CheckCrateTest { compiler: Compiler<'a> }), + (check_crate_rustc, CheckCrateRustc { compiler: Compiler<'a> }), // Distribution targets, creating tarballs (dist, Dist { stage: u32 }), @@ -376,6 +379,9 @@ impl<'a> Step<'a> { self.check_cfail(compiler), self.check_rfail(compiler), self.check_pfail(compiler), + self.check_crate_std(compiler), + self.check_crate_test(compiler), + self.check_crate_rustc(compiler), self.check_codegen(compiler), self.check_codegen_units(compiler), self.check_debuginfo(compiler), @@ -437,6 +443,15 @@ impl<'a> Step<'a> { Source::CheckErrorIndex { compiler } => { vec![self.libstd(compiler), self.tool_error_index(compiler.stage)] } + Source::CheckCrateStd { compiler } => { + vec![self.libtest(compiler)] + } + Source::CheckCrateTest { compiler } => { + vec![self.libtest(compiler)] + } + Source::CheckCrateRustc { compiler } => { + vec![self.libtest(compiler)] + } Source::ToolLinkchecker { stage } | Source::ToolTidy { stage } => { diff --git a/src/bootstrap/rustc.rs b/src/bootstrap/rustc.rs index 046bc34438c42..97decedf91dce 100644 --- a/src/bootstrap/rustc.rs +++ b/src/bootstrap/rustc.rs @@ -29,6 +29,7 @@ extern crate bootstrap; use std::env; use std::ffi::OsString; +use std::path::PathBuf; use std::process::Command; fn main() { @@ -43,16 +44,22 @@ fn main() { // have the standard library built yet and may not be able to produce an // executable. Otherwise we just use the standard compiler we're // bootstrapping with. - let rustc = if target.is_none() { - env::var_os("RUSTC_SNAPSHOT").unwrap() + let (rustc, libdir) = if target.is_none() { + ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR") } else { - env::var_os("RUSTC_REAL").unwrap() + ("RUSTC_REAL", "RUSTC_LIBDIR") }; let stage = env::var("RUSTC_STAGE").unwrap(); + let rustc = env::var_os(rustc).unwrap(); + let libdir = env::var_os(libdir).unwrap(); + let mut dylib_path = bootstrap::dylib_path(); + dylib_path.insert(0, PathBuf::from(libdir)); + let mut cmd = Command::new(rustc); cmd.args(&args) - .arg("--cfg").arg(format!("stage{}", stage)); + .arg("--cfg").arg(format!("stage{}", stage)) + .env(bootstrap::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); if let Some(target) = target { // The stage0 compiler has a special sysroot distinct from what we diff --git a/src/bootstrap/rustdoc.rs b/src/bootstrap/rustdoc.rs index 8c618196113ba..88ac26d32f6c3 100644 --- a/src/bootstrap/rustdoc.rs +++ b/src/bootstrap/rustdoc.rs @@ -12,17 +12,25 @@ //! //! See comments in `src/bootstrap/rustc.rs` for more information. +extern crate bootstrap; + use std::env; use std::process::Command; +use std::path::PathBuf; fn main() { let args = env::args_os().skip(1).collect::>(); let rustdoc = env::var_os("RUSTDOC_REAL").unwrap(); + let libdir = env::var_os("RUSTC_LIBDIR").unwrap(); + + let mut dylib_path = bootstrap::dylib_path(); + dylib_path.insert(0, PathBuf::from(libdir)); let mut cmd = Command::new(rustdoc); cmd.args(&args) .arg("--cfg").arg(format!("stage{}", env::var("RUSTC_STAGE").unwrap())) - .arg("--cfg").arg("dox"); + .arg("--cfg").arg("dox") + .env(bootstrap::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); std::process::exit(match cmd.status() { Ok(s) => s.code().unwrap_or(1), Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index 5da0f1a10b977..0889ca9fc84d4 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -6,7 +6,6 @@ version = "0.0.0" [lib] name = "alloc" path = "lib.rs" -test = false [dependencies] core = { path = "../libcore" } diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index 5d521913b48f3..33a675331ab9d 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + extern crate build_helper; extern crate gcc; @@ -18,6 +20,7 @@ use build_helper::run; fn main() { println!("cargo:rustc-cfg=cargobuild"); + println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); @@ -40,6 +43,19 @@ fn main() { let cflags = compiler.args().iter().map(|s| s.to_str().unwrap()) .collect::>().join(" "); + let mut stack = src_dir.join("../jemalloc") + .read_dir().unwrap() + .map(|e| e.unwrap()) + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } + let mut cmd = Command::new("sh"); cmd.arg(src_dir.join("../jemalloc/configure").to_str().unwrap() .replace("C:\\", "/c/") diff --git a/src/libcollections/Cargo.toml b/src/libcollections/Cargo.toml index 18e322ff74f6c..65d456e750f6f 100644 --- a/src/libcollections/Cargo.toml +++ b/src/libcollections/Cargo.toml @@ -6,9 +6,12 @@ version = "0.0.0" [lib] name = "collections" path = "lib.rs" -test = false [dependencies] alloc = { path = "../liballoc" } core = { path = "../libcore" } rustc_unicode = { path = "../librustc_unicode" } + +[[test]] +name = "collectionstest" +path = "../libcollectionstest/lib.rs" diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml index 98f941f0057a3..02fe574b81edd 100644 --- a/src/libcore/Cargo.toml +++ b/src/libcore/Cargo.toml @@ -8,3 +8,7 @@ build = "build.rs" name = "core" path = "lib.rs" test = false + +[[test]] +name = "coretest" +path = "../libcoretest/lib.rs" diff --git a/src/libcore/build.rs b/src/libcore/build.rs index a991ac0de1af1..255a367e58b45 100644 --- a/src/libcore/build.rs +++ b/src/libcore/build.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + fn main() { // Remove this whenever snapshots and rustbuild nightlies are synced. println!("cargo:rustc-cfg=cargobuild"); + println!("cargo:rerun-if-changed=build.rs") } diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 1cc008c5ee9ce..b578b064d67ca 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -27,11 +27,7 @@ #![feature(libc)] #![feature(staged_api)] #![feature(unique)] -#![cfg_attr(test, feature(rustc_private, rand))] - -#[cfg(test)] -#[macro_use] -extern crate log; +#![cfg_attr(test, feature(rand))] extern crate libc; @@ -175,14 +171,8 @@ mod tests { for _ in 0..2000 { input.extend_from_slice(r.choose(&words).unwrap()); } - debug!("de/inflate of {} bytes of random word-sequences", - input.len()); let cmp = deflate_bytes(&input); let out = inflate_bytes(&cmp).unwrap(); - debug!("{} bytes deflated to {} ({:.1}% size)", - input.len(), - cmp.len(), - 100.0 * ((cmp.len() as f64) / (input.len() as f64))); assert_eq!(&*input, &*out); } } diff --git a/src/libpanic_abort/Cargo.toml b/src/libpanic_abort/Cargo.toml index a7905703f596f..9d62be64fc4ec 100644 --- a/src/libpanic_abort/Cargo.toml +++ b/src/libpanic_abort/Cargo.toml @@ -5,6 +5,7 @@ version = "0.0.0" [lib] path = "lib.rs" +test = false [dependencies] core = { path = "../libcore" } diff --git a/src/libpanic_unwind/Cargo.toml b/src/libpanic_unwind/Cargo.toml index 27edecd6f9668..18f37a8bb174e 100644 --- a/src/libpanic_unwind/Cargo.toml +++ b/src/libpanic_unwind/Cargo.toml @@ -5,6 +5,7 @@ version = "0.0.0" [lib] path = "lib.rs" +test = false [dependencies] alloc = { path = "../liballoc" } diff --git a/src/librand/Cargo.toml b/src/librand/Cargo.toml index 784654c085990..86b061db05413 100644 --- a/src/librand/Cargo.toml +++ b/src/librand/Cargo.toml @@ -6,7 +6,6 @@ version = "0.0.0" [lib] name = "rand" path = "lib.rs" -test = false [dependencies] core = { path = "../libcore" } diff --git a/src/librustc_bitflags/Cargo.toml b/src/librustc_bitflags/Cargo.toml index 926ed5960d68a..d1e66dcf9351b 100644 --- a/src/librustc_bitflags/Cargo.toml +++ b/src/librustc_bitflags/Cargo.toml @@ -7,3 +7,4 @@ version = "0.0.0" name = "rustc_bitflags" path = "lib.rs" test = false +doctest = false diff --git a/src/librustc_borrowck/Cargo.toml b/src/librustc_borrowck/Cargo.toml index 6da87f97fb79f..fbc267aaa6a06 100644 --- a/src/librustc_borrowck/Cargo.toml +++ b/src/librustc_borrowck/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_borrowck" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 3f0cd397e769c..7674cc529bef8 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_lint" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 217445715a81b..a63460d912d7d 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_resolve" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index ccb430fbb782f..9a0580472b401 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_trans" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] arena = { path = "../libarena" } diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index e9dabf16eaece..a0c4c7534fab2 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_typeck" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 6d33fb311cff0..eded6e24f3ef5 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -8,7 +8,6 @@ build = "build.rs" name = "std" path = "lib.rs" crate-type = ["dylib", "rlib"] -test = false [dependencies] alloc = { path = "../liballoc" } diff --git a/src/libstd/build.rs b/src/libstd/build.rs index e879d440643f9..ff9dacbb6799b 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + extern crate gcc; extern crate build_helper; use std::env; -use std::fs; use std::path::PathBuf; use std::process::Command; @@ -20,6 +21,7 @@ use build_helper::run; fn main() { println!("cargo:rustc-cfg=cargobuild"); + println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); @@ -65,8 +67,16 @@ fn build_libbacktrace(host: &str, target: &str) { println!("cargo:rustc-link-lib=static=backtrace"); println!("cargo:rustc-link-search=native={}/.libs", build_dir.display()); - if fs::metadata(&build_dir.join(".libs/libbacktrace.a")).is_ok() { - return + let mut stack = src_dir.read_dir().unwrap() + .map(|e| e.unwrap()) + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } } let compiler = gcc::Config::new().get_compiler(); diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index dca222c49d0a1..b537c6b1b71c1 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -7,6 +7,7 @@ build = "build.rs" [lib] name = "unwind" path = "lib.rs" +test = false [dependencies] core = { path = "../libcore" } diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 7431c35efba01..24499cb8f08c2 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -13,6 +13,8 @@ path = "rustdoc.rs" [profile.release] opt-level = 2 +[profile.bench] +opt-level = 2 # These options are controlled from our rustc wrapper script, so turn them off # here and have them controlled elsewhere. diff --git a/src/rustc/libc_shim/Cargo.toml b/src/rustc/libc_shim/Cargo.toml index a7860b50e08ff..8fc713e0f1bb3 100644 --- a/src/rustc/libc_shim/Cargo.toml +++ b/src/rustc/libc_shim/Cargo.toml @@ -15,6 +15,7 @@ build = "build.rs" [lib] name = "libc" path = "../../liblibc/src/lib.rs" +test = false [dependencies] core = { path = "../../libcore" } diff --git a/src/rustc/libc_shim/build.rs b/src/rustc/libc_shim/build.rs index bc428d6908235..546f60482e7bc 100644 --- a/src/rustc/libc_shim/build.rs +++ b/src/rustc/libc_shim/build.rs @@ -8,8 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + // See comments in Cargo.toml for why this exists fn main() { println!("cargo:rustc-cfg=stdbuild"); + println!("cargo:rerun-if-changed=build.rs"); } diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml index 1ce3937157da0..5602ef866b83a 100644 --- a/src/rustc/std_shim/Cargo.toml +++ b/src/rustc/std_shim/Cargo.toml @@ -30,6 +30,8 @@ path = "lib.rs" [profile.release] opt-level = 2 +[profile.bench] +opt-level = 2 # These options are controlled from our rustc wrapper script, so turn them off # here and have them controlled elsewhere. diff --git a/src/rustc/test_shim/Cargo.toml b/src/rustc/test_shim/Cargo.toml index bf5766504867c..87f2ccd51e885 100644 --- a/src/rustc/test_shim/Cargo.toml +++ b/src/rustc/test_shim/Cargo.toml @@ -14,6 +14,8 @@ path = "lib.rs" [profile.release] opt-level = 2 +[profile.bench] +opt-level = 2 # These options are controlled from our rustc wrapper script, so turn them off # here and have them controlled elsewhere.