faramirInIthilien
faramirInIthilien

Reputation: 23

Why is cargo downloading libc for the rand package?

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:

  1. rand 0.5.5 depends on
  2. rand_core ^0.2 (I downloaded 0.2.2) depends on
  3. rand_core ^0.3 (I downloaded 0.3.1) depends on
  4. rand_core ^0.4 (I downloaded 0.4.2).

However, no required dependency on libc anywhere.

Why am I downloading libc?

Upvotes: 2

Views: 500

Answers (1)

kmdreko
kmdreko

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

Related Questions