
Недавно я обновил свой компьютер для разработки до Ubuntu 16.04 (чистая установка, 14.04 удалена)
Версия gcc по умолчанию — gcc-5.3.1
.
Проблема, с которой я столкнулся, заключается в том, что библиотека, поставляемая поставщиком, собрана только с использованием gcc-4.9, который несовместим с gcc-5.
Я попросил поставщика предоставить новую версию библиотеки, но маловероятно, что это произойдет в ближайшее время.
В то же время я выполнил установку gcc-4.9.3
из репозиториев пакетов Ubuntu.
Теперь у меня установлены и gcc-4.9, и 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
Я пытался собрать наш исходный код с помощью gcc-4.9, но теперь я сталкиваюсь с теми же проблемами ABI, но делаю это другим способом.
Проблема в том, что у нас есть куча зависимостей, которые мы обычно устанавливаем из пакетов дистрибутива.
sudo apt-get install \
python-dev \
libbz2-dev \
libboost-all-dev \
libprotobuf-dev \
libgoogle-perftools-dev \
postgresql \
libpqxx-dev
Хотя я могу настроить свою сборку на использование gcc-4.9
mkdir build && cd build
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 cmake ..
make -j8
Теперь я получаю ошибки компоновщика при компоновке с libtcmalloc_minimal.a
и libprotobuf.a
т. д.
Поэтому следующим шагом, который я попробовал, было удаление всех зависимостей, установленных из репозиториев дистрибутива, и начало сборки зависимостей из исходного кода.
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 ./configure
make -j8
sudo make install
Проблема в том, что я начинаю спускаться в кроличью нору. Каждая зависимость имеет другие зависимости, и я не уверен, где это закончится.
Другой вариант — вернуться к Ubuntu 14.04 или какой-либо другой версии, которая поставляется с gcc-4.9 вместо gcc-5.
Прежде чем попробовать этот термоядерный вариант, я задавался вопросом, есть ли лучший способ сделать это?
Может быть, можно установить из репозиториев, собранных с помощью gcc-4.9, или каким-то другим способом?
решение1
Проблема, с которой вы столкнулись, связана со стандартом C++11, требующим иной реализации строковых (и списковых) типов C++. Для совместимости g++5.2 и выше компилируют новый совместимый с C++11 тип по умолчанию (независимо от того, указали ли вы -std=c++11), но вы можете задать макрос
-D_GLIBCXX_USE_CXX11_ABI=0
для возврата к старому типу строки C++. Новая реализация libstdc++ содержитобаABI. Так что если у вас есть двоичные файлы, которые нужно связать со старым несовместимым ABI, вы должны установить макрос выше в ваших компиляциях g++. Это должно создать двоичные файлы, совместимые со старым ABI.
К сожалению, если вы используете библиотеки из ОС, отличные от стандартных библиотек C++, то, если только эти библиотеки не являются многоархитектурными в смысле предоставления всех функций, которые отличаются ABI вобаABI, то вы влипли, потому что у них, скорее всего, будет только новый ABI.
Сказав это, у меня возникла проблема на старой Ubuntu при загрузке ненадежного современного g++, который просто отказывается производить новый ABI. Так что, похоже, что backport from ppa:ubuntu-toolchain-r/test
на самом деле сильно сломан, поскольку он отказывается производить двоичные файлы в соответствии с новым ABI.
В любом случае, суть в том, что когда вы связываете все вместе, все должно быть либо старым ABI, либо новым ABI. Следующее покажет, что вы используете:
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
Если это так
std::basic_string<char, ....
в нем, этостарыйABI. Если у него есть
std::__cxx11::basic_string<char, ...
в нем, этоновыйАБИ.
решение2
Перейдите на tty1, нажав:CTRL+ALT+F1
Очистите gcc-5.3.1 с помощью этого:
sudo apt-get purge gcc-5.3.1*
И установите gcc-4.9.3 с помощью этого:
sudo apt-get install gcc-4.9.3
Примечание: для этого требуется подключение к Интернету!
решение3
Это хорошо использовать-D_GLIBCXX_USE_CXX11_ABI=0. но вы также можете использовать этот вариант g++, который может быть даже лучше
-fabi-version=n
Use version n of the C++ ABI. The default is version 0.
Version 0 refers to the version conforming most closely to the C++ ABI specification. Therefore, the ABI obtained using version 0 will change in different versions of G++ as ABI bugs are
fixed.
Version 1 is the version of the C++ ABI that first appeared in G++ 3.2.
Version 2 is the version of the C++ ABI that first appeared in G++ 3.4, and was the default through G++ 4.9.
Version 3 corrects an error in mangling a constant address as a template argument.
Version 4, which first appeared in G++ 4.5, implements a standard mangling for vector types.
Version 5, which first appeared in G++ 4.6, corrects the mangling of attribute const/volatile on function pointer types, decltype of a plain decl, and use of a function parameter in the
declaration of another parameter.
Version 6, which first appeared in G++ 4.7, corrects the promotion behavior of C++11 scoped enums and the mangling of template argument packs, const/static_cast, prefix ++ and --, and a class
scope function used as a template argument.
Version 7, which first appeared in G++ 4.8, that treats nullptr_t as a builtin type and corrects the mangling of lambdas in default argument scope.
Version 8, which first appeared in G++ 4.9, corrects the substitution behavior of function types with function-cv-qualifiers.
Version 9, which first appeared in G++ 5.2, corrects the alignment of "nullptr_t".
See also -Wabi.
-fabi-compat-version=n
On targets that support strong aliases, G++ works around mangling changes by creating an alias with the correct mangled name when defining a symbol with an incorrect mangled name. This switch
specifies which ABI version to use for the alias.
With -fabi-version=0 (the default), this defaults to 2. If another ABI version is explicitly selected, this defaults to 0.
The compatibility version is also set by -Wabi=n.