From 3eaf8675650e79c61dcbe442b7c9df83a9ec5d28 Mon Sep 17 00:00:00 2001 From: Guillaume Bouchard Date: Sat, 16 Sep 2017 14:28:57 +0200 Subject: [PATCH] More robust dependency lookup --- README.md | 24 +++++++++++++++++++----- default.nix | 2 +- nixGL | 28 +++++++++++++++------------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 2ebebe0..9e4d376 100644 --- a/README.md +++ b/README.md @@ -46,13 +46,27 @@ 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. +The idea is really simple and should work reliably in most cases. -## Library paths +However there is still two configurations variables hardcoded in the wrapper. -The path of where the `libGL.so` library can be found on your system, usually `/usr/lib`. +- `ignored`: the list of all nix packages which may contain a wrong `libGL.so`. +- `systemLibs`: the list of where on the host system the `libGL.so` can be found. -## Name of the Nix package which contains `libGL.so` +Open a bug / pull request if this does not work on your distribution / driver. -This package will be ignored by the wrapper. It is currently hardcoded as `mesa-noglu` but this can be fixed. +It works with `primus`, but there is some artifacts. +## Fundamental issue + +If your program libraries depends on different version of the same library, for example, this dependency tree: + +``` +program + libFoo-1.2 + libBar-1.4 + libTurtle-1.6 + libBar-1.2 +``` + +One version or the other of `libBar` may be used. In practice this does not happen a lot. \ No newline at end of file diff --git a/default.nix b/default.nix index b570c0d..9f1e8b7 100644 --- a/default.nix +++ b/default.nix @@ -8,7 +8,7 @@ rec { name = "nixGL-${version}"; version = "1.0.0"; - buildInputs = [ pkgs.python3 pkgs.which pkgs.patchelf ]; + buildInputs = [ pkgs.python3 pkgs.which pkgs.binutils ]; outputs = [ "out" ]; src = ./.; diff --git a/nixGL b/nixGL index 481dfda..6326959 100755 --- a/nixGL +++ b/nixGL @@ -16,18 +16,19 @@ systemLibs = [b"/usr/lib", b"/lib"] 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':')) +# extract libs deps of the program +paths = [] +for line in subprocess.check_output(['ldd', realProg]).split(b'\n'): + line = line.split() + if len(line) == 4: + lib = line[2] + path = os.path.dirname(lib) -# 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()) + for c in ignored: + if c in path: + break + else: + paths.append(path) # build the new environment newenv = os.environb @@ -42,7 +43,8 @@ oldLdLibraryPath = newenv.get(b'LD_LIBRARY_PATH', b'').split() # 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 +newLibraryPath = b':'.join(oldLdLibraryPath + paths + systemLibs) + +newenv.update({b'LD_LIBRARY_PATH': newLibraryPath}) -newenv.update({b'LD_LIBRARY_PATH': b':'.join(newLibraryPath)}) os.execvpe(prog, cmd, newenv)