GNU/Linux >> Linux Esercitazione >  >> Ubuntu

Come devo gestire l'incompatibilità Abi tra Gcc-4.9 e Gcc-5?

Di recente ho aggiornato la mia macchina di sviluppo a Ubuntu 16.04 (nuova installazione, cancellata 14.04)

La versione predefinita di gcc è gcc-5.3.1 .

Un problema che ho è che una libreria fornita dal fornitore viene creata solo utilizzando gcc-4.9, che non è compatibile con gcc-5.

Ho chiesto al fornitore di fornire una nuova versione della libreria, ma è improbabile che ciò accada presto.

Nel frattempo ho installato gcc-4.9.3 dai repository di pacchetti di Ubuntu.

Ora ho installato sia gcc-4.9 che gcc-5:

ls -l /usr/bin/gcc*
lrwxrwxrwx 1 root root      5 May  9 11:49 /usr/bin/gcc -> gcc-5
-rwxr-xr-x 1 root root 838008 Apr 13 23:23 /usr/bin/gcc-4.9
-rwxr-xr-x 1 root root 915704 Apr 13 11:29 /usr/bin/gcc-5

Ho provato a creare il nostro sorgente con gcc-4.9, ma ora mi imbatto negli stessi problemi dell'ABI, ma andando dall'altra parte.

Il problema che ho è che abbiamo un sacco di dipendenze che in genere installiamo dai pacchetti di distribuzione

sudo apt-get install \
    python-dev \
    libbz2-dev \
    libboost-all-dev \
    libprotobuf-dev \
    libgoogle-perftools-dev \
    postgresql \
    libpqxx-dev

Mentre posso configurare la mia build per usare gcc-4.9

mkdir build && cd build
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 cmake ..
make -j8

Ora ricevo errori di linker quando mi collego a libtcmalloc_minimal.a , libprotobuf.a ecc.

Quindi il passaggio successivo che ho provato è stato rimuovere tutte le dipendenze installate dai repository distro e iniziare a creare le dipendenze dal sorgente.

CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 ./configure
make -j8
sudo make install

Il problema qui è che sto iniziando a dirigermi verso una tana del coniglio. Ogni dipendenza ha altre dipendenze e non sono sicuro di dove andrà a finire.

L'altra opzione è il downgrade a Ubuntu 14.04 o ad alcune versioni fornite con gcc-4.9 invece di gcc-5.

Prima di provare questa opzione turmonucleare, mi chiedevo se esiste un modo migliore per farlo?

Forse è possibile eseguire l'installazione da repository creati con gcc-4.9 o in qualche altro modo?

Risposta accettata:

Il problema che hai è correlato allo standard C++ 11 che richiede una diversa implementazione di tipi di stringhe (e elenchi) C++. Per compatibilità, g++5.2 e versioni successive compilano il nuovo tipo conforme a C++11 per impostazione predefinita (indipendentemente dal fatto che tu specifichi o meno -std=c++11), ma puoi impostare la macro

-D_GLIBCXX_USE_CXX11_ABI=0

per ripristinare il vecchio tipo di stringa C++. La nuova implementazione di libstdc++ contiene entrambi ABI. Quindi, se hai binari a cui devi collegarti con il vecchio ABI non conforme, devi impostare la macro sopra sulle tue compilazioni g++. Questo dovrebbe produrre binari compatibili con il vecchio ABI.

Correlati:come ottenere una risoluzione di 2560 × 1440 all'interno di VirtualBox su un Mac?

Sfortunatamente se stai usando librerie dal sistema operativo diverse dalle librerie standard C++, a meno che queste librerie non siano multi-arcate nel senso di fornire tutte le funzioni che differiscono per ABI in entrambe ABI, allora sei fregato perché probabilmente avranno solo il nuovo ABI.

Detto questo, ho un problema su un vecchio Ubuntu che scarica un g++ moderno non affidabile che semplicemente si rifiuta di produrre il nuovo ABI. Quindi sembra che backport da ppa:ubuntu-toolchain-r/test è infatti gravemente rotto perché si rifiuta di produrre binari secondo il nuovo ABI.

Comunque la linea di fondo è quando si collegano insieme tutto deve essere il vecchio ABI o il nuovo ABI. Quanto segue indicherà quale stai utilizzando:

g++ --version
echo '#include <string>' > test.cpp
echo 'void f(std::string s) {}' >> test.cpp
cat test.cpp
g++ -std=gnu++11 -c -o test.o test.cpp
nm test.o | c++filt

Se è così

std::basic_string<char, ....

in esso, è il vecchio ABI. Se ha

std::__cxx11::basic_string<char, ...

in esso, è il nuovo ABI.


Ubuntu
  1. Come gestire le librerie dinamiche e statiche in Linux

  2. Linux:come passare dalla sessione Tty a quella Xorg?

  3. Come trovare/grep cosa c'è tra String1 e String2?

  4. Come installare Gcc-5.3 su Ubuntu 16.04?

  5. Cos'è Content Curation e come dovresti farlo?

Alcuni comuni display manager di Ubuntu e come passare da uno all'altro

Come passare da GDM a LightDM in Ubuntu [Suggerimento rapido]

Come passare da Xorg a Wayland in Ubuntu

Come sincronizzare gli appunti tra desktop Ubuntu e telefono Android?

Come copiare file tra host e contenitore Docker

Come condividere file tra Ubuntu e Windows 10?