Linux 시스템의 glibc 패키지의 버전을 바꾸지 않고 다른 버전을 glibc를 사용하고 싶은 경우가 있다면 어찌 해야 하나?
동적 라이브러리(so)를 사용하지 않는다면 문제가 되지 않지만 동적 라이브러리를 사용한다면 문제가 된다. ldd를 통해서 보이는 최종 라이브러리 경로를 시스템 기본 경로가 아닌 다른 경로로 바꾸어야 하는 것이 과제이다.
다른 라이브러리는 LD_LIBRARY_PATH 환경 변수를 통해서 변경을 하는 것이 가능하지만 dynamic linker는 절대 경로로 잡혀 있어서 이 방법도 통하지 않는다.
1. dynamic linker 위치 변경하기
ld의 옵션 중에 –dynamic-linker 옵션을 사용하면 다른 dynamic linker를 사용하도록 하는 것이 가능하다. 다음과 같다.
$ gcc -Wl,–dynamic-linker=/<some where>/lib/ld-linux.so.2 <…>
2. 라이브러리 경로 추가하기
시스템의 ld.so.conf 등에 설정된 라이브러리 경로 보다 우선하는 경로를 추가할 수 있다. LD_LIBRARY_PATH 환경 변수를 사용하는 방법도 있지만 불편하다. /etc/ld.so.conf 를 수정하는 것은 다른 프로그램에도 영향을 미치므로 사용하기 어렵다.
ld의 -rpath 옵션을 사용하면 된다. 다음과 같다.
$ gcc -Wl,-rpath=/<some where>/lib:/<some where>/usr/lib <…>
3. Runtime에 변경하기
이미 컴파일된 바이너리를 다른 버전의 glibc로 변경을 할 수 있다. 다음과 같다.
$ /<some where>/lib/ld-linux.so.2 –library-path /<some where>/lib:/<some where>/usr/lib ./a.out
a.out은 변경하고자 하는 실행 파일이다. 현재 디렉토리에 있더라고 ./를 붙여주어야 한다. –library-path 다음에는 =가 아닌 공백이 있다는 것에도 주의하자.
–list 옵션은 ldd와 같은 결과를 보여준다. 실제 실행 예는 아래와 같다.
$ /tmp/lib/ld-2.12.so –list –library-path /tmp/lib ./a.out
linux-gate.so.1 => (0×00288000)
libc.so.6 => /tmp/lib/libc.so.6 (0x008f6000)
/lib/ld-linux.so.2 => /tmp/lib/ld-2.12.so (0x008d0000)