cargo 0.14.0

Cargo, a package manager for Rust.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
% Cargo Guide

Welcome to the Cargo guide. This guide will give you all that you need to know
about how to use Cargo to develop Rust projects.

# Why Cargo exists

Cargo is a tool that allows Rust projects to declare their various
dependencies and ensure that you’ll always get a repeatable build.

To accomplish this goal, Cargo does four things:

* Introduces two metadata files with various bits of project information.
* Fetches and builds your project’s dependencies.
* Invokes `rustc` or another build tool with the correct parameters to build your project.
* Introduces conventions to make working with Rust projects easier.

# Creating a new project

To start a new project with Cargo, use `cargo new`:

```shell
$ cargo new hello_world --bin
```

We’re passing `--bin` because we’re making a binary program: if we
were making a library, we’d leave it off. This also initializes a new `git`
repository by default. If you don't want it to do that, pass `--vcs none`.

Let’s check out what Cargo has generated for us:

```shell
$ cd hello_world
$ tree .
.
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files
```

If we had just used `cargo new hello_world` without the `--bin` flag, then
we would have a `lib.rs` instead of a `main.rs`. For now, however, this is all
we need to get started. First, let’s check out `Cargo.toml`:

```toml
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
```

This is called a **manifest**, and it contains all of the metadata that Cargo
needs to compile your project.

Here’s what’s in `src/main.rs`:

```
fn main() {
    println!("Hello, world!");
}
```

Cargo generated a “hello world” for us. Let’s compile it:

