release: options.flag_release,
mode: ops::CompileMode::Build,
filter: if examples.is_empty() && bins.is_empty() {
- ops::CompileFilter::Everything
+ ops::CompileFilter::Everything { required_features_filterable: false, }
} else {
ops::CompileFilter::Only {
lib: false, tests: &[], benches: &[],
}
pub enum CompileFilter<'a> {
- Everything,
+ Everything {
+ /// Flag whether targets can be safely skipped when required-features are not satisfied.
+ required_features_filterable: bool,
+ },
Only {
lib: bool,
bins: &'a [String],
tests: tests,
}
} else {
- CompileFilter::Everything
+ CompileFilter::Everything {
+ required_features_filterable: true,
+ }
}
}
pub fn matches(&self, target: &Target) -> bool {
match *self {
- CompileFilter::Everything => true,
+ CompileFilter::Everything { .. } => true,
CompileFilter::Only { lib, bins, examples, tests, benches } => {
let list = match *target.kind() {
TargetKind::Bin => bins,
CompileMode::Doctest => &profiles.doctest,
};
let mut targets = match *filter {
- CompileFilter::Everything => {
+ CompileFilter::Everything { .. } => {
match mode {
CompileMode::Bench => {
pkg.targets().iter().filter(|t| t.benched()).map(|t| {
continue;
}
- if let CompileFilter::Only { .. } = *filter {
+ if match *filter {
+ CompileFilter::Everything { required_features_filterable } =>
+ !required_features_filterable,
+ CompileFilter::Only { .. } => true,
+ } {
let required_features = target.required_features().unwrap();
let quoted_required_features: Vec<String> = required_features.iter()
.map(|s| format!("`{}`",s))
filter: &ops::CompileFilter,
prev: &CrateListingV1,
force: bool) -> CargoResult<BTreeMap<String, Option<PackageId>>> {
- if let CompileFilter::Everything = *filter {
+ if let CompileFilter::Everything { .. } = *filter {
// If explicit --bin or --example flags were passed then those'll
// get checked during cargo_compile, we only care about the "build
// everything" case here
}
};
match *filter {
- CompileFilter::Everything => {
+ CompileFilter::Everything { .. } => {
pkg.targets().iter()
.filter(|t| t.is_bin())
.filter_map(|t| check(t.name()))
no_default_features: false,
all_features: false,
spec: ops::Packages::Packages(&[]),
- filter: ops::CompileFilter::Everything,
+ filter: ops::CompileFilter::Everything { required_features_filterable: true },
release: false,
message_format: ops::MessageFormat::Human,
mode: ops::CompileMode::Build,
let mut bins = pkg.manifest().targets().iter().filter(|a| {
!a.is_lib() && !a.is_custom_build() && match options.filter {
- CompileFilter::Everything => a.is_bin(),
+ CompileFilter::Everything { .. } => a.is_bin(),
CompileFilter::Only { .. } => options.filter.matches(a),
}
});
if bins.next().is_none() {
match options.filter {
- CompileFilter::Everything => {
+ CompileFilter::Everything { .. } => {
bail!("a bin target must be available for `cargo run`")
}
CompileFilter::Only { .. } => {
}
if bins.next().is_some() {
match options.filter {
- CompileFilter::Everything => {
+ CompileFilter::Everything { .. } => {
bail!("`cargo run` requires that a project only have one \
executable; use the `--bin` option to specify which one \
to run")
error[E0463]: can't find crate for `bar`", p.url())));
}
}
+
+#[test]
+fn run_default() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = []
+ a = []
+
+ [[bin]]
+ name = "foo"
+ required-features = ["a"]
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "extern crate foo; fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("run"),
+ execs().with_status(101).with_stderr("\
+error: target `foo` requires the features: `a`
+Consider enabling them by passing e.g. `--features=\"a\"`
+"));
+
+ assert_that(p.cargo("run").arg("--features").arg("a"),
+ execs().with_status(0));
+}
+
+#[test]
+fn run_default_multiple_required_features() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+ b = []
+
+ [[bin]]
+ name = "foo1"
+ path = "src/foo1.rs"
+ required-features = ["a"]
+
+ [[bin]]
+ name = "foo2"
+ path = "src/foo2.rs"
+ required-features = ["b"]
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/foo1.rs", "extern crate foo; fn main() {}")
+ .file("src/foo2.rs", "extern crate foo; fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("run"),
+ execs().with_status(101).with_stderr("\
+error: `cargo run` requires that a project only have one executable; \
+use the `--bin` option to specify which one to run"));
+}
\ No newline at end of file