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
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.
Następnie koniecznie należy przekompilować pakiet libtool i wykonać polecenie /usr/share/gcc-data/$CHOST/<gcc-version>/fix_libtool_files.sh. Należy upewnić się, że używa się odpowiedniej wersji gcc. Zmienną $CHOST zastępujemy nową wartością CHOST, a <gcc-version> nową wersją gcc. W przykładzie tym przyjęto i686 jako wartość CHOST.
Listing 2.11: Zapewnienie poprawności biblioteki |
# emerge -av1 libtool # /usr/share/gcc-data/i686-pc-linux-gnu/4.1.1/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.
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.
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!
Materiał udostępniany na podstawie licencji Creative Commons - Attribution / Share Alike.