Hi there,
I have a simple piece of rust code that I want to write a flake for. The flake contains three interesting outputs: a devShell, a package and an overlay containing said package. My project is very standard, built using the rustPlatform.buildRustPackage
function, but I want to use the excellent oxalica/rust-overlay
to have more control over the version of rustc
and cargo
that are used to develop and build my package (for the sake of readability, here we will assume the latest stable).
I am trying to follow the advice from 1000 instance of nixpkgs and avoid creating a new instance of nixpkgs when used as a dependency (I have no such qualms in e.g. the devShell).
This has brought me to write the following code for the overlay (full flake code at the end of the post):
{
overlay = final: prev: with final;
let pkgs = prev.appendOverlays [ (import rust-overlay) ];
in {
hello-world =
(prev.makeRustPlatform {
cargo = pkgs.rust-bin.stable.latest.minimal;
rustc = pkgs.rust-bin.stable.latest.minimal;
}).buildRustPackage {
inherit name version;
cargoLock.lockFile = ./Cargo.lock;
buildInputs = [ openssl ];
nativeBuildInputs = [ pkg-config ];
};
};
I have also read this discourse thread, which points out that, regarding the appendOverlays
function, the nixpkgs manual states that “it is often preferable to avoid these functions, because they recompute the Nixpkgs fixpoint, which is somewhat expensive to do.”.
This leaves me a bit stymied as to the proper way to go forward: I would like to write a flake that exposes my application to other users through an overlay and as a package, using the oxalica/rust-overlay
to control the rust toolchain, and without neither importing nixpkgs or using appendOverlays
. With my current nix{,pkgs} knowledge, this seems impossible.
-
Would the problem be solved if there was a non-overlay way of controlling the rust toolchain (say foo-project), similar to oxalica’s work but where I could write something like
foo-project.packages.rust-bin.stable.latest...
? Does such a project exist ? -
Currently, I write the code building the package in the overlay and then use the following line for exposing a package:
packages = forAllSystems (pkgs: pkgs.lib.getAttrs [ "hello-world" ] pkgs);
where forAllSystems (also used in the devShells definition) is defined as:
let forAllSystems = f: nixpkgs.lib.genAttrs (import systems) (
system: f (
import nixpkgs {
inherit system;
overlays = [ self.overlay (import rust-overlay) ];
}));
in ....
would abandoning the idea of providing users with an overlay and directly writing the package here help in anyway ? I don’t see how I could avoid creating an instance of nixpkgs, since I need to apply the rust-overlay anyway, but maybe there is something I haven’t thought of ?
Thank you for any help or insights on the leanest way to provide a flake for consumers of my application