Rust
What do I need for a basic environment?
First we'll show you the answer, and then we'll explain.
A manifest that provides you a Rust development environment would look like this:
version = 1
[install]
# Rust toolchain
cargo.pkg-path = "cargo"
cargo.pkg-group = "rust-toolchain"
rustc.pkg-path = "rustc"
rustc.pkg-group = "rust-toolchain"
clippy.pkg-path = "clippy"
clippy.pkg-group = "rust-toolchain"
rustfmt.pkg-path = "rustfmt"
rustfmt.pkg-group = "rust-toolchain"
rust-lib-src.pkg-path = "rustPlatform.rustLibSrc"
rust-lib-src.pkg-group = "rust-toolchain"
libiconv.pkg-path = "libiconv"
libiconv.systems = ["aarch64-darwin", "x86_64-darwin"]
# rust-analyzer goes in its own group because it's updated
# on a different cadence from the compiler and doesn't need
# to match versions
rust-analyzer.pkg-path = "rust-analyzer"
rust-analyzer.pkg-group = "rust-analyzer"
# Linker
gcc.pkg-path = "gcc"
gcc.systems = ["aarch64-linux", "x86_64-linux"]
clang.pkg-path = "clang"
clang.systems = ["aarch64-darwin", "x86_64-darwin"]
[vars]
[hook]
[profile]
[options]
systems = ["aarch64-darwin", "x86_64-darwin", "aarch64-linux", "x86_64-linux"]
The typical Rust developer probably uses rustup to manage their
toolchains.
Flox aims to be an all-in-one solution, so you'll use Flox instead of rustup
.
The main difference here is that the toolchain components are unbundled in
Flox,
so you'll need to install cargo
and rustc
as independent packages.
Some common packages you'll want to install are:
cargo
rustc
rustfmt
clippy
gcc
on Linux,clang
on macOSlibiconv
on macOSrustPlatform.rustLibSrc
rust-analyzer
Let's explain some of those packages.
cargo
is self-explanatory, it's the default build tool for Rust.
However, all Flox packages automatically install all of their dependencies,
so cargo
also installs rustc
on its own.
If that's the case, why do we need a rustc
package?
The short answer is build scripts (build.rs
files).
One of the ways that Flox makes environments deterministic and reproducible
is that packages don't expose their dependencies to PATH
,
so cargo
doesn't expose its rustc
to PATH
.
This is fine in most cases since you often don't need to call rustc
yourself,
but this becomes an issue for crates that contain build.rs
build scripts that
manually invoke rustc
.
However, even if your crate doesn't have a build.rs
,
it is very common for a transitive dependency to need to link to system
libraries such as openssl
.
This is why we install a separate rustc
package.
You may also find that you need to install a pkg-config
package if some
system libraries aren't found.
Build scripts are also why we install the gcc
or clang
package:
build scripts often call out to linkers in addition to rustc
.
The libiconv
package is necessary on macOS because the Rust standard library
links against it on macOS.
The rustPlatform.rustLibSrc
provides the source code for std
so that
rust-analyzer
can provide diagnostics and documentation for standard library
code.
As a final step, you want to make sure that your Rust toolchain componenents
share the same exact versions of their dependencies,
so you'll want to add them to a package group
(rust-toolchain
in the example above).
How do I use nightly compilers?
Nightly compilers aren't currently packaged in the Flox Catalog.
If you need to use nightly compilers,
you can use our Nix flake support to prepare a flake that provides a nightly
compiler.
You would need to prepare that flake, call it github:rust-dev/my-nightly
,
and add it to the manifest as a flake package:
Popular projects used by the Nix community for this purpose are:
Add the target
directory to PATH
If you're developing a binary instead of a library,
you may find it useful to add the target/debug
or target/release
directories to your PATH
for interactive testing.
That is very simple to do with the hook.on-activate
section of the manifest:
Now if you were developing a binary called mybin
,
you could call it directly instead of via target/debug/mybin
,
and it will automatically be kept up to date on every cargo build
.
Add cargo
aliases
The [profile]
section allows you to add aliases to your development shell
that are available after activating your environment.
If you currently use make
, just
, or a .cargo/config.toml
file to set
provide simple aliaes in your development environment,
you may be able to remove those dependencies and just use the Flox manifest
instead: