Manos’ Blog
Table of Contents
About
Here I write about things I usually figure out, such as pytorch
development in nix
, game development, or anything that piques my interest. If you want to discuss about something, reach me by email or github issues.
Run Godot made games/apps on NixOS
Trying to run games (or apps) made in Godot in Nixos will result in (in this example Pixelover):
mmxgn@emerdesktop ~/Downloads/pixelover-linux-demo $ ./PixelOver.x86_64 Could not start dynamically linked executable: ./PixelOver.x86_64 NixOS cannot run dynamically linked executables intended for generic linux environments out of the box. For more information, see: https://nix.dev/permalink/stub-ld
The correct nix approach would be to create a derivation with all the necessary dependencies and patchelf the binaries. However noone has time for that. Here’s a solution that has served me well:
environment.systemPackages = with pkgs; [ (let base = pkgs.appimageTools.defaultFhsEnvArgs; in pkgs.buildFHSEnv(base // { name = "fhs"; targetPkgs = pkgs: (base.targetPkgs pkgs) ++ (with pkgs; [ pkg-config ncurses zsh mesa libglvnd wayland wayland-protocols glfw ] ); LD_LIBRARY_PATH = with pkgs; lib.makeLibraryPath [ mesa libglvn ]; profile = "export FHS=1"; runScript = "zsh"; extraOutputsToInstall = ["dev"]; })) ];
Then by running fhs
first, you can simply execute the binary as you would under an FHS-compliant distribution:
mmxgn@emerdesktop ~/Downloads/pixelover-linux-demo $ fhs mmxgn@emerdesktop ~/Downloads/pixelover-linux-demo $ ./PixelOver.x86_64
Figure 1: Pixelover is a great app for converting your 3d models to 2d sprites (spaceship model by yours truly).
How I work with CUDA and devenv
for developing with python/pytorch
in NixOS
Disclaimer
What I write applies to the following:
- Date: Jan 30, 2025
- NixOS version
25.05
(unstable) - Nixpkgs channel
github:nixos/nixpkgs/nixos-unstable
- Nvidia Drivers / CUDA Version:
565.77
/12.7
Your mileage may vary, especially if visiting this article in the future.
The problem
Machine learning with python was one of my big pain with NixOS that occasionally brought me close to abandoning it. There is no single way to make things work and if not using python from nixpkgs
it is almost guaranteed to break (e.g. during compilation of numpy
or something similar). Furthermore, trying different ways requires writing lots of boilerplate code which can be hard to convince your colleagues to add to the git repo. I have figured two ways to keep my sanity: by using docker and by using devenv. Here I write about the latter while I might write about the former in the future:
devenv
to the rescue
I recently came across devenv which looks promising as an easy way to let me collaborate with colleagues on ml-based python projects while still using NixOS on my local environment and not having to fight through docker shenanigans (fixing for permissions, working with git repositories, and stuff). It is easy, first include it with:
environment.systemPackages = [
pkgs.devenv
];
Then, after rebuilding from configuration.nix
, switch to your repository on your disk and run:
# Initialise a devenv package devenv init
And use the following devenv.nix
, and devenv.yaml
file (remember to change the python version and requirements.txt
file):
{ pkgs, lib, config, inputs, ... }: { # Required for compiling numpy packages = [ pkgs.libz ]; languages.python = { enable = true; version = "3.10"; venv.enable = true; venv.requirements = ./requirements.txt; }; # This is required if you want your module to see cuda env.LD_LIBRARY_PATH = "/run/opengl-driver/lib"; }
inputs: nixpkgs-python: url: github:cachix/nixpkgs-python inputs: nixpkgs: follows: nixpkgs nixpkgs: url: github:cachix/devenv-nixpkgs/rolling
numpy torch torchaudio torchvision
So, finally, after devenv shell
:
python -c 'import torch; print(torch.cuda.is_available())'
True
Devenv will also modify your .gitignore
file to include itself, don’t forget to stage it with git stage .gitignore
.
diff --git a/.gitignore b/.gitignore index 51aa465..7fd8971 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,12 @@ build/* **/checkpoint* **/output**.wav **/*.ipynb +# Devenv +.devenv* +devenv.local.nix + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml
Troubleshoot
- Importing
module
fails withImportError: libXXX.so.X: cannot open shared object file: No such file or directory
If you get an error like:
>>> import numpy Traceback (most recent call last): File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/_core/__init__.py", line 23, in <module> from . import multiarray File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/_core/multiarray.py", line 10, in <module> from . import overrides File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/_core/overrides.py", line 7, in <module> from numpy._core._multiarray_umath import ( ImportError: libz.so.1: cannot open shared object file: No such file or directory During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/__init__.py", line 114, in <module> from numpy.__config__ import show_config File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/__config__.py", line 4, in <module> from numpy._core._multiarray_umath import ( File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/_core/__init__.py", line 49, in <module> raise ImportError(msg) ImportError: IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! Importing the numpy C-extensions failed. This error can happen for many reasons, often due to issues with your setup or how NumPy was installed. We have compiled some common reasons and troubleshooting tips at: https://numpy.org/devdocs/user/troubleshooting-importerror.html Please note and check the following: * The Python version is: Python3.10 from "<your-path>/.devenv/state/venv/bin/python" * The NumPy version is: "2.2.2" and make sure that they are the versions you expect. Please carefully study the documentation linked above for further help. Original error was: libz.so.1: cannot open shared object file: No such file or directory The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<your-path>/.devenv/state/venv/lib/python3.10/site-packages/numpy/__init__.py", line 119, in <module> raise ImportError(msg) from e ImportError: Error importing numpy: you should not try to import numpy from its source directory; please exit the numpy source tree, and relaunch your python interpreter from there. >>>
The solution is to add the corresponding
pkgs.<library>
indevenv.nix
. If you don’t know what that is, you can figure it out with nix-locate:E.g.:
# First create the index nix-index # Then find the corresponding package nix-locate 'libz.so.1'
... zlib.out 0 s /nix/store/jb442jir0a2x7zsk0d63xb6rh8p280ai-zlib-1.3.1/lib/libz.so.1 zlib.out 128,584 x /nix/store/jb442jir0a2x7zsk0d63xb6rh8p280ai-zlib-1.3.1/lib/libz.so.1.3.1 ... libz.out 0 s /nix/store/x4hgdkl1i7x76phgkqv24m70jawqa7jm-libz-1.2.8.2015.12.26-unstable-2018-03-31/lib/libz.so.1 libz.out 107,680 r /nix/store/x4hgdkl1i7x76phgkqv24m70jawqa7jm-libz-1.2.8.2015.12.26-unstable-2018-03-31/lib/libz.so.1.2.8 ...
And now you can add
pkgs.libz
todevenv.nix
:... packages = [ pkgs.libz ]; ...
Another usual suspect is
cv2
which requirespkgs.libGL
andpkgs.glib
.