Description
Problem
I am working on some features for rules_rust
(bazel build rules for rust) and we depend on cargo tree
to help with per feature target resolution
See:
cargo metadata
doesn't indicate that feature-enabled transitive platform-specific deps are platform-specific #9863- crate_universe support for
resolver = "2"
target-specific features bazelbuild/rules_rust#1662
The problem is cargo tree's output sometimes is very hard to read. For example:
troy@scuf ➜ cargo-tree git:(main) ✗ cargo tree --target aarch64-pc-windows-msvc
a v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/a)
└── b v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/b)
└── c v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/c)
└── windows-sys v0.60.2
└── windows-targets v0.53.2
└── windows_aarch64_msvc v0.53.0
[build-dependencies]
└── b v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/b)
└── c v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/c)
└── libc v0.2.174
b v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/b) (*)
b v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/b) (*)
c v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/c) (*)
c v0.1.0 (/home/troy/github/scuffle/cargo-tree/crates/c) (*)
troy@scuf ➜ cargo-tree git:(main) ✗
If we have a dependency which appears in both the build
or underneath a proc-macro
it will be repeated and it becomes unclear which (*)
the star is referring to (the host version or the target version).
This isnt a problem in the above case because it happens that cargo-tree rendered a
and its sub dependencies before rendering b
and c
however if that isnt the case it sometimes can render b
before a
in which case we would render 2 copies of b
and be unsure which target it is for.
Proposed Solution
I think cargo tree should also have a {cfg}
format option which outputs the {cfg}
flags for a given dependency to be included. This would simply the output and show something like the following when expanding.
troy@scuf ➜ cargo-tree git:(main) ✗ cargo tree --target aarch64-pc-windows-msvc --format ';{p};{cfg};'
;a v0.1.0;aarch64-pc-windows-msvc; (/home/troy/github/scuffle/cargo-tree/crates/a)
└── ;b v0.1.0;aarch64-pc-windows-msvc; (/home/troy/github/scuffle/cargo-tree/crates/b)
└── ;c v0.1.0;aarch64-pc-windows-msvc; (/home/troy/github/scuffle/cargo-tree/crates/c)
└── ;windows-sys;'cfg(windows)'; v0.60.2
└── windows-targets v0.53.2
└── windows_aarch64_msvc v0.53.0
[build-dependencies]
└── ;b v0.1.0;x86_64-unknown-linux-gnu; (/home/troy/github/scuffle/cargo-tree/crates/b)
└── ;c v0.1.0;x86_64-unknown-linux-gnu; (/home/troy/github/scuffle/cargo-tree/crates/c)
└── ;libc v0.2.174;'cfg(unix)';
;b v0.1.0;x86_64-unknown-linux-gnu; (/home/troy/github/scuffle/cargo-tree/crates/b) (*)
;b v0.1.0;aarch64-pc-windows-msvc; (/home/troy/github/scuffle/cargo-tree/crates/b) (*)
;c v0.1.0;x86_64-unknown-linux-gnu; (/home/troy/github/scuffle/cargo-tree/crates/c) (*)
;c v0.1.0;aarch64-pc-windows-msvc; (/home/troy/github/scuffle/cargo-tree/crates/c) (*)
troy@scuf ➜ cargo-tree git:(main) ✗
Notes
# Cargo.toml
[workspace]
members = [
"crates/a",
"crates/b",
"crates/c",
]
resolver = "3"
# crates/a/Cargo.toml
[package]
name = "a"
version = "0.1.0"
edition = "2024"
[dependencies]
b = { path = "../b" }
[build-dependencies]
b = { path = "../b" }
# crates/b/Cargo.toml
[package]
name = "b"
version = "0.1.0"
edition = "2024"
[dependencies]
c = { path = "../c" }
# crates/c/Cargo.toml
[package]
name = "c"
version = "0.1.0"
edition = "2024"
[dependencies]
[target.'cfg(windows)'.dependencies]
windows-sys = "0.60"
[target.'cfg(unix)'.dependencies]
libc = "0.2"