Like this:
<attr>.<system> -> packages.<system>.<attr>
?
Is there something in flake-utils
that does that? Or puts it there in the first place? It seems irksome to have to treat the two so differently.
Like this:
<attr>.<system> -> packages.<system>.<attr>
?
Is there something in flake-utils
that does that? Or puts it there in the first place? It seems irksome to have to treat the two so differently.
flake-utils.eachDefaultSystem
should do that for you.
And it is packages.${system}.${name}
, such that you can do nix build .#$name
.
All the functions in flake-utils
that iterate over a list of systems, do exactly that, they will add the “current” system as second layer in the attributes of the attribute set you returned from the function.
and use
nix (build|run|shell|...) <flake>#<package>
forpackages.${system}.<package>
.
… maybe I’m being dense, but isn’t that exactly what I was originally trying to do here:
- The following fail with equivalent error messages:
flake output attribute 'defaultPackage(-etc) is not a derivation
nix build .#defaultPackage
nix build .#defaultPackage-but-with-different-attribute-name
… or do you mean something else?
flake-utils.eachDefaultSystem
should do that for you.
… which is exactly what I was using already …
If you want to build an unknown top-level attribute, then it has to be a derivation directly.
If you move it to packages.${system}
, then you can use it with infering of the system from the CLI.
Yes, but without packages
, perhaps do not use flake-utils
until you understood how the flake actually should look like, with hard coded systems in the attribute pathes.
IIUC the answer seems to be that the code sample I provided originally (with the non-defaultPackage name shortened for convenience):
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; in { defaultPackage = pkgs.stdenv.mkDerivation { name = "whatever"; # THE DERIVATION BODY }; NOT-defaultPackage = pkgs.stdenv.mkDerivation { name = "whatever"; # *IDENTICAL* COPYPASTA of THE DERIVATION BODY above }; });
should be modified thus:
- NOT-defaultPackage = pkgs.stdenv.mkDerivation {
+packages.NOT-defaultPackage = pkgs.stdenv.mkDerivation {
After this change
nix build .#NOT-defaultPackage
works sensibly, and
nix flake show
gives
├───defaultPackage
│ ├───aarch64-linux: package 'whatever'
│ ├───i686-linux: package 'whatever'
│ ├───x86_64-darwin: package 'whatever'
│ └───x86_64-linux: package 'whatever'
└───packages
├───aarch64-linux
│ └───NOT-defaultPackage: package 'whatever'
├───i686-linux
│ └───NOT-defaultPackage: package 'whatever'
├───x86_64-darwin
│ └───NOT-defaultPackage: package 'whatever'
└───x86_64-linux
└───NOT-defaultPackage: package 'whatever'
(I wonder whether I’ll learn to appreciate this special-case/inconsistency in the long run. Right now it’s just a PITA!)
This is not an inconsistency.
Any of the non-well known output attributes as described in the wiki linked above, have to be directly buildable derivations. At least if you want to use them as “packages”.
Though this is exactly the reason why you should use packages
instead, as there the flake system knows how to resolve in the context of the current system.
Also the recommended way of using defaultPackage
is more like this:
{
outputs = { self, nixpkgs }: {
packages."x86_64-linux".hello = nixpkgs.legacyPackages."x86_64-system".hello;
defaultPackage."x86_64-linux" = self.packages."x86_64-linux".hello;
};
}
The presence of a hidden (starting with dot) file whose name matches the name of a package in the flake in the current directory, breaks nix {shell,build} .#the-package
.
Demo: I have a flake containing a package called aaa-and-bbb
which contains an executable aaa
which prints out This is program AAA.
$ pwd
/tmp/aaaaaargh
$ nix shell .#aaa-and-bbb -c aaa
This is program AAA.
$ touch .aaa-and-bbb
$ nix shell .#aaa-and-bbb -c aaa
error: --- BadURL -------------------------------------------------------------- nix
path '/tmp/aaaaaargh/.aaa-and-bbb' is not a flake (because it's not a directory)
In other words, nix .#aaa-and-bbb -c aaa
works fine, unless the file ./.aaa-and-bbb
exists.
No problems here…
$ nix shell .#flux2 -c flux --version
flux version 0.8.0
$ touch .flux2
$ nix shell .#flux2 -c flux --version
flux version 0.8.0
Perhaps some bash
vs zsh
thing?
It may depend on configuration, but for me, in zsh also without the hidden file it doesn’t work:
$ nix run .#hello
zsh: no matches found: .#hello
$ touch .hello
$ nix run .#hello
error: --- BadURL ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
path '/home/johannes/testflake/.hello' is not a flake (because it's not a directory)
Basically, in zsh you have to escape the hash:
$ touch .hello
$ nix run .\#hello
Hello, world!
$ nix run '.#hello'
Hello, world!
I never had to escape the #
sign. Not sure why…
I’m on nix (Nix) 2.4pre20201201_5a6ddb3
and zsh 5.8 (x86_64-pc-linux-gnu)
.
The octothorpe only has special meaning in zsh with EXTENDED_GLOB
set, requiring either the escape or quotes for flake refs. Of course, I’ve been using zsh so long now, it took me a while to realize this wasn’t the case in bash.
I had the issue with zsh which force me to escape the #
but thanks to your comment @nrdxp I found out that setting this in my .zshrc
fix problem:
setopt no_extendedglob
Thanks!