How do I install rust?

Me want install rust.

Me search forum. Find bunch of random things.

Me go to rust-lang.org copy command. No worky.

Me click “Other Installation Methods” on rust-lang.org. Me Ctrl-F “nix” find much Unix. Search stupid.

Me look manual: nix-env -qa for search package. Me nix-env -qa rust. No findy. Me nix-env -qa '*rust*'. Finger ouch. Invalid regex. Me nix-env -qa '.*rust.*'. Finger more ouchy. Find rustup but search stupid. Me sad.

Me want nix-env -i rustup. @jonringer say no use nix-env..

Me look manual. Manual long. Me browse a bit until too sad. Me look configuration.nix. Me find

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    wget vim
  ];

Me nix search rust. Long list. Me find nixpks.rustup. Me add rustup after vim. Me sudo nixos-rebuild switch. Me afraid Xorg will go away again. Sometimes sudo nixos-rebuild switch make Xorg go away. Me anxiety now.

Xorg no go away. Me relieved.

Me rustup toolchain install nightly. Me less sad. But much late now.

Me cargo new foo. Have new project. Me cargo run in project. error: linker cc not found. Me more sad again. Me sleep now.

NixOS too much sad.

7 Likes

I personally just use rustup to manage the whole rust toolchain like what you did in the end. It seems that you need to have c/c++ toolchain package installed, either gcc or clang. You can just add either of them to the list of environment.systemPackages.

Sometimes sudo nixos-rebuild switch make Xorg go away

I agree that in certain cases this will happen, when your graphic card driver gets updated or so (e.g. when you update the channel). This is usually anticipated and a reboot can get you back to X, unless when you can’t - at that moment NixOS always allow you to go back to the previous generation, which is proved to work

1 Like

You do systemd.services.display-manager.restartIfChanged = false;, you no anxiety more.

Or whatever display manager service is restarting while switch instead of “display-manager”. That one works for me…

2 Likes

I once experience a -2 error with the executables installed by rustup: Do rustup installed components such as rls supposed to be usable on NixOS? so I use the

I use the stable toolchain so I don’t mind using the packages rustc, cargo directly.

I tend to use the mozilla overlay and install rust in nix shells only.

For project generation I tend to use nix run, even though the long attribute path is a little bit unfriendly to work with…

$ nix run nixpkgs.latest.rustChannels.nightly.cargo -c cargo new foo
[3 built, 0.0 MiB DL]
     Created binary (application) `foo` package

I then copy a shell.nix template and edit it to my needs:

{ rustDate ? "2020-06-01" }:

let
  mozillaOverlay = import (builtins.fetchTarball "https://github.com/mozilla/nixpkgs-mozilla/archive/e912ed483e980dfb4666ae0ed17845c4220e5e7c.tar.gz");
  pkgs = import <nixpkgs> {
    overlays = [ mozillaOverlay ];
  };
  rustChannel = pkgs.rustChannelOf { date = rustDate; channel = "nightly"; };
in pkgs.mkShell {
  nativeBuildInputs = [
    rustChannel.rust
  ];
}

Usually I just use a recent commit.

The rustDates sole purpose is to quickly change the nightlies version. nix-shell --argstr rustDate 2020-05-01

4 Likes

Also using nix-shell but don’t need nightly so my shell.nix looks similar to:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = with pkgs; [ rustc cargo rustfmt rustPackages.clippy ];
  RUST_BACKTRACE = 1;
}

Add gcc and libraries to buildInputs as needed.

1 Like

Yeah, so adding “gcc”…

  environment.systemPackages = with pkgs; [
    wget vim rustup gcc
  ];

This works. Thanks to everybody else but I don’t know what nix-shell is, yet. :slight_smile:

I don’t recommend go install gcc to environment.systemPackages but always use a nix-shell for every project for the following reasons:

  1. Once you have all the build tools required for your project defined in a shell.nix it is easy to move between machines or share your expression with colleges.
  2. Compiling any C library installed with nix does not work unless you use a nix-shell. This is because our gcc package is actually a shell script that receives location of library/header paths through environment variables. These environment variables are only set if you add packages to buildInputs within a shell.nix. You can read more about this here

If it becomes to tedious to setup a shell.nix and run nix-shell in every project. Have a look at this page in particular nixify and nix-direnv

6 Likes

Hm…no flat learning curve available, huh?

So, to do just some Rust development, I guess I at least need to understand the following things:

  1. nix-shell
  2. derivations
  3. overlays

