web-dev-qa-db-fra.com

Comment gérer l'incompatibilité ABO entre gcc-4.9 et gcc-5?

J'ai récemment mis à niveau ma machine de développement vers Ubuntu 16.04 (nouvelle installation, effacé le 14.04)

La version par défaut de gcc est gcc-5.3.1.

Un problème que j'ai est une bibliothèque fournie par le fournisseur est uniquement construit en utilisant gcc-4.9, qui n'est pas compatible avec gcc-5.

J'ai demandé au fournisseur de fournir une nouvelle version de la bibliothèque, mais il est peu probable que cela se produise de si tôt.

Entre-temps, j'ai installé gcc-4.9.3 à partir des dépôts de paquets d'Ubuntu.

J'ai maintenant les deux gcc-4.9 et gcc-5 installés:

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

J'ai essayé de construire notre source avec gcc-4.9, mais maintenant je me heurte aux mêmes problèmes avec ABI, mais je vais dans l'autre sens.

Le problème que j'ai est que nous avons un tas de dépendances que nous installerions typiquement à partir des paquets de distribution

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

Bien que je puisse configurer ma construction pour utiliser gcc-4.9

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

Je reçois maintenant des erreurs de l'éditeur de liens lors de la liaison avec libtcmalloc_minimal.a, libprotobuf.a etc.

La prochaine étape que j'ai essayée consistait donc à supprimer toutes les dépendances installées dans le dépôt de distribution et à commencer à créer les dépendances à partir du source.

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

Le problème ici est que je commence à descendre un terrier de lapin. Chaque dépendance a d'autres dépendances et je ne sais pas où cela va finir.

L'autre option consiste à revenir à Ubuntu 14.04 ou à une version fournie avec gcc-4.9 au lieu de gcc-5.

Avant d’essayer cette option thurmonucléaire, je me demandais s’il existait un meilleur moyen de le faire.

Peut-être est-il possible d'installer à partir de dépôts construits avec gcc-4.9 ou d'une autre manière?

3
Steve Lorimer

Le problème que vous avez est lié à la norme C++ 11 nécessitant une implémentation différente du ou des types de chaîne (et de liste) C++. Pour des raisons de compatibilité, g ++ 5.2 et versions ultérieures compilent le nouveau type conforme à C++ 11 par défaut (que vous spécifiiez ou non -std = c ++ 11), mais vous pouvez définir la macro.

-D_GLIBCXX_USE_CXX11_ABI=0

pour revenir à l'ancien type de chaîne C++. La nouvelle implémentation de libstdc ++ contient les deux ABI. Ainsi, si vous avez des fichiers binaires sur lesquels vous devez créer un lien avec l'ancien ABI non conforme, vous devez définir la macro ci-dessus sur vos compilations g ++. Cela devrait produire des binaires compatibles avec l'ancien ABI.

Malheureusement, si vous utilisez des bibliothèques du système d’exploitation autres que les bibliothèques standard C++, à moins que ces bibliothèques ne soient multiarchives dans le sens de fournir toutes les fonctions qui diffèrent par ABI dans les deux ABI, vous êtes vissé parce qu'ils auront probablement que le nouvel ABI.

Cela dit, j’ai un problème avec une ancienne Ubuntu qui télécharge un g ++ moderne non fiable qui refuse simplement de produire le nouvel ABI. Donc, il semble que le backport de ppa:ubuntu-toolchain-r/test soit en fait mal cassé car il refuse de produire des binaires conformément au nouvel ABI.

Quoi qu’il en soit, lorsque vous établissez un lien, tout doit être l’ancien ABI ou le nouvel ABI. Ce qui suit vous dira lequel vous utilisez:

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

Si cela a

std::basic_string<char, ....

en elle, c'est la ancienne ABI. Si ça a

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

en elle, c'est le nouvea ABI.

8
Yttrill

Allez à tty1 en appuyant sur: CTRL+ALT+F1

Purger gcc-5.3.1 en utilisant ceci:

Sudo apt-get purge gcc-5.3.1*

Et installez gcc-4.9.3 en utilisant ceci:

Sudo apt-get install gcc-4.9.3

Remarque: Cela nécessite une connexion Internet!

0
Eofla