Ensure that a system-compatible OpenGL driver is available for nix-shell-encapsulated programs.
This is an attempt at automated solution to NixOS/nixpkgs#9415
The home of nix-install-vendor-gl.sh
is at: https://github.com/deepfire/nix-install-vendor-gl
Currently only nVidia drivers are supported, although the infrastructure is generalised sufficiently so, that adding support for a new driver stack should amount to extending case statements in a number of functions – the list is here: https://github.com/deepfire/nix-install-vendor-gl/blob/master/nix-install-vendor-gl.sh#L7
nvidia | nouveau | AMDGPU | radeonsi | Catalyst | Intel | |
---|---|---|---|---|---|---|
SteamOS | ✅ | |||||
Ubuntu 14.04 LTS | ✅ | |||||
Ubuntu 16.04 | ✅ | |||||
Ubuntu 16.10 | #7 | |||||
Ubuntu 17.04 |
- Nix, obviously.
- Both system and Nix-provided
glxinfo
’s:- system one
- likely, is at
/usr/bin/glxinfo
(if it is elsewhere, you would have to specify its path with--system-glxinfo
). This one is installed with distro-specific means:apt-get install mesa-utils
,dnf install glx-utils
, or similar. - Nix-provided
- should be at
~/.nix-profile/bin/glxinfo
, and can also be similarly specified.
- Enter shell, face failure:
desktop@steamos:~/src/reflex-glfw$ nix-shell [nix-shell:~/src/reflex-glfw]$ glxinfo name of display: :1 libGL error: unable to load driver: swrast_dri.so libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 155 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 54 Current serial number in output stream: 53
- Call for rescue (note the
.
dot) – will require interactive input, due to asudo
invocation (suggestions on how to improve this are welcome!):[nix-shell:~/src/reflex-glfw]$ . ../nix-install-vendor-gl/nix-install-vendor-gl.sh INFO: The version of the vendor driver in nixpkgs: 375.26 doesn't match the system vendor driver version: 367.27 ..so a semi-automated vendor GL package download is required. downloading ‘http://download.nvidia.com/XFree86/Linux-x86_64/367.27/NVIDIA-Linux-x86_64-367.27.run’... [74251/75142 KiB, 3525.9 KiB/s] path is ‘/nix/store/lfp9md7r5ms29wqy99bsayql8sh9fwbw-NVIDIA-Linux-x86_64-367.27.run’ /nix/store/4mxr3p5cl16fvmfqqj780937b5wrv1gn-opengl-drivers Nix-compatible vendor GL driver is now installed at /run/opengl-driver To make them available to Nix-build applications you can now issue: export LD_LIBRARY_PATH=/run/opengl-driver/lib (Doing the export, in case you have sourced the file directly.)
- Proceed happily:
[nix-shell:~/src/reflex-glfw]$ glxinfo name of display: :1 display: :1 screen: 0 direct rendering: Yes server glx vendor string: NVIDIA Corporation server glx version string: 1.4 server glx extensions: GLX_ARB_context_flush_control, GLX_ARB_create_context,
- The cases of re-activation are handled transparently:
[nix-shell:~/src/reflex-glfw]$ . ../nix-install-vendor-gl/nix-install-vendor-gl.sh INFO: Nix-available GL seems to be okay (according to glxinfo exit status). [nix-shell:~/src/reflex-glfw]$ exit exit desktop@steamos:~/src/reflex-glfw$ nix-shell [nix-shell:~/src/reflex-glfw]$ . ../nix-install-vendor-gl/nix-install-vendor-gl.sh INFO: A global libGL.so.1 already seems to be installed at /run/opengl-driver/lib/libGL.so.1, and it appears to be sufficient for the Nix 'glxinfo'. export LD_LIBRARY_PATH=/run/opengl-driver/lib
Firstly, there’s an examine
subcommand that dumps a lot of information, that
might prove to be useful in case something goes wrong.
Secondly, still, if anything goes wrong, please:
- If the script is obviously failing, repeat the failing invocation with
--verbose
. - File a bug report at https://github.com/deepfire/nix-install-vendor-gl/issues (with the log attached, if #1).
When one uses Nix to run Nix-encapsulated OpenGL software on non-NixOS, it’s not unlikely to encounter a similarly-looking error:
[nix-shell:~/src/reflex-glfw]$ dist/build/reflex-glfw-demo/reflex-glfw-demo libGL error: unable to load driver: swrast_dri.so libGL error: failed to load driver: swrast
This happens because nix isolates your program from the system, which implies a purposeful ignorance of your host GL libraries.
However, these particular host GL libraries are essential for your program to be able to talk to your X server.
The issue is well-known:
So, it’s a fairly fundamental conflict, and one solution is to supply a sufficiently matching version of GL libraries (yes, that means your nVidia drivers) using Nix itself.
Thankfully, it’s not impossible – this script attempts to be a proof.