32비트 Intel x86용으로 동적으로 컴파일된 바이너리가 있고 이를 64비트 x86-64 Guix 시스템에서 실행하려고 한다고 가정해 보겠습니다. 이 바이너리는 다른 시스템에서 컴파일되었습니다. 어떻게 실행하시겠습니까?
Ubuntu에서는 동일한 작업을 수행하는 방법에 대한 지침을 여기에서 찾을 수 있습니다.Ubuntu 64비트에서 32비트 애플리케이션을 실행하는 방법은 무엇입니까?
답변1
Guix 시스템에서 바이너리를 실행할 때의 한 가지 문제점은 라이브러리의 실제 위치를 모른다는 것입니다. 그들은 전역적으로 설치된 라이브러리를 사용하고 싶어하지만 guix는 이를 스토어에만 설치합니다. 두 가지 해결 방법이 있습니다. 바이너리가 라이브러리를 찾을 수 있는 환경을 만들거나 바이너리를 패치하여 라이브러리를 찾을 수 있는 것입니다.
두 솔루션 모두 어떤 라이브러리가 필요한지 알아야 합니다. 이것을 시도해 보세요( 패키지 ldd
에서 ):glibc
$ ldd my-binary
linux-vdso.so.1 (0x00007ffe80da9000)
libdl.so.2 => not found
libc.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libc.so.6 (0x00007f7651b77000)
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 (0x00007f7651d3b000)
이제 어떤 라이브러리 파일이 필요한지 알 수 있습니다. 이를 기록하고 glibc
실행하는 데 필요한 패키지를 찾으십시오.
컨테이너 포함
첫 번째 솔루션에서는 전역 위치에 라이브러리와 바이너리를 노출하는 컨테이너를 생성해야 합니다. -s i686-linux
기본 아키텍처 대신 이 아키텍처에 대한 환경을 어떻게 구축했는지 주목하세요 .
PROFILE=$(guix environment -C -N --ad-hoc glibc ... -s i686-linux -- bash -c 'echo $GUIX_ENVIRONMENT')
guix environment -C -N --ad-hoc glibc ... -s i686-linux --expose=$PROFILE/lib=/lib --expose=$PROFILE/lib=/lib64
첫 번째 줄은 PROFILE
환경을 위해 생성한 구성 파일의 경로가 포함된 변수를 생성합니다. echo 명령을 실행하고 즉시 존재합니다. bash가 발생하는 것을 원하지 않으므로 작은 따옴표를 사용하는 것이 필수적입니다.외부변수의 환경을 확장합니다. 두 번째 명령은 실제로 환경으로 이동합니다. 프로그램에 그래픽 표시가 필요한 경우 더 많은 콘텐츠를 공유/노출해야 합니다.
패치 포함
두 번째 해결 방법은 바이너리를 패치하여 일반 환경에서 실행할 수 있도록 하는 것입니다. 이는 그래픽 인터페이스, 오디오 또는 기타 하드웨어에 액세스하는 데 따른 문제를 줄이는 것을 의미합니다. 이것은 patchelf를 사용하며 수동 방식(빠르고 더러운) 또는 패키지 방식의 두 가지 방법이 있습니다.
빠르고 더러운
빠르고 더러운 방법은 다음과 같이 이전에 (glibc의 경우) 알아차린 모든 종속성을 구축하는 것입니다.
$ guix build glibc -s i686-linux
/gnu/store/9728x9zhj8d3zlyzsjpz342jpccrgkgd-glibc-2.31
이렇게 하면 매장 경로가 제공되고 매장에 재고가 있는지 확인할 수 있습니다.
이제 ( patchelf
패키지에서) patchelf를 사용하세요:
patchelf --set-interpreter /gnu/store/...-glibc-.../lib/ld-linux.so.2
patchelf --set-rpath /gnu/store/...-glibc-.../lib:/gnu/store/.../lib:/gnu/store/.../lib:...
그러면 인터프리터가 ld-linux.so.2(32비트용) 및 rpath(동적 라이브러리 검색 경로)로 설정됩니다. 필수 라이브러리가 있는 콜론으로 구분된 디렉토리 목록이어야 합니다.
이 방법은 상대적으로 빠르지만 gc 루트를 등록하지 않고 guix가 업데이트되거나 가비지 수집기가 실행될 때마다 다시 실행해야 하기 때문에 지저분합니다.
패키지 사용
마지막 가능성은 종속성 정보를 등록할 바이너리에 대한 패키지 정의를 생성하는 것입니다. 이 방법을 사용하여 구성 파일에 바이너리를 설치할 수도 있습니다. nonguix에서 사용할 수 있습니다 binary-build-system
.https://gitlab.com/nonguix/nonguix
이 방법의 한 가지 단점은 바이너리 파일을 저장소에 복사하고 바이너리 파일이 커질 수 있다는 것입니다. 그러나 패키지 정의를 사용하면 언제든지 다시 빌드하고 패키지를 업데이트할 수 있으므로 미래 지향적입니다. 바이너리 빌드 시스템은 본질적으로 더 선언적인 방식으로 위의 patchelf 명령을 수행합니다. 다음과 같이 패키지를 정의할 수 있습니다.
(package
(name "my-binary")
(version "version")
(source (local-file "/home/..."))
(build-system binary-build-system)
(arguments
`(#:patchelf-plan
`(("my-binary" ("libc" "gcc:lib" ...)))
#:install-plan
`(("my-binary" "bin/"))))
(inputs
`(("gcc:lib" ,gcc "lib")))); note how the first string must match the one in
; patchelf-plan. libc is already implicitely defined
그런 다음 다음을 사용하여 이 패키지를 빌드할 수 있습니다.
guix build -s i686-linux -f my-package.scm