SO(공유 객체) 번호는 어떻게 작동하나요?

SO(공유 객체) 번호는 어떻게 작동하나요?

나는 Linux에서 공유 객체가 "so number"를 사용한다는 것을 알고 있습니다. 즉, 공유 객체의 서로 다른 버전에는 서로 다른 확장자가 부여된다는 것입니다. 예를 들면 다음과 같습니다.

  • example.so.1
  • example.so.2

나는 두 가지 버전의 라이브러리가 시스템에 존재할 수 있도록 두 개의 서로 다른 파일을 갖는 아이디어를 이해합니다(Windows의 "DLL Hell"과 반대). 이것이 실제로 어떻게 작동하는지 알고 싶습니다. 종종 나는 이것이 example.so실제로 최신 버전이 example.so.2어디에 있는지에 대한 상징적 링크임을 확인합니다. .2그렇다면 이전 버전에 의존하는 애플리케이션은 example.so이를 어떻게 올바르게 식별합니까? 어떤 숫자를 사용해야 하는지에 대한 규칙이 있나요? 아니면 이것은 단순한 관례인가요? 소프트웨어 바이너리가 시스템 간에 전송되는 Windows와 달리 시스템에 최신 버전의 공유 객체가 있는 경우 소스에서 컴파일할 때 자동으로 이전 버전에 연결됩니까?

나는 이것이 관련이 있다고 생각 ldconfig하지만 어떻게되는지 잘 모르겠습니다.

답변1

바이너리 자체는 자신이 의존하는 공유 라이브러리의 버전을 알고 구체적으로 요청합니다. ldd종속성을 표시하는 데 사용할 수 있습니다 . 내 ls것은:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

보시다시피, 이는 libpthread.so.0단지 가 아닌 eg 를 가리킵니다 libpthread.so.


심볼릭 링크를 하는 이유는 링커 때문입니다. libpthread.so직접 연결하려는 경우 gcc플래그를 지정하면 접두사와 접미사가 자동으로 -lpthread추가됩니다 . 접미사를 추가하라고 지시할 수 없으므로 심볼릭 링크는 이를 용이하게 하기 위해 최신 버전의 lib를 가리킵니다.lib.so.so.0

답변2

공유 라이브러리의 숫자는 Linux에서 라이브러리의 API를 식별하는 데 사용되는 규칙입니다. 일반적으로 형식은 다음과 같습니다.

libFOO.so.MAJOR.MINOR

그리고 일반적으로 알 수 있듯이 libFOO.so에서 libFOO.so.MAJOR.MINOR로의 심볼릭 링크가 있습니다. ldconfig는 이 링크를 최신 버전으로 업데이트하는 역할을 담당합니다.

MAJOR는 일반적으로 API가 변경될 때 증가됩니다(새 진입점이 제거되거나 매개변수 또는 유형이 변경됨). MINOR는 일반적으로 버그 수정 릴리스 또는 기존 API를 중단하지 않고 새 API가 도입될 때 증가됩니다.

보다 광범위한 토론은 여기에서 찾을 수 있습니다.공유 라이브러리 분석

답변3

공유 라이브러리는 다음 체계에 따라 버전이 지정되어야 합니다.

blah.so.X.Y.Z

어디

  • X = 이전 버전과 호환되지 않는 ABI 릴리스
  • Y = 이전 버전과 호환되는 ABI 릴리스
  • Z = 내부 변경만 가능 - ABI는 변경되지 않음

hello.so.1일반적으로 다른 모든 숫자는 이전 버전과 호환되므로 첫 번째 숫자만 라이브러리의 "버전"을 식별하는 데 필요한 유일한 것이기 때문에 첫 번째 숫자만 표시됩니다 .

ldconfig시스템에서 사용할 수 있는 공유 라이브러리와 해당 라이브러리에 대한 경로가 어디에 있는지에 대한 테이블을 유지 관리합니다. 다음을 실행하여 이를 확인할 수 있습니다.

ldconfig -p

Red Hat과 같은 패키지를 빌드할 때 바이너리에서 호출되는 공유 라이브러리는 RPM 빌드 시 패키지의 종속성으로 조회되어 추가됩니다. 따라서 패키지를 설치하려고 할 때 설치 프로그램은 를 hello.so.1확인하여 이 시스템에 설치되어 있는지 여부를 조회합니다 ldconfig.

다음과 같은 작업을 수행하여 패키지의 종속성을 확인할 수 있습니다.

rpm -qpR hello.rpm

Windows와 달리 이 시스템에서는 여러 버전의 시스템을 hello.so시스템에 설치하고 동시에 여러 응용 프로그램에서 사용할 수 있습니다.

답변4

libNAME.so는 -lNAME으로 지정된 라이브러리를 처음 찾을 때 컴파일러/링커가 사용하는 파일 이름입니다. 공유 라이브러리 파일 내부에는 SONAME이라는 필드가 있습니다. 이 필드는 빌드 프로세스에 의해 라이브러리 자체가 공유 객체(so)에 처음 링크될 때 설정됩니다. 이 SONAME은 실제로 링크된 공유 객체에 따라 링커가 실행 파일에 저장하는 것입니다. 일반적으로 SONAME은 libNAME.so.MAJOR 형식이며 라이브러리가 연결된 기존 실행 파일과 호환되지 않을 때마다 변경되며 필요에 따라 라이브러리의 두 주요 버전을 모두 설치할 수 있습니다(개발을 위해 하나만 지정됩니다) as libNAME.so) 또한 라이브러리의 부 버전 간 쉽게 업그레이드를 지원하기 위해 libNAME.so.MAJOR는 일반적으로 libNAME.so.MAJOR.MINOR와 같은 파일에 대한 링크입니다. 새로운 부 버전을 설치할 수 있고 완료되면 이전 부 버전에 대한 링크가 업그레이드된 라이브러리를 사용하기 위해 모든 새로운 실행을 즉시 업그레이드하는 새로운 부 버전을 가리키도록 범프됩니다. 또한 내 답변을 참조하십시오.Linux, GNU GCC, ld, 버전 스크립트 및 ELF 바이너리 형식 - 어떻게 작동합니까?

관련 정보