I don’t know about this specific issue regarding libGL
but I wanted to share some of my development practices that I’ve come up with for doing development under NixOS since it came up.
Typically, when I develop software on NixOS, I do so in the context of a dev shell or direnv.
Here, for example, is a flake I can use to compile Go software that depends on GTK:
{
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs =
{ nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
go
gtk4
];
};
}
);
}
If I have this flake.nix
file in a folder, I can call nix develop
to enter a dev shell, or add an .envrc
with the directive use flake
to get the environment automatically added upon cd
’ing into the directory of the project.
You can combine this with other tools, too. You can make a derivation locally that compiles your project via buildGoModule
but then use mkShell
with inputsFrom
(and possibly other inputs for convenience: e.g. you can add specific Go dev tools not needed for actually building the software). I don’t have an example off-hand for Go, but I can point to a relatively small project where I just recently set up a Nix dev environment following this pattern, hopefully it may lend some help:
This way of doing development has its ups and downs. Your flake inputs get locked which means they need to manually be updated periodically, but OTOH without updating them your project should remain buildable indefinitely.
Tailscale also has a Nix flake and it has an interesting trick to handle the vendor hash: it is a separate file imported from the flake and they have their own package for calculating it irrespective of Nix which is ran via a shell script. This allows people to work on a Go project that has an official Nix flake without breaking the Nix flake by changing dependencies, keeping the vendor hash up to date, even if they don’t have Nix installed.
There are also other patterns I use when working on other people’s projects that don’t have a Nix flake:
- For some projects, it is enough to just use a devShell of the upstream Nixpkgs derivation, if one exists. Something like
nix develop nixpkgs\#dolphinEmuMaster
.
- If I want to create a custom flake and keep it in the dev directory, I can do that. I can keep Git from trying to version it by adding some files to the local gitignore at
.git/info/exclude
: usually, flake.nix
, flake.lock
, .direnv
and .envrc
. Then, I can write an .envrc that does a use flake path://$PWD
, which disables the Git fetcher, allowing the unversioned flake files to be seen. I use this for contributing to open source upstreams. The direnv caching makes Nix store bloat less of a problem since it caches aggressively.
There’s probably more stuff here to say. If you are using an IDE or text editor that manages its own processes, like VSCode, environments like this might be somewhat challenging; I have some solutions for this but ultimately it’s not a perfect fit.
Hope this helps.
P.S.: The approaches I outlined all mention Nix flakes, but just to be sure, none of them depend on Nix flakes particularly. For example, it is fully possible to use .envrc
without Nix flakes; see the use nix
directive. Tailscale’s nardump
should work fine with projects that are not using flakes, too. I do find flakes useful, though.