Rust
This article is about the Rust programming language. There are 3 methods to use the rust compiler and toolchain in Nix/NixOS:
- via nixpkgs,
- via rustup,
- or with unofficial overlays on nixpkgs.
Installing via nixpkgs is the nix-iest way to use rust, but there are valid reasons to use any approach.
Installing via nixpkgs
The cargo
and rustc
derivations provide the rust toolchain in nixpkgs. A pro of using nixpkgs is that it's dead-simple and you get pinned versions, deterministic builds in nix-shell, etc. However, nixpkgs only maintains a single version of the rust stable toolchain, so if you require a nightly toolchain or require switching between multiple toolchains then this approach may not be for you.
Here's an example shell.nix
:
let
# Pinned nixpkgs, deterministic. Last updated: 2/12/21.
pkgs = import (fetchTarball("https://github.com/NixOS/nixpkgs/archive/a58a0b5098f0c2a389ee70eb69422a052982d990.tar.gz")) {};
# Rolling updates, not deterministic.
# pkgs = import (fetchTarball("channel:nixpkgs-unstable")) {};
in pkgs.mkShell {
buildInputs = [ pkgs.cargo pkgs.rustc ];
}
VSCode integration
The rust-lang.rust and matklad.rust-analyzer VSCode extensions offer rust support. However, you'll need a few more ingredients to get everything working:
let
# Pinned nixpkgs, deterministic. Last updated: 2/12/21.
pkgs = import (fetchTarball("https://github.com/NixOS/nixpkgs/archive/a58a0b5098f0c2a389ee70eb69422a052982d990.tar.gz")) {};
# Rolling updates, not deterministic.
# pkgs = import (fetchTarball("channel:nixpkgs-unstable")) {};
in pkgs.mkShell {
buildInputs = [
pkgs.cargo
pkgs.rustc
pkgs.rustfmt
];
# Certain Rust tools won't work without this
# This can also be fixed by using oxalica/rust-overlay and specifying the rust-src extension
# See https://discourse.nixos.org/t/rust-src-not-found-and-other-misadventures-of-developing-rust-on-nixos/11570/3?u=samuela. for more details.
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
}
You can use the arrterian.nix-env-selector extension to enable your nix-shell inside VSCode and have these settings picked up by other extensions.
Installation via rustup
The rustup tool is maintained by the rust community and offers and interface to install and switch between rust toolchains. In this scenario, rustup handles the "package management" of rust toolchains and places them in $PATH
. Nixpkgs offers rustup via the rustup
derivation. More info on using rustup can be found on their official website: https://rustup.rs/.
Unofficial overlays
Rust Nightlies
- Use one of the overlays above,
- Or, use rustup
Developing Rust projects using Nix
Neovim Completion
Racer completion can be configured using the following snippet:
(neovim.override {
configure = {
customRC = ''
if filereadable($HOME . "/.vimrc")
source ~/.vimrc
endif
let $RUST_SRC_PATH = '${stdenv.mkDerivation {
inherit (rustc) src;
inherit (rustc.src) name;
phases = ["unpackPhase" "installPhase"];
installPhase = ''cp -r library $out'';
}}'
'';
packages.nixbundle.start = with vimPlugins; [
nvim-completion-manager
nvim-cm-racer
];
};
})
Shell.nix example
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [ rustc cargo gcc ];
buildInputs = with pkgs; [ rustfmt clippy ];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
}
This will have the stable rust compiler + the official formatter and linter inside the ephemeral shell. It'll also set the RUST_SRC_PATH environment variable to point to the right location, which tools, such as rust-analyzer, require to be set.
FAQ
Building the openssl-sys crate
You'll need to have the openssl
and pkg-config
derivatives in order to build openssl-sys
crate. For example, you can start a shell providing these packages:
$ nix-shell -p pkg-config openssl
In some cases (eg here) you may also need
PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig";