Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand and master Rust package manager Cargo

2025-01-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "how to understand and master the Rust package manager Cargo", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let the editor take you to learn "how to understand and master the Rust package manager Cargo"!

Rust is a modern programming language that provides high performance, reliability, and productivity. It has been rated as the most popular language by the StackOverflow survey for several years.

In addition to being an excellent programming language, Rust has a build system and package manager called Cargo. Cargo handles many tasks, such as building code, downloading libraries, or dependencies, and so on. The two are bundled together, so you get Cargo when you install Rust.

Install Rust and Cargo

Before you begin, you need to install Rust and Cargo. The Rust project provides a downloadable script to handle installation. To get the script, open a browser to access https://sh.rustup.rs and save the file. Read the script to make sure you know something about its behavior, and then run it:

$sh. / rustup.rs

You can also refer to this page where you install Rust for more information.

After installing Rust and Cargo, you must get the configuration in the sourceenv file:

$source $HOME/.cargo/env

Even better, add the desired directory to the PATH environment variable:

Export PATH=$PATH:~/.cargo/bin

If you prefer to use package managers (such as DNF or Apt on Linux), look for Rust and Cargo packages in the distribution repository and install them accordingly. For example:

$dnf install rust cargo

After installing and setting them up, verify the Rust and Cargo versions you have:

$rustc-- versionrustc 1.41.0 (5e1a79984 2020-01-27) $cargo-- versioncargo 1.41.0 (626f0f40e 2019-12-03) manually build and run Rust

From printing "Hello, world!" on the screen The simple program begins. Open your favorite text editor and type the following program:

Cat hello.rsfn main () {println! ("Hello, world!");}

Save the file with the extension .rs to identify it as a Rust source code file.

Compile the program using the Rust compiler rustc:

$rustc hello.rs

After compilation, you will have a binary file with the same name as the source program:

$ls-ltotal 2592-rwxr-xr-x. 1 user group 2647944 Feb 13 14:14 hello-rw-r--r--. 1 user group 45 Feb 13 14:14 hello.rs$

Execute the program to verify that it works as expected:

$. / helloHello, world!

These steps are sufficient for smaller programs or anything you want to test quickly. However, Cargo is the best way forward when working on large programs that involve many people.

Create a new package using Cargo

Cargo is the build system and package manager for Rust. It helps developers download and manage dependencies and helps create Rust packages. In the Rust community, the word "package" in Rust is often referred to as "crate", but in this article, the two words are interchangeable. Please refer to the Cargo FAQ provided by the Rust community to distinguish.

If you need any help with the Cargo command line utility, use the-- help or-h command-line arguments:

$cargo-help

To create a new package, use the keyword new, followed by the package name. In this example, hello_opensource is used as the new package name. After running the command, you will see a message confirming that Cargo has created a binary package with the given name:

$cargo new hello_opensource Created binary (application) `hello_ opensource` package

Run the tree command to view the directory structure, which reports that some files and directories have been created. First, it creates a directory with the package name, and within that directory there is a src directory where your source code files are stored:

$tree.. └── hello_opensource ├── Cargo.toml └── src └── main.rs 2 directories, 2 files

Cargo not only creates packages, it also creates a simple "Hello, world" program. Open the main.rs file and have a look:

Cat hello_opensource/src/main.rsfn main () {println! ("Hello, world!");}

The next file to deal with is Cargo.toml, which is the configuration file for your package. It contains information about the package, such as its name, version, author information, and Rust version information.

Programs usually rely on external libraries or dependencies to run, which allows you to write applications to perform tasks that you don't know how to code or don't want to spend time coding. All your dependencies will be listed in this file. At this point, your new program does not have any dependencies. Open the Cargo.toml file and view its contents:

$cat hello_opensource/ Cargo. Toml [package] name = "hello_opensource" version = "0.1.0" authors = ["user"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] build the program using Cargo

So far, everything has gone well. Now you have a package to build a binary file (also known as an executable). Before that, enter the package directory:

$cd hello_opensource/

You can use Cargo's build command to build the package. Note the message that it is "compiling" your program:

$cargo build Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.38s

After running the build command, check what happened to the project directory:

