GNU/Linux >> Tutoriels Linux >  >> Ubuntu

Comment dois-je gérer l'incompatibilité Abi entre Gcc-4.9 et Gcc-5 ?

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

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

Un problème que j'ai est qu'une bibliothèque fournie par un fournisseur n'est construite qu'avec 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 sitôt.

En attendant, j'ai installé gcc-4.9.3 depuis les dépôts de paquets d'Ubuntu.

J'ai maintenant installé gcc-4.9 et 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

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

Le problème que j'ai est que nous avons un tas de dépendances que nous installerions généralement à partir des packages de distribution

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

Alors que je peux 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

J'obtiens maintenant des erreurs de l'éditeur de liens lors de la liaison avec libtcmalloc_minimal.a , libprotobuf.a etc.

Donc, l'étape suivante que j'ai essayée était de supprimer toutes les dépendances installées à partir des dépôts de distribution et de commencer à créer les dépendances à partir de la 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 à me diriger vers un terrier de lapin. Chaque dépendance a d'autres dépendances, et je ne sais pas où cela va se terminer.

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

Avant d'essayer cette option thurmonuclear, je me demandais s'il y avait une meilleure façon de faire cela ?

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

Réponse acceptée :

Le problème que vous rencontrez est lié à la norme C++11 nécessitant une implémentation différente des types de chaîne (et de liste) C++. Pour des raisons de compatibilité, g++5.2 et versions ultérieures compilent par défaut le nouveau type compatible C++11 (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. Donc, si vous avez des binaires que vous devez lier 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'ancienne ABI.

En relation :Comment obtenir une résolution de 2560×1440 dans VirtualBox sur un Mac ?

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 multi-arch dans le sens de fournir toutes les fonctions qui diffèrent par ABI dans les deux ABI, alors vous êtes foutu car ils n'auront probablement que le nouvel ABI.

Cela dit, j'ai un problème sur un ancien Ubuntu qui télécharge un g ++ moderne non fiable qui refuse simplement de produire le nouvel ABI. Il semble donc que le backport de ppa:ubuntu-toolchain-r/test est en fait gravement cassé car il refuse de produire des binaires selon la nouvelle ABI.

Quoi qu'il en soit, l'essentiel est que lorsque vous reliez tout, il doit s'agir soit de l'ancien ABI, soit du nouveau 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, ....

dedans, c'est l'ancien ABI. S'il a

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

dedans, c'est le nouveau AB.


Ubuntu
  1. Comment gérer les bibliothèques dynamiques et statiques sous Linux

  2. Linux - Comment basculer entre les sessions Tty et Xorg ?

  3. Comment installer Gcc-5.3 sur Ubuntu 16.04 ?

  4. Qu'est-ce que la curation de contenu et comment procéder ?

  5. Comment partager des fichiers entre Ubuntu et Mac OS X

Certains gestionnaires d'affichage Ubuntu courants et comment basculer entre eux

Comment basculer entre GDM et LightDM dans Ubuntu [Astuce rapide]

Comment basculer entre Xorg et Wayland dans Ubuntu

Comment synchroniser le presse-papiers entre le bureau Ubuntu et le téléphone Android ?

Comment copier des fichiers entre l'hôte et le conteneur Docker

Comment partager un fichier entre Ubuntu et Windows 10 ?