GCC frissítése
A GCC frissítéseket általában zökkenőmentesen kell kezelni a Portage és a szokásos Gentoo eszközök segítségével, tekintse meg a következő szakaszt . Ha valaha is olyan összetettebb frissítésekre kerül sor, amelyek felhasználói beavatkozást igényelnek, akkor ezekhez egy megfelelő hírelem kell, amelyet el kell olvasni és követni kell.
A GCC visszaminősítése (downgrading) nem kívánt mellékhatásokkal járhat. A gyakran jelentett problémákért tekintse meg a Hibaelhárítás szakaszt .
Gyors útmutató a GCC frissítésekhez
A legtöbb GCC frissítés olyan egyszerű, mint a fordító verziójának módosítása (ebben az esetben 10.3.0-ról 11.2.0-ra) és a dev-build/libtool újbóli lefordítása a forráskódból.
root
#
emerge --ask --oneshot sys-devel/gcc
root
#
gcc-config --list-profiles
[1] x86_64-pc-linux-gnu-10.3.0 * [2] x86_64-pc-linux-gnu-11.2.0
root
#
gcc-config 2
root
#
source /etc/profile
root
#
emerge --ask --oneshot --usepkg=n dev-build/libtool
Ellenőrizze a jelenlegi verziószámot, majd távolítsa el a régi verziót:
root
#
gcc --version
root
#
emerge --ask --depclean sys-devel/gcc:10.3.0
Élvezze az új forráskódfordítót!
Bővített útmutató a GCC frissítésekhez
A GCC frissítése mindig is misztifikálva volt, az ajánlások pedig széles skálán mozogtak: "A felhasználóknak nem kell semmit tenniük" és "A felhasználóknak kétszer újra kell építeniük a forráskódból az egész rendszert". A bizonytalanságot az ABI inkompatibilitás körüli zavarok okozták, ami manapság már ritkán okoz problémát.
libtool
Azért kell forráskódból újraépíteni a libtoolt a gcc verziók frissítése után, mert ez a fő funkciója: A libtool egy eszközkészlet, amely az adott platformra jellemző kódokat egy általános interfészbe foglalja, lehetővé téve az alkalmazások számára, hogy megosztott könyvtárakkal dolgozzanak anélkül, hogy a platform-specifikus szempontokat figyelembe kellene venniük. Ahhoz, hogy megfelelően ellássa feladatát, a libtool script különböző könyvtári helyeket használ, amelyekben be közvetlenül bele van kódolva a gcc verzióinformáció.
Tekintse meg a bug #88596 hibabejegyzést.
ABI változások
GCC 5.1 előtt
Az ABI ( Alkalmazás bináris interfész ) olyan konvenciók összessége, amelyet minden olyan eszköz alkalmaz, amely programok bináris ábrázolásával foglalkozik, beleértve a forráskódfordítókat, assembler programokat, linker programokat és a nyelvi futtatási környezeteket (forrás: GCC bináris kompatibilitás ). Amikor az ABI-t módosítják a bináris alkalmazások és könyvtárak számára, akkor fennáll a veszélye a linkelési hibáknak vagy a nem megfelelően működő programoknak, hacsak nem történik meg az összes C++ kódot használó könyvtár újbóli lefordítása a forráskódból.
Amikor a GCC 4.1 vagy a GCC 5.1 verzióra történik frissítés, valószínűleg ABI problémákba lehet ütközni. Ennek elkerülése érdekében a revdep-rebuild parancsot kell futtatni a libstdc++.so.5 könyvtár ellenőrzésére, ha a GCC 3-ról GCC 4.1-re történik az áttérés, vagy a libstdc++.so.6 könyvtár esetén, ha a GCC 4-ről GCC 5.1-re történik a váltás.
root
#
revdep-rebuild --library 'libstdc++.so.6' -- --exclude gcc
Ez csak a GCC 4.1/5.1 verzióig szükséges, mert ettől a verziótól kezdve a GCC előre kompatibilis ABI-t használ, amely megszünteti az alkalmazások és könyvtárak újrafordításának szükségességét. Természetesen soha nem lehet korlátlan garanciát vállalni, de ha ismét inkompatibilitás lép fel, akkor azt itt dokumentálni fogjuk és kiadunk egy hírelemet. Ebben az esetben valószínűleg növelve lesz a libstdc++.so könyvtár verziószáma.
Különleges eset: C++11 (és C++14)
Bár a GCC (pontosabban a libstdc++) nagy erőfeszítéseket tesz az ABI stabilitásának garantálására, ez a garancia nem terjed ki a C++ minden részére a libstdc++ könyvtáron belül. Formálisan a 3.4-es verziótól kezdve a GCC/libstdc++ csak a C++98/C++03 ABI stabilitását biztosítja, és ennél többet nem. Ez különösen fontos a C++11-et használó szoftvercsomagok esetében. A GCC csak az 5.1-es verziótól kezdve garantálja a C++11 ABI stabilitását. Ez azt jelenti, hogy még a GCC kisebb verzióváltásai (például 4.7.3 → 4.7.4) is ABI törést okozhatnak a C++11 kódból készült binárisok számára.
További információkért és néhány példáért tekintse meg a következő linkeket:
- bug #513386
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61758
- https://blogs.gentoo.org/blueness/2015/03/10/the-c11-abi-incompatibility-problem-in-gentoo/
- https://stackoverflow.com/questions/16190269/g-always-backward-compatible-with-older-static-libraries/16196475#16196475
GCC visszaminősítése (downgrade)
A fent említett okok miatt, ha a GCC visszaminősítésére (downgrade) sor kerül, vagy egy régebbi helyet választanak a
gcc-config
segítségével, akkor szükséges futtatni a
revdep-rebuild
parancsot, hogy felismerje azokat a
libstdc++
fogyasztókat, amelyek újabb szimbólumokat igényelnek:
root
#
revdep-rebuild --library 'libstdc++.so.6' -- --exclude gcc
Melyik szoftvercsomagokat kell újraépíteni?
Az alábbi táblázat felsorolja azokat a szoftvercsomagokat, amelyeket – ha telepítve vannak –, akkor újra kell építeni a forráskódból, valamint ennek okát is felsorolja.
| Szoftvercsomag | Forráskódból történő újjáépítésre van szükség mert ... |
|---|---|
| dev-build/libtool | A libtool közvetlen belekódolt (hard coded) elérési utakat tartalmaz a GCC belső könyvtáraihoz. Részletek a bug #88596 bejegyzésben. |
root
#
emerge --ask --oneshot --usepkg=n --verbose dev-build/libtool
Egyes szoftvercsomag-gyűjteményeket ugyanazzal a forráskódfordítóval kell felépíteni (például a különféle qt-* szoftvercsomagokat). Az ilyen szoftvercsomagokat általában a szoftvercsomag-karbantartók egyszerre frissítik, így mindig ugyanazzal a GCC verzióval lesznek a forráskódból lefordítva binárisra. A szelektív újratelepítés ezen szoftvercsomagok esetében problémás lehet.
Mindent szoftvercsomagot újból lefordítani a forráskódból
Ez a művelet nem szükséges, de itt le van írva annak érdekében, hogy az érdeklődők alaposan végezhessék el, ha szeretnék.
Vannak, akik esküsznek arra, hogy minden egyes szoftvercsomagot újból le kell fordítani a forráskódból az operációs rendszerükön, amikor egy új GCC verzió válik elérhetővé. Természetesen ennek nincs értelme, mivel számos alkalmazás nem használja a GCC-t a forráskódnak a fordításához és a telepítéshez, így ezek egyáltalán nem lennének érintettek az ilyen változások által.
Ez azonban nem jelenti azt, hogy teljesen tévednének: Az újabb GCC verziók gyakran jobb támogatást nyújtanak a processzorok utasításkészletéhez, ami pozitívan befolyásolhatja az egyes alkalmazásoknak a teljesítményét.
Az ilyen "ártalmatlan" előnyökön túl bizonyos esetekben elengedhetetlen lehet mindent az alapoktól újból lefordítani binárisra annak érdekében, hogy megoldjunk olyan problémákat, amelyeknek nincs egyértelmű oka.
Egyes szoftverproblémák eleve nehezen diagnosztizálhatók, és mégis megoldhatók lehetnek egyszerűen az egyik vagy több megfelelő szoftvercsomag újbóli lefordításával. Ha egy ilyen probléma a GCC frissítését követően jelentkezett, és továbbra is fennáll a fent ismertetett revdep-rebuild megközelítés alkalmazása után (valamint az egyéb egyértelműen releváns szoftvercsomagok újbóli lefordítása után), akkor a teljes rendszernek a forráskódból történő lefordítása lehet a megoldás.
A "legbiztonságosabb", de egyben leglassabb módja ennek a
--emptytree
(
-e
) opció használata az emerge segédprogramban a
rendszerkészlet
és utána a
world készlet
újbóli lefordítása:
root
#
emerge --ask --emptytree --usepkg=n @system
root
#
emerge --ask --emptytree --usepkg=n @world
Próbálja ki ezt a megközelítést, mielőtt olyan hibákat jelentene, amelyeket esetleg a GCC frissítése okozott.
A fenti parancsok miatt az operációs rendszerben lévő szoftvercsomagok kétszer újból lefordítódnak, ami szükséges ahhoz, hogy teljesen biztos lehessen abban, hogy minden szoftvercsomag ugyanabban a feltételezett "problémamentes" környezetben jőjjön létre. Az ezek után fennmaradó problémák vagy "valódi hibák", amelyeket jelenteni kell, vagy a rossz rendszerbeállításnak a következményei.
Hibaelhárítás
Boost újraépítése
Ha dev-libs/boost szoftvercsomag forráskódja újbóli lefordításra szorul, akkor a következő hibaüzenetet kapja:
root
#
emerge ...
checking for the Boost _____ library... no configure: error: cannot find the flags to link with Boost _____
Újból lefordítható a forráskódból binárisra a következő módon:
root
#
emerge --ask --oneshot --usepkg=n --verbose dev-libs/boost
libstdc++.so.6: verzió `GLIBCXX_3.4.15' nem található
Frissítések során előfordulhat egy ehhez hasonló hiba:
cmake_bootstrap_28021_test: /usr/lib/gcc/i486-pc-linux-gnu/4.1.2/libstdc++.so.6:
version `GLIBCXX_3.4.11' not found
Ez azt jelenti, hogy egy szoftvercsomag forráskódból történő lefordítása egy régebbi GCC verzióval történik, mint amellyel néhány szoftverfüggőségi könyvtár elkészült. A C++ ABI előre kompatibilis, de csak azt biztosítja, hogy magasabb (vagy azonos) GCC verziókat lehessen használni az alkalmazások forráskódból történő létrehozásához és függvénykönyvtárak összekapcsolásához (összehasonlítva azzal a GCC verzióval, amellyel ezek a könyvtárak készültek).
Az összes libstdc++ függvénykönyvtártól függő szoftvercsomag újraépítéséhez tekintse meg a fentebb található revdep-rebuild instructions útmutatót.
undefined reference to `__cxa_call_terminate@CXXABI_1.3.15'
Ez általában annak az eredménye, hogy egy szoftvercsomagot olyan szoftverfüggőségekkel fordítottak le binárisra, amelyek egy újabb GCC verzióval készültek, mint a jelenleg kiválasztott verzió. Egy példakimenet lehet:
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib64/libgtest.so: undefined reference to `__cxa_call_terminate@CXXABI_1.3.15'
Ez azt jelenti, hogy a települő szoftvercsomag például a GCC 13 verzióval épül fel a forráskódból, míg a
libgtest.so
-t biztosító szoftvercsomag egy újabb GCC verzióval. Ebben az esetben a 14-es verzióval készült.
Ha ez történik, akkor először, amennyiben nem szándékosan csökkenti a GCC verzióját, győződjön meg róla, hogy a legújabb eszközkészlet-verziókat választja.
root
#
binutils-config latest && gcc-config latest && . /etc/profile
A probléma megoldása meglehetősen egyszerű, de nehéz lehet kideríteni, ha a fájlt biztosító szoftvercsomag ismeretlen. A Portage szoftvercsomag-kezelő támogatja a fájlútvonalak közvetlen telepítését, így a emerge -1 /path/to/file.so futtatása érzékelheti a fájlt.
A példában az emerging segítségével meg van próbálva a /usr/lib64/libgtest.so fordítása és telepítése.
root
#
emerge -1a /usr/lib64/libgtest.so
Calculating dependencies - !!! '/usr/lib/libgtest.so' is not claimed by any package. ... done!
Sajnos a szükséges fájl nem lett azonosítva, de létezik a Pfl segédprogram a szoftvercsomagok által telepített fájlok keresésére. A e-file használatával megtalálható az a szoftvercsomag, amely telepíti a szükséges fájlt.
user
$
e-file libgtest.so
...
[I] dev-cpp/gtest
Seen Versions: 1.13.0 1.14.0
Portage Versions: 1.13.0 1.14.0 9999
Installed Versions: 1.14.0(Fri Nov 24 04:35:00 2023)
Homepage: https://github.com/google/googletest
Description: Google C++ Testing Framework
Matched Files: /usr/lib/libgtest.so; /usr/lib64/libgtest.so
...
Ebben az esetben a dev-cpp/gtest szoftvercsomag okozza a forráskód fordítási problémát. Fordítsa le újból a forráskódból és telepítse azt a következő parancs kiadásával:
root
#
emerge --ask --oneshot dev-cpp/gtest
Ez a megoldás valószínűleg kijavítja a problémát, és lehetővé teszi az eredeti szoftvercsomag telepítésének a folytatását.
Nagyobb szoftvercsomagok esetén valószínűleg többször is szembe kell nézni ezzel a problémával, miközben egy alacsonyabb verziójú GCC fordítóprogrammal történik az újbóli lefordítás. Folytassa a fentebb ismertetett lépéseket, hogy végül sikeresen újra lefordítsa a szoftvercsomagot a GCC 13 verzióval.
További olvasnivaló a témában
- Upgrade GCC up to 4.1 - Az előző verziója ennek a dokumentumnak.
- Frissítés gcc-4.x-ről gcc-5.x-re.
- Project:Toolchain/sys-devel/gcc#Snapshots - Gentoo eszközkészlet karbantartási jegyzetei
- A Fedora 'Changes/GCC6' Wiki oldala
Külső források
- https://gcc.gnu.org/onlinedocs/gcc.pdf - A GNU Compiler Collection PDF használata.
- https://gcc.gnu.org/onlinedocs/gccint.pdf - A GNU Compiler Collection belső működése PDF.