Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/bin/cargo/commands/owner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ pub fn cli() -> App {
.about("Manage the owners of a crate on the registry")
.arg(opt("quiet", "No output printed to stdout").short("q"))
.arg(Arg::with_name("crate"))
.arg(multi_opt("add", "LOGIN", "Name of a user or team to invite as an owner").short("a"))
.arg(
multi_opt(
"add",
"LOGIN",
"Name of a user or team to invite as an owner",
)
.short("a"),
)
.arg(
multi_opt(
"remove",
Expand Down
13 changes: 8 additions & 5 deletions src/bin/cargo/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ pub fn cli() -> App {
.last(true),
)
.arg(
opt("quiet", "Display one character per test instead of one line")
.short("q")
opt(
"quiet",
"Display one character per test instead of one line",
)
.short("q"),
)
.arg_targets_all(
"Test only this package's library unit tests",
Expand Down Expand Up @@ -131,9 +134,9 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
} else if test_name.is_some() {
if let CompileFilter::Default { .. } = compile_opts.filter {
compile_opts.filter = ops::CompileFilter::new(
LibRule::Default, // compile the library, so the unit tests can be run filtered
FilterRule::All, // compile the binaries, so the unit tests in binaries can be run filtered
FilterRule::All, // compile the tests, so the integration tests can be run filtered
LibRule::Default, // compile the library, so the unit tests can be run filtered
FilterRule::All, // compile the binaries, so the unit tests in binaries can be run filtered
FilterRule::All, // compile the tests, so the integration tests can be run filtered
FilterRule::none(), // specify --examples to unit test binaries filtered
FilterRule::none(), // specify --benches to unit test benchmarks filtered
); // also, specify --doc to run doc tests filtered
Expand Down
3 changes: 2 additions & 1 deletion src/bin/cargo/commands/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use crate::command_prelude::*;
use crate::cli;

pub fn cli() -> App {
subcommand("version").about("Show version information")
subcommand("version")
.about("Show version information")
.arg(opt("quiet", "No output printed to stdout").short("q"))
}

Expand Down
4 changes: 1 addition & 3 deletions src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,7 @@ impl TargetConfig {
}
"rustc-cdylib-link-arg" => {
let args = value.list(k)?;
output
.linker_args
.extend(args.iter().map(|v| v.0.clone()));
output.linker_args.extend(args.iter().map(|v| v.0.clone()));
}
"rustc-cfg" => {
let list = value.list(k)?;
Expand Down
7 changes: 6 additions & 1 deletion src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,13 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
}
}

/// Returns the root of the build output tree.
/// Returns the root of the build output tree for the target
pub fn target_root(&self) -> &Path {
self.target.as_ref().unwrap_or(&self.host).dest()
}

/// Returns the root of the build output tree for the host
pub fn host_root(&self) -> &Path {
self.host.dest()
}

Expand Down
7 changes: 4 additions & 3 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
path.display()
)
};
let suggestion = "Consider changing their names to be unique or compiling them separately.\n\
This may become a hard error in the future; see \
<https://github.com/rust-lang/cargo/issues/6313>.";
let suggestion =
"Consider changing their names to be unique or compiling them separately.\n\
This may become a hard error in the future; see \
<https://github.com/rust-lang/cargo/issues/6313>.";
let report_collision = |unit: &Unit<'_>,
other_unit: &Unit<'_>,
path: &PathBuf|
Expand Down
134 changes: 80 additions & 54 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use std::sync::{Arc, Mutex};
use crate::core::PackageId;
use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::machine_message;
use crate::util::Cfg;
use crate::util::{self, internal, paths, profile};
use crate::util::{Cfg, Freshness};

use super::job::Work;
use super::job::{Freshness, Job, Work};
use super::{fingerprint, Context, Kind, TargetConfig, Unit};

/// Contains the parsed output of a custom build script.
Expand Down Expand Up @@ -80,32 +80,19 @@ pub struct BuildDeps {
/// prepare work for. If the requirement is specified as both the target and the
/// host platforms it is assumed that the two are equal and the build script is
/// only run once (not twice).
pub fn prepare<'a, 'cfg>(
cx: &mut Context<'a, 'cfg>,
unit: &Unit<'a>,
) -> CargoResult<(Work, Work, Freshness)> {
pub fn prepare<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult<Job> {
let _p = profile::start(format!(
"build script prepare: {}/{}",
unit.pkg,
unit.target.name()
));

let key = (unit.pkg.package_id(), unit.kind);
let overridden = cx.build_script_overridden.contains(&key);
let (work_dirty, work_fresh) = if overridden {
(Work::noop(), Work::noop())
} else {
build_work(cx, unit)?
};

if cx.bcx.build_config.build_plan {
Ok((work_dirty, work_fresh, Freshness::Dirty))
if cx.build_script_overridden.contains(&key) {
fingerprint::prepare_target(cx, unit, false)
} else {
// Now that we've prep'd our work, build the work needed to manage the
// fingerprint and then start returning that upwards.
let (freshness, dirty, fresh) = fingerprint::prepare_build_cmd(cx, unit)?;

Ok((work_dirty.then(dirty), work_fresh.then(fresh), freshness))
build_work(cx, unit)
}
}

Expand All @@ -125,7 +112,7 @@ fn emit_build_output(output: &BuildOutput, package_id: PackageId) {
});
}

fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult<(Work, Work)> {
fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult<Job> {
assert!(unit.mode.is_run_custom_build());
let bcx = &cx.bcx;
let dependencies = cx.dep_targets(unit);
Expand Down Expand Up @@ -248,7 +235,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
let output_file = script_run_dir.join("output");
let err_file = script_run_dir.join("stderr");
let root_output_file = script_run_dir.join("root-output");
let host_target_root = cx.files().target_root().to_path_buf();
let host_target_root = cx.files().host_root().to_path_buf();
let all = (
id,
pkg_name.clone(),
Expand All @@ -260,22 +247,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
let kind = unit.kind;
let json_messages = bcx.build_config.json_messages();
let extra_verbose = bcx.config.extra_verbose();

// Check to see if the build script has already run, and if it has, keep
// track of whether it has told us about some explicit dependencies.
let prev_script_out_dir = paths::read_bytes(&root_output_file)
.and_then(|bytes| util::bytes2path(&bytes))
.unwrap_or_else(|_| script_out_dir.clone());

let prev_output = BuildOutput::parse_file(
&output_file,
&pkg_name,
&prev_script_out_dir,
&script_out_dir,
)
.ok();
let deps = BuildDeps::new(&output_file, prev_output.as_ref());
cx.build_explicit_deps.insert(*unit, deps);
let (prev_output, prev_script_out_dir) = prev_build_output(cx, unit);

fs::create_dir_all(&script_dir)?;
fs::create_dir_all(&script_out_dir)?;
Expand Down Expand Up @@ -392,7 +364,17 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
Ok(())
});

Ok((dirty, fresh))
let mut job = if cx.bcx.build_config.build_plan {
Job::new(Work::noop(), Freshness::Dirty)
} else {
fingerprint::prepare_target(cx, unit, false)?
};
if job.freshness() == Freshness::Dirty {
job.before(dirty);
} else {
job.before(fresh);
}
Ok(job)
}

impl BuildState {
Expand Down Expand Up @@ -637,22 +619,20 @@ pub fn build_map<'b, 'cfg>(cx: &mut Context<'b, 'cfg>, units: &[Unit<'b>]) -> Ca
return Ok(&out[unit]);
}

{
let key = unit
.pkg
.manifest()
.links()
.map(|l| (l.to_string(), unit.kind));
let build_state = &cx.build_state;
if let Some(output) = key.and_then(|k| build_state.overrides.get(&k)) {
let key = (unit.pkg.package_id(), unit.kind);
cx.build_script_overridden.insert(key);
build_state
.outputs
.lock()
.unwrap()
.insert(key, output.clone());
}
let key = unit
.pkg
.manifest()
.links()
.map(|l| (l.to_string(), unit.kind));
let build_state = &cx.build_state;
if let Some(output) = key.and_then(|k| build_state.overrides.get(&k)) {
let key = (unit.pkg.package_id(), unit.kind);
cx.build_script_overridden.insert(key);
build_state
.outputs
.lock()
.unwrap()
.insert(key, output.clone());
}

let mut ret = BuildScripts::default();
Expand All @@ -661,6 +641,10 @@ pub fn build_map<'b, 'cfg>(cx: &mut Context<'b, 'cfg>, units: &[Unit<'b>]) -> Ca
add_to_link(&mut ret, unit.pkg.package_id(), unit.kind);
}

if unit.mode.is_run_custom_build() {
parse_previous_explicit_deps(cx, unit)?;
}

// We want to invoke the compiler deterministically to be cache-friendly
// to rustc invocation caching schemes, so be sure to generate the same
// set of build script dependency orderings via sorting the targets that
Expand Down Expand Up @@ -694,4 +678,46 @@ pub fn build_map<'b, 'cfg>(cx: &mut Context<'b, 'cfg>, units: &[Unit<'b>]) -> Ca
scripts.to_link.push((pkg, kind));
}
}

fn parse_previous_explicit_deps<'a, 'cfg>(
cx: &mut Context<'a, 'cfg>,
unit: &Unit<'a>,
) -> CargoResult<()> {
let script_run_dir = cx.files().build_script_run_dir(unit);
let output_file = script_run_dir.join("output");
let (prev_output, _) = prev_build_output(cx, unit);
let deps = BuildDeps::new(&output_file, prev_output.as_ref());
cx.build_explicit_deps.insert(*unit, deps);
Ok(())
}
}

/// Returns the previous parsed `BuildOutput`, if any, from a previous
/// execution.
///
/// Also returns the directory containing the output, typically used later in
/// processing.
fn prev_build_output<'a, 'cfg>(
cx: &mut Context<'a, 'cfg>,
unit: &Unit<'a>,
) -> (Option<BuildOutput>, PathBuf) {
let script_out_dir = cx.files().build_script_out_dir(unit);
let script_run_dir = cx.files().build_script_run_dir(unit);
let root_output_file = script_run_dir.join("root-output");
let output_file = script_run_dir.join("output");

let prev_script_out_dir = paths::read_bytes(&root_output_file)
.and_then(|bytes| util::bytes2path(&bytes))
.unwrap_or_else(|_| script_out_dir.clone());

(
BuildOutput::parse_file(
&output_file,
&unit.pkg.to_string(),
&prev_script_out_dir,
&script_out_dir,
)
.ok(),
prev_script_out_dir,
)
}
Loading