Aktualizacja GCC w Gentoo

Wernfried Haas  Autor
Jan Kundrát  Autor
Mark Loeser  Redaktor
Mark Loeser  Redaktor
Joshua Saddler  Redaktor
Artur Czepiel  Tłumaczenie

Zaktualizowano 19 lipca 2008

1.  Wstęp

Uaktualnienie GCC

Dlaczego należy uaktualniać GCC? Kompilator jest podobny do innych pakietów zainstalowanych w systemie, jest tylko trochę ważniejszy od reszty. Powinniśmy zatem aktualizować GCC jeżeli tylko pojawi się nowsza wersja, która naprawia część błędów poprzedniej lub posiada nowe, ważne dla nas funkcje. Jeżeli jednak mimo wszystko chcemy mieć stare GCC możemy odkładać uaktualnienie dopóki ta wersja GCC będzie w pełni wspierana przez Gentoo.

Jeżeli chcemy zainstalować nowszą wersję GCC, nasz system nie zacznie jej używać dopóki go odpowiednio nie skonfigurujemy. Zmiana nie może zostać przeprowadzona automatycznie i bez udziału użytkownika, ponieważ wymaga od niego podjęcia dodatkowych czynności. Jeżeli zdecydujemy jednak, aby nie dokonywać zmiany, Portage będzie dalej pracowało ze starszą wersją kompilatora, dopóki nie zmienimy jej na nowszą lub dopóki nie usuniemy z systemu starszej wersji GCC.

Ten poradnik opisuje najważniejsze kroki potrzebne do przygotowania bezproblemowej aktualizacji kompilatora w Gentoo. Specjalna część jest dedykowana aktualizacji GCC 3.3 do GCC 3.4 oraz problemom związanym z libstdc++. Druga specjalna część skierowana jest do użytkowników, którzy po raz pierwszy instalują Gentoo ze stage3, gdy wydano w międzyczasie nową dużą wersję GCC.

Ostrzeżenie: Aktualizacja GCC-3.4 (lub 3.3) do GCC-4.1 i nowszych wymaga wykonania serii specyficznych kroków, gdyż ich ABI różnią się między sobą.

2.  Ogólne wskazówki dotyczące aktualizacji

Wstęp

Ważne: Jeżeli jest to zmiana z GCC-3.3 na GCC-3.4, szczegółowy opis znajduje się pod tym adresem.

Ważne: Informacje na temat aktualizacji GCC tuż po świeżej instalacji Gentoo znajdują się w osobnej sekcji.

Generalnie mówiąc, uaktualnienia w zakresie jednej wersji, poprawiające tylko drobne błędy (np. z 3.3.5 do 3.3.6) powinny być bezpieczne. Zwykle wystarcza wtedy instalacja nowej wersji i przekonfigurowanie systemu tak, aby jej używał oraz przebudowanie jedynego pakietu, który w takich wypadkach przebudowania wymaga, libtool. Niektóre aktualizacje GCC łamią kompatybilność skompilowanych programów. W takich przypadkach może być wymagana przebudowa także innych pakietów, czasem całego toolchaina, a w ekstremalnych przypadkach nawet całego systemu.

Kiedy mówiliśmy o potrzebie zmiany kompilatora na nowszą wersję, wspominaliśmy, że nie odbywa się to automatycznie. Wyjątkiem są tu uaktualnienia w zakresie tej samej wersji (np. z 3.3.5 do 3.3.6) - w takim przypadku nie używa się kilku slotów z wersjami, ponieważ GCC jest automatycznie przestawiane na nowszą wersję. Instalowanie w takim wypadku nowego GCC na inny slot nie miało sensu, gdyż niewielu użytkowników tego potrzebowało.

Listing 2.1: Aktualizacja GCC

# emerge -uav gcc

(Należy zmienić "i686-pc-linux-gnu-4.1.1" na odpowiednią wersję GCC oraz ustawienie zmiennej CHOST)
# gcc-config i686-pc-linux-gnu-4.1.1
# env-update && source /etc/profile

(Należy zamienić wartość $CHOST na używaną w systemie, ustawienie znajduje się w pliku /etc/make.conf)
(Należy zamienić <gcc-version> używaną (zaktualizowaną) wersją GCC)
# /usr/share/gcc-data/$CHOST/<gcc-version>/fix_libtool_files.sh 3.4.6

