Rust: Difference between revisions
Make everything more cross-compatible |
m Update that buildRustPackage can now import Cargo.lock |
||
| (16 intermediate revisions by 11 users not shown) | |||
| Line 12: | Line 12: | ||
Here's an example <code>shell.nix</code>: | Here's an example <code>shell.nix</code>: | ||
< | <syntaxhighlight lang="nix"> | ||
let | let | ||
# Pinned nixpkgs, deterministic. Last updated: 2/12/21. | # Pinned nixpkgs, deterministic. Last updated: 2/12/21. | ||
| Line 27: | Line 27: | ||
}: | }: | ||
mkShell { | mkShell { | ||
strictDeps = true; | |||
nativeBuildInputs = [ | nativeBuildInputs = [ | ||
cargo | cargo | ||
| Line 33: | Line 34: | ||
} | } | ||
) { } | ) { } | ||
</ | </syntaxhighlight> | ||
== Installating with bindgen support == | == Installating with bindgen support == | ||
By default crates using <code>bindgen</code> will not compile. To add | By default crates using <code>bindgen</code> will not compile. To add bindgen support add the <code>rustPlatform.bindgenHook</code> to your <code>nativeBuildInputs</code>. | ||
Here's an example <code>shell.nix</code>: | Here's an example <code>shell.nix</code>: | ||
< | <syntaxhighlight lang="nix"> | ||
{ | { | ||
pkgs ? import <nixpkgs> { }, | pkgs ? import <nixpkgs> { }, | ||
| Line 53: | Line 54: | ||
}: | }: | ||
mkShell { | mkShell { | ||
strictDeps = true; | |||
nativeBuildInputs = [ | nativeBuildInputs = [ | ||
cargo | cargo | ||
| Line 67: | Line 69: | ||
} | } | ||
) { } | ) { } | ||
</ | </syntaxhighlight> | ||
This also works, when compiling rust crates: | This also works, when compiling rust crates: | ||
| Line 94: | Line 96: | ||
If you want 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"> | ||
{ pkgs ? import <nixpkgs> {} }: | { | ||
pkgs ? import <nixpkgs> { }, | |||
}: | |||
let | |||
overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml)); | |||
in | in | ||
pkgs.callPackage ( | |||
{ | |||
stdenv, | |||
mkShell, | |||
rustup, | |||
rustPlatform, | |||
}: | |||
mkShell { | |||
strictDeps = true; | |||
nativeBuildInputs = [ | |||
rustup | rustup | ||
rustPlatform.bindgenHook | |||
]; | ]; | ||
# libraries here | |||
buildInputs = | |||
[ | |||
]; | |||
RUSTC_VERSION = overrides.toolchain.channel; | RUSTC_VERSION = overrides.toolchain.channel; | ||
# https://github.com/rust-lang/rust-bindgen#environment-variables | # https://github.com/rust-lang/rust-bindgen#environment-variables | ||
shellHook = '' | shellHook = '' | ||
export PATH= | export PATH="''${CARGO_HOME:-~/.cargo}/bin":"$PATH" | ||
export PATH= | export PATH="''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-${stdenv.hostPlatform.rust.rustcTarget}/bin":"$PATH" | ||
''; | |||
} | } | ||
</ | ) { } | ||
</syntaxhighlight> | |||
It's important to have a file named <code>rust-toolchain.toml</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. | ||
| Line 147: | Line 141: | ||
# or nightly-20XX-XX-XX for a specific nightly. | # or nightly-20XX-XX-XX for a specific nightly. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Cross-compiling == | == Cross-compiling == | ||
| Line 156: | Line 148: | ||
* [https://github.com/jraygauthier/jrg-rust-cross-experiment/tree/master/simple-static-rustup-target-windows simple-static-rustup-target-windows] | * [https://github.com/jraygauthier/jrg-rust-cross-experiment/tree/master/simple-static-rustup-target-windows simple-static-rustup-target-windows] | ||
** [https://github.com/jraygauthier/jrg-rust-cross-experiment/blob/master/simple-static-rustup-target-windows/shell.nix shell.nix] | ** [https://github.com/jraygauthier/jrg-rust-cross-experiment/blob/master/simple-static-rustup-target-windows/shell.nix shell.nix] | ||
=== To Windows via a cargo plugin: === | |||
* use [https://crates.io/crates/cargo-xwin cargo-xwin] with rustup install or the [https://search.nixos.org/packages?show=cargo-xwin&type=packages&query=cargo+windows nix cargo plugin] | |||
* run cargo commands prefixed by xwin, e.g. <code>cargo xwin run --target x86_64-pc-windows-msvc</code> | |||
== Unofficial overlays == | == Unofficial overlays == | ||
| Line 171: | Line 168: | ||
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://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 | [https://web.archive.org/web/20260108165619/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 == | ||
There are two ways to use <code>overrideAttrs</code> with Rust packages: | |||
[ | * Using [[Import From Derivation]]: | ||
<p> | |||
== | <syntaxhighlight lang="nix"> | ||
nil = pkgs.nil.overrideAttrs ( | |||
finalAttrs: previousAttrs: { | |||
version = "unstable-2024-09-19"; | |||
< | |||
src = pkgs.fetchFromGitHub { | |||
owner = "oxalica"; | |||
repo = "nil"; | |||
rev = "c8e8ce72442a164d89d3fdeaae0bcc405f8c015a"; | |||
hash = "sha256-mIuOP4I51eFLquRaxMKx67pHmhatZrcVPjfHL98v/M8="; | |||
}; | |||
} | |||
}) | # Requires IFD | ||
cargoDeps = pkgs.rustPlatform.importCargoLock { | |||
</ | lockFile = finalAttrs.src + "/Cargo.lock"; | ||
allowBuiltinFetchGit = true; | |||
}; | |||
cargoHash = null; | |||
} | |||
); | |||
</syntaxhighlight> | |||
</p> | |||
* Overriding <code>cargoDeps</code>: | |||
<p> | |||
<syntaxhighlight lang="nix"> | |||
nil = pkgs.nil.overrideAttrs ( | |||
finalAttrs: previousAttrs: { | |||
version = "unstable-2024-09-19"; | |||
src = pkgs.fetchFromGitHub { | |||
owner = "oxalica"; | |||
repo = "nil"; | |||
rev = "c8e8ce72442a164d89d3fdeaae0bcc405f8c015a"; | |||
hash = "sha256-mIuOP4I51eFLquRaxMKx67pHmhatZrcVPjfHL98v/M8="; | |||
}; | |||
# Doesn't require IFD | |||
cargoDeps = previousAttrs.cargoDeps.overrideAttrs { | |||
name = "nil-vendor.tar.gz"; | |||
inherit (finalAttrs) src; | |||
#outputHash = pkgs.lib.fakeHash; | |||
outputHash = "sha256-RWgknkeGNfP2wH1X6nc+b10Qg1QX3UeewDdeWG0RIE8="; | |||
#}; | |||
} | |||
); | |||
</syntaxhighlight> | |||
</p> | |||
== Packaging Rust projects with nix == | == Packaging Rust projects with nix == | ||
| Line 197: | Line 227: | ||
At the time of writing, there are now no less than 8 different solutions for building Rust code with Nix. In the following table they are compared: | At the time of writing, there are now no less than 8 different solutions for building Rust code with Nix. In the following table they are compared: | ||
{| | {| class="wikitable" style="margin:auto" | ||
|- | |- | ||
| [https://github.com/NixOS/nixpkgs/blob/ | ! Name !! Cargo.lock solution !! Derivations !! Build logic !! Supports cross !! Notes | ||
| Checksum | |- | ||
| <code>[https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/rust.section.md buildRustPackage]</code> | |||
| Checksum or <code>[https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/rust.section.md#importing-a-cargolock-file-importing-a-cargolock-file Import]</code> | |||
| 1 | | 1 | ||
| cargo | | cargo | ||
| Line 263: | Line 289: | ||
== Shell.nix example == | == Shell.nix example == | ||
< | <syntaxhighlight lang="nix"> | ||
{ | { | ||
pkgs ? import <nixpkgs> { }, | pkgs ? import <nixpkgs> { }, | ||
| Line 279: | Line 305: | ||
}: | }: | ||
mkShell { | mkShell { | ||
strictDeps = true; | |||
nativeBuildInputs = [ | nativeBuildInputs = [ | ||
rustc | rustc | ||
| Line 294: | Line 321: | ||
} | } | ||
) { } | ) { } | ||
</ | </syntaxhighlight> | ||
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. | This will have the stable Rust compiler + the official formatter and linter inside the ephemeral shell. It'll also set the <code>RUST_SRC_PATH</code> environment variable to point to the right location, which tools, such as rust-analyzer, require to be set. | ||
=== Custom Rust version or targets === | === Custom Rust version or targets === | ||
| Line 332: | Line 359: | ||
}: | }: | ||
mkShell { | mkShell { | ||
strictDeps = true; | |||
# host/target agnostic programs | # host/target agnostic programs | ||
depsBuildBuild = [ | depsBuildBuild = [ | ||
| Line 351: | Line 379: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== | === VS Code integration === | ||
The [https://marketplace.visualstudio.com/items?itemName=rust-lang.rust rust- | The [https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer rust-analyzer] VS Code extension offers Rust support. | ||
If you get the error <code>can't load standard library, try installing rust-src</code>, either configure <code>RUST_SRC_PATH</code> as shown above, or set <code>"rust-analyzer.server.path": "rust-analyzer"</code> in your VS Code settings to use rust-analyzer from nixpkgs rather than the one bundled with the extension. | |||
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. | ||
| Line 377: | Line 407: | ||
}: | }: | ||
mkShell { | mkShell { | ||
strictDeps = true; | |||
nativeBuildInputs = [ | nativeBuildInputs = [ | ||
my-rust-toolchain | my-rust-toolchain | ||
| Line 446: | Line 477: | ||
[[Category:Languages]] | [[Category:Languages]] | ||
[[Category:Rust]] | |||