After quiet some time of contributing packages and fixes to Nixpkgs, I came to the conclusion that multiple outputs are not implemented good enough. I’d like to hear some opinions / experiences around this. Here’s my own:
I once tried to package a library which installs cmake files, headers and shared objects. The cmake files referenced the full paths of the headers and the shared objects. From the library’s
Makefile's prespective, it installs everything to the prefix (
$out). However, if you set
outputs, after all the files are installed, we move the headers to
$dev and the libraries to
$lib etc at the
How could our package know that it actually installs it’s files to different prefixes? I’m just curios what was the expectation out of this idea.
When I tried to use that library with the outputs split, and use it as a dependency for another package, I found out that the package didn’t find the cmake files of the library which are found at
$out/share/<lib-name>/cmake and not as expected by
multi-outputs.sh - in
$out/lib/cmake. Even when I managed to tell the package where exactly to find the library’s cmake files, the build still failed because the cmake files pointed to where the headers were originally installed - to the original
$out and not to
Today, I tried to improve a little bit a closure size issue of a package that splits outputs and I got hit by this error which I can’t even explain.
What’s adding to the frustration, is that it’s hard to debug these shell errors because they happen at the end of the build and you have no idea what shell function exactly failed - there’s no context to the errors.
If I were to design this feature for our ecosystem from the ground up, I would do this:
- Set the same value for
$libetc for all packages.
- Teach Nix itself, to distinguish between outputs - for example:
$out/includeshould be downloaded only if you want to build something with this library.
$out/share/manshould be downloaded only if you use this package directly.
- Make Nix itself, download only needed files from cache.nixos.org according to the context of the request:
- If it’s
nixos-rebuildthen download only the actually needed outputs.
- if it’s
nix-shell, download everything unless told otherwise.
- If it’s
I believe we can reach closure size decreases we have never dreamed of with this approach.
Is there an implementation problem I’m not seeing here?