2012-02-21 26 views
26

Chúng tôi có một cơ sở mã được chia thành các thư viện tĩnh. Thật không may, các thư viện có phụ thuộc vòng tròn; ví dụ: libfoo.a tùy thuộc vào libbar.a và ngược lại.Giải quyết các phụ thuộc vòng tròn bằng cách liên kết cùng một thư viện hai lần?

Tôi biết "đúng" cách xử lý này là sử dụng của mối liên kết --start-group--end-group tùy chọn, như vậy:

g++ -o myApp -Wl,--start-group -lfoo -lbar -Wl,--end-group 

Nhưng trong Makefiles hiện của chúng tôi, vấn đề thường được xử lý như thế này:

g++ -o myApp -lfoo -lbar -lfoo 

(Hãy tưởng tượng này kéo dài đến ~ 20 thư viện với sự phụ thuộc phức tạp.)

tôi đã được trải qua ou r Makefiles thay đổi hình thức thứ hai để đầu tiên, nhưng bây giờ đồng nghiệp của tôi đang hỏi tôi tại sao ... Và khác hơn "bởi vì nó sạch hơn" và một cảm giác mơ hồ rằng hình thức khác là nguy hiểm, tôi không có một câu trả lời tốt.

Vì vậy, có thể liên kết cùng một thư viện nhiều lần bao giờ có tạo sự cố không? Ví dụ, có thể liên kết thất bại với các biểu tượng được xác định nhân nếu cùng một .o được kéo vào hai lần? Hoặc có bất kỳ rủi ro nào chúng ta có thể làm nảy sinh với hai bản sao của cùng một đối tượng tĩnh, tạo ra các lỗi nhỏ không?

Về cơ bản, tôi muốn biết liệu có khả năng xảy ra lỗi liên kết hoặc thời gian chạy liên kết từ cùng một thư viện nhiều lần không; và nếu có, làm thế nào để kích hoạt chúng. Cảm ơn.

+0

Vấn đề duy nhất tôi có thể nghĩ đến là khi bạn quản lý liên kết với hai phiên bản khác nhau của cùng một thư viện. Đó là khó để làm và (IMO) là dường như không xảy ra trên Linux. Ngoài ra, chỉ có 20 thư viện không giống nhiều. Có đáng để đi qua makefiles không? Bạn có thể dành thời gian đó làm việc khác. – SigTerm

+3

Sự cố này sẽ biến mất nếu bạn sửa các thư viện của mình không có phụ thuộc vòng tròn. –

+3

Tôi giả sử loại bỏ phụ thuộc vòng tròn bằng cách kiểm tra và phá vỡ các thư viện là không khả thi? Bởi vì đó sẽ là cách sạch nhất –

Trả lời

5

Tất cả những gì tôi có thể cung cấp là thiếu thông tin phản đối. Tôi đã thực sự không bao giờ nhìn thấy hình thức đầu tiên trước (mặc dù nó rõ ràng là tốt hơn) và luôn luôn nhìn thấy điều này được giải quyết với hình thức thứ hai, và đã không quan sát thấy vấn đề như là một kết quả.

Mặc dù vậy tôi vẫn đề xuất thay đổi thành biểu mẫu đầu tiên vì nó cho thấy rõ ràng mối quan hệ giữa các thư viện thay vì dựa vào mối liên kết hoạt động theo một cách cụ thể.

Điều đó nói rằng, tôi sẽ đề nghị ít nhất là xem xét nếu có khả năng tái cấu trúc mã để kéo ra các phần phổ biến vào các thư viện bổ sung.

+5

Cảm ơn, Mark. Mặc dù tôi thấy thật thú vị khi một nửa số nhận xét về câu hỏi của tôi nói "Sửa mã nguồn của bạn!" và nửa còn lại nói "Tại sao bạn giả mạo với một codebase làm việc?" :-) – Nemo

+0

Biểu mẫu đầu tiên sẽ giới thiệu chi phí hiệu suất khi trình liên kết cố tìm các biểu tượng được lặp lại trên tất cả các thư viện được liệt kê. xem biểu mẫu này: http://stackoverflow.com/a/409470/70198 –

+0

Biểu mẫu đầu tiên cũng chỉ hoạt động với GNU ld và do đó không phải là giải pháp di động. – user1225999

1

Vì nó là một ứng dụng kế thừa, tôi đặt cược cấu trúc của các thư viện được thừa hưởng từ một số sắp xếp mà có thể không quan trọng nữa, chẳng hạn như đang được sử dụng để xây dựng một sản phẩm khác mà bạn không còn làm nữa.

Thậm chí nếu vẫn còn nguyên nhân về cấu trúc cho cấu trúc thư viện kế thừa, gần như chắc chắn, vẫn có thể chấp nhận để xây dựng thêm một thư viện từ sắp xếp cũ. Chỉ cần đặt tất cả các mô-đun từ 20 thư viện vào một thư viện mới, liballofthem.a. Sau đó, mỗi ứng dụng đơn giản chỉ là g++ -o myApp -lallofthem ...

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