Jump to content

Rust: Difference between revisions

Remove Rust Nightlies section. This section had no information that wasn't found on the rest of the page (only having two bullet points referring to other sections of the page). Instead, modify the page to elaborate more in the respective sections.
imported>Domenkozar
(Added note about devenv)
(Remove Rust Nightlies section. This section had no information that wasn't found on the rest of the page (only having two bullet points referring to other sections of the page). Instead, modify the page to elaborate more in the respective sections.)
 
(20 intermediate revisions by 18 users not shown)
Line 5: Line 5:
# or with unofficial overlays on nixpkgs.  
# 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 is the best way to use Rust, but there are valid reasons to use any approach.


== Installing via nixpkgs ==
== Installing via nixpkgs ==
The <code>cargo</code> and <code>rustc</code> derivations provide the Rust toolchain in nixpkgs. An advantage 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.  
The <code>cargo</code> and <code>rustc</code> derivations provide the Rust toolchain in nixpkgs. An advantage 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 switch between multiple toolchains then this approach may not be for you.  


Here's an example <code>shell.nix</code>:
Here's an example <code>shell.nix</code>:
Line 25: Line 25:


== Installation via rustup ==
== 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 <code>$PATH</code>. Nixpkgs offers rustup via the <code>rustup</code> derivation. More info on using rustup can be found on their official website: https://rustup.rs/.
The rustup tool is maintained by the Rust community and offers an interface to install and switch between Rust toolchains. In this scenario, rustup handles the "package management" of Rust toolchains and places them in <code>$PATH</code>. Nixpkgs offers rustup via the <code>rustup</code> derivation. More info on using rustup can be found on their official website: https://rustup.rs/.


If you want to have the most "normal" Rust experience I recommend using rustup with the following example shell.nix:
If you want the most "normal" Rust experience I recommend using rustup with the following example shell.nix:
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
{ pkgs ? import <nixpkgs> {} }:
{ pkgs ? import <nixpkgs> {} }:
  let
    overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml));
    libPath = with pkgs; lib.makeLibraryPath [
      # load external libraries that you need in your rust project here
    ];
in
   pkgs.mkShell rec {
   pkgs.mkShell rec {
     buildInputs = with pkgs; [
     buildInputs = with pkgs; [
       llvmPackages_latest.llvm
       clang
       llvmPackages_latest.bintools
       # Replace llvmPackages with llvmPackages_X, where X is the latest LLVM version (at the time of writing, 16)
       zlib.out
       llvmPackages.bintools
       rustup
       rustup
      xorriso
      grub2
      qemu
      llvmPackages_latest.lld
      python3
     ];
     ];
     RUSTC_VERSION = pkgs.lib.readFile ./rust-toolchain;
     RUSTC_VERSION = overrides.toolchain.channel;
     # https://github.com/rust-lang/rust-bindgen#environment-variables
     # https://github.com/rust-lang/rust-bindgen#environment-variables
     LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];
     LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];
    HISTFILE = toString ./.history;
     shellHook = ''
     shellHook = ''
       export PATH=$PATH:${CARGO_HOME:-~/.cargo}/bin
       export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin
       export PATH=$PATH:${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/
       export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/
       '';
       '';
     # Add libvmi precompiled library to rustc search path
     # Add precompiled library to rustc search path
     RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [
     RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [
       pkgs.libvmi
       # add libraries here (e.g. pkgs.libvmi)
     ]);
     ]);
     # Add libvmi, glibc, clang, glib headers to bindgen search path
    LD_LIBRARY_PATH = libPath;
     BINDGEN_EXTRA_CLANG_ARGS =  
     # Add glibc, clang, glib, and other headers to bindgen search path
     # Includes with normal include path
     BINDGEN_EXTRA_CLANG_ARGS =
     # Includes normal include path
     (builtins.map (a: ''-I"${a}/include"'') [
     (builtins.map (a: ''-I"${a}/include"'') [
       pkgs.libvmi
       # add dev libraries here (e.g. pkgs.libvmi.dev)
       pkgs.glibc.dev  
       pkgs.glibc.dev
     ])
     ])
     # Includes with special directory paths
     # Includes with special directory paths
