2012-02-06 12 views
5

Đây là tình huống, tôi có một codebase C++ đang sử dụng GCC (4.3.3) gần đây, nhưng tôi cần liên kết với thư viện cũ được xây dựng bằng GCC 3.2. 3. Không có phiên bản mới hơn của thư viện có sẵn, tôi không thể đi mà không có nó, và nó là nguồn đóng nên không thể xây dựng lại.Trộn C++ ABIs để xây dựng chống lại các thư viện cũ

Điều này dường như đặt ra một vấn đề vì có sự không tương thích ABI giữa GCC 4.3.3 và 3.2.3, vì vậy tôi đang cố gắng xem tùy chọn của tôi là gì để giải quyết vấn đề này.

Một vài chi tiết bổ sung:

  • tôi có thể xây dựng lại tất cả mọi thứ trong codebase của tôi với -fabi-version = 1 để có được phiên bản ABI đúng, nhưng tôi phụ thuộc vào một số tính năng mới hơn từ libstdC++ phiên bản 6.
  • Tất cả các phụ thuộc thư viện C++ bên ngoài codebase là mã nguồn mở, vì vậy tôi có thể xây dựng lại chúng khi cần thiết, ngoại trừ thư viện này.
  • Nhiều phụ thuộc thư viện C không thể được xây dựng lại hoặc sẽ khó xây dựng lại.
  • Thư viện cũ có vẻ là phụ thuộc vào một số libstdC++ phiên bản 5 tính năng

Tôi đã cho đến nay đã thử:

  • Rebuild tất cả các mã và phụ thuộc thư viện C++ với -fabi-version = 1 và liên kết chống lại libstdC++ phiên bản 6. Điều này không thành công với một số ít các dấu hiệu biểu tượng không xác định cho các ký hiệu thư viện chuẩn C++.
  • Tương tự như trên nhưng thêm liên kết trong thư viện được chia sẻ cho libstdC++ 5, điều này giải quyết vấn đề liên kết nhưng dường như dẫn đến việc trộn hai phiên bản vào thời gian chạy bên trong thư viện cũ và gây ra sự cố.

Tôi đọc trang này: http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html có vẻ như có thể trộn các phiên bản C++ ABI trong ứng dụng để đáp ứng các phụ thuộc khác nhau giữa các thư viện. Nó không có vẻ hoạt động rất tốt ở đây, mặc dù, trừ khi tôi đang thiếu một cái gì đó.

Bất kỳ ý tưởng nào?

+0

Tùy chọn trình liên kết '-Bsymbolic' và' --exclude-libs' sẽ giúp bạn nếu bạn liên kết libstdC++ tĩnh tĩnh thành một thư viện được chia sẻ. –

Trả lời

3

Ok, cách giải quyết của bạn là:

  • viết một "C" giao diện vào thư viện cũ C++, biên dịch với 3.2.3 vì vậy nó sẽ làm việc.
  • Bây giờ bạn có thể sử dụng giao diện C trong trình biên dịch mới.

Bạn có thể viết một số mã C++ "bao quanh thư viện C để bạn sử dụng nó như C++ nhưng mã này sẽ được xây dựng trong trình biên dịch mới.

+1

Tất nhiên, điều này có bất lợi khi thêm một bó mã keo, nhưng có lợi thế là làm việc với BẤT CỨ cặp trình biên dịch/phiên bản C. – kibibu

+0

Điều đó có vẻ giống như một cách tiếp cận hợp lý. Nếu tôi tạo một thư viện chia sẻ ra khỏi nó, nó vẫn sẽ có một sự phụ thuộc vào thư viện chia sẻ cũ libstdC++. Tôi sẽ không có cùng một vấn đề? Hoặc tôi có nên liên kết tĩnh trong phiên bản cũ hơn không? –

+0

Sau khi thực hiện một số việc đào bới, có vẻ như điều đúng đắn cần làm là liên kết tĩnh trong libstdC++ từ GCC cũ hơn vào thư viện được chia sẻ này.Tuy nhiên chỉ cần liên kết với điều đó là, tôi nghi ngờ, không hoàn toàn đủ, vì bạn có hiệu quả có cùng một vấn đề như trước đây với các biểu tượng được chia sẻ trên ranh giới thư viện. Tôi nghĩ rằng bạn có thể loại bỏ bất kỳ cơ hội nào bằng cách thực hiện một dlopen bên trong ứng dụng và sử dụng RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL. –