# Setting up a Rust Development Environment

In this post we'll be discussing one way to set up your machine for Rust development. There are different ways, particularly related to the text editor, so feel free to skip what is irrelevant to you. We'll focus on:

• Setting up Rust via Rustup.
• Valuable tools like clippy and rustfmt.
• Configuring VS Code for Rust.
• Debugging with the command line and inside of VS Code.
• Using different compile targets.

Everything we do should be functional on both Linux and MacOS, on Windows your mileage may vary. I, unfortunately, don't have a Windows instance to test on.

In order to finish this all up you'll need to have the build-essentials (Ubuntu/Debian), base-devel (Arch), or XCode (Mac) installed already.

## Setting up Rust via Rustup

Rustup is an official Rust project that allows us to install, manage, and update multiple Rust toolchains. It can be installed easily via:

curl https://sh.rustup.rs -sSf | sh


After a brief download Rustup will prompt us for some configuration. Just accept the defaults here:

Current installation options:

default host triple: x86_64-apple-darwin
default toolchain: stable
modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation


After we'll be prompted to run the following command to update the current shell with the changes:

# Linux
export RUST_SRC_PATH=${HOME}/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src  If you're not on MacOS or Linux you will need to set this to what is shown as default in rustup show. Then you can test that racer works by doing a test run via the command line: racer complete std::io::B  You should see several matches from this. At this point racer is set up and ready to be used in your editor or with rls. ### rls Why do we want this? It enables a much richer development experience and extends on the capabilities of racer. rls is a language server implementation for Rust. It provides things like code completion, goto definitions, rich refactoring, and some other nice features. To install rls we need to use Rustup, specifying the appropriate toolchain when we do. (Macs use nightly-x86_64-apple-darwin, Linux should be nightly-x86_64-unknown-linux-gnu) If you don't use VS Code it might be worth skipping this step for now. rustup component add rls --toolchain nightly-x86_64-apple-darwin rustup component add rust-analysis --toolchain nightly-x86_64-apple-darwin rustup component add rust-src --toolchain nightly-x86_64-apple-darwin  Next we need to set up an environment variable. We need to set DYLD_LIBRARY_PATH and RLS_ROOT (you'll probably need to adjust this to your repository clone): # Mac export DYLD_LIBRARY_PATH=${HOME}/.rustup/toolchains/stable-x86_64-apple-darwin/lib
export RLS_ROOT=${HOME}/git/rust/rls # Linux export DYLD_LIBRARY_PATH=${HOME}/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib
export RLS_ROOT=${HOME}/git/rust/rls  At this point it should be set up. We'll test and use it later when we configure VS Code. ## Configuring VS Code for Rust I've been using VS Code for Rust for several months and it's quite pleasant. As with any text editor there are many knobs to tweak, so we're just going to focus on the directly relevant ones. You may use a different editor, and that's totally fine. Have at! I still regularly reach for vim for minor edits and some of my colleagues quite enjoy their emacs. Diversity is good, use what is best for you and let others use what is best for them. First, let's download VS Code. Drop over to their website and grab the installer. I'm a bit silly and use the 'Insiders' version that is released nightly, but you don't need to. In order to run code from the command line we may need to open up VS Code and open the 'Command Palette' with Shift+Command+P on Mac, or Shift+Control+P on Linux. In it, enter shell command and look for the Shell Command: Install 'code' command in PATH option. After doing this any new shell we open should be able to run code. ### Extension: Rust The 'Rust' extension provides some helpers around build, formatting, and other useful things. It can be installed by selecting the bottom 'Box with border and smaller box in the top right corner' button on the sidebar and searching for 'Rust'. You can take a look at the readme before you install. ### Extension: rls_vscode We'll need node installed, you can do this via your package manager (If you're on a Mac brew works great.) Once this is done we can install the rls_vscode extension. Since rls isn't released yet we need to do all the fun work ourselves! Nagivate to your regular git directory and clone the repository and install its dependencies. git clone https://github.com/jonathandturner/rls_vscode.git cd rls_vscode npm install  Next step is to build the extension, which we do through VS Code itself. Run code . in the repository we just cloned. In the VS Code window, select the 'Crossed out bug' icon and hit the green 'Play Button' beside the words 'Launch Extension' in the left. A new VS Code window will pop up, you can just close it. Now that the extension is built we can set up a symlink to install it into VS Code (if you're using Insiders the directory is .vscode-insiders): ln -s${HOME}/git/rust/rls_vscode/ ${HOME}/.vscode/extensions/rls_vscode  Later you can update the extension with a similar process. Due to the development pace it's advisable do to this every once in awhile. Next, quit VS Code and reopen it. Open up any Rust project and you should see in the blue bar at the bottom "RLS analysis: Starting up", this should change to "RLS analysis: Done" shortly after. Gotcha: If you reboot your machine you will need to open a terminal before opening VS Code, or use the integrated terminal in VS Code and restart it, before RLS will be able to successfully start. There are some ways around this but they're rather annoying in their own right. Perhaps in the future there will be a setting in VS Code. ### Extension: Better TOML The Rust ecosystem frequently uses TOML files for configuration. While 'Rusty code' provides basic TOML support, the 'Better TOML' goes a bit further, and is worth installing as well. ### Extension: LLDB Debugger The 'LLDB Debugger' (that's 'Low Level Debugger Debugger' for those paying attention) extension later if we want to debug our Rust applications from inside VS Code. It can be installed from the Extensions tab. You'll also need Python's six library which you can install via pip install six. We'll talk about how to use this extension in the next section. ## Debugging Rust Code Let's scaffold out a super basic application to test our debugging on before we get on to any real experimentation. We'll run cargo init --bin example and set src/main.rs to: pub enum Direction { North, South, East, West } pub fn is_north(dir: Direction) -> bool { match dir { Direction::North => true, _ => false, } } fn main() { let two = 1+1; println!("{}", two); let points = Direction::South; let compass = is_north(points); println!("{}", compass); }  This gives us something actually worthwhile to use the debugger on. Let's debug! ### On The Command Line The first step before debugging is to build, then fire it up with the debugger: cargo build rust-lldb ./target/debug/example  From here we can interact with the program like we normally would with LLDB. (Yes, there is rust-gdb, you're free to use that too!) For example: (lldb) breakpoint set -f main.rs -l 3 Breakpoint 1: where = exampleexample::is_north + 10 at main.rs:3, address = 0x0000000100000ffa (lldb) process launch Process 8376 launched: '/Users/hoverbear/git/rust/example/target/debug/example' (x86_64) 2 Process 8376 stopped * thread #1: tid = 0x2c222, 0x0000000100000ffa exampleexample::is_north(dir=South) + 10 at main.rs:3, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000ffa exampleexample::is_north(dir=South) + 10 at main.rs:3 1 pub enum Direction { North, South, East, West } 2 -> 3 fn is_north(dir: Direction) -> bool { 4 match dir { 5 Direction::North => true, 6 _ => false, 7 } (lldb) print dir (example::Direction)$0 = South


### With VS Code

After installing the 'LLDB Debugger' extension you can set a breakpoint by clicking to the left of the line numbers, you'll see a big red dot marking a breakpoint. In order to actually debug we need to do a couple things:

Add the following to .vscode/launch.json:

{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceRoot}/target/debug/example", "args": [], "cwd": "${workspaceRoot}",
"sourceLanguages": ["rust"]
}
]
}


