I don’t have a complete idea about this at the moment, just some random thoughts.
Create a module system for Nixpkgs, which will be evaluated to a tree of sets (what’s the name of this?) to determine some optional wrapper behaviors. This will be further formed into a function, in which the input is the original derivation of the program to be wrapped, and the output is an overlay with the wrapped derivation. The overlay can override the original derivation, or place the wrapped derivation in a new attribute (which should be preferred?).
In my idea, these optional wrappers are not built in the original derivation itself, just like the *-unwrapped
package commonly seen in Qt Apps. Rather, they are added in the derivation the user finally installs, and built on users’ machine.
There are two ways to specify the affected package in a module.
The first is to directly specify a package. This situation applies to configuring a single program, such as neovim or vscode. We can further move the programs.foo
type configuration of NixOS modules and Home manager into this Nixpkgs wrapper module, by adding optional wrappers to specify the configuration files and command arguments for them.
The second is to add a list like passthru.optionalWrappers
to the derivations of packages that need to be wrapped, and then override the wrappers with null
or some sets/derivations (which would be better?). This applies to all programs that look for optional library and resource dependencies on specific paths. For example, to address the problem that OpenGL drivers cannot be used directly on other Linux distributions, we can use wrappers to add drivers to the search path of libraries such as libdrm
. Other common apps can also be configured to include optional dependencies and settings, such as Qt plugins, GTK themes, icon themes, electron flags, etc.
The wrapper module system added to Nixpkgs will allow us to reduce closure size more freely and manage parts of our configuration without placing configuration files in a large number of different places (and sometimes it creates havoc with programs installed by other package managers). We can also install several copies of the same program with different configurations at the same time. For example, one vim for writing markdown and another vim for writing Nix!
Obviously, this relies on a series of improvements to wrapper generators, including using a more consistent and structured representation of wrapper, allowing arguments, environment variables and others to be added, overridden and removed (instead of double wrapping). And it would be better to generate wrappers by directly splicing the binaries, or making them read structured configuration files, rather than using a compiler to compile them (or maybe we can do this with some minimal compiler). Hopefully some can be addressed by [RFC 0075] Declarative wrappers.