
nix
root以外のシステムで「シングルユーザーモード」として使用しています(以下のnix設定の説明を参照)。
システムに存在しないライブラリに動的にリンクされたバイナリの1つをすばやく実行したいと思います。
だからライブラリをインストールしました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
私のKnicks設定:
私がルートに要求する唯一のことは次のとおりです。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
答え1
長い話を短く
考えられる解決策はpatchelf
、(矛盾するglibcバージョンを処理する必要がある場合:ホストシステムからnixライブラリにリンクされている)私のストーリーの後半を参照することです。
一般的な方法を試してください
LD_LIBRARY_PATHをお試しください。
さて、これに環境変数を設定しました~/.bash_profile
。
NIX_LINK=/home/ivan/.nix-profile
export LD_LIBRARY_PATH="$NIX_LINK"/lib
しかし、それはすべてではありません!
今、別のバージョンに接続するのに問題がありますlibc
。
$ 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)
../valencies: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/ivan/.nix-profile/lib/libgmp.so.10)
linux-vdso.so.1 => (0x00007fff365ff000)
/usr/local/lib/libsnoopy.so (0x00007f56c72e6000)
libgmp.so.10 => /home/ivan/.nix-profile/lib/libgmp.so.10 (0x00007f56c7063000)
libffi.so.5 => /usr/lib64/libffi.so.5 (0x00007f56c6e54000)
libm.so.6 => /lib64/libm.so.6 (0x00007f56c6bd0000)
librt.so.1 => /lib64/librt.so.1 (0x00007f56c69c7000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f56c67c3000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f56c65a6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f56c6211000)
/lib64/ld-linux-x86-64.so.2 (0x00007f56c74f1000)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference (/home/ivan/.nix-profile/lib/libgmp.so.10)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference (../valencies)
symbol __fdelt_chk, version GLIBC_2.15 not defined in file libc.so.6 with link time reference (../valencies)
$
glibcの2つのバージョンのクリーンアップ
ここで最も驚くべきエラーは次のとおりです。
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference (/home/ivan/.nix-profile/lib/libgmp.so.10)
使用しているバージョンがインストールされている必要があるためですnix
!glibc
libgmp
実際にはglibc
fromがnix
そこにあります。
$ ldd -r /home/ivan/.nix-profile/lib/libgmp.so.10
linux-vdso.so.1 => (0x00007fff0f1ff000)
/usr/local/lib/libsnoopy.so (0x00007f06e9919000)
libc.so.6 => /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libc.so.6 (0x00007f06e957c000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f06e9371000)
/lib64/ld-linux-x86-64.so.2 (0x00007f06e9da7000)
symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference (/nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libc.so.6)
/home/ivan/.nix-profile/lib/libgmp.so.10: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
$
glibc
ユーザーが利用できない可能性があるため、バイナリを実行すると、glibc
システムバイナリが最初にロードされます。証明する:
$ ls ~/.nix-profile/lib/*libc*
ls: cannot access /home/ivan/.nix-profile/lib/*libc*: No such file or directory
$
glibc
まあ、ユーザーに表示されるようにすることもできます。
$ nix-env -i glibc
その場合、すべてが悪い:
$ ldd -r ../valencies
/bin/bash: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
$ /bin/echo ok
/bin/echo: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
$
nix
だから、独自のバイナリを実行するときにライブラリをロードしたい場合は簡単ではないようです。
今コメントします
export LD_LIBRARY_PATH="$NIX_LINK"/lib
シェルセッションで、次の操作を行います。
$ unset LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH
もっと考えが必要です。 (読む__vdso_time: dlopen() の無効なモード:あなたglibc
のLD_LIBRARY_PATH
。単一のシステムに複数のバージョンのglibcを持つことは可能ですが、この回答で説明されているように少し面倒です。 )ld-linux-x86-64.so.2
libc.so.6
必要な解決策: patchelf
したがって、動的リンカーへのパスはバイナリにハードコードされます。そして、使用された動的リンカーは、nixではなくシステム(ホストglibc)から取得されます。そして動的リンカーは私たちが望んで使用しなければならないglibcと一致しないので動作しません。
シンプルで実現可能な解決策は次のとおりです。パヘルフ。
patchelf --set-interpreter /home/ivan/.nix-profile/lib/ld-linux-x86-64.so.2 ../valencies
その後は効果がありました。しかし、まだバイオリンをオンにする必要がありますLD_LIBRARY_PATH
。
$ LD_LIBRARY_PATH=/home/ivan/.nix-profile/lib:/lib64/:/usr/lib64/ ../valencies
私の不完全なように、いくつかのライブラリはnixからインポートされ、一部はホストシステムからインポートされます(まだインストールしていないためnix-env -i
)。〜しなければならないnix ライブラリーとホスト・システム・ライブラリーへのパスを指定しますLD_LIBRARY_PATH
(基本検索パスを完全にオーバーライドします)。
追加手順:ライブラリ検索パスのpatchelf
(ページからpatchelf
)
RPATH
同様に、実行可能ファイルと動的ライブラリに含まれるリンカ検索パスを変更できます。
patchelf --set-rpath /opt/my-libs/lib:/foo/lib program
これにより、動的リンカーは/opt/my-libs/lib
プログラム/foo/lib
に必要な共有ライブラリを検索します。もちろん環境変数を設定することもできますがLD_LIBRARY_PATH
、環境設定にはラッパースクリプトが必要なため不便な場合が多いです。
答え2
Nixの「シングルユーザーモード」に加え、回答も提供しました。ニックOSユーザー。あなたは通常バイナリファイルを実行できませんNixOSで。
パッケージをローカルにインストールする場合、nix-env -i
すべての.so
ファイルは~/.nix-profile/lib/
。
パッケージをインストールするとグローバルで指定すると、そのファイルが見つかります/etc/nixos/configuration.nix
。より正確には、このディレクトリ内の対応するファイルを指すシンボリックリンクのみがあります。.so
/nix/var/nix/profiles/system/sw/lib/
/nix/store/
したがって、パッケージをグローバルにインストールする場合Ivan Zaharyachevのソリューションになる:
$ patchelf --set-interpreter /nix/var/nix/profiles/system/sw/lib/ld-linux-x86-64.so.2 ./YOUREXECUTABLE
$ LD_LIBRARY_PATH=/nix/var/nix/profiles/system/sw/lib ./YOUREXECUTABLE
最初のコマンドが機能するには、グローバルglibc
にインストールする必要があります。グローバルパッケージとユーザー固有のパッケージの両方がインストールされている場合は、2番目のコマンドを変更することもできます。
$ LD_LIBRARY_PATH=/home/YOURUSERNAME/.nix-profile/lib:/nix/var/nix/profiles/system/sw/lib ./YOUREXECUTABLE
.so
必要なファイルがシステムにインストールされていない可能性があるため、次のエラーが発生する可能性があります。
./YOUREXECUTABLE: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory
欠落しているファイルに対応するパッケージを見つける方法はわかりませんが、Googleでファイル名を検索してそのパッケージをインストール.so
してから、LD_LIBRARY_PATH
カスタムパッケージで実行可能ファイルを再実行してみてください。