(Przebudowanie pakietu libtool)
# emerge --oneshot -av libtool

Aby być w zupełności pewnym, że system jest w pełni zdrowy, należy przebudować podstawowe składniki systemu czyli tzw. toolchain oraz resztę pakietów z grup system i world. W ten sposób zrobimy użytek z naszego nowego kompilatora.

Listing 2.2: Przekompilowanie systemu

# emerge -eav system
# emerge -eav world

Teraz możemy bezpiecznie usunąć stare GCC z systemu. (Zastępujemy =sys-devel/gcc-3.4* odpowiednią wersją GCC)

Listing 2.3: Usuwanie starszej wersji GCC

# emerge -aC =sys-devel/gcc-3.4*

Ważne: GCC 4.1 i nowsze jest w stanie skompilować tylko jądra powyżej wersji 2.4.34. Jeśli chce się zatem korzystać ze starszych jąder, nie należy usuwać starego kompilatora.

Ważne: Jeżeli robisz aktualizację z gcc w wersji 3.3 powinieneś wykonać emerge --oneshot sys-libs/libstdc++-v3 aby zapewnić kompatybilność ze starszymi aplikacjami binarnymi C++.

3.  Aktualizacja z GCC-3.3 do 3.4

Wstęp

Aktualizacja GCC 3.3 do wersji 3.4 jest trochę bardziej skomplikowana, ponieważ mogą wystąpić pewne problemy z biblioteką libstdc++.

Wybór metody aktualizacji

Ważne: Jeżeli aktualizacja odbywa się z gcc 3.4 do 4.1, należy postępować według ogólnych wskazówek dotyczących aktualizacji.

Ważne: Jeśli aktualizacja odbywa się na komputerze SPARC, potrzebne będzie całkowite przebudowanie systemu w związku z pewnymi wewnętrznymi zmianami ABI w sposobie w jaki GCC przekazuje parametry.

Jeżeli aktualizacja odbywa się z gcc 3.3 do 3.4, to wtedy mamy dwie możliwości aktualizacji naszego systemu. Pierwsza metoda jest szybsza i wymaga użycia programu revdep-rebuild wchodzącego w skład pakietu gentoolkit, podczas gdy druga metoda przebudowuje wszystkie pakiety naszego systemu. Wybór metody pozostawiamy użytkownikowi. W większości przypadków wystarcza pierwsza metoda.

Jeżeli aktualizacja odbywa się z gcc 3.3 do 4.1, to nie należy używać metody opartej na revdep-rebuild, ale wykonać kompletną przebudowę systemu.

Użycie revdep-rebuild

Ta metoda wymaga zainstalowania pakietu gentoolkit. Zainstalujemy najnowsze GCC oraz skonfigurujemy system tak, aby go używał. Przebudujemy również pakiet libtool, aby upewnić się, że toolchain będzie w dobrej formie.

Listing 3.1: Instalacja gentoolkit oraz aktualizacja GCC

# emerge -an gentoolkit
# emerge -uav gcc
(Należy zastąpić i686-pc-linux-gnu-3.4.5 odpowiednią wersją GCC i nazwą CHOST)
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(Przebudowanie pakietu libtool)
# emerge --oneshot -av libtool

Najpierw sprawdzimy, które pakiety chce przebudować revdep-rebuild, później każemy mu to zrobić. Może to zająć trochę czasu.

Listing 3.2: Użycie revdep-rebuild

# revdep-rebuild --library libstdc++.so.5 -- -p -v
# revdep-rebuild --library libstdc++.so.5

Uwaga: Mogą pojawić się problemy z nieistniejącymi wersjami pakietów, ponieważ mogły się one przedawnić lub zostać zamaskowane. W takim przypadku może zajść potrzeba uruchomienia revdep-rebuild z opcją --package-names. Sprawia ona, że revdep-rebuild instaluje pakiety w najnowszej wersji, nieważne jaka wersja jest obecnie zainstalowana w systemie.

Aby zadbać o kompatybilność już skompilowanych aplikacji napisanych w C++ oraz wszelkich pakietów jakie revdep-rebuild mógłby opuścić, sys-libs/libstdc++-v3 musi zostać przebudowane przed odinstalowaniem GCC 3.3 z systemu.

Listing 3.3: Instalacja libstdc++-v3 oraz oczyszczanie systemu

# emerge --oneshot sys-libs/libstdc++-v3
# emerge -aC =sys-devel/gcc-3.3*

Użycie emerge -e

Ta metoda zajmuje znacznie więcej czasu, zakłada bowiem przekompilowanie całego systemu. Najpierw uaktualnimy GCC i skonfigurujemy system tak, aby z niego korzystał.

Listing 3.4: Aktualizacja GCC

# emerge -uav gcc
(Należy zastąpić i686-pc-linux-gnu-3.4.5 odpowiednią wersją GCC i nazwą CHOST)
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(Należy zamienić wartość $CHOST na używaną w systemie, ustawienie znajduje się w pliku /etc/make.conf)
(Należy zamienić <gcc-version> używaną (zaktualizowaną) wersją GCC)
#fix_libtool_files.sh 3.3.6

(Przebudowanie pakietu libtool)
# emerge --oneshot -av libtool

sys-libs/libstdc++-v3 musi zostać przebudowane przed odinstalowaniem GCC 3.3 z systemu, co zapewni kompatybilność już skompilowanych aplikacji napisanych w C++.

Listing 3.5: Instalacja libstdc++-v3

# emerge --oneshot sys-libs/libstdc++-v3

Najpierw przekompilujemy pakiety z grupy system, a następnie pakiety z grupy world. Może to zająć trochę czasu, zależnie od ilości zainstalowanych pakietów, Przekompilowane zostaną podstawowe składniki systemu (jak np. binutils, glibc czyli tak zwany toolchain) oraz podstawowe pliki systemowe. Następnie, wykorzystując nowy toolchain, zostanie przekompilowana reszta plików, wliczając w to sam toolchain.

Listing 3.6: Przekompilowanie grup system i world

# emerge -e system
# emerge -e world

W tym momencie możemy bezpiecznie usunąć stare GCC z systemu.

Listing 3.7: Oczyszczanie systemu

# emerge -aC =sys-devel/gcc-3.3*

4.  Aktualizacja GCC tuż po pierwszej instalacji

Wprowadzenie

Aktualizacja GCC po instalacji systemu za pomocą archiwum stage3 to prosta sprawa. Użytkownicy, którzy dopiero co zainstalowali system zwykle nie mają zbyt wielu pakietów zlinkowanych ze starą wersją GCC. Poniższy przykład dotyczy aktualizacji z GCC 3.3 do GCC 3.4. Niektóre polecenia mogą być inne w przypadku, gdy aktualizuje się pomiędzy innymi niż przykładowe wersjami GCC. Na przykład nazwy bibliotek używane poniżej dla revdep-rebuild są specyficzne dla GCC 3.3, podobnie jak potrzeba instalowania libstdc++-v3.

Jeśli użytkownik nie dokona do tego momentu żadnych zmian w swoim systemie, aktualizacja GCC nie będzie stanowiła dużego problemu. Podobnie jak przy zwykłej aktualizacji można wybrać tu jedną ze ścieżek, z tym że tutaj aktualizacje nie będzie tak problematyczna. Pierwsza metoda jest szybsza gdyż wykorzystuje narzędzie revdep-rebuild z pakietu gentoolkit, który przebudowuje tylko te pakiety, które są zlinkowane ze starymi bibliotekami. Druga metoda to przebudowanie całego systemu za pomocą nowego GCC. Cały proces zajmuje znacznie więcej czasu. Taka przebudowa zwykle nie jest konieczna, a opisujemy ją tutaj tylko po to, aby opis był kompletny.

Pierwsze kroki są takie same dla obu metod.

Listing 4.1: Aktualizacja GCC

# emerge -uav gcc
(Należy zastąpić "i686-pc-linux-gnu-3.4.5" odpowiednią wersją GCC i nazwą CHOST)
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(Ponowna kompilacja libtool)
# emerge --oneshot -av libtool

Aby zapewnić kompatybilność ze starszymi programami pisanymi w C++, należy zainstalować sys-libs/libstdc++-v3.

Listing 4.2: Instalowanie libstdc++-v3

# emerge --oneshot sys-libs/libstdc++-v3

Użycie revdep-rebuild

Ta metoda wymaga zainstalowania pakietu gentoolkit. Następnie uruchomimy polecenie revdep-rebuild i przeskanujemy zainstalowane pakiety w poszukiwaniu tych, które trzeba będzie przebudować, a następnie je przebudujemy.

