Zmiana wartości zmiennej CHOST
1.
Wstęp
Zmiana wartości zmiennej CHOST może być problemem, który poważnie może uszkodzić
system. Zatem dlaczego jest do tego w ogóle przewodnik?
Istnieje sporo przypadków, kiedy zmiana wartości zmiennej CHOST jest
nieunikniona, np. jeśli chce się zaktualizować glibc 2.4, które wspiera tylko
nptl, a zmienna CHOST to i386, co uniemożliwia wykorzystanie nptl. W takim
wypadku nie ma zbyt dużej liczby rozwiązań problemu. Zmiana wartości zmiennej
CHOST jest jedną z nich.
Nawet jeśli wykona się poniższe instrukcje, mogą powstać problemy, dlatego
trzeba być podczas całego procesu bardzo uważnym. W tym przykładzie zmienna
CHOST będzie zmieniania z i386 na i686. Aby dokonać zmiany z innych wartości
zmiennej CHOST, należy zmienić odpowiednio komendy.
2.
Zmiana wartości zmiennej CHOST
Instalowanie pakietów
Aby zmienić wartość zmiennej CHOST, otwieramy plik /etc/make.conf i
zmieniamy wartość CHOST na taką, jakiej potrzebujemy. Potem należy
przebudować następujące pakiety:
Listing 2.1: Przebudowanie ważnych narzędzi systemowych |
# emerge -av1 binutils gcc glibc
|
Ważne:
Aktualizacja gcc i zmiana wartości zmiennej CHOST w tym samym czasie (np. wersja
gcc 3.3, wartość zmiennej CHOST i386 zmieniane na gcc w wersji 4.1 i wartość
zmiennej CHOST na i686) mogą powodować szereg problemów dodatkowych. Może się
okazać niemożliwe wykonanie tej zmiany. Dlatego ostrzegamy, należy wykonywać
tylko jedną czynność naraz, np. zaktualizować najpierw gcc (korzystając z
podręcznika aktualizacji gcc) a
następnie zmienić wartość zmiennej CHOST. Jeśli wartość zmiennej CHOST to i386,
trzeba zamaskować pakiet glibc w wersji 2.4 (lub nowszej) podczas aktualizacji
gcc, tak by nie mógł on być użyty z i386. Po skończonej aktualizacji
odmaskowujemy go.
|
Sprawdzenie wprowadzonych zmian
Teraz sprawdzimy czy ustawienia gcc-config i binutils-config są w
porządku i czy nie ma żadnych pozostałości w /etc/env.d/.
Wynik poleceń gcc-config i binutils-config powinien wyglądać mniej
więcej tak jak poniżej (mogą się nieznacznie różnić z zależności od wersji gcc i
wartości CHOST). My podajemy przykłady dla wersji 4.1.1 i 2.16.1.
Listing 2.2: Sprawdzenie poprawności ustawień |
# gcc-config -l
[1] i686-pc-linux-gnu-4.1.1 *
# gcc-config -c
i686-pc-linux-gnu-4.1.1
# binutils-config -l
[1] i686-pc-linux-gnu-2.16.1 *
# binutils-config -c
i686-pc-linux-gnu-2.16.1
|
Następnie wyszukujemy odwołania do starej wartości zmiennej CHOST w katalogu
/etc/env.d/:
Listing 2.3: Sprawdzenie odwołań do starej wartości zmiennej CHOST |
# cd /etc/env.d/
# 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"
|
Uwaga:
Może się to nie zdarzyć każdemu, ale akurat w tym wypadku plik
05gcc-i386-pc-linux-gnu zawiera odwołanie do starej wartości zmiennej CHOST.
Ustawienia w systemie, które odwołują się do wartości zmiennej CHOST mogą się
różnić od przykładu albo być w porządku. Nazwa powinna wyglądać tak:
05gcc-nowa_wartość_CHOST-pc-linux-gnu.
|
Przed skasowaniem tego pliku należy sprawdzić pliki ze zaktualizowaną wartością
zmiennej CHOST:
Listing 2.4: Sprawdzenie plików ze zaktualizowaną wartością zmiennej CHOST |
# 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"
|
Ten plik wygląda dobrze. Jest tylko jeden problem. Powinien być tylko jeden plik
dla gcc w katalogu /etc/env.d/ (05gcc w tym przykładzie),
więc kasujemy ten drugi z niepoprawnym odwołaniem:
Listing 2.5: Usuwanie plików z niepoprawnymi odwołaniami |
# rm 05gcc-i386-pc-linux-gnu
|
To same kroki należy wykonać dla binutils. Jeśli jest jakiś dodatkowy
niepasujący do wersji zmiennej CHOST plik, należy go usunąć. Następnie
sprawdzamy katalog /etc/env.d/binutils/
Listing 2.6: Sprawdzenie zawartości katalogu binutils |
# cd /etc/env.d/binutils/
# 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
# cat config-i686-pc-linux-gnu
CURRENT=2.16.1
# 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"
|
Ten katalog wygląda dobrze, te dwa pliki powinny w nim zostać. Teraz czas na
przejście do katalogu gcc.
Listing 2.7: Sprawdzenie zawartości katalogu gcc |
# 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
# cat config
CURRENT=i686-pc-linux-gnu-4.1.1
# cat config-i386-pc-linux-gnu
CURRENT=i386-pc-linux-gnu-4.1.1
# 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"
|
Pliki config i i686-pc-linux-gnu-4.1.1 wyglądają w
porządku, ale plik config-i386-pc-linux-gnu jest kolejną
pozostałością do usunięcia.
Uwaga:
Ponownie nazwa pliku zawiera odwołanie do nieistniejącej wersji gcc, np.
config-i686-pc-linux-gnu, nawet jeśli zmieniono wartość na i686. Jest ważne, aby
sprawdzać pliki po ich zawartości, a nie tylko po nazwie.
|
Listing 2.8: Usuwanie niepoprawnego pliku konfiguracyjnego dla gcc |
# rm config-i386-pc-linux-gnu
|
Następnie wykonujemy poniższe komendy, aby zaktualizować środowisko:
Listing 2.9: Aktualizacja środowiska |
# env-update && source /etc/profile
|
Następnie sprawdzamy czy wszystko jest w porządku:
Listing 2.10: Sprawdzenie odwołań do starej wartości zmiennej CHOST |
# grep -r 386 /etc/env.d/
|
Jeśli ciągle istnieją niepoprawne odwołania, najprawdopodobniej pominięto jakiś
plik. Trzeba znaleźć go ręcznie przed przejściem dalej.
Kończenie zmian
Następnie koniecznie należy przekompilować pakiet libtool i wykonać
polecenie fix_libtool_files.sh. Należy upewnić się, że używa się
odpowiedniej wersji gcc.
Listing 2.11: Zapewnienie poprawności biblioteki |
# emerge -av1 libtool
# fix_libtool_files.sh 4.1.1 --oldarch i386-pc-linux-gnu
|
Teraz jest dobra okazja by przebudować cały system:
Listing 2.12: Przebudowa world |
# emerge -e world
|
Przebudowa systemu jest wskazana, ale nie konieczna, poza tym nie ma 100%
pewności, że to ten przypadek. Jeśli nie przebudowano całego systemu na pewno
pewne pakiety wymagają rekompilacji. Zaczynamy od:
Listing 2.13: Rekompilacja pythona |
# emerge -av1 python
|
Pakiety związane z perlem instalują się do katalogu, który ma zmienną CHOST w
nazwie. W związku z tym należy je teraz wszystkie przebudować. Jeśli w systemie
nie ma jeszcze programu qfile, trzeba będzie najpierw zainstalować pakiet
app-portage/portage-utils.
Listing 2.14: Ponowna instalacja pakietów perla |
# emerge -av portage-utils
# emerge -av1 `qfile /usr/lib/perl* -Cq | sort -u`
|
Jeśli jakiś pakiet nie wymieniony w tym dokumencie wymaga przebudowy po zmianie
CHOST, należy o tym poinformować autora tego dokumentu.
Częste problemy
Po aktualizacji gcc z wersji 3.3 do 4.1 z równoczesną zmianą zmiennej CHOST (nie
jest to wskazane), kilku użytkowników zgłosiło, że pakiety takie jak groff i
courier wymagają rekompilacji:
Listing 2.15: Błąd |
error while loading shared libraries: libstdc++.so.5: cannot open shared object
file: No such file or directory
|
Dzieje się tak, ponieważ po aktualizacji zmienna CHOST nie pasuje do zmiennej
CTARGET i kompilator wybiera kompilację skrośną (ang. cross-compiling). W
konsekwencji zmienna LDPATH nie zostaje załadowana do ld.so.conf,
powodując ten błąd.
Aby dowiedzieć się, co trzeba zrobić po przejściu na inną wersję gcc, należy
przeczytać tekst o aktualizacji gcc.
W rzadkich przypadkach może to również spowodować popsucie starych wersji
pythona. Może to zostać naprawione poprzez dodanie
/usr/lib/gcc-lib/i386-pc-linux-gnu/3.3.6 (należy odpowiednio
zmienić wartość chost i wersję gcc na używane poprzednio) w
/etc/ld.so.conf, wykonać polecenie ldconfig i dopiero wtedy
emerge libstdc++-v3. Jednak jak widać powinno się unikać tego problemu -
stąd wniosek: nie powinno się zmieniać wartości zmiennej CHOST z jednoczesną
aktualizacją gcc.
Kontakt
Wszelkie komentarze na temat tego tekstu (zarówno pozytywne jak i konstruktywną
krytykę) należy przesyłać na adres Wernfried Haas lub publikować
w tym wątku na
forum. Sporą część tego tekstu napisał vapier, dziękujemy!
Zawartość tego dokumentu jest rozpowszechniana na podstawie licencji Creative Commons -
Attribution / Share Alike.
|