Saya menggunakan nix
dalam "mode single-user" dalam sistem di mana saya bukan root (lihat di bawah untuk deskripsi pengaturan nix saya).
Saya ingin cepat menjalankan salah satu binari saya yang secara dinamis terkait dengan perpustakaan yang tidak ada dalam sistem.
Jadi, saya telah menginstal perpustakaan dengan nix
:
$ nix-env -qa 'gmp'
gmp-4.3.2
gmp-5.1.3
$ nix-env -i gmp-5.1.3
Namun perpustakaan masih belum ditemukan oleh tautan:
$ 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)
$
Lihat, ini ada di sistem file:
$ 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
$
Apa yang harus saya lakukan agar perpustakaan yang diinstal nix
"terlihat"?
Mungkin, script user-instalasi standar nix
memodifikasi .bash_profile
untuk menambahkan nya bin/
ke dalam PATH
, tapi tidak melakukan sesuatu yang analog untuk perpustakaan.
Pengaturan nix saya:
Satu-satunya hal yang saya minta dilakukan root untuk saya adalah mkdir -m 0755 /nix && chown ivan /nix
:, jika tidak, saya telah mengikuti prosedur instalasi nix sederhana standar. Jadi sekarang saya bisa menggunakan program khusus dari paket nix. Saya tidak dapat melakukan ini dengan baik tanpa bantuan dari root sama sekali, yaitu, tanpa /nix/
, karena /nix/
tidak tersedia untuk saya; Saya tentu saja dapat menggunakan direktori lain, tetapi kemudian paket-paket biner pra-dibangun tidak akan valid dan semua paket harus dibangun kembali, menurut dokumentasi nix. Dalam kasus saya, lebih mudah untuk meminta /nix/
saya.
Hal lain yang saya lakukan adalah menambahkan ~/.bash_profile
:
export NIX_CONF_DIR=/nix/etc/nix
sehingga saya bisa mengedit nix.conf
. (Seharusnya di root-dikendalikan /etc/
sebaliknya. Saya melakukannya karena saya ingin build-max-jobs
dan build-cores
pengaturan di dalamnya.)
sumber
nix-env
, belum laginix.conf
. OS apa ini? Juga, apa yang Andanix
maksud dengan referensi berulang ? Saya hanya pernah mendengarnya digunakan sebagai singkatanUnix
, tetapi sepertinya Anda menggunakannya dalam konteks yang lebih spesifik.nix
adalah manajer paket modern , dan nixOS adalah distro, dan Hydra adalah sistem untuk terus-menerus membangun kembali paket nix, dan nixOps adalah alat untuk mengelola infrastruktur (jaringan beberapa host) secara deklaratif, dan menonaktifkan untuk mengelola serangkaian layanan secara deklaratif (di atas infrastruktur).guix
adalah keturunan GNU darinix
, dengan distro (dipromosikan sebagai 100% gratis IICguix
.Jawaban:
TL; DR
Solusi yang digunakan adalah menggunakan
patchelf
(jika Anda harus berurusan dengan versi glibc yang tidak cocok: di sistem host dan satu lib lix telah dikaitkan dengan), lihat bagian kedua dari cerita saya.Mencoba pendekatan yang biasa
Mencoba menggunakan LD_LIBRARY_PATH
Yah, saya telah menyiapkan variabel lingkungan untuk ini di
~/.bash_profile
:tapi itu belum semuanya!
Sekarang ada masalah dengan menautkan dengan berbagai versi
libc
:Menyortir 2 versi glibc
Kesalahan paling mengejutkan di sini adalah:
karena
nix
pasti sudah menginstal versiglibc
yang digunakan oleh nyalibgmp
!Dan memang,
glibc
darinix
sana:Mungkin,
glibc
tidak tersedia untuk pengguna, jadi ketika saya menjalankan biner saya, sistemglibc
dimuat terlebih dahulu. Bukti:Oke, kita juga bisa mencoba membuatnya
glibc
terlihat oleh pengguna:Maka semuanya buruk:
Jadi, sepertinya bukan pekerjaan yang mudah jika Anda ingin memuat pustaka dari
nix
saat menjalankan binari Anda sendiri ...Untuk saat ini, saya berkomentar
dan lakukan di sesi shell:
Perlu berpikir lebih jauh. (Baca tentang __vdso_time: modus valid untuk dlopen () : memiliki lain
glibc
diLD_LIBRARY_PATH
diharapkan kecelakaan, karena Andald-linux-x86-64.so.2
tidak akan cocok Andalibc.so.6
Memiliki beberapa versi glibc pada sistem tunggal adalah mungkin, tapi sedikit rumit, seperti yang dijelaskan dalam jawaban ini..)Solusi yang dibutuhkan: patchelf
Jadi, path ke dynamic linker adalah hard-coded dalam biner. Dan linker dinamis yang digunakan adalah dari sistem (dari host glibc), bukan dari nix. Dan karena penghubung dinamis tidak cocok dengan glibc yang kita inginkan dan perlu kita gunakan, itu tidak berfungsi.
Solusi sederhana dan berhasil adalah patchelf .
Setelah itu berhasil. Anda masih perlu mengutak-atik
LD_LIBRARY_PATH
.Jika - seperti dalam kasus tidak sempurna saya - beberapa perpustakaan diambil dari nix, tetapi beberapa diambil dari sistem host (karena saya belum menginstalnya dengan
nix-env -i
), Anda harus menentukan kedua path ke nix libs, dan ke sistem host Anda, libs inLD_LIBRARY_PATH
(itu sepenuhnya mengesampingkan jalur pencarian default).langkah tambahan: patchelf untuk jalur pencarian perpustakaan
(dari
patchelf
halaman)Demikian juga, Anda dapat mengubah
RPATH
, jalur pencarian tautan yang tertanam ke executable dan perpustakaan dinamis:Ini menyebabkan tautan dinamis untuk mencari
/opt/my-libs/lib
dan/foo/lib
untuk perpustakaan bersama yang dibutuhkan oleh program. Tentu saja, Anda juga dapat mengatur variabel lingkunganLD_LIBRARY_PATH
, tetapi itu seringkali tidak nyaman karena memerlukan skrip wrapper untuk mengatur lingkungan.sumber
Selain "mode pengguna tunggal" Nix, saya memberikan jawaban untuk pengguna NixOS . Anda biasanya tidak dapat menjalankan file biner di NixOS.
Jika Anda menginstal paket menggunakan lokal
nix-env -i
, semua.so
file Anda disimpan~/.nix-profile/lib/
.Jika Anda menginstal paket secara global dengan menetapkannya
/etc/nixos/configuration.nix
,.so
file yang sesuai dapat ditemukan di/nix/var/nix/profiles/system/sw/lib/
. Lebih tepatnya, hanya symlinks ke file yang sesuai di suatu tempat di/nix/store/
dalam direktori itu.Jadi jika Anda menginstal paket secara global, solusi Ivan Zakharyaschev menjadi:
Agar perintah pertama berfungsi, Anda harus menginstal
glibc
secara global. Anda juga dapat memodifikasi perintah kedua jika Anda memiliki paket yang diinstal secara global dan per-pengguna:Mungkin saja
.so
file yang dibutuhkan tidak diinstal di sistem, jadi Anda akan memiliki kesalahan seperti:Saya tidak yakin bagaimana menemukan paket yang sesuai untuk file yang hilang secara umum, tetapi Anda dapat google nama
.so
file dan menginstal paket yang sesuai dan mencoba untuk menjalankan executable Anda dengan kustomLD_LIBRARY_PATH
lagi.sumber