Обновление GCC

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Upgrading GCC and the translation is 73% complete.
Outdated translations are marked like this.

GCC upgrades should generally be handled gracefully with Portage and the usual Gentoo tools, see next section. If ever there are more involved updates that require user intervention, they should be accompanied by a corresponding news item, that should be read and followed.

Обратите внимание, что понижение версии GCC может иметь нежелаемые побочные эффекты. Обратитесь к секции Устранение проблем для информации по часто встречаемым проблемам.

Quick guide to GCC upgrades

Большинство обновлений GCC так же просты, как смена версии компилятора (тут с 10.3.0 на 11.2.0) и пересборка sys-devel/libtool:

root #emerge --ask --oneshot sys-devel/gcc
root #gcc-config --list-profiles
[1] x86_64-pc-linux-gnu-5.4.0 *
[2] x86_64-pc-linux-gnu-6.4.0
root #gcc-config 2
root #source /etc/profile
root #emerge --ask --oneshot --usepkg=n sys-devel/libtool

Проверьте текущую версию и удалите старую версию:

root #gcc --version
root #emerge --ask --depclean =sys-devel/gcc-5.4.0

Наслаждайтесь новым компилятором!

Объяснение обновления GCC

Обновление GCC всегда считалось какой-то мистикой, с предположениями от "пользователям ничего не нужно делать" до "пользователям нужно дважды пересобрать всю свою систему". Большинство страха, неуверенности и сомнений проистекает из проблем, связанных с несовместимостью ABI. Такое редко происходит в наши дни (и когда происходит, это анонсируется). Но, сначала кратко о libtool.

libtool

Причина, по которой нужно пересобирать libtool после обновления версий gcc это потому, что главной функцией libtool является объединение кода, зависящего от платформы в общем интерфейсе, что позволяет приложениям использовать разделяемые библиотеки без нужды иметь дело с вещами, зависящими от платформы для разделяемых библиотек. Чтобы реализовать эту функцию, скрипт libtool использует различные пути до библиотек, в которых есть жестко заданная информация о версии gcc.

Смотрите bug #88596.

Изменения ABI

До GCC 5.1

ABI, или Двоичный интерфейс приложений, это набор соглашений, используемых всеми инструментами, работающими с бинарным видом программ, например, компиляторы, ассемблеры, линкеры и поддержка рантайма для языков (источник: Бинарная совместимость GCC). Когда ABI, используемый для бинарных приложений и библиотек меняется, появляется риск получить ошибку компоновщика, либо неработающие программы, если только вы не пересоберёте все программы, использующие код C++.

Да, C++, поскольку в большинстве случаев несоответствия обнаруживаются на уровне двоичного интерфейса приложений C++. Если вы обновляетесь до GCC 4.1, или GCC 5.1, вы, вероятно, столкнетесь с проблемами в двоичном интерфейсе. Чтобы избежать этого должна быть запущена команда revdep-rebuild для libstdc++.so.5 (от GCC 3 до GCC 4.1), или libstdc++.so.6 (от GCC 4 до GCC 5.1).

root #revdep-rebuild --library 'libstdc++.so.6' -- --exclude gcc

Так почему же это нужно только до GCC 3.4.0/4.1/5? Это потому что с этой версии GCC использует обратно-совместимое ABI, и пересборка приложений и библиотек больше не требуется. Конечно, мы не можем дать вам гарантию, что так будет вечно, но если снова возникнет несоответствие, мы явно опишем этот случай здесь. В этом случае, скорее всего, будет увеличена версия библиотеки libstdc++.so.

Особый случай C++11 (и C++14)

В то время как GCC (или точнее libstdc++) идет большими шагами вперед, гарантируя стабильность ABI, эта гарантия не распространяется на все части C++ в libstdc++. Формально, начиная с версии 3.4, GCC/libstdc++ только гарантируется стабильность C++98/C++03 ABI и не более. Это очень важно для пакетов, которые зависят от C++11. GCC даёт гарантию на стабильность C++11 ABI, начиная только с версии 5.1. Это означает, что переключение (даже незначительные) версии GCC (скажем, от 4.7.3 -> 4.7.4) может привести к поломке ABI для бинарных файлов, собранных из C++11 кода.

Более подробную информацию и некоторые примеры можно найти здесь:

Понижение версии GCC

For the aforementioned reasons, if downgrading GCC or choosing an older slot with gcc-config, it is necessary to run revdep-rebuild to catch libstdc++ consumers requiring newer symbols:

root #revdep-rebuild --library 'libstdc++.so.6' -- --exclude gcc

Какие пакеты определенно нужно пересобрать?

В следующей таблице приведены пакеты, которые нужно пересобрать, если они установлены, и причины этой необходимости.

Пакет Нужно пересобрать, потому что...
sys-devel/libtool приложение libtool имеет внутри себя вшитые пути к встроенным библиотекам GCC. Смотрите bug #88596.
root #emerge --ask --oneshot --usepkg=n --verbose sys-devel/libtool

Также известны случаи, когда пакеты должны быть собраны одним и тем же компилятором (к примеру, различные qt-* пакеты). Эти пакеты чаще всего обновляются сопровождающими пакета одновременно (поэтому они всегда будут собираться одной и той же версией GCC). Выборочная переустановка таких пакетов часто сопровождается проблемами.

Пересборка всего

Совет
This isn't necessary but is described here so people know how to do it thoroughly if they desire.

Некоторые люди клянутся, что нужно пересобрать все пакеты на их системе при выходе новой версии GCC. Конечно, в этом нет смысла, так как многие приложения не используют GCC для процесса сборки и установки, и на них вообще не распространяется это изменение.

Это, однако, не означает, что они полностью неправы: новые версии GCC часто предлагают более хорошую поддержку набора инструкций процессора, а это может повлиять на производительность приложений в лучшую сторону.

Кроме таких "небольших" плюсов, пересборка всего с нуля может быть обязательна в некоторых случаях, чтобы исправить проблемы без очевидных причин.

Некоторые проблемы с программами исконно трудны в диагностике, но их можно решить простой пересборкой одного или больше соответствующих пакетов. Если подобная проблема возникла после обновления GCC и сохранилась после применения revdep-rebuild как показано выше (и после пересборки прочих очевидно связанных пакетов), полная пересборка системы может решить этот вопрос.

Самый "безопасный" (но также затратный по времени) способ этого достичь - использование опции --emptytree (-e) для emerge, чтобы пересобрать системные пакеты и мир:

root #emerge --ask --emptytree --usepkg=n @system
root #emerge --ask --emptytree --usepkg=n @world

Пользователям рекомендуется попробовать этот подход, прежде чем писать о багах, которые могли произойти из-за обновления GCC.

(Заметьте, что команды выше пересоберут пакеты в системном наборе дважды, что необходимо, дабы быть "абсолютно уверенными", что каждый пакет был собран в одинаковой [предположительно] "безпроблемной" среде. Любые проблемы, что сохраняются после этого - действительно баги, о которых нужно сообщить, или серьёзные проблемы с конфигурацией системы.)

Устранение проблем

пересборка boost

Если dev-libs/boost нужно пересобрать, вы получите следующее сообщение об ошибке:

root #emerge ...
checking for the Boost _____ library... no
configure: error: cannot find the flags to link with Boost _____

Пересобрать можно с помощью:

root #emerge --ask --oneshot --usepkg=n --verbose dev-libs/boost

libstdc++.so.6: version `GLIBCXX_3.4.15' not found

В процессе обновлений вы можете встретить ошибку, похожую на следующую:

КОД GLIBCXX_x.y.z not found
cmake_bootstrap_28021_test: /usr/lib/gcc/i486-pc-linux-gnu/4.1.2/libstdc++.so.6:
version `GLIBCXX_3.4.11' not found

Это означает, что вы пытаетесь собрать пакет более старой версией GCC, чем собирались библиотеки, от которых зависит пакет. Помните, мы говорили, что C++ ABI обратно совместим? Это так, но означает только, что для сборки приложений и линковки библиотек могут использоваться более новые (или те же самые) версии GCC (по сравнению с версией GCC, использованной для сборки этих библиотек).

Как сделать пересборку всех зависящих пакетов от libstdc++ смотрите инструкции команды revdep-rebuild.

Смотрите также

Внешние ресурсы

Ссылки