2012-09-28 26 views
33

Tôi đã học được "Program Library HOWTO". Nó đề cập rằng sử dụng soname để quản lý phiên bản như sau.Tùy chọn 'soname' để xây dựng thư viện được chia sẻ là gì?

gcc -shared -fPIC -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0.0 foo.c 
ln -s libfoo.so.1.0.0 libfoo.so.1 
ln -s libfoo.so.1 libfoo.so 

Và tôi nhận được thông tin rằng nếu soname không được đặt. nó sẽ bằng libfoo.so.1.0.0, xem câu trả lời từ here.

Và tôi thấy rằng nó cũng có thể làm việc mà không soname, như sau

gcc -shared -fPIC -o libfoo.so.1.0.0 foo.c 
ln -s libfoo.so.1.0.0 libfoo.so.1 
ln -s libfoo.so.1 libfoo.so 

Vì vậy, tôi nghĩ rằng chỉ có một điểm hữu ích là các tùy chọn soname thể cho bạn biết phiên bản của thư viện chia sẻ khi bạn sử dụng readelf -d libfoo.so lệnh để kiểm tra.

Có thể làm gì khác?

Trả lời

38

soname được sử dụng để cho biết khả năng tương thích nhị phân api của thư viện của bạn.

SONAME được sử dụng tại thời gian biên dịch bởi trình liên kết để xác định từ tệp thư viện phiên bản thư viện đích thực sự. gcc -l NAME sẽ tìm kiếm lib NAME .so liên kết hoặc tệp sau đó chụp SONAME của nó chắc chắn sẽ cụ thể hơn (ví dụ: libnuke.so liên kết tới libnuke.so.0.1.4 chứa SONAME libnuke.so.0).

Khi chạy, nó sẽ liên kết với điều này sau đó được đặt thành phần động ELF NEEDED, khi đó thư viện có tên này (hoặc liên kết đến nó) sẽ tồn tại. Tại thời gian chạy SONAME không được chú ý, do đó chỉ có liên kết hoặc tồn tại tệp là đủ.

Lưu ý: SONAME chỉ được thực thi tại thời gian liên kết/xây dựng chứ không phải lúc chạy.

'SONAME' của thư viện có thể xem bằng 'tệp objdump -p | grep SONAME'. 'CẦN' của tệp nhị phân có thể được xem bằng 'tệp objdump -p | grep NEEDED'.

[EDIT] CẢNH BÁO Sau đây là nhận xét chung, không phải là nhận xét được triển khai trong linux. Xem ở cuối.

Giả sử bạn có một thư viện với tên libnuke.so.1.2 và bạn phát triển một thư viện libnuke mới:

  • nếu thư viện mới của bạn là một sửa chữa từ trước đó mà không thay đổi api, bạn nên chỉ cần giữ cùng soname , tăng phiên bản của tên tập tin. tức là tập tin sẽ là libnuke.so.1.2.1 nhưng soname vẫn sẽ là libnuke.so.1.2.
  • nếu bạn có thư viện mới chỉ thêm chức năng mới nhưng không phá vỡ chức năng và vẫn tương thích với trước đó bạn muốn sử dụng cùng một tên son hơn trước đó cộng với hậu tố mới như .1. tức là tập tin và soname sẽ là libnuke.so.1.2.1. Bất kỳ chương trình nào được liên kết với libnuke.1.2 sẽ vẫn hoạt động với chương trình đó. Các chương trình mới được liên kết với libnuke.1.2.1 sẽ chỉ hoạt động với chương trình đó (cho đến khi phiên bản lật đổ mới xuất hiện như libnuke.1.2.1.1).
  • nếu thư viện mới của bạn không tương thích với bất kỳ libnuke: libnuke.so.2
  • nếu thư viện mới của bạn tương thích với phiên bản cũ: libnuke.so.1.3 [ie vẫn tương thích với libnuke.so.1]

[EDIT] để hoàn tất: trường hợp linux.

Trong linux SONAME cuộc sống thực như một hình thức cụ thể:. lib [NAME] [API-VERSION] .so [chính-version] lớn phiên bản chỉ có một giá trị số nguyên tăng với mỗi thay đổi thư viện lớn. API-VERSION trống theo mặc định

cũ libnuke.so.0

Sau đó filename thực bao gồm phiên bản nhỏ và subversions ví dụ: libnuke.so.0.1.5

Tôi nghĩ rằng không cung cấp một soname là một hành động không tốt kể từ khi đổi tên tệp sẽ thay đổi hành vi của tệp.

+1

Philippe, theo David A. Wheeler (http://bit.ly/1CkQJmR), các soname có một số phiên bản duy nhất, như libnuke. so.1 hoặc libnuke.so.4. Bạn có biết nếu một số phiên bản thứ hai thực sự có thể là một phần của soname, như libnuke.so.1.2? –

+0

Vâng, sonmae với nhiều chữ số tồn tại, ví dụ cho thư viện openssl: SONAME: libssl.so.0.9.8, nhưng bạn nói đúng hơn là tổng quát hơn "Program Library HOWTO" là debian có vẻ hạn chế hơn thực sự –

+0

Bạn có vẻ để được mô tả rằng tên tập tin và soname nên được thiết lập khác nhau nhưng bạn không mô tả cách soname nên được thiết lập trong các trường hợp sau này. – poolie

0

Một khía cạnh khác: Ít nhất trên Linux mục SONAME cung cấp một gợi ý cho hệ thống runtime-mối liên kết về cách tạo liên kết thích hợp trong/lib,/lib64, vv Chạy ldconfig lệnh cố gắng để tạo ra một liên kết tượng trưng tên với SONAME cũng được đưa vào bộ đệm trình liên kết thời gian chạy. Một trong những thư viện mới nhất gắn thẻ cùng một SONAME thắng liên kết. Nếu một số phần mềm dựa vào SONAME cụ thể và bạn muốn gia hạn thư viện, bạn phải cung cấp SONAME này để có được thanh ldconfig trên thư viện mới này (nếu ldconfig được sử dụng để xây dựng lại bộ đệm và các liên kết). Ví dụ. libssl.so.6 và libcrypto.so.6 là những trường hợp như vậy.

1

Giả sử libA.so phụ thuộc vào libB.so và tất cả chúng trong một thư mục (tất nhiên thư mục không thể được tìm thấy bởi liên kết động). Nếu bạn không thiết lập soname sau đó dlopen không hoạt động:

auto pB = dlopen("./libB.so", RTLD_LAZY | RTLD_GLOBAL); 
auto pA = dlopen("./libA.so", RTLD_LAZY | RTLD_GLOBAL); 

Bởi vì thời gian chạy mối liên kết không thể tìm thấy libB.so, vì vậy pA được thiết lập để NULL.

Trong trường hợp này soname sẽ giúp bạn tiết kiệm từ địa ngục ...

Các vấn đề liên quan