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
?
Bạn đã thử với '-shared -z defs' chưa? –
@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