2017-07-31 135 views
8

我們收到了一些爲linux編譯的庫(.a)(可能使用GCC 6.x編譯)。_GLIBCXX_USE_CXX11_ABI,GCC 4.8和ABI兼容性

我們正在使用GCC 4.8,並且在嘗試鏈接時遇到類型錯誤: undefined reference to std::__cxx11::basic_string

正常情況下,可以通過確保所有單位已使用相同的_GLIBCXX_USE_CXX11_ABI標誌進行編譯來解決此問題。但是,如果我理解正確,這是由GCC 5.1和以上引入的。

  1. 有沒有辦法使這項工作與GCC 4.8或我們需要問人們重新編譯與不同_GLIBCXX_USE_CXX11_ABI庫?
  2. 我想如果我們能夠切換到GCC> = 5.1,我們可以使這項工作?

謝謝!

+0

另請參閱Red Hat博客上的[GCC5和C++ 11 ABI](https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/) ,GCC手冊中的[Dual ABI](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)和[由於符號與abi :: cxx11?相關聯的問題](https:// stackoverflow.com/q/36159238/608639)堆棧溢出。這給我們帶來了很多問題,特別是當Clang不是GCC5/C++ 11時。這看起來像你的dup,但它沒有答案:[我應該如何處理gcc-4.9和gcc-5之間的ABI不兼容問題](https://stackoverflow.com/q/37145066/608639) – jww

回答

3

可以使用C++ 11 ABI和gcc 4.8.2,但這是一個危險的破解;如果可能的話,要求供應商發佈使用C++ 03 ABI(-D_GLIBCXX_USE_CXX11_ABI=0)編譯的庫或升級到GCC 5或更高版本,您將會變得更好。

您需要下載並安裝gcc 5,以便您可以使用它的libstdC++頭文件和庫,然後直接使用gcc 4.8來優先使用它們。此外,因爲gcc 4.8缺少gcc 5附帶的libstdC++所需的一些內在函數,所以您需要破解它們的用法。

例如,編譯包括一個簡單的單文件應用<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 

這是危險的,因爲在gcc 5.4的libstdC++不被設計用gcc 4.8工作,並重新定義所使用的內在(__is_trivially_copyable等)可能會改變結構的佈局,否則會導致程序與供應商的庫之間的二進制不兼容。

爲了運行生成的可執行文件,你還需要確保動態鏈接加入到/usr/local/gcc-5.4.0/lib64/etc/ld.so.conf,或使用-Wl,-rpath /usr/local/gcc-5.4.0/lib64找到兼容的libstdC++,例如。

+0

可能有意義添加'', - 'rrp'也是。 – yugr

+0

哇,這是可怕的(和酷)的東西!更好地降低風險並遵循安全路徑並要求重新編譯。 – Tanasis