environment-variables.md book/src/03-04-environment-variables.md
external-tools.md book/src/03-09-external-tools.md
faq.md book/src/faq.md
-guide.md
+guide.md book/src/guide.md
index.md
manifest.md
pkgid-spec.md
* 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.
+* Invokes `rustc` or another build tool with the correct parameters to build
+ your project.
* Introduces conventions to make working with Rust projects easier.
Hello, world!
```
-We can also use `cargo run` to compile and then run it, all in one step (you
+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):
Hello, world!
```
-You'll notice several new files and directories have been created:
-```shell
-$ tree .
-.
-├── Cargo.lock
-├── Cargo.toml
-├── src
-│ └── main.rs
-└── target
- └── debug
- ├── build
- ├── deps
- │ └── hello_world-2386c2fd0156916f
- ├── examples
- ├── hello_world
- ├── hello_world.d
- ├── incremental
- └── native
-
-8 directories, 6 files
-```
+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.
-The `Cargo.lock` file contains information about our dependencies. Since we
-don’t have any yet, it’s not very interesting. The `target` directory contains
-all the build products, and, as can be seen, Cargo produces debug builds by
-default. You can use `cargo build --release` to compile your files with
-optimizations turned on:
+Once you’re ready for release, you can use `cargo build --release` to compile
+your files with optimizations turned on:
```shell
$ cargo build --release
Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
```
-`cargo build --release` puts the resulting binary in `target/release`
-instead of `target/debug`.
+`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
+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.
└── some-integration-tests.rs
```
-* `Cargo.toml` and `Cargo.lock` are stored in the root of your project.
+* `Cargo.toml` and `Cargo.lock` are stored in the root of your project (*package
+ root*).
* 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).
+* Integration tests go in the `tests` directory (unit tests go in each file
+ they're testing).
* Examples go in the `examples` directory.
* Benchmarks go in the `benches` directory.
`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.
+* `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
--- /dev/null
+## 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](03-07-pkgid-spec.html) and `rand` is just a short
+specification.
+++ /dev/null
-## 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:
-
-```shell
-$ cargo test
- Compiling rand v0.1.0 (https://github.com/rust-lang-nursery/rand.git#9f35b8e)
- Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
- Running target/test/hello_world-9c2b65bbb79eabce
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-```
-
-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:
-
-```shell
-$ cargo test foo
-```
-
-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
+++ /dev/null
-## Continuous integration
-
-### 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.
--- /dev/null
+## 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:
+
+```shell
+$ cargo test
+ Compiling rand v0.1.0 (https://github.com/rust-lang-nursery/rand.git#9f35b8e)
+ Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
+ Running target/test/hello_world-9c2b65bbb79eabce
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
+```
+
+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:
+
+```shell
+$ cargo test foo
+```
+
+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
--- /dev/null
+## Continuous integration
+
+### Travis CI
+
+To test your project on Travis CI, here is a sample `.travis.yml` file:
+
+```yaml
+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.
* [Working on an existing Cargo project](02-03-working-on-an-existing-project.html)
* [Dependencies](02-04-dependencies.html)
* [Project layout](02-05-project-layout.html)
-* [Tests](02-06-tests.html)
-* [Continuous Integration](02-07-continuous-integration.html)
+* [Cargo.toml vs Cargo.lock](02-06-cargo-toml-vs-cargo-lock.html)
+* [Tests](02-07-tests.html)
+* [Continuous Integration](02-08-continuous-integration.html)
### Further reading
-Now that you have an overview of how to use cargo and have created your first crate,
-you may be interested in:
+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](03-06-crates-io.html)
* [Reading about all the possible ways of specifying dependencies](03-01-specifying-dependencies.html)
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>
+```shell
+$ cargo build
+ Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
+```
And then run it:
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>
+```shell
+$ cargo run
+ Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
+ Running `target/debug/hello_world`
+Hello, world!
+```
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>
+```shell
+$ cargo build --release
+ Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
+```
-`cargo build --release` puts the resulting binary in
-`target/release` instead of `target/debug`.
+`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
First, get the project from somewhere. In this example, we’ll use `rand`
cloned from its repository on GitHub:
-```sh
+```shell
$ 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>
+```shell
+$ cargo build
+ Compiling rand v0.1.0 (file:///path/to/project/rand)
+```
This will fetch all of the dependencies and then build them, along with the
project.
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>
+```shell
+$ cargo build
+ Updating registry `https://github.com/rust-lang/crates.io-index`
+ Downloading memchr v0.1.5
+ Downloading libc v0.1.10
+ Downloading regex-syntax v0.2.1
+ Downloading memchr v0.1.5
+ Downloading aho-corasick v0.3.0
+ Downloading regex v0.1.41
+ Compiling memchr v0.1.5
+ Compiling libc v0.1.10
+ Compiling regex-syntax v0.2.1
+ Compiling memchr v0.1.5
+ Compiling aho-corasick v0.3.0
+ Compiling regex v0.1.41
+ Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
+```
Our `Cargo.lock` contains the exact information about which revision of all of
these dependencies we used.
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>
-
+```shell
+$ cargo run
+ Running `target/hello_world`
+Did our date match? true
+```
# Project layout
Cargo uses conventions for file placement to make it easy to dive into a new
```shell
$ cargo update # updates all dependencies
-$ cargo update -p rand # updates just “rand”
+$ cargo update -p rand # updates just “rand”
```
This will write out a new `Cargo.lock` with the new version information. Note
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
+```shell
+$ cargo test
+ Compiling rand v0.1.0 (https://github.com/rust-lang-nursery/rand.git#9f35b8e)
+ Compiling hello_world v0.1.0 (file:///path/to/project/hello_world)
+ Running target/test/hello_world-9c2b65bbb79eabce
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
-</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>
+```shell
+$ cargo test foo
+```
This will run any test with `foo` in its name.
To test your project on Travis CI, here is a sample `.travis.yml` file:
-```
+```yaml
language: rust
rust:
- stable