Flakes referencing other flakes

I’m experimenting with flakes. I created an initial flake in repository “arcan”. I then referenced it in another project’s flake like shown below:

{
  description = "TODO(akavel)";

  inputs = {
    arcan.url = "github:akavel/arcan/nix0.02";
  };

  outputs = { self, nixpkgs, arcan }: {

    defaultPackage.x86_64-linux = self.packages.x86_64-linux.foobar;

    packages.x86_64-linux.foobar =
      with import nixpkgs { system = "x86_64-linux"; };
      stdenv.mkDerivation {
        name = "foobar";
        version = "0.0.1";
        src = ./foobar;
        nativeBuildInputs = with pkgs; [
          meson pkg-config ninja
        ];
        buildInputs = with pkgs; [
          arcan.defaultPackage.x86_64-linux
        ];
      };

  };
}

Notably, it took me a while to discover that I have to reference the first derivation as arcan.defaultPackage.x86_64-linux instead of just as arcan. The simple arcan reference seems to only resolve to a directory containing the github sources (i.e. /nix/store/.....-source). That is what shows up in arcan.outPath as well. Is it normal and expected? Is there some shorter and more intuitive way to do that? Or am I doing something wrong somewhere?

TIA!

1 Like

As far as I understand, basically the arcan input in your example will contain the result of evaluating the outputs function of the arcan flake (and it works this way for every flake), with the additional property that if you try to use it as a string, a flake will evaluate to a path containing the contents of the repository that contains the flake.

The reason that you have to specifically use arcan.defaultPackage.x86_64-linux, rather than just arcan, is actually quite useful, because for some flakes you do not want to use the defaultPackage it provides for some system, but you may want to use some of its other outputs. Take for example flake-utils, which doesn’t even provide a derivation to build, only a set of functions.

Also, flakes are supposed to be reproducible (or close to it) so that’s why you have to pass a specific system to build for.

The defaultPackage.${system} output is used by nix build when you don’t pass a specific attribute of outputs.packages to build.

So all in all, the way you’re using the flake seems perfectly fine to me :slight_smile:

Ok, thanks! :heart:

Honestly, I was expecting arcan when used as string to evaulate to arcan.defaultPackage.${system} — due to ergonomy, and with a sincere expectation that this is what I’ll be doing some 98% of the time probably. Having to do that repeatedly by hand has me quite surprised. I always like to think computers were created to automate onerous tasks for people :smile: As to sources, I would imagine something like arcan.source or arcan.src to evaluate to them. Also isn’t this basically how “classic nix” worked?

As to flake-utils, I’d imagine there could be way to make the .lib attribute be the default one — or alternatively, it could be invalid to try evaluating flake-utils alone as string.

It’s quite common to use something like let fooPkgs = foo.packages.${system}; in ...

That could be said to support the question whether the current default is the more useful one :smile: