2013-10-09 20 views
7

Tôi có một mảnh nhỏ của C++ code mà trông giống như sau:Tại sao GNU ld phân giải các biểu tượng khác nhau khi liên kết các tệp thi hành với các đối tượng được chia sẻ?

#include <boost/timer/timer.hpp> 

int main(void) { 
    boost::timer::auto_cpu_timer t; 
    return 0; 
} 

tôi đã cố gắng để biên dịch và liên kết nó (với gcc 4.8.1 và GNU ld 2.23.52.20130828) như sau:

$ g++ -o test test.cc -lboost_timer 
/usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv' 
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line 
collect2: error: ld returned 1 exit status 

Một giải pháp là đề cập rõ ràng -lboost_system trên dòng lệnh và hoạt động. Tuy nhiên, tôi cũng có thể làm:

$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer 

Theo tài liệu ld "với --copy-dt-cần-mục thư viện động nêu trên dòng lệnh sẽ được đệ quy tìm kiếm, sau thẻ DT_NEEDED của họ để các thư viện khác, để giải quyết các ký hiệu được yêu cầu bởi đầu ra nhị phân ", do đó, tất cả điều này có ý nghĩa: ld là tìm ra từ boost_timer rằng nó cũng cần phải liên kết với boost_system để giải quyết tất cả các biểu tượng.

Tuy nhiên, tôi nhận ra rằng điều này cũng hoạt động:

$ g++ -fPIC -shared -o test test.cc -lboost_timer 

Rõ ràng, bây giờ tôi đã tạo ra một đối tượng chia sẻ chứ không phải là một thực thi. Rõ ràng, tuy nhiên, ld đã có thể hình dung ra rằng nó cần thiết để liên kết các đối tượng chia sẻ với boost_system:

$ ldd test | grep boost_system 
     libboost_system.so.1.54.0 => /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000) 

Vì vậy, câu hỏi của tôi là thế này: tại sao là độ phân giải biểu tượng khác nhau khi xây dựng một đối tượng chia sẻ so với một thực thi? Làm thế nào là ld có thể tìm ra rằng đối tượng chia sẻ của tôi nên được liên kết với boost_system mà không có chỉ định của tôi --copy-dt-needed-entries?

+0

Bạn đã thử với '-shared -z defs' chưa? –

+0

@CharlesBailey Thêm '-z defs' vào phiên bản dùng chung sẽ khiến nó bị hỏng (' test.cc :(.text + 0x85): tham chiếu không xác định đến 'boost :: system :: generic_category()' '). Nhìn vào '-z defs' cũng đã chỉ cho tôi' - [no-] allow-shlib-undefined' và điều đó thực sự có thể giải thích những gì đang xảy ra ... cảm ơn con trỏ! – user2862505

Trả lời

5

Câu trả lời trực tiếp cho câu hỏi của tôi là ở tùy chọn --[no-]allow-shlib-undefined cho ld, tôi nghĩ vậy. Từ trang người đàn ông:

Hành vi mặc định là để báo cáo lỗi cho bất kỳ biểu tượng không xác định tham chiếu trong các thư viện chia sẻ nếu mối liên kết đang được sử dụng để tạo ra một thực thi, nhưng để cho phép họ nếu mối liên kết đang được sử dụng để tạo thư viện được chia sẻ.

Vì vậy, khi tôi xây dựng với -shared, các ký hiệu trong boost_system không được xác định, nhưng hành vi mặc định của ld không quan tâm. Nó có thể được cho biết để chăm sóc:

$ g++ -fPIC -shared -Wl,--no-allow-shlib-undefined -o test test.cc -lboost_timer 
/usr/bin/ld: /tmp/cc6j1de3.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv' 
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line 
collect2: error: ld returned 1 exit status 

Tương tự như vậy, chúng ta có thể nói nó không quan tâm khi xây dựng một thực thi:

$ g++ -Wl,--allow-shlib-undefined -o test test.cc -lboost_timer 
/tmp/ccUHoCIU.o: In function `__static_initialization_and_destruction_0(int, int)': 
test.cc:(.text+0x7a): undefined reference to `boost::system::generic_category()' 
test.cc:(.text+0x86): undefined reference to `boost::system::generic_category()' 
test.cc:(.text+0x92): undefined reference to `boost::system::system_category()' 
collect2: error: ld returned 1 exit status 

Nhưng tạo ra nhị phân không mà không thể xác định những biểu tượng.

Cảm ơn @CharlesBailey đã chỉ cho tôi đúng hướng!

0

Có sự khác biệt trong lệnh collect2 có thể có liên quan. Các lệnh khác nhau được so sánh tại http://imgur.com/eMr2tY2. Phía bên tay phải tạo thư viện được chia sẻ (-fPic -shared), bên trái là biên dịch bình thường.

+0

đây có thể là một câu hỏi ngoài chủ đề. Nhưng hình ảnh khác của bạn trông thú vị. bạn có thể vui lòng cho chúng tôi biết nơi bạn có công cụ tìm khác biệt đó không ?? – earthdan

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