I have a science experiment to share that I imagine some of you will enjoy.
Recently I’ve been trying out writing derivations directly, and limiting my reliance on Nixpkgs ( within reason ). Largely this is motivated by a need for fine grain caching at work and also making Nix more approachable to coworkers by avoiding the complexity of setup.sh.
I wanted to try getting real pedantic with derivations, and use them to process commands like cc, ln, ar, and cp directly. What I cooked up was a minimal set of helpers for C++ builds.
I took it for a spin on a relatively simple set of packages to produce static and shared libraries, as well as dynamic and static executables.
These depend on a mixture of Nixpkgs and “from scratch” libs.
The scale here is too small to make any sweeping performance claims, but because it’s this fine grained, changes to sources only trigger rebuilds of the effected files. It would be easy to extend this to mark individual headers as inputs as well using cpp traces, and to library linkage by using traces in ld ( there’s potentially a large performance advantage for linkage ).
The README in the repo covers limitations and possible extensions, but overall I’m really pleased with this little experiment.
You may be interested in https://github.com/edolstra/nix-ccache, which provides a gcc wrapper that runs the input through the preprocessor and then uses a Nix derivation to perform the actual compilation. This enables caching and distributed builds similar to ccache (hence the name - it doesn’t actually use ccache).
There is also the ancient https://github.com/edolstra/nix-make which provides functions for building C/C++ source files, using some import-from-derivation magic to figure out the header file dependencies automatically.