Skip to content

Commit

Permalink
Auto merge of #9771 - hi-rustin:rustin-patch-dep, r=ehuss
Browse files Browse the repository at this point in the history
Warning for no lib dependencies

close #6702
  • Loading branch information
bors committed Aug 23, 2021
2 parents 1bc1868 + 0b543ba commit 491deb6
Show file tree
Hide file tree
Showing 3 changed files with 287 additions and 23 deletions.
102 changes: 79 additions & 23 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,32 +516,19 @@ impl<'cfg> PackageSet<'cfg> {
if !used.insert(pkg_id) {
return Ok(());
}
let filtered_deps = resolve.deps(pkg_id).filter(|&(_id, deps)| {
deps.iter().any(|dep| {
if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No {
return false;
}
// This is overly broad, since not all target-specific
// dependencies are used both for target and host. To tighten this
// up, this function would need to track "for_host" similar to how
// unit dependencies handles it.
if force_all_targets == ForceAllTargets::No {
let activated = requested_kinds
.iter()
.chain(Some(&CompileKind::Host))
.any(|kind| target_data.dep_platform_activated(dep, *kind));
if !activated {
return false;
}
}
true
})
});
for (dep_id, _deps) in filtered_deps {
let filtered_deps = PackageSet::filter_deps(
pkg_id,
resolve,
has_dev_units,
requested_kinds,
target_data,
force_all_targets,
);
for pkg_id in filtered_deps {
collect_used_deps(
used,
resolve,
dep_id,
pkg_id,
has_dev_units,
requested_kinds,
target_data,
Expand Down Expand Up @@ -571,6 +558,75 @@ impl<'cfg> PackageSet<'cfg> {
Ok(())
}

/// Check if there are any dependency packages that do not have any libs.
pub(crate) fn no_lib_pkgs(
&self,
resolve: &Resolve,
root_ids: &[PackageId],
has_dev_units: HasDevUnits,
requested_kinds: &[CompileKind],
target_data: &RustcTargetData<'_>,
force_all_targets: ForceAllTargets,
) -> BTreeMap<PackageId, Vec<&Package>> {
root_ids
.iter()
.map(|&root_id| {
let pkgs = PackageSet::filter_deps(
root_id,
resolve,
has_dev_units,
requested_kinds,
target_data,
force_all_targets,
)
.filter_map(|package_id| {
if let Ok(dep_pkg) = self.get_one(package_id) {
if !dep_pkg.targets().iter().any(|t| t.is_lib()) {
Some(dep_pkg)
} else {
None
}
} else {
None
}
})
.collect();
(root_id, pkgs)
})
.collect()
}

fn filter_deps<'a>(
pkg_id: PackageId,
resolve: &'a Resolve,
has_dev_units: HasDevUnits,
requested_kinds: &'a [CompileKind],
target_data: &'a RustcTargetData<'_>,
force_all_targets: ForceAllTargets,
) -> impl Iterator<Item = PackageId> + 'a {
resolve
.deps(pkg_id)
.filter(move |&(_id, deps)| {
deps.iter().any(|dep| {
if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No {
return false;
}
if force_all_targets == ForceAllTargets::No {
let activated = requested_kinds
.iter()
.chain(Some(&CompileKind::Host))
.any(|kind| target_data.dep_platform_activated(dep, *kind));
if !activated {
return false;
}
}
true
})
})
.map(|(pkg_id, _)| pkg_id)
.into_iter()
}

pub fn sources(&self) -> Ref<'_, SourceMap<'cfg>> {
self.sources.borrow()
}
Expand Down
18 changes: 18 additions & 0 deletions src/cargo/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,24 @@ pub fn resolve_ws_with_opts<'cfg>(
feature_opts,
)?;

let no_lib_pkgs = pkg_set.no_lib_pkgs(
&resolved_with_overrides,
&member_ids,
has_dev_units,
requested_targets,
target_data,
force_all_targets,
);
for (pkg_id, dep_pkgs) in no_lib_pkgs {
for dep_pkg in dep_pkgs {
ws.config().shell().warn(&format!(
"{} ignoring invalid dependency `{}` which is missing a lib target",
pkg_id,
dep_pkg.name(),
))?;
}
}

Ok(WorkspaceResolve {
pkg_set,
workspace_resolve: resolve,
Expand Down
190 changes: 190 additions & 0 deletions tests/testsuite/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,196 @@ fn run_dylib_dep() {
p.cargo("run hello world").run();
}

#[cargo_test]
fn run_with_bin_dep() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[dependencies.bar]
path = "bar"
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "0.0.1"
authors = []
[[bin]]
name = "bar"
"#,
)
.file("bar/src/main.rs", r#"fn main() { println!("bar"); }"#)
.build();

p.cargo("run")
.with_stderr(
"\
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar` which is missing a lib target
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo[EXE]`",
)
.with_stdout("hello")
.run();
}

#[cargo_test]
fn run_with_bin_deps() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[dependencies.bar1]
path = "bar1"
[dependencies.bar2]
path = "bar2"
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"bar1/Cargo.toml",
r#"
[package]
name = "bar1"
version = "0.0.1"
authors = []
[[bin]]
name = "bar1"
"#,
)
.file("bar1/src/main.rs", r#"fn main() { println!("bar1"); }"#)
.file(
"bar2/Cargo.toml",
r#"
[package]
name = "bar2"
version = "0.0.1"
authors = []
[[bin]]
name = "bar2"
"#,
)
.file("bar2/src/main.rs", r#"fn main() { println!("bar2"); }"#)
.build();

p.cargo("run")
.with_stderr(
"\
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar1` which is missing a lib target
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar2` which is missing a lib target
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo[EXE]`",
)
.with_stdout("hello")
.run();
}

#[cargo_test]
fn run_with_bin_dep_in_workspace() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo1", "foo2"]
"#,
)
.file(
"foo1/Cargo.toml",
r#"
[package]
name = "foo1"
version = "0.0.1"
[dependencies.bar1]
path = "bar1"
"#,
)
.file("foo1/src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"foo1/bar1/Cargo.toml",
r#"
[package]
name = "bar1"
version = "0.0.1"
authors = []
[[bin]]
name = "bar1"
"#,
)
.file(
"foo1/bar1/src/main.rs",
r#"fn main() { println!("bar1"); }"#,
)
.file(
"foo2/Cargo.toml",
r#"
[package]
name = "foo2"
version = "0.0.1"
[dependencies.bar2]
path = "bar2"
"#,
)
.file("foo2/src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"foo2/bar2/Cargo.toml",
r#"
[package]
name = "bar2"
version = "0.0.1"
authors = []
[[bin]]
name = "bar2"
"#,
)
.file(
"foo2/bar2/src/main.rs",
r#"fn main() { println!("bar2"); }"#,
)
.build();

p.cargo("run")
.with_status(101)
.with_stderr(
"\
[ERROR] `cargo run` could not determine which binary to run[..]
available binaries: bar1, bar2, foo1, foo2",
)
.run();

p.cargo("run --bin foo1")
.with_stderr(
"\
[WARNING] foo1 v0.0.1 ([CWD]/foo1) ignoring invalid dependency `bar1` which is missing a lib target
[WARNING] foo2 v0.0.1 ([CWD]/foo2) ignoring invalid dependency `bar2` which is missing a lib target
[COMPILING] foo1 v0.0.1 ([CWD]/foo1)
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo1[EXE]`",
)
.with_stdout("hello")
.run();
}

#[cargo_test]
fn release_works() {
let p = project()
Expand Down

0 comments on commit 491deb6

Please sign in to comment.