commit 3eaf8675650e79c61dcbe442b7c9df83a9ec5d28
parent 23acee6ede90c30fd938584975cbaead08874b7f
Author: Guillaume Bouchard <guillaum.bouchard@gmail.com>
Date: Sat, 16 Sep 2017 14:28:57 +0200
More robust dependency lookup
Diffstat:
3 files changed, 37 insertions(+), 20 deletions(-)
diff --git 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
@@ -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
@@ -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':'))
-
-# 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())
+# 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)
+
+ 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)