2010-04-29 16 views
14

Tôi đang chuyển một hệ thống hiện có từ Windows sang Linux. Bản dựng được cấu trúc với nhiều thư viện tĩnh. Tôi chạy vào một lỗi liên kết mà một biểu tượng (được định nghĩa trong libA) không thể được tìm thấy trong một đối tượng từ libB. Điểm mấu mối liên kết trông giống nhưLàm thế nào để đối phó với phụ thuộc đệ quy giữa các thư viện tĩnh bằng cách sử dụng liên kết binutils?

g ++ test_obj.o -LA -lB -o test

Vấn đề tất nhiên là, theo thời gian các mối liên kết tìm thấy nó cần các biểu tượng từ Liba, nó đã qua mặt họ, và không quét lại, do đó, nó chỉ đơn giản là lỗi ra mặc dù biểu tượng là có cho việc lấy. Tất nhiên ý tưởng ban đầu của tôi là chuyển đổi liên kết (thành -lB -lA) để libA được quét sau đó, và bất kỳ ký hiệu nào bị thiếu từ libB trong libA đều được chọn. Nhưng sau đó tôi thấy có thực sự là một phụ thuộc đệ quy giữa libA và libB! Tôi giả định các liên kết Visual C++ xử lý này theo một cách nào đó (hiện nó rescan theo mặc định?).

cách đối phó với điều này tôi đã xem xét:

  • Sử dụng đối tượng chia sẻ. Thật không may, điều này là không mong muốn từ quan điểm yêu cầu sự tuân thủ PIC (đây là mã nhạy cảm hiệu suất và mất% ebx để giữ GOT thực sự bị tổn thương), và các đối tượng dùng chung là không cần thiết.

  • Xây dựng một mega ar của tất cả các đối tượng, tránh sự cố.

  • Tái cấu trúc mã để tránh sự phụ thuộc đệ quy (điều này rõ ràng là Điều cần làm, nhưng tôi đang cố gắng thực hiện cổng này với những thay đổi tối thiểu).

Bạn có ý tưởng khác để giải quyết vấn đề này không? Có cách nào tôi có thể thuyết phục các liên kết binutils để thực hiện rescans của thư viện nó đã xem xét khi nó thiếu một biểu tượng?

Trả lời

18

Chỉ cần làm điều này:

g++ test_obj.o -lA -lB -lA  -o test 

Khi mối liên kết đọc Liba đầu tiên trên dòng lệnh, nó sẽ loại bỏ các đối tượng/biểu tượng trong đó mà không ai đã phụ thuộc vào bài viết nào, ví dụ tất cả các ký hiệu libB cần nhưng không phải test_obj.o. Vì vậy, bạn chỉ cần làm cho nó đọc libA một lần nữa, và nó cũng sẽ nhận những biểu tượng đó.

+2

Câu hỏi này và câu trả lời đó là một ví dụ tuyệt vời của một giải pháp thanh lịch nhìn chằm chằm vào mặt bạn như vậy ... Nó đọc gần giống như rằng phần cuối của một trò đùa ...:) – dicroce

10

Trong khi @nos cung cấp một giải pháp đơn giản, nó không mở rộng khi có nhiều thư viện liên quan và sự phụ thuộc lẫn nhau phức tạp hơn. Để sắp xếp các vấn đề, ld cung cấp --start-group archives --end-group.

Trong trường hợp cụ thể của bạn:

g++ test_obj.o --start-group -lA -lB --end-group -o test 
+0

g ++ test_obj.o -Wl, - nhóm bắt đầu -lA -lB -Wl, - thử nghiệm nhóm cuối -o – yokto