I’m trying to build the smallest possible system image with nwipe and its dependencies. I’ve posted a first pass on github, but that’s still much smaller than something truly minimal – its sizes are as follows:
12MB for ncurses is an obvious place to focus – by making it static, we could let the compiler include only the actually useful parts in the final image.
Glad to answer – as aforementioned, the program I’m ultimately trying to build here is nwipe.
The intent is to build a standalone EFI executable that, when executed, wipes all drives attached to a device (for hardware with sensitive data being deprovisioned). Once I’ve got a standalone nwipe, the next step will be combining that with some of the tools currently used to build a stage-1 initrd, and thus to build a cpio archive usable as an initramfs; given that, the next step is to use objcopy to generate a single binary containing a kernel, kernel command line, and the initrd in question; after that, the only remaining piece is to deal with generating a signed version of that binary. I’m presently optimistic that this can all be described as one nix expression, once I’ve got the language down.
Since some of the devices that need to be supported have EFI boot partitions that are quite small, size matters in this context.
(Indeed, I’m probably going to also be supplementing the staticPackage function with a noBinaries function removing the /bin directory from the dependencies we’re building only for their libraries; no point to having the parted executable or the various tools that are generated along with ncurses).
(sorry, neither of my comments are actual answers)
@dtzWill’s ALLVM work might be relevant for size-minimisation/unikernel work, iirc it actually does better than both static and shared-library builds at minimising size by combining a level of sharing even greater than that achieved by shared libraries with the optimisation opportunities of static builds. As far as I understand.
Also not a real answer to your question, but have you considered deploying the standalone wipe tool via network boot? That seems like it might be more efficient:
Definitely a lot to think about there, and some of those suggestions might warrant follow-up (I’d seen early articles on ALLVM, but had it mentally catalogued as an academic experiment rather than production-ready tooling). That said, netboot doesn’t work with my deployment model, and I am still interested in an answer to the original question.
This is still not a full answer as I am not 100% up to date with current nixpkgs development but you might want to look into multiple outputs, it might be that the static libraries are in another output (maybe .static) than the default one.
Yes, it gets confusing because there are multiple ways to do static. I think the dontDisableStatic and enableSharedExecutables are a little bit hacky - we don’t know about them at eval time. Some packages have special tricks to avoid big outputs.
My conceptual model still needs some work here – it feels like there should be a way to only override enableStatic where it would be accepted, and I still haven’t really properly internalized the difference between attributes and arguments; regardless, this is significant improvement over where I was before, and the assistance ya’ll have offered is much appreciated.
My long-term feeling is that multiple outputs aren’t really suitable for static libraries, and I’d rather see an option, i.e. use e.g. something like zlib.override { isStatic = true; }.
Of course, we would have to investigate+RFC some such style and start consistently using it…
Here’s one reason, another one is that also pkg-config and some other tools only support one library directory per package.