Inheriting nixpkgs configuration in flakes

While writing this I discovered I was mostly reinventing the wheel of @zimbatm’s nixpkgs-unfree, but I think discussing the essence of the technique might be useful for others.

Recently, my team has been using flakes to package individual python libraries for re-use. One difficulty we encountered it that if we enable cudaSupport in nixpkgs, there wasn’t an easy way to propagate that to our dependencies. Using inputs.<a>.inputs.nixpkgs.follows would bring in the unconfigured nixpkgs. So a dependency might bring in pytorch without cuda enabled, but the toplevel flake might request it with cuda, the two versions would conflict and the build would fail.

To work-around this we came up with small hack. We set up a small flake to pull in nixpkgs, reimport with our config, and re-export it in a format that works for our dependencies as the legacyPackages output of the flake. It looks like this

{
  description = "Flake for nixpkgs with GPU stuff set up";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-24.11";
  };

  outputs =  { self, nixpkgs,
    }:
    let
      pkgs = import nixpkgs {
        system = "x86_64-linux";
        config = {  cudaSupport = true;  };
    in {
      legacyPackages.x86_64-linux = pkgs;
   };
}

additional config can be added as well such as allowUnfree or cudaCapabilities.

The nice part of this approach is that this flake can follow nixpkgs from the top-level flake, where dependencies can follow this flake, so the the top-level flake can still handle version pinning.

A dependent project flake would look like:

{
  description = "A GPU project";
  inputs = {
     nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-24.11";
     nixpkgs-gpu.url = "github:<our>/<repo-for-this>";
     nixpkgs-gpu.inputs.nixpkgs.follows = "nixpkgs";
     another-dep = "github:<our>/<package-repo>";
     another-dep.inputs.nixpkgs.follows = "nixpkgs-gpu";
  };
  outputs = { self, nixpkgs, nixpkgs-gpu, another-dep }:
     let  pkgs = nixpkgs-gpu.legacyPackages.x86_64-linux; in
     {
      ....
     };
}

This strategy doesn’t work if the other dependencies try to import nixpkgs but that is not recommended any longer anyway (nixpkgs-unfree has solved this)

If you’re in a situation like we were, using nixpkgs-unfree directly, or forking it so you can make your own configuration changes is probably superior to the approach we used.

4 Likes

for readers: this should be nixos-24.11

oops, fixed, thanks!

Ah I actually only noticed it on the second example