Best way to add global shell-level environment variables

Hi! I’ve been trying to find an easy way to add an environment variable to my shell but globally. When sarching, the options I’ve found so far are:

  • Setting a variable system-wide (requires reboots)
  • Setting a variable session-wide (requires session restart)
  • Using nix shell or nix develop to create a variable for the current shell (requires adding nix stuff to each repository I need the variable in)
  • Manually declaring a fish plugin that just exists to set that variable (that’s ok, but it’s locked into that one shell, I use fish btw).

So my question is, does nixpkgs have a way of doing the last one, but for all known shells within nixpkgs? It sounds like it should be possible, e.g. generating an extension for each shell based on that shell’s “enable” flag, but I couldn’t find anything from my search.

For some context, I need a variable that points to a global installation of a custom-built LLVM as I work with LLVM a lot but I don’t want to manually include a nix config in each one as no one else who looks at the codebase uses nix. Also for personal convenience too. I understand that it’s technically against the Nix philosophy though.

One approach that may solve your goals but isn’t really what you literally ask for:

  • Define the build environment in a one-and-done flake devShell, which you can version however you need
  • Use direnv and nix-direnv, so that your .envrc only has to contain use flake absolute-or-relative-path-to-that-flake
    • optionally install these via NixOS or HM modules to have it all auto-wired for you going forward
  • Gitignore those envrc files using global setting, repo setting, or .git/info/exclude

I’ve used this technique at a number of job roles to keep out-of-repo dev environments, without ever polluting the work repos.

If the LLVM isn’t nix managed then direnv by itself may just be enough.

Yeah I’ve considered using direnv with flakes, I’ve gotten a setup working already, it just feels a bit annoying to manually ignore it in each new repo I create (or globally blacklist it and then have to whitelist it in some new repos I make). But yeah at the moment my best solution is to just build a simple fish plugin to set a single variable, which isnt too many lines, but I’ll look into repository-level direnv flake stuff for more niche requirements, e.g. if some repo needs very specific build tools that I don’t want polluting my host config.