Open joepie91 opened 9 years ago
Tricky... I wonder if it can be fixed binding openarena to mesa libGL. Then you'd at least have something that runs, although not necessarily optimally for your system.
On NixOS, programs find the selected/best OpenGL implementation here:
$ echo $LD_LIBRARY_PATH
/run/opengl-driver/lib:/run/opengl-driver-32/lib
Something similar can of course be done with nixpkgs programs on non-NixOS (manually set $LD_LIBRARY_PATH).
CC @vcunat.
There's a deliberate choice to be impure in this respect, as I view libGL* as a part of your GPU driver. I expect using your system one is better even for apps that don't report an error (most do link against our version from mesa).
If one is able, the safest approach on non-nixos should be to actually create /run/opengl-driver/lib
(speaking of x86_64-linux) and put symlinks to your system libGL*
. Alternatively one could just set $LD_LIBRARY_PATH
to the location, but beware if it contains too many other libs...
Hmm. Would this not be a good usecase for parameters (letting you pick between a system libGL* path or a mesa dependency)? Or can those not be specified from the command-line?
(I'm still pretty new to Nix)
You can easily use $LD_LIBRARY_PATH
to open any libGL version. I've only seen one person who wanted to use the bundled mesa instead of system libGL (and on NixOS it's often the same one).
couldn't we require a nixpkgs config setting to be set and wrap all libGL
software with it? that way users would get a message how/where to set the setting
@domenkozar: I don't understand what you mean. Note that the problems only happen on non-nixos, and different distros have libGL on different locations, I think.
I'm saying we could use nixpkgs config to set $LD_LIBRARY_PATH
for non-nixos users
To a non-technical user, what would the correct (current) procedure look like for installing openarena
on a non-NixOS distribution? I'm technical, but I don't know much about compiler toolchains, so an ELI5-style explanation might be the best way to make sense of this.
After talking about this with @ttuegel for a while, we've established that the following works:
nix-env -i patchelf
)libGL.so.1
(usually in /usr/lib64
) somewhere, eg. ~/.libgl-shim/libGL.so.1
.patchelf --set-rpath /lib:/usr/lib:/lib64:/usr/lib64 ~/.libgl-shim/libGL.so.1
(adjust lib
paths if necessary for your distribution)libGL.so.*
symlinks that your system has, but in your ~/.libgl-shim
, and pointing to your modified copy.openarena
as follows: LD_LIBRARY_PATH=~/.libgl-shim openarena
This approach also seems automatable, and should work for other things that use makeWrapper :)
I'm still working on something, but once I've gotten further with that, I'll probably do a proper writeup of this on my blog or something.
What does this give beyond what the simpler LD_LIBRARY_PATH=/usr/lib64 openarena
provides (substitute for whatever path libGL.so.1 has on your system)? It seems you still need to provide the custom path to libGL, which cannot be automated.
@bjornfor You'd only load the system libGL
, and the rest of the dependencies would remain the pure Nix variants.
Good point :-)
What about LD_PRELOAD=/lib/libGL.so.1 openarena
then?
That wouldn't work because of libGL dependencies:
sven@linux-etoq:~/projects/nixpkgs/test> LD_PRELOAD=/usr/lib64/libGL.so.1 openarena
/nix/store/zmd4jk4db5lgxb8l93mhkvr3x92g2sx2-bash-4.3-p39/bin/bash: error while loading shared libraries: libglapi.so.0: cannot open shared object file: No such file or directory
It'd only look in the Nix store, since Nix uses a custom ld
. By elfpatch
ing it, we have a copy of libGL that will also look for its own dependencies in the system-wide library directories, without affecting non-libGL dependencies of the application.
I see. I'm going to stop suggesting alternatives now :-)
I tried this according to the instructions of joepie91 above, since I wanted to use OpenSCAD from Nix on Debian Jessie with Intel HD graphics (Haswell). Copying/patching libGL.so.1
was not enough, and glxinfo/OpenSCAD/OpenArena failed because they couldn't find i965_dri.so
. Adding i965_dri.so
also wasn't enough, because i965_dri.so needed some more libraries to be loaded. After adding these libraries, it worked. :)
The contents of my ~/.nix-libs is now:
libGL.so -> libGL.so.1.2.0
libGL.so.1 -> libGL.so.1.2.0
libGL.so.1.2.0
libpciaccess.so.0
dri/i965_dri.so
# edit: removed libz.so.1
Commands used:
mkdir ~/.nix_libs
rsync -aszvi /usr/lib/x86_64-linux-gnu/libGL.* ~/.nix_libs/
patchelf --set-rpath /lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu ~/.nix_libs/libGL.so.1.2.0
mkdir ~/.nix_libs/dri
rsync -aszvi /usr/lib/x86_64-linux-gnu/dri/i965_dri.so ~/.nix_libs/dri/
patchelf --set-rpath /lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu ~/.nix_libs/dri/i965_dri.so
cp -pi /nix/store/0fp3kp6kx12wqs593xwk7l6pbq0dkrdp-libpciaccess-0.13.4/lib/libpciaccess.so.0 ~/.nix_libs/
# edit: now works without the following lines
# (for OpenArena additionally:)
# (cp -pi /nix/store/31w31mc8immhpnmxvcl4l0fvc3i5iwh0-zlib-1.2.8/lib/libz.so.1 ~/.nix_libs/)
How to find out which libraries are required in ~/.nix_libs for some program:
Follow joepie91's instructions:
mkdir ~/.nix_libs
rsync -aszvi /usr/lib/x86_64-linux-gnu/libGL.* ~/.nix_libs/
patchelf --set-rpath /lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu ~/.nix_libs/libGL.so.1.2.0
Run your program (e.g. glxinfo, openscad or openarena) with LD_LIBRARY_PATH:
LD_LIBRARY_PATH=~/.nix_libs openscad
libGL error: unable to load driver: i965_dri.so
)Run the program again with strace:
LD_LIBRARY_PATH=~/.nix_libs strace openscad 2>&1 | less -S
and search the output for the error-message and the missing library or the fatal ENOENT.
By the way, glxinfo still aborts with glxinfo: : ATUSHûHìH-Ó : Error 18644416
(same for glxgears), but OpenSCAD and OpenArena work.
LD_LIBRARY_PATH=~/.nix_libs
is slightly dangerous with having standard libs in there (libz in particular). It means that all nix-installed stuff will use that libz instead of the one they were compiled against. But if the list is very small, it might cause no problems (and it's rather easy to set up).ldd
on the executables or libraries, but it won't show _dlopen_ed libs and some programs do use that to open libGL.libvdpau_*.so
. (I don't remember how libva works ATM.)LD_LIBRARY_PATH=~/.nix_libs is slightly dangerous with having standard libs in there (libz in particular). It means that all nix-installed stuff will use that libz instead of the one they were compiled against.
Since I only call some OpenGL-needing-programs with LD_LIBRARY_PATH=~/.nix_libs
, only those use that libz.
I would of course like to remove the standard libs from my ~/.nix_libs
, but I don't know how to do this without breaking the OpenGL-needing-programs, since the libs are only searched in .nix_libs and some "wrong" nix-store-paths:
open("/nix/store/nkp9sq3jj09wjxmq4h5zyaa0spc6nsrs-SDL-1.2.15/lib/libpciaccess.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/nix/store/ikgb8896hqcy7pz7n35v1y6qcifim9bi-libogg-1.3.2/lib/libpciaccess.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/nix/store/w0p7bn2rzyd4q8haggr5z7pyqh9kmmgk-libvorbis-1.3.5/lib/libpciaccess.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/user/.nix_libs/libpciaccess.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/nix/store/hd6km3hscbgl2yw8nx7lr5z9s8h89p04-glibc-2.21/lib/libpciaccess.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
(But I've removed libz now, since strangely it now works without ~/.nix_libs/libz.so.1 after uninstalling and reinstalling...)
DRI drivers are located by libGL
Unfortunately, the i965_dri.so is only searched in the wrong places, so I had to copy it to .nix_libs/dri/tls/i965_dri.so
:
open("/home/user/.nix_libs/dri/tls/i965_dri.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/user/.nix_libs/dri/i965_dri.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/dri/tls/i965_dri.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/dri/i965_dri.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
For inspecting (broken dynamic) linkage it seems easiest to run ldd on the executables or libraries
Yes, but neither ldd nor LD_DEBUG helped here, since they did not show the missing libraries.
Unfortunately, the i965_dri.so is only searched in the wrong places, so I had to copy it to .nix_libs/dri/tls/i965_dri.so:
That part is a very good solution, I think, except symlink should be better than copy (due to your OS updates).
Yes, but neither ldd nor LD_DEBUG helped here, since they did not show the missing libraries.
Hmm, then I suppose these are also cases using dlopen
, unfortunately. I know nothing better than strace
for that, which is what you used.
I just ran into a similar issue trying to get nix's blender running on Fedora: blender wouldn't find i965_dri.so
. Here are the steps that I had to do to make this work - notably I also had to set LIBGL_DRIVERS_PATH in addition to LD_LIBRARY_PATH (hence why I'm posting this here - this hasn't been mentioned above yet):
Run
LIBGL_DEBUG=verbose LD_LIBRARY_PATH=/path/to/drivers LIBGL_DRIVERS_PATH=/path/to/drivers blender
If this works, great! You can drop LIBGL_DEBUG=verbose
in future invokations.
LD_DEBUG=libs
may help too in step 2 in case you don't get enough output from LIBGL_DEBUG=verbose
- but I didn't have to use it.
i can reproduce it on elementary OS Freya (based on Ubuntu 14.04 LTS).
i copied the systems libGL.so and patched it, then openarena works.
# apt-get install libgl1-mesa-dev
$ cp /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0 ~/.nix_libs/
$ patchelf --set-rpath /lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu ~/.nix_libs/libGL.so.1.2.0
$ cd ~/.nix_libs
$ mv libGL.so.1.2.0 libGL.so
$ LD_LIBRARY_PATH=~/.nix_libs openarena
It still seems rather inconvenient that one needs to do update libGL by hand (after the host OS updates).
I've had success using the following wrapper script :
#! /bin/sh
set -x &&
sys=/usr/lib/x86_64-linux-gnu &&
LIBGL_DEBUG=verbose \
LIBGL_DRIVERS_PATH=$sys/dri \
LD_PRELOAD=\
$sys/libdrm.so:\
$sys/libdrm_intel.so:\
$sys/libdrm_nouveau.so:\
$sys/libdrm_radeon.so:\
$sys/libpciaccess.so.0:\
$sys/libz.so:\
$sys/libstdc++.so.6 \
exec "$@"
on ubuntu i would have to add a lot more librarys. it is easier to add a path like
$ LIBGL_DEBUG=verbose LIBGL_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri LD_LIBRARY_PATH=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu kdenlive
With openarena i get a Segmentation fault, with kde5.kdenlive this error:
$ LIBGL_DEBUG=verbose LIBGL_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri LD_LIBRARY_PATH=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu kdenlive
kdenlive: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /nix/store/2hp0a5arv6bi8zii79xhy23nagh7470s-qtbase-5.4.2/lib/libQt5Core.so.5)
kdenlive: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /nix/store/gfzkhby7nlz97r5g0ny8qwmlrjnsjm0y-icu4c-55.1/lib/libicui18n.so.55)
kdenlive: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /nix/store/gfzkhby7nlz97r5g0ny8qwmlrjnsjm0y-icu4c-55.1/lib/libicuuc.so.55)
this happens because the package needs GCC >=4.9 but Ubuntu 14.04 uses 4.8
so i installed it using nix with nix-env -iA nixos.pkgs.gcc
, add the library to the path and i can finally start it, but it also crashes with a Segmentation fault :(
$ LIBGL_DEBUG=verbose LIBGL_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri LD_LIBRARY_PATH=/nix/store/0lx4bbsik6xmi8qs0x0g76jha59m2m2n-user-environment/lib/:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu kdenlive
Couldn't start kglobalaccel from org.kde.kglobalaccel.service: QDBusError("org.freedesktop.DBus.Error.ServiceUnknown", "The name org.kde.kglobalaccel was not provided by any .service files")
mlt_repository_init: failed to dlopen /nix/store/h8jq0q7gyyh1x2hxssq6b9135b6kdjj3-mlt-0.9.6/lib/mlt/libmltavformat.so
(/nix/store/mhzz265j047cxsbmfrkci06j6wq77j47-gnutls-3.4.5/lib/libgnutls.so.30: symbol asn1_decode_simple_ber, version LIBTASN1_0_3 not defined in file libtasn1.so.6 with link time reference)
QFSFileEngine::open: No file name specified
QFSFileEngine::open: No file name specified
libGL: screen 0 does not appear to be DRI3 capable
libGL: pci id for fd 10: 1002:95c5, driver r600
libGL: OpenDriver: trying /usr/lib/x86_64-linux-gnu/dri/tls/r600_dri.so
libGL: OpenDriver: trying /usr/lib/x86_64-linux-gnu/dri/r600_dri.so
libGL: Can't open configuration file /home/davidak/.drirc: No such file or directory.
libGL: Can't open configuration file /home/davidak/.drirc: No such file or directory.
libGL: Using DRI2 for screen 0
Icon theme "oxygen" not found.
kf5.kiconthemes: Couldn't find current icon theme, falling back to default.
Icon theme "oxygen" not found.
Error: standard icon theme "oxygen" not found!
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
QWidget::setMaximumSize: (/QToolButton) Negative sizes (2,-2) are not possible
kf5.kxmlgui: Registering action "edit_select_all" under new name "select_all_tracks"
libDeckLinkAPI.so: cannot open shared object file: No such file or directory
QCoreApplication::postEvent: Unexpected null receiver
QFSFileEngine::open: No file name specified
ui/ui_standards.rc not found in ("/home/davidak/.config", "/etc/xdg/xdg-pantheon", "/etc/xdg")
cannot find .rc file "kdenliveui.rc" for component "kdenlive"
Speicherzugriffsfehler (Speicherabzug geschrieben)
the end again with strace:
stat("/usr/share/kdenlive/kdenliveui.rc", 0x7ffe41f78420) = -1 ENOENT (No such file or directory)
write(2, "cannot find .rc file \"kdenliveui"..., 62cannot find .rc file "kdenliveui.rc" for component "kdenlive"
) = 62
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\4\0\2\0\340\0\300\2\4\0\2\0\335\0\300\2", 16}], 1) = 16
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x2aabc68, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 0
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"N\0\4\0\337\0\300\2\6\0\300\2\17\2\0\0\1\30\v\0\343\0\300\2\6\0\300\2\0\0\0\0"..., 60}, {NULL, 0}, {"", 0}], 3) = 60
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\2\0\7\0\343\0\300\2\1\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\240b\0\22\0\30\0"..., 400}], 1) = 400
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 1
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\203.\7\0\343\0\300\2\2\0\300\2\10\0\1\0`\0\0\0\4\0\1\0`\0\0\0\203.\5\0"..., 48}, {NULL, 0}, {"", 0}], 3) = 48
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\2\0\5\0\343\0\300\2\0\n\0\0\0\0\0\0\177\240b\0\22\0\7\0\343\0\300\2F\1\0\0"..., 116}], 1) = 116
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x7ffe41f77d20, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x7ffe41f77d24, FUTEX_WAIT_PRIVATE, 1, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 0
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\22\0\17\0\343\0\300\2#\0\0\0#\0\0\0 \0\0\0\t\0\0\0\3\0\0\0\1\0\0\0"..., 92}], 1) = 92
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 1
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"+.\1\0", 4}, {NULL, 0}, {"", 0}], 3) = 4
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 1
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
getcwd("/home/davidak", 4098) = 14
getcwd("/home/davidak", 4098) = 14
getcwd("/home/davidak", 4098) = 14
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\22\0\7\0\343\0\300\2l\1\0\0\4\0\0\0 \0\0\0\1\0\0\0\5\0\0\0\22\0\30\0"..., 240}], 1) = 240
futex(0x2aabc68, FUTEX_WAKE_PRIVATE, 1) = 1
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x8} ---
+++ killed by SIGSEGV (core dumped) +++
Speicherzugriffsfehler (Speicherabzug geschrieben)
@davidak: that's all because setting LD_LIBRARY_PATH
overrides the libs for all binaries, even nix-installed ones. Note the broken dependency chain:
/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /nix/store/2hp0a5arv6bi8zii79xhy23nagh7470s-qtbase-5.4.2/lib/libQt5Core.so.5)
I may be missing something here as I'm not actually running NixOS, but, I'm not sure I follow why mesa
has to be patched to look for it's dri libraries in /run/opengl-driver{,-32}/lib.
That is, say it was't patched and looked in the $drivers
output instead. Wouldn't this still work fine so long as the appropriate libGL is symlinked into the /run/... directory that is in LD_LIBRARY_PATH
.
If it is the mesa one, then it would find its drivers in the $drivers
output and if it was some proprietary one (NVIDIA/AMD) then it wouldn't care about the mesa dri drivers.
We plan to get rid of that $LD_LIBRARY_PATH
on NixOS, or at least reduce its usage, as it's an error-prone technique.
@vcunat will that solve also issues with programs installed with Nix on non-nixos machines?
No, I don't think it would really help on non-NixOS.
The wrapper script posted in https://github.com/NixOS/nixpkgs/issues/9415#issuecomment-170661702 is probably the best solution for users of Nix on host systems other than NixOS. You'll have to adapt the paths and the selection of libraries for your local machine, of course, but I've run Blender, mplayer, and mpv successfully on openSUSE with that approach.
Perhaps, though preloading general libs like libz and libstdc++ is also asking for trouble. The problem is that the environment variables don't affect just libGL but everything.
It is also no intuitive solution for "ordinary users" of Nix. You should be able to just install and use a program. (if possible somehow)
Well, we all agree that we don't like the LD_PRELOAD solution. However, what do you suggest we should do instead? Stating how things "should" be is one thing. Suggesting a viable path to that state is another.
@peti Okay. Unfortunately i have no better solution. :/
I hope we can come up with something that also works outside of NixOS.
It would, in particular, be nice to avoid paths like /run/opengl-driver{,-32}/lib showing up in the Nix expressions as changing them to something more appropriate for non-NixOS environments means you can't use the binary cache. To that end I would suggest either
With regard the LD_LIBRARY_PATH
, possibly we should be doing the indirection through something like the xorg_sys_opengl
package. That is, a package that provides symlinks from the store directly to outside libraries or (better) symlinks from the store to a second level of indirection symlinks like /run/opengl-driver{,-32}/lib that then symlink to the final libraries.
Why do you think /nix/*
is more suitable than /run/*
? When I read FHS item on wiki, /run
seems to fit very well:
Run-time variable data: Information about the running system since last boot, e.g., currently logged-in users and running daemons.
Indirection through a package may seem nice at first, but note that it would have to be an inherently impure package, as the symlinks have to lead to different locations based on configuration of your OS. For example on an Ubuntu instance I see it's just in /usr/lib/nvidia-352/
which will change even on major driver update (!).
Maybe a Script or systemd timer that is run at startup and collects all needed paths and symlinks them?
@vcunat I was thinking mostly of permissions and containment on non-NixOS systems
I see. Though, on NixOS it seems strange to put it in there, and to share binaries we probably want to share the paths. I don't know.
Anyone had any luck with proprietary nvidia driver?
Has anyone given any thought to overriding mesa
(or other packages depended upon for libGL and friends) in the user's local config with a version matching what the user has on their system?
I'm sure it's not quite as simple as this, but it does seem to fit quite neatly into the existing packaging framework.
How about we add wrappers for the different distro's to Nixpkgs and have a function libGLWrap
which creates a derivation that wraps the original derivation and where the specific wrapper is chosen with a nixpkgs.config
option?
I am trying to install mrtrix3's mrview on Ubuntu (a QT app) using https://github.com/NixOS/nixpkgs/issues/9415#issuecomment-170661702, does it make sense for me to have to go so far as to including X libraries?
I have managed to get the executable to load using the following, although it does not actually work apart from some of the toolbar.
#! /bin/sh
set -x &&
sys=/lib/x86_64-linux-gnu &&
usr=/usr/lib/x86_64-linux-gnu &&
nvi=/usr/lib/nvidia-367 &&
LIBGL_DEBUG=verbose \
LD_PRELOAD=$usr/libdrm.so:\
$usr/libX11.so.6:\
$usr/libXext.so.6:\
$usr/libxcb.so.1:\
$usr/libXau.so.6:\
$usr/libXdmcp.so.6:\
$nvi/libGL.so:\
$nvi/libGLX.so.0:\
$nvi/libGLdispatch.so.0 \
"$@"
https://github.com/deepfire/nix-install-vendor-gl is an attempt at automated, clean solution to this problem.
Currently nVidia-only -- AMD and Intel contributions welcome!
Btw, the original concept on how to solve this is due to @cleverca22, who first helped me to overcome the GL-no-comprendo issue on SteamOS.
Any updates / progress?
@deepfire does your solution support intel and amd cards yet?
@alexozer, no, unfortunately not -- I've had very little free time lately..
I have a script that makes Intel work in Ubuntu. I spent some time trying to fit it into nix-install-vendor-gl but the task seems overly complex for me so I'm giving up for now. Feel free to give it a try.
Anyone had any luck with proprietary nvidia driver?
@olejorgenb I use LD_LIBRARY_PATH=/usr/lib/nvidia-375 myprogram
to get OpenGL programs inside nix-shell
on Ubuntu to work on NVIDIA.
FWIW I have this sytemd unit on ubuntu, horribly hardcoded to a specific driver version...
[Unit]
Description="Link OpenGL driver for nix programs"
[Service]
Type=oneshot
ExecStart=/bin/mkdir -p /run/opengl-driver/lib
ExecStart=/bin/sh -c 'ln -s /usr/lib/x86_64-linux-gnu/libcuda.so* /usr/lib/x86_64-linux-gnu/libXext.so* /usr/lib/nvidia-375/* /run/opengl-driver/lib/'
TimeoutSec=0
StandardInput=tty
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Installation works, running it does not.