Linux에서 공유 객체는 "so 숫자"를 사용한다는 것을 알고 있습니다. 즉, 다른 버전의 공유 객체에는 다른 확장자가 제공됩니다.
example.so.1
example.so.2
아이디어는 두 가지 버전의 라이브러리가 시스템에 존재할 수 있다는 것입니다 (Windows의 "DLL Hell"과 반대). 이것이 실제로 어떻게 작동하는지 알고 싶습니다. 종종 example.so
는 실제로 example.so.2
에 대한 심볼릭 링크입니다. 여기서 .2
는 최신 버전입니다. 그러면 이전 버전의 example.so
에 따라 어떻게 응용 프로그램이 올바르게 식별됩니까? 어떤 숫자를 사용해야하는지에 대한 규칙이 있습니까? 아니면 이것은 단순히 관습입니까? 소프트웨어 바이너리가 시스템간에 전송되는 Windows와 달리 시스템에 최신 버전의 공유 객체가있는 경우 소스에서 컴파일 할 때 이전 버전에 자동으로 연결되는 경우입니까?
이것이 ldconfig
과 관련이 있다고 생각하지만 어떻게해야할지 모르겠습니다.
바이너리 자체는 자신이 의존하는 공유 라이브러리의 버전을 알고 구체적으로 요청합니다. 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
에 -lpthread
플래그를 지정하면 lib
접두사와 .so
가 추가됩니다. 접미사 자동으로. .so.0
접미사를 추가하도록 지시 할 수 없으므로 기호 링크는 최신 버전의 lib를 가리켜 서
공유 라이브러리의 숫자는 Linux에서 라이브러리의 API를 식별하기 위해 사용되는 규칙입니다. 일반적으로 형식은 다음과 같습니다.
libFOO.so.MAJOR.MINOR
그리고 일반적으로 알 수 있듯이 libFOO.so에서 libFOO.so.MAJOR.MINOR 로의 심볼릭 링크가 있습니다. ldconfig는이 링크를 최신 버전으로 업데이트합니다.
MAJOR는 일반적으로 API가 변경 될 때 증가합니다 (새 진입 점이 제거되거나 매개 변수 또는 유형이 변경됨). MINOR는 일반적으로 버그 수정 릴리스 또는 기존 API를 중단하지 않고 새 API를 도입 할 때 증가합니다.
보다 광범위한 토론은 여기에서 찾을 수 있습니다 : Distributing shared library
공유 라이브러리는 다음 구성표에 따라 버전이 지정되어야합니다.
blah.so.X.Y.Z
어디
다른 모든 숫자는 이전 버전과 호환되므로 첫 번째 숫자 만 라이브러리의 "버전"을 식별하는 데 필요한 유일한 숫자이므로 hello.so.1
와 같은 첫 번째 숫자 만 표시됩니다.
ldconfig
는 시스템에서 사용 가능한 공유 라이브러리 및 해당 라이브러리에 대한 경로가 존재하는 테이블을 유지 관리합니다. 다음을 실행하여이를 확인할 수 있습니다.
ldconfig -p
패키지가 Red Hat과 같은 것을 위해 빌드 될 때, 바이너리에서 호출되는 공유 라이브러리는 RPM 빌드 타임에 패키지의 종속성으로 조회 및 추가됩니다. 따라서 패키지를 설치할 때 설치 관리자는 ldconfig
를 확인하여 시스템에 hello.so.1
가 설치되어 있는지 확인합니다.
다음과 같은 작업을 수행하여 패키지의 종속성을 볼 수 있습니다.
rpm -qpR hello.rpm
이 시스템 (Windows와 달리)은 hello.so
의 여러 버전을 시스템에 설치하고 동시에 다른 응용 프로그램에서 사용할 수 있습니다.
libNAME.so는 -lNAME으로 지정된 라이브러리를 처음 찾을 때 컴파일러/링커에서 사용하는 파일 이름입니다. 공유 라이브러리 파일에는 SONAME이라는 필드가 있습니다. 이 필드는 라이브러리 자체가 빌드 프로세스에 의해 공유 오브젝트 (so)에 처음 링크 될 때 설정됩니다. 이 SONAME은 실제로 공유 객체가 링크되어있는 링커가 실행 파일에 저장하는 것입니다. 일반적으로 SONAME은 libNAME.so.MAJOR 형식이며 라이브러리가 연결된 기존 실행 파일과 호환되지 않을 때마다 변경되며 필요에 따라 라이브러리의 두 주요 버전을 모두 설치 상태로 유지할 수 있습니다 (개발을 위해 하나만 지적 됨) 또한 마이너 버전의 라이브러리 간을 쉽게 업그레이드 할 수 있도록 libNAME.so.MAJOR는 일반적으로 libNAME.so.MAJOR.MINOR와 같은 파일에 대한 링크입니다. 새 부 버전을 설치하고 완료하면 이전 부 버전으로의 링크가 업그레이드 된 라이브러리를 사용하기 위해 모든 새 실행을 즉시 업그레이드하는 새 부 버전을 가리 키도록 충돌합니다. 또한 Linux, GNU GCC, ld, 버전 스크립트 및 ELF 이진 형식-작동 방식)에 대한 내 대답을 참조하십시오.