Я использую nix
в «однопользовательском режиме» в системе, где я не root (см. Ниже описание моей настройки nix).
Я хотел быстро запустить один из моих двоичных файлов, который динамически связан с библиотекой, которая отсутствует в системе.
Итак, я установил библиотеку с nix
:
$ nix-env -qa 'gmp'
gmp-4.3.2
gmp-5.1.3
$ nix-env -i gmp-5.1.3
Но библиотека все еще не найдена компоновщиком:
$ ldd -r ../valencies
../valencies: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ../valencies)
../valencies: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ../valencies)
linux-vdso.so.1 => (0x00007fffbbf28000)
/usr/local/lib/libsnoopy.so (0x00007f4dcfbdc000)
libgmp.so.10 => not found
libffi.so.5 => /usr/lib64/libffi.so.5 (0x00007f4dcf9cc000)
libm.so.6 => /lib64/libm.so.6 (0x00007f4dcf748000)
librt.so.1 => /lib64/librt.so.1 (0x00007f4dcf540000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f4dcf33c000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4dcf11f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4dced8b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4dcfde7000)
undefined symbol: __gmpz_gcd (../valencies)
undefined symbol: __gmpn_cmp (../valencies)
undefined symbol: __gmpz_mul (../valencies)
undefined symbol: __gmpz_fdiv_r (../valencies)
undefined symbol: __gmpz_fdiv_q_2exp (../valencies)
undefined symbol: __gmpz_com (../valencies)
undefined symbol: __gmpn_gcd_1 (../valencies)
undefined symbol: __gmpz_sub (../valencies)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference (../valencies)
undefined symbol: __gmpz_fdiv_q (../valencies)
undefined symbol: __gmpz_fdiv_qr (../valencies)
undefined symbol: __gmpz_add (../valencies)
undefined symbol: __gmpz_init (../valencies)
undefined symbol: __gmpz_ior (../valencies)
undefined symbol: __gmpz_mul_2exp (../valencies)
undefined symbol: __gmpz_xor (../valencies)
undefined symbol: __gmpz_and (../valencies)
symbol __fdelt_chk, version GLIBC_2.15 not defined in file libc.so.6 with link time reference (../valencies)
undefined symbol: __gmpz_tdiv_qr (../valencies)
undefined symbol: __gmp_set_memory_functions (../valencies)
undefined symbol: __gmpz_tdiv_q (../valencies)
undefined symbol: __gmpz_divexact (../valencies)
undefined symbol: __gmpz_tdiv_r (../valencies)
$
Смотри, он присутствует в файловой системе:
$ find / -name 'libgmp.so.10' 2>/dev/null
/nix/store/mnmzq0qbrvw6dv1k2vj3cwz9ffdh05zr-user-environment/lib/libgmp.so.10
/nix/store/fnww2w81hv5v3dl9gsb7p4llb7z7krzd-gmp-5.1.3/lib/libgmp.so.10
$
Что мне делать, чтобы установленные библиотеки nix
были "видны"?
Возможно, стандартный пользовательский скрипт установки nix
модифицирует, .bash_profile
чтобы добавить его bin/
в PATH
, но не делает что-то аналогичное для библиотек.
Моя установка NIX:
Единственное, что я попросил, чтобы root сделал для меня, было: mkdir -m 0755 /nix && chown ivan /nix
иначе я следовал стандартной простой процедуре установки nix. Так что теперь я могу использовать пользовательские программы из пакетов nix. Я не смог бы сделать это красиво без какой-либо помощи со стороны рута, т. Е. Без /nix/
, потому что /nix/
был недоступен для меня; Я мог бы, конечно, использовать другой каталог, но тогда предварительно собранные двоичные пакеты не будут действительными, и все пакеты должны быть перестроены, согласно документации nix. В моем случае было проще попросить /nix/
меня.
Еще одна вещь, которую я сделал, добавляет ~/.bash_profile
:
export NIX_CONF_DIR=/nix/etc/nix
так что я могу редактировать nix.conf
. (В /etc/
противном случае он должен был находиться в рут-контроле . Я сделал это, потому что хотел build-max-jobs
и build-cores
настройки в нем.)
источник
nix-env
, не говоря уже оnix.conf
. Что это за ОС? Кроме того, что вы повторяли ссылки, чтобыnix
иметь в виду? Я только когда-либо слышал, чтобы это использовалось как аббревиатураUnix
, но кажется, что вы используете это в более конкретном контексте.nix
это современный менеджер пакетов , и nixOS является дистрибутивом, а Hydra система для постоянно восстановления NIX пакетов, и nixOps является инструментом для управления инфраструктурой (сеть из нескольких хостов) декларативно и disNix для управления набором услуг декларативно (поверх инфраструктуры).guix
является потомком GNUnix
с дистрибутивом (продвигается как 100% libre IICguix
.Ответы:
TL; DR
Рабочее решение использует
patchelf
(если вам приходится иметь дело с несовпадающими версиями glibc: в хост-системе и с одной библиотекой nix были связаны), смотрите вторую половину моей истории.Пробуя обычный подход
Попытка использовать LD_LIBRARY_PATH
Ну, я установил переменную окружения для этого в
~/.bash_profile
:но это не все!
В настоящее время существуют проблемы со связыванием с различными версиями
libc
:Разбираемся 2 версии glibc
Самая удивительная ошибка здесь:
потому что
nix
должен был установить версию,glibc
которая используется егоlibgmp
!И действительно,
glibc
отnix
там есть:Возможно,
glibc
он не был доступен пользователю, поэтому, когда я запустил свой двоичный файл, системаglibc
была загружена первой. Доказательство:Хорошо, мы можем попытаться сделать
glibc
видимым для пользователя тоже:Тогда все плохо
Так что, если вы хотите загружать библиотеки
nix
при запуске ваших собственных двоичных файлов , это кажется не простой задачей ...Сейчас я комментирую
и делать в сеансе оболочки:
Нужно больше думать. (Читайте о __vdso_time: неверный режим для dlopen () : имея другой
glibc
ин ,LD_LIBRARY_PATH
как ожидается , к краху, потому что вашld-linux-x86-64.so.2
не будет соответствовать вашимlibc.so.6
Наличие нескольких версий Glibc на одной системе можно, но немного хитрым, как описано в этом ответе.) .Нужное решение: patchelf
Таким образом, путь к динамическому компоновщику жестко запрограммирован в двоичном файле. И динамический компоновщик используется из системы (с хоста glibc), а не из nix. А поскольку динамический компоновщик не соответствует glibc, который мы хотим и должны использовать, он не работает.
Простое и рабочее решение - патчелф .
После этого все работает. Вы все еще должны возиться с
LD_LIBRARY_PATH
хотя.Если - как в моем несовершенном случае - некоторые библиотеки взяты из nix, но некоторые взяты из хост-системы (потому что я их не установил
nix-env -i
), вы должны указать оба пути к библиотекам nix, и к вашей системе хостаLD_LIBRARY_PATH
(он полностью переопределяет путь поиска по умолчанию).дополнительный шаг: patchelf для пути поиска библиотеки
(со
patchelf
страницы)Кроме того, вы можете изменить
RPATH
путь поиска компоновщика, встроенный в исполняемые файлы и динамические библиотеки:Это заставляет динамический компоновщик искать
/opt/my-libs/lib
и/foo/lib
совместно использовать библиотеки, необходимые программе. Конечно, вы также можете установить переменную средыLD_LIBRARY_PATH
, но это часто неудобно, так как для настройки среды требуется скрипт-обертка.источник
В дополнение к «однопользовательскому режиму» Nix, я даю ответ пользователям NixOS . Обычно вы не можете запускать двоичные файлы в NixOS.
Если вы устанавливаете пакеты локально
nix-env -i
, все ваши.so
файлы хранятся в~/.nix-profile/lib/
.Если вы устанавливаете пакеты глобально , указав их
/etc/nixos/configuration.nix
, соответствующие.so
файлы можно найти в/nix/var/nix/profiles/system/sw/lib/
. Вернее,/nix/store/
в этом каталоге находятся только символические ссылки на соответствующие файлы .Таким образом, если вы устанавливаете пакеты глобально, решение Ивана Захарящева становится:
Чтобы первая команда работала, вам нужно установить
glibc
глобально. Вы также можете изменить вторую команду, если у вас установлены пакеты как глобально, так и для каждого пользователя:Может случиться так, что нужный
.so
файл просто не установлен в системе, поэтому у вас будет такая ошибка:Я не уверен, как найти соответствующий пакет для отсутствующего файла в целом, но вы можете погуглить имя
.so
файла и установить соответствующий пакет и попробовать снова запустить свой исполняемый файл с кастомомLD_LIBRARY_PATH
.источник