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