I’ve been meaning to try nixos for a while, and recently I had an issue with ubuntu getting into a corrupt state and discovered how poor the support for rollback was, and that finally pushed me over the hump.
I have heard that nixos is great for developers who want to manage a bunch of environments with different versions of the same libraries and tools, so that was one of the first things I wanted to try.
There is a website called highload.fun where people compete to write the most optimized possible compiled code. However they very specifically use GCC 9.3.0 to evaluate submissions. So installing that was the first thing that I wanted to try… I can’t make it work. But note that I am as interested in understanding why the things I tried below didn’t work as I am in actually getting GCC 9.3.0 installed. How else am I going to learn how the distro works?
I expect three common use cases for package installs: wanting it to be system wide, wanting it to be the default in PATH for a particular user, and wanting it to be the default for a particular sandbox for a particular user. I have managed to install some packages system wide like htop and git – I can edit /etc/nixos/configuration.nix and add to systemPackages
. But to make something the default for a single user I guess I need to use Home Manager? But the README basically tells you not to use it if you’re a newbie, and specifically says it doesn’t support rollbacks which is the main reason for me wanting to try nixos…
So anyway what if in settle for installing system wide? Well then the problem is I can’t get the version I want. After some googling I tried this:
environment.systemPackages = with pkgs; [
(gcc9.overrideAttrs (oldAttrs: { version = "9.3.0"; }))
];
AFAICT the version is completely ignored and it installs 9.5.0. Disappointingly, I don’t get any errors! It doesn’t give me a lot of faith that a totally reproducible system is actually reproducible that I can ask for one version explicitly and get a completely different version…
More googling then tried this:
{
environment.systemPackages = with pkgs; [
(gcc9.overrideAttrs (oldAttrs: {
version = "9.3.0";
src = fetchurl {
url = "mirror://gcc/releases/gcc-9.3.0/gcc-9.3.0.tar.xz";
sha256 = "I put the hash here";
};
}))
];
}
to get the hash to insert I tried:
nix-prefetch-url --unpack "https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.gz"
Which reported 15cyd8gwcyy0cxd4iarb6ns3qfs6vywqhwi6f78sx9h9sr7q52qq
. So I put that in…
'/nix/store/bsxmb8x9rswwin2di2kzb6z3d9c0v1ls-gcc-9.3.0.tar.gz.drv':
specified: sha256-GIuCT9YJpq7RcSZyiLnfRjs8tDUrq0haZ8B7xh9qnpU=
got: sha256-Uliptq/pRjwuVrnoNVsaS+4SXKgouAePkQMDvC75H6Y=
error: 1 dependencies of derivation '/nix/store/1zng9pcpkvgn5xgw4i21vqqxs4nvbix0-gcc-wrapper-9.3.0.drv' failed to build
error: 1 dependencies of derivation '/nix/store/a69j2an2yhrwd3xlc3bjg3p3il3gj5qn-system-path.drv' failed to build
error: 1 dependencies of derivation '/nix/store/f43xr2lpca809j1h3j03dkyy1b8plbhm-nixos-system-sliceserv-23.05.3037.f155f0cf4ea4.drv' failed to build
Now what is extremely confusing about this is neither of those hashes are the one I specified! Oh well, I guess I will try using the hash that it explicitly gave me… hey it succeeded! So lets try…
$ gcc --version
gcc (GCC) 9.5.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Not getting an error an still getting the wrong version in this circumstance seems totally bonkers, it means nix downloaded the tarball and then decided not to use it anyway! The command also finished suspiciously fast making me think that it didn’t spend any time building anything…
Alright I do some more reading and somebody suggests something called an overlay file. Don’t really know what overlays are yet, but I try putting this code in ~/.config/nixpkgs/overlays/gcc-overlay.nix
:
self: super: {
gcc9custom = super.gcc9.overrideAttrs (old: {
version = "9.3.0";
src = fetchurl {
url = "mirror://gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.xz";
sha256 = "I put the hash here";
};
});
Then I ran:
nix-env -iA nixos.gcc9custom
…nope still GCC 9.5.
Okay, surely if I just google a little bit more… I find this thread which seems to be suggesting to use a special build hack to deal with packages that expect a typical file system layout… Something I’m guessing the official package already does under the hood? But the version that they have put together is using something called flakes… So I google to trying to figure out what flakes are, and I find THIS thread, which says that flakes, like home manager, are not yet stable and not really ready for prime time, and also apparently have some design problems, but also they are what everybody is using instead of the stable method? @_@
So at this point what I am trying to understand is whether or not what I’m doing is extremely weird compared to what people would normally want to use NixOS for? I thought the raison d’ etre here was easy rollbacks (turns out not for your home directory), reproducibility (except versions other than the one that you requested are silently installed), and having multiple versions of the same toolchain and libraries simultaneously (same problem). I wasn’t expecting this much friction on the first thing I tried, multiple compiler versions doesn’t seem that exotic? I could download gcc on Ubuntu and install it with --prefix
into my home folder pretty easily.