Changing the CHOST variable

From Gentoo Wiki
Jump to: navigation, search
Other languages:
English • ‎español • ‎français • ‎日本語 • ‎한국어 • ‎русский

This document explains how to change the CHOST variable of an existing system.

Introduction

Changing the CHOST is a big issue that can seriously screw up a system - so why is there a guide for that if it can cause that much havoc?

There are certain situations where changing the CHOST variable is inevitable, e.g. when upgrading to glibc 2.4 which only supports nptl and the user finds out that the current CHOST is i386, which makes it impossible to use nptl. In this case, there are not a lot of options, and changing CHOST is one of them.

Even after following these instructions, problems may arise, so please make sure to read and execute them very carefully. In this example the CHOST variable will be changed from i386 to i686. Please change the commands according to the personal situation.

Changing the CHOST variable

Building the packages

To start out with the CHOST variable change, edit the /etc/portage/make.conf file and change the CHOST value to suit the requirements. Then, rebuild the following packages in this order:

root #emerge --ask binutils gcc glibc
Important
Please be aware that major gcc upgrades executed at the same time as changing the CHOST variable (e.g. starting with gcc 3.3, CHOST i386 and switching to gcc 4.1, CHOST i686) can lead to severe side effects. 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. As a consequence, please do one thing at a time, e.g. upgrade gcc first according to the gcc upgrade guide and change the CHOST afterwards. 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.
Note
It may be necessary to run binutils-config before compiling gcc.

Verifying things work

Now it is time to make sure that the gcc-config and binutils-config settings are sane and that there are no leftovers in /etc/env.d/.

The output of gcc-config and binutils-config should look like the following:

Note
The output may, or even will differ according to the gcc version and CHOST settings. The example below uses gcc 4.1.1 on 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

Next, check to see if there are references to the old CHOST variable in /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"
Note
This may not happen in every case, but in this case 05gcc-i386-pc-linux-gnu contains references to the old CHOST value. Things may look differently on each system depending on which CHOST value the system is changing to/from. In some cases, no references are left at all. The name may also be 05gcc-new_CHOST-pc-linux-gnu.

Before deleting the file, let's check for files with the updated CHOST value:

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"

This one looks good as there should always be only one file for gcc in /etc/env.d/ (05gcc in this example), so delete the one with the wrong references:

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

The same also applies to binutils - if there's an extra one, see which is the outdated one and delete it. Next, check the contents of /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"

That one looks good, those two files should be there. Time to move on to the gcc/ directory.

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 and i686-pc-linux-gnu-4.1.1 are fine, but config-i386-pc-linux-gnu is another leftover that needs removal.

Note
Again, the name of the file containing references to an outdated gcc version may have a different name, e.g. config-i686-pc-linux-gnu even though the system is being changed to (in this case) i686. It is important to identify the file on its content, not only the name.
root #rm config-i386-pc-linux-gnu

Now run the following commands to update the environment:

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

Next, verify everything is fixed:

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

If there are still files found, try to track it down before going on.

Finishing The Change

Now it is necessary to re-emerge libtool and run fix_libtool_files.sh which can be found in /usr/share/gcc-data/$CHOST/<gcc-version>/. Make sure to use the correct gcc version (the current one, 4.1.1 here) and pass the old architecture (i386 here) as argument. Replace $CHOST with the new CHOST value, and <gcc-version> with the gcc version. This example assumes a CHOST value applicable to i686.

root #emerge --ask 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

It is now possible to rebuild all the packages:

root #emerge -e world

In theory, it should not be necessary to do so, but it can not be 100% guaranteed that this is actually the case.

The following set of packages really need to be rebuilt:

root #emerge --ask python

All packages using perl install to the CHOST directory and hence need rebuilding. In case qfile is not available on the system yet, install app-portage/portage-utils first.

root #emerge --ask portage-utils

Now rebuild all packages that have files installed in any /usr/lib/perl* location:

root #emerge -av1 `qfile /usr/lib/perl* -Cq | sort -u`

When encountering other packages that need recompiling, please let us know through the discussion page of this guide.

Common problems

When upgrading from gcc 3.3 to 4.1 at the same time as changing the CHOST variable (please don't do that anyway), a couple of users reported broken packages that need recompiling, such as groff and courier:

CODE Error messsage
error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory

This happens because during the upgrade, the CHOST variable doesn't exactly match the CTARGET variable value, making the compiler assume that the system is using cross-compiling. As a consequence, LDPATH isn't inserted into ld.so.conf, resulting in this error.

Please see the GCC upgrade guide for what needs to be rebuilt after a GCC upgrade.

In some rare cases, this can break old versions of python, too. This may be fixed by adding /usr/lib/gcc-lib/i386-pc-linux-gnu/3.3.6 (change accordingly to the old CHOST and gcc version) to /etc/ld.so.conf, running ldconfig and then emerge libstdc++-v3. However, as can be seen, this situation needs to be avoided - don't change CHOST and gcc at the same time.

Feedback

That should be all, feedback (both if it worked, failed or other problems were encountered) is welcome, please use the discussion page or post to this forum thread. Much in this guide comes from vapier, thanks for your help!



This article is based on a document formerly found on our main website gentoo.org.
The following people have contributed to the original document: Wernfried Haas, Mike Frysinger, Chris White
They are listed here as the Wiki history does not provide for any attribution. If you edit the Wiki article, please do not add yourself here, your contributions are recorded on the history page.