ImportError: libstdc++.so.6: cannot open shared object file: No such file or directory

ok so the issue is when you create a virtual-env, a copy of python binary is copied and this does not know where to get its glibc and certain other libraries from. I faced this issue previously as well. You have 2 choices

  1. Provide a python with the required packages using nix
  2. Provide the libs needed for python

Provide python with required packages using nix

I’ll give you a direct example and you can figure out how to put it in a nix.shell file. If you run bellow command, you get a shell with a python that has pandas:

$ nix shell --impure --expr '(import (builtins.getFlake "nixpkgs/23.11") {}).python310.withPackages (pyPkgs: [pyPkgs.pandas])'
$ python
Python 3.10.13 (main, Aug 24 2023, 12:59:26) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
>>> exit()

the key part is this python310.withPackages (pyPkgs: [pyPkgs.pandas]). This will return a python which has the pandas package available. You can search for packages here. Its easy to package new ones if its not already available. You can put the produced derivation in buildInputs of a shell.nix or simply run a nix-shell as above to get it

Provide the libs to python binary via virtual env

This is a lot messier. You need to provide certain libs and maybe even put them in your LD_LIBRARY_PATH. Bellow is an example derivation I make in my python projects which use virtualenv

  localPython = writeScriptBin "local-python"
  ''
  .venv/bin/python "$@"
  '';

  # Wrap only python with the required lib files
  python =
    runCommand "python" { 
      nativeBuildInputs = [ makeWrapper  ];
      buildInputs = [ libGL libGLU localPython];
    } ''
    makeWrapper ${localPython}/bin/local-python $out/bin/py \
     --prefix LD_LIBRARY_PATH : /usr/lib/wsl/lib \
     --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [pkgs.stdenv.cc.cc pkgs.cudaPackages.cudatoolkit pkgs.cudaPackages.cudnn libGL libGLU]}
    '';

In my examples I’ve also added cuda packages and wsl to library path but for your case its not needed. You just need pkgs.stdenv.cc.cc in LD_LIBRARY_PATH to make the error go away. Note that if you export that on your shell for all programs, it could cause issues so would recommend only wrapping the python runner with it.

I would recommend you always create shell.nix files per project so you can lock its dependencies for future use. Can use flakes, or simply use niv to lock nixpkgs sources as well with an easy interface to update later. Anytime in doubt, search github for nix files and a few keywords and more often than not you’ll find other examples. This has been the main method I’ve learned nix over the years

5 Likes