Then, add a .vscode/tasks.json with the following:

{
"version": "0.1.0",
"command": "cargo",
"isShellCommand": true,
"args": ["build"],
"showOutput": "always"
}


Next let's set a breakpoint somewhere. Finally we can go to the 'No Bugs' icon and hit the 'Play' and we should see something like this:

## Compiling to Different Targets

So far we've been building x86_64-apple-darwin. If we were using Linux we'd be building x86_64-unknown-linux-gnu most likely. Let's target asmjs-unknown-emscripten (that is, Javascript) for fun.

First we need to install the emcripten package. On Mac this can be found in brew via brew install emscripten, some Linux distributions also package emscripten, but you can also set it up via the guide here.

Next install the target with rustup:

rustup target add asmjs-unknown-emscripten


If on Mac, the following probably needs to be changed in ~/.emscripten:

LLVM_ROOT = "/usr/local/opt/emscripten/libexec/llvm/bin"
#LLVM_ROOT = os.path.expanduser(os.getenv('LLVM') or '/usr/bin') # directory
#BINARYEN_ROOT = os.path.expanduser(os.getenv('BINARYEN') or '/usr/bin') # directory

# Avoid annoying popups about Java.
#JAVA = 'java'


Now you can compile our example in asm.js, then run it:

cargo build --target=asmjs-unknown-emscripten
node target/asmjs-unknown-emscripten/debug/example.js


The output should be:

2
false


Targetting other systems and architectures works similarly, the biggest stumbling block is installing the toolchain (in this case it was emscripten.)

## Closing Thoughts

At this point we have a functional Rust development environment that can target our native system as well as asm.js. Our editor supports debugging and has nice features like autocomplete. Finally, we have handy tools like clippy to help us detect errors.

Some of the tools and extensions we're using are still alpha, or don't work perhaps as well as we might hope, but things are only getting better! If you're interested, you can even get involved with these different projects to help them be even more awesome. Every few weeks you can go and do a quick update of things and see the improvements.

Now, we don't have any excuses not to have fun with Rust! Why not find something that looks interesting and try to make your first PR? Can't find something? Check out /r/rust and look at the projects people are talking about, look at the E - Easy issues on rustc, or tackle something small from rust-rosetta!

Thanks to Asquera for allocating some time for me to write this! The same article is hosted here as well!

5ada95b33393c3fbd6d7705652aa535f2a01e152
`