Now, let’s for a moment ignore that I am apparently learning the inner workings of a package manager and if that is a good use of my time and just hope that it is and focus on:

What else should be on this list and what is the recommended way to learn these things?

1 Like

You don’t need any overlays. Unless you always want the latest stable or a specific nightly, it is ok to just use the cargo derivation from nixpkgs. In many of my project I just use a shell.nix with cargo and clippy and it works fine.

Just to be completely fair (I think it’s good to have the right expectations): Nix/NixOS’ learning curve is quite steep. To use Nix productively, especially for development, you’ll need to learn the Nix language and some common nixpkgs functions and conventions.

4 Likes

Thanks for the clear statement. I guess I will have to find myself some tutorials.

Here, take this wall of text:

nixpkgs || rustup || nixpkgs-mozilla

NixOS has Cargo and the rust compiler packaged, so using the packages cargo rustc gcc from nixpkgs (see further below on how to use them) you should get an environment that enables you to compile Rust code. The main disadvantage of this is that the Rust nightly releases are not packaged, and it is quite common in the Rust ecosystem for crates to depend on experimental features and thus the nightly Rust compiler.

Then there’s rustup, a tool provided by Rust upstream to manage the Rust tools on your system. This is basically a package manager by itself. It provides the cargo und rustc binaries and dynamically points them to some downloaded version in your home directory. This is probably the best way to get a nightly Rust toolchain, if you don’t mind using a different package management tool.
Some more detailed information on rustup on NixOS: The thing is a bit tricky, because the downloaded binaries make some assumptions about system, that are not met on NixOS. Fortunately the rustup packaged in nixpkgs fixes this by patching the downloaded binaries on the fly to work on NixOS.

nixpkgs-mozilla is mostly just a repository containing additional packaging information for Nix on how to obtain the latest Rust tools as binaries and patch them to work on NixOS. This is a bit similar to a PPA on Ubuntu, as it contains additional Nix packages that are not available from the main package sources, nixpkgs.
This is mostly useful in cases where you need a nightly release, but also want to use the Nix package manager, for example to share your build environment with collegues or CI workers.
The Nix expression required to use it is indeed a bit more complicated involving overlays and stuff. I won’t go into detail here, because using nixpkgs-mozilla should not be necessary in most cases, but this is also described in one of the shell.nix examples above.

nix-env || NixOS || nix-shell

There are lots of different ways to use Nix to make some package available in your PATH. They all serve different purposes.
nix-env is a tool that can directly manage a Nix profile (each user can have one), and add packages to it imperatively. After adding a package to your user profile with nix-env -iA nixos.<package>, it will be downloaded from a binary cache (or built, if binaries are not available) and made available in the PATH.
You probably only want to use this when using Nix a non-NixOS Linux distribution, because you can not take advantage of the declarative nature of NixOS when using nix-env.

NixOS, as you probably know, is a Linux distribution that uses the Nix package manager to manage the whole system including system packages and configuration files. On NixOS, you can use your NixOS configuration files to declaratively set up the system and user profiles as well. This has many advantages compared to nix-env, for example you can put the configuration in a git repository or share it between multiple hosts. It also ensures that the packages in your profile are updated when you do nixos-rebuild switch --upgrade, which is not the case for nix-env (!).

nix-shell is a tool that allows you to set up an ad-hoc environment (a shell with a set of environment variables). You tell Nix what packages you need, it takes care of fetching them and putting them in your PATH for the duration of the nix-shell session. You can do this by running nix-shell -p <package1> <package2>. This is temporary and the packages may be garbage-collected after the nix-shell has been closed, if they are not referenced anywhere else.
I always set a shell alias from use to nix-shell -p, so I can just say use cargo rustc gcc.
nix-shell can also be used with a Nix expression in a file. If a shell.nix or default.nix exists in the current directory, executing just nix-shell will load the environment described in the file. This is useful for shareing build environments with other people, and it can contain more complex definitions, overrides and project-specific version requirements. Some people already posted good examples of shell.nix files.

9 Likes

Thanks for this explanation. I was always wondering how rustup seemed to work so flawlessly on Nixos, but I never took the time to investigate. This explains it!

Thank you to the rust people in nixpkgs who put in the time to make this work nicely!

How I Start: Nix - Xe the blog answers elaborately to your question

2 Likes

Thank you very much for the clear explanation!
Is there any chance to add the article into NixOS manual?

Hosted by Flying Circus.