유닉스 / 리눅스 시스템이 링크 된 라이브러리의 필요한 버전을 찾을 때까지 디렉토리를 통과하지 않는 이유는 무엇입니까?


17

"alpha"라는 바이너리 실행 파일이 있는데 링크 된 라이브러리 (libz.so.1.2.7)가 필요합니다. /home/username/myproduct/lib/libz.so.1.2.7

다음 명령을 실행하여 이진 실행 파일을 생성하기 전에 터미널 인스턴스로 내 보냅니다.

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

이제 동일한 라이브러리가 필요하지만 다른 버전 (예 : (libz.so.1.2.8))이 필요한 다른 응용 프로그램 "bravo"를 생성 /lib/x86_64-linux-gnu/libz.so.1.2.8하면 시스템에서 다음 오류가 발생합니다.

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

을 설정 해제하면 LD_LIBRARY_PATH"bravo"가 정상적으로 시작됩니다. 위의 동작은 연결된 라이브러리를 찾는 동안 LD_LIBRARY_PATH정의 된 디렉토리 경로보다 우선 하기 때문에 /etc/ld.so.conf위의 오류가 발생 했음을 이해합니다 . 라이브러리의 첫 번째 인스턴스가 다른 버전 인 경우 UNIX / LINUX 개발자가 계층 구조에 따라 다른 디렉토리에서 링크 된 라이브러리를 검색하도록 OS를 설계하지 않은 이유가 궁금합니다.

간단히 말해, UNIX / LINUX 시스템은 필요한 라이브러리를 찾을 때까지 일련의 디렉토리를 통과합니다. 그러나 버전에 관계없이 라이브러리의 첫 번째 인스턴스를 수락하는 대신 예상 버전을 찾을 때까지 왜 그렇게하지 않습니까?


확실하지는 않지만 보안을 생각합니다. 나는 개인적으로 내 컴퓨터 어디에서나 심볼 링크에 대해 걱정할 필요가 없다
Joe

@Joe 많은 라이브러리 자체가이를 가리키는 심볼릭 링크를 가지고 있습니다. libz.so.1libz.so.1.2.8
Nasir Riley

답변:


28

그러나 버전에 관계없이 라이브러리의 첫 번째 인스턴스를 수락하는 대신 예상 버전을 찾을 때까지 왜 그렇게하지 않습니까?

알고있는 한 그렇게합니다. zlib.so.1.2.7그리고 zlib.so.1.2.8모두의 불리는이 zlib.so.1당신의 있도록, alpha그리고 bravo바이너리들이 필요하다고 zlib.so.1. 동적 로더는 찾은 첫 번째 일치 라이브러리를로드합니다. 버전 1.2.8은 필요한 추가 기호를 제공한다는 것을 모릅니다 bravo. (이 때문에 배포판이와 같은 추가 종속성 정보를 지정하는 데 어려움을 겪는 이유 zlib1g (>= 1.2.8)입니다 bravo.)

이 문제를 쉽게 해결할 수 있다고 생각할 수도 있지만 바이너리와 라이브러리가 필요한 라이브러리와 별도로 필요한 기호를 나열하기 때문에 로더가 주어진 라이브러리가 모든 기호를 제공하는지 확인할 수는 없습니다. 그것으로부터 필요합니다. 심볼은 다양한 방식으로 제공 될 수 있으며 심볼과이를 제공하는 라이브러리 사이에 링크를 도입하면 기존 바이너리가 손상 될 수 있습니다. 또한 복잡한 것을위한 기호 삽입 기능이 추가되었습니다 (보안에 민감한 개발자가 머리카락을 찢어 버리게 함).

일부 라이브러리는에 제공되는 버전 정보를 .gnu.version_r제공하며 제공 라이브러리에 대한 링크가 여기에 도움이되지만 libz그 중 하나는 아닙니다.

(sonames을 부여하면 alpha바이너리가 제대로 작동 할 것으로 기대합니다 zlib.so.1.2.8.)


그리고 GNU 스타일 라이브러리 버전 관리는 우리가 가장 익숙한 시맨틱 (-ish) 버전 관리와 다릅니다. zlib.so.1.2.8은 동일한 "현재"번호를 갖기 때문에 zlib.so.1.2.7이 지원하지 않는 기능을 제공해서는 안되므로 (ABI 관점에서) 어떤 것이 중요하지는 않습니다. 녹이다. 문제는 결함으로 간주되어야합니다.
John Bollinger

4
@John no, 유일한 보증은 동일한 soname을 가진 라이브러리가 이전 버전과 호환된다는 것입니다. 최신 라이브러리는 기능을 추가 할 수 있으며 이전 버전과 호환되지 않는 방식으로 기능을 제거하거나 변경할 수 없습니다. 즉, zlib 1.2.7에 대해 빌드 된 이진은 해당 또는 최신 zlib 1과 함께 작동합니다. 그러나 zlib 1.2.8에 대해 빌드 된 바이너리는 이전 zlib 1에서 작동하지 않을 수도 있습니다. (의미 버전 관리는 가능하지만 soname 처리는 시맨틱 버전 관리가 아닙니다.)
Stephen Kitt

1
내가 말했듯이 GNU 규칙에 대해 구체적으로 이야기하고 있으며 특히 libtool 에 대해 추측 합니다. 모든 프로젝트가 이러한 규칙을 따르는 것은 아니므로 zlib 결함을 호출하는 것은 너무 강력하지만 다른 한편으로는 관련된 라이브러리 버전 번호의 의미 적 버전 해석조차도 같은 결론에 도달 할 것입니다. 앞으로 이러한 경우 (이진) 호환성은 불리는 고유의 약속은 아니지만, 그것은 이다 이 경우 합리적인 기대.
John Bollinger

1
예, 저는 CRA 번호와 SOVERSION의 관계를 잘 알고 있습니다. 원래의 요점으로 돌아 왔습니다. OP에 설명 된 상황 이 CRA 체계의 올바른 사용법과 일치하지 않는 것 같습니다 . OP와 같은 문제를 피하는 것이 그 계획의 주요 목표 중 하나입니다. zlib가 새로운 (버전의 a) 바이너리 인터페이스를 추가하면 C 번호를 늘려야합니다. 이러한 범프는 이차 범프를 야기 할 수있다.
John Bollinger

2
@John 맞아, 나는 우리가 폭력적으로 동의하고 있다고 생각하며 당신이 한 말을 잘못 이해했다고 생각합니다. Darwin을 제외하고는 어쨌든 zlib사용하지 않습니다 . ;-). libtoolar
Stephen Kitt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.