Изменение переменной CHOST

From Gentoo Wiki
Jump to: navigation, search
This page is a translated version of the page Changing the CHOST variable and the translation is 79% complete.

Other languages:
English • ‎español • ‎français • ‎日本語 • ‎한국어 • ‎русский • ‎中文(中国大陆)‎

Данный документ объясняет, как изменить переменную CHOST на существующей системе.

Введение

Изменение CHOST может доставить много «головной боли» и серьезно испортить систему. Зачем тогда нужно данное руководство, если это может привести к хаосу?

Существуют ситуации, когда изменение переменной CHOST необходимо, например, при обновлении библиотеки glibc до версии 2.4, которая поддерживает nptl, пользователь узнается, что текущий CHOST — это i386, что делает использование nptl невозможным. В данном случае не так уж и много возможностей, и изменение CHOST одна из них.

Проблемы могут возникнуть, даже после выполнения этих инструкций, так что, пожалуйста, внимательно читайте и очень тщательно выполняйте их. В данном примере переменная CHOST изменится с i386 на i686. Пожалуйста, скорректируйте команды в соответствии с персональной ситуацией.

Изменение переменной CHOST

Updating make.conf

To start out with the CHOST variable change, edit the /etc/portage/make.conf file and add/change the CHOST value to suit the requirements.

Файл /etc/portage/make.conf
CHOST="i686-pc-linux-gnu"

Please note that if you are planning to use another value of CHOST than the profile default, you may need to update the CHOST_${ABI} variable as well. You can query the current value of these variable via portageq tool:

user $portageq envvar ABI
x86
user $portageq envvar CHOST_x86
i686-pc-linux-gnu

If this value is equal to your CHOST, you're good. Otherwise, you should override it as well, e.g.:

Файл /etc/portage/make.conf
CHOST_x86="i686-pc-linux-gnu"

Собираем пакеты

Важно
It is generally a good idea to rebuild the packages to the same versions as before the CHOST switch, i.e. avoiding combining upgrades with it. If you have multiple slots installed, either uninstall extraneous slots or rebuild all of them. If you can't do that, please upgrade the packages first (with old CHOST). While it may not be impossible to do so, it is hard to predict which potential problems may arise and almost impossible to document them in this guide.
Совет
On a system with CHOST set to an i386 value, mask glibc 2.4 (or newer) during the gcc upgrade as it cannot be used with i386. Unmask it once the change has been performed completely.

Rebuild the following packages in this order:

root #emerge --ask --oneshot sys-devel/binutils
Заметка
Перед компиляцией gcc может понадобиться запустить binutils-config.
root #emerge --ask --oneshot sys-devel/gcc
root #emerge --ask --oneshot sys-libs/glibc

Проверяем, что всё работает

Пришло время проверить, что настройки gcc-config и binutils-config в порядке, и что нет никакого «мусора» в /etc/env.d/.

Вывод gcc-config и binutils-config должен выглядеть следующим образом:

Заметка
Вывод скорее всего будет отличаться в зависимости от версии gcc и настроек CHOST. В примере ниже используется gcc 4.1.1 на i686.
root #gcc-config -l
 [1] i686-pc-linux-gnu-4.1.1 *
root #gcc-config -c
i686-pc-linux-gnu-4.1.1
root #binutils-config -l
 [1] i686-pc-linux-gnu-2.16.1 *
# binutils-config -c
i686-pc-linux-gnu-2.16.1

Теперь проверим, остались ли ссылки на старую переменную CHOST в /etc/env.d/:

root #cd /etc/env.d/
root #grep 386 *
05gcc-i386-pc-linux-gnu:PATH="/usr/i386-pc-linux-gnu/gcc-bin/4.1.1"
05gcc-i386-pc-linux-gnu:ROOTPATH="/usr/i386-pc-linux-gnu/gcc-bin/4.1.1"
Заметка
Обычно этого может не произойти, но в рассматриваемом примере файл 05gcc-i386-pc-linux-gnu содержит ссылку на старое значение CHOST. Ситуация может выглядеть иначе на других системах, в зависимости от того, с какого и на какое значение меняется CHOST. В некоторых случаях не остается никаких упоминаний. Имя файла также может быть 05gcc-new_CHOST-pc-linux-gnu.

Перед удалением файла проверьте файлы с новым CHOST:

root #grep 686 *
05binutils:MANPATH=/usr/share/binutils-data/i686-pc-linux-gnu/2.16.1/man
05binutils:INFOPATH=/usr/share/binutils-data/i686-pc-linux-gnu/2.16.1/info
05binutils:LDPATH=/usr/i686-pc-linux-gnu/lib
05gcc:PATH="/usr/i686-pc-linux-gnu/gcc-bin/4.1.1"
05gcc:ROOTPATH="/usr/i686-pc-linux-gnu/gcc-bin/4.1.1"
05gcc:MANPATH="/usr/share/gcc-data/i686-pc-linux-gnu/4.1.1/man"
05gcc:INFOPATH="/usr/share/gcc-data/i686-pc-linux-gnu/4.1.1/info"
05gcc:LDPATH="/usr/lib/gcc/i686-pc-linux-gnu/4.1.1"

Всё выглядит хорошо, так как для gcc всегда должен быть только один файл в /etc/env.d/ (в этом примере 05gcc), так что удалим файл с ошибочной ссылкой:

root #rm 05gcc-i386-pc-linux-gnu

Аналогично поступим с файлами binutils: если существует больше одного файла, смотрите, какой является устаревшим и удалите его. Далее, проверьте содержимое /etc/env.d/binutils/.