Listing 4.3: Instalowanie gentoolkit i uruchamianie revdep-rebuild

# emerge -an gentoolkit
# revdep-rebuild --library libstdc++.so.5 -- -p -v
# revdep-rebuild --library libstdc++.so.5

Uwaga: Mogą pojawić się problemy związane z nieistniejącymi wersjami niektórych pakietów, w związku z tym, że część z nich będzie zamaskowana lub nieaktualna. W takim wypadku należy skorzystać z opcji --package-names przy uruchamianiu revdep-rebuild. Spowoduje to, że pakiety będą przebudowywane na podstawie tylko ich nazwy, a nie nazwy i numeru wersji.

Użycie emerge -e

Druga metoda jest znacznie wolniejsza od pierwszej. Polega na przebudowaniu całego całego systemu. Nie jest to konieczne, ale może być całkiem sensowne gdy jednocześnie zmieni się na przykład ustawienia CFLAGS lub inne zmienne w pliku make.conf.

W związku z tym, że wszystkie te czynności są wykonywane tuż po świeżej instalacji systemu, nie trzeba przebudowywać całej kategorii world, ponieważ jego przebudowa zostanie dokonana przy okazji aktualizacji systemu. Część użytkowników mimo wszystko woli przebudować cały world zamiast tylko systemu, aby upewnić się, że zostaną przebudowane wszystkie pakiety bez wyjątku.

Listing 4.4: Przebudowa systemu

# emerge -e system

Porządkowanie systemu

W tym momencie można już bezpiecznie usunąć stare wersje GCC. W przykładach należy zastąpić wpis YOUR-NEW-GCC-VERSION wersją GCC do której aktualizowano system.

Listing 4.5: Porządkowanie systemu

# emerge -aC "<sys-devel/gcc-YOUR-NEW-GCC-VERSION"

5.  Częste problemy

Przed aktualizacją (nieważne którą metodą) należy wyłączyć distcc (jeśli się go używa). Mieszanie wersji kompilatorów może spowodować problemy z kompilacją. Nie jest to wymagane w przypadku ccache, ponieważ obiekty z ccache zostaną i tak unieważnione.

Moduły jądra systemu (np. app-emulation/qemu-softmmu) przekompilowane przy pomocy GCC 4.1 nie będą działać ze starym kernelem. Przekompilowanie jądra za pomocą GCC 4.1 rozwiązuje ten problem.

Jeśli aktualizacja odbywa się na komputerze SPARC, należy wpisać silo -f po każdej przebudowie systemu.

Najczęstsze problemy

Jeżeli pojawi się błąd: libtool: link: ` /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/libstdc++.la' is not a valid libtool archive, należy uruchomić /usr/share/gcc-data/$CHOST/<gcc-version>/fix_libtool_files.sh 3.3.6 (zastępując 3.3.6 odpowiednią wersją oraz zmieniając $CHOST i <gcc-version> na właściwe dla danego systemu ustawienia CHOST oraz wersję GCC).

Jeżeli pojawi się błąd: /usr/bin/gcc-config: line 632: /etc/env.d/gcc/i686-pc-linux-gnu-3.3.5: No such file or directory należy usunąć /etc/env.d/gcc/config-i686-pc-linux-gnu oraz uruchomić gcc-config jeszcze raz, a następnie wpisać source /etc/profile. Można to robić jednak tylko wtedy jeżeli nie zostały ustawione żadne kompilatory skrośne.

Jeżeli kompilacja jakiegoś pakietu podczas wykonywania emerge -e system lub emerge -e world nie powiedzie się, można wznowić ją poleceniem emerge --resume. Jeżeli za każdym razem kompilacja nie wychodzi, można ominąć pakiet używając emerge --resume --skipfirst. W międzyczasie nie wolno uruchamiać emerge w innym celu. W przeciwnym wypadku nastąpi utrata informacji potrzebnych do wznowienia kompilacji grup system lub world i trzeba będzie zaczynać te kompilacje od początku.

Jeżeli pojawia się błąd: spec failure: unrecognized spec option podczas aktualizacji kompilatora, należy z powrotem zmienić domyślny kompilator, wyzerować opcję GCC_SPECS i ponownie zaktualizować GCC:

Listing 5.1: Odzyskiwanie początkowych ustawień

# gcc-config 1
# source /etc/profile
# unset GCC_SPECS
# emerge -uav gcc