mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
cargo-metadata: support -Zbindeps info
This commit is contained in:
parent
ca626c5915
commit
e5ec492b6f
@ -1,8 +1,8 @@
|
||||
use crate::core::compiler::{CompileKind, RustcTargetData};
|
||||
use crate::core::dependency::DepKind;
|
||||
use crate::core::dependency::{ArtifactKind, DepKind};
|
||||
use crate::core::package::SerializedPackage;
|
||||
use crate::core::resolver::{features::CliFeatures, HasDevUnits, Resolve};
|
||||
use crate::core::{Dependency, Package, PackageId, Workspace};
|
||||
use crate::core::{Package, PackageId, Target, Workspace};
|
||||
use crate::ops::{self, Packages};
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::CargoResult;
|
||||
@ -90,15 +90,26 @@ struct Dep {
|
||||
struct DepKindInfo {
|
||||
kind: DepKind,
|
||||
target: Option<Platform>,
|
||||
}
|
||||
|
||||
impl From<&Dependency> for DepKindInfo {
|
||||
fn from(dep: &Dependency) -> DepKindInfo {
|
||||
DepKindInfo {
|
||||
kind: dep.kind(),
|
||||
target: dep.platform().cloned(),
|
||||
}
|
||||
}
|
||||
// vvvvv The fields below are introduced for `-Z bindeps`.
|
||||
/// Artifact's crate type, e.g. staticlib, cdylib, bin...
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
artifact: Option<&'static str>,
|
||||
/// What the manifest calls the crate.
|
||||
///
|
||||
/// A renamed dependency will show the rename instead of original name.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
extern_name: Option<InternedString>,
|
||||
/// Equivalent to `{ target = "…" }` in an artifact dependency requirement.
|
||||
///
|
||||
/// * If the target points to a custom target JSON file, the path will be absolute.
|
||||
/// * If the target is a build assumed target `{ target = "target" }`, it will show as `<target>`.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
compile_target: Option<InternedString>,
|
||||
/// Executable name for an artifact binary dependency.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
bin_name: Option<String>,
|
||||
// ^^^^^ The fields above are introduced for `-Z bindeps`.
|
||||
}
|
||||
|
||||
/// Builds the resolve graph as it will be displayed to the user.
|
||||
@ -206,22 +217,101 @@ fn build_resolve_graph_r(
|
||||
}
|
||||
})
|
||||
.filter_map(|(dep_id, deps)| {
|
||||
let mut dep_kinds: Vec<_> = deps.iter().map(DepKindInfo::from).collect();
|
||||
let mut dep_kinds = Vec::new();
|
||||
|
||||
let targets = package_map[&dep_id].targets();
|
||||
|
||||
// Try to get the extern name for lib, or crate name for bins.
|
||||
let extern_name = |target| {
|
||||
resolve
|
||||
.extern_crate_name_and_dep_name(pkg_id, dep_id, target)
|
||||
.map(|(ext_crate_name, _)| ext_crate_name)
|
||||
.ok()
|
||||
};
|
||||
|
||||
let lib_target_name = targets.iter().find(|t| t.is_lib()).map(extern_name);
|
||||
|
||||
for dep in deps.iter() {
|
||||
let mut include_lib = || {
|
||||
dep_kinds.push(DepKindInfo {
|
||||
kind: dep.kind(),
|
||||
target: dep.platform().cloned(),
|
||||
artifact: None,
|
||||
extern_name: lib_target_name,
|
||||
compile_target: None,
|
||||
bin_name: None,
|
||||
});
|
||||
};
|
||||
|
||||
// When we do have a library target, include them in deps if...
|
||||
match (dep.artifact(), lib_target_name) {
|
||||
// it is also an artifact dep with `{ …, lib = true }`
|
||||
(Some(a), Some(_)) if a.is_lib() => include_lib(),
|
||||
// it is not an artifact dep at all
|
||||
(None, Some(_)) => include_lib(),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// No need to proceed if there is no artifact dependency.
|
||||
let Some(artifact_requirements) = dep.artifact() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let compile_target = match artifact_requirements.target() {
|
||||
Some(t) => t
|
||||
.to_compile_target()
|
||||
.map(|t| t.rustc_target())
|
||||
// Given that Cargo doesn't know which target it should resolve to,
|
||||
// when an artifact dep is specified with { target = "target" },
|
||||
// keep it with a special "<target>" string,
|
||||
.or_else(|| Some(InternedString::new("<target>"))),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut extend = |kind: &ArtifactKind, filter: &dyn Fn(&&Target) -> bool| {
|
||||
let iter = targets.iter().filter(filter).map(|target| DepKindInfo {
|
||||
kind: dep.kind(),
|
||||
target: dep.platform().cloned(),
|
||||
artifact: Some(kind.crate_type()),
|
||||
extern_name: extern_name(target),
|
||||
compile_target,
|
||||
bin_name: target.is_bin().then(|| target.name().to_string()),
|
||||
});
|
||||
dep_kinds.extend(iter);
|
||||
};
|
||||
|
||||
for kind in artifact_requirements.kinds() {
|
||||
match kind {
|
||||
ArtifactKind::Cdylib => extend(kind, &|t| t.is_cdylib()),
|
||||
ArtifactKind::Staticlib => extend(kind, &|t| t.is_staticlib()),
|
||||
ArtifactKind::AllBinaries => extend(kind, &|t| t.is_bin()),
|
||||
ArtifactKind::SelectedBinary(bin_name) => {
|
||||
extend(kind, &|t| t.is_bin() && t.name() == bin_name.as_str())
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
dep_kinds.sort();
|
||||
package_map
|
||||
.get(&dep_id)
|
||||
.and_then(|pkg| pkg.targets().iter().find(|t| t.is_lib()))
|
||||
.and_then(|lib_target| {
|
||||
resolve
|
||||
.extern_crate_name_and_dep_name(pkg_id, dep_id, lib_target)
|
||||
.map(|(ext_crate_name, _)| ext_crate_name)
|
||||
.ok()
|
||||
})
|
||||
.map(|name| Dep {
|
||||
|
||||
let pkg = normalize_id(dep_id);
|
||||
|
||||
match (lib_target_name, dep_kinds.len()) {
|
||||
(Some(name), _) => Some(Dep {
|
||||
name,
|
||||
pkg: normalize_id(dep_id),
|
||||
pkg,
|
||||
dep_kinds,
|
||||
})
|
||||
}),
|
||||
// No lib target exists but contains artifact deps.
|
||||
(None, 1..) => Some(Dep {
|
||||
name: InternedString::new(""),
|
||||
pkg,
|
||||
dep_kinds,
|
||||
}),
|
||||
// No lib or artifact dep exists.
|
||||
// Ususally this mean parent depending on non-lib bin crate.
|
||||
(None, _) => None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let dumb_deps: Vec<PackageId> = deps.iter().map(|dep| normalize_id(dep.pkg)).collect();
|
||||
|
@ -3393,6 +3393,7 @@ fn metadata_master_consistency() {
|
||||
"pkg": "bar 1.0.0 (__BAR_SOURCE__#__BAR_HASH__)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "bar",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
|
@ -526,6 +526,7 @@ fn cargo_metadata_with_deps_and_version() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "baz",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -552,6 +553,7 @@ fn cargo_metadata_with_deps_and_version() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "bar",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -562,6 +564,7 @@ fn cargo_metadata_with_deps_and_version() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "foobar",
|
||||
"kind": "dev",
|
||||
"target": null
|
||||
}
|
||||
@ -1617,20 +1620,57 @@ fn workspace_metadata_with_dependencies_and_resolve() {
|
||||
{
|
||||
"dependencies": [
|
||||
"artifact 0.5.0 (path+file://[..]/foo/artifact)",
|
||||
"bin-only-artifact 0.5.0 (path+file://[..]/foo/bin-only-artifact)",
|
||||
"non-artifact 0.5.0 (path+file://[..]/foo/non-artifact)"
|
||||
],
|
||||
"deps": [
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "artifact",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "baz-name",
|
||||
"compile_target": "wasm32-unknown-unknown",
|
||||
"extern_name": "baz_name",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "cdylib",
|
||||
"compile_target": "wasm32-unknown-unknown",
|
||||
"extern_name": "artifact",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "staticlib",
|
||||
"compile_target": "wasm32-unknown-unknown",
|
||||
"extern_name": "artifact",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"extern_name": "artifact",
|
||||
"kind": "dev",
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "bar-name",
|
||||
"compile_target": "<target>",
|
||||
"extern_name": "bar_name",
|
||||
"kind": "build",
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "baz-name",
|
||||
"compile_target": "<target>",
|
||||
"extern_name": "baz_name",
|
||||
"kind": "build",
|
||||
"target": null
|
||||
}
|
||||
@ -1641,14 +1681,53 @@ fn workspace_metadata_with_dependencies_and_resolve() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "a-name",
|
||||
"extern_name": "a_name",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "b-name",
|
||||
"extern_name": "b_name",
|
||||
"kind": "dev",
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "a-name",
|
||||
"compile_target": "wasm32-unknown-unknown",
|
||||
"extern_name": "a_name",
|
||||
"kind": "build",
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"artifact": "bin",
|
||||
"bin_name": "b-name",
|
||||
"compile_target": "wasm32-unknown-unknown",
|
||||
"extern_name": "b_name",
|
||||
"kind": "build",
|
||||
"target": null
|
||||
}
|
||||
],
|
||||
"name": "",
|
||||
"pkg": "bin-only-artifact 0.5.0 (path+file://[..]/foo/bin-only-artifact)"
|
||||
},
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "non_artifact",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"extern_name": "non_artifact",
|
||||
"kind": "dev",
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"extern_name": "non_artifact",
|
||||
"kind": "build",
|
||||
"target": null
|
||||
}
|
||||
@ -2625,6 +2704,7 @@ fn rename_dependency() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "bar",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -2635,6 +2715,7 @@ fn rename_dependency() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "baz",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -3251,6 +3332,7 @@ fn filter_platform() {
|
||||
"pkg": "alt-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "alt_dep",
|
||||
"kind": null,
|
||||
"target": "$ALT_TRIPLE"
|
||||
}
|
||||
@ -3261,6 +3343,7 @@ fn filter_platform() {
|
||||
"pkg": "cfg-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "cfg_dep",
|
||||
"kind": null,
|
||||
"target": "cfg(foobar)"
|
||||
}
|
||||
@ -3271,6 +3354,7 @@ fn filter_platform() {
|
||||
"pkg": "host-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "host_dep",
|
||||
"kind": null,
|
||||
"target": "$HOST_TRIPLE"
|
||||
}
|
||||
@ -3281,6 +3365,7 @@ fn filter_platform() {
|
||||
"pkg": "normal-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "normal_dep",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -3362,6 +3447,7 @@ fn filter_platform() {
|
||||
"pkg": "alt-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "alt_dep",
|
||||
"kind": null,
|
||||
"target": "$ALT_TRIPLE"
|
||||
}
|
||||
@ -3372,6 +3458,7 @@ fn filter_platform() {
|
||||
"pkg": "normal-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "normal_dep",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -3437,6 +3524,7 @@ fn filter_platform() {
|
||||
"pkg": "host-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "host_dep",
|
||||
"kind": null,
|
||||
"target": "$HOST_TRIPLE"
|
||||
}
|
||||
@ -3447,6 +3535,7 @@ fn filter_platform() {
|
||||
"pkg": "normal-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "normal_dep",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -3528,6 +3617,7 @@ fn filter_platform() {
|
||||
"pkg": "cfg-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "cfg_dep",
|
||||
"kind": null,
|
||||
"target": "cfg(foobar)"
|
||||
}
|
||||
@ -3538,6 +3628,7 @@ fn filter_platform() {
|
||||
"pkg": "host-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "host_dep",
|
||||
"kind": null,
|
||||
"target": "$HOST_TRIPLE"
|
||||
}
|
||||
@ -3548,6 +3639,7 @@ fn filter_platform() {
|
||||
"pkg": "normal-dep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "normal_dep",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -3645,14 +3737,17 @@ fn dep_kinds() {
|
||||
"pkg": "bar 0.1.0 [..]",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "bar",
|
||||
"kind": null,
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"extern_name": "bar",
|
||||
"kind": "dev",
|
||||
"target": null
|
||||
},
|
||||
{
|
||||
"extern_name": "bar",
|
||||
"kind": "build",
|
||||
"target": null
|
||||
}
|
||||
@ -3663,6 +3758,7 @@ fn dep_kinds() {
|
||||
"pkg": "winapi 0.1.0 [..]",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "winapi",
|
||||
"kind": null,
|
||||
"target": "cfg(windows)"
|
||||
}
|
||||
@ -3753,6 +3849,7 @@ fn dep_kinds_workspace() {
|
||||
"pkg": "foo 0.1.0 (path+file://[..]/foo)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "foo",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
@ -3778,6 +3875,7 @@ fn dep_kinds_workspace() {
|
||||
"pkg": "dep 0.5.0 (path+file://[..]/foo/dep)",
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "dep",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
|
@ -608,6 +608,7 @@ fn update_precise_first_run() {
|
||||
{
|
||||
"dep_kinds": [
|
||||
{
|
||||
"extern_name": "serde",
|
||||
"kind": null,
|
||||
"target": null
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user