Rust: Difference between revisions

imported>TenTypekMatus
m Add some fixes, notably with devenv.sh
m dream2nix update link
 
(6 intermediate revisions by 4 users not shown)
Line 21: Line 21:
in pkgs.mkShell {
in pkgs.mkShell {
   buildInputs = [ pkgs.cargo pkgs.rustc ];
   buildInputs = [ pkgs.cargo pkgs.rustc ];
}
</syntaxHighlight>
== Installating with bindgen support ==
By default crates using <code>bindgen</code> will not compile. To add bindegen support add the <code>rustPlatform.bindegenHook</code> to your <code>nativeBuildInputs</code>.
Here's an example <code>shell.nix</code>:
<syntaxHighlight lang="nix">
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  nativeBuildInputs = [
    pkgs.cargo
    pkgs.rustc
    pkgs.rustPlatform.bindgenHook
    # optional: add pkg-config support
    pkgs.pkg-config
  ];
  buildInputs = [
    # add desired native packages
    # ...
  ];
  # ...
}
</syntaxHighlight>
This also works, when compiling rust crates:
<syntaxHighlight lang="nix">
{
  rustPlatform,
  pkg-config,
  ...
}:
rustPlatform.buildRustPackage {
  # ...
  nativeBuildInputs = [
    rustPlatform.bindgenHook
    pkg-config
  ];
  buildInputs = [
    # add desired native packages
    # ...
  ];
}
}
</syntaxHighlight>
</syntaxHighlight>
Line 30: Line 74:
<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; [
Line 37: Line 87:
       rustup
       rustup
     ];
     ];
     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 ];
Line 48: Line 98:
       # add libraries here (e.g. pkgs.libvmi)
       # add libraries here (e.g. pkgs.libvmi)
     ]);
     ]);
    LD_LIBRARY_PATH = libPath;
     # Add glibc, clang, glib, and other headers to bindgen search path
     # Add glibc, clang, glib, and other headers to bindgen search path
     BINDGEN_EXTRA_CLANG_ARGS =  
     BINDGEN_EXTRA_CLANG_ARGS =
     # Includes normal include path
     # Includes normal include path
     (builtins.map (a: ''-I"${a}/include"'') [
     (builtins.map (a: ''-I"${a}/include"'') [
       # add dev libraries here (e.g. pkgs.libvmi.dev)
       # 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 61: Line 112:
       ''-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 90: Line 144:


# https://github.com/cachix/devenv/blob/main/examples/rust/devenv.nix and <code>devenv shell</code>
# 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 176: Line 225:
| Inspired by naersk, with [https://discourse.nixos.org/t/introducing-crane-composable-and-cacheable-builds-with-cargo/17275/4 better support for composing Cargo invocations as completely separate derivations]
| Inspired by naersk, with [https://discourse.nixos.org/t/introducing-crane-composable-and-cacheable-builds-with-cargo/17275/4 better support for composing Cargo invocations as completely separate derivations]
|-
|-
| [https://github.com/nix-community/dream2nix/blob/main/docs/src/subsystems/rust.md <code>dream2nix</code>]
| [https://dream2nix.dev/reference/rust-crane <code>dream2nix</code>]
| Codegen
| Codegen
| 1 or 2
| 1 or 2
| cargo (via <code>buildRustPackage</code> or <code>crane</code>)
| cargo (via <code>buildRustPackage</code> or <code>crane</code>)
| Yes
| Yes
| A framework for unifying 2nix converters across languages
| A framework for unifying 2nix converters across languages (Experimental)
|}
|}


Line 241: Line 290:


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 291: Line 314:
</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">