1## Specifying Dependencies 2 3Your crates can depend on other libraries from [crates.io] or other 4registries, `git` repositories, or subdirectories on your local file system. 5You can also temporarily override the location of a dependency — for example, 6to be able to test out a bug fix in the dependency that you are working on 7locally. You can have different dependencies for different platforms, and 8dependencies that are only used during development. Let's take a look at how 9to do each of these. 10 11### Specifying dependencies from crates.io 12 13Cargo is configured to look for dependencies on [crates.io] by default. Only 14the name and a version string are required in this case. In [the cargo 15guide](../guide/index.md), we specified a dependency on the `time` crate: 16 17```toml 18[dependencies] 19time = "0.1.12" 20``` 21 22The string `"0.1.12"` is a [semver] version requirement. Since this 23string does not have any operators in it, it is interpreted the same way as 24if we had specified `"^0.1.12"`, which is called a caret requirement. 25 26[semver]: https://github.com/steveklabnik/semver#requirements 27 28### Caret requirements 29 30**Caret requirements** allow SemVer compatible updates to a specified version. 31An update is allowed if the new version number does not modify the left-most 32non-zero digit in the major, minor, patch grouping. In this case, if we ran 33`cargo update -p time`, cargo should update us to version `0.1.13` if it is the 34latest `0.1.z` release, but would not update us to `0.2.0`. If instead we had 35specified the version string as `^1.0`, cargo should update to `1.1` if it is 36the latest `1.y` release, but not `2.0`. The version `0.0.x` is not considered 37compatible with any other version. 38 39Here are some more examples of caret requirements and the versions that would 40be allowed with them: 41 42```notrust 43^1.2.3 := >=1.2.3, <2.0.0 44^1.2 := >=1.2.0, <2.0.0 45^1 := >=1.0.0, <2.0.0 46^0.2.3 := >=0.2.3, <0.3.0 47^0.2 := >=0.2.0, <0.3.0 48^0.0.3 := >=0.0.3, <0.0.4 49^0.0 := >=0.0.0, <0.1.0 50^0 := >=0.0.0, <1.0.0 51``` 52 53This compatibility convention is different from SemVer in the way it treats 54versions before 1.0.0. While SemVer says there is no compatibility before 551.0.0, Cargo considers `0.x.y` to be compatible with `0.x.z`, where `y ≥ z` 56and `x > 0`. 57 58### Tilde requirements 59 60**Tilde requirements** specify a minimal version with some ability to update. 61If you specify a major, minor, and patch version or only a major and minor 62version, only patch-level changes are allowed. If you only specify a major 63version, then minor- and patch-level changes are allowed. 64 65`~1.2.3` is an example of a tilde requirement. 66 67```notrust 68~1.2.3 := >=1.2.3, <1.3.0 69~1.2 := >=1.2.0, <1.3.0 70~1 := >=1.0.0, <2.0.0 71``` 72 73### Wildcard requirements 74 75**Wildcard requirements** allow for any version where the wildcard is 76positioned. 77 78`*`, `1.*` and `1.2.*` are examples of wildcard requirements. 79 80```notrust 81* := >=0.0.0 821.* := >=1.0.0, <2.0.0 831.2.* := >=1.2.0, <1.3.0 84``` 85 86> **Note**: [crates.io] does not allow bare `*` versions. 87 88### Comparison requirements 89 90**Comparison requirements** allow manually specifying a version range or an 91exact version to depend on. 92 93Here are some examples of comparison requirements: 94 95```notrust 96>= 1.2.0 97> 1 98< 2 99= 1.2.3 100``` 101 102### Multiple requirements 103 104As shown in the examples above, multiple version requirements can be 105separated with a comma, e.g., `>= 1.2, < 1.5`. 106 107### Specifying dependencies from other registries 108 109To specify a dependency from a registry other than [crates.io], first the 110registry must be configured in a `.cargo/config.toml` file. See the [registries 111documentation] for more information. In the dependency, set the `registry` key 112to the name of the registry to use. 113 114```toml 115[dependencies] 116some-crate = { version = "1.0", registry = "my-registry" } 117``` 118 119> **Note**: [crates.io] does not allow packages to be published with 120> dependencies on other registries. 121 122[registries documentation]: registries.md 123 124### Specifying dependencies from `git` repositories 125 126To depend on a library located in a `git` repository, the minimum information 127you need to specify is the location of the repository with the `git` key: 128 129```toml 130[dependencies] 131regex = { git = "https://github.com/rust-lang/regex" } 132``` 133 134Cargo will fetch the `git` repository at this location then look for a 135`Cargo.toml` for the requested crate anywhere inside the `git` repository 136(not necessarily at the root - for example, specifying a member crate name 137of a workspace and setting `git` to the repository containing the workspace). 138 139Since we haven’t specified any other information, Cargo assumes that 140we intend to use the latest commit on the main branch to build our package. 141You can combine the `git` key with the `rev`, `tag`, or `branch` keys to 142specify something else. Here's an example of specifying that you want to use 143the latest commit on a branch named `next`: 144 145```toml 146[dependencies] 147regex = { git = "https://github.com/rust-lang/regex", branch = "next" } 148``` 149 150Anything that is not a branch or tag falls under `rev`. This can be a commit 151hash like `rev = "4c59b707"`, or a named reference exposed by the remote 152repository such as `rev = "refs/pull/493/head"`. What references are available 153varies by where the repo is hosted; GitHub in particular exposes a reference to 154the most recent commit of every pull request as shown, but other git hosts often 155provide something equivalent, possibly under a different naming scheme. 156 157Once a `git` dependency has been added, Cargo will lock that dependency to the 158latest commit at the time. New commits will not be pulled down automatically 159once the lock is in place. However, they can be pulled down manually with 160`cargo update`. 161 162See [Git Authentication] for help with git authentication for private repos. 163 164> **Note**: [crates.io] does not allow packages to be published with `git` 165> dependencies (`git` [dev-dependencies] are ignored). See the [Multiple 166> locations](#multiple-locations) section for a fallback alternative. 167 168[Git Authentication]: ../appendix/git-authentication.md 169 170### Specifying path dependencies 171 172Over time, our `hello_world` package from [the guide](../guide/index.md) has 173grown significantly in size! It’s gotten to the point that we probably want to 174split out a separate crate for others to use. To do this Cargo supports **path 175dependencies** which are typically sub-crates that live within one repository. 176Let’s start off by making a new crate inside of our `hello_world` package: 177 178```console 179# inside of hello_world/ 180$ cargo new hello_utils 181``` 182 183This will create a new folder `hello_utils` inside of which a `Cargo.toml` and 184`src` folder are ready to be configured. In order to tell Cargo about this, open 185up `hello_world/Cargo.toml` and add `hello_utils` to your dependencies: 186 187```toml 188[dependencies] 189hello_utils = { path = "hello_utils" } 190``` 191 192This tells Cargo that we depend on a crate called `hello_utils` which is found 193in the `hello_utils` folder (relative to the `Cargo.toml` it’s written in). 194 195And that’s it! The next `cargo build` will automatically build `hello_utils` and 196all of its own dependencies, and others can also start using the crate as well. 197However, crates that use dependencies specified with only a path are not 198permitted on [crates.io]. If we wanted to publish our `hello_world` crate, we 199would need to publish a version of `hello_utils` to [crates.io] 200and specify its version in the dependencies line as well: 201 202```toml 203[dependencies] 204hello_utils = { path = "hello_utils", version = "0.1.0" } 205``` 206 207> **Note**: [crates.io] does not allow packages to be published with `path` 208> dependencies (`path` [dev-dependencies] are ignored). See the [Multiple 209> locations](#multiple-locations) section for a fallback alternative. 210 211### Multiple locations 212 213It is possible to specify both a registry version and a `git` or `path` 214location. The `git` or `path` dependency will be used locally (in which case 215the `version` is checked against the local copy), and when published to a 216registry like [crates.io], it will use the registry version. Other 217combinations are not allowed. Examples: 218 219```toml 220[dependencies] 221# Uses `my-bitflags` when used locally, and uses 222# version 1.0 from crates.io when published. 223bitflags = { path = "my-bitflags", version = "1.0" } 224 225# Uses the given git repo when used locally, and uses 226# version 1.0 from crates.io when published. 227smallvec = { git = "https://github.com/servo/rust-smallvec", version = "1.0" } 228 229# N.B. that if a version doesn't match, Cargo will fail to compile! 230``` 231 232One example where this can be useful is when you have split up a library into 233multiple packages within the same workspace. You can then use `path` 234dependencies to point to the local packages within the workspace to use the 235local version during development, and then use the [crates.io] version once it 236is published. This is similar to specifying an 237[override](overriding-dependencies.md), but only applies to this one 238dependency declaration. 239 240### Platform specific dependencies 241 242Platform-specific dependencies take the same format, but are listed under a 243`target` section. Normally Rust-like [`#[cfg]` 244syntax](../../reference/conditional-compilation.html) will be used to define 245these sections: 246 247```toml 248[target.'cfg(windows)'.dependencies] 249winhttp = "0.4.0" 250 251[target.'cfg(unix)'.dependencies] 252openssl = "1.0.1" 253 254[target.'cfg(target_arch = "x86")'.dependencies] 255native = { path = "native/i686" } 256 257[target.'cfg(target_arch = "x86_64")'.dependencies] 258native = { path = "native/x86_64" } 259``` 260 261Like with Rust, the syntax here supports the `not`, `any`, and `all` operators 262to combine various cfg name/value pairs. 263 264If you want to know which cfg targets are available on your platform, run 265`rustc --print=cfg` from the command line. If you want to know which `cfg` 266targets are available for another platform, such as 64-bit Windows, 267run `rustc --print=cfg --target=x86_64-pc-windows-msvc`. 268 269Unlike in your Rust source code, you cannot use 270`[target.'cfg(feature = "fancy-feature")'.dependencies]` to add dependencies 271based on optional features. Use [the `[features]` section](features.md) 272instead: 273 274```toml 275[dependencies] 276foo = { version = "1.0", optional = true } 277bar = { version = "1.0", optional = true } 278 279[features] 280fancy-feature = ["foo", "bar"] 281``` 282 283The same applies to `cfg(debug_assertions)`, `cfg(test)` and `cfg(proc_macro)`. 284These values will not work as expected and will always have the default value 285returned by `rustc --print=cfg`. 286There is currently no way to add dependencies based on these configuration values. 287 288In addition to `#[cfg]` syntax, Cargo also supports listing out the full target 289the dependencies would apply to: 290 291```toml 292[target.x86_64-pc-windows-gnu.dependencies] 293winhttp = "0.4.0" 294 295[target.i686-unknown-linux-gnu.dependencies] 296openssl = "1.0.1" 297``` 298 299#### Custom target specifications 300 301If you’re using a custom target specification (such as `--target 302foo/bar.json`), use the base filename without the `.json` extension: 303 304```toml 305[target.bar.dependencies] 306winhttp = "0.4.0" 307 308[target.my-special-i686-platform.dependencies] 309openssl = "1.0.1" 310native = { path = "native/i686" } 311``` 312 313> **Note**: Custom target specifications are not usable on the stable channel. 314 315### Development dependencies 316 317You can add a `[dev-dependencies]` section to your `Cargo.toml` whose format 318is equivalent to `[dependencies]`: 319 320```toml 321[dev-dependencies] 322tempdir = "0.3" 323``` 324 325Dev-dependencies are not used when compiling 326a package for building, but are used for compiling tests, examples, and 327benchmarks. 328 329These dependencies are *not* propagated to other packages which depend on this 330package. 331 332You can also have target-specific development dependencies by using 333`dev-dependencies` in the target section header instead of `dependencies`. For 334example: 335 336```toml 337[target.'cfg(unix)'.dev-dependencies] 338mio = "0.0.1" 339``` 340 341> **Note**: When a package is published, only dev-dependencies that specify a 342> `version` will be included in the published crate. For most use cases, 343> dev-dependencies are not needed when published, though some users (like OS 344> packagers) may want to run tests within a crate, so providing a `version` if 345> possible can still be beneficial. 346 347### Build dependencies 348 349You can depend on other Cargo-based crates for use in your build scripts. 350Dependencies are declared through the `build-dependencies` section of the 351manifest: 352 353```toml 354[build-dependencies] 355cc = "1.0.3" 356``` 357 358 359You can also have target-specific build dependencies by using 360`build-dependencies` in the target section header instead of `dependencies`. For 361example: 362 363```toml 364[target.'cfg(unix)'.build-dependencies] 365cc = "1.0.3" 366``` 367 368In this case, the dependency will only be built when the host platform matches the 369specified target. 370 371The build script **does not** have access to the dependencies listed 372in the `dependencies` or `dev-dependencies` section. Build 373dependencies will likewise not be available to the package itself 374unless listed under the `dependencies` section as well. A package 375itself and its build script are built separately, so their 376dependencies need not coincide. Cargo is kept simpler and cleaner by 377using independent dependencies for independent purposes. 378 379### Choosing features 380 381If a package you depend on offers conditional features, you can 382specify which to use: 383 384```toml 385[dependencies.awesome] 386version = "1.3.5" 387default-features = false # do not include the default features, and optionally 388 # cherry-pick individual features 389features = ["secure-password", "civet"] 390``` 391 392More information about features can be found in the [features 393chapter](features.md#dependency-features). 394 395### Renaming dependencies in `Cargo.toml` 396 397When writing a `[dependencies]` section in `Cargo.toml` the key you write for a 398dependency typically matches up to the name of the crate you import from in the 399code. For some projects, though, you may wish to reference the crate with a 400different name in the code regardless of how it's published on crates.io. For 401example you may wish to: 402 403* Avoid the need to `use foo as bar` in Rust source. 404* Depend on multiple versions of a crate. 405* Depend on crates with the same name from different registries. 406 407To support this Cargo supports a `package` key in the `[dependencies]` section 408of which package should be depended on: 409 410```toml 411[package] 412name = "mypackage" 413version = "0.0.1" 414 415[dependencies] 416foo = "0.1" 417bar = { git = "https://github.com/example/project", package = "foo" } 418baz = { version = "0.1", registry = "custom", package = "foo" } 419``` 420 421In this example, three crates are now available in your Rust code: 422 423```rust,ignore 424extern crate foo; // crates.io 425extern crate bar; // git repository 426extern crate baz; // registry `custom` 427``` 428 429All three of these crates have the package name of `foo` in their own 430`Cargo.toml`, so we're explicitly using the `package` key to inform Cargo that 431we want the `foo` package even though we're calling it something else locally. 432The `package` key, if not specified, defaults to the name of the dependency 433being requested. 434 435Note that if you have an optional dependency like: 436 437```toml 438[dependencies] 439bar = { version = "0.1", package = 'foo', optional = true } 440``` 441 442you're depending on the crate `foo` from crates.io, but your crate has a `bar` 443feature instead of a `foo` feature. That is, names of features take after the 444name of the dependency, not the package name, when renamed. 445 446Enabling transitive dependencies works similarly, for example we could add the 447following to the above manifest: 448 449```toml 450[features] 451log-debug = ['bar/log-debug'] # using 'foo/log-debug' would be an error! 452``` 453 454[crates.io]: https://crates.io/ 455[dev-dependencies]: #development-dependencies 456 457<script> 458(function() { 459 var fragments = { 460 "#overriding-dependencies": "overriding-dependencies.html", 461 "#testing-a-bugfix": "overriding-dependencies.html#testing-a-bugfix", 462 "#working-with-an-unpublished-minor-version": "overriding-dependencies.html#working-with-an-unpublished-minor-version", 463 "#overriding-repository-url": "overriding-dependencies.html#overriding-repository-url", 464 "#prepublishing-a-breaking-change": "overriding-dependencies.html#prepublishing-a-breaking-change", 465 "#overriding-with-local-dependencies": "overriding-dependencies.html#paths-overrides", 466 }; 467 var target = fragments[window.location.hash]; 468 if (target) { 469 var url = window.location.toString(); 470 var base = url.substring(0, url.lastIndexOf('/')); 471 window.location.replace(base + "/" + target); 472 } 473})(); 474</script> 475