<pre><code class="language-shell"><span class="gp">$</span> cargo build
<span style="font-weight: bold"
class="s1">   Compiling</span> hello_world v0.1.0 (file:///path/to/project/hello_world)</code></pre>

And then run it:

```shell
$ ./target/debug/hello_world
Hello, world!
```

We can also use `cargo run` to compile and then run it, all in one step (You
won't see the `Compiling` line if you have not made any changes since you last
compiled):

<pre><code class="language-shell"><span class="gp">$</span> cargo run
<span style="font-weight: bold"
class="s1">   Compiling</span> hello_world v0.1.0 (file:///path/to/project/hello_world)
<span style="font-weight: bold"
class="s1">   Running</span> `target/debug/hello_world`
Hello, world!</code></pre>

You’ll now notice a new file, `Cargo.lock`. It contains information about our
dependencies. Since we don’t have any yet, it’s not very interesting.

Once you’re ready for release, you can use `cargo build --release` to compile your files with optimizations turned on:

<pre><code class="language-shell"><span class="gp">$</span> cargo build --release
<span style="font-weight: bold"
class="s1">   Compiling</span> hello_world v0.1.0 (file:///path/to/project/hello_world)</code></pre>

`cargo build --release` puts the resulting binary in
`target/release` instead of `target/debug`.

Compiling in debug mode is the default for development-- compilation time is
shorter since the compiler doesn't do optimizations, but the code will run
slower. Release mode takes longer to compile, but the code will run faster.

# Working on an existing Cargo project

If you download an existing project that uses Cargo, it’s really easy
to get going.

First, get the project from somewhere. In this example, we’ll use `rand`
cloned from its repository on GitHub:

```sh
$ git clone https://github.com/rust-lang-nursery/rand.git
$ cd rand
```

To build, use `cargo build`:

<pre><code class="language-shell"><span class="gp">$</span> cargo build
<span style="font-weight: bold" class="s1">   Compiling</span> rand v0.1.0 (file:///path/to/project/rand)</code></pre>

This will fetch all of the dependencies and then build them, along with the
project.

# Adding dependencies from crates.io

[crates.io] is the Rust community's central repository that serves
as a location to discover and download packages. `cargo` is configured to use
it by default to find requested packages.

To depend on a library hosted on [crates.io], add it to your `Cargo.toml`.

[crates.io]: https://crates.io/

## Adding a dependency

If your `Cargo.toml` doesn't already have a `[dependencies]` section, add that,
then list the crate name and version that you would like to use. This example
adds a dependency of the `time` crate:

```toml
[dependencies]
time = "0.1.12"
```

The version string is a [semver] version requirement. The [specifying
dependencies](specifying-dependencies.html) docs have more information about
the options you have here.

[semver]: https://github.com/steveklabnik/semver#requirements

If we also wanted to add a dependency on the `regex` crate, we would not need
to add `[dependencies]` for each crate listed. Here's what your whole
`Cargo.toml` file would look like with dependencies on the `time` and `regex`
crates:

```toml
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]

[dependencies]
time = "0.1.12"
regex = "0.1.41"
```

Re-run `cargo build`, and Cargo will fetch the new dependencies and all of
their dependencies, compile them all, and update the `Cargo.lock`:

<pre><code class="language-shell"><span class="gp">$</span> cargo build
<span style="font-weight: bold" class="s1">    Updating</span> registry `https://github.com/rust-lang/crates.io-index`
<span style="font-weight: bold" class="s1"> Downloading</span> memchr v0.1.5
<span style="font-weight: bold" class="s1"> Downloading</span> libc v0.1.10
<span style="font-weight: bold" class="s1"> Downloading</span> regex-syntax v0.2.1
<span style="font-weight: bold" class="s1"> Downloading</span> memchr v0.1.5
<span style="font-weight: bold" class="s1"> Downloading</span> aho-corasick v0.3.0
<span style="font-weight: bold" class="s1"> Downloading</span> regex v0.1.41
<span style="font-weight: bold" class="s1">   Compiling</span> memchr v0.1.5
<span style="font-weight: bold" class="s1">   Compiling</span> libc v0.1.10
<span style="font-weight: bold" class="s1">   Compiling</span> regex-syntax v0.2.1
<span style="font-weight: bold" class="s1">   Compiling</span> memchr v0.1.5
<span style="font-weight: bold" class="s1">   Compiling</span> aho-corasick v0.3.0
<span style="font-weight: bold" class="s1">   Compiling</span> regex v0.1.41
<span style="font-weight: bold" class="s1">   Compiling</span> hello_world v0.1.0 (file:///path/to/project/hello_world)</code></pre>

Our `Cargo.lock` contains the exact information about which revision of all of
these dependencies we used.

Now, if `regex` gets updated, we will still build with the same revision until
we choose to `cargo update`.

You can now use the `regex` library using `extern crate` in `main.rs`.

```
extern crate regex;

use regex::Regex;

fn main() {
    let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
    println!("Did our date match? {}", re.is_match("2014-01-01"));
}
```

Running it will show:

<pre><code class="language-shell"><span class="gp">$</span> cargo run
<span style="font-weight: bold" class="s1">     Running</span> `target/hello_world`
Did our date match? true</code></pre>

# Project layout

Cargo uses conventions for file placement to make it easy to dive into a new
Cargo project:

```shell
.
├── Cargo.lock
├── Cargo.toml
├── benches
│   └── large-input.rs
├── examples
│   └── simple.rs
├── src
│   ├── bin
│   │   └── another_executable.rs
│   ├── lib.rs
│   └── main.rs
└── tests
    └── some-integration-tests.rs
```

* `Cargo.toml` and `Cargo.lock` are stored in the root of your project.
* Source code goes in the `src` directory.
* The default library file is `src/lib.rs`.
* The default executable file is `src/main.rs`.
* Other executables can be placed in `src/bin/*.rs`.
* Integration tests go in the `tests` directory (unit tests go in each file they're testing).
* Example executable files go in the `examples` directory.
* Benchmarks go in the `benches` directory.

These are explained in more detail in the [manifest
description](manifest.html#the-project-layout).

# Cargo.toml vs Cargo.lock

`Cargo.toml` and `Cargo.lock` serve two different purposes. Before we talk
about them, here’s a summary:

* `Cargo.toml` is about describing your dependencies in a broad sense, and is written by you.
* `Cargo.lock` contains exact information about your dependencies. It is maintained by Cargo and should not be manually edited.

If you’re building a library that other projects will depend on, put
`Cargo.lock` in your `.gitignore`. If you’re building an executable like a
command-line tool or an application, check `Cargo.lock` into `git`. If you're
curious about why that is, see ["Why do binaries have `Cargo.lock` in version
control, but not libraries?" in the
FAQ](faq.html#why-do-binaries-have-cargolock-in-version-control-but-not-libraries).

Let’s dig in a little bit more.

`Cargo.toml` is a **manifest** file in which we can specify a bunch of
different metadata about our project. For example, we can say that we depend
on another project:

```toml
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]

[dependencies]
rand = { git = "https://github.com/rust-lang-nursery/rand.git" }
```

This project has a single dependency, on the `rand` library. We’ve stated in
this case that we’re relying on a particular Git repository that lives on
GitHub. Since we haven’t specified any other information, Cargo assumes that
we intend to use the latest commit on the `master` branch to build our project.

Sound good? Well, there’s one problem: If you build this project today, and
then you send a copy to me, and I build this project tomorrow, something bad
could happen. There could be more commits to `rand` in the meantime, and my
build would include new commits while yours would not. Therefore, we would
get different builds. This would be bad because we want reproducible builds.

We could fix this problem by putting a `rev` line in our `Cargo.toml`:

```toml
[dependencies]
rand = { git = "https://github.com/rust-lang-nursery/rand.git", rev = "9f35b8e" }
```

Now our builds will be the same. But there’s a big drawback: now we have to
manually think about SHA-1s every time we want to update our library. This is
both tedious and error prone.

Enter the `Cargo.lock`. Because of its existence, we don’t need to manually
keep track of the exact revisions: Cargo will do it for us. When we have a
manifest like this:

```toml
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]

[dependencies]
rand = { git = "https://github.com/rust-lang-nursery/rand.git" }
```

Cargo will take the latest commit and write that information out into our
`Cargo.lock` when we build for the first time. That file will look like this:

```toml
[root]
name = "hello_world"
version = "0.1.0"
dependencies = [
 "rand 0.1.0 (git+https://github.com/rust-lang-nursery/rand.git#9f35b8e439eeedd60b9414c58f389bdc6a3284f9)",
]

[[package]]
name = "rand"
version = "0.1.0"
source = "git+https://github.com/rust-lang-nursery/rand.git#9f35b8e439eeedd60b9414c58f389bdc6a3284f9"

```

You can see that there’s a lot more information here, including the exact
revision we used to build. Now when you give your project to someone else,
they’ll use the exact same SHA, even though we didn’t specify it in our
`Cargo.toml`.

When we’re ready to opt in to a new version of the library, Cargo can
re-calculate the dependencies and update things for us:

```shell
$ cargo update           # updates all dependencies
$ cargo update -p rand  # updates just “rand”
```

This will write out a new `Cargo.lock` with the new version information. Note
that the argument to `cargo update` is actually a
[Package ID Specification](pkgid-spec.html) and `rand` is just a short
specification.

# Tests

Cargo can run your tests with the `cargo test` command. Cargo looks for tests
to run in two places: in each of your `src` files and any tests in `tests/`.
Tests in your `src` files should be unit tests, and tests in `tests/` should be
integration-style tests. As such, you’ll need to import your crates into
the files in `tests`.

Here's an example of running `cargo test` in our project, which currently has
no tests:

<pre><code class="language-shell"><span class="gp">$</span> cargo test
<span style="font-weight: bold"
class="s1">   Compiling</span> rand v0.1.0 (https://github.com/rust-lang-nursery/rand.git#9f35b8e)
<span style="font-weight: bold"
class="s1">   Compiling</span> hello_world v0.1.0 (file:///path/to/project/hello_world)
<span style="font-weight: bold"
class="s1">     Running</span> target/test/hello_world-9c2b65bbb79eabce

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
</code></pre>

If our project had tests, we would see more output with the correct number of
tests.

You can also run a specific test by passing a filter:

<pre><code class="language-shell"><span class="gp">$</span> cargo test foo
</code></pre>

This will run any test with `foo` in its name.

`cargo test` runs additional checks as well. For example, it will compile any
examples you’ve included and will also test the examples in your
documentation. Please see the [testing guide][testing] in the Rust
documentation for more details.

[testing]: https://doc.rust-lang.org/book/testing.html

## Travis CI

To test your project on Travis CI, here is a sample `.travis.yml` file:

```
language: rust
rust:
  - stable
  - beta
  - nightly
matrix:
  allow_failures:
    - rust: nightly
```

This will test all three release channels, but any breakage in nightly
will not fail your overall build. Please see the [Travis CI Rust
documentation](https://docs.travis-ci.com/user/languages/rust/) for more
information.

# Further reading

Now that you have an overview of how to use cargo and have created your first crate, you may be interested in:

* [Publishing your crate on crates.io](crates-io.html)
* [Reading about all the possible ways of specifying dependencies](specifying-dependencies.html)
* [Learning more details about what you can specify in your `Cargo.toml` manifest](manifest.html)

Even more topics are available in the Docs menu at the top!