8.30.1. Installasjon av GCC
Hvis du bygger på x86_64, endre standard mappenavn for 64-bit
bibliotekene til «lib»:
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
GCC dokumentasjonen anbefaler å bygge GCC i en dedikert byggemappe:
mkdir -v build
cd build
Forbered GCC for kompilering:
../configure --prefix=/usr \
LD=ld \
--enable-languages=c,c++ \
--enable-default-pie \
--enable-default-ssp \
--enable-host-pie \
--disable-multilib \
--disable-bootstrap \
--disable-fixincludes \
--with-system-zlib
Vi aktiverer bare C og C++ her for å spare byggetid, ettersom ingen
pakker i LFS og BLFS krever GCC for å kompilere andre språk. Legg
til cobol
for Cobol (merk at det vil
føre til at GCC mislykkes å bygge på et 32-bit LFS system),
fortran
for Fortran, go
for Go, objc
for
Objective C, obj-c++
for Objective
C++, og/eller m2
for Modula 2 inn i
verdien av --enable-languages
alternativet hvis
du vil kompilere programmer på ett eller flere av disse språkene
med GCC. GCC støtter også Ada og D, men koden for å støtte Ada
eller D er skrevet i Ada eller D selv, så støtten kan bare bygges
med en eksisterende Ada eller D kompilatorinstallasjon, og vi kan
ikke aktivere støtten her.
Betydningen av de nye konfigureringsparametrene:
-
LD=ld
-
Denne parameteren gjør at konfigureringsskriptet bruker ld
installert av binutils bygget tidligere i dette kapittelet, i
stedet for den kryssbygde versjonen som ellers ville blitt
brukt.
-
--disable-bootstrap
-
Som standard vil byggesystemet til GCC bootstrappe det i tre
trinn med mindre det er bygget som en krysskompilator eller
det blir krysskompilert. Bootstrap prosessen er nødvendig for
robusthet, spesielt når du oppgraderer GCC til en ny versjon.
I LFS bruker vi en annen metode for å bootstrappe GCC (som vi
introduserte i Verktøykjedens tekniske
merknader), så her trenger vi ikke oppstartsprosessen som
byggesystemet tilbyr, og vi deaktiverer den for å redusere
byggetiden betydelig. Fjern dette alternativet når du
oppgraderer GCC på et komplett LFS system (i stedet for å
bygge LFS).
-
--disable-fixincludes
-
Som standard, under installasjonen av GCC noen
systemdeklarasjoner vil være «låst» for bruk med
GCC. Dette er ikke nødvendig for et moderne Linuxsystem, og
potensielt skadelig hvis en pakke installeres på nytt etter
installasjon av GCC. Denne bryteren hindrer GCC fra å
«låse»
deklarasjonene.
-
--with-system-zlib
-
Denne bryteren forteller GCC å koble til den
systeminstallerte kopien av zlib biblioteket, i stedet for
sin egen interne kopi.
Notat
PIE (position independent executable) er en teknikk for å
produsere binære programmer som kan lastes hvor som helst i
minnet. Uten PIE, sikkerhetsfunksjonen kalt ASLR (Address Space
Layout Randomization) kan legges til for de delte bibliotekene,
men ikke de kjørbare filen. Aktivering av PIE tillater ASLR for
de kjørbare filene i tillegg til de delte bibliotekene, og
reduserer noen angrep basert på faste adresser til sensitiv kode
eller data i de kjørbare filene.
SSP (Stack Smashing Protection) er en teknikk for å sikre at
parameterstabelen ikke er ødelagt. Stabelkorrupsjon kan for
eksempel endre returadressen til en subrutine, som ville tillate
overføring av kontroll til en eller annen farlig kode (som
eksisterer i programmet eller delte biblioteker, eller injisert
av en angriper på en eller annen måte) i stedet for den
originale.
Kompiler pakken:
make
Viktig
I denne delen vurderes testpakken for GCC å være viktig, men det
tar lang tid. Førstegangsbyggere oppfordres til ikke å hoppe over
dette. Tiden for å kjøre testene kan bli redusert betydelig ved å
legge til -jx til make -k
check kommandoen nedenfor hvor x er antall
kjerner på systemet ditt.
GCC kan trenge mer stabelplass for å kompilere noen ekstremt
komplekse kodemønstre. Som en forholdsregel for vertsdistros med en
liten stabelbegrensing, angi eksplisitt stabelstørrelsen hard
grense til uendelig. På de fleste vertsdistroer (og det endelige
LFS systemet) er den harde grensen uendelig som standard, men det
er ingen skade ved å angi det eksplisitt. Det er ikke nødvendig å
endre myk grense for stabelstørrelsen fordi GCC vil sette den
automatisk til en passende verdi, så lenge verdien ikke overskrider
den harde grensen:
ulimit -s -H unlimited
Fjern nå flere kjente testfeil:
sed -e '/cpython/d' -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp
Test resultatene som en ikke-privilegert bruker, men ikke stopp ved
feil:
chown -R tester .
su tester -c "PATH=$PATH make -k check"
For å trekke ut et sammendrag av resultatene for testpakken, kjør:
../contrib/test_summary
For å filtrere ut bare sammendragene, kanaliser utdataene gjennom
grep -A7 Summ
.
Resultatene kan sammenlignes med de som ligger på https://www.linuxfromscratch.org/lfs/build-logs/development/
og https://gcc.gnu.org/ml/gcc-testresults/.
Testene knyttet til pr90579.c
er
kjent for å mislykkes.
Noen få uventede feil kan ikke alltid unngås. I noen tilfeller
testfeil avhenger av den spesifikke maskinvaren til systemet. Med
mindre testresultatene er svært forskjellige fra de på URLen
ovenfor, er det trygt å fortsette.
Installer pakken:
make install
GCC byggemappen eies av tester
nå
og eierskapet til den installerte deklarasjonsmappen (og dens
innhold) vil være feil. Endre eierskapet til root
bruker og gruppe:
chown -v -R root:root \
/usr/lib/gcc/$(gcc -dumpmachine)/15.2.0/include{,-fixed}
Lag en symbolkobling som kreves av FHS
av "historiske" grunner.
ln -svr /usr/bin/cpp /usr/lib
Mange pakker bruker navnet cc for å kalle C kompilatoren. Vi
har allerede opprettet cc som en symbolsk lenke i
gcc-pass2, opprett manualsiden til
den som en symbolkobling også
ln -sv gcc.1 /usr/share/man/man1/cc.1
Legg til en kompatibilitetssymbolkobling for å aktivere
byggeprogrammer med optimalisering av koblingstid (LTO (Link Time
Optimization)):
ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/15.2.0/liblto_plugin.so \
/usr/lib/bfd-plugins/
Nå som vår endelige verktøykjede er på plass, er det viktig å sikre
at kompilering og kobling vil fungere som forventet. Dette gjør vi
ved å utføre noen sunnhetssjekker:
echo 'int main(){}' | cc -x c - -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
Det bør ikke være noen feil, og utdataen av den siste kommandoen
vil være (som gir rom for plattformspesifikke forskjeller i det
dynamiske linkernavnet):
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
Sørg nå for at vi er konfigurert til å bruke de riktige
startfilene:
grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
Utdata fra den siste kommandoen bør være:
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/../../../../lib/crtn.o succeeded
Avhengig av maskinarkitekturen din, kan ovenstående avvike litt.
Forskjellen vil være navnet på mappen etter /usr/lib/gcc
. Det viktige å se etter her er det
at gcc har funnet
alle tre crt*.o
filene under
/usr/lib
mappen.
Bekreft at kompilatoren søker etter riktige deklarasjonsfiler:
grep -B4 '^ /usr/include' dummy.log
Denne kommandoen bør returnere følgende utdata:
#include <...> search starts here:
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/include
/usr/local/include
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/include-fixed
/usr/include
Igjen, mappen oppkalt etter måltripletten kan være annerledes enn
de ovennevnte, avhengig av systemarkitekturen.
Deretter bekrefter du at den nye linkeren brukes med de riktige
søkebanene:
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
Referanser til stier som har komponenter med '-linux-gnu' bør
ignoreres, men ellers bør utdata fra den siste kommandoen være:
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
Et 32-bits system kan se noen forskjellige mapper. For eksempel her
er utdata fra en i686-maskin:
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
Neste forsikre deg om at vi bruker riktig libc:
grep "/lib.*/libc.so.6 " dummy.log
Utdata fra den siste kommandoen bør være:
attempt to open /usr/lib/libc.so.6 succeeded
Sørg for at GCC bruker riktig dynamisk linker:
grep found dummy.log
Utdataen fra den siste kommandoen bør være (som gir rom for
plattformspesifikke forskjeller i dynamisk linkernavn):
found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2
Hvis utdataen ikke vises som vist ovenfor eller ikke mottas i det
hele tatt, så er det noe alvorlig galt. Undersøk og spor trinn for
trinn for å finne ut hvor problemet er og rette det. Eventuelle
problemer må løses før du fortsetter med prosessen.
Når alt fungerer som det skal, rydd opp i testfilene:
rm -v a.out dummy.log
Til slutt flytter du en feilplassert fil:
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib