Saya baru saja memutakhirkan mesin dev saya ke Ubuntu 16.04 (instalasi baru, dihapus 14.04)
Versi default gcc adalah gcc-5.3.1
.
Masalah yang saya miliki adalah pustaka yang disediakan vendor hanya dibuat menggunakan gcc-4.9, yang tidak kompatibel dengan gcc-5.
Saya telah meminta vendor untuk menyediakan versi perpustakaan yang baru, tetapi sepertinya hal itu tidak akan terjadi dalam waktu dekat.
Sementara itu saya telah menginstal gcc-4.9.3
dari repo paket Ubuntu.
Sekarang saya telah menginstal gcc-4.9 dan 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
Saya mencoba membangun sumber kami dengan gcc-4.9, tetapi sekarang saya menghadapi masalah ABI yang sama, tetapi sebaliknya.
Masalah yang saya miliki adalah kami memiliki banyak dependensi yang biasanya kami instal dari paket distro
sudo apt-get install \
python-dev \
libbz2-dev \
libboost-all-dev \
libprotobuf-dev \
libgoogle-perftools-dev \
postgresql \
libpqxx-dev
Sementara saya dapat mengonfigurasi build saya untuk menggunakan gcc-4.9
mkdir build && cd build
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 cmake ..
make -j8
Saya sekarang mendapatkan kesalahan tautan saat menautkan ke libtcmalloc_minimal.a
, libprotobuf.a
dll.
Jadi langkah selanjutnya yang saya coba adalah menghapus semua dependensi yang diinstal dari repo distro dan mulai membangun dependensi dari sumber.
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 ./configure
make -j8
sudo make install
Masalahnya di sini adalah saya mulai memasuki lubang kelinci. Setiap ketergantungan memiliki ketergantungan lain, dan saya tidak yakin di mana itu akan berakhir.
Opsi lainnya adalah menurunkan versi kembali ke Ubuntu 14.04 atau beberapa versi yang dikirimkan dengan gcc-4.9 alih-alih gcc-5.
Sebelum mencoba opsi thurmonuklir ini, saya bertanya-tanya apakah ada cara yang lebih baik untuk melakukannya?
Mungkinkah menginstal dari repo yang dibuat dengan gcc-4.9, atau cara lain?
Jawaban yang Diterima:
Masalah yang Anda miliki terkait dengan standar C++ 11 yang membutuhkan implementasi tipe string (dan daftar) C++ yang berbeda. Untuk kompatibilitas, g++5.2 dan di atasnya mengompilasi tipe baru yang sesuai dengan C++11 secara default, (terlepas dari apakah Anda menentukan -std=c++11), tetapi Anda dapat mengatur makro
-D_GLIBCXX_USE_CXX11_ABI=0
untuk kembali ke tipe string C++ lama. Implementasi libstdc++ baru berisi keduanya ABI. Jadi, jika Anda memiliki binari yang harus Anda tautkan dengan ABI lama yang tidak sesuai, Anda harus menyetel makro di atas pada kompilasi g++ Anda. Ini akan menghasilkan binari yang kompatibel dengan ABI lama.
Terkait:Bagaimana cara mendapatkan resolusi 2560 × 1440 dalam VirtualBox di Mac?Sayangnya jika Anda menggunakan pustaka dari OS selain Pustaka Standar C++, maka kecuali pustaka ini multi-lengkungan dalam arti menyediakan semua fungsi yang berbeda menurut ABI di keduanya ABI, maka Anda kacau karena mereka mungkin hanya memiliki ABI baru.
Setelah mengatakan bahwa saya memiliki masalah pada Ubuntu lama yang mengunduh g++ modern yang tidak tepercaya yang hanya menolak untuk menghasilkan ABI baru. Jadi sepertinya backport dari ppa:ubuntu-toolchain-r/test
sebenarnya rusak parah karena menolak menghasilkan binari menurut ABI baru.
Bagaimanapun intinya adalah ketika Anda menghubungkan semuanya harus ABI lama atau ABI baru. Berikut ini akan memberi tahu mana yang Anda gunakan:
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
Jika sudah
std::basic_string<char, ....
di dalamnya, itu yang lama ABI. Jika sudah
std::__cxx11::basic_string<char, ...
di dalamnya, ini adalah baru ABI.