Reputation: 23
I'm learning rust. As part of the guessing game tutorial, I downloaded the rand crate. I am concerned about dependency confusion, and do not wish to download any more packages than absolutely necessary.
Therefore, I set my Cargo.toml
to:
[dependencies]
rand = "=0.5.5"
However, I noticed that 3 different versions of rand_core were downloaded, as well as libc.
Updating crates.io index
Downloaded rand_core v0.3.1
Downloaded rand_core v0.4.2
Downloaded rand v0.5.5
Downloaded rand_core v0.2.2
Downloaded libc v0.2.87
Downloaded 5 crates (702.2 KB) in 1.17s
Compiling libc v0.2.87
Compiling rand_core v0.4.2
Compiling rand_core v0.3.1
Compiling rand_core v0.2.2
Compiling rand v0.5.5
Compiling guessing_game v0.1.0 (/home/user/projects/learn-rust/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 26.19s
Running `target/debug/guessing_game`
I went to the dependencies page for rand 0.5.5 on crates.io, and found that:
However, no required dependency on libc anywhere.
Why am I downloading libc?
Upvotes: 2
Views: 500
Reputation: 60517
You can use cargo tree -i <CRATE>
to see what is depending on a particular crate:
$ cargo tree -i libc
libc v0.2.87
└── rand v0.5.5
└── guessing_game v0.1.0 (...)
So it is rand
. The dependencies page for rand 0.5.5 indeed says that rand_core
is the only required crate, but libc
is listed as optional. That means that it is gated by a feature.
You can look at the output of cargo tree -i libc -e features
to see the features that are enabled, but its not exactly straightforward since it shows all the features enabled in the rand
crate, not just the ones that enable libc
.
The only sure-fire way to know is to look at the crate's Cargo.toml
:
[features]
default = ["std"]
nightly = ["i128_support"]
std = ["rand_core/std", "alloc", "libc", "winapi", "cloudabi", "fuchsia-zircon"]
alloc = ["rand_core/alloc"]
i128_support = []
serde1 = ["serde", "serde_derive", "rand_core/serde1"]
[dependencies]
rand_core = { path = "rand_core", version = "0.2", default-features = false }
log = { version = "0.4", optional = true }
serde = { version = "1", optional = true }
serde_derive = { version = "1", optional = true }
[target.'cfg(unix)'.dependencies]
libc = { version = "0.2", optional = true }
So libc
is both feature- and target-gated. Its only a dependency on unix
platforms, and its only used if the "std"
feature is enabled, which it is by "default"
. You can specify default-features = false
to opt out of it, however be warned that it will end up disabling most of the crate.
Upvotes: 5