]>
Commit | Line | Data |
---|---|---|
83c7162d XL |
1 | ## Hello, Cargo! |
2 | ||
94b46f34 XL |
3 | Cargo is Rust’s build system and package manager. Most Rustaceans use this tool |
4 | to manage their Rust projects because Cargo handles a lot of tasks for you, | |
5 | such as building your code, downloading the libraries your code depends on, and | |
6 | building those libraries. (We call libraries your code needs *dependencies*.) | |
83c7162d XL |
7 | |
8 | The simplest Rust programs, like the one we’ve written so far, don’t have any | |
94b46f34 XL |
9 | dependencies. So if we had built the Hello, world! project with Cargo, it would |
10 | only use the part of Cargo that handles building your code. As you write more | |
11 | complex Rust programs, you’ll add dependencies, and if you start a project | |
12 | using Cargo, adding dependencies will be much easier to do. | |
83c7162d | 13 | |
94b46f34 XL |
14 | Because the vast majority of Rust projects use Cargo, the rest of this book |
15 | assumes that you’re using Cargo too. Cargo comes installed with Rust if you | |
16 | used the official installers discussed in the “Installation” section. If you | |
17 | installed Rust through some other means, check whether Cargo is installed by | |
18 | entering the following into your terminal: | |
83c7162d XL |
19 | |
20 | ```text | |
21 | $ cargo --version | |
22 | ``` | |
23 | ||
94b46f34 XL |
24 | If you see a version number, you have it! If you see an error, such as `command |
25 | not found`, look at the documentation for your method of installation to | |
26 | determine how to install Cargo separately. | |
83c7162d XL |
27 | |
28 | ### Creating a Project with Cargo | |
29 | ||
30 | Let’s create a new project using Cargo and look at how it differs from our | |
94b46f34 XL |
31 | original Hello, world! project. Navigate back to your *projects* directory (or |
32 | wherever you decided to store your code). Then, on any operating system, run | |
33 | the following: | |
83c7162d XL |
34 | |
35 | ```text | |
94b46f34 | 36 | $ cargo new hello_cargo |
83c7162d XL |
37 | $ cd hello_cargo |
38 | ``` | |
39 | ||
94b46f34 XL |
40 | The first command creates a new directory called *hello_cargo*. We’ve named |
41 | our project *hello_cargo*, and Cargo creates its files in a directory of the | |
42 | same name. | |
43 | ||
44 | Go into the *hello_cargo* directory and list the files. You’ll see that Cargo | |
45 | has generated two files and one directory for us: a *Cargo.toml* file and a | |
46 | *src* directory with a *main.rs* file inside. It has also initialized a new Git | |
47 | repository along with a *.gitignore* file. | |
83c7162d XL |
48 | |
49 | > Note: Git is a common version control system. You can change `cargo new` to | |
94b46f34 XL |
50 | > use a different version control system or no version control system by using |
51 | > the `--vcs` flag. Run `cargo new --help` to see the available options. | |
83c7162d | 52 | |
94b46f34 XL |
53 | Open *Cargo.toml* in your text editor of choice. It should look similar to the |
54 | code in Listing 1-2. | |
83c7162d XL |
55 | |
56 | <span class="filename">Filename: Cargo.toml</span> | |
57 | ||
58 | ```toml | |
59 | [package] | |
60 | name = "hello_cargo" | |
61 | version = "0.1.0" | |
62 | authors = ["Your Name <you@example.com>"] | |
63 | ||
64 | [dependencies] | |
65 | ``` | |
66 | ||
67 | <span class="caption">Listing 1-2: Contents of *Cargo.toml* generated by `cargo | |
68 | new`</span> | |
69 | ||
94b46f34 XL |
70 | This file is in the [*TOML*][toml]<!-- ignore --> (*Tom’s Obvious, Minimal |
71 | Language*) format, which is Cargo’s configuration format. | |
83c7162d XL |
72 | |
73 | [toml]: https://github.com/toml-lang/toml | |
74 | ||
75 | The first line, `[package]`, is a section heading that indicates that the | |
76 | following statements are configuring a package. As we add more information to | |
77 | this file, we’ll add other sections. | |
78 | ||
94b46f34 XL |
79 | The next three lines set the configuration information Cargo needs to compile |
80 | your program: the name, the version, and who wrote it. Cargo gets your name and | |
81 | email information from your environment, so if that information is not correct, | |
82 | fix the information now and then save the file. | |
83c7162d XL |
83 | |
84 | The last line, `[dependencies]`, is the start of a section for you to list any | |
85 | of your project’s dependencies. In Rust, packages of code are referred to as | |
86 | *crates*. We won’t need any other crates for this project, but we will in the | |
87 | first project in Chapter 2, so we’ll use this dependencies section then. | |
88 | ||
94b46f34 | 89 | Now open *src/main.rs* and take a look: |
83c7162d XL |
90 | |
91 | <span class="filename">Filename: src/main.rs</span> | |
92 | ||
93 | ```rust | |
94 | fn main() { | |
95 | println!("Hello, world!"); | |
96 | } | |
97 | ``` | |
98 | ||
94b46f34 XL |
99 | Cargo has generated a Hello, world! program for you, just like the one we wrote |
100 | in Listing 1-1! So far, the differences between our previous project and the | |
101 | project Cargo generates are that Cargo placed the code in the *src* directory, | |
102 | and we have a *Cargo.toml* configuration file in the top directory. | |
83c7162d | 103 | |
94b46f34 XL |
104 | Cargo expects your source files to live inside the *src* directory. The |
105 | top-level project directory is just for README files, license information, | |
106 | configuration files, and anything else not related to your code. Using Cargo | |
107 | helps you organize your projects. There’s a place for everything, and | |
108 | everything is in its place. | |
83c7162d | 109 | |
94b46f34 XL |
110 | If you started a project that doesn’t use Cargo, as we did with the Hello, |
111 | world! project, you can convert it to a project that does use Cargo. Move the | |
112 | project code into the *src* directory and create an appropriate *Cargo.toml* | |
113 | file. | |
83c7162d XL |
114 | |
115 | ### Building and Running a Cargo Project | |
116 | ||
94b46f34 XL |
117 | Now let’s look at what’s different when we build and run the Hello, world! |
118 | program with Cargo! From your *hello_cargo* directory, build your project by | |
119 | entering the following command: | |
83c7162d XL |
120 | |
121 | ```text | |
122 | $ cargo build | |
123 | Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) | |
124 | Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs | |
125 | ``` | |
126 | ||
94b46f34 XL |
127 | This command creates an executable file in *target/debug/hello_cargo* (or |
128 | *target\debug\hello_cargo.exe* on Windows) rather than in your current | |
129 | directory. You can run the executable with this command: | |
83c7162d XL |
130 | |
131 | ```text | |
132 | $ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows | |
133 | Hello, world! | |
134 | ``` | |
135 | ||
94b46f34 XL |
136 | If all goes well, `Hello, world!` should print to the terminal. Running `cargo |
137 | build` for the first time also causes Cargo to create a new file at the top | |
138 | level: *Cargo.lock*. This file keeps track of the exact versions of | |
139 | dependencies in your project. This project doesn’t have dependencies, so the | |
140 | file is a bit sparse. You won’t ever need to change this file manually; Cargo | |
141 | manages its contents for you. | |
83c7162d XL |
142 | |
143 | We just built a project with `cargo build` and ran it with | |
94b46f34 XL |
144 | `./target/debug/hello_cargo`, but we can also use `cargo run` to compile the |
145 | code and then run the resulting executable all in one command: | |
83c7162d XL |
146 | |
147 | ```text | |
148 | $ cargo run | |
149 | Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs | |
150 | Running `target/debug/hello_cargo` | |
151 | Hello, world! | |
152 | ``` | |
153 | ||
94b46f34 XL |
154 | Notice that this time we didn’t see output indicating that Cargo was compiling |
155 | `hello_cargo`. Cargo figured out that the files hadn’t changed, so it just ran | |
156 | the binary. If you had modified your source code, Cargo would have rebuilt the | |
157 | project before running it, and you would have seen this output: | |
83c7162d XL |
158 | |
159 | ```text | |
160 | $ cargo run | |
161 | Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) | |
162 | Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs | |
163 | Running `target/debug/hello_cargo` | |
164 | Hello, world! | |
165 | ``` | |
166 | ||
94b46f34 XL |
167 | Cargo also provides a command called `cargo check`. This command quickly checks |
168 | your code to make sure it compiles but doesn’t produce an executable: | |
83c7162d XL |
169 | |
170 | ```text | |
171 | $ cargo check | |
172 | Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) | |
173 | Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs | |
174 | ``` | |
175 | ||
94b46f34 XL |
176 | Why would you not want an executable? Often, `cargo check` is much faster than |
177 | `cargo build`, because it skips the step of producing an executable. If you’re | |
178 | continually checking your work while writing the code, using `cargo check` will | |
179 | speed up the process! As such, many Rustaceans run `cargo check` periodically | |
180 | as they write their program to make sure it compiles. Then they run `cargo | |
181 | build` when they’re ready to use the executable. | |
83c7162d | 182 | |
94b46f34 | 183 | Let’s recap what we’ve learned so far about Cargo: |
83c7162d | 184 | |
94b46f34 XL |
185 | * We can build a project using `cargo build` or `cargo check`. |
186 | * We can build and run a project in one step using `cargo run`. | |
187 | * Instead of saving the result of the build in the same directory as our code, | |
188 | Cargo stores it in the *target/debug* directory. | |
83c7162d | 189 | |
94b46f34 XL |
190 | An additional advantage of using Cargo is that the commands are the same no |
191 | matter which operating system you’re working on. So, at this point, we’ll no | |
192 | longer provide specific instructions for Linux and macOS versus Windows. | |
83c7162d XL |
193 | |
194 | ### Building for Release | |
195 | ||
196 | When your project is finally ready for release, you can use `cargo build | |
94b46f34 XL |
197 | --release` to compile it with optimizations. This command will create an |
198 | executable in *target/release* instead of *target/debug*. The optimizations | |
199 | make your Rust code run faster, but turning them on lengthens the time it takes | |
200 | for your program to compile. This is why there are two different profiles: one | |
201 | for development, when you want to rebuild quickly and often, and another for | |
83c7162d | 202 | building the final program you’ll give to a user that won’t be rebuilt |
94b46f34 XL |
203 | repeatedly and that will run as fast as possible. If you’re benchmarking your |
204 | code’s running time, be sure to run `cargo build --release` and benchmark with | |
205 | the executable in *target/release*. | |
83c7162d XL |
206 | |
207 | ### Cargo as Convention | |
208 | ||
94b46f34 XL |
209 | With simple projects, Cargo doesn’t provide a lot of value over just using |
210 | `rustc`, but it will prove its worth as your programs become more intricate. | |
211 | With complex projects composed of multiple crates, it’s much easier to let | |
212 | Cargo coordinate the build. | |
83c7162d XL |
213 | |
214 | Even though the `hello_cargo` project is simple, it now uses much of the real | |
94b46f34 XL |
215 | tooling you’ll use in the rest of your Rust career. In fact, to work on any |
216 | existing projects, you can use the following commands to check out the code | |
217 | using Git, change to that project’s directory, and build: | |
83c7162d XL |
218 | |
219 | ```text | |
220 | $ git clone someurl.com/someproject | |
221 | $ cd someproject | |
222 | $ cargo build | |
223 | ``` | |
224 | ||
94b46f34 | 225 | For more information about Cargo, check out [its documentation]. |
83c7162d XL |
226 | |
227 | [its documentation]: https://doc.rust-lang.org/cargo/ | |
228 | ||
83c7162d XL |
229 | ## Summary |
230 | ||
231 | You’re already off to a great start on your Rust journey! In this chapter, | |
94b46f34 XL |
232 | you’ve learned how to: |
233 | ||
234 | * Install the latest stable version of Rust using `rustup` | |
235 | * Update to a newer Rust version | |
236 | * Open locally installed documentation | |
237 | * Write and run a Hello, world! program using `rustc` directly | |
238 | * Create and run a new project using the conventions of Cargo | |
239 | ||
240 | This is a great time to build a more substantial program to get used to reading | |
241 | and writing Rust code. So, in Chapter 2, we’ll build a guessing game program. | |
242 | If you would rather start by learning how common programming concepts work in | |
243 | Rust, see Chapter 3 and then return to Chapter 2. |