Lor*_*ic- 5 linux opengl nixos nix
首先,我对 ELF 和所有这些库链接过程不太满意。但是在玩了一下 Nix/NixOS 之后,我仍然不太理解图形驱动程序链接到二进制文件的方式。
Nix/NixOS 的设计之一是 OpenGL 驱动程序不能成为可重现环境的一部分,因为它将依赖于目标硬件。
大多数 Nix 程序都会在“/run/opengl-driver/lib”中找到 OpenGL 驱动程序。
对于 NixOS 系统,驱动程序将下载并安装在此路径中,然后可以LD_LIBRARY_PATH在配置中使用全局定义hardware.opengl.setLdLibraryPath = true(请参阅https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/hardware /opengl.nix#L166)。
但是,在非 NixOS 操作系统的情况下,我可以注意到程序仍然引用此/run/opengl-driver/lib路径,但未LD_LIBRARY_PATH在任何地方定义。所以我的问题是:为什么二进制文件仍然在非 NixOS 系统上将驱动程序搜索到 /run/opengl-driver/lib 中?
我这里的例子是康普顿。它在 Nixpkgs 中的派生位于以下地址。
我可以使用 strace 看到程序尝试libGLX_mesa.so在运行时加载库。
$ strace -e openat $(readlink -f $(which compton)) 2>&1 | grep -E ".*opengl.*.so"
openat(AT_FDCWD, "/run/opengl-driver/lib/tls/haswell/x86_64/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/tls/haswell/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/tls/x86_64/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/tls/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/haswell/x86_64/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/haswell/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/x86_64/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/run/opengl-driver/lib/libGLX_mesa.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Run Code Online (Sandbox Code Playgroud)
事实上,使用ldd揭示了libGLX_mesa.so不是动态链接的。
$ ldd $(readlink -f $(which compton)) | grep mesa | wc -l
0
Run Code Online (Sandbox Code Playgroud)
所以我的猜测是这个库是在运行时加载的,可能使用dlopen. dlopen我在https://github.com/chjj/compton中找不到任何参考,但也许它是从 compton 链接的库之一间接完成的。
如果我的猜测是正确的,我发现能够通过搜索环境变量中定义的路径(当路径是叶名称时)dlopen找到所需的库。LD_LIBRARY_PATH
因此,我的下一步是使用以下两个命令之一来分析 compton 在运行时可用的环境变量。
$ strace -v -s 10000 -e execve $(readlink -f $(which compton)) 2>&1 | grep LD_LIBRARY_PATH | wc -l
0
$ ltrace -e getenv $(readlink -f $(which compton)) 2>&1 | grep LD_LIBRARY_PATH | wc -l
0
Run Code Online (Sandbox Code Playgroud)
但这LD_LIBRARY_PATH似乎没有定义。我有点陷入我的分析中。
回顾一下,我的问题是:
/run/opengl-driver/lib注入到compton中的?/usr/lib/x86_64-linux-gnu/足够/run/opengl-drivers/lib/?