2015-08-20 22 views
5

Nếu tôi muốn tạo chương trình C++ liên kết với một thư viện tĩnh, thì tệp thực thi cuối cùng sẽ chứa cả mã từ chương trình của tôi và mã từ thư viện (tôi nghĩ ...!). Nhưng tôi không hoàn toàn chắc chắn như những gì sẽ xảy ra khi tôi liên kết với một thư viện được chia sẻ.Điều gì sẽ được thêm vào tệp thực thi khi liên kết với một thư viện được chia sẻ?

Giả sử tôi liên kết với thư viện có tên libfoo.so, bằng cách chỉ định trong số CMakeLists.txt của mình, hãy ghi dòng target_link_libraries(${PROJECT_NAME} foo). Tôi giả định rằng tệp thực thi cuối cùng sẽ chứa một số thông tin về thư viện này, nhưng không chứa đầy đủ mã. Thông tin khác này là gì? Hơn nữa, thư viện có được gọi chính xác là libfoo.so trên hệ thống của người dùng không?

+0

Lưu ý: Chuẩn C++ thường không hỗ trợ thư viện động. Về sự hỗ trợ rõ ràng nhất mà bạn nhận được là câu lệnh khởi tạo các biến phạm vi không gian tên có thể bị trì hoãn sau câu lệnh đầu tiên của 'main'. Các từ ngữ trong tiêu chuẩn chỉ là gây hiểu lầm, tôi đoán giải thích hợp lý duy nhất là "sau khi bắt đầu tuyên bố đầu tiên của' chính' ". –

+1

Tệp thực thi có tiêu đề chứa thông tin trong các phần khác nhau. Nếu bạn quan tâm đến việc khám phá các tiêu đề, bạn có thể sử dụng tiện ích linux 'readelf' để đọc các tiêu đề trên một tập tin thực thi. Đặc biệt, bạn sẽ cần các công tắc '-d' và' -s' để hiển thị Bảng Động và Bảng Biểu tượng tương ứng. – alvits

Trả lời

6

Khi bạn liên kết đến thư viện động, trình liên kết sẽ thêm mục nhập NEEDED trong phần động của chương trình. Sau đó, trình tải động sẽ sử dụng các trình tải này để định vị thư viện và sử dụng thư viện để giải quyết bất kỳ biểu tượng động không xác định nào.

Lưu ý rằng không có kết nối giữa các biểu tượng động không xác định và thư viện động nơi chúng được mong đợi sẽ được tìm thấy. Đôi khi chúng được tìm thấy trong một thư viện khác và những điều thú vị có thể xảy ra.

Tên đặc biệt lưu trong mục NEEDED phụ thuộc vào việc thư viện có một mục SONAME trong phần năng động của nó:

  • Nếu có một SONAME, sau đó nội dung của nó sẽ được sao chép vào NEEDED của chương trình
  • Nếu không có SONAME, tên tệp của thư viện được sử dụng trong lệnh trình liên kết sẽ được lưu trữ.

Bạn có thể kiểm tra các nội dung của bộ phận năng động của một thư viện hoặc chương trình với:

$ objdump -p program 

như thế nào này được sử dụng trong thực tế? Vâng, hầu hết (? Tất cả) các bản phân phối Linux sử dụng các chương trình sau đây, với các thư viện hệ thống (mất libfoo.so):

  • Thư viện này được cài đặt như /usr/lib/libfoo.so.1.2 hoặc bất kỳ phiên bản của nó.
  • Các liên kết tượng trưng cho thư viện đó có tên /usr/lib/libfoo.so.1/usr/lib/libfoo.so.
  • SONAME của thư viện là libfoo.so.1.
  • Đường dẫn /usr/lib được đặt làm đường dẫn thư viện động.

Bằng cách đó, khi bạn liên kết với -lfoo nó sẽ tìm thấy các liên kết tượng trưng libfoo.so, nhưng sẽ ghi lại các SONAME như libfoo.so.1. Và khi chương trình được chạy, nó sẽ tìm thấy các liên kết tượng trưng khác và tải thư viện. Thủ thuật này được sử dụng để bạn có thể cài đặt ABI tương thích, cải tiến libfoo.so.1.3 và ABI không tương thích mới hơn libfoo.so.2.1 và chương trình cũ sẽ tải thư viện cũ trong khi các bộ sưu tập mới sẽ sử dụng thư viện mới.

Cũng lưu ý rằng các biến môi trường LD_PRELOAD, LD_LIBRARY_PATH và các biến thể khác ảnh hưởng đến hành vi thời gian chạy. Để biết thêm chi tiết, bạn có thể đọc man ld.so

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