SE 및 기타 튜토리얼에서 이에 대해 상충되는 정보를 많이 받았습니다. 대부분의 사람들은 버전이 의미론적 버전이라고 생각하는 것 같습니다. 그러면 다른 사람들은 그것이 반드시 따라야 한다고 정정했습니다.libtools 규칙-version-info C:R:A
, libtools에 전달된 숫자가 이라는 파일을 생성한다고 암시적으로 가정하거나 암시합니다 libfoo.so.C.R.A
. 그러나 libtools 매뉴얼에는 파일 이름 지정 방법이 명시적으로 나와 있는 내용이 표시되지 않습니다. 이는 내가 보고 있는 동작과 일치하지 않습니다. .
저는 타사 패키지(gdal)를 빌드 중이고 빌드 중에 를 호출 libtool --mode=link -version-info 25:4:5 <many other arguments>
하지만 빌드 후 .libs에 남아 있는 so 파일의 버전은 libgdal.20.5.4입니다.
나는 동일한 라이브러리의 여러 다른 버전을 시도했는데 모두 동일한 패턴을 따르는 것 같습니다. libtools를 호출하면 생성되는 current:revision:age를 전달합니다 libfoo.so.current-age.age.revision
. 이로 인해 soname은 libfoo.so.current-age
항상 가 됩니다.최저 한도에서다른 게시물에서 제안한 최대 버전이 아니라 이 라이브러리가 호환되는 버전입니다.
RHEL 7 및 Debian 10에서 이것을 테스트했습니다.
이것이 일이 진행되는 방식입니까? 이 도서관 뭔가 이상한 일을 하고 있는 걸까요? 이것이 권위 있게 또는 적어도 정확하게 문서화될 수 있는 곳이 있습니까?
답변1
Linux에 대한 일반적인 기대는 공유 라이브러리가 libfoo.so.N
N이 정수인 형식을 갖는다는 것입니다. 또한 사용하는 규칙(libtool 또는 기타)에 따라 추가 의미를 가질 수 있는 추가 정수가 있는 형식을 가질 수도 있습니다. 다른 양식을 사용할 수 있으며 일부 라이브러리(예: OpenSSL)는 다른 양식을 사용할 수 있습니다.
Linux에서 올바른 공유 라이브러리의 일부는 SONAME
바이너리의 공유 객체 이름을 지정하는 ELF 항목입니다. 예를 들어, libz의 경우:
$ readelf -a /lib/x86_64-linux-gnu/libz.so.1 | grep SONAME
0x000000000000000e (SONAME) Library soname: [libz.so.1]
이 경우 SONAME이 임을 알 수 있습니다 libz.so.1
. 바이너리가 이 공유 라이브러리에 연결되면 NEEDED
섹션이 포함됩니다. 동적 링커가 공유 라이브러리를 구문 분석할 때 검색 경로에서 SONAME과 동일한 이름을 가진 공유 라이브러리를 찾습니다. 예를 들어 Git에는 다음 4개의 공유 라이브러리가 필요합니다.
$ readelf -a /usr/bin/git | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libpcre2-8.so.0]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
따라서 실제로 중요한 것은 의미론적으로 버전이 지정된 스니펫의 주요 버전에 해당하는 SONAME에 무엇이 있는지입니다. SONAME(일반적으로 다음 정수) 값을 변경하지 않고 공유 라이브러리에서 호환되지 않는 변경을 수행하는 것은 화난 사용자 무리가 프로젝트에 참여하게 만드는 심각한 실수입니다(그리고 당연히 그렇습니다).
따라서 SONAME의 일부가 아닌 공유 라이브러리 부분은 중요하지 않습니다. libtool 규칙과 의미적 버전 관리 규칙은 모두 .so
이름 부분 뒤의 첫 번째 정수를 호환되지 않는 변경 사항의 버전으로 취급하며 둘 다 동일한 작업을 수행합니다. 이는 일반적으로 SONAME에 존재하는 부분이므로 이 목적과 동일합니다.
일부 공유 라이브러리가 다른 작업을 수행한다고 언급했습니다. 예를 들어 OpenSSL은 SONAME을 공유 라이브러리로 보유 libssl.so.1.1
하고 사용합니다. libcrypto.so.1.1
이는 권장되는 규칙은 아니지만 작동합니다. 그러나 사람들이 혼란스러워하기 때문에 향후 버전에서는 의미 체계 버전 관리로 변경될 것입니다.