$tree.. ├── Cargo.lock ├── Cargo.toml ├── src │ └── main.rs └── target debug ├── build ├── deps │ ├── hello_opensource-147b8a0f466515dd │ └── hello_opensource-147b8a0f466515dd.d ├── examples ├── hello_opensource ├── hello_opensource.d └── incremental └── hello_opensource-3pouh5i8ttpvz ├── s-fkmhjmt8tj-x962ep-1hivstog8wvf │ ├── 1r37g6m45p8rx66m.o │ ├── 2469ykny0eqo592v.o │ ├── 2g5i2x8ie8zed30i.o │ ├── 2yrvd7azhgjog6zy.o │ ├── 3g9rrdr4hyk76jtd .o │ ├── dep-graph.bin │ ├── query-cache.bin │ ├── work-products.bin │ └── wqif2s56aj0qtct.o └── s-fkmhjmt8tj-x962ep.lock 9 directories 17 files

Wow! The compilation process produces many intermediate files. In addition, your binaries will be saved in the. / target/debug directory with the same name as the package.

Use Cargo to run your application

Now that your binaries have been built, run it using Cargo's run command. As expected, it will print Hello, world! on the screen.

$cargo run Finished dev [unoptimized + debuginfo] target (s) in 0.01s Running `target/debug/hello_ opensource`Hello, world!

Alternatively, you can run the binary file directly, which is located in:

$ls-l. / target/debug/hello_opensource-rwxr-xr-x. 2 root root 2655552 Feb 13 14:19. / target/debug/hello_opensource

As expected, it produces the same result:

$. / target/debug/hello_opensourceHello, world!

Suppose you need to rebuild the package and discard all binaries and intermediate files created during the earlier compilation process. Cargo provides a convenient clean option to delete all intermediate files, except for source code and other required files:

$cargo clean$ tree.. ├── Cargo.lock ├── Cargo.toml └── src └── main.rs 1 directory, 3 files

Make some changes to the program, and then run it again to see how it works. For example, the following minor change adds Opensource to Hello, world! In the string:

Cat src/main.rsfn main () {println! ("Hello, Opensource world!");}

Now, build the program and run it again. This time, you will see Hello, Opensource worldview on the screen:

$cargo build Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.39s $cargo run Finished dev [unoptimized + debuginfo] target (s) in 0.01s Running `target/debug/hello_ opensource`Hello, Opensource world! Add dependencies using Cargo

Cargo allows you to add dependencies that the program needs to run. It is very easy to add dependencies using Cargo. Each Rust package contains a Cargo.toml file containing a list of dependencies (empty by default). Open the file with your favorite text editor, locate the [dependencies] section, and add libraries to include in the package. For example, add the rand library as a dependency:

