일반적인 방법을 시도해 보세요

일반적인 방법을 시도해 보세요

nix루트가 아닌 시스템에서 "단일 사용자 모드"로 사용하고 있습니다(아래 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

내 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의 두 가지 버전 정리

여기서 가장 놀라운 오류는 다음과 같습니다.

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!glibclibgmp

실제로 glibcfrom이 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()에 대한 잘못된 모드: 귀하 glibcLD_LIBRARY_PATH. ​단일 시스템에 여러 버전의 glibc를 갖는 것이 가능하지만 이 답변에 설명된 것처럼 약간 까다롭습니다. )ld-linux-x86-64.so.2libc.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전역적으로 설치해야 합니다. 전역 패키지와 사용자별 패키지가 모두 설치된 경우 두 번째 명령을 수정할 수도 있습니다.

$ 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사용자 지정 패키지로 실행 파일을 다시 실행해 보세요.

관련 정보