diff --git a/src/cargo/core/compiler/build_config.rs b/src/cargo/core/compiler/build_config.rs index 2056408097e..b87641ab87a 100644 --- a/src/cargo/core/compiler/build_config.rs +++ b/src/cargo/core/compiler/build_config.rs @@ -127,6 +127,11 @@ pub enum CompileMode { Test, /// Building a target with `rustc` (lib or bin). Build, + /// Building just the metadata of an rlib with `rustc` + /// + /// This is somewhat of a special mode, and for more information see the + /// documentation in `job_queue.rs` + BuildRmeta, /// Building a target with `rustc` to emit `rmeta` metadata only. If /// `test` is true, then it is also compiled with `--test` to check it like /// a test. @@ -154,6 +159,7 @@ impl ser::Serialize for CompileMode { match *self { Test => "test".serialize(s), Build => "build".serialize(s), + BuildRmeta => "build-rmeta".serialize(s), Check { .. } => "check".serialize(s), Bench => "bench".serialize(s), Doc { .. } => "doc".serialize(s), @@ -202,9 +208,10 @@ impl CompileMode { /// List of all modes (currently used by `cargo clean -p` for computing /// all possible outputs). pub fn all_modes() -> &'static [CompileMode] { - static ALL: [CompileMode; 9] = [ + static ALL: &[CompileMode] = &[ CompileMode::Test, CompileMode::Build, + CompileMode::BuildRmeta, CompileMode::Check { test: true }, CompileMode::Check { test: false }, CompileMode::Bench, @@ -213,6 +220,6 @@ impl CompileMode { CompileMode::Doctest, CompileMode::RunCustomBuild, ]; - &ALL + ALL } } diff --git a/src/cargo/core/compiler/build_context/mod.rs b/src/cargo/core/compiler/build_context/mod.rs index 858f7ae9074..18badc4bc81 100644 --- a/src/cargo/core/compiler/build_context/mod.rs +++ b/src/cargo/core/compiler/build_context/mod.rs @@ -8,9 +8,9 @@ use crate::core::profiles::Profiles; use crate::core::{Dependency, Workspace}; use crate::core::{PackageId, PackageSet, Resolve}; use crate::util::errors::CargoResult; -use crate::util::{profile, Cfg, Config, Rustc}; -use crate::core::compiler::{Unit, Kind, BuildConfig, BuildOutput}; +use crate::core::compiler::{Unit, Kind, BuildConfig, BuildOutput, CompileMode}; use crate::core::compiler::unit::UnitInterner; +use crate::util::{profile, Cfg, Config, Rustc}; mod target_info; pub use self::target_info::{FileFlavor, TargetInfo}; @@ -179,7 +179,18 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> { } pub fn extra_args_for(&self, unit: &Unit<'a>) -> Option<&Vec> { - self.extra_compiler_args.get(unit) + // Extra arguments are currently only registered for top-level units and + // this is how `cargo rustc` and `cargo rustdoc` are implemented. We may + // split a top level unit though for pipelining, and the actual work + // happens in the `BuildRmeta` stage and not the `Build` stage. To + // handle that difference and ensure arguments get to the right place be + // sure to switch `BuildRmeta` modes to `Build` for lookup. + if unit.mode == CompileMode::BuildRmeta { + let build = unit.with_mode(CompileMode::Build, self.units); + self.extra_compiler_args.get(&build) + } else { + self.extra_compiler_args.get(unit) + } } } diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index 217022f7132..47e8a60934a 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use lazycell::LazyCell; use log::info; -use super::{BuildContext, Context, FileFlavor, Kind, Layout}; +use super::{BuildContext, Context, FileFlavor, Kind, Layout, CompileMode}; use crate::core::compiler::Unit; use crate::core::{TargetKind, Workspace}; use crate::util::{self, CargoResult}; @@ -299,18 +299,19 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { let mut ret = Vec::new(); let mut unsupported = Vec::new(); - { - if unit.mode.is_check() { + match unit.mode { + CompileMode::BuildRmeta | CompileMode::Check { .. } => { // This may be confusing. rustc outputs a file named `lib*.rmeta` // for both libraries and binaries. let path = out_dir.join(format!("lib{}.rmeta", file_stem)); ret.push(OutputFile { - path, + path: path.clone(), hardlink: None, export_path: None, flavor: FileFlavor::Linkable, }); - } else { + } + CompileMode::Test | CompileMode::Build | CompileMode::Bench => { let mut add = |crate_type: &str, flavor: FileFlavor| -> CargoResult<()> { let crate_type = if crate_type == "lib" { "rlib" @@ -324,34 +325,35 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { bcx.target_triple(), )?; - match file_types { - Some(types) => { - for file_type in types { - let path = out_dir.join(file_type.filename(&file_stem)); - let hardlink = link_stem - .as_ref() - .map(|&(ref ld, ref ls)| ld.join(file_type.filename(ls))); - let export_path = if unit.target.is_custom_build() { - None - } else { - self.export_dir.as_ref().and_then(|export_dir| { - hardlink.as_ref().and_then(|hardlink| { - Some(export_dir.join(hardlink.file_name().unwrap())) - }) - }) - }; - ret.push(OutputFile { - path, - hardlink, - export_path, - flavor: file_type.flavor, - }); - } - } + let types = match file_types { + Some(types) => types, // Not supported; don't worry about it. None => { unsupported.push(crate_type.to_string()); + return Ok(()); } + }; + + for file_type in types { + let path = out_dir.join(file_type.filename(&file_stem)); + let hardlink = link_stem + .as_ref() + .map(|&(ref ld, ref ls)| ld.join(file_type.filename(ls))); + let export_path = if unit.target.is_custom_build() { + None + } else { + self.export_dir.as_ref().and_then(|export_dir| { + hardlink.as_ref().and_then(|hardlink| { + Some(export_dir.join(hardlink.file_name().unwrap())) + }) + }) + }; + ret.push(OutputFile { + path, + hardlink, + export_path, + flavor: file_type.flavor, + }); } Ok(()) }; @@ -381,6 +383,9 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { } } } + CompileMode::Doc { .. } | CompileMode::Doctest | CompileMode::RunCustomBuild => { + return Ok(Arc::new(ret)); + } } if ret.is_empty() { if !unsupported.is_empty() { @@ -425,6 +430,14 @@ fn compute_metadata<'a, 'cfg>( cx: &Context<'a, 'cfg>, metas: &mut HashMap, Option>, ) -> Option { + // Check to see if this is a pipelined unit which means that it doesn't + // actually do any work, but rather its dependency on an rmeta unit will do + // all the work. In that case we'll take the same metadata as our rmeta + // compile to ensure that our file names all align. + if let Some(rmeta) = cx.rmeta_unit_if_pipelined(unit) { + return compute_metadata(&rmeta, cx, metas); + } + // No metadata for dylibs because of a couple issues: // - macOS encodes the dylib name in the executable, // - Windows rustc multiple files of which we can't easily link all of them. diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index 3eb20bb4bde..878824381ad 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -42,6 +42,18 @@ pub struct Context<'a, 'cfg: 'a> { unit_dependencies: HashMap, Vec>>, files: Option>, package_cache: HashMap, + + // A map from a unit to the dependencies listed for it which are considered + // as "order only" dependencies. These dependencies are only used to + // sequence compilation correctly and shouldn't inject `--extern` flags, for + // example. + pub order_only_dependencies: HashMap, HashSet>>, + + // A set of units which have been "pipelined". These units are in `Build` + // mode and depend on a `BuildRmeta` mode unit. The pipelined `Build` units + // should do no work because the `BuildRmeta` unit will do all the work for + // them. + pub pipelined_units: HashSet>, } impl<'a, 'cfg> Context<'a, 'cfg> { @@ -76,6 +88,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> { unit_dependencies: HashMap::new(), files: None, package_cache: HashMap::new(), + order_only_dependencies: HashMap::new(), + pipelined_units: HashSet::new(), }) } @@ -266,6 +280,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> { self.bcx, &mut self.unit_dependencies, &mut self.package_cache, + &mut self.order_only_dependencies, + &mut self.pipelined_units, )?; let files = CompilationFiles::new( units, @@ -453,6 +469,20 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } Ok(()) } + + /// Returns the `BuildRmeta` unit which is actually doing compilation if the + /// `unit` specified has been pipelined. + /// + /// If the unit specified has not been pipelined then `None` will be + /// returned. + pub fn rmeta_unit_if_pipelined(&self, unit: &Unit<'a>) -> Option> { + if self.pipelined_units.contains(unit) { + assert_eq!(unit.mode, CompileMode::Build); + Some(unit.with_mode(CompileMode::BuildRmeta, self.bcx.units)) + } else { + None + } + } } #[derive(Default)] diff --git a/src/cargo/core/compiler/context/unit_dependencies.rs b/src/cargo/core/compiler/context/unit_dependencies.rs index 618c925b37a..e566dab205b 100644 --- a/src/cargo/core/compiler/context/unit_dependencies.rs +++ b/src/cargo/core/compiler/context/unit_dependencies.rs @@ -16,6 +16,7 @@ //! graph of `Unit`s, which capture these properties. use std::cell::RefCell; +use std::mem; use std::collections::{HashMap, HashSet}; use log::trace; @@ -31,6 +32,8 @@ use crate::CargoResult; struct State<'a: 'tmp, 'cfg: 'a, 'tmp> { bcx: &'tmp BuildContext<'a, 'cfg>, deps: &'tmp mut HashMap, Vec>>, + order_only_dependencies: &'tmp mut HashMap, HashSet>>, + pipelined_units: &'tmp mut HashSet>, pkgs: RefCell<&'tmp mut HashMap>, waiting_on_download: HashSet, downloads: Downloads<'a, 'cfg>, @@ -41,6 +44,8 @@ pub fn build_unit_dependencies<'a, 'cfg>( bcx: &BuildContext<'a, 'cfg>, deps: &mut HashMap, Vec>>, pkgs: &mut HashMap, + order_only_dependencies: &mut HashMap, HashSet>>, + pipelined_units: &mut HashSet>, ) -> CargoResult<()> { assert!(deps.is_empty(), "can only build unit deps once"); @@ -50,6 +55,8 @@ pub fn build_unit_dependencies<'a, 'cfg>( pkgs: RefCell::new(pkgs), waiting_on_download: HashSet::new(), downloads: bcx.packages.enable_download()?, + order_only_dependencies, + pipelined_units, }; loop { @@ -84,10 +91,15 @@ pub fn build_unit_dependencies<'a, 'cfg>( break; } } - trace!("ALL UNIT DEPENDENCIES {:#?}", state.deps); connect_run_custom_build_deps(&mut state); + trace!("BEFORE PIPELINING {:#?}", state.deps); + + pipeline_compilations(&mut state)?; + + trace!("ALL UNIT DEPENDENCIES {:#?}", state.deps); + // Dependencies are used in tons of places throughout the backend, many of // which affect the determinism of the build itself. As a result be sure // that dependency lists are always sorted to ensure we've always got a @@ -501,6 +513,200 @@ fn connect_run_custom_build_deps(state: &mut State<'_, '_, '_>) { } } +fn pipeline_compilations(state: &mut State<'_, '_, '_>) -> CargoResult<()> { + // Disable pipelining in build plan mode for now. Pipelining doesn't really + // reflect well to the build plan and only really gets benefits within Cargo + // itself, so let's not export it just yet. + if state.bcx.build_config.build_plan { + return Ok(()) + } + + // Additionally use a config variable for testing for now while the + // pipelining implementation is still relatively new. This should allow easy + // disabling if there's accidental bugs or just for local testing. + if !state.bcx.config.get_bool("build.pipelining")?.map(|t| t.val).unwrap_or(true) { + return Ok(()); + } + + // First thing to do is to restructure the dependency graph in two ways: + // + // 1. First, we need to split all rlib builds into an actual build which + // depends on the metadata build. The metadata build will actually do all + // the work and the normal build will be an effective noop. + // + // 2. Next, for candidate dependencies, we depend on rmeta builds instead of + // full builds. This ensures that we're only depending on what's + // absolutely necessary, ensuring we don't wait too long to start + // compilations. + let mut new_nodes = Vec::new(); + for (unit, deps) in state.deps.iter_mut() { + // Only building rlibs are candidates for pipelining. The first check + // here is effectively "is this an rlib" and the second filters out all + // other forms of units that aren't compilations (like unit tests, + // documentation, etc). + if unit.target.requires_upstream_objects() || unit.mode != CompileMode::Build { + continue; + } + state.pipelined_units.insert(*unit); + + // Update all `deps`, that we can, to depend on `BuildRmeta` instead of + // `Build`. This is where we get pipelining wins by hoping that our + // dependencies can be fulfilled faster by only depending on metadata + // information. + for dep in deps.iter_mut() { + if dep.target.requires_upstream_objects() { + continue; + } + match dep.mode { + CompileMode::Build => {} + _ => continue, + } + *dep = dep.with_mode(CompileMode::BuildRmeta, state.bcx.units); + } + + // Rewrite our `Build` unit and its dependencies. Our `Build` unit will + // now only depend on the `BuildRmeta` unit which we're about to create. + // Our `BuildRmeta` unit then actually lists all of the dependencies + // that we previously had. + let build_rmeta = unit.with_mode(CompileMode::BuildRmeta, state.bcx.units); + let new_deps = vec![build_rmeta]; + new_nodes.push((build_rmeta, mem::replace(deps, new_deps))); + + // As a bit of side information flag that the `Build` -> `BuildRmeta` + // dependency we've created here is an "order only" dependency which + // means we won't try to pass `--extern` to ourselves which would be + // silly. + state + .order_only_dependencies + .entry(*unit) + .or_insert_with(HashSet::new) + .insert(build_rmeta); + } + state.deps.extend(new_nodes); + + // The next step we need to perform is to add more dependencies in the + // dependency graph (more than we've already done). Let's take an example + // dependency graph like: + // + // A (exe) -> B (rlib) -> C (rlib) + // + // our above loop transformed this graph into: + // + // A (exe) -> B (rlib) -> B (rmeta) -> C (remta) + // ^ + // | + // C (rlib) + // + // This is actually incorrect because "A (exe)" actually depends on "C + // (rlib)". Technically just the linking phase depends on it but we take a + // coarse approximation and say the entirety of "A (exe)" depend on it. + // + // The graph that we actually want is: + // + // A (exe) -> B (rlib) -> B (rmeta) -> C (remta) + // \ ^ + // \ | + // -------------------> C (rlib) + // + // To do this transformation we're going to take a look at all rlib builds + // which now depend on just an `BuildRmeta` node. We walk from these nodes + // higher up to the root of the dependency graph (all paths to the root). As + // soon as any path has a node that is not `BuildRmeta` we add a dependency + // in its list of dependencies to the `Build` version of our unit. + // + // In reality this means that the graph we produce will be: + // + // A (exe) -> B (rlib) -> B (rmeta) -> C (remta) + // \ ^ + // \ | + // --------> C (rlib) + // + // and this should have the same performance characteristics as our desired + // graph from above because "B (rlib)" is a free phantom dependency node. + let mut reverse_deps = HashMap::new(); + for (unit, deps) in state.deps.iter() { + for dep in deps { + reverse_deps + .entry(*dep) + .or_insert_with(HashSet::new) + .insert(*unit); + } + } + + let mut updated = HashSet::new(); + for build_unit in state.pipelined_units.clone() { + let build_rmeta_unit = build_unit.with_mode(CompileMode::BuildRmeta, state.bcx.units); + update_built_parents( + &build_unit, + &build_rmeta_unit, + state, + &reverse_deps, + &mut updated, + ); + } + + return Ok(()); + + /// Walks the dependency graph upwards from `build_rmeta_unit` to find a + /// unit which is *not* `BuildRmeta`. When found, adds `build_unit` to that + /// unit's list of dependencies. + fn update_built_parents<'a>( + build_unit: &Unit<'a>, + build_rmeta_unit: &Unit<'a>, + state: &mut State<'a, '_, '_>, + reverse_deps: &HashMap, HashSet>>, + updated: &mut HashSet<(Unit<'a>, Unit<'a>)>, + ) { + debug_assert_eq!(build_rmeta_unit.mode, CompileMode::BuildRmeta); + debug_assert_eq!(build_unit.mode, CompileMode::Build); + + // There may be multiple paths to the root of the dependency graph as we + // walk upwards, but we don't want to add units more than once. Use a + // visited set to guard against this. + if !updated.insert((*build_unit, *build_rmeta_unit)) { + return; + } + + // Look for anything that depends on our `BuildRmeta` unit. If nothing + // depends on us then we've reached the root of the graph, and nothing + // needs to depend on the `Build` version! + let parents = match reverse_deps.get(build_rmeta_unit) { + Some(list) => list, + None => return, + }; + + for parent in parents { + match parent.mode { + // If a `BuildRmeta` depends on this `BuildRmeta`, then we + // recurse and keep walking up the graph to add the `build_unit` + // into the dependency list + CompileMode::BuildRmeta => { + update_built_parents(build_unit, parent, state, reverse_deps, updated); + } + // ... otherwise this unit is not a `BuildRmeta`, but very + // likely a `Build`. In that case for it to actually execute we + // need to finish all transitive `BuildRmeta` units, so we + // update its list of dependencies to include the full built + // artifact. + _ => { + // If these are the same that means we're propagating the + // `BuildRmeta` unit to the `Build` of itself so we can + // safely skip that. + if parent == build_unit { + continue; + } + state.deps.get_mut(parent).unwrap().push(*build_unit); + state + .order_only_dependencies + .entry(*parent) + .or_insert_with(HashSet::new) + .insert(*build_unit); + } + } + } + } +} + impl<'a, 'cfg, 'tmp> State<'a, 'cfg, 'tmp> { fn get(&mut self, id: PackageId) -> CargoResult> { let mut pkgs = self.pkgs.borrow_mut(); diff --git a/src/cargo/core/compiler/fingerprint.rs b/src/cargo/core/compiler/fingerprint.rs index e7a2b378542..8017cede2ef 100644 --- a/src/cargo/core/compiler/fingerprint.rs +++ b/src/cargo/core/compiler/fingerprint.rs @@ -212,7 +212,7 @@ use super::job::{ Freshness::{Dirty, Fresh}, Job, Work, }; -use super::{BuildContext, Context, FileFlavor, Kind, Unit}; +use super::{BuildContext, CompileMode, Context, FileFlavor, Kind, Unit}; /// Determines if a `unit` is up-to-date, and if not prepares necessary work to /// update the persisted fingerprint. @@ -478,9 +478,7 @@ enum LocalFingerprint { /// The `dep_info` file, when present, also lists a number of other files /// for us to look at. If any of those files are newer than this file then /// we need to recompile. - CheckDepInfo { - dep_info: PathBuf, - }, + CheckDepInfo { dep_info: PathBuf }, /// This represents a nonempty set of `rerun-if-changed` annotations printed /// out by a build script. The `output` file is a arelative file anchored at @@ -500,10 +498,7 @@ enum LocalFingerprint { /// build script. The exact env var and value are hashed here. There's no /// filesystem dependence here, and if the values are changed the hash will /// change forcing a recompile. - RerunIfEnvChanged { - var: String, - val: Option, - }, + RerunIfEnvChanged { var: String, val: Option }, } enum StaleFile { @@ -899,7 +894,16 @@ impl DepFingerprint { dep: &Unit<'a>, ) -> CargoResult { let fingerprint = calculate(cx, dep)?; - let name = cx.bcx.extern_crate_name(parent, dep)?; + let order_only = cx + .order_only_dependencies + .get(parent) + .map(|s| s.contains(dep)) + .unwrap_or(false); + let name = if order_only { + String::new() + } else { + cx.bcx.extern_crate_name(parent, dep)? + }; // We need to be careful about what we hash here. We have a goal of // supporting renaming a project directory and not rebuilding @@ -1013,7 +1017,12 @@ fn calculate_normal<'a, 'cfg>( // get bland fingerprints because they don't change without their // `PackageId` changing. let target_root = target_root(cx, unit); - let local = if use_dep_info(unit) { + let local = if cx.pipelined_units.contains(unit) { + // If we're a "pipelined" unit then our fingerprint information is used + // and checked in the rmeta dependency that we depend on, so nothing new + // here. + Vec::new() + } else if use_dep_info(unit) { let dep_info = dep_info_loc(cx, unit); let dep_info = dep_info.strip_prefix(&target_root).unwrap().to_path_buf(); vec![LocalFingerprint::CheckDepInfo { dep_info }] @@ -1307,9 +1316,14 @@ pub fn prepare_init<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> Ca /// Returns the location that the dep-info file will show up at for the `unit` /// specified. pub fn dep_info_loc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> PathBuf { + // If `unit` is a pipelined unit, or one that doesn't actually do any work + // because it's happening elsewhere, then we want to switch to the actual + // `rmeta` unit that does the work which will generate dep info. Otherwise + // the `unit` will produce its own dep info. + let unit = cx.rmeta_unit_if_pipelined(unit).unwrap_or(*unit); cx.files() - .fingerprint_dir(unit) - .join(&format!("dep-{}", filename(cx, unit))) + .fingerprint_dir(&unit) + .join(&format!("dep-{}", filename(cx, &unit))) } /// Returns an absolute path that the `unit`'s outputs should always be relative @@ -1453,14 +1467,15 @@ fn filename<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> String { // even if the package is fresh, we'll still link the fresh target let file_stem = cx.files().file_stem(unit); let kind = unit.target.kind().description(); - let flavor = if unit.mode.is_any_test() { - "test-" - } else if unit.mode.is_doc() { - "doc-" - } else if unit.mode.is_run_custom_build() { - "run-" - } else { - "" + let flavor = match unit.mode { + CompileMode::Test + | CompileMode::Bench + | CompileMode::Check { test: true } + | CompileMode::Doctest => "test-", + CompileMode::Doc { .. } => "doc-", + CompileMode::RunCustomBuild => "run-", + CompileMode::BuildRmeta => "rmeta-", + CompileMode::Check { test: false } | CompileMode::Build => "", }; format!("{}{}-{}", flavor, kind, file_stem) } diff --git a/src/cargo/core/compiler/job_queue.rs b/src/cargo/core/compiler/job_queue.rs index f7a6a6f7e45..e40b8e374c6 100644 --- a/src/cargo/core/compiler/job_queue.rs +++ b/src/cargo/core/compiler/job_queue.rs @@ -1,3 +1,67 @@ +//! A job queue for executing Cargo's dependency graph +//! +//! This module primarily contains a `JobQueue` type which is the source of +//! executing Cargo's jobs in parallel. This is the module where we actually +//! execute rustc and the job graph. The internal `DependencyQueue` is +//! constructed elsewhere in Cargo, and the job of this module is to simply +//! execute what's described internally in the `DependencyQueue` as fast as it +//! can (using configured parallelism settings). +//! +//! Note that this is also the primary module where jobserver management comes +//! into play because that governs how many jobs we can execute in parallel. +//! Additionally of note is that everything here is using blocking/synchronous +//! I/O and such. We spawn a thread per rustc instance and it all coordinates +//! back to the main Cargo thread which coordinates everything. Perhaps one day +//! we can use async I/O, but it's not super pressing right now. +//! +//! ## Pipelining +//! +//! Another major feature of this module is the execution of a pipelined job +//! graph. The term "pipelining" here refers to executing rustc in an overlapped +//! fashion. We can build rlibs, for example, as soon as their dependencies have +//! metadata files available. No need to wait for codegen! +//! +//! Pipelined execution is modeled in Cargo with a few properties: +//! +//! * The `DependencyQueue` dependency graph has two nodes for each rlib. One +//! node is a `BuildRmeta` node while the other is a `Build` node (which +//! depends on `BuildRmeta`). This is prepared elsewhere. +//! +//! * Each node in a `DependencyQueue` is associated with a unit of work to +//! complete that node. In the case of pipelined compilation the `BuildRmeta` +//! node's work actually performs the full compile for both `BuildRmeta` and +//! `Build`. The work associated with `Build` is just some bookkeeping that +//! doesn't do any actual work. +//! +//! * The execution of a `BuildRmeta` unit will, before the end of the work, +//! send a message through `JobState` that the metadata file is ready. Later, +//! when it's fully finished, it will flag that the `Build` work is ready. +//! +//! All of this is somewhat wonky and doesn't fit perfectly into the +//! `JobQueue`'s management of all other sorts of jobs, but it looks like it +//! generally works ok below. The strategy is that we specially handle pipelined +//! units in the `run` and `finish` methods, but ideally not many other places. +//! +//! When a `BuildRmeta` unit is executed we'll arrange for the the correct +//! messages to be sent. A `Finish` for the `BuildRmeta` will be sent ASAP as +//! the work indicates, and then `Finish` for the `Build` will be sent +//! afterwards. This means that running a `BuildRmeta` unit allocates some +//! metadata for the `Build` unit as well. +//! +//! When a `BuildRmeta` unit finishes we try hard to make sure the `Build` unit +//! doesn't leak into the standard paths elsewhere because it's, well, not very +//! standard. To handle this we immediately remove the `Build` from the +//! dependency graph and specially handle it. It's internally flagged as an +//! active unit which allocates a jobserver token, and then execution proceeds +//! as usual. +//! +//! When the original work queued with the `BuildRmeta` completes it will send a +//! `Finish` notification for the `Build` unit. When this happens we catch this +//! happening and run the deferred `Job` we found during the completion of the +//! `BuildRmeta`. This should handle everything in theory and add up to a +//! working system! + +use std::cell::Cell; use std::collections::{HashMap, HashSet}; use std::io; use std::marker; @@ -29,20 +93,59 @@ use crate::util::{Progress, ProgressStyle}; /// actual compilation step of each package. Packages enqueue units of work and /// then later on the entire graph is processed and compiled. pub struct JobQueue<'a, 'cfg> { + // An instance of a dependency queue which keeps track of all units and jobs + // associated to execute with them. This is built up over time while we're + // preparing a `JobQueue` and is then used to dynamically track what work is + // ready to execute as work finishes. queue: DependencyQueue, Job>, + + // A cross-thread channel used to send messages to the main reactor thread + // which spawns off work. tx: Sender, rx: Receiver, + + // All work items that are currently executing. Maps from a unique ID + // assigned in a monotonically increasing fashion (allocated from `next_id`) + // to the `Unit` that is being executed. `Finish` messages will contain + // these ids and allow mapping back to the original `Unit`. active: HashMap>, + next_id: u32, + + // Metadata information used to keep track of what we're printing on the + // console. This ensures we don't print messages more than once and we print + // them at reasonable-ish times. compiled: HashSet, documented: HashSet, counts: HashMap, is_release: bool, progress: Progress<'cfg>, - next_id: u32, + + // Auxiliary tables to track the status of pipelined units. A `Unit` with a + // `BuildRmeta` mode will actually perform the work of a `Build` unit that + // depends on it, so we need to track that information here to ensure that + // we execute all the callbacks and finish units at the right time. + // + // The `pipelined` map keeps track of `BuildRmeta` units to their + // corresponding `Build` unit along with a preallocated id for the `Build` + // unit. This is created during `self.run`, and then consumed later during + // `self.finish` for the `BuildRmeta` unit. + // + // The `deferred` map keeps track of a mapping of the id of the `Build` unit + // to the `Job` that should execute when it's finished. The `Job` should + // always be a quick noop. + pipelined: HashMap, (Unit<'a>, u32)>, + deferred: HashMap, } pub struct JobState<'a> { + // Communication channel back to the main coordination thread. tx: Sender, + + // If this job is executing as part of a pipelined compilation this will + // list the id of the rmeta job. This is mutated to `None` once we send a + // message saying that the rmeta if finished. + rmeta_id: Cell>, + // Historical versions of Cargo made use of the `'a` argument here, so to // leave the door open to future refactorings keep it here. _marker: marker::PhantomData<&'a ()>, @@ -93,6 +196,19 @@ impl<'a> JobState<'a> { capture_output, ) } + + /// A method to only be used when rustc is being executed to compile an + /// rlib. As soon as the job learns that a metadata file is available this + /// method is called to send a notification back to the job queue that + /// metadata is ready to go and work that only depends on the metadata + /// should be executed ASAP. + /// + /// This will panic if executed twice or outside of a unit that's not for an + /// rlib. + pub fn finish_rmeta(&self) { + let id = self.rmeta_id.replace(None).unwrap(); + self.tx.send(Message::Finish(id, Ok(()))).unwrap(); + } } impl<'a, 'cfg> JobQueue<'a, 'cfg> { @@ -110,6 +226,8 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { is_release: bcx.build_config.release, progress, next_id: 0, + deferred: Default::default(), + pipelined: Default::default(), } } @@ -119,18 +237,25 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { unit: &Unit<'a>, job: Job, ) -> CargoResult<()> { + // Binaries aren't actually needed to *compile* tests, just to run + // them, so we don't include this dependency edge in the job graph. let dependencies = cx.dep_targets(unit); let dependencies = dependencies .iter() - .filter(|unit| { - // Binaries aren't actually needed to *compile* tests, just to run - // them, so we don't include this dependency edge in the job graph. - !unit.target.is_test() || !unit.target.is_bin() - }) + .filter(|unit| !unit.target.is_test() || !unit.target.is_bin()) .cloned() .collect::>(); self.queue.queue(unit, job, &dependencies); - *self.counts.entry(unit.pkg.package_id()).or_insert(0) += 1; + + // Keep track of how many work items we have for each package. This'll + // help us later print whether a package is "fresh" or not if all of its + // component units are indeed fresh. + // + // Note that we skip pipelined units since they don't make their way + // into `run` below. + if !cx.pipelined_units.contains(unit) { + *self.counts.entry(unit.pkg.package_id()).or_insert(0) += 1; + } Ok(()) } @@ -139,7 +264,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { /// This function will spawn off `config.jobs()` workers to build all of the /// necessary dependencies, in order. Freshness is propagated as far as /// possible along each dependency chain. - pub fn execute(&mut self, cx: &mut Context<'_, '_>, plan: &mut BuildPlan) -> CargoResult<()> { + pub fn execute(&mut self, cx: &mut Context<'a, 'cfg>, plan: &mut BuildPlan) -> CargoResult<()> { let _p = profile::start("executing the job graph"); self.queue.queue_finished(); @@ -176,7 +301,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { fn drain_the_queue( &mut self, - cx: &mut Context<'_, '_>, + cx: &mut Context<'a, 'cfg>, plan: &mut BuildPlan, scope: &Scope<'a>, jobserver_helper: &HelperThread, @@ -265,15 +390,11 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { print.print(&msg)?; } Message::Finish(id, result) => { + trace!("end id {}", id); let unit = self.active.remove(&id).unwrap(); info!("end: {:?}", unit); - - if !self.active.is_empty() { - assert!(!tokens.is_empty()); - drop(tokens.pop()); - } match result { - Ok(()) => self.finish(&unit, cx)?, + Ok(()) => self.finish(&unit, id, cx)?, Err(e) => { let msg = "The following warnings were emitted during compilation:"; self.emit_warnings(Some(msg), &unit, cx)?; @@ -376,24 +497,71 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { &mut self, unit: &Unit<'a>, job: Job, - cx: &Context<'_, '_>, + cx: &Context<'a, 'cfg>, scope: &Scope<'a>, ) -> CargoResult<()> { - info!("start: {:?}", unit); + // This unit should never run with a unit which has been pipelined. + // These units are handled specially in `finish` below so just assert we + // don't handle those here. + assert!(cx.rmeta_unit_if_pipelined(unit).is_none()); - let id = self.next_id; - self.next_id = id.checked_add(1).unwrap(); + let id = self.next_id(); + info!("start: {} {:?}", id, unit); assert!(self.active.insert(id, *unit).is_none()); *self.counts.get_mut(&unit.pkg.package_id()).unwrap() -= 1; - let my_tx = self.tx.clone(); + // If we're the rmeta component of a build then our work will actually + // produce the `Build` unit as well. Allocate a `build_id` for that unit + // here and prepare some internal state to know about how this unit is + // pipelined with another `Build` unit. This will also configure what + // messages are sent back to the coordination thread to ensure that we + // finish the `BuildRmeta` unit first and then the `Build` unit. let fresh = job.freshness(); + let (rmeta_id, last_id) = if unit.mode == CompileMode::BuildRmeta { + log::debug!("preparing state to pipeline next unit"); + let build_id = self.next_id(); + let build_unit = unit.with_mode(CompileMode::Build, cx.bcx.units); + assert!(self + .pipelined + .insert(*unit, (build_unit, build_id)) + .is_none()); + (Some(id), build_id) + } else { + (None, id) + }; + + let my_tx = self.tx.clone(); let doit = move || { - let res = job.run(&JobState { + let state = JobState { tx: my_tx.clone(), _marker: marker::PhantomData, - }); - my_tx.send(Message::Finish(id, res)).unwrap(); + rmeta_id: Cell::new(rmeta_id), + }; + let res = job.run(&state); + + // If the `rmeta_id` wasn't consumed but it was set previously, then + // we either have: + // + // 1. The `job` didn't do anything because it was "fresh". + // 2. The `job` returned an error and didn't reach the point where + // it called `finish_rmeta`. + // 3. We forgot to call `finish_rmeta` and there's a bug in Cargo. + // + // Ruling out the third, the other two are pretty common and we just need + // to say that both the `BuildRmeta` and `Build` (which we're + // responsible for) are finished. If an error happens we don't + // finish `Build` because it didn't actually complete. + if let Some(rmeta_id) = state.rmeta_id.replace(None) { + let ok = res.is_ok(); + my_tx.send(Message::Finish(rmeta_id, res)).unwrap(); + if ok { + my_tx.send(Message::Finish(last_id, Ok(()))).unwrap(); + } + } else { + // ... otherwise if we don't have anything to do with pipelining + // this is business as usual... + my_tx.send(Message::Finish(last_id, res)).unwrap(); + } }; if !cx.bcx.build_config.build_plan { @@ -411,6 +579,12 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { Ok(()) } + fn next_id(&mut self) -> u32 { + let ret = self.next_id; + self.next_id = ret.checked_add(1).unwrap(); + return ret; + } + fn emit_warnings( &mut self, msg: Option<&str>, @@ -439,11 +613,38 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { Ok(()) } - fn finish(&mut self, unit: &Unit<'a>, cx: &mut Context<'_, '_>) -> CargoResult<()> { + fn finish(&mut self, unit: &Unit<'a>, id: u32, cx: &mut Context<'_, '_>) -> CargoResult<()> { if unit.mode.is_run_custom_build() && cx.bcx.show_warnings(unit.pkg.package_id()) { self.emit_warnings(None, unit, cx)?; } self.queue.finish(unit); + + // Specially handled pipelined units here. If we're finishing the + // metadata component of a pipelined unit then we have an invariant that + // the `Build` unit is always ready to go. Forcibly dequeue that from + // the dependency queue and save off the work it would otherwise do. + // Along the way we also update the `active` map which should transition + // the jobserver token we were previously using to this unit. + // + // If we're finishing a `Build` unit then the whole pipeline is now + // finished, so we need to actually run the work we deferred earlier + // which should complete quickly. + if unit.mode == CompileMode::BuildRmeta { + log::debug!("first of a pipelined unit finished"); + let (build_unit, build_id) = self.pipelined[unit]; + assert!(self.active.insert(build_id, build_unit).is_none()); + let job = self.queue.dequeue_key(&build_unit); + assert!(self.deferred.insert(build_id, job).is_none()); + } else if cx.pipelined_units.contains(unit) { + log::debug!("completing the work of a pipelined unit"); + let job = self.deferred.remove(&id).unwrap(); + job.run(&JobState { + tx: self.tx.clone(), + _marker: marker::PhantomData, + rmeta_id: Cell::new(None), + })?; + } + Ok(()) } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 9c9f6533b92..7650f83b841 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -15,7 +15,7 @@ use std::env; use std::ffi::{OsStr, OsString}; use std::fs; use std::io::{self, Write}; -use std::path::{self, Path, PathBuf}; +use std::path::{Path, PathBuf}; use std::sync::Arc; use failure::Error; @@ -155,7 +155,11 @@ fn compile<'a, 'cfg: 'a>( let force = exec.force_rebuild(unit) || force_rebuild; let mut job = fingerprint::prepare_target(cx, unit, force)?; job.before(if job.freshness() == Freshness::Dirty { - let work = if unit.mode.is_doc() { + let work = if cx.pipelined_units.contains(unit) { + // If we're a pipelined unit then we're just a phantom + // dependency node so there's no actual work for us to do. + Work::new(|_| Ok(())) + } else if unit.mode.is_doc() { rustdoc(cx, unit)? } else { rustc(cx, unit, exec)? @@ -240,6 +244,7 @@ fn rustc<'a, 'cfg>( .unwrap_or_else(|| cx.bcx.config.cwd()) .to_path_buf(); let fingerprint_dir = cx.files().fingerprint_dir(unit); + let is_build_rmeta = unit.mode == CompileMode::BuildRmeta; return Ok(Work::new(move |state| { // Only at runtime have we discovered what the extra -L and -l @@ -311,6 +316,25 @@ fn rustc<'a, 'cfg>( .chain_err(|| format!("Could not compile `{}`.", name))?; } + // FIXME(rust-lang/rust#58465): this is the whole point of "pipelined + // compilation" in Cargo. We want to, here in this unit, call + // `finish_rmeta` as soon as we can which indicates that the metadata + // file is emitted by rustc and ready to go. This will start dependency + // compilations as soon as possible. + // + // The compiler doesn't currently actually implement the ability to let + // us know, however, when the metadata file is ready to go. It actually + // today produces the file very late in compilation, far later than it + // would otherwise be able to do! + // + // In any case this is all covered by the issue above. This is just a + // marker for "yes we unconditionally do this today but tomorrow we + // should actually read what rustc is doing and execute this at an + // appropriate time, ideally long before rustc finishes completely". + if is_build_rmeta { + state.finish_rmeta(); + } + if do_rename && real_name != crate_name { let dst = &outputs[0].path; let src = dst.with_file_name( @@ -786,11 +810,14 @@ fn build_base_args<'a, 'cfg>( } } - if unit.mode.is_check() { - cmd.arg("--emit=dep-info,metadata"); - } else { - cmd.arg("--emit=dep-info,link"); - } + cmd.arg(match unit.mode { + CompileMode::Build | CompileMode::Test | CompileMode::Bench => "--emit=dep-info,link", + CompileMode::BuildRmeta => "--emit=dep-info,metadata,link", + CompileMode::Check { .. } => "--emit=dep-info,metadata", + CompileMode::Doc { .. } | CompileMode::Doctest | CompileMode::RunCustomBuild => { + unreachable!() + } + }); let prefer_dynamic = (unit.target.for_host() && !unit.target.is_custom_build()) || (crate_types.contains(&"dylib") && bcx.ws.members().any(|p| p != unit.pkg)); @@ -984,6 +1011,17 @@ fn build_deps_args<'a, 'cfg>( dep: &Unit<'a>, ) -> CargoResult<()> { let bcx = cx.bcx; + + // If this dependency edge was "order only" then we explicitly don't + // want to pass `--extern` because there's no actual dependency and it + // would accidentally let the crate use apis it shouldn't have access + // to. + if let Some(set) = cx.order_only_dependencies.get(current) { + if set.contains(dep) { + return Ok(()); + } + } + for output in cx.outputs(dep)?.iter() { if output.flavor != FileFlavor::Linkable { continue; @@ -992,9 +1030,7 @@ fn build_deps_args<'a, 'cfg>( let name = bcx.extern_crate_name(current, dep)?; v.push(name); v.push("="); - v.push(cx.files().out_dir(dep)); - v.push(&path::MAIN_SEPARATOR.to_string()); - v.push(&output.path.file_name().unwrap()); + v.push(&output.path); cmd.arg("--extern").arg(&v); } Ok(()) diff --git a/src/cargo/core/compiler/output_depinfo.rs b/src/cargo/core/compiler/output_depinfo.rs index b09f5344c58..3f7e042c11c 100644 --- a/src/cargo/core/compiler/output_depinfo.rs +++ b/src/cargo/core/compiler/output_depinfo.rs @@ -45,9 +45,10 @@ fn add_deps_for_unit<'a, 'b>( } } else { debug!( - "can't find dep_info for {:?} {}", + "can't find dep_info for {:?} {} at {:?}", unit.pkg.package_id(), - unit.target + unit.target, + dep_info_loc, ); return Err(internal("dep_info missing")); } diff --git a/src/cargo/core/compiler/unit.rs b/src/cargo/core/compiler/unit.rs index bf7d6f0871c..251823ee806 100644 --- a/src/cargo/core/compiler/unit.rs +++ b/src/cargo/core/compiler/unit.rs @@ -54,6 +54,12 @@ impl<'a> Unit<'a> { pub fn buildkey(&self) -> String { format!("{}-{}", self.pkg.name(), short_hash(self)) } + + /// Returns a new `Unit` with all the same fields as this one except with a + /// different `mode` + pub fn with_mode(&self, mode: CompileMode, units: &'a UnitInterner<'a>) -> Unit<'a> { + units.intern(self.pkg, self.target, self.profile, self.kind, mode) + } } // Just hash the pointer for fast hashing diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 3cb9481680e..0272a200c15 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -120,6 +120,19 @@ impl LibKind { LibKind::Other(..) => false, } } + + pub fn requires_upstream_objects(&self) -> bool { + match *self { + // "lib" == "rlib" and is a compilation that doesn't actually + // require upstream object files to exist, only upstream metadata + // files. As a result, it doesn't require upstream artifacts + LibKind::Lib | LibKind::Rlib => false, + + // Everything else, however, is some form of "linkable output" or + // something that requires upstream object files. + _ => true, + } + } } impl fmt::Debug for LibKind { @@ -795,6 +808,10 @@ impl Target { }) } + /// Returns whether this target produces an artifact which can be linked + /// into a Rust crate. + /// + /// This only returns true for certain kinds of libraries. pub fn linkable(&self) -> bool { match self.kind { TargetKind::Lib(ref kinds) => kinds.iter().any(|k| k.linkable()), @@ -802,6 +819,20 @@ impl Target { } } + /// Returns whether production of this artifact requires the object files + /// from dependencies to be available. + /// + /// This only returns `false` when all we're producing is an rlib, otherwise + /// it will return `true`. + pub fn requires_upstream_objects(&self) -> bool { + match &self.kind { + TargetKind::Lib(kinds) | TargetKind::ExampleLib(kinds) => { + kinds.iter().any(|k| k.requires_upstream_objects()) + } + _ => true, + } + } + pub fn is_bin(&self) -> bool { self.kind == TargetKind::Bin } diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 8cf142981c8..16a7bab89ff 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -93,6 +93,7 @@ impl Profiles { } } CompileMode::Build + | CompileMode::BuildRmeta | CompileMode::Check { .. } | CompileMode::Doctest | CompileMode::RunCustomBuild => { diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 3d1719dfc34..749e9d048d7 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -271,6 +271,7 @@ pub fn compile_ws<'a>( match build_config.mode { CompileMode::Test | CompileMode::Build + | CompileMode::BuildRmeta | CompileMode::Check { .. } | CompileMode::Bench | CompileMode::RunCustomBuild => { @@ -502,8 +503,10 @@ impl CompileFilter { pub fn need_dev_deps(&self, mode: CompileMode) -> bool { match mode { CompileMode::Test | CompileMode::Doctest | CompileMode::Bench => true, - CompileMode::Build | CompileMode::Doc { .. } | CompileMode::Check { .. } => match *self - { + CompileMode::Build + | CompileMode::BuildRmeta + | CompileMode::Doc { .. } + | CompileMode::Check { .. } => match *self { CompileFilter::Default { .. } => false, CompileFilter::Only { ref examples, @@ -845,7 +848,7 @@ fn filter_default_targets(targets: &[Target], mode: CompileMode) -> Vec<&Target> .iter() .filter(|t| t.tested() || t.is_example()) .collect(), - CompileMode::Build | CompileMode::Check { .. } => targets + CompileMode::Build | CompileMode::BuildRmeta | CompileMode::Check { .. } => targets .iter() .filter(|t| t.is_bin() || t.is_lib()) .collect(), diff --git a/src/cargo/util/dependency_queue.rs b/src/cargo/util/dependency_queue.rs index 9df373ee4f0..55da8e22eab 100644 --- a/src/cargo/util/dependency_queue.rs +++ b/src/cargo/util/dependency_queue.rs @@ -132,6 +132,19 @@ impl DependencyQueue { Some((key, data)) } + /// Forcibly dequeues a particular key from the dependency queue. + /// + /// # Panics + /// + /// Panics if `key`'s dependencies haven't finished yet or if `key` isn't in + /// the dependency queue. + pub fn dequeue_key(&mut self, key: &K) -> V { + let (deps, data) = self.dep_map.remove(&key).unwrap(); + assert!(deps.is_empty()); + self.pending.insert(key.clone()); + return data; + } + /// Returns `true` if there are remaining packages to be built. pub fn is_empty(&self) -> bool { self.dep_map.is_empty() && self.pending.is_empty() diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index cb7d021254a..6d7b868af34 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1462,7 +1462,7 @@ fn cargo_default_env_metadata_env_var() { -L dependency=[CWD]/target/debug/deps` [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ -C extra-filename=[..] \ --out-dir [..] \ @@ -1490,7 +1490,7 @@ fn cargo_default_env_metadata_env_var() { -L dependency=[CWD]/target/debug/deps` [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ -C extra-filename=[..] \ --out-dir [..] \ @@ -1864,7 +1864,7 @@ fn lto_build() { "\ [COMPILING] test v0.0.0 ([CWD]) [RUNNING] `rustc --crate-name test src/main.rs --color never --crate-type bin \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level=3 \ -C lto \ -C metadata=[..] \ @@ -1884,7 +1884,7 @@ fn verbose_build() { "\ [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..] \ -L dependency=[CWD]/target/debug/deps` @@ -1902,7 +1902,7 @@ fn verbose_release_build() { "\ [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level=3 \ -C metadata=[..] \ --out-dir [..] \ @@ -1952,7 +1952,7 @@ fn verbose_release_build_deps() { [COMPILING] foo v0.0.0 ([CWD]/foo) [RUNNING] `rustc --crate-name foo foo/src/lib.rs --color never \ --crate-type dylib --crate-type rlib \ - --emit=dep-info,link \ + --emit=[..]link \ -C prefer-dynamic \ -C opt-level=3 \ -C metadata=[..] \ @@ -1960,7 +1960,7 @@ fn verbose_release_build_deps() { -L dependency=[CWD]/target/release/deps` [COMPILING] test v0.0.0 ([CWD]) [RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level=3 \ -C metadata=[..] \ --out-dir [..] \ @@ -3349,9 +3349,8 @@ fn compiler_json_error_format() { .file("bar/src/lib.rs", r#"fn dead() {}"#) .build(); - // Use `jobs=1` to ensure that the order of messages is consistent. - p.cargo("build -v --message-format=json --jobs=1") - .with_json( + p.cargo("build -v --message-format=json") + .with_json_contains_unordered( r#" { "reason":"compiler-artifact", @@ -3462,8 +3461,8 @@ fn compiler_json_error_format() { // With fresh build, we should repeat the artifacts, // but omit compiler warnings. - p.cargo("build -v --message-format=json --jobs=1") - .with_json( + p.cargo("build -v --message-format=json") + .with_json_contains_unordered( r#" { "reason":"compiler-artifact", @@ -4497,11 +4496,11 @@ fn build_filter_infer_profile() { p.cargo("build -v") .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) .run(); @@ -4509,15 +4508,15 @@ fn build_filter_infer_profile() { p.cargo("build -v --test=t1") .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 [..]", + --emit=[..]link -C debuginfo=2 [..]", ) .with_stderr_contains( - "[RUNNING] `rustc --crate-name t1 tests/t1.rs --color never --emit=dep-info,link \ + "[RUNNING] `rustc --crate-name t1 tests/t1.rs --color never --emit=[..]link \ -C debuginfo=2 [..]", ) .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link -C debuginfo=2 [..]", + --emit=[..]link -C debuginfo=2 [..]", ) .run(); @@ -4526,16 +4525,16 @@ fn build_filter_infer_profile() { p.cargo("build -v --bench=b1") .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 [..]", + --emit=[..]link -C debuginfo=2 [..]", ) .with_stderr_contains( - "[RUNNING] `rustc --crate-name b1 benches/b1.rs --color never --emit=dep-info,link \ + "[RUNNING] `rustc --crate-name b1 benches/b1.rs --color never --emit=[..]link \ -C debuginfo=2 [..]", ) .with_stderr_does_not_contain("opt-level") .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link -C debuginfo=2 [..]", + --emit=[..]link -C debuginfo=2 [..]", ) .run(); } @@ -4548,18 +4547,18 @@ fn targets_selected_default() { .with_stderr_contains( "\ [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) // Benchmarks. .with_stderr_does_not_contain( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C opt-level=3 --test [..]", ) // Unit tests. .with_stderr_does_not_contain( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C debuginfo=2 --test [..]", ) .run(); @@ -4573,12 +4572,12 @@ fn targets_selected_all() { .with_stderr_contains( "\ [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) // Unit tests. .with_stderr_contains( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C debuginfo=2 --test [..]", ) .run(); @@ -4592,12 +4591,12 @@ fn all_targets_no_lib() { .with_stderr_contains( "\ [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) // Unit tests. .with_stderr_contains( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C debuginfo=2 --test [..]", ) .run(); diff --git a/tests/testsuite/build_lib.rs b/tests/testsuite/build_lib.rs index 00c256b610f..05627fe0552 100644 --- a/tests/testsuite/build_lib.rs +++ b/tests/testsuite/build_lib.rs @@ -12,7 +12,7 @@ fn build_lib_only() { "\ [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..] \ -L dependency=[CWD]/target/debug/deps` diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 3303327fea9..db2bf4a0982 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -241,7 +241,7 @@ fn custom_build_script_rustc_flags() { -C metadata=[..] \ -C extra-filename=-[..] \ --out-dir [CWD]/target \ - --emit=dep-info,link \ + --emit=[..]link \ -L [CWD]/target \ -L [CWD]/target/deps` ", @@ -1015,19 +1015,19 @@ fn build_cmd_with_a_build_cmd() { [RUNNING] `rustc [..] a/build.rs [..] --extern b=[..]` [RUNNING] `[..]/a-[..]/build-script-build` [RUNNING] `rustc --crate-name a [..]lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..]target/debug/deps \ -L [..]target/debug/deps` [COMPILING] foo v0.5.0 ([CWD]) [RUNNING] `rustc --crate-name build_script_build build.rs --color never --crate-type bin \ - --emit=dep-info,link \ + --emit=[..]link \ -C debuginfo=2 -C metadata=[..] --out-dir [..] \ -L [..]target/debug/deps \ --extern a=[..]liba[..].rlib` [RUNNING] `[..]/foo-[..]/build-script-build` [RUNNING] `rustc --crate-name foo [..]lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..] \ -L [..]target/debug/deps` @@ -2228,7 +2228,7 @@ fn diamond_passes_args_only_once() { [COMPILING] a v0.5.0 ([..] [RUNNING] `rustc [..]` [COMPILING] foo v0.5.0 ([..] -[RUNNING] `[..]rlib -L native=test` +[RUNNING] `[..]rmeta -L native=test` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", ) diff --git a/tests/testsuite/cfg.rs b/tests/testsuite/cfg.rs index 36866cc27d8..09b0d18c5d6 100644 --- a/tests/testsuite/cfg.rs +++ b/tests/testsuite/cfg.rs @@ -409,7 +409,9 @@ fn any_ok() { .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); - p.cargo("build -v").run(); + p.cargo("build -v") + .env("RUST_LOG", "cargo") + .run(); } // https://github.com/rust-lang/cargo/issues/5313 diff --git a/tests/testsuite/clean.rs b/tests/testsuite/clean.rs index a0ec3affcfb..23e822986d7 100644 --- a/tests/testsuite/clean.rs +++ b/tests/testsuite/clean.rs @@ -289,6 +289,7 @@ fn clean_verbose() { "\ [REMOVING] [..] [REMOVING] [..] +[REMOVING] [..] ", ) .run(); diff --git a/tests/testsuite/cross_compile.rs b/tests/testsuite/cross_compile.rs index 6e9623aba21..e98d0b04456 100644 --- a/tests/testsuite/cross_compile.rs +++ b/tests/testsuite/cross_compile.rs @@ -379,7 +379,7 @@ fn linker_and_ar() { "\ [COMPILING] foo v0.5.0 ([CWD]) [RUNNING] `rustc --crate-name foo src/foo.rs --color never --crate-type bin \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [CWD]/target/{target}/debug/deps \ --target {target} \ diff --git a/tests/testsuite/dep_info.rs b/tests/testsuite/dep_info.rs index 2f8b910f8ba..4e228e86535 100644 --- a/tests/testsuite/dep_info.rs +++ b/tests/testsuite/dep_info.rs @@ -60,7 +60,9 @@ fn build_dep_info_rlib() { .file("examples/ex.rs", "") .build(); - p.cargo("build --example=ex").run(); + p.cargo("build --example=ex") + .env("RUST_LOG", "cargo") + .run(); assert!(p.example_lib("ex", "rlib").with_extension("d").is_file()); } diff --git a/tests/testsuite/freshness.rs b/tests/testsuite/freshness.rs index 76c10a71655..8a076a8dbd0 100644 --- a/tests/testsuite/freshness.rs +++ b/tests/testsuite/freshness.rs @@ -1439,8 +1439,8 @@ fn reuse_panic_pm() { .with_stderr_unordered( "\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C debuginfo=2 [..] +[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C debuginfo=2 [..] +[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C debuginfo=2 [..] [COMPILING] somepm [..] [RUNNING] `rustc --crate-name somepm [..] [COMPILING] foo [..] diff --git a/tests/testsuite/profile_overrides.rs b/tests/testsuite/profile_overrides.rs index 09bfd7dba48..141a709402a 100644 --- a/tests/testsuite/profile_overrides.rs +++ b/tests/testsuite/profile_overrides.rs @@ -321,17 +321,17 @@ fn profile_override_hierarchy() { p.cargo("build -v").masquerade_as_nightly_cargo().with_stderr_unordered("\ [COMPILING] m3 [..] [COMPILING] dep [..] -[RUNNING] `rustc --crate-name m3 m3/src/lib.rs --color never --crate-type lib --emit=dep-info,link -C codegen-units=4 [..] -[RUNNING] `rustc --crate-name dep [..]dep/src/lib.rs --color never --crate-type lib --emit=dep-info,link -C codegen-units=3 [..] -[RUNNING] `rustc --crate-name m3 m3/src/lib.rs --color never --crate-type lib --emit=dep-info,link -C codegen-units=1 [..] -[RUNNING] `rustc --crate-name build_script_build m1/build.rs --color never --crate-type bin --emit=dep-info,link -C codegen-units=4 [..] +[RUNNING] `rustc --crate-name m3 m3/src/lib.rs --color never --crate-type lib --emit=[..]link -C codegen-units=4 [..] +[RUNNING] `rustc --crate-name dep [..]dep/src/lib.rs --color never --crate-type lib --emit=[..]link -C codegen-units=3 [..] +[RUNNING] `rustc --crate-name m3 m3/src/lib.rs --color never --crate-type lib --emit=[..]link -C codegen-units=1 [..] +[RUNNING] `rustc --crate-name build_script_build m1/build.rs --color never --crate-type bin --emit=[..]link -C codegen-units=4 [..] [COMPILING] m2 [..] -[RUNNING] `rustc --crate-name build_script_build m2/build.rs --color never --crate-type bin --emit=dep-info,link -C codegen-units=2 [..] +[RUNNING] `rustc --crate-name build_script_build m2/build.rs --color never --crate-type bin --emit=[..]link -C codegen-units=2 [..] [RUNNING] `[..]/m1-[..]/build-script-build` [RUNNING] `[..]/m2-[..]/build-script-build` -[RUNNING] `rustc --crate-name m2 m2/src/lib.rs --color never --crate-type lib --emit=dep-info,link -C codegen-units=2 [..] +[RUNNING] `rustc --crate-name m2 m2/src/lib.rs --color never --crate-type lib --emit=[..]link -C codegen-units=2 [..] [COMPILING] m1 [..] -[RUNNING] `rustc --crate-name m1 m1/src/lib.rs --color never --crate-type lib --emit=dep-info,link -C codegen-units=1 [..] +[RUNNING] `rustc --crate-name m1 m1/src/lib.rs --color never --crate-type lib --emit=[..]link -C codegen-units=1 [..] [FINISHED] dev [unoptimized + debuginfo] [..] ", ) diff --git a/tests/testsuite/profile_targets.rs b/tests/testsuite/profile_targets.rs index f9de30d1acf..e1f5f8b510f 100644 --- a/tests/testsuite/profile_targets.rs +++ b/tests/testsuite/profile_targets.rs @@ -78,16 +78,16 @@ fn profile_selection_build() { // - build_script_build is built without panic because it thinks `build.rs` is a plugin. p.cargo("build -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); p.cargo("build -vv") @@ -109,16 +109,16 @@ fn profile_selection_build_release() { // `build --release` p.cargo("build --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]/target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] ").run(); p.cargo("build --release -vv") @@ -165,22 +165,22 @@ fn profile_selection_build_all_targets() { // example dev build p.cargo("build --all-targets -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..]` -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); p.cargo("build -vv") @@ -230,22 +230,22 @@ fn profile_selection_build_all_targets_release() { // example release build p.cargo("build --all-targets --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]/target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..]` -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` [FINISHED] release [optimized] [..] ").run(); p.cargo("build --all-targets --release -vv") @@ -286,21 +286,21 @@ fn profile_selection_test() { // p.cargo("test -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]link -C codegen-units=3 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [FINISHED] dev [unoptimized + debuginfo] [..] [RUNNING] `[..]/deps/foo-[..]` [RUNNING] `[..]/deps/foo-[..]` @@ -351,21 +351,21 @@ fn profile_selection_test_release() { // p.cargo("test --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]/target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] [RUNNING] `[..]/deps/foo-[..]` [RUNNING] `[..]/deps/foo-[..]` @@ -416,20 +416,20 @@ fn profile_selection_bench() { // p.cargo("bench -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] [RUNNING] `[..]/deps/foo-[..] --bench` [RUNNING] `[..]/deps/foo-[..] --bench` @@ -480,23 +480,23 @@ fn profile_selection_check_all_targets() { // p.cargo("check --all-targets -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep[..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=[..]metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); // Starting with Rust 1.27, rustc emits `rmeta` files for bins, so @@ -525,23 +525,23 @@ fn profile_selection_check_all_targets_release() { // `dev` for all targets. p.cargo("check --all-targets --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep[..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=[..]metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=[..]metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] ").run(); @@ -586,20 +586,20 @@ fn profile_selection_check_all_targets_test() { // p.cargo("check --all-targets --profile=test -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep[..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--emit=[..]metadata -C codegen-units=1 -C debuginfo=2 --test [..] [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); @@ -632,13 +632,13 @@ fn profile_selection_doc() { p.cargo("doc -vv").with_stderr_unordered("\ [COMPILING] bar [..] [DOCUMENTING] bar [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `rustdoc --crate-name bar bar/src/lib.rs [..] -[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 [DOCUMENTING] foo [..] diff --git a/tests/testsuite/profiles.rs b/tests/testsuite/profiles.rs index dd5608a0573..a139399b823 100644 --- a/tests/testsuite/profiles.rs +++ b/tests/testsuite/profiles.rs @@ -27,7 +27,7 @@ fn profile_overrides() { "\ [COMPILING] test v0.0.0 ([CWD]) [RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level=1 \ -C debug-assertions=on \ -C metadata=[..] \ @@ -63,7 +63,7 @@ fn opt_level_override_0() { "\ [COMPILING] test v0.0.0 ([CWD]) [RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..] \ @@ -96,7 +96,7 @@ fn debug_override_1() { "\ [COMPILING] test v0.0.0 ([CWD]) [RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C debuginfo=1 \ -C metadata=[..] \ --out-dir [..] \ @@ -132,7 +132,7 @@ fn check_opt_level_override(profile_level: &str, rustc_level: &str) { "\ [COMPILING] test v0.0.0 ([CWD]) [RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level={level} \ -C debuginfo=2 \ -C debug-assertions=on \ @@ -171,6 +171,9 @@ fn top_level_overrides_deps() { version = "0.0.0" authors = [] + [lib] + crate-type = ['cdylib'] + [profile.release] opt-level = 1 debug = true @@ -206,7 +209,7 @@ fn top_level_overrides_deps() { [COMPILING] foo v0.0.0 ([CWD]/foo) [RUNNING] `rustc --crate-name foo foo/src/lib.rs --color never \ --crate-type dylib --crate-type rlib \ - --emit=dep-info,link \ + --emit=[..]link \ -C prefer-dynamic \ -C opt-level=1 \ -C debuginfo=2 \ @@ -214,8 +217,8 @@ fn top_level_overrides_deps() { --out-dir [CWD]/target/release/deps \ -L dependency=[CWD]/target/release/deps` [COMPILING] test v0.0.0 ([CWD]) -[RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link \ +[RUNNING] `rustc --crate-name test src/lib.rs --color never --crate-type cdylib \ + --emit=[..]link \ -C opt-level=1 \ -C debuginfo=2 \ -C metadata=[..] \ diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 25494a51cc4..70e938dd09c 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -697,14 +697,14 @@ fn example_with_release_flag() { "\ [COMPILING] bar v0.5.0 ([CWD]/bar) [RUNNING] `rustc --crate-name bar bar/src/bar.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level=3 \ -C metadata=[..] \ --out-dir [CWD]/target/release/deps \ -L dependency=[CWD]/target/release/deps` [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name a examples/a.rs --color never --crate-type bin \ - --emit=dep-info,link \ + --emit=[..]link \ -C opt-level=3 \ -C metadata=[..] \ --out-dir [CWD]/target/release/examples \ @@ -726,14 +726,14 @@ fast2", "\ [COMPILING] bar v0.5.0 ([CWD]/bar) [RUNNING] `rustc --crate-name bar bar/src/bar.rs --color never --crate-type lib \ - --emit=dep-info,link \ + --emit=[..]link \ -C debuginfo=2 \ -C metadata=[..] \ --out-dir [CWD]/target/debug/deps \ -L dependency=[CWD]/target/debug/deps` [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name a examples/a.rs --color never --crate-type bin \ - --emit=dep-info,link \ + --emit=[..]link \ -C debuginfo=2 \ -C metadata=[..] \ --out-dir [CWD]/target/debug/examples \ diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index 8fef310b173..7674afdb62d 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -16,7 +16,7 @@ fn build_lib_for_foo() { "\ [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..] \ -L dependency=[CWD]/target/debug/deps` @@ -38,7 +38,7 @@ fn lib() { "\ [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C debug-assertions=off \ -C metadata=[..] \ --out-dir [..] \ @@ -61,12 +61,12 @@ fn build_main_and_allow_unstable_options() { "\ [COMPILING] {name} v{version} ([CWD]) [RUNNING] `rustc --crate-name {name} src/lib.rs --color never --crate-type lib \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C metadata=[..] \ --out-dir [..] \ -L dependency=[CWD]/target/debug/deps` [RUNNING] `rustc --crate-name {name} src/main.rs --color never --crate-type bin \ - --emit=dep-info,link -C debuginfo=2 \ + --emit=[..]link -C debuginfo=2 \ -C debug-assertions \ -C metadata=[..] \ --out-dir [..] \ @@ -106,10 +106,10 @@ fn build_with_args_to_one_of_multiple_binaries() { .with_stderr( "\ [COMPILING] foo v0.0.1 ([CWD]) -[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib --emit=dep-info,link \ +[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib --emit=[..]link \ -C debuginfo=2 -C metadata=[..] \ --out-dir [..]` -[RUNNING] `rustc --crate-name bar src/bin/bar.rs --color never --crate-type bin --emit=dep-info,link \ +[RUNNING] `rustc --crate-name bar src/bin/bar.rs --color never --crate-type bin --emit=[..]link \ -C debuginfo=2 -C debug-assertions [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", @@ -144,10 +144,10 @@ fn build_with_args_to_one_of_multiple_tests() { .with_stderr( "\ [COMPILING] foo v0.0.1 ([CWD]) -[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib --emit=dep-info,link \ +[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib --emit=[..]link \ -C debuginfo=2 -C metadata=[..] \ --out-dir [..]` -[RUNNING] `rustc --crate-name bar tests/bar.rs --color never --emit=dep-info,link -C debuginfo=2 \ +[RUNNING] `rustc --crate-name bar tests/bar.rs --color never --emit=[..]link -C debuginfo=2 \ -C debug-assertions [..]--test[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", @@ -233,18 +233,18 @@ fn targets_selected_default() { .with_stderr_contains( "\ [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) // bench .with_stderr_does_not_contain( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C opt-level=3 --test [..]", ) // unit test .with_stderr_does_not_contain( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C debuginfo=2 --test [..]", ) .run(); @@ -258,12 +258,12 @@ fn targets_selected_all() { .with_stderr_contains( "\ [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]", + --emit=[..]link[..]", ) // unit test .with_stderr_contains( "\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=[..]link \ -C debuginfo=2 --test [..]", ) .run();