여러 버전의 공유 라이브러리를 설치할 수없는 이유는 무엇입니까?


10

특정 프로그램이 라이브러리 버전 xy와 xz에 의존하는 경우가 종종 있지만, 아는 한, xy와 xz를 모두 설치할 수있는 패키지 관리자가 없을 때가 있습니다. 때로는 주요 버전 (예 : qt4와 qt5는 동시에 설치 될 수 있지만 부 버전은 아닙니다.

왜 이런거야? 마찬가지로, 그것을 막는 제한 요소는 무엇입니까? 이처럼 유용한 기능을 허용하지 않는 충분한 이유가 있어야한다고 생각합니다. 예를 들어, 공유 객체를로드 할 때로드 할 버전을 표시하는 필드가 없으므로 Linux에서로드 할 결정 방법을 알 수있는 방법이 없습니까? 아니면 그럴 이유가 없습니까? 모든 부 버전이 어쨌든 호환되는 것으로 가정합니까?

답변:


13

실제로, 제대로 수행 된 경우 여러 버전의 공유 라이브러리를 설치할 수 있습니다.

공유 라이브러리는 일반적으로 다음과 같이 이름이 지정됩니다.

lib<name>.so.<api-version>.<minor>

다음으로 라이브러리에 대한 심볼릭 링크가 다음 이름으로 있습니다.

lib<name>.so
lib<name>.so.<api-version>

개발자가 라이브러리와 링크하여 바이너리를 생성하면 파일 이름 .so은 링커가 찾는 파일 이름입니다 . 특정 시점에 한 번에 하나만 설치할 수 <name>있지만 이는 개발자가 동시에 여러 버전의 라이브러리를 대상으로 할 수 없음을 의미합니다. 패키지 관리자의 경우이 .so심볼릭 링크는 -dev개발자 만 설치 하면되는 별도의 패키지의 일부입니다 .

링커는 이름이 끝나는 파일을 찾아서 .so사용하면 해당 라이브러리에서 soname 이라는 필드를 찾습니다 . soname은 링커에게 결과 바이너리에 포함시킬 파일 이름과 런타임에 어떤 파일 이름을 찾을 것인지 조언합니다. soname은로 설정되어 있어야합니다 lib<name>.so.<api-version>.

따라서 런타임시 동적 링커에서이를 찾아 lib<name>.so.<api-version>사용합니다.

의도는 다음과 같습니다.

  • <minor>업그레이드는 라이브러리의 API를 변경하지 않으며 <minor>상위 버전으로 충돌하면 모든 바이너리를 새 버전으로 업그레이드하는 것이 안전합니다. 바이너리는 모두 lib<name>.so.<api-version>최신 설치에 대한 심볼릭 링크 인 이름으로 라이브러리를 찾고 lib<name>.so.<api-version>.<minor>있으므로 업그레이드를받습니다.
  • <api-version>업그레이드는 라이브러리의 API를 변경하므로 기존 바이너리 응용 프로그램에서 새 버전을 사용하도록하는 것은 안전하지 않습니다. <api-version>이 변경 되는 경우 , 해당 애플리케이션은 이름을 찾고 lib<name>.so.<api-version>있지만에 대한 값이 다르기 <api-version>때문에 새 버전을 선택하지 않습니다.

라이브러리를 사용하는 모든 바이너리를 포함하여 전체 배포가 배포 전에 모든 라이브러리의 일관된 버전을 사용하도록 컴파일되기 때문에 패키지 관리자는 동일한 배포 버전 내에서 동일한 라이브러리의 둘 이상의 버전을 종종 패키지하지 않습니다. 출시. 모든 것이 일관되고 배포의 모든 것이 다른 모든 것과 호환되는지 확인하는 것은 배포자 작업의 큰 부분입니다.

그러나 시스템을 한 버전의 배포판에서 다른 버전으로 업그레이드했지만 이전 라이브러리 버전이 필요한 일부 오래된 패키지가있는 경우 여러 버전의 라이브러리로 쉽게 끝날 수 있습니다. 예:

  • 이전 데비안의 libmysqlclient16 은 contains libmysqlclient.so.16.0.0및 symlink libmysqlclient.so.16입니다.
  • 현재 데비안의 libmysqlclient18 , contains libmysqlclient.so.18.0.0및 symlink libmysqlclient.so.18.

4

이 기능은 허용되지 않으며 대부분의 라이브러리 번호 지정 작업 방식과 패키지 이름 변경으로 인한 불편으로 인해 일반적이지 않습니다.

점으로 구분 된 버전 번호 체계를 사용하는 경우 XYZ "마이크로"버전 Z는 종종 버그 수정에서 변경되며, "부"번호 Y는 이전 버전과 호환되는 변경 사항에서 변경되고 "주"버전 번호 X는 API 변경에서 변경되어야합니다 (때로는 변경됨). 주요 추가 기능).

최신 버그를 수정하지 않으려는 이유가 없어야하며 이전 버전과 호환되는 변경으로 인해 소프트웨어가 손상되지 않아야합니다.

라이브러리가 이런 식으로 개발 된 경우 항상 XYZ를 X. (Y + m). (Z + n)으로 바꿀 수 있어야합니다. 주어진 m과 n에 대해. 즉, 항상 동일한 주요 번호 시리즈의 라이브러리로 라이브러리를 교체 할 수 있어야합니다. 또한 라이브러리 개발자가주의를 기울이고 다음 메이저 번호가 호환 가능한 경우 (예 : 더 이상 사용하지 않지만 아직 제거하지 않겠다는 발표로) 다음 메이저 번호를 사용할 수도 있습니다.

패키지 개발자의 경우 패키지를 업데이트하여 이름을 하나만 사용하거나 숫자를 사용하지 않고 최신 버전을 제공 할 수 있습니다. 그들이 패키지에 라이브러리를 제공하는 경우 abc2그들은 자신의 소프트웨어 이동할 농구를 통해 이동해야 의존abc2사용하기로 업그레이드 abc3전환 패키지 때때로을. 대부분의 종속 패키지에서 작동하는 경우 라이브러리에서 주 버전 번호를 제외하는 것이 더 편리합니다. 그래서 심지어 두 경우 abc2abc3분포에서 사용할 수있는 몇 가지 지점에서 사용할 수 있어야합니다, abc3종종라고합니다 abc(것처럼 abc2이없는 때 불렀다 abc3아직), 그리고 곧 어떤 패키지에 의존하지 않기 때문에 abc2분포 내에서이 드롭 할 수있게된다abc2 전부.

번호 매기기 체계는 균등하게 따르지 않지만 인터넷의 출현으로 그러한 체계를 사용하는 방법에 대한 정보를 전파하고 도서관 사용자 (배포 개발자 포함)의 압력으로 인해 하위 호환성과 같은 중요한 것들을 명확하게 밝히지 않아야한다는 압력을 상상할 수 있습니다. 라이브러리에 포함 된 CHANGES 파일을 읽어야하는 상황에서 이것이보다 일반적이되었습니다.

하나의 카운터 예제이지만 라이브러리는 아닙니다. 파이썬 인터프리터는 공유 객체와 호환되지 않으며 작은 숫자 변경에서 산세 형식입니다. 따라서 python 3.3 (최신 2.7 시리즈) 및 python3 (현재 python3.4 시리즈의 최신) 패키지와 python 2.6 (일반적이지 않음) 및 python 3.3 용 패키지를 볼 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.