According to our conventions, this should be a separate file

This commit is contained in:
Carol (Nichols || Goulding)
2018-02-19 14:09:53 -05:00
parent dc085d5ff9
commit 3bac2f0c8f
3 changed files with 266 additions and 266 deletions

View File

@@ -7,6 +7,7 @@
- [Getting Started](ch01-00-getting-started.md)
- [Installation](ch01-01-installation.md)
- [Hello, World!](ch01-02-hello-world.md)
- [Hello, Cargo!](ch01-03-hello-cargo.md)
- [Guessing Game Tutorial](ch02-00-guessing-game-tutorial.md)

View File

@@ -216,269 +216,3 @@ Just compiling with `rustc` is fine for simple programs, but as your project
grows, youll want to be able to manage all of the options and make it easy to
share your code. Next, well introduce you to a tool called Cargo, which will
help you write real-world Rust programs.
## Hello, Cargo!
Cargo is Rusts build system and package manager. Most Rustaceans will use this
tool to manage their Rust projects because Cargo takes care of a lot of tasks
for you, such as building your code, downloading the libraries your code
depends on, and building those libraries. (We call libraries your code needs
*dependencies*.)
The simplest Rust programs, like the one weve written so far, dont have any
dependencies, so if we had built the Hello World project with Cargo, it would
only be using the part of Cargo that takes care of building your code. As you
write more complex Rust programs, youll want to add dependencies, and if you
start the project off using Cargo, that will be a lot easier to do.
As the vast majority of Rust projects use Cargo, the rest of this book will
assume that you're using Cargo too. Cargo comes installed with Rust itself, if
you used the official installers as covered in the “Installation” section. If
you installed Rust through some other means, you can check if you have Cargo
installed by entering the following into your terminal:
```text
$ cargo --version
```
If you see a version number, great! If you see an error like `command not
found`, then you should look at the documentation for your method of
installation to determine how to install Cargo separately.
### Creating a Project with Cargo
Lets create a new project using Cargo and look at how it differs from our
original Hello World project. Navigate back to your *projects* directory (or
wherever you decided to put your code) and then on any operating system run:
```text
$ cargo new hello_cargo --bin
$ cd hello_cargo
```
<!-- Below -- so we always have to start a cargo project with the --bin option
if we want it to be something we can execute and not just a library, is that
right? It might be worth laying that out -->
<!-- As of Rust 1.21.0 (the version we're using for the book), yes, you must
always specify `--bin`. In a version of Rust in the near future (1.25 or 1.26),
binary crates will become the default kind of crate that `cargo new` makes, so
you won't have to specify `--bin` (but you can if you want and the behavior
will be the same). We'd rather not go into any more detail than we have here
because of this change; I think "The `--bin` argument to passed to `cargo new`
makes an executable application (often just called a *binary*), as opposed to a
library." lays this out enough. /Carol -->
This creates a new binary executable called `hello_cargo`. The `--bin` argument
to passed to `cargo new` makes an executable application (often just called a
*binary*), as opposed to a library. Weve given `hello_cargo` as the name for
our project, and Cargo creates its files in a directory of the same name.
Go into the *hello_cargo* directory and list the files, and you should see that
Cargo has generated two files and one directory for us: a *Cargo.toml* and a
*src* directory with a *main.rs* file inside. It has also initialized a new git
repository, along with a *.gitignore* file.
> Note: Git is a common version control system. You can change `cargo new` to
> use a different version control system, or no version control system, by
> using the `--vcs` flag. Run `cargo new --help` to see the available options.
Open up *Cargo.toml* in your text editor of choice. It should look similar to
the code in Listing 1-2:
<span class="filename">Filename: Cargo.toml</span>
```toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
[dependencies]
```
<span class="caption">Listing 1-2: Contents of *Cargo.toml* generated by `cargo
new`</span>
This file is in the [*TOML*][toml]<!-- ignore --> (Toms Obvious, Minimal
Language) format, which is what Cargo uses as its configuration format.
[toml]: https://github.com/toml-lang/toml
The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
this file, well add other sections.
The next three lines set the configuration information Cargo needs in order to
know that it should compile your program: the name, the version, and who wrote
it. Cargo gets your name and email information from your environment, so if
that's not correct, go ahead and fix that and save the file.
The last line, `[dependencies]`, is the start of a section for you to list any
of your project's dependencies. In Rust, packages of code are referred to as
*crates*. We wont need any other crates for this project, but we will in the
first project in Chapter 2, so we'll use this dependencies section then.
Now open up *src/main.rs* and take a look:
<span class="filename">Filename: src/main.rs</span>
```rust
fn main() {
println!("Hello, world!");
}
```
Cargo has generated a “Hello World!” for you, just like the one we wrote in
Listing 1-1! So far, the differences between our previous project and the
project generated by Cargo are that with Cargo our code goes in the *src*
directory, and we have a *Cargo.toml* configuration file in the top directory.
Cargo expects your source files to live inside the *src* directory so that the
top-level project directory is just for READMEs, license information,
configuration files, and anything else not related to your code. In this way,
using Cargo helps you keep your projects nice and tidy. Theres a place for
everything, and everything is in its place.
If you started a project that doesnt use Cargo, as we did with our project in
the *hello_world* directory, you can convert it to a project that does use
Cargo by moving the project code into the *src* directory and creating an
appropriate *Cargo.toml*.
### Building and Running a Cargo Project
Now lets look at whats different about building and running your Hello World
program through Cargo! From your project directory, build your project by
entering the following commands:
```text
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
```
This creates an executable file in *target/debug/hello_cargo* (or
*target\\debug\\hello_cargo.exe* on Windows), which you can run with this
command:
```text
$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!
```
Bam! If all goes well, `Hello, world!` should print to the terminal once more.
Running `cargo build` for the first time also causes Cargo to create a new file
at the top level called *Cargo.lock*, which is used to keep track of the exact
versions of dependencies in your project. This project doesnt have
dependencies, so the file is a bit sparse. You wont ever need to touch this
file yourself; Cargo will manage its contents for you.
We just built a project with `cargo build` and ran it with
`./target/debug/hello_cargo`, but we can also use `cargo run` to compile and
then run all in one go:
```text
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Notice that this time, we didnt see the output telling us that Cargo was
compiling `hello_cargo`. Cargo figured out that the files havent changed, so
it just ran the binary. If you had modified your source code, Cargo would have
rebuilt the project before running it, and you would have seen output like this:
```text
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Finally, theres `cargo check`. This command will quickly check your code to
make sure that it compiles, but not bother producing an executable:
```text
$ cargo check
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
```
Why would you not want an executable? `cargo check` is often much faster than
`cargo build`, because it skips the entire step of producing the executable. If
yourre checking your work throughout the process of writing the code, using
`cargo check` will speed things up! As such, many Rustaceans run `cargo check`
periodically as they write their program to make sure that it compiles, and
then run `cargo build` once theyre ready to give it a spin themselves.
So to recap, using Cargo:
- We can build a project using `cargo build` or `cargo check`
- We can build and run the project in one step with `cargo run`
- Instead of the result of the build being put in the same directory as our
code, Cargo will put it in the *target/debug* directory.
A final advantage of using Cargo is that the commands are the same no matter
what operating system youre on, so at this point we will no longer be
providing specific instructions for Linux and Mac versus Windows.
### Building for Release
When your project is finally ready for release, you can use `cargo build
--release` to compile your project with optimizations. This will create an
executable in *target/release* instead of *target/debug*. These optimizations
make your Rust code run faster, but turning them on makes your program take
longer to compile. This is why there are two different profiles: one for
development when you want to be able to rebuild quickly and often, and one for
building the final program youll give to a user that wont be rebuilt
repeatedly and that will run as fast as possible. If youre benchmarking the
running time of your code, be sure to run `cargo build --release` and benchmark
with the executable in *target/release*.
### Cargo as Convention
With simple projects, Cargo doesnt provide a whole lot of value over just
using `rustc`, but it will prove its worth as you continue. With complex
projects composed of multiple crates, its much easier to let Cargo coordinate
the build.
Even though the `hello_cargo` project is simple, it now uses much of the real
tooling youll use for the rest of your Rust career. In fact, to work on any
existing projects you can use the following commands to check out the code
using Git, change into the project directory, and build:
```text
$ git clone someurl.com/someproject
$ cd someproject
$ cargo build
```
If you want to look at Cargo in more detail, check out [its documentation].
[its documentation]: https://doc.rust-lang.org/cargo/
<!--Below -- I`m not sure this is the place for this conversation, it seems too
deep into the weeds for the "getting started" chapter. I know we discussed
Nightly Rust as an appendix previosuly, but honestly I think this is more
suited somewhere online, perhaps in the extended docs. I like the idea of
finishing the chapter here, on this practical note, and I think at this point
readers will want to get stuck in anyway and may skip this and never come back
because it's buried at the end of a chapter that's not really related to it. If
it's online somewhere separate they can come to it when they're ready. What do
you think?-->
<!-- Ok, I can see that. /Carol -->
## Summary
Youre already off to a great start on your Rust journey! In this chapter,
youve:
* Installed the latest stable version of Rust
* Written a “Hello, world!” program using both `rustc` directly and using
the conventions of `cargo`
This is a great time to build a more substantial program, to get used to
reading and writing Rust code. In the next chapter, well build a guessing game
program. If youd rather start by learning about how common programming
concepts work in Rust, see Chapter 3.

View File

@@ -0,0 +1,265 @@
## Hello, Cargo!
Cargo is Rusts build system and package manager. Most Rustaceans will use this
tool to manage their Rust projects because Cargo takes care of a lot of tasks
for you, such as building your code, downloading the libraries your code
depends on, and building those libraries. (We call libraries your code needs
*dependencies*.)
The simplest Rust programs, like the one weve written so far, dont have any
dependencies, so if we had built the Hello World project with Cargo, it would
only be using the part of Cargo that takes care of building your code. As you
write more complex Rust programs, youll want to add dependencies, and if you
start the project off using Cargo, that will be a lot easier to do.
As the vast majority of Rust projects use Cargo, the rest of this book will
assume that you're using Cargo too. Cargo comes installed with Rust itself, if
you used the official installers as covered in the “Installation” section. If
you installed Rust through some other means, you can check if you have Cargo
installed by entering the following into your terminal:
```text
$ cargo --version
```
If you see a version number, great! If you see an error like `command not
found`, then you should look at the documentation for your method of
installation to determine how to install Cargo separately.
### Creating a Project with Cargo
Lets create a new project using Cargo and look at how it differs from our
original Hello World project. Navigate back to your *projects* directory (or
wherever you decided to put your code) and then on any operating system run:
```text
$ cargo new hello_cargo --bin
$ cd hello_cargo
```
<!-- Below -- so we always have to start a cargo project with the --bin option
if we want it to be something we can execute and not just a library, is that
right? It might be worth laying that out -->
<!-- As of Rust 1.21.0 (the version we're using for the book), yes, you must
always specify `--bin`. In a version of Rust in the near future (1.25 or 1.26),
binary crates will become the default kind of crate that `cargo new` makes, so
you won't have to specify `--bin` (but you can if you want and the behavior
will be the same). We'd rather not go into any more detail than we have here
because of this change; I think "The `--bin` argument to passed to `cargo new`
makes an executable application (often just called a *binary*), as opposed to a
library." lays this out enough. /Carol -->
This creates a new binary executable called `hello_cargo`. The `--bin` argument
to passed to `cargo new` makes an executable application (often just called a
*binary*), as opposed to a library. Weve given `hello_cargo` as the name for
our project, and Cargo creates its files in a directory of the same name.
Go into the *hello_cargo* directory and list the files, and you should see that
Cargo has generated two files and one directory for us: a *Cargo.toml* and a
*src* directory with a *main.rs* file inside. It has also initialized a new git
repository, along with a *.gitignore* file.
> Note: Git is a common version control system. You can change `cargo new` to
> use a different version control system, or no version control system, by
> using the `--vcs` flag. Run `cargo new --help` to see the available options.
Open up *Cargo.toml* in your text editor of choice. It should look similar to
the code in Listing 1-2:
<span class="filename">Filename: Cargo.toml</span>
```toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
[dependencies]
```
<span class="caption">Listing 1-2: Contents of *Cargo.toml* generated by `cargo
new`</span>
This file is in the [*TOML*][toml]<!-- ignore --> (Toms Obvious, Minimal
Language) format, which is what Cargo uses as its configuration format.
[toml]: https://github.com/toml-lang/toml
The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
this file, well add other sections.
The next three lines set the configuration information Cargo needs in order to
know that it should compile your program: the name, the version, and who wrote
it. Cargo gets your name and email information from your environment, so if
that's not correct, go ahead and fix that and save the file.
The last line, `[dependencies]`, is the start of a section for you to list any
of your project's dependencies. In Rust, packages of code are referred to as
*crates*. We wont need any other crates for this project, but we will in the
first project in Chapter 2, so we'll use this dependencies section then.
Now open up *src/main.rs* and take a look:
<span class="filename">Filename: src/main.rs</span>
```rust
fn main() {
println!("Hello, world!");
}
```
Cargo has generated a “Hello World!” for you, just like the one we wrote in
Listing 1-1! So far, the differences between our previous project and the
project generated by Cargo are that with Cargo our code goes in the *src*
directory, and we have a *Cargo.toml* configuration file in the top directory.
Cargo expects your source files to live inside the *src* directory so that the
top-level project directory is just for READMEs, license information,
configuration files, and anything else not related to your code. In this way,
using Cargo helps you keep your projects nice and tidy. Theres a place for
everything, and everything is in its place.
If you started a project that doesnt use Cargo, as we did with our project in
the *hello_world* directory, you can convert it to a project that does use
Cargo by moving the project code into the *src* directory and creating an
appropriate *Cargo.toml*.
### Building and Running a Cargo Project
Now lets look at whats different about building and running your Hello World
program through Cargo! From your project directory, build your project by
entering the following commands:
```text
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
```
This creates an executable file in *target/debug/hello_cargo* (or
*target\\debug\\hello_cargo.exe* on Windows), which you can run with this
command:
```text
$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!
```
Bam! If all goes well, `Hello, world!` should print to the terminal once more.
Running `cargo build` for the first time also causes Cargo to create a new file
at the top level called *Cargo.lock*, which is used to keep track of the exact
versions of dependencies in your project. This project doesnt have
dependencies, so the file is a bit sparse. You wont ever need to touch this
file yourself; Cargo will manage its contents for you.
We just built a project with `cargo build` and ran it with
`./target/debug/hello_cargo`, but we can also use `cargo run` to compile and
then run all in one go:
```text
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Notice that this time, we didnt see the output telling us that Cargo was
compiling `hello_cargo`. Cargo figured out that the files havent changed, so
it just ran the binary. If you had modified your source code, Cargo would have
rebuilt the project before running it, and you would have seen output like this:
```text
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Finally, theres `cargo check`. This command will quickly check your code to
make sure that it compiles, but not bother producing an executable:
```text
$ cargo check
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
```
Why would you not want an executable? `cargo check` is often much faster than
`cargo build`, because it skips the entire step of producing the executable. If
yourre checking your work throughout the process of writing the code, using
`cargo check` will speed things up! As such, many Rustaceans run `cargo check`
periodically as they write their program to make sure that it compiles, and
then run `cargo build` once theyre ready to give it a spin themselves.
So to recap, using Cargo:
- We can build a project using `cargo build` or `cargo check`
- We can build and run the project in one step with `cargo run`
- Instead of the result of the build being put in the same directory as our
code, Cargo will put it in the *target/debug* directory.
A final advantage of using Cargo is that the commands are the same no matter
what operating system youre on, so at this point we will no longer be
providing specific instructions for Linux and Mac versus Windows.
### Building for Release
When your project is finally ready for release, you can use `cargo build
--release` to compile your project with optimizations. This will create an
executable in *target/release* instead of *target/debug*. These optimizations
make your Rust code run faster, but turning them on makes your program take
longer to compile. This is why there are two different profiles: one for
development when you want to be able to rebuild quickly and often, and one for
building the final program youll give to a user that wont be rebuilt
repeatedly and that will run as fast as possible. If youre benchmarking the
running time of your code, be sure to run `cargo build --release` and benchmark
with the executable in *target/release*.
### Cargo as Convention
With simple projects, Cargo doesnt provide a whole lot of value over just
using `rustc`, but it will prove its worth as you continue. With complex
projects composed of multiple crates, its much easier to let Cargo coordinate
the build.
Even though the `hello_cargo` project is simple, it now uses much of the real
tooling youll use for the rest of your Rust career. In fact, to work on any
existing projects you can use the following commands to check out the code
using Git, change into the project directory, and build:
```text
$ git clone someurl.com/someproject
$ cd someproject
$ cargo build
```
If you want to look at Cargo in more detail, check out [its documentation].
[its documentation]: https://doc.rust-lang.org/cargo/
<!--Below -- I`m not sure this is the place for this conversation, it seems too
deep into the weeds for the "getting started" chapter. I know we discussed
Nightly Rust as an appendix previosuly, but honestly I think this is more
suited somewhere online, perhaps in the extended docs. I like the idea of
finishing the chapter here, on this practical note, and I think at this point
readers will want to get stuck in anyway and may skip this and never come back
because it's buried at the end of a chapter that's not really related to it. If
it's online somewhere separate they can come to it when they're ready. What do
you think?-->
<!-- Ok, I can see that. /Carol -->
## Summary
Youre already off to a great start on your Rust journey! In this chapter,
youve:
* Installed the latest stable version of Rust
* Written a “Hello, world!” program using both `rustc` directly and using
the conventions of `cargo`
This is a great time to build a more substantial program, to get used to
reading and writing Rust code. In the next chapter, well build a guessing game
program. If youd rather start by learning about how common programming
concepts work in Rust, see Chapter 3.