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

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

일반적으로 하나의 프로그램은 라이브러리 버전 xy에 의존하고 다른 프로그램은 xz에 의존하지만 내가 아는 한 패키지 관리자는 xy와 xz를 모두 설치할 수 있도록 허용하지 않으며 때로는 두 가지 주요 버전(예: qt4 및 qt5를 동시에 설치할 수 있음)을 허용하지만 마이너 버전은 전혀 없는 것 같습니다.

왜 이런거야? 예를 들어, 이를 방지하는 제한 요소는 무엇입니까? 이렇게 유용해 보이는 기능을 허용하지 않는 데는 그만한 이유가 있을 것이라고 생각합니다. 예를 들어, 공유 객체를 로드할 때 로드할 버전을 나타내는 필드가 없어서 Linux가 로드할 버전을 결정하는 방법을 알 수 없습니까? 아니면 정말 이유가 없는 걸까요? 모든 마이너 버전이 호환되어야 하는 것처럼요?

답변1

실제로 올바르게 수행되면 여러 버전의 공유 라이브러리를 설치할 수 있습니다.

공유 라이브러리의 이름은 일반적으로 다음과 같습니다.

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

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

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

개발자가 바이너리를 생성하기 위해 라이브러리에 연결하면 .so링커는 해당 파일 이름으로 끝나는 파일 이름을 찾습니다. 주어진 상황에서 한 번에 하나만 설치할 수 있다는 것은 사실이지만 <name>이는 개발자가 동시에 여러 버전의 라이브러리를 대상으로 할 수 없다는 것을 의미합니다. 패키지 관리자에게 이 기호 링크는 개발자만 설치해야 .so하는 별도 패키지의 일부 입니다.-dev

링커는 이름이 다음으로 끝나는 파일을 찾아서 .so사용하면 해당 라이브러리에서 다음과 같은 필드를 찾습니다.소남. 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>새 버전을 선택하지 않습니다.

패키지 관리자는 일반적으로 동일한 릴리스에 동일한 라이브러리의 여러 버전을 패키징하지 않습니다. 전체 배포판(라이브러리를 사용하는 모든 바이너리 포함)은 일반적으로 릴리스 전에 각 라이브러리의 일관된 버전을 사용하도록 컴파일되기 때문입니다. 해방되었습니다. 모든 것이 일관되고 릴리스의 모든 것이 다른 모든 것과 호환되는지 확인하는 것은 게시자의 작업량에서 큰 부분을 차지합니다.

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

  • libmysql클라이언트16이전 데비안에서는 include libmysqlclient.so.16.0.0및 Symlink 를 포함합니다 libmysqlclient.so.16.
  • libmysql클라이언트18현재 데비안부터 include libmysqlclient.so.18.0.0및 Symlink 가 포함됩니다 libmysqlclient.so.18.

답변2

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

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

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

라이브러리가 이런 방식으로 개발되면 항상 XYZ를 X.(Y+m).(Z+n)으로 바꿀 수 있어야 합니다. 주어진 m과 n에 대해. 즉, 동일한 주요 디지털 시리즈의 최신 버전으로 라이브러리를 항상 교체할 수 있어야 합니다. 라이브러리 개발자가 주의를 기울이고 다음 주요 번호가 호환되는 경우(예: 더 이상 사용되지 않는 항목을 선언했지만 아직 제거하지 않은 경우) 다음 주요 번호를 사용할 수도 있습니다.

패키지 개발자의 경우 이는 숫자 이름이 아닌 이름만 사용하고 패키지를 업데이트하여 최신 버전을 제공할 수 있음을 의미합니다. 라이브러리를 패키지로 제공하면 abc2자체 소프트웨어를 옮기는 데 많은 어려움을 겪게 됩니다.의지하다abc2사용하기 위해 업그레이드하려면 abc3전환 패키지가 필요한 경우가 있습니다. 대부분의 종속 패키지에 적용할 수 있는 경우 라이브러리에서 주요 버전 번호를 생략하는 것이 더 편리합니다. 따라서 배포판의 특정 시점에서 둘 다 사용할 abc2수 있어야 하지만 종종 호출되며(아직 호출되지 않은 것처럼 ) 배포판에 패키지 종속성이 없으면 완전히 제거할 수 있습니다.abc3abc3abcabc2abc3abc2abc2

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

라이브러리가 아닌 반례는 Python intpreter입니다. 이는 사소한 수치 변경 시 공유 객체 및 피클링 형식과 호환되지 않습니다. 따라서 Python(2.7 시리즈의 최신 버전) 및 python3(현재 python3.4 시리즈의 최신 버전)용 패키지와 Python 2.6(점점 일반화됨) 및 Python 3.3용 명시적 패키지가 표시됩니다.

관련 정보