Normally I prefer to install software via the Debian repositories, but unfortunately, the version of Rust that is in the current version (as of this writing) of Debian, Bullseye (v.11, as well as the pre-release of 12, Bookworm), is a tad too old to do some of the things we need to do.
So the best solution is to grab "rustc"/"cargo"/etc directly from the https://www.rust-lang.org web site.
If you visit the https://www.rust-lang.org web site, and click on the "Install" menu item, you'll see that the instructions for installing Rust/Cargo is to install a third component, "Rustup", which is a tool that installs and updates Rust and Cargo. Installing this component will also install the Rust and Cargo components. So let's do as the instructions say:
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
This method only installs Rust/Cargo/toolchains for the user running this command. It will create a couple of new directories in your home folder, most notably "~/.rustup" and "~./cargo", and will make some edits to your profile setup files as well, which means you may need to restart your terminal window (or logout/login) for Rust/Cargo to work for you, or do the command at the end of the installation that sources your modified setup file.
Let's give our install of Rust a quick test to make sure it works. Even though we're going to program in Rust, most of our interactions will be with its "housekeeping" tool, Cargo.
Make a directory in which you want to do your programming work, and cd
into it. For this project, I'll create a "projects" folder in my home directory, for all my programming projects, along with a subdirectory under it for my projects particularly dealing with the Rust programming language, like this:
$ mkdir -p ~/projects/RUST/
You don't have to capitalize your "RUST" directory; I only do so to help me see at a glance that it is a directory.
Now we'll cd
into that directory:
$ cd ~/projects/RUST
Although it's possible to use the "rustc" compiler to manually compile a Rust program, it's more convenient in most cases to use the Rust housekeeping tool "cargo". We'll use cargo throughout this project, but just to see rustc in action, you can do the following.
Create, and cd into, a new directory for our project:
$ mkdir first $ cd first
Use your favorite text editor ("nano" is standard on Debian) to create the following file, and name it "first.rs":
fn main() { println!("Hello, world!"); }
Now compile the human-readable source file "first.rs" into a computer-executable file named "first":
$ rustc first.rs
Now, if you $ ls -lah
, you'll see two files: your original source-code file "first.rs", and an executable file, "first". You can run the "first" executable with:
$ ./first
You should see "Hello, world!" printed to the screen.
You can also create a source and target directory, like so:
mkdir src mkdir target mv first.rs src rm first
and then tell "rustc" where to find the source file and where to place, and even name, the executable:
$ rustc src/first.rs -o target/second
Then you can run $ ./target/second
to see the results of your compiled program.
But as a general rule, you won't want to use the "rustc" compiler directly; almost always you'd want to use rustc's "housekeeper", Cargo.
Before continuing, you'll want to cd up a level, and probably remove this "first" directory:
$ cd .. $ rm -rf first
Now we'll create a new Rust project, using Cargo, with this command:
$ cargo new testflight
We could name our project anything, but since this is just a "test flight" of the Rust compiler, the name "testflight" seems apropos. The command above will create a new directory named "testflight". cd
into that directory, and then do a directory listing to see the files there:
~/projects/RUST$ cd testflight/ ~/projects/RUST/testflight$ ls -lah total 24K drwxr-xr-x 4 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 . drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 .. -rw-r--r-- 1 westk@acu.local domain users@acu.local 179 Dec 12 09:02 Cargo.toml drwxr-xr-x 6 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 .git -rw-r--r-- 1 westk@acu.local domain users@acu.local 8 Dec 12 09:02 .gitignore drwxr-xr-x 2 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 src ~/projects/rust/testflight$
Cargo creates for us a "src" directory (and later, when a program gets compiled/built, a "target" directory), and places within it a "seed" file which is nothing more than a simple "hello, world" program like what we created above. The "Cargo.toml" file is a "preference" file for Cargo, which we can ignore for the moment. We can also ignore the ".git" and ".gitignore" files
If you look in the "src" directory, you'll see one file:
~/projects/RUST/testflight$ ls -lah src/ total 12K drwxr-xr-x 2 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 . drwxr-xr-x 4 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 .. -rw-r--r-- 1 westk@acu.local domain users@acu.local 45 Dec 12 09:02 main.rs ~/projects/rust/testflight$
This "main.rs" file contains a "main()" function, which is the starting point for all Rust programs. Earlier we created a "first.rs" file which performed the same role as this "main.rs". Cargo, by default, looks for a file named "main.rs", so we'll leave it named as-is.
This program is ready to be compiled, which is the process of converting a source code file like "main.rs", which is mostly-readable by humans, into a binary executable file that is readable by computers.
But compiling/building this program, and running, let's take a look inside the "main.rs" file, using your favorite text editor. Here I'll be using "nano", as it's a standard text editor in Debian.
~/projects/RUST/testflight$ nano src/main.rs
(You can then exit out of "nano" with Ctrl-X
.)
To compile the program, run this command:
$ cargo build
You results should look something like this:
~/projects/RUST/testflight$ cargo build Compiling testflight v0.1.0 (/home/westk@acu.local/projects/rust/testflight) Finished dev [unoptimized + debuginfo] target(s) in 1.58s ~/projects/rust/testflight$
Now if you ls
again, you'll see a new "target" directory has been created, and if you look inside that directory, you'll see a "debug" directory, and if you look in there, you'll see:
~/projects/RUST/testflight$ ls -lah total 32K drwxr-xr-x 5 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 . drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 .. -rw-r--r-- 1 westk@acu.local domain users@acu.local 154 Dec 12 09:21 Cargo.lock -rw-r--r-- 1 westk@acu.local domain users@acu.local 179 Dec 12 09:02 Cargo.toml drwxr-xr-x 6 westk@acu.local domain users@acu.local 4.0K Dec 12 09:02 .git -rw-r--r-- 1 westk@acu.local domain users@acu.local 8 Dec 12 09:02 .gitignore drwxr-xr-x 2 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 src drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 target ~/projects/RUST/testflight$ ls -lah target/ total 20K drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 . drwxr-xr-x 5 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 .. -rw-r--r-- 1 westk@acu.local domain users@acu.local 177 Dec 12 09:21 CACHEDIR.TAG drwxr-xr-x 7 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 debug -rw-r--r-- 1 westk@acu.local domain users@acu.local 1.1K Dec 12 09:21 .rustc_info.json ~/projects/RUST/testflight$ ls -lah target/debug/ total 11M drwxr-xr-x 7 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 . drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 .. drwxr-xr-x 2 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 build -rw-r--r-- 1 westk@acu.local domain users@acu.local 0 Dec 12 09:21 .cargo-lock drwxr-xr-x 2 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 deps drwxr-xr-x 2 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 examples drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 .fingerprint drwxr-xr-x 3 westk@acu.local domain users@acu.local 4.0K Dec 12 09:21 incremental -rwxr-xr-x 2 westk@acu.local domain users@acu.local 11M Dec 12 09:21 testflight -rw-r--r-- 1 westk@acu.local domain users@acu.local 131 Dec 12 09:21 testflight.d ~/projects/rust/testflight$
That "testflight" file in the "~/projects/rust/testflight/target/debug" directory is your new executable. You can run it like so:
~/projects/RUST/testflight$ ./target/debug/testflight Hello, world! ~/projects/RUST/testflight$
An alternative way to run the executable is to tell "Cargo" to run it, like so:
~/projects/RUST/testflight$ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.01s Running `target/debug/testflight` Hello, world! ~/projects/RUST/testflight$
Notice you get a little more "visual noise" when running it this way. If you want to suppress that noise when using "Cargo", you can use the "quiet" switch, like so:
:~/projects/rust/testflight$ cargo -q run Hello, world! ~/projects/RUST/testflight$
It's also possible, and more convenient, to compile and run the program in one step, instead of two. The cargo run
command checks to see if any changes have been made to the source code file since the last compilation, and if so, it will re-compile the source code and then, if the compilation is successful, run the resulting executable, all in one step. To see this, let's make a change to the source file, deleting the code below that is in reddish strike-through, and adding the code that is in yellow highlight, so that it has a different message. Edit the "src/main.rs" file, to look like this:
fn main() {println!("Hello, world!");println!("Howdy, Earthlings!"); }// end of main()
Notice that in addition to changing the message, I added a comment to the end of the main() function (fn
stands for function); these comments, which start with a double slash (//
), are ignored by the compiler, as they're not actually program code, but help humans make sense of what's going on in the program, particularly as the programs get more complex. It's totally optional to add such comments, and is only for your benefit and the benefit of those trying to read and understand your code.
To compile and run the program in one step instead of two, just run cargo run
:
~/projects/RUST/testflight$ cargo run Compiling testflight v0.1.0 (/home/westk@acu.local/projects/rust/testflight) Finished dev [unoptimized + debuginfo] target(s) in 0.28s Running `target/debug/testflight` Howdy, Earthlings! ~/projects/RUST/testflight$
You now have a working installation of Rust and Cargo, and can successfully compile and run a Rust program. We're now done with the "testflight" project, so unless you just want to keep it around, you can delete the "~/projects/RUST/testflight" directory. "cd" to its parent diectory (cd ~/projects/RUST
) and then delete it with rm -rf ~/projects/RUST/testflight
.
When editing these program files, using a stand-alone editor like "nano" is fine, but sometimes it's more convenient to use an Integrated Development Environment, or IDE. Although there are several IDEs you might want to use, Geany is not a bad choice. If you want to try using Geany, just CLICK HERE. Another popular IDE, also free/open-source, is Microsoft Visual Studio Code, although it is not in the Debian repositories. It is my usual go-to IDE, with the "rust-analyzer" extension installed. If you're running KDE's Plasma (or otherwise have Kate and Konsole installed), Kate also is not a bad choice.
If you don't care to take a look at Geany, and just want to move on to the next lesson, let's Download the Source Code for "sl".