First version

This commit is contained in:
Guillaume Bouchard 2017-09-16 13:45:18 +02:00
commit c17063d377
3 changed files with 135 additions and 0 deletions

58
README.md Normal file
View 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
View 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
View 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)