Как путь libs "/ run / opengl-driver" внедряется в двоичные файлы Nix, такие как compton - PullRequest
0 голосов
/ 29 января 2020

Во-первых, мне не очень нравится ELF и весь этот процесс связывания библиотек. Но после того, как я немного поиграл с Nix / NixOS, я все еще не совсем понял, как драйверы graphi c связаны в двоичные файлы.

Один из проектов Nix / NixOS заключается в том, что драйвер OpenGL не может быть частью воспроизводимой среды, поскольку он будет зависеть от целевого оборудования.

Большинство программ Nix находят драйверы OpenGL в "/run/opengl-driver/lib".

In В случае системы 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 нигде не определен. И вот мой вопрос: почему двоичный файл все еще ищет драйверы в / run / opengl-driver / lib в системе, отличной от NixOS?

Мой пример здесь - compton. Его вывод в Nixpkgs находится по следующему адресу:

https://github.com/NixOS/nixpkgs/blob/274e095f761b2da76a376d105c41591739350b14/pkgs/applications/window-managers/compton/default.nix#L51

Я вижу, используя 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)

Действительно, использование ldd показывает, что libGLX_mesa.so не является динамически связанным.

$ ldd $(readlink -f $(which compton)) | grep mesa | wc -l
0

Так что я предполагаю, что эта библиотека загружается во время выполнения, возможно, с использованием dlopen , Я не могу найти ссылку на dlopen в https://github.com/chjj/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

Но это LD_LIBRARY_PATH, похоже, не определено. И я как бы застрял в своем анализе здесь.

Итак, подведем итог, мои вопросы:

  • Как этот путь opengl /run/opengl-driver/lib вводится в compton?
  • Каким был бы стандартный способ добавления этого пути к библиотеке в программы, требующие графических драйверов c в Nix?
  • И последний вопрос, на самом деле не связанный с этим анализом, но: если вы хотите, чтобы Compton работал на -NixOS система, будет ли достаточно вручную связать библиотеки opengl с /usr/lib/x86_64-linux-gnu/ до /run/opengl-drivers/lib/?
...