GNU/Linux >> LINUX-Kenntnisse >  >> Ubuntu

Wie soll ich mit der Abi-Inkompatibilität zwischen Gcc-4.9 und Gcc-5 umgehen?

Ich habe kürzlich meinen Entwicklungscomputer auf Ubuntu 16.04 aktualisiert (Neuinstallation, 14.04 gelöscht)

Die Standardversion von gcc ist gcc-5.3.1 .

Ein Problem, das ich habe, ist, dass eine vom Hersteller bereitgestellte Bibliothek nur mit gcc-4.9 erstellt wurde, das nicht mit gcc-5 kompatibel ist.

Ich habe den Anbieter gebeten, eine neue Version der Bibliothek bereitzustellen, aber es ist unwahrscheinlich, dass dies in absehbarer Zeit geschehen wird.

Inzwischen habe ich gcc-4.9.3 installiert aus den Paket-Repos von Ubuntu.

Ich habe jetzt sowohl gcc-4.9 als auch gcc-5 installiert:

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

Ich habe versucht, unseren Quellcode mit gcc-4.9 zu erstellen, aber jetzt stoße ich auf die gleichen ABI-Probleme, aber in die andere Richtung.

Das Problem, das ich habe, ist, dass wir eine Reihe von Abhängigkeiten haben, die wir normalerweise aus den Distributionspaketen installieren würden

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

Während ich meinen Build so konfigurieren kann, dass er gcc-4.9 verwendet

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

Ich bekomme jetzt Linker-Fehler, wenn ich gegen libtcmalloc_minimal.a verlinke , libprotobuf.a usw.

Der nächste Schritt, den ich versuchte, bestand also darin, alle installierten Abhängigkeiten aus den Distributionsrepos zu entfernen und mit dem Erstellen der Abhängigkeiten aus den Quellen zu beginnen.

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

Das Problem hier ist, dass ich anfange, in ein Kaninchenloch zu gehen. Jede Abhängigkeit hat andere Abhängigkeiten, und ich bin mir nicht sicher, wo sie enden wird.

Die andere Option ist ein Downgrade auf Ubuntu 14.04 oder eine Version, die mit gcc-4.9 statt gcc-5 ausgeliefert wird.

Bevor ich diese thurmonucleare Option ausprobiere, habe ich mich gefragt, ob es einen besseren Weg gibt, dies zu tun?

Vielleicht ist es möglich, von Repos zu installieren, die mit gcc-4.9 erstellt wurden, oder auf andere Weise?

Akzeptierte Antwort:

Das Problem, das Sie haben, hängt mit dem C++11-Standard zusammen, der eine andere Implementierung von C++-Zeichenfolgen- (und Listen-)Typen erfordert. Aus Kompatibilitätsgründen kompiliert g++5.2 und höher standardmäßig den neuen C++11-kompatiblen Typ (unabhängig davon, ob Sie -std=c++11 angeben oder nicht), aber Sie können das Makro

festlegen
-D_GLIBCXX_USE_CXX11_ABI=0

um zum alten C++-String-Typ zurückzukehren. Die neue libstdc++-Implementierung enthält beides ABIs. Wenn Sie also Binärdateien haben, gegen die Sie mit der alten, nicht kompatiblen ABI verknüpfen müssen, müssen Sie das obige Makro auf Ihren g++-Kompilierungen festlegen. Dies sollte Binärdateien erzeugen, die mit der alten ABI kompatibel sind.

Verwandte:Wie bekomme ich eine Auflösung von 2560 × 1440 in VirtualBox auf einem Mac?

Wenn Sie andere Bibliotheken aus dem Betriebssystem als die C++-Standardbibliotheken verwenden, dann leider, es sei denn, diese Bibliotheken sind Multi-Arch im Sinne der Bereitstellung aller Funktionen, die sich von ABI in beiden unterscheiden ABIs, dann bist du am Arsch, weil die wahrscheinlich nur das neue ABI haben werden.

Allerdings habe ich ein Problem mit einem alten Ubuntu, das ein nicht vertrauenswürdiges modernes g ++ herunterlädt, das sich einfach weigert, das neue ABI zu erstellen. Es scheint also, dass die Rückportierung von ppa:ubuntu-toolchain-r/test ist in der Tat stark kaputt, weil es sich weigert, Binärdateien gemäß der neuen ABI zu erstellen.

Wie auch immer, das Endergebnis ist, wenn Sie alles miteinander verbinden, muss es entweder das alte ABI oder das neue ABI sein. Folgendes zeigt an, welche Sie verwenden:

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

Falls ja

std::basic_string<char, ....

darin ist es das alte ABI. Falls ja

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

Darin ist es das Neue ABI.


Ubuntu
  1. Umgang mit dynamischen und statischen Bibliotheken unter Linux

  2. Linux – Wie wechselt man zwischen Tty- und Xorg-Sitzung?

  3. Wie finde/grep was zwischen String1 und String2 ist?

  4. Wie installiert man Gcc-5.3 auf Ubuntu 16.04?

  5. Was ist Content Curation und wie sollten Sie es tun?

Einige gängige Ubuntu Display Manager und wie man zwischen ihnen wechselt

So wechseln Sie zwischen GDM und LightDM in Ubuntu [Kurztipp]

So wechseln Sie zwischen Xorg und Wayland in Ubuntu

Wie synchronisiert man die Zwischenablage zwischen Ubuntu Desktop und Android Phone?

So kopieren Sie Dateien zwischen Host und Docker-Container

Wie teilt man Dateien zwischen Ubuntu und Windows 10?