root #cd /etc/env.d/binutils/
root #ls -la
total 8
-rw-r--r-- 1 root root  15 Sep  3 13:48 config-i686-pc-linux-gnu
-rw-r--r-- 1 root root 126 Sep  3 13:48 i686-pc-linux-gnu-2.16.1
root #cat config-i686-pc-linux-gnu
CURRENT=2.16.1
root #cat i686-pc-linux-gnu-2.16.1
TARGET="i686-pc-linux-gnu"
VER="2.16.1"
LIBPATH="/usr/lib/binutils/i686-pc-linux-gnu/2.16.1"
FAKE_TARGETS="i686-pc-linux-gnu"

Всё хорошо, эти два файла и должны быть тут. Пришло время заглянуть в каталог gcc/.

root #cd /etc/env.d/gcc
# ls -la
total 12
-rw-r--r-- 1 root root  32 Sep  3 16:43 config
-rw-r--r-- 1 root root  32 Aug  3 14:25 config-i386-pc-linux-gnu
-rw-r--r-- 1 root root 292 Sep  3 16:43 i686-pc-linux-gnu-4.1.1
root #cat config
CURRENT=i686-pc-linux-gnu-4.1.1
root #cat config-i386-pc-linux-gnu
CURRENT=i386-pc-linux-gnu-4.1.1
root #cat i686-pc-linux-gnu-4.1.1
PATH="/usr/i686-pc-linux-gnu/gcc-bin/4.1.1"
ROOTPATH="/usr/i686-pc-linux-gnu/gcc-bin/4.1.1"
LDPATH="/usr/lib/gcc/i686-pc-linux-gnu/4.1.1"
GCCBITS="32"
MANPATH="/usr/share/gcc-data/i686-pc-linux-gnu/4.1.1/man"
INFOPATH="/usr/share/gcc-data/i686-pc-linux-gnu/4.1.1/info"
STDCXX_INCDIR="g++-v4"

Файлы config и i686-pc-linux-gnu-4.1.1 в порядке, а config-i386-pc-linux-gnu — «мусор», который нужно удалить.

Заметка
Опять же файл, содержащий ссылку на старую версию gcc, может иметь другое имя (например, config-i686-pc-linux-gnu) даже в случае, когда система меняется (в данном случае) на CHOST i686. Важно различать файлы по содержимому, а не только по имени.
root #rm config-i386-pc-linux-gnu

Теперь запустите следующую команду для обновления переменных среды:

root #env-update && source /etc/profile

Далее проверим, что всё в порядке:

root #grep -r 386 /etc/env.d/

Если все еще находятся файлы, попробуйте отследить их, прежде чем продолжить.

Завершение изменений

Теперь нужно пересобрать sys-devel/libtool и запустить fix_libtool_files.sh, который можно найти в /usr/share/gcc-data/$CHOST/<gcc-version>/. Убедитесь, что указали правильную версию gcc (текущую выбранную, здесь 4.1.1) и передали старую архитектуру (здесь i386) в качестве аргумента. Замените $CHOST новым значением переменной CHOST, а <gcc-version> версией gcc. Следующий пример подразумевает CHOST значение i686.

root #emerge --ask --oneshot libtool
root #/usr/share/gcc-data/i686-pc-linux-gnu/4.1.1/fix_libtool_files.sh 4.1.1 --oldarch i386-pc-linux-gnu

Теперь можно пересобрать все пакеты:

root #emerge -e world

In theory, it should not be necessary to do so, but it cannot be 100% guaranteed that this is actually the case. Alternatively, you can manually rebuild all the known problematic packages:

  • multilib packages using CHOST prefixing or header wrapping,
  • Perl, Python and other tools that store configured compiler path.
root #emerge --ask --oneshot /usr/bin/i386-pc-linux-gnu-* /usr/include/i386-pc-linux-gnu /usr/lib/llvm/*/bin/i386-pc-linux-gnu-* dev-lang/perl dev-lang/python

Note that you may need to remove paths that do not apply to your system from the above invocation.

Если обнаружили пакет, который также требует пересборки, то, пожалуйста, сообщите нам на странице обсуждения этого руководства.

Известные проблемы

При обновлении с gcc 3.3 до 4.1 одновременно с изменением переменной CHOST (и всё же, пожалуйста, не делайте этого), пара пользователей сообщала о «битых» пакетах, которые нуждаются в пересборке, таких как sys-apps/groff и mail-mta/courier:

Код Сообщение об ошибке
error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory

Это происходит, поскольку процессе обновления CHOST не соответствует CTARGET, из-за чего компилятор считает что в системе используется кросс-компиляция. Как следствие, LDPATH не вносится в ld.so.conf, что приводит к ошибке.

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

В некоторый редких случаях, могут также «сломаться» старые версии python. Это можно исправить, добавив /usr/lib/gcc-lib/i386-pc-linux-gnu/3.3.6 (измените в соответствии со старым CHOST и версией gcc) в /etc/ld.so.conf, запустите ldconfig и, затем, emerge libstdc++-v3. Однако, как можно увидеть, этих проблем определённо стоит избегать — не изменяйте CHOST и версию gcc одновременно.

Обратная связь

На этом, должно быть, всё. Отзывы (как в случае, если это сработало, так и в случае неудачи или неожиданных проблем) приветствуются: пожалуйста, используйте страницу обсуждения или сообщите в этом треде форума. Многое в этом руководстве сделано участником vapier, спасибо за помощь!


This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Wernfried Haas, Mike Frysinger (vapier), Chris White
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.