Line 67: Line 68:
       ''-I${pkgs.glib.out}/lib/glib-2.0/include/''
       ''-I${pkgs.glib.out}/lib/glib-2.0/include/''
     ];
     ];
   }
   }
</syntaxHighlight>
</syntaxHighlight>


It's important to have a file named <code>rust-toolchain</code> lying in the same directory as the shell.nix.
It's important to have a file named <code>rust-toolchain.toml</code> lying in the same directory as the shell.nix.
Its purpose is to pin the version of the used Rust compiler.
Rust already has a standardized way of pinning a toolchain version for a workspace or a project.
<syntaxHighlight lang="shell-session">
See [https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file the Rustup book] for its syntax.
$ cat rust-toolchain
 
nightly-2021-09-19
A minimal example of the <code>rust-toolchain.toml</code>:
</syntaxHighlight>
<syntaxhighlight lang="toml">
[toolchain]
channel = "stable" # This can also be "nightly" if you want a nightly rust
                  # or nightly-20XX-XX-XX for a specific nightly.
</syntaxhighlight>


The important part is that this also works with complex setups using bindgen and precompiled C libraries. To add a new C library in the search path of bindgen and rustc edit the variables <code>BINDGEN_EXTRA_CLANG_ARGS</code> and <code>RUSTFLAGS</code>
The important part is that this also works with complex setups using bindgen and precompiled C libraries. To add a new C library in the search path of bindgen and rustc edit the variables <code>BINDGEN_EXTRA_CLANG_ARGS</code> and <code>RUSTFLAGS</code>
Line 95: Line 99:
== devenv.sh support ==
== devenv.sh support ==


# https://github.com/cachix/devenv/blob/main/examples/rust/devenv.nix and `devenv shell`
# https://github.com/cachix/devenv/blob/main/examples/rust/devenv.nix and <code>devenv shell</code>
 
== Rust Nightlies ==
 
# Use one of the overlays above,
# Or, use rustup


