2009-09-28 7 views
29

Gentoo를 사용하기 때문에 업데이트 프로그램이 이전 버전의 라이브러리에 링크 된 후에 종종 발생합니다. 일반적으로 revdep-rebuild는이를 해결하는 데 도움이되지만, 이번에는 파이썬 라이브러리에 대한 의존성이 있습니다. python-updater은 가져 오지 않습니다.계층 적 ldd (1)

ldd의 "계층 적"변종이 어떤 공유 라이브러리가 다른 공유 라이브러리에 의존하는지 보여줍니다. 대부분의 시간 라이브러리와 실행 파일은 소수의 다른 공유 라이브러리에 대해서만 링크되어 있습니다. 소수의 라이브러리는 라이브러리 의존성을 큰 목록으로 만듭니다. 내가 업그레이드 한 다른 라이브러리의 새 버전으로 다시 빌드해야하는 종속성을 알고 싶습니다. 필요에 따라 이전 .so. 적이있는가 (보존 될 것이다

답변

15

당신이 FEATURES=preserve-libs으로 운반 ≥ 2.2을 실행하는 경우는 거의 이제까지 더 이상 revdep-rebuild 필요가 없어야합니다 당신은 여전히 ​​libA.so.0가 원할 때 물건은 여전히 ​​터져 죽자을 간다,주의 깊게 재 구축 할 필요가 있지만 libC.so.0libB.so.0libC.so.1을 원하고 일부 바이너리는 libA.so.0libB.so.0을 모두 원합니다. 말했다되고 그건


, 무슨 ldd가하는 것은 보통처럼 실행 파일 또는 라이브러리를로드 할 동적 링커를 얻을 수 있지만, 그 길을 따라 몇 가지 정보를 출력하는 것입니다. 재귀적인 "바이너리 요구 라이브러리는 다른 라이브러리가 필요합니다 & hellip"검색입니다. 동적 링커가하는 일이기 때문입니다.

현재 Linux/ppc32를 실행 중입니다. Linux/x86에서 동적 링커는 보통 /lib/ld-linux.so.2이고 Linux/x86_64에서는 동적 링커가 보통 /lib/ld-linux-x86-64.so.2입니다. 여기서 나는 모든 것을 ldd이 다이내믹 링커가 마법을 수행하도록 요청하는 셸 스크립트에 지나지 않는다는 점에서 망치질하기 위해 직접 호출한다.

 
$ /lib/ld.so.1 /sbin/badblocks 
Usage: /sbin/badblocks [-b block_size] [-i input_file] [-o output_file] [-svwnf] 
     [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks] 
     [-p num_passes] [-t test_pattern [-t test_pattern [...]]] 
     device [last_block [first_block]] 
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /sbin/badblocks 
     linux-vdso32.so.1 => (0x00100000) 
     libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000) 
     libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000) 
     libc.so.6 => /lib/libc.so.6 (0x0fdfa000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000) 
     /lib/ld.so.1 (0x48000000) 
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /lib/libcom_err.so.2 
     linux-vdso32.so.1 => (0x00100000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0x6ffa2000) 
     libc.so.6 => /lib/libc.so.6 (0x6fe18000) 
     /lib/ld.so.1 (0x203ba000) 
$ grep -l pthread /sbin/badblocks /lib/libcom_err.so.2 
/lib/libcom_err.so.2 

/sbin/badblocks

은 라이브러리 의존성 등 libpthread.so.0을 나열하지 않지만, libcom_err.so.2에 의해 뽑아됩니다.

ldd이 멋지게 보이는 종속성 트리를 출력하지 않는다는 문제가 있습니까? ldd -v을 사용하십시오.


