Sự khác biệt giữa .so và .dylib trên osx là gì?


214

.dylib là phần mở rộng thư viện động trên OSX, nhưng tôi chưa bao giờ rõ ràng khi tôi không thể / không nên sử dụng một đối tượng chia sẻ.

Một số câu hỏi tôi có:

  • Ở cấp độ khái niệm, sự khác biệt chính giữa .so và .dylib là gì?
  • Khi nào tôi có thể / nên sử dụng cái này hơn cái kia?
  • Thủ thuật & mẹo tổng hợp (Ví dụ: thay thế cho gcc-shared -fPIC, vì nó không hoạt động trên osx)

Câu trả lời:


206

Định dạng tệp đối tượng Mach-O được Mac OS X sử dụng cho các tệp thực thi và thư viện phân biệt giữa các thư viện dùng chungcác mô-đun được tải động . Sử dụng otool -hv some_fileđể xem filetype của some_file.

Các thư viện dùng chung Mach-O có loại tệp MH_DYLIBvà mang phần mở rộng .dylib. Chúng có thể được liên kết với các cờ liên kết tĩnh thông thường, ví dụ như -lfoolibfoo.dylib. Chúng có thể được tạo bằng cách chuyển -dynamiclibcờ đến trình biên dịch. ( -fPIClà mặc định và không cần phải được chỉ định.)

Các mô-đun có thể tải được gọi là "gói" trong Mach-O speak. Họ có loại tập tin MH_BUNDLE. Họ có thể mang theo bất kỳ phần mở rộng nào; Phần mở rộng .bundleđược Apple khuyến nghị, nhưng hầu hết các phần mềm được chuyển đều sử dụng .sovì mục đích tương thích. Thông thường, bạn sẽ sử dụng các gói cho các plugin mở rộng ứng dụng; trong các tình huống như vậy, gói sẽ liên kết với tệp nhị phân của ứng dụng để có quyền truy cập vào API đã xuất của ứng dụng. Chúng có thể được tạo bằng cách chuyển -bundlecờ đến trình biên dịch.

Cả hai dylibs và bó có thể được tự động nạp bằng cách sử dụng dlAPI (ví dụ dlopen, dlclose). Không thể liên kết với các gói như thể chúng là các thư viện được chia sẻ. Tuy nhiên, có thể một gói được liên kết với các thư viện chia sẻ thực sự; những cái đó sẽ được tải tự động khi gói được tải.

Trong lịch sử, sự khác biệt có ý nghĩa hơn. Trong Mac OS X 10.0, không có cách nào để tải động các thư viện. Một bộ API dyld (ví dụ NSCreateObjectFileImageFromFile, NSLinkModule) đã được giới thiệu với 10.1 để tải và dỡ các gói, nhưng chúng không hoạt động đối với các dylib. Một dlopenthư viện tương thích làm việc với các gói đã được thêm vào trong 10.3; trong 10,4, dlopenđã được viết lại để trở thành một phần nguyên gốc của dyld và thêm hỗ trợ cho việc tải (nhưng không tải) dylibs. Cuối cùng, 10,5 đã thêm hỗ trợ cho việc sử dụng dlclosevới dylib và không dùng API dyld.

Trên các hệ thống ELF như Linux, cả hai đều sử dụng cùng một định dạng tệp ; bất kỳ đoạn mã được chia sẻ nào cũng có thể được sử dụng làm thư viện và để tải động.

Cuối cùng, hãy lưu ý rằng trong Mac OS X, "gói" cũng có thể tham chiếu đến các thư mục có cấu trúc được tiêu chuẩn hóa chứa mã thực thi và các tài nguyên được sử dụng bởi mã đó. Có một số sự chồng chéo về mặt khái niệm (đặc biệt với "các gói có thể tải" như các plugin, thường chứa mã thực thi dưới dạng gói Mach-O), nhưng chúng không nên bị nhầm lẫn với các gói Mach-O đã thảo luận ở trên.

Tham khảo thêm:


1
Cảm ơn bạn đã nhận xét rộng rãi này :) Tôi có hiểu chính xác không, nếu tôi tải một gói từ gói khác (tức là đường dẫn là ứng dụng -> gói A -> gói B), thì gói B sẽ không thể thấy bất kỳ ký hiệu trong bó A? Và nếu có, có cách nào để giải quyết vấn đề này không? Tôi vừa mới đánh nó, tôi nghĩ: stackoverflow.com/questions/4193539/
Kẻ

4
@noloader: -dynamicliblà cờ GCC. Nó làm cho trình biên dịch chuyển -dylibđến ld.
Miles

URL được cập nhật cho trang man cho ld trên Mac OSX: manpages.info/macosx/ld.1.html
netpoetica

18

Tệp .so không phải là phần mở rộng tệp UNIX cho thư viện dùng chung.

Nó chỉ là một phổ biến.

Kiểm tra dòng 3b tại trang chia sẻ của ArnaudRecipes

Về cơ bản .dylib là phần mở rộng tệp mac được sử dụng để biểu thị một lib được chia sẻ.


9
@ninefingers. Chính xác. Nhưng một số công cụ sẽ sử dụng các giá trị mặc định trừ khi có gì đó rất rõ ràng. ví dụ: Trình biên dịch sẽ sử dụng phần mở rộng libray được chia sẻ cụ thể của nền tảng khi cờ -l <lib> được sử dụng (cờ thực tế có thể rất trên các trình biên dịch).
Martin York

14

Sự khác biệt giữa .dylib và .so trên mac os x là cách chúng được biên dịch. Đối với các tệp .so bạn sử dụng - dùng chung và cho .dylib, bạn sử dụng -dynamiclib. Cả .so và .dylib đều có thể hoán đổi cho nhau dưới dạng tệp thư viện động và có loại là DYLIB hoặc BUNDLE. Đây là phần đọc cho các tập tin khác nhau cho thấy điều này.

libtriangle.dylib:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    17       1368   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS



libtriangle.so:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    17       1256   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS

triangle.so:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      BUNDLE    16       1696   NOUNDEFS DYLDLINK TWOLEVEL

Lý do hai cái tương đương trên Mac OS X là để tương thích ngược với các chương trình UNIX OS khác biên dịch thành loại tệp .so.

Ghi chú biên dịch: cho dù bạn biên dịch tệp .so hoặc tệp .dylib, bạn cần chèn đường dẫn chính xác vào thư viện động trong bước liên kết. Bạn làm điều này bằng cách thêm -install_name và đường dẫn tệp vào lệnh liên kết. Nếu bạn không làm điều này, bạn sẽ gặp phải vấn đề được thấy trong bài đăng này: Mac Dynamic Library Craziness (Chỉ có thể là Fortran) .


Làm cách nào ./configuređể tạo .dylibtệp để tạo tệp chứ không phải tệp bó .so? ./configure --enable-sharedkhông làm nhiệm vụ này.
Đô đốc

từ kinh nghiệm của tôi, hầu hết các tệp cấu hình trên mac sẽ xây dựng tệp .so hoặc tệp thư viện tĩnh vì các tệp cấu hình đang sử dụng tên tệp unix / linux tiêu chuẩn.
Zachary Kraus

4

Chỉ là một quan sát tôi vừa thực hiện trong khi xây dựng mã ngây thơ trên OSX bằng cmake:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

tạo tập tin .so

trong khi

cmake ... -DBUILD_SHARED_LIBS=ON ...

tạo tập tin .dynlib .

Có lẽ điều này giúp bất cứ ai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.