Изменение переменной CHOST
Данный документ объясняет, как изменить переменную CHOST на существующей системе.
Введение
Изменение CHOST может доставить много «головной боли» и серьезно испортить систему. Зачем тогда нужно данное руководство, если это может привести к хаосу?
Существуют ситуации, когда изменение переменной CHOST необходимо, например, при обновлении библиотеки glibc до версии 2.4, которая поддерживает nptl, пользователь узнается, что текущий CHOST — это i386, что делает использование nptl невозможным. В данном случае не так уж и много возможностей, и изменение CHOST одна из них.
Проблемы могут возникнуть, даже после выполнения этих инструкций, так что, пожалуйста, внимательно читайте и очень тщательно выполняйте их. В данном примере переменная CHOST изменится с i386 на i686. Пожалуйста, скорректируйте команды в соответствии с конкретной ситуацией.
Изменение переменной CHOST
Обновление 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 this 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 --ask --emptytree @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.