Hacker News new | ask | show | jobs
by jolmg 3 days ago
> The only way it would recompile everything is if, for example, you modified a particular version of glibc that was imported by most packages.

The package dependencies aren't based on whether what's packaged is a linked library, and built packages are linked to the dependencies by the digests. The digest of a package is made from the store derivation which contains the digests of the dependencies. Or does the digest of a package not depend on the digests of its dependencies anymore?

Because if they do, then on changing any minor thing, like a typo on a manpage, it would cause the change to cascade by changing the digests of its own package and its dependants recursively. Meaning, none would be found prebuilt and would need to be recompiled.

EDIT: s/hashes/digests/ because that's what appears to be the conventional name for the base32 strings used to identify an entry in /nix/store. The site has changed a lot in the last decade, but I do see this in the thesis that confirms what I remembered:

> The store derivation in /nix/store/1ja1w63wbk5q...-hello-2.1.1.drv is shown in Figure 2.13. It lists all information necessary to build the component, with references to the store derivations of dependencies [...] The output field specifies the path that will be built by this derivation, if and when it is built. It is computed essentially by hashing the store derivation with the output field cleared. --- https://edolstra.github.io/pubs/phd-thesis.pdf

EDIT 2:

> I modify udev rules and the system rebuilds in seconds.

Maybe there's a beaten path for udev rules, a way to override them without modifying the package / store derivation. Or maybe the derivations you're modifying don't have many dependants.

1 comments

I didn't say anything about linked libraries. I was just using glibc as an example. I could have used a man page too.
Was trying to figure out why you said that it wouldn't happen with a systemd executable but it would with glibc. Figured it being a library was the difference you meant. Maybe you just meant that glibc has more dependents.
The systemd issue in particular is something I've experienced. nixpkgs does not split systemd into many packages, so everything that needs udev, libsystemd, etc depends on it, so replacing systemd via an overlay will cause a mass rebuild. The trick is to patch systemd and refer to your patched version separately, e.g. with a pkgs.writeShellScript that calls ${systemd-patched}/bin/patched-binary.
> The trick is to patch systemd and refer to your patched version separately

I mean, generally when you patch things, you want all dependents to use the patched version. It's just irksome that you know the change you made strictly speaking doesn't need a rebuild of dependents, but nix will still require it in the interest of ensuring reproducibility. Just wish there were an established expert-mode I-know-this-may-break-things way to have a modified derivation act as a drop-in replacement of a particular package/digest.

For example, it would be neat to have derivation foo.nix, from which the digest is calculated. Then, have the system check for a mod/foo.nix or similar path which would be a function that can modify the derivation without having the digest be recalculated on the result. Or maybe this could be done by having a function calcDigest, which sets the digest of a derivation and the system can simply not set the field when it's already been set. This to allow further changes while being treated as if changes haven't been made.