$cat Cargo. Toml [package] name = "hello_opensource" version = "0.1.0" authors = ["test user"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rand = "0.3.14"

Try building your package and see what happens.

$cargo build Updating crates.io index Compiling libc v0.2.66 Compiling rand v0.4.6 Compiling rand v0.3.23 Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 4.48s

Cargo now contacts Crates.io, the central repository where Rust stores crate (or packages), and downloads and compiles rand. But wait-- what's with the libc bag? You don't want to install libc. Yes, the rand package depends on the libc package; therefore, Cargo also downloads and compiles libc.

New versions of the library will continue to emerge, and Cargo provides an easy way to update all its dependencies using the update command:

Cargo update

You can also choose to update a specific library with the-p flag followed by the package name:

Cargo update-p rand compiles and runs with a single command

So far, whenever changes are made to the program, build has been used first, followed by run. There is a simpler way: you can use the run command directly, which compiles and runs the program internally. To see how it works, first clean up your package directory:

$cargo clean$ tree.. ├── Cargo.lock ├── Cargo.toml └── src └── main.rs 1 directory, 3 files

Now execute run. The output indicates that it has been compiled and then runs the program, which means that you do not need to explicitly run build every time:

$cargo run Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.41s Running `target/debug/hello_ opensource`Hello, world! Check the code during development

When developing a program, you often go through multiple iterations. You need to make sure that your program is free from coding errors and compiles properly. You don't have to bear the overhead of generating binaries each time you compile. Cargo provides you with a check option that compiles code, but skips the last step in generating executable files. First run cargo clean in the package directory:

$tree.. ├── Cargo.lock ├── Cargo.toml └── src └── main.rs 1 directory, 3 files

Now run the check command to see what changes have been made to the directory:

$cargo check Checking hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.18s

The output shows that even if an intermediate file is created during compilation, no final binary or executable is created. This saves some time, which is important if the package contains thousands of lines of code:

$tree.. ├── Cargo.lock ├── Cargo.toml ├── src │ └── main.rs └── target debug ├── build ├── deps │ ├── hello_opensource-842d9a06b2b6a19b.d │ └── libhello_opensource-842d9a06b2b6a19b.rmeta ├── examples └── incremental └── hello_opensource-1m3f8arxhgo1u ├── s-fkmhw18fjk-542o8d-18nukzzq7hpxe │ ├── dep-graph.bin │ ├── query-cache.bin │ └── work-products.bin └── s-fkmhw18fjk-542o8d.lock 9 directories 9 files

To see if you really saved time, time and compare the build and check commands. First, the timing build command:

$time cargo build Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.40s real 0m0.416suser 0m0.251ssys 0m0.199s

Clean up the directory before running the check command:

$cargo clean

Timing check command:

$time cargo check Checking hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.15s real 0m0.166suser 0m0.086ssys 0m0.081s

Obviously, the check command is much faster.

Create an external Rust package

What you've done so far can be applied to any Rust crate you get from the Internet. All you have to do is download or clone the repository, move to the package folder, and then run the build command.

Git clone cd cargo build uses Cargo to build optimized Rust programs

So far, you have run build many times, but have you noticed its output? Don't worry, build it again and pay close attention:

$cargo build Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished dev [unoptimized + debuginfo] target (s) in 0.36s

Do you see the [unoptimized + debuginfo] text after each compilation? This means that the binaries generated by Cargo contain a lot of debugging information and are not optimized for execution. Developers often go through multiple iterations of development and need this debugging information for analysis. Similarly, performance is not a near-term goal when developing software. Therefore, there is no problem for now.

However, once you are ready to release the software, you no longer need this debugging information. Instead, it needs to be optimized for the best performance. In the final stages of development, you can use the-- release flag with build. Look carefully, after compiling, you should see the [optimized] text:

$cargo build-- release Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Finished release [optimized] target (s) in 0.29s

If you prefer, you can use this exercise to learn about the time saved when running optimized and unoptimized software.

Use Cargo to create libraries or binaries

Any software program can be roughly classified as a separate binary file or library. A stand-alone binary may be able to run itself even if it is used as an external library. However, as a library, it can be utilized by another independent binary. So far, all the programs you have built in this tutorial are stand-alone binaries, because this is the default setting for Cargo. To create a library, add the-- lib option:

$cargo new-- lib libhello Created library `libhello` package

This time, instead of creating a main.rs file, Cargo creates a lib.rs file. The code for your library should look like this:

$tree.. └── libhello ├── Cargo.toml └── src └── lib.rs 2 directories, 2 files

That's what Cargo is like, and not surprisingly, it adds some code to your new library file. Find the added content by moving to the package directory and viewing the file. By default, Cargo places a test function in the library file.

Run tests using Cargo

Rust provides best-in-class support for unit testing and integration testing, while Cargo allows you to perform any of the following tests:

$cd libhello/ $cat src/lib.rs# [cfg (test)] mod tests {# [test] fn it_works () {assert_eq! (2 + 2,4);}}

Cargo has a convenient test command that can run any test that exists in the code. Try to run the test that Cargo puts in the library code by default:

$cargo test Compiling libhello v0.1.0 (/ opensource/libhello) Finished test [unoptimized + debuginfo] target (s) in 0.55s Running target/debug/deps/libhello-d52e35bb47939653 running 1 testtest tests::it_works. Ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Doc-tests libhello running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out learn more about the inside of Cargo

You may be interested to know what happens under a Cargo command when it is run. After all, in many ways, Cargo is just a wrapper. To understand what it is doing, you can use the-v option with any Cargo command to output the details to the screen.

These are several examples of running build and clean using the-v option.

In the build command, you can see that these given command-line options trigger the underlying rustc (Rust compiler):

$cargo build-v Compiling hello_opensource v0.1.0 (/ opensource/hello_opensource) Running `rustc-edition=2018-- crate-name hello_opensource src/main.rs-- error-format=json-- json=diagnostic-rendered-ansi-- crate-type bin-- emit=dep-info Link-C debuginfo=2-C metadata=147b8a0f466515dd-C extra-filename=-147b8a0f466515dd-- out-dir / opensource/hello_opensource/target/debug/deps-C incremental=/opensource/hello_opensource/target/debug/incremental-L dependency=/opensource/hello_opensource/target/debug/ deps` Finished dev [unoptimized + debuginfo] target (s) in 0.36s

The clean command indicates that it simply deletes the directory that contains intermediate files and binaries:

Cargo clean-v Removing / opensource/hello_opensource/target so far, I believe you have a deeper understanding of "how to understand and master the Rust package manager Cargo". You might as well do it in practice! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report