Skip to content

Commit 491deb6

Browse files
committed
Auto merge of #9771 - hi-rustin:rustin-patch-dep, r=ehuss
Warning for no lib dependencies close #6702
2 parents 1bc1868 + 0b543ba commit 491deb6

File tree

3 files changed

+287
-23
lines changed

3 files changed

+287
-23
lines changed

src/cargo/core/package.rs

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -516,32 +516,19 @@ impl<'cfg> PackageSet<'cfg> {
516516
if !used.insert(pkg_id) {
517517
return Ok(());
518518
}
519-
let filtered_deps = resolve.deps(pkg_id).filter(|&(_id, deps)| {
520-
deps.iter().any(|dep| {
521-
if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No {
522-
return false;
523-
}
524-
// This is overly broad, since not all target-specific
525-
// dependencies are used both for target and host. To tighten this
526-
// up, this function would need to track "for_host" similar to how
527-
// unit dependencies handles it.
528-
if force_all_targets == ForceAllTargets::No {
529-
let activated = requested_kinds
530-
.iter()
531-
.chain(Some(&CompileKind::Host))
532-
.any(|kind| target_data.dep_platform_activated(dep, *kind));
533-
if !activated {
534-
return false;
535-
}
536-
}
537-
true
538-
})
539-
});
540-
for (dep_id, _deps) in filtered_deps {
519+
let filtered_deps = PackageSet::filter_deps(
520+
pkg_id,
521+
resolve,
522+
has_dev_units,
523+
requested_kinds,
524+
target_data,
525+
force_all_targets,
526+
);
527+
for pkg_id in filtered_deps {
541528
collect_used_deps(
542529
used,
543530
resolve,
544-
dep_id,
531+
pkg_id,
545532
has_dev_units,
546533
requested_kinds,
547534
target_data,
@@ -571,6 +558,75 @@ impl<'cfg> PackageSet<'cfg> {
571558
Ok(())
572559
}
573560

561+
/// Check if there are any dependency packages that do not have any libs.
562+
pub(crate) fn no_lib_pkgs(
563+
&self,
564+
resolve: &Resolve,
565+
root_ids: &[PackageId],
566+
has_dev_units: HasDevUnits,
567+
requested_kinds: &[CompileKind],
568+
target_data: &RustcTargetData<'_>,
569+
force_all_targets: ForceAllTargets,
570+
) -> BTreeMap<PackageId, Vec<&Package>> {
571+
root_ids
572+
.iter()
573+
.map(|&root_id| {
574+
let pkgs = PackageSet::filter_deps(
575+
root_id,
576+
resolve,
577+
has_dev_units,
578+
requested_kinds,
579+
target_data,
580+
force_all_targets,
581+
)
582+
.filter_map(|package_id| {
583+
if let Ok(dep_pkg) = self.get_one(package_id) {
584+
if !dep_pkg.targets().iter().any(|t| t.is_lib()) {
585+
Some(dep_pkg)
586+
} else {
587+
None
588+
}
589+
} else {
590+
None
591+
}
592+
})
593+
.collect();
594+
(root_id, pkgs)
595+
})
596+
.collect()
597+
}
598+
599+
fn filter_deps<'a>(
600+
pkg_id: PackageId,
601+
resolve: &'a Resolve,
602+
has_dev_units: HasDevUnits,
603+
requested_kinds: &'a [CompileKind],
604+
target_data: &'a RustcTargetData<'_>,
605+
force_all_targets: ForceAllTargets,
606+
) -> impl Iterator<Item = PackageId> + 'a {
607+
resolve
608+
.deps(pkg_id)
609+
.filter(move |&(_id, deps)| {
610+
deps.iter().any(|dep| {
611+
if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No {
612+
return false;
613+
}
614+
if force_all_targets == ForceAllTargets::No {
615+
let activated = requested_kinds
616+
.iter()
617+
.chain(Some(&CompileKind::Host))
618+
.any(|kind| target_data.dep_platform_activated(dep, *kind));
619+
if !activated {
620+
return false;
621+
}
622+
}
623+
true
624+
})
625+
})
626+
.map(|(pkg_id, _)| pkg_id)
627+
.into_iter()
628+
}
629+
574630
pub fn sources(&self) -> Ref<'_, SourceMap<'cfg>> {
575631
self.sources.borrow()
576632
}

src/cargo/ops/resolve.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ pub fn resolve_ws_with_opts<'cfg>(
171171
feature_opts,
172172
)?;
173173

174+
let no_lib_pkgs = pkg_set.no_lib_pkgs(
175+
&resolved_with_overrides,
176+
&member_ids,
177+
has_dev_units,
178+
requested_targets,
179+
target_data,
180+
force_all_targets,
181+
);
182+
for (pkg_id, dep_pkgs) in no_lib_pkgs {
183+
for dep_pkg in dep_pkgs {
184+
ws.config().shell().warn(&format!(
185+
"{} ignoring invalid dependency `{}` which is missing a lib target",
186+
pkg_id,
187+
dep_pkg.name(),
188+
))?;
189+
}
190+
}
191+
174192
Ok(WorkspaceResolve {
175193
pkg_set,
176194
workspace_resolve: resolve,

tests/testsuite/run.rs

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,196 @@ fn run_dylib_dep() {
723723
p.cargo("run hello world").run();
724724
}
725725

726+
#[cargo_test]
727+
fn run_with_bin_dep() {
728+
let p = project()
729+
.file(
730+
"Cargo.toml",
731+
r#"
732+
[package]
733+
name = "foo"
734+
version = "0.0.1"
735+
736+
[dependencies.bar]
737+
path = "bar"
738+
"#,
739+
)
740+
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
741+
.file(
742+
"bar/Cargo.toml",
743+
r#"
744+
[package]
745+
name = "bar"
746+
version = "0.0.1"
747+
authors = []
748+
749+
[[bin]]
750+
name = "bar"
751+
"#,
752+
)
753+
.file("bar/src/main.rs", r#"fn main() { println!("bar"); }"#)
754+
.build();
755+
756+
p.cargo("run")
757+
.with_stderr(
758+
"\
759+
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar` which is missing a lib target
760+
[COMPILING] foo v0.0.1 ([CWD])
761+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
762+
[RUNNING] `target/debug/foo[EXE]`",
763+
)
764+
.with_stdout("hello")
765+
.run();
766+
}
767+
768+
#[cargo_test]
769+
fn run_with_bin_deps() {
770+
let p = project()
771+
.file(
772+
"Cargo.toml",
773+
r#"
774+
[package]
775+
name = "foo"
776+
version = "0.0.1"
777+
778+
[dependencies.bar1]
779+
path = "bar1"
780+
[dependencies.bar2]
781+
path = "bar2"
782+
"#,
783+
)
784+
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
785+
.file(
786+
"bar1/Cargo.toml",
787+
r#"
788+
[package]
789+
name = "bar1"
790+
version = "0.0.1"
791+
authors = []
792+
793+
[[bin]]
794+
name = "bar1"
795+
"#,
796+
)
797+
.file("bar1/src/main.rs", r#"fn main() { println!("bar1"); }"#)
798+
.file(
799+
"bar2/Cargo.toml",
800+
r#"
801+
[package]
802+
name = "bar2"
803+
version = "0.0.1"
804+
authors = []
805+
806+
[[bin]]
807+
name = "bar2"
808+
"#,
809+
)
810+
.file("bar2/src/main.rs", r#"fn main() { println!("bar2"); }"#)
811+
.build();
812+
813+
p.cargo("run")
814+
.with_stderr(
815+
"\
816+
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar1` which is missing a lib target
817+
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar2` which is missing a lib target
818+
[COMPILING] foo v0.0.1 ([CWD])
819+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
820+
[RUNNING] `target/debug/foo[EXE]`",
821+
)
822+
.with_stdout("hello")
823+
.run();
824+
}
825+
826+
#[cargo_test]
827+
fn run_with_bin_dep_in_workspace() {
828+
let p = project()
829+
.file(
830+
"Cargo.toml",
831+
r#"
832+
[workspace]
833+
members = ["foo1", "foo2"]
834+
"#,
835+
)
836+
.file(
837+
"foo1/Cargo.toml",
838+
r#"
839+
[package]
840+
name = "foo1"
841+
version = "0.0.1"
842+
843+
[dependencies.bar1]
844+
path = "bar1"
845+
"#,
846+
)
847+
.file("foo1/src/main.rs", r#"fn main() { println!("hello"); }"#)
848+
.file(
849+
"foo1/bar1/Cargo.toml",
850+
r#"
851+
[package]
852+
name = "bar1"
853+
version = "0.0.1"
854+
authors = []
855+
856+
[[bin]]
857+
name = "bar1"
858+
"#,
859+
)
860+
.file(
861+
"foo1/bar1/src/main.rs",
862+
r#"fn main() { println!("bar1"); }"#,
863+
)
864+
.file(
865+
"foo2/Cargo.toml",
866+
r#"
867+
[package]
868+
name = "foo2"
869+
version = "0.0.1"
870+
871+
[dependencies.bar2]
872+
path = "bar2"
873+
"#,
874+
)
875+
.file("foo2/src/main.rs", r#"fn main() { println!("hello"); }"#)
876+
.file(
877+
"foo2/bar2/Cargo.toml",
878+
r#"
879+
[package]
880+
name = "bar2"
881+
version = "0.0.1"
882+
authors = []
883+
884+
[[bin]]
885+
name = "bar2"
886+
"#,
887+
)
888+
.file(
889+
"foo2/bar2/src/main.rs",
890+
r#"fn main() { println!("bar2"); }"#,
891+
)
892+
.build();
893+
894+
p.cargo("run")
895+
.with_status(101)
896+
.with_stderr(
897+
"\
898+
[ERROR] `cargo run` could not determine which binary to run[..]
899+
available binaries: bar1, bar2, foo1, foo2",
900+
)
901+
.run();
902+
903+
p.cargo("run --bin foo1")
904+
.with_stderr(
905+
"\
906+
[WARNING] foo1 v0.0.1 ([CWD]/foo1) ignoring invalid dependency `bar1` which is missing a lib target
907+
[WARNING] foo2 v0.0.1 ([CWD]/foo2) ignoring invalid dependency `bar2` which is missing a lib target
908+
[COMPILING] foo1 v0.0.1 ([CWD]/foo1)
909+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
910+
[RUNNING] `target/debug/foo1[EXE]`",
911+
)
912+
.with_stdout("hello")
913+
.run();
914+
}
915+
726916
#[cargo_test]
727917
fn release_works() {
728918
let p = project()

0 commit comments

Comments
 (0)