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단지 가 아닌 를 가리킵니다 libpthread.so.


심볼릭 링크를 사용하는 이유는 링커를 위한 것입니다. 직접 연결하려는 경우 플래그를 libpthread.so지정하면 접두사와 접미사가 자동으로 추가됩니다 . 접미사를 추가하라고 지시할 수 없으므로 심볼릭 링크는 추가를 용이하게 하기 위해 최신 버전의 라이브러리를 가리킵니다.gcc-lpthreadlib.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 형식이며 라이브러리가 연결된 기존 실행 파일과 호환되지 않을 때마다 변경되며 원하는 경우 설치된 라이브러리의 두 주요 버전을 모두 유지할 수 있습니다. (예: libNAME.so) 또한, 라이브러리의 부 버전 간 쉬운 업그레이드를 지원하기 위해 libNAME.so.MAJOR는 일반적으로 libNAME.so.MAJOR.MINOR와 같은 파일에 대한 링크입니다. 새로운 마이너 버전을 설치할 수 있으며, 완료되면 이전 마이너 버전에 대한 링크가 새 마이너 버전으로 이동하여 업그레이드된 라이브러리를 사용하도록 모든 새 실행을 즉시 업그레이드합니다. 내 답변도 참조하세요Linux, GNU GCC, ld, 버전 스크립트 및 ELF 바이너리 형식 - 어떻게 작동하나요?

관련 정보