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.