I meant that you could edit the NixOS module itself and submit a pull request.
With overlays, you are taking a specific Nixpkgs attribute and are replacing it with another one (possibly derived from the previous one – in super
). That is why it causes so many rebuilds – when an attribute changes, all derivations that (transitively) refer to it are considered different as well.
replaceRuntimeDependencies
uses a completely different approach: First your system is built as normal and then, in the resulting system package and its dependencies, the store paths are textually replaced. If the packages you replaced are equivalent in the sense that the packages depending on them would not change if you used overlays (modulo store path changes), you will have saved many builds. But if any package depending on one of the packages you replaced would produce a different output you might get wrong results (for example, if xorgserver
parsed the xkeyboardconfig
files at build time and compiled the data into the program) or even crashes (if the replaced package was a library and the replacement was not ABI compatible). I do not suspect that to be the case but one should always keep this in mind.
Going the replaceRuntimeDependencies
, you would do something like the following untested snippet:
system.replaceRuntimeDependencies =
let
xkeyboardconfig = pkgs.xorg.xkeyboardconfig_custom {
layouts = config.services.xserver.extraLayouts;
};
xorgserver = pkgs.xorg.xorgserver.overrideAttrs (old: {
configureFlags = old.configureFlags ++ [
"--with-xkb-bin-directory=${xkbcomp}/bin"
"--with-xkb-path=${xkeyboardconfig}/share/X11/xkb"
];
});
setxkbmap = pkgs.xorg.setxkbmap.overrideAttrs (old: {
postInstall =
''
mkdir -p $out/share
ln -sfn ${xkeyboardconfig}/etc/X11 $out/share/X11
'';
});
xkbcomp = pkgs.xorg.xkbcomp.overrideAttrs (old: {
configureFlags = [
"--with-xkb-config-root=${xkeyboardconfig}/share/X11/xkb"
];
});
in
[
{
original = pkgs.xorg.xkeyboardconfig;
replacement = xkeyboardconfig;
}
{
original = pkgs.xorg.xorgserver;
replacement = xorgserver;
}
{
original = pkgs.xorg.setxkbmap;
replacement = setxkbmap;
}
{
original = pkgs.xorg.xkbcomp;
replacement = xkbcomp;
}
];
Actually, looking at the xorg overrides the packages are already passed the flags so only the xkeyboardconfig
is really necessary.
Of course, you could also put that code into your configuration.nix
and be done with it – it is just another NixOS module after all.
I think, in GNOME Settings, you are only adding an existing layout returned by Xorg. You still need to make Xorg itself aware of it, which is what the extraLayout
option does.
Nix cannot know if the same output will be produced when a dependency changes (see above) so it needs to build it. And since Nix bases identity of packages (derivations) on the identity of their dependencies, it would still be considered a different package even if the output were the same (modulo store paths).
There is an experimental feature that will allow early cut-offs when derivation output is the same (modulo store paths) but you will always need to rebuild at least packages directly depending on the package you change.