Running Fooocus (or other gen-AI tools) on NixOS

Context:

I’m trying to set up and run fooocus (a platform that runs AI models locally to generate images) on my machine, with NixOS 24.11 (Vicuna) as per the instructions available in their README.

What I’ve done so far:

The instructions are basically, clone the repo, create a virtual environment, install depedencies, and run a script. After some hacking, I realized I needed a python version between 3.10 and 3.11 to run it successfully. I decided to use a shell.nix file to try and make sure things are reproducible, and isolated to a degree.

The Error I Keep Running Into:

However, I kept running into a certain error as I tried to run the script: ImportError: libstdc++.so.6: cannot open shared object file: No such file or directory. After much googling (I’m new to Nix and NixOS, so apologies if I’m trying things that don’t make sense) I managed to figure out that meant that the nix shell created doesn’t have access to the C++ development tools. So, I made some modifications to the shell.nix file, and I now have the following:

let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-24.11.tar.gz";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in

pkgs.mkShell {
  packages = with pkgs; [
    pkgs.llvmPackages_16.libcxxClang
    pkgs.python310Full
  ];
  shellHook = ''
    # fixes libstdc++ issues and libgl.so issues
    LD_LIBRARY_PATH=${stdenv.cc.cc.lib}/lib/:/run/opengl-driver/lib/
    # fixes xcb issues :
    # QT_PLUGIN_PATH=${qt5.qtbase}/${qt5.qtbase.qtPluginPrefix}
  '';
}

This is cobbled together from various posts I found online. I commented out the QT_PLUGIN_PATH line, because that’s irrelevant to the problem at hand. What I am running into is an error whenever I try to invoke nix-shell, which is:

error: undefined variable 'stdenv'
       at /mnt/store/Projects/Fooocus/shell.nix:13:23:
           12|     # fixes libstdc++ issues and libgl.so issues
           13|     LD_LIBRARY_PATH=${stdenv.cc.cc.lib}/lib/:/run/opengl-driver/lib/
             |                       ^
           14|     # fixes xcb issues :

And now I’m unsure what to do. I thought stdenv got installed with llvmPackages_16.libcxxClang. Or am I making an incorrect assumption? And will this solve the original problem of the missing compilation tools? I run into the exact same error when attempting to run stable-diffusion-webui as well.

Any help would be much appreciated!!

stdenv is introduced nowhere, lexically. pkgs.stdenv would evaluate though. In fact “${pkgs.stdenv.cc.cc.lib}/lib” will yield a folder with libstdc++.so.6 in it. Note that this is a GCC library. Llvm doesn’t provide it (it provides libc++). I’d also recommend trying to move away from LD preload tricks and either patch the python wherever it’s doing dlopen things or if it’s a native dependency using autopatchelf to fix it (see nixpkgs manual).

2 Likes

Nix is more of a programming language than a configuration language, so copy-pasting fragments is less likely to work for you than it would if it were just a matter of having the right magic words present in your file. You need to think about scopes and variables and have some basic understanding of how the Nix language works in order to get through situations like this.

The error message here is that stdenv is an undefined variable. Indeed, what you should do here is reference the stdenv attribute on pkgs, which is a variable you’ve defined. So change stdenv.cc.cc.lib to pkgs.stdenv.cc.cc.lib to get around that one issue. If you uncomment the QT_PLUGIN_PATH line, you’ll need to do the same thing with qt5.

More feedback: this is a very non-reproducible way of getting a Nixpkgs!

fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-24.11.tar.gz";

It’ll work while you’re standing things up, but it will change from hour to hour — if you’re using Nix to get reproducibility, you won’t get it like this. You should get in the habit of using pinned references and hashes. The standard idiom would be more like this:

  nixpkgs = builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/adf66883a1bd1509136e797fd641ce5acdad569f.tar.gz";
    sha256 = "sha256:09yn7ssh52h1j6m4kizs7b7wmfak37drd1snqyv5mrwhqzr1j8dj";
  };

(For the first inscrutable sequence of characters, pick a recent commit from the GitHub interface. For the second, if you start with an empty string, Nix will raise a hash mismatch error that tells you the string to actually use.)

Also, this sticks out to me as not something a Nix programmer would write (though it isn’t an error per se):

  packages = with pkgs; [
    pkgs.llvmPackages_16.libcxxClang
    pkgs.python310Full
  ];

Again, it’s all about variables and scopes. The function of with pkgs; is to bring all of the attributes on the pkgs value into scope for the following expression. So here, you would either take advantage of the with keyword and write:

  packages = with pkgs; [
    llvmPackages_16.libcxxClang
    python310Full
  ];

or (and I recommend this to you as a beginner) drop the with pkgs; and use the ‘full names’ of the values you need:

  packages = [
    pkgs.llvmPackages_16.libcxxClang
    pkgs.python310Full
  ];
2 Likes

Thank you both for the helpful answers. I’m marking the @rhendric’s answer as the solution, just because it’s more comprehensive, but both were insightful, and taught me things I didn’t know about Nix. Thanks again!!

1 Like