Hey all,
Customary note: Discovered and started playing with nix since a few days - noob alert!
What is the fundamental difference between building of a “buildInputs” vs building of a package directly? More specifically, why can’t I see man entries for buildInputs
but I can see them if I installed them directly?
E.g (assume I’ve man-db
installed in the system already)
nix profile install nixpkgs#feh
man feh # Works, the man pages for feh are brought in by the installation above
however:
# flake.nix
{
outputs = { self, nixpkgs }:
let
n = nixpkgs.legacyPackages."aarch64-linux";
in
{
packages."aarch64-linux".default = n.stdenv.mkDerivation {
buildInputs = [ p.feh ];
...
};
};
}
# Now run:
nix profile install .
# I can see /nix/store/<hash>-feh/bin/feh just like before but this time
# it's minimalistic and there are no man pages for it for e.g. in nix store anywhere.
Is there something I can do to ensure the installation of dependencies (or buildInputs
) is as complete as if it were being directly installed (with man pages and all the glitters)?
FWIW, this too compiles in the man pages:
# flake.nix
{
outputs = { self, nixpkgs }:
let
n = nixpkgs.legacyPackages."aarch64-linux";
in
{
packages."aarch64-linux".default = n.feh;
};
}
# Now run:
nix profile install .
# I can see the man pages brought in too in /nix/store/
How can I get this behaviour for dependencies specified in the buildInputs
too?
Eh after staring at and comparing the derivations of various packages, I think I understand what’s happening.
So some packages like nixpkgs#maim
for e.g don’t have outputs
attribute supplied to their mkDerivation
function and dump everything in just one place in the nix store /nix/store/<hash>-maim/{bin,share,...etc}
and for those the man pages are indeed built even if maim
was in buildInputs
for some other package.
However some others like nixpkgs#feh
for e.g. have outputs = [ "out" "man" "doc" ];
etc and for those the only thing that gets generated due to them being present in buildInputs
of some other flake is whatever is in their out
output, whereas if you did nix profile install
then all the outputs get dumped into /nix/store/...
under various paths suffixed with the corresponding output (except for out
which doesn’t have a suffix).
That’s why the man pages for feh
as a value in buildInputs
of some other flake’s mkDerivation
was not being put in /nix/store/<hash>-feh-man
.
OK now that I’ve spent an hour getting to the bottom of this, I suppose my next step will be to find out how to make a nixpkgs#foo
given as buildInputs
of some other flake.nix’s mkDerivation
dump all its outputs
and not just its out
path in the nix-store. Probably a new question but I’ll leave it here before creating a new post in-case someone knows this off the top of their head.
I think your problem is that while nix downloads buildInputs, it usually doesn’t expose them. They will be there, but without set changing the PATH. (that is not true for all packages).
Like:
- interpret your nix file
- download the source of your package (sometimes is in the same dir)
- download the nix files of your dependencies (usually nixpkgs or other inputs)
- build the dependencies
- copy your dependencies to /nix/store/
- build your package (hard coding the /nix/store/ of dependencies)
- copy your package build outputs¹ to /nix/store/
- configure your profile (environment) to know the path of your package (not of dependencies).
Sometimes it only requires the bin
output so it doesn’t keep the others (man, docs, dev).
¹ That is confusing, flakes has “outputs” (packages, nixos configs, etc) but they aren’t your package ‘outputs’ (out, bin, dev, doc, etc).
Flakes outputs ~ collection of packages
Package outputs ~ subpackages of our package.
Flakes ~ collection of Inputs (other flakes) and Outputs (packages or configs)
Derivation ~ “Package” (mkDerivation ~ “make package”).
Anyway, there are two-way to configure your system, or profile, or dev environment with nix, Imperative or Declarative:
- imperative:
nix profile install nixpkgs#somePackage
(for every package you wanted)
- declarative: have a .nix file with your packages list and run a single “install”
There are utility functions in nixpkgs lib to do it declaratively, but usually people here just use:
-
DevEnv - Very Easy: for dev projects (won’t mess with your system or user)
-
HomeManager - Easy: for your user profile (won’t mess with your system)
-
System Manager - Medium: for your distro (at least you can resort to your distro packages)
-
NixOS - Hard: for new distro (the brave new world)
-
etc - Asian: for emotional damage (“stop it, get some help”).
Check this diagram