First version
This commit is contained in:
commit
c17063d377
58
README.md
Normal file
58
README.md
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
This tool tries to solve the "OpenGL" problem on nix.
|
||||||
|
|
||||||
|
# Motivation
|
||||||
|
|
||||||
|
You use Nix on any distribution, and any GL application installed fails with this error:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ program
|
||||||
|
libGL error: unable to load driver: i965_dri.so
|
||||||
|
libGL error: driver pointer missing
|
||||||
|
libGL error: failed to load driver: i965
|
||||||
|
libGL error: unable to load driver: i965_dri.so
|
||||||
|
libGL error: driver pointer missing
|
||||||
|
libGL error: failed to load driver: i965
|
||||||
|
libGL error: unable to load driver: swrast_dri.so
|
||||||
|
libGL error: failed to load driver: swrast
|
||||||
|
```
|
||||||
|
|
||||||
|
This library contains a wrapper which is able to launch GL application:
|
||||||
|
|
||||||
|
```
|
||||||
|
nixGL program
|
||||||
|
```
|
||||||
|
|
||||||
|
# Installation / Usage
|
||||||
|
|
||||||
|
Clone this git repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/guibou/nixGL
|
||||||
|
```
|
||||||
|
|
||||||
|
(Optional) installation:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd nixGL
|
||||||
|
nix-build
|
||||||
|
nix-env -i ./result
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```
|
||||||
|
nixGL program args
|
||||||
|
```
|
||||||
|
|
||||||
|
# Limitations
|
||||||
|
|
||||||
|
The idea is really simple and should work reliably. However there is still two configurations variables hardcoded in the wrapper. Open a bug / pull request if this does not work on your distribution / driver.
|
||||||
|
|
||||||
|
## Library paths
|
||||||
|
|
||||||
|
The path of where the `libGL.so` library can be found on your system, usually `/usr/lib`.
|
||||||
|
|
||||||
|
## Name of the Nix package which contains `libGL.so`
|
||||||
|
|
||||||
|
This package will be ignored by the wrapper. It is currently hardcoded as `mesa-noglu` but this can be fixed.
|
||||||
|
|
29
default.nix
Normal file
29
default.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ system ? builtins.currentSystem }:
|
||||||
|
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> { inherit system; };
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
nixGl = pkgs.stdenv.mkDerivation rec {
|
||||||
|
name = "nixGL-${version}";
|
||||||
|
version = "1.0.0";
|
||||||
|
|
||||||
|
buildInputs = [ pkgs.python3 pkgs.which pkgs.patchelf ];
|
||||||
|
outputs = [ "out" ];
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
cp nixGL $out/bin
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with pkgs.stdenv.lib; {
|
||||||
|
description = "A tool to launch OpenGL application on system other than NixOS";
|
||||||
|
homepage = "https://github.com/guibou/nixGL";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
48
nixGL
Executable file
48
nixGL
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# Any rpath with this pattern is ignored
|
||||||
|
# TODO: perhaps libOpenGL.so in nix exists in other packages, we
|
||||||
|
# should extend this list
|
||||||
|
ignored = [b'mesa-noglu']
|
||||||
|
|
||||||
|
# These are the list of system library which are added
|
||||||
|
# TODO: extend this list for other systems
|
||||||
|
systemLibs = [b"/usr/lib", b"/lib"]
|
||||||
|
|
||||||
|
# extract command line and real path of the program
|
||||||
|
cmd = (prog, *args) = sys.argv[1:]
|
||||||
|
realProg = subprocess.check_output(["which", prog]).strip()
|
||||||
|
|
||||||
|
# extract rpath of the program
|
||||||
|
rpaths = map(bytes.strip, subprocess.check_output(
|
||||||
|
['patchelf', '--print-rpath', realProg]).split(b':'))
|
||||||
|
|
||||||
|
# filter rpath, removing ignored and empty paths
|
||||||
|
dir = []
|
||||||
|
|
||||||
|
for i in rpaths:
|
||||||
|
for c in ignored:
|
||||||
|
if c not in i:
|
||||||
|
if i.strip():
|
||||||
|
dir.append(i.strip())
|
||||||
|
|
||||||
|
# build the new environment
|
||||||
|
newenv = os.environb
|
||||||
|
oldLdLibraryPath = newenv.get(b'LD_LIBRARY_PATH', b'').split()
|
||||||
|
|
||||||
|
# The build order is IMPORTANT
|
||||||
|
# first, any LD_LIBRARY_PATH from outside world. That's the default
|
||||||
|
# behavior, LD_LIBRARY_PATH has precedance over rpath
|
||||||
|
# Then, the different directory which satisfy our rpaths
|
||||||
|
# The the system library where the openGL lib can be located
|
||||||
|
|
||||||
|
# This ensure three properties:
|
||||||
|
# a) system library (and libOpenGL.so) are used AFTER the one of nix
|
||||||
|
# b) the executible respect the LD_LIBRARY_PATH for an user viewpoint
|
||||||
|
newLibraryPath = oldLdLibraryPath + dir + systemLibs
|
||||||
|
|
||||||
|
newenv.update({b'LD_LIBRARY_PATH': b':'.join(newLibraryPath)})
|
||||||
|
os.execvpe(prog, cmd, newenv)
|
Loading…
Reference in New Issue
Block a user