당신이 원하는 경우

 
$ LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=1 /lib/ld.so.1 /sbin/badblocks 
     linux-vdso32.so.1 => (0x00100000) 
     libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000) 
     libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000) 
     libc.so.6 => /lib/libc.so.6 (0x0fdfa000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000) 
     /lib/ld.so.1 (0x201f9000) 

     Version information: 
     /sbin/badblocks: 
       libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6 
     /lib/libext2fs.so.2: 
       libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 
     /lib/libcom_err.so.2: 
       ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 
       libpthread.so.0 (GLIBC_2.1) => /lib/libpthread.so.0 
       libpthread.so.0 (GLIBC_2.0) => /lib/libpthread.so.0 
       libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 
     /lib/libc.so.6: 
       ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1 
       ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 
     /lib/libpthread.so.0: 
       ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 
       ld.so.1 (GLIBC_2.1) => /lib/ld.so.1 
       ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1 
       libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_PRIVATE) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 

대신 동적 링커에 따라의 직접 ELF 헤더를 읽을 수 있습니다.

 
$ readelf -d /sbin/badblocks | grep NEEDED 
0x00000001 (NEEDED)      Shared library: [libext2fs.so.2] 
0x00000001 (NEEDED)      Shared library: [libcom_err.so.2] 
0x00000001 (NEEDED)      Shared library: [libc.so.6] 
$ readelf -d /lib/libcom_err.so.2 | grep NEEDED 
0x00000001 (NEEDED)      Shared library: [libpthread.so.0] 
0x00000001 (NEEDED)      Shared library: [libc.so.6] 
0x00000001 (NEEDED)      Shared library: [ld.so.1] 

는 또한 man ld.so 다른 귀여운 트릭 당신은 glibc의 동적 링커와 함께 재생할 수 있습니다.

+0

와우, 정말 고마워! – Astro

+0

'ldd -v' 출력의 트리 섹션은 버전이 부여 된 심볼이있는 라이브러리 만 보여줍니다. – marcin

0

나는 또한 "readelf -d"를 제안 할 것이지만 LDFLAGS = "- Wl, - as-needed"를 사용하여 빌드하도록합니다. 이렇게하면이 문제가 덜 자주 발생합니다. Portage 2.2의 preserve-libs는 멋지지만, 주로 그것 때문에 가려져서 모았습니다. 결함이 있습니다.

+0

결함은 오늘날 사소한 것입니다. 그 동안 나는 한 달 전에 뭔가를 더 자세히 살펴야한다고 생각했다 : P. –

60

많은 재미있는 내용이 있지만 질문에 대한 직접적인 대답은 없습니다.

ldd의 '계층'버전은 lddtree (app-misc/pax-utils에서)입니다 :

$ lddtree /usr/bin/xmllint 
xmllint => /usr/bin/xmllint (interpreter => /lib64/ld-linux-x86-64.so.2) 
    libreadline.so.6 => /lib64/libreadline.so.6 
     libncurses.so.5 => /lib64/libncurses.so.5 
      libdl.so.2 => /lib64/libdl.so.2 
    libxml2.so.2 => /usr/lib64/libxml2.so.2 
     libicui18n.so.49 => /usr/lib64/libicui18n.so.49 
      libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libstdc++.so.6 
       ld-linux.so.2 => /lib64/ld-linux.so.2 
      libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libgcc_s.so.1 
     libicuuc.so.49 => /usr/lib64/libicuuc.so.49 
     libicudata.so.49 => /usr/lib64/libicudata.so.49 
     libz.so.1 => /lib64/libz.so.1 
     liblzma.so.5 => /usr/lib64/liblzma.so.5 
     libm.so.6 => /lib64/libm.so.6 
    libpthread.so.0 => /lib64/libpthread.so.0 
    libc.so.6 => /lib64/libc.so.6 
+2

당신은 내 영웅입니다. 'lddtree'에 대해 언급해 주셔서 고맙습니다. 저는 꽤 오랫동안 이런 도구를 찾고있었습니다. – ack

6

나는 이런 식으로 뭔가를 필요, 그래서 여기가 자신의 라이브러리 의존성 표시되고, tldd을 썼다 :

 
$ ./tldd ./tldd 
./tldd 
└─libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003687c00000) 
    ├─libm.so.6 => /lib64/libm.so.6 (0x0000003685000000) 
    │ └─libc.so.6 => /lib64/libc.so.6 (0x0000003684c00000) 
    │ └─ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000003684400000) 
    └─libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003686c00000)