Using a nix flake in a flake (e.g. buildInputs)

Hi, I somehow cannot figure how to use / access a dependency in a flake.

Consider a simple hello world flake, defined as, and available at https://github.com/sbellem/hello-flake:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system};
      in {
        packages.hello = pkgs.hello;
        defaultPackage = pkgs.hello;

        devShell = pkgs.mkShell { buildInputs = [ pkgs.hello pkgs.cowsay ]; };
      });
}

Now, invoking the hello program with nix shell or nix develop as in the following works.

nix develop github:sbellem/hello-flake -c hello

But trying to use it in a flake such as the following does not work …

{
  description = "hello hello world";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.hello-flake.url = "github:sbellem/hello-flake";

  outputs = { self, nixpkgs, flake-utils, hello-flake }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
      in {
        devShell = pkgs.mkShell {
          buildInputs = [
            hello-flake
          ];
        };
      }
    );
}

What am I doing wrong?

Does this work?

          buildInputs = [
            hello-flake.defaultPackage.x86_64-linux
          ];
1 Like

Flakes are really picking up, we get this question in slightly different forms almost every day now - also probably means we need better documentation for this exact thing, or work out the ergonomics a bit better :slight_smile:

@mackenzie suggestion should work, and you can even do this with flake-utils:

          buildInputs = [
            hello-flake.defaultPackage.${system}
          ];

The cleaner approach that doesn’t rely on your config being entirely in flake.nix is using module._args or an overlay, see this related thread: Install agenix in "environment.systemPackages" on nixos with flakes

For devshells overlays are definitely more ergonomic.

2 Likes

Thanks! Yes that works!

Thanks! That’s helpful! Yeah, flakes are cool!

I added some notes on the toy project: GitHub - sbellem/hello-flake.

I tried adding an overlay, but struggling with

error: All overlays passed to nixpkgs must be functions

I somehow thought that for instance, this would work:

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system};
      in {
        # ...

        # to use as an overlay
        overlay = final: prev: {
          boost = prev.boost.override {
            python = final.python3;
          };
          rr = prev.callPackage ./pkgs/rr {
            stdenv = final.stdenv_32bit;
          };
        };
      }
    );

I’ve looked at the agenix code, and followed their structure, but still got the same error. If you have any pointers to other examples, or documentation on writing an overlay for a flake, that would be great.

Overlays are not bound by system, you need to move it out of the eachDefaultSystem call:

(flake-utils.lib.eachDefaultSystem (system:
  # …
}) // {
  overlay = final: prev: {
    # …
  };
}
2 Likes

Ah, great! That works! Thanks!