2017-07-31 17 views
8

Otrzymaliśmy kilka bibliotek (.a) skompilowanych dla systemu Linux (prawdopodobnie skompilowanych z GCC 6.x)._GLIBCXX_USE_CXX11_ABI, zgodność GCC 4.8 i ABI

Używamy GCC 4.8 i otrzymujemy błąd typu: undefined reference to std::__cxx11::basic_string podczas próby połączenia.

Zazwyczaj można to naprawić, upewniając się, że wszystkie jednostki zostały skompilowane przy użyciu tej samej flagi _GLIBCXX_USE_CXX11_ABI. Jednak jeśli dobrze zrozumiałem, zostało to wprowadzone przez GCC 5.1 i na.

  1. Czy istnieje sposób, aby to działało z gcc 4.8, czy musimy prosić ludzi, aby skompilować biblioteki z inną _GLIBCXX_USE_CXX11_ABI?
  2. Sądzę, że jeśli uda nam się przełączyć na GCC> = 5.1, możemy to wykonać?

Dzięki!

+0

Zobacz także [GCC5 i C++ 11 ABI] (https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/) na blogach Red Hat , [Dual ABI] (https://gc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) w podręczniku GCC i [Łączenie problemów związanych z symbolami z abi :: cxx11?] (https: // stackoverflow.com/q/36159238/608639) na przepełnieniu stosu. To spowodowało wiele problemów, szczególnie gdy Clang nie był świadomy GCC5/C++ 11. To wygląda na dupę, ale nie ma odpowiedzi: [Jak radzić sobie z niezgodnością ABI między gcc-4.9 a gcc-5?] (Https://stackoverflow.com/q/37145066/608639) – jww

Odpowiedz

3

Możliwe jest użycie C++ 11 ABI z gcc 4.8.2, ale jest to niebezpieczny hack; byłoby o wiele lepiej, gdyby w ogóle można było poprosić sprzedawców o dostarczenie bibliotek skompilowanych z C++ 03 ABI (-D_GLIBCXX_USE_CXX11_ABI=0) lub o uaktualnienie do GCC 5 lub nowszego.

Będziesz musiał pobrać i zainstalować gcc 5, aby móc korzystać z jego nagłówków i bibliotek libstdC++, a następnie bezpośrednio gcc 4.8, aby użyć tych, które preferują. Ponadto, ponieważ w gcc 4.8 brakuje pewnych właściwości wymaganych przez libstdC++ dostarczanych z gcc 5, trzeba zhackować ich użycie.

Na przykład, aby skompilować prostą aplikację pojedynczym pliku, który zawiera <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 

Jest to niebezpieczne, ponieważ gcc 5.4 libstdC++ nie jest przeznaczony do pracy z gcc 4.8, i redefiniowania intrinsics używany (__is_trivially_copyable itp.) może zmienić układ struktur lub w inny sposób spowodować binarną niekompatybilność między twoimi programami i bibliotekami dostawcy.

W celu uruchomienia wynikowy plik wykonywalny, to trzeba także zapewnić dynamiczny linker znajdzie kompatybilnego libstdC++, na przykład przez dodanie /usr/local/gcc-5.4.0/lib64 do /etc/ld.so.conf lub przy użyciu -Wl,-rpath /usr/local/gcc-5.4.0/lib64.

+0

Może mieć sens, aby dodać '-Wl, -rpath' też. – yugr

+0

Wow, to jest straszne (i fajne) rzeczy! Lepiej zminimalizuj ryzyko i podążaj bezpieczną ścieżką i poproś o rekompilację. – Tanasis