2017-07-31 23 views
8

Chúng tôi đã nhận được một số thư viện (.a) được biên dịch cho Linux (có thể được biên dịch bằng GCC 6.x)._GLIBCXX_USE_CXX11_ABI, GCC 4.8 và khả năng tương thích ABI

Chúng tôi đang sử dụng GCC 4.8 và chúng tôi gặp phải lỗi thuộc loại: undefined reference to std::__cxx11::basic_string khi cố liên kết.

Thông thường, điều này có thể được khắc phục bằng cách đảm bảo tất cả các đơn vị đã được biên dịch với cùng một cờ _GLIBCXX_USE_CXX11_ABI. Tuy nhiên nếu tôi hiểu chính xác, điều này đã được giới thiệu bởi GCC 5.1 trở đi.

  1. Có cách nào để thực hiện công việc này với GCC 4.8 hoặc chúng tôi có cần yêu cầu mọi người biên dịch lại các thư viện với một khác nhau _GLIBCXX_USE_CXX11_ABI không?
  2. Tôi đoán nếu chúng tôi có thể chuyển sang GCC> = 5.1, chúng tôi có thể thực hiện công việc này?

Cảm ơn!

+0

Xem thêm [GCC5 và C++ 11 ABI] (https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/) trên blog của Red Hat , [Dual ABI] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) trong hướng dẫn GCC và [Liên kết các vấn đề do ký hiệu với abi :: cxx11?] (https: // stackoverflow.com/q/36159238/608639) trên Stack overflow. Điều đó khiến chúng tôi gặp rất nhiều vấn đề, đặc biệt khi Clang không nhận thức được GCC5/C++ 11. Điều này trông giống như dup của bạn, nhưng nó không có câu trả lời: [Làm thế nào tôi nên xử lý ABI không tương thích giữa gcc-4.9 và gcc-5?] (Https://stackoverflow.com/q/37145066/608639) – jww

Trả lời

3

Có thể sử dụng C++ 11 ABI với gcc 4.8.2, nhưng đó là một hack nguy hiểm; bạn sẽ tốt hơn hết nếu có thể yêu cầu các nhà cung cấp của bạn gửi các thư viện được biên dịch bằng C++ 03 ABI (-D_GLIBCXX_USE_CXX11_ABI=0) hoặc nâng cấp lên GCC 5 hoặc cao hơn.

Bạn sẽ cần phải tải xuống và cài đặt gcc 5 để bạn có thể sử dụng tiêu đề libstdC++ và thư viện của mình, sau đó chuyển hướng gcc 4.8 để sử dụng những tùy chọn này. Ngoài ra, vì gcc 4.8 thiếu một số nội dung bắt buộc bởi libstdC++ được chuyển với gcc 5, bạn sẽ cần phải loại bỏ việc sử dụng chúng.

Ví dụ, để biên dịch một ứng dụng duy nhất-file đơn giản mà bao gồm <string>:

/usr/local/gcc-4.8.2/bin/g++ \ 
    -std=c++11 \ 
    -D_GLIBCXX_USE_CXX11_ABI=1 \ 
    -D'__is_trivially_copyable(...)=0' \ 
    -D'__is_trivially_constructible(...)=0' \ 
    -D'__is_trivially_assignable(...)=0' \ 
    -nostdinc++ \ 
    -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/ \ 
    -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/x86_64-unknown-linux-gnu \ 
    -L /usr/local/gcc-5.4.0/lib64 
    a.cpp 

này rất nguy hiểm vì gcc 5.4 libstdC++ không được thiết kế để làm việc với gcc 4.8, và xác định lại intrinsics sử dụng (__is_trivially_copyable vv) có thể thay đổi cách bố trí của các cấu trúc hoặc nếu không gây ra sự không tương thích nhị phân giữa các chương trình của bạn và thư viện của nhà cung cấp.

Để chạy kết quả thực thi, bạn cũng sẽ cần đảm bảo rằng trình liên kết động tìm thấy libstdC++ tương thích, ví dụ bằng cách thêm /usr/local/gcc-5.4.0/lib64 vào /etc/ld.so.conf hoặc sử dụng -Wl,-rpath /usr/local/gcc-5.4.0/lib64.

+0

Có thể có ý nghĩa để thêm '-Wl, -rpath' nữa. – yugr

+0

Wow đây là thứ đáng sợ (và thú vị)! Giảm thiểu rủi ro tốt hơn và đi theo con đường an toàn và yêu cầu biên dịch lại. – Tanasis

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