When the build script is run, there are a number of inputs to the build script,
all passed in the form of [environment variables][env].
-In addition to environment variables, the build script's current directory is
-the source directory of the build script's package.
+In addition to environment variables, the build script’s current directory is
+the source directory of the build script’s package.
[env]: environment-variables.html
```
The build script **does not** have access to the dependencies listed in the
-`dependencies` or `dev-dependencies` section (they're not built yet!). All build
+`dependencies` or `dev-dependencies` section (they’re not built yet!). All build
dependencies will also not be available to the package itself unless explicitly
stated as so.
system of passing metadata between package build scripts.
Primarily, Cargo requires that there is at most one package per `links` value.
-In other words, it's forbidden to have two packages link to the same native
+In other words, it’s forbidden to have two packages link to the same native
library. Note, however, that there are [conventions in place][star-sys] to
alleviate this.
# Case study: Code generation
Some Cargo packages need to have code generated just before they are compiled
-for various reasons. Here we'll walk through a simple example which generates a
+for various reasons. Here we’ll walk through a simple example which generates a
library call as part of the build script.
-First, let's take a look at the directory structure of this package:
+First, let’s take a look at the directory structure of this package:
```notrust
.
```
Here we can see that we have a `build.rs` build script and our binary in
-`main.rs`. Next, let's take a look at the manifest:
+`main.rs`. Next, let’s take a look at the manifest:
```toml
# Cargo.toml
build = "build.rs"
```
-Here we can see we've got a build script specified which we'll use to generate
-some code. Let's see what's inside the build script:
+Here we can see we’ve got a build script specified which we’ll use to generate
+some code. Let’s see what’s inside the build script:
```rust,no_run
// build.rs
}
```
-There's a couple of points of note here:
+There’s a couple of points of note here:
* The script uses the `OUT_DIR` environment variable to discover where the
- output files should be located. It can use the process's current working
+ output files should be located. It can use the process’ current working
directory to find where the input files should be located, but in this case we
- don't have any input files.
+ don’t have any input files.
* This script is relatively simple as it just writes out a small generated file.
One could imagine that other more fanciful operations could take place such as
generating a Rust module from a C header file or another language definition,
for example.
-Next, let's peek at the library itself:
+Next, let’s peek at the library itself:
```rust,ignore
// src/main.rs
This is where the real magic happens. The library is using the rustc-defined
`include!` macro in combination with the `concat!` and `env!` macros to include
-the generated file (`mod.rs`) into the crate's compilation.
+the generated file (`mod.rs`) into the crate’s compilation.
Using the structure shown here, crates can include any number of generated files
-from the build script itself. We've also seen a brief example of how a build
+from the build script itself. We’ve also seen a brief example of how a build
script can use a crate as a dependency purely for the build process and not for
the crate itself at runtime.
# Case study: Building some native code
-Sometimes it's necessary to build some native C or C++ code as part of a
+Sometimes it’s necessary to build some native C or C++ code as part of a
package. This is another excellent use case of leveraging the build script to
-build a native library before the Rust crate itself. As an example, we'll create
-a Rust library which calls into C to print "Hello, World!".
+build a native library before the Rust crate itself. As an example, we’ll create
+a Rust library which calls into C to print “Hello, World!”.
-Like above, let's first take a look at the project layout:
+Like above, let’s first take a look at the project layout:
```notrust
.
build = "build.rs"
```
-For now we're not going to use any build dependencies, so let's take a look at
+For now we’re not going to use any build dependencies, so let’s take a look at
the build script now:
```rust,no_run
Note that there are a number of drawbacks to this hardcoded approach:
-* The `gcc` command itself is not portable across platforms. For example it's
+* The `gcc` command itself is not portable across platforms. For example it’s
unlikely that Windows platforms have `gcc`, and not even all Unix platforms
may have `gcc`. The `ar` command is also in a similar situation.
-* These commands do not take cross-compilation into account. If we're cross
- compiling for a platform such as Android it's unlikely that `gcc` will produce
+* These commands do not take cross-compilation into account. If we’re cross
+ compiling for a platform such as Android it’s unlikely that `gcc` will produce
an ARM executable.
Not to fear, though, this is where a `build-dependencies` entry would help! The
functionality as possible out to common build dependencies rather than
duplicating logic across all build scripts!
-Back to the case study though, let's take a quick look at the contents of the
+Back to the case study though, let’s take a quick look at the contents of the
`src` directory:
```c
```rust,ignore
// src/main.rs
-// Note the lack of the `#[link]` attribute. We're delegating the responsibility
+// Note the lack of the `#[link]` attribute. We’re delegating the responsibility
// of selecting what to link to over to the build script rather than hardcoding
// it in the source file.
extern { fn hello(); }
script is again to farm out as much of this as possible to make this as easy as
possible for consumers.
-As an example to follow, let's take a look at one of [Cargo's own
+As an example to follow, let’s take a look at one of [Cargo’s own
dependencies][git2-rs], [libgit2][libgit2]. This library has a number of
constraints:
* It is often not installed on all systems by default.
* It can be built from source using `cmake`.
-To visualize what's going on here, let's take a look at the manifest for the
+To visualize what’s going on here, let’s take a look at the manifest for the
relevant Cargo package.
```toml
# ...
```
-As the above manifests show, we've got a `build` script specified, but it's
+As the above manifests show, we’ve got a `build` script specified, but it’s
worth noting that this example has a `links` entry which indicates that the
crate (`libgit2-sys`) links to the `git2` native library.
`libssh2-sys` crate, as well as a platform-specific dependency on `openssl-sys`
for unix (other variants elided for now). It may seem a little counterintuitive
to express *C dependencies* in the *Cargo manifest*, but this is actually using
-one of Cargo's conventions in this space.
+one of Cargo’s conventions in this space.
## `*-sys` Packages
## Building libgit2
-Now that we've got libgit2's dependencies sorted out, we need to actually write
-the build script. We're not going to look at specific snippets of code here and
+Now that we’ve got libgit2’s dependencies sorted out, we need to actually write
+the build script. We’re not going to look at specific snippets of code here and
instead only take a look at the high-level details of the build script of
`libgit2-sys`. This is not recommending all packages follow this strategy, but
rather just outlining one specific strategy.
The first step of the build script should do is to query whether libgit2 is
-already installed on the host system. To do this we'll leverage the preexisting
-tool `pkg-config` (when its available). We'll also use a `build-dependencies`
-section to refactor out all the `pkg-config` related code (or someone's already
+already installed on the host system. To do this we’ll leverage the preexisting
+tool `pkg-config` (when its available). We’ll also use a `build-dependencies`
+section to refactor out all the `pkg-config` related code (or someone’s already
done that!).
-If `pkg-config` failed to find libgit2, or if `pkg-config` just wasn't
+If `pkg-config` failed to find libgit2, or if `pkg-config` just wasn’t
installed, the next step is to build libgit2 from bundled source code
(distributed as part of `libgit2-sys` itself). There are a few nuances when
doing so that we need to take into account, however:
-* The build system of libgit2, `cmake`, needs to be able to find libgit2's
- optional dependency of libssh2. We're sure we've already built it (it's a
+* The build system of libgit2, `cmake`, needs to be able to find libgit2’s
+ optional dependency of libssh2. We’re sure we’ve already built it (it’s a
Cargo dependency), we just need to communicate this information. To do this
we leverage the metadata format to communicate information between build
scripts. In this example the libssh2 package printed out `cargo:root=...` to
tell us where libssh2 is installed at, and we can then pass this along to
cmake with the `CMAKE_PREFIX_PATH` environment variable.
-* We'll need to handle some `CFLAGS` values when compiling C code (and tell
+* We’ll need to handle some `CFLAGS` values when compiling C code (and tell
`cmake` about this). Some flags we may want to pass are `-m64` for 64-bit
code, `-m32` for 32-bit code, or `-fPIC` for 64-bit code as well.
-* Finally, we'll invoke `cmake` to place all output into the `OUT_DIR`
- environment variable, and then we'll print the necessary metadata to instruct
+* Finally, we’ll invoke `cmake` to place all output into the `OUT_DIR`
+ environment variable, and then we’ll print the necessary metadata to instruct
rustc how to link to libgit2.
Most of the functionality of this build script is easily refactorable into
-common dependencies, so our build script isn't quite as intimidating as this
-descriptions! In reality it's expected that build scripts are quite succinct by
+common dependencies, so our build script isn’t quite as intimidating as this
+descriptions! In reality it’s expected that build scripts are quite succinct by
farming logic such as above to build dependencies.
% Configuration - Cargo Documentation
-This document will explain how cargo's configuration system works, as well as
+This document will explain how cargo’s configuration system works, as well as
available keys or configuration. For configuration of a project through its
manifest, see the [manifest format](manifest.html).
# Configuration keys related to the registry
[registry]
index = "..." # URL of the registry index (defaults to the central repository)
-token = "..." # Access token (found on the central repo's website)
+token = "..." # Access token (found on the central repo’s website)
[http]
proxy = "..." # HTTP proxy to use for HTTP requests (defaults to none)
glob = "0.0.3"
```
-With this format, adding new dependencies should just add a new line, you don't
+With this format, adding new dependencies should just add a new line, you don’t
need to add `[dependencies]` for each dependency listed, for example:
```toml
`^1.2.3` is an example of a caret requirement.
-When considering â\80\98compatibleâ\80\99 versions, `0.1` and `0.2` are not considered
+When considering â\80\9ccompatibleâ\80\9d versions, `0.1` and `0.2` are not considered
compatible, but `1.0` and `1.1` are for example. If no operator is specified,
this is the default requirement (e.g. `1.3` is the same as `^1.3`).
# Publishing crates
-Ok, now that we've got a crate which is using dependencies from crates.io,
-let's publish it! Publishing a crate is when a specific version is uploaded to
+Ok, now that we’ve got a crate which is using dependencies from crates.io,
+let’s publish it! Publishing a crate is when a specific version is uploaded to
crates.io.
Take care when publishing a crate, because a publish is **permanent**. The
## Acquiring an API token
-First thing's first, you'll need an account on [crates.io][crates-io] to acquire
+First thing’s first, you’ll need an account on [crates.io][crates-io] to acquire
an API token. To do so, [visit the home page][crates-io] and log in via a GitHub
account (required for now). After this, visit your [Account
Settings](https://crates.io/me) page and run the `cargo login` command
## Packaging a crate
The next step is to package up your crate into a format that can be uploaded to
-crates.io. For this we'll use the `cargo package` subcommand. This will take
+crates.io. For this we’ll use the `cargo package` subcommand. This will take
our entire crate and package it all up into a `*.crate` file in the
`target/package` directory.
```
As an added bonus, the `*.crate` will be verified independently of the current
-source tree. After the `*.crate` is created, it's unpacked into
+source tree. After the `*.crate` is created, it’s unpacked into
`target/package` and then built from scratch to ensure that all necessary files
are there for the build to succeed. This behavior can be disabled with the
`--no-verify` flag.
-Now's a good time to take a look at the `*.crate` file to make sure you didn't
+Now’s a good time to take a look at the `*.crate` file to make sure you didn’t
accidentally package up that 2GB video asset. Cargo will automatically ignore
files ignored by your version control system when packaging, but if you want to
specify an extra set of files to ignore you can use the `exclude` key in the
```
The syntax of each element in this array is what
-[rust-lang/glob](https://github.com/rust-lang/glob) accepts. If you'd rather
+[rust-lang/glob](https://github.com/rust-lang/glob) accepts. If you’d rather
roll with a whitelist instead of a blacklist, Cargo also supports an `include`
key:
## Uploading the crate
-Now that we've got a `*.crate` file ready to go, it can be uploaded to
-crates.io with the `cargo publish` command. And that's it, you've now published
+Now that we’ve got a `*.crate` file ready to go, it can be uploaded to
+crates.io with the `cargo publish` command. And that’s it, you’ve now published
your first crate!
```notrust
$ cargo publish
```
-If you'd like to skip the `cargo package` step, the `cargo publish` subcommand
-will automatically package up the local crate if a copy isn't found already.
+If you’d like to skip the `cargo package` step, the `cargo publish` subcommand
+will automatically package up the local crate if a copy isn’t found already.
Be sure to check out the [metadata you can
specify](manifest.html#package-metadata) to ensure your crate can be discovered
Occasions may arise where you publish a version of a crate that actually ends up
being broken for one reason or another (syntax error, forgot to include a file,
-etc). For situations such as this, Cargo supports a "yank" of a version of a
+etc). For situations such as this, Cargo supports a “yank” of a version of a
crate.
```notrust
The owner IDs given to these commands must be GitHub user names or Github teams.
-If a user name is given to `--add`, that user becomes a "named" owner, with
+If a user name is given to `--add`, that user becomes a “named” owner, with
full rights to the crate. In addition to being able to publish or yank versions
of the crate, they have the ability to add or remove owners, *including* the
-owner that made *them* an owner. Needless to say, you shouldn't make people you
-don't fully trust into a named owner. In order to become a named owner, a user
+owner that made *them* an owner. Needless to say, you shouldn’t make people you
+don’t fully trust into a named owner. In order to become a named owner, a user
must have logged into crates.io previously.
-If a team name is given to `--add`, that team becomes a "team" owner, with
+If a team name is given to `--add`, that team becomes a “team” owner, with
restricted right to the crate. While they have permission to publish or yank
versions of the crate, they *do not* have the ability to add or remove owners.
In addition to being more convenient for managing groups of owners, teams are
Team membership is not something Github provides simple public access to, and it
is likely for you to encounter the following message when working with them:
-> It looks like you don't have permission to query a necessary property from
+> It looks like you don’t have permission to query a necessary property from
Github to complete this request. You may need to re-authenticate on crates.io
to grant permission to read github org memberships. Just go to
https://crates.io/login
-This is basically a catch-all for "you tried to query a team, and one of the
-five levels of membership access control denied this". That is not an
-exaggeration. Github's support for team access control is Enterprise Grade.
+This is basically a catch-all for “you tried to query a team, and one of the
+five levels of membership access control denied this”. That is not an
+exaggeration. Github’s support for team access control is Enterprise Grade.
The most likely cause of this is simply that you last logged in before this
feature was added. We originally requested *no* permissions from Github when
-authenticating users, because we didn't actually ever use the user's token for
+authenticating users, because we didn’t actually ever use the user’s token for
anything other than logging them in. However to query team membership on your
behalf, we now require
[the `read:org` scope](https://developer.github.com/v3/oauth/#scopes).
were introduced will keep working. However you will never be able to add a team
as an owner, or publish a crate as a team owner. If you ever attempt to do this,
you will get the error above. You may also see this error if you ever try to
-publish a crate that you don't own at all, but otherwise happens to have a team.
+publish a crate that you don’t own at all, but otherwise happens to have a team.
-If you ever change your mind, or just aren't sure if crates.io has sufficient
+If you ever change your mind, or just aren’t sure if crates.io has sufficient
permission, you can always go to https://crates.io/login, which will prompt you
-for permission if crates.io doesn't have all the scopes it would like to.
+for permission if crates.io doesn’t have all the scopes it would like to.
An additional barrier to querying github is that the organization may be
actively denying third party access. To check this, you can go to:
![Organization Access Control](images/org-level-acl.png)
-Where you may choose to explicitly remove crates.io from your organization's
-blacklist, or simply press the "Remove Restrictions" button to allow all third
+Where you may choose to explicitly remove crates.io from your organization’s
+blacklist, or simply press the “Remove Restrictions” button to allow all third
party applications to access this data.
Alternatively, when crates.io requested the `read:org` scope, you could have
explicitly whitelisted crates.io querying the org in question by pressing
-the "Grant Access" button next to its name:
+the “Grant Access” button next to its name:
![Authentication Access Control](images/auth-level-acl.png)
unique for the package in question.
* `TARGET` - the target triple that is being compiled for. Native code should be
compiled for this triple. Some more information about target
- triples can be found in [clang's own documentation][clang].
+ triples can be found in [clang’s own documentation][clang].
* `HOST` - the host triple of the rust compiler.
* `NUM_JOBS` - the parallelism specified as the top-level parallelism. This can
be useful to pass a `-j` parameter to a system like `make`.
# Why build crates.io rather than use Github as a registry?
-We think that it's very important to support multiple ways to download
+We think that it’s very important to support multiple ways to download
packages, including downloading from Github and copying packages into
your project itself.
That said, we think that crates.io offers a number of important benefits, and
will likely become the primary way that people download packages in Cargo.
-For precedent, both Node.js's [npm][1] and Ruby's [bundler][2] support both a
+For precedent, both Node.js’s [npm][1] and Ruby’s [bundler][2] support both a
central registry model as well as a Git-based model, and most packages
are downloaded through the registry in those ecosystems, with an
important minority of packages making use of git-based packages.
[target-deps]: manifest.html#the-dependencies-section
-In the longer-term, we're looking at ways to conveniently cross-compile
+In the longer-term, we’re looking at ways to conveniently cross-compile
projects using Cargo.
# Does Cargo support environments, like `production` or `test`?
For libraries the situation is somewhat different. A library is not only used by
the library developers, but also any downstream consumers of the library. Users
-dependent on the library will not inspect the library's `Cargo.lock` (even if it
+dependent on the library will not inspect the library’s `Cargo.lock` (even if it
exists). This is precisely because a library should **not** be deterministically
recompiled for all users of the library.
-If a library ends up being used transitively by several dependencies, it's
+If a library ends up being used transitively by several dependencies, it’s
likely that just a single copy of the library is desired (based on semver
compatibility). If all libraries were to check in their `Cargo.lock`, then
multiple copies of the library would be used, and perhaps even a version
# 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.
+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.
+* Fetches and builds your project’s dependencies.
* Invokes `rustc` or another build tool with the correct parameters to build your project.
* Introduces conventions, making working with Rust projects easier.
# Converting to Cargo
-You can convert an existing Rust project to use Cargo. You'll have to create a
+You can convert an existing Rust project to use Cargo. You’ll have to create a
`Cargo.toml` file with all of your dependencies, and move your source files and
test files into the places where Cargo expects them to be. See the [manifest
description](manifest.html) and the [Project Layout](#project-layout) section
$ 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. If you'd like to not initialize a new
+We’re passing `--bin` because we’re making a binary program: if we
+were making a library, we’d leave it off. If you’d like to not initialize a new
git repository as well (the default), you can also pass `--vcs none`.
-Let's check out what Cargo has generated for us:
+Let’s check out what Cargo has generated for us:
```shell
$ cd hello_world
If we had just used `cargo new hello_world` without the `--bin` flag, then the
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`:
+we need to get started. First, let’s check out `Cargo.toml`:
```toml
[package]
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`:
+Here’s what’s in `src/main.rs`:
```
fn main() {
}
```
-Cargo generated a 'hello world' for us. Let's compile it:
+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"
Hello, world!</code></pre>
To pass some arguments to your program, use `cargo run first_arg second_arg`.
-If flags are being passed, use a '--' separator to tell Cargo which flags go where, like `cargo run -- --foo -b bar`.
+If flags are being passed, use a “--” separator to tell Cargo which flags go where, like `cargo run -- --foo -b bar`.
-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.
+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:
+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"
# Working on an existing Cargo project
-If you download an existing project that uses Cargo, it's really easy
+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 `color-rs`:
+First, get the project from somewhere. In this example, we’ll use `color-rs`:
```sh
$ git clone https://github.com/bjz/color-rs.git
## Adding a dependency
-It's quite simple to add a dependency. Simply add it to your `Cargo.toml` file:
+It’s quite simple to add a dependency. Simply add it to your `Cargo.toml` file:
```toml
[dependencies]
# Cargo.toml vs Cargo.lock
`Cargo.toml` and `Cargo.lock` serve two different purposes. Before we talk
-about them, here's a summary:
+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, and is maintained by Cargo.
-* If you're building a library, put `Cargo.lock` in your `.gitignore`.
-* If you're building an executable, check `Cargo.lock` into `git`.
+* If you’re building a library, put `Cargo.lock` in your `.gitignore`.
+* If you’re building an executable, check `Cargo.lock` into `git`.
-Let's dig in a little bit more.
+Let’s dig in a little bit more.
`Cargo.toml` is a **manifest** file. In the manifest, we can specify a bunch of
different metadata about our project. For example, we can say that we depend
color = { git = "https://github.com/bjz/color-rs.git" }
```
-This project has a single dependency, on the `color` 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
+This project has a single dependency, on the `color` 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
+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. `bjz` could update `color-rs` in the meantime, and my build would
include this commit, while yours would not. Therefore, we would get different
color = { git = "https://github.com/bjz/color-rs.git", rev = "bf739419" }
```
-Now, our builds will be the same. But, there's a big drawback: now we have to
+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
+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:
```
-You can see that there's a lot more information here, including the exact
+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
+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
+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 color # updates just 'color'
+$ cargo update -p color # updates just “color”
```
This will write out a new `Cargo.lock` with the new version information. Note
# Overriding Dependencies
-Sometimes, you may want to override one of Cargo's dependencies. For example,
-let's say you're working on a project, `conduit-static`, which depends on
+Sometimes, you may want to override one of Cargo’s dependencies. For example,
+let’s say you’re working on a project, `conduit-static`, which depends on
the package `conduit`. You find a bug in `conduit`, and you want to write a
-patch. Here's what `conduit-static`'s `Cargo.toml` looks like:
+patch. Here’s what `conduit-static`’s `Cargo.toml` looks like:
```toml
[package]
conduit = "0.7"
```
-You check out a local copy of `conduit`, let's say in your `~/src` directory:
+You check out a local copy of `conduit`, let’s say in your `~/src` directory:
```shell
$ cd ~/src
$ git clone https://github.com/conduit-rust/conduit.git
```
-You'd like to have `conduit-static` use your local version of `conduit`,
+You’d like to have `conduit-static` use your local version of `conduit`,
rather than the one on GitHub, while you fix the bug.
Cargo solves this problem by allowing you to have a local configuration
with all projects.
To specify overrides, create a `.cargo/config` file in some ancestor of
-your project's directory (common places to put it is in the root of
+your project’s directory (common places to put it is in the root of
your code directory or in your home directory).
Inside that file, put this:
```
This array should be filled with directories that contain a `Cargo.toml`. In
-this instance, we're just adding `conduit`, so it will be the only one that's
+this instance, we’re just adding `conduit`, so it will be the only one that’s
overridden. This path must be an absolute path.
Note: using a local configuration to override paths will only work for crates
Cargo can run your tests with the `cargo test` command. Cargo runs tests 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
+integration-style tests. As such, you’ll need to import your crates into
the files in `tests`.
To run your tests, just run `cargo test`:
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
</code></pre>
-Of course, if your project has tests, you'll see more output, with the
+Of course, if your project has tests, you’ll see more output, with the
correct number of tests.
You can also run a specific test by passing a filter:
# Path Dependencies
-Over time our `hello_world` project has grown significantly in size! It's gotten
+Over time our `hello_world` project has grown significantly in size! It’s gotten
to the point that we probably want to split out a separate crate for others to
use. To do this Cargo supports **path dependencies** which are typically
-sub-crates that live within one repository. Let's start off by making a new
+sub-crates that live within one repository. Let’s start off by making a new
crate inside of our `hello_world` project:
```shell
```
This tells Cargo that we depend on a crate called `hello_utils` which is found
-in the `hello_utils` folder (relative to the `Cargo.toml` it's written in).
+in the `hello_utils` folder (relative to the `Cargo.toml` it’s written in).
-And that's it! The next `cargo build` will automatically build `hello_utils` and
+And that’s it! The next `cargo build` will automatically build `hello_utils` and
all of its own dependencies, and others can also start using the crate as well.
## Travis-CI
-% Cargo, Rust's Package Manager
+% Cargo, Rust’s Package Manager
# Installing
Alternatively, you can build Cargo from source.
-# Let's Get Started
+# Let’s Get Started
To start a new project with Cargo, use `cargo new`:
$ 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.
+We’re passing `--bin` because we’re making a binary program: if we
+were making a library, we’d leave it off.
-Let's check out what Cargo has generated for us:
+Let’s check out what Cargo has generated for us:
```shell
$ cd hello_world
1 directory, 2 files
```
-This is all we need to get started. First, let's check out `Cargo.toml`:
+This is all we need to get started. First, let’s check out `Cargo.toml`:
```toml
[package]
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`:
+Here’s what’s in `src/main.rs`:
```
fn main() {
}
```
-Cargo generated a 'hello world' for us. Let's compile it:
+Cargo generated a “hello world” for us. Let’s compile it:
<pre><code class="language-shell">$ cargo build
<span style="font-weight: bold"
* Before you reach 1.0.0, anything goes.
* After 1.0.0, only make breaking changes when you increment the major
version. In Rust, breaking changes include adding fields to structs or
- variants to enums. Don't break the build.
-* After 1.0.0, don't add any new public API (no new `pub` anything) in
+ variants to enums. Don’t break the build.
+* After 1.0.0, don’t add any new public API (no new `pub` anything) in
tiny versions. Always increment the minor version if you add any new
`pub` structs, traits, fields, types, functions, methods or anything else.
* Use version numbers with three numeric parts such as 1.0.0 rather than 1.0.
explicitly included.
If a VCS is being used for a package, the `exclude` field will be seeded with
-the VCS's ignore settings (`.gitignore` for git for example).
+the VCS’ ignore settings (`.gitignore` for git for example).
```toml
[package]
native = { path = "native/x86_64" }
```
-If you're using a custom target specification, quote the full path and file
+If you’re using a custom target specification, quote the full path and file
name:
```toml
Cargo supports custom configuration of how rustc is invoked through **profiles**
at the top level. Any manifest may declare a profile, but only the **top level**
-project's profiles are actually read. All dependencies' profiles will be
+project’s profiles are actually read. All dependencies’ profiles will be
overridden. This is done so the top-level project has control over how its
dependencies are compiled.
* Conditional compilation options (usable through `cfg` attributes);
* Optional dependencies, which enhance a package, but are not required;
-* Clusters of optional dependencies, such as "postgres", that would include the
+* Clusters of optional dependencies, such as “postgres”, that would include the
`postgres` package, the `postgres-macros` package, and possibly other packages
(such as development-time mocking libraries, debugging tools, etc.)
name = "awesome"
[features]
-# The "default" set of optional packages. Most people will
+# The “default” set of optional packages. Most people will
# want to use these packages, but they are strictly optional.
# Note that `session` is not a package but rather another
# feature listed in this manifest.
# compilation, like `#[cfg(feature = "go-faster")]`.
go-faster = []
-# The "secure-password" feature depends on the bcrypt package.
+# The “secure-password” feature depends on the bcrypt package.
# This aliasing will allow people to talk about the feature in
# a higher-level way and allow this package to add more
# requirements to the feature in the future.
[dependencies]
# These packages are mandatory and form the core of this
-# package's distribution
+# package’s distribution
cookie = "1.2.0"
oauth = "1.1.0"
route-recognizer = "=2.1.0"
# A list of all of the optional dependencies, some of which
-# are included in the above "features". They can be opted
+# are included in the above “features”. They can be opted
# into by apps.
jquery = { version = "1.0.2", optional = true }
uglifier = { version = "1.5.3", optional = true }
## Usage In Packages
-In most cases, the concept of "optional dependency" in a library is best
+In most cases, the concept of “optional dependency” in a library is best
expressed as a separate package that the top-level application depends on.
However, high-level packages, like Iron or Piston, may want the ability to
dependencies:
* Grouping a number of low-level optional dependencies together into a single
- high-level "feature".
+ high-level “feature”.
* Specifying packages that are recommended (or suggested) to be included by
users of the package.
* Including a feature (like `secure-password` in the motivating example) that
When you run `cargo test`, Cargo will:
-* Compile and run your library's unit tests, which are in files reachable from
+* Compile and run your library’s unit tests, which are in files reachable from
`lib.rs`. Any sections marked with `#[cfg(test)]` will be included.
* Compile and run your library’s documentation tests, which are embedded
inside of documentation blocks.
-* Compile and run your library's [integration tests](#integration-tests).
-* Compile your library's examples.
+* Compile and run your library’s [integration tests](#integration-tests).
+* Compile your library’s examples.
## Integration tests
[lib]
name = "..."
-# this could be "staticlib" as well
+# this could be “staticlib” as well
crate-type = ["dylib"]
```