Nixify your Rust projects today with cargo2nix
,
bringing you reproducible builds and better caching.
This repository hosts two components:
-
A Nixpkgs overlay, located at the
/overlay
directory, providing utilities to build your Cargo workspace and set up airplane mode. -
A utility written in Rust to generate version pins of crate dependencies.
Together, these components will take an existing Cargo.lock
and delegate the process of fetching and combining your dependencies (generated by Cargo) using the deterministic Nix package manager.
- Install the Nix package manager on your *nix machine.
- Run the command below to build the
cargo2nix
utility:
# For Linux users
nix-build -A package
# For macOS/Darwin users
nix-build -A package --arg crossSystem null
-
Generate version pins to
Cargo.nix
by runningcargo2nix > Cargo.nix
at the root of your cargo workspace. -
Use
default.nix
in this repository as an example, select the package you want to build and set up required build-time/run-time dependencies.
As an example, cargo2nix
can be built from package.unknown.cargo2nix."0.1.0"
in the generated package set rustPackages
.
Note: The naming convention behind
package.unknown.cargo2nix."0.1.0"
is
package.<registry>.<crate>.<version>
...where unknown
is currently a placeholder for anything that does not come from the crates.io registry
You can optionally use any of these crate derivation as your nix-shell
development shell.
The advantage of this shell is that in this environment users can develop their
crates and be sure that their crates builds in the same way that cargo2nix
overlay will build them.
To do this, run nix-shell -A 'package.<package-id-attrset-path>'
.
For instance, the following command being invoked in this repository root drops
you into such a development shell.
nix-shell -A 'package.unknown.cargo2nix."0.1.0"'
You will need to bootstrap some environment in this declarative development shell first.
runHook configureCargo # this overrides your .cargo folder for setting cross-compilers, for example
runHook setBuildEnv # this sets up linker flags for the `rustc` invocations
You will need to override your Cargo.toml
and Cargo.lock
in this shell,
so make sure that you have them backed up beforehand.
runHook overrideCargoManifest
Now you can use your favorite editor in this environment.
To run build command used by cargo2nix
, use
runHook runCargo
Note: This functionality is currently not working in version 0.4. Revert back to version 0.3 if you need it.
Going flying next morning and planning to code Rust to kill your boredom for the
next 12 hours?
Airplane mode allows you to work offline as long as you have checked in the
crates-io
dependencies into Nix store.
The shell
derivation in default.nix
is a sample derivation that enables
airplane mode for your cargo
.
To enter airplane mode, run the following command.
nix-shell -A shell --fallback --option substitute false
Then execute vendor_source
command in the shell to install source replacement
for the crates-io
public crates.
- Many
crates.io
public crates may not build using the current Rust compiler, unless a lint cap is put on these crates. For instance,cargo2nix
caps all warnings in thefailure
crate to justwarn
.
This Nixpkgs overlay builds your Rust crates and binaries by first pulling the
dependencies apart, building them individually as separate Nix derivations and
linking them together.
This is achieved by basically passing linker flags to the cargo
invocations
and the underlying rustc
/rustdoc
invocations.
The overlay is built on top of the work by James Kay. In addition, this overlay also takes cross-compilation into account and build the crates onto the correct host platform configurations with the correct platform-dependent feature flags specified in the Cargo manifests and build-time dependencies.
This Nix overlay is inspired by the excellent work done by James Kay, which is described here and here. His source is available here. This work is impossible without these fantastic write-ups. Special thanks to James Kay!