== Developing Rust projects using Nix ==
== Developing Rust projects using Nix ==
Line 106: Line 105:
The [https://nixos.org/manual/nixpkgs/stable/#rust Nixpkgs manual] uses <code>buildRustPackage</code>.
The [https://nixos.org/manual/nixpkgs/stable/#rust Nixpkgs manual] uses <code>buildRustPackage</code>.


[https://www.srid.ca/rust-nix This] blog post shows how to do it using <code>crate2nix</code>.
[https://srid.ca/rust-nix This] blog post shows how to do it using <code>dream2nix</code>. A template repo is available here: https://github.com/srid/rust-nix-template


== Using overrideAttrs with Rust Packages ==
== Using overrideAttrs with Rust Packages ==
Line 146: Line 145:
| Yes
| Yes
| Built into nixpkgs
| Built into nixpkgs
|-
| <code>carnix</code>
| Codegen
| Many
| <code>buildRustCrate</code>
| No?
| Unmaintained, AFAICT; [https://nest.pijul.com/pmeunier/carnix:master repository] is gone
|-
|-
| [https://github.com/kolloch/crate2nix <code>crate2nix</code>]
| [https://github.com/kolloch/crate2nix <code>crate2nix</code>]
Line 159: Line 151:
| <code>buildRustCrate</code>
| <code>buildRustCrate</code>
| [https://github.com/kolloch/crate2nix/commit/8bfeb42bda097e0bdf5452691a5e157aad3cc11f experimental]
| [https://github.com/kolloch/crate2nix/commit/8bfeb42bda097e0bdf5452691a5e157aad3cc11f experimental]
| Spiritual successor to carnix
| Spiritual successor to [https://github.com/nix-community/carnix <code>carnix</code>]
|-
|-
| [https://github.com/nmattia/naersk/ <code>naersk</code>]
| [https://github.com/nmattia/naersk/ <code>naersk</code>]
Line 165: Line 157:
| 2
| 2
| cargo
| cargo
| [https://github.com/nmattia/naersk/issues/79 No?]
| Yes
| [https://github.com/nmattia/naersk/blob/22b96210b2433228d42bce460f3befbdcfde7520/rust/rustc.nix#L22-L29 Seems to only support building on x86]
| [https://github.com/nmattia/naersk/blob/22b96210b2433228d42bce460f3befbdcfde7520/rust/rustc.nix#L22-L29 Seems to only support building on x86]
|-
|-
Line 208: Line 200:
{ pkgs ? import <nixpkgs> {} }:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
pkgs.mkShell {
   nativeBuildInputs = with pkgs; [ rustc cargo gcc ];
   nativeBuildInputs = with pkgs; [ rustc cargo gcc rustfmt clippy ];
  buildInputs = with pkgs; [ rustfmt clippy ];


   # Certain Rust tools won't work without this
   # Certain Rust tools won't work without this
Line 234: Line 225:
     extensions = [
     extensions = [
       "rust-src" # for rust-analyzer
       "rust-src" # for rust-analyzer
      "rust-analyzer"
     ];
     ];
   };
   };
Line 241: Line 233:
     rust
     rust
   ] ++ (with pkgs; [
   ] ++ (with pkgs; [
    rust-analyzer
     pkg-config
     pkg-config
     # other dependencies
     # other dependencies
Line 255: Line 246:


You can use the [https://marketplace.visualstudio.com/items?itemName=arrterian.nix-env-selector arrterian.nix-env-selector] extension to enable your nix-shell inside VSCode and have these settings picked up by other extensions.
You can use the [https://marketplace.visualstudio.com/items?itemName=arrterian.nix-env-selector arrterian.nix-env-selector] extension to enable your nix-shell inside VSCode and have these settings picked up by other extensions.
=== Neovim Completion ===
Racer completion can be configured using the following snippet:
<syntaxHighlight lang="nix">
(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
    ];
  };
})
</syntaxHighlight>


== FAQ ==
== FAQ ==
Line 305: Line 270:
</syntaxHighlight>
</syntaxHighlight>


Note that you need to use a <code>nix-shell</code> environment. Installing the Nix packages <code>openssl</code> or <code>sqlite</code> globally under <code>systemPackages</code> in NixOS or in <code>nix-env</code> [https://nixos.wiki/wiki/FAQ/I_installed_a_library_but_my_compiler_is_not_finding_it._Why%3F is discouraged] and doesn't always work (<code>pkg-config</code> may not be able to locate the libraries).
Note that you need to use a <code>nix-shell</code> environment. Installing the Nix packages <code>openssl</code> or <code>sqlite</code> globally under <code>systemPackages</code> in NixOS or in <code>nix-env</code> [[FAQ/I installed a library but my compiler is not finding it. Why? | is discouraged]] and doesn't always work (<code>pkg-config</code> may not be able to locate the libraries).


=== Building with a different Rust version than the one in Nixpkgs ===
=== Building with a different Rust version than the one in Nixpkgs ===


The following uses the [https://github.com/nix-community/fenix fenix] overlay and <code>makeRustPlatform</code> to build a crate with Rust nightly:
The following uses the [https://github.com/nix-community/fenix fenix] overlay and <code>makeRustPlatform</code> to build a crate with Rust Nightly:


<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
Line 337: Line 302:
}
}
</syntaxHighlight>
</syntaxHighlight>
=== Using LLD instead of LD ===
If you want to use <code>lld</code>, then the correct way to do this is to use <code>pkgs.llvmPackages.bintools</code>, <em>not</em> <code>pkgs.lld</code>. This is because the former uses a wrapper script that correctly sets <code>rpath</code>. You can find more information about this [https://matklad.github.io/2022/03/14/rpath-or-why-lld-doesnt-work-on-nixos.html here].
[[Category:Languages]]
3

edits