Linux od Podstaw

2008-11-16 , Papiewski Łukasz , Linux / Unix / OS

Projekt Linux Od Podstaw ma na celu stworzenie dystrybucji Linuksa całkowicie od początku (czyt. z dostępnego kodu źródłowego). Opis bazuję na stronie http://linuxfromscratch.org, do której odsyłam w pierwszej kolejności. Znajdują się tam też inne ciekawe projekty jak CLFS, ALFS, BLFS itp.

Nie jest to, jak polskie tłumaczenie angielskiego tytułu Linux From Scratch mogło by sugerować, coś dla początkujących, a wręcz przeciwnie - gratka dla znudzonych wyjadaczy Linuksa.

LFS (może bardziej BLFS) jest kompletną dystrybucją, podobną w pierwszej kolejności do Slackware'a. Co więcej, po udanym postawieniu BLFS-a, można po zainstalowaniu menadżera pakietów Slackeware'a - installpkg, korzystać ze wszystkich opcji z tym związanych (instalowanie, zarządzanie, usuwanie pakietów).

Zarządzanie pakietami jest zagadnieniem dość interesującym (zob. lfs-package-managing), jednak nie do końca tu rozwiązane. Sami deweloperzy informuję, że jest to inny rodzaj zagadnień, nie związany z ideą akurrat tej dystrybucji.

Jaka jest idea? Ciężko określić obiektywnie. Dla mnie pozwoliło to jeszcze lepiej poznać Linuxa oraz znaleźć punkty podobieństwa innych dystrybucji. Dalej, można się przekonać na własnej skórze, jaki wkład jest potrzebny aby utrzymać nowe distro.

Ten artykuł jest streszczeniem zagadnień i w większości przekłada się na to co jest napisane na stronie projektu. Jest to mój umotywowany i udokumentowany, luźny sposób na dokonanie tego niebanalnego wyczynu.

Obecnie korzystam z BLFS i muszę nawet przyznać, że nigdy lepiej nie pracowało mi się z Linuksem. Póki mam wsparcie ze strony BLFS jak skompilować przykładowo Gimp'a, Forefox'a, menadżera okien itp. nie ma żadnych problemów. Największym problemem jednak może być upgrade systemu (czego jeszcze nie czyniłem) - zmiana którejś biblioteki podstawowej lub jądra. Poszczególny update pakietów nie stanowi problemów, dopóki, dopóty rozwiązane są zależności.

Cały proces nie musi polegać na pracochłonnym wklepywaniu, jest raczej powtarzalnym i dający się zautomatyzować. Dzięki skryptom (szukaj ALFS) instalacja może być przeprowadzona przy minimum wkładu własnego, jednak wymagany jest bardzo długi (w porównaniu chociażby instalacją Gentoo) czas na skompilowanie wszystkiego.

Moje skrypty oraz logi można znaleźć w katalogu dl/lfs/scripts

Przygotowania

W fazie przygotowań najważniejsze jest poprawne ustawienie środowiska

Co jakiś czas zmieniają się pakiety i wersje LFS (obecna development to 6.6), a wraz z nimi numeracje paczek oraz możliwe parę flag instalacyjnych.

Na pierwszym stadium zagłębiania się w tajniki świata kodu źródłowego, pobrać należy pakiety, rozpakować, ustawić zmienne i środowisko oraz przystąpić do właściwej fazy kompilowania wszystkiego ze źródeł open-source'owych.

Umożliwi nam to przystąpienie do pierwszej fazy projektu (patrz. rozdz. 5. Constructing a Temporary System).

Narzędzia

Sprawdzić można na wszelki wypadek, czy środowisko developerskie posiada wszystkie narzędzia.


#!/bin/bash
# Simple script to list version numbers of critical development tools
 
bash --version | head -n1 | cut -d" " -f2-4
echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-4
bison --version | head -n1
bzip2 --version 2<1 > /dev/null | head -n1 | cut -d" " -f1,6-
echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1
gcc --version | head -n1
/lib/libc.so.6 | head -n1 | cut -d" " -f1-7
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
make --version | head -n1
patch --version | head -n1
sed --version | head -n1
tar --version | head -n1

Nie każda wersja narzędzi jest w stanie wyprodukować docelową wersję LFS (wymagania na stronie projektu)

Środowisko

Krytyczną rzeczą w pierwszej fazie jest dobrze skonfigurowane środowisko. Jeśli pominiemy cokolwiek błędy mogą ukazać się dopiero pod koniec fazy drugiej, więc przeoczenie takie może owocować totalną stratą czasu.

Wchodzimy w 'czyste' środowisko:

exec env -i HOME=$HOME TERM=$TERM PS1='u:w$ ' /bin/bash -norc

Dalej konfiguracja środowiska. Poniżej można sobie zmienić LFS, LFS_PKG, LFS_SRC, LFS_SYS. Wszystkie zmienne a przede wszystkim niepozorne 'set +h' muszą być obecne na czysto w profilu, najlepiej bez innych dodatków

set +h #no hash
umask  022
export LFS=/mnt/lfs
export LC_ALL=POSIX 
export LFS_TGT=$(uname -m)-lfs-linux-gnu #target architecture
export LFS_VERSION=6.6-rc1 # version
export TOOLS=/tools  #najlepiej ustawić jako tools
export PATH=$TOOLS/bin:/bin:/usr/bin  #reset PATH
 
#additional
export LFS_PKG=$LFS/pkg  #tarballs
export LFS_SRC=$LFS/src  #compilation goes here 
export LFS_SYS=$LFS/sys  tu jest nasz system

Dodawanie nowych ścieżek, katalogów i linków:

ln -s $LFS_SYS $TOOLS #
mkdir -p $LFS
mkdir -p $LFS_PKG
mkdir -p $LFS_SRC
mkdir -p $LFS_SYS
Po wklepaniu wszystkiego najlepiej screen -R lfs aby można było łatwo powielać sesję o tych samych parametrach (zmiennych). Można teraz przystąpić do fazy I.

Opis zmiennych

Polecenia i eksporty nakładają odpowiednie uprawnienia na nowo tworzone pliki (bezpieczeństwo) oraz ustawiają zmienną $PATH na katalog z plikami wykonywalnymi należącymi do systemu.

Zamiast przełącznika -norc można umieścić drugi listing w pliku ~/.bash.rc na chwilę i uruchomić screen'a aby mieć pewność. Można też zapisać jako plik (np. lfs.env) dla programu source

Zmienna LFS wskazuje na katalog główny, znajdujący się wg książki w /mnt/lfs, ale można go ustawić np. jako podkatalogu użytkownika na serwerze

Wymagany jest, zgodnie z dokumentacją LinuxFromScratch, link symboliczny TOOLS wskazujący na nasz katalog z powstającą z 'jajka' dystrybucją ($LFS_SYS). Konta roota używamy do stworzenia właśnie tego linka oraz ewentualnie później do chroot'owania. Reszta zadań tego nie wymaga.

Zmienna TOOLS jest potrzebna aby nazwy po kompilacji narzędzi miały w kodzie taką samą ścieżkę po chroot'owaniu a nie inaczej. Zmienna ta jest niczym innym jak reprezentacją względną roboczego systemu.

Teoretycznie nic nie stoi na przeszkodzie aby miała ścieżkę inną. W drugiej fazie (patrz. rozdz. 6. Installing Basic System Software ) katalogiem głównym będzie $TOOLS i wszystkie narzędzia będą odnosić się do bibliotek w tym katalogu bo ścieżka się nie zmieniła.

W drugiej fazie kompilacja łańcucha zależności rozwiązuje problem statycznych dowiązań w plikach binarnych (znika tools i pozostaje standardowy ROOT - '/').

Pakiety

Pakiety i wszystkie inne dobra dotyczące opisywanego w tym arcie przedsięwzięcia, można znaleźć: opcjonalnie na SVN'ie pod adresem https://svn.papiewski.pl/kody/lfs. lub papiewski.pl/dl/lfs.

Znajdują się tam też (powinny) skrypty samo-wszystko-auto-magicznie-robiące ;) ala ALFS (Automated Linux From Scratch - co spostrzegłem później, ale z czego nie korzystam bo boli)


Dobrym nawykiem jest sprawdzanie sumy kontrolnej po ściągnięciu paczek, kto wie jakie "zło" może czyhać.

cd $LFS_PKG
wget ftp://ftp.lfs-matrix.net/pub/lfs/lfs-packages/lfs-packages-$LFS_VERSION.tar
tar -xvf lfs-packages-$LFS_VERSION.tar
md5sum -c MD5SUMS

Faza I

Zaczynamy od pierwszego rozdziału który będzie polegał na stworzenie linker'ów, kompilatora i bibliotek, które to staną się narzędziami do budowy i tworzenie nowego systemu (bootstrapping). Ważne jest tu prawidłowe oddzielenie się od hosta.

Przed kompilacją każdej nowej paczki zalecam zaznajomić się z plikami README i INSTALL, zawierającymi wiele cennych informacji jak np. szczegółowe informacje, jak poprawnie zainstalować dany pakiet, jakie są zależności, co to jest, może nawet jakąś historię, opis.

To co jest tu ważne to poprawne skompilowanie i zainstalowanie. Przy pierwszych pakietach można też poczytać o paru informacjach. Ogólnie cały proces w fazie pierwszej i drugiej to niekończące się './configure && make && make install

.

Binutils

Pakiet ten jest kolekcją narzędzi do obróbki wykonywalnych plików binarnych. Składa się z takich programów jak asembler, biblioteki do obsługi różnych plików z kodem, przetwarzania rożnych formatów plików wyjściowych oraz linkera.

W tym przypadku na początku generujemy plik Makefile. Używamy od tego pliku wykonywalnego 'configure' i podajemy opcjonalne parametry np. katalog docelowy, kompilator itp.

cd $LFS
 
rm -Rf $LFS_SRC/binutils-build
rm -R $LFS_SRC/binutils-2.17
 
tar  -jxvf $LFS_PKG/binutils-2.17.tar.bz2 -C $LFS_SRC/
cd $LFS_SRC
mkdir binutils-build
cd binutils-build
 
CC="gcc -B /usr/bin"  ../binutils-2.17/configure  
--prefix=$TOOLS  
--disable-nls  
--disable-werror    
 
make
make install

Na procesorze 4 GHz kompilacja binutils zajmuje niecałe 4 min. (patrz. jednostak SBU).

W trakcie instalacji możemy dostać różne podsumowujące informacje. Zazwyczaj gdy instalowane są biblioteki to w przypadku niestandardowych lokacji trzeba ustawić cache bibliotek. Poniższe się w pojawia się nagminnie w pierwszej fazie (bo mamy $TOOLS zmiast /). Nie trzeba się nimi przejmować, ale warto wiedzieć o co chodzi.

Poniżej przykładowa informacja po instalacji 'binutils' mówiąca o wymogu ustawienia odpowiedniej zmiennej środowiskowej.

PATH="$PATH:/sbin" ldconfig -n $TOOLS/lib ---------------------------------------------------------------------- Libraries have been installed in: $TOOLS/lib If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the `LD_RUN_PATH' environment variable during linking - use the `-Wl,--rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to `/etc/ld.so.conf' See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. ----------------------------------------------------------------------

Następnie kompilujemy 'linkera' jeszcze raz komendami make -C ld clean oraz make -C ld LIB_PATH=$TOOLS/lib. Poleceniem ostatnim linkujemy biblioteki z katalogu '$TOOLS/lib', czyli nie macierzyste a nowo powstałe. Kopiujemy do naszego katalogu pod nazwą ld-new, w celu późniejszego wykorzystania. Na razie jest nie przydatny bo nie mamy żadnych bibliotek w $LFS_SYS. W odpowiednim momencie można ale jak pokazują najnowsze instrukcję LFS, ale niekoniecznie trzeba linkera z tej fazy wykorzystać.

Komenda generująca plik 'ld':

make -C ld clean
make -C ld LIB_PATH=$TOOLS/lib
cp -v ld/ld-new $TOOLS/bin

GCC

cd $LFS
tar -xjvf $LFS_PKG/gcc-4.1.2.tar.bz2 -C $LFS_SRC
cd $LFS_SRC
mkdir gcc-build
cd gcc-build
 
../gcc-4.1.2/configure  
--prefix=$TOOLS  
--with-local-prefix=$TOOLS/  
--disable-nls  
--enable-shared  
--enable-languages=c
 
make bootstrap
make install
 
cd $LFS_SYS/bin
ln -vs gcc cc
To co się zainstalowało jest wyszczególnione tutaj.

Linux Headers - pliku nagłówkowe

The Linux kernel needs to expose an Application Programming Interface (API) for the system's C library (Glibc in LFS) to use. This is done by way of sanitizing various C header files that are shipped in the Linux kernel source tarball.

Bez nich nie wykorzystamy bibliotek programistycznych naszego systemu. Chociaż teoretycznie moglibyśmy je wykorzystać, gdyż wszystkie te funkcje są w 'kernelu'. W praktyce przechodzenie w tryb jądra jest kosztowne i lepiej mieć podręczne biblioteki nadzorujące te operacje.

Standardowa procedura: rozpakowujemy, czytamy README? i instalujemy powtarzającą się sekwencję 'configure && make && make install'.

cd $LFS
rm -R $LFS_SRC/linux-2.6.22.5  -R
tar -xvjf $LFS_PKG/linux-2.6.22.5.tar.bz2  -C $LFS_SRC
cd $LFS_SRC/linux-2.6.22.5
make headers_check 
make INSTALL_HDR_PATH=dest headers_install 
cp -rav dest/include/* $TOOLS/include
A oto wszystkie pliki nagłówkowe (i nie tylko) jakie powinny się znaleźć gdzieś w drzewie katalogów 'include'.

GLibC

Czyli kolejna paczka bibliotek wraz z plikami nagłówkowymi, odpowiedzialna za pisanie i odczyt z dysku. Ogólnie kolekcja podstawowych bibliotek C, ale również różne pomocne aplikacje (z ciekawszych rpcgen, obsługa socketów, bibliteki protokołów internetowych, locale, malloc, stdlib, sygnały, kryptografię, ctype, stringi, czas i wiele innych ... ).

cd $LFS
rm -Rf $LFS_SRC/glibc-2.5.1/
tar -xjvf $LFS_PKG/glibc-2.5.1.tar.bz2 -C $LFS_SRC/
mkdir $LFS_SRC/glibc-build
cd $LFS_SRC/glibc-build
 
../glibc-2.5.1/configure 
--prefix=$TOOLS 
--disable-profile 
--enable-add-ons 
--enable-kernel=2.6.0 
--with-binutils=$TOOLS/bin 
--without-gd 
--with-headers=$TOOLS/include 
--without-selinux 
make
make check
mkdir -v $TOOLS/etc
touch $TOOLS/etc/ld.so.conf
make install

Instalacja tworzy rozległą listę (różnorakie strefy czasowe i językowe) obiektów 'glibc'.

Ewentualne problemy

Najczęściej popełnianym błędem jest nie skompilowanie przeciwko naszym wcześniej wyprodukowanym plikom w $TOOLS/bin i $TOOLS/include.

Problemy które mogą wystąpić (na pewno wystąpią w tej wersji) to niekompatybilność gawk i mawk:

mawk: scripts/gen-sorted.awk: line 19: syntax error at or near ] 
mawk: scripts/gen-sorted.awk: line 19: runaway regular expression /, "", subd ... 
make[1]: Leaving directory `/mnt/clfs/sources/glibc-2.4' 
make[1]: Entering directory `/mnt/clfs/sources/glibc-2.4'
Łatwo to można naprawić edytując plik 'scripts/gen-sorted.awk' w katalogu 'glibc' i w linijkach (19,59,65) z podanym błędem przed slashem musimy postawić backslash (zamiana /[^/]+$ na /[^/]+$ ). Przed instalowaniem możemy wykonać sprawdzenie poprawności komendą 'make check', jednak w tej fazie praktycznie zawsze występują jakieś błędy uzależnienia od systemu macierzystego. Np.: c-dir/dlfcn/bug-atexit3-lib.os ../include/unistd.h:4: warning: 'void _exit(int)': visibility attribute ignored because it ../posix/unistd.h:548: warning: conflicts with previous declaration here ../include/unistd.h:7: warning: 'int execl(const char*, const char*, ...)': visibility attribute ignored because it ../posix/unistd.h:527: warning: conflicts with previous declaration here ../include/unistd.h:8: warning: 'int execle(const char*, const char*, ...)': visibility attribute ignored because it ../posix/unistd.h:522: warning: conflicts with previous declaration here ../include/unistd.h:9: warning: 'int execlp(const char*, const char*, ...)': visibility attribute ignored because it ../posix/unistd.h:538: warning: conflicts with previous declaration here ../include/unistd.h:10: warning: 'int execvp(const char*, char* const*)': visibility attribute ignored because it ../posix/unistd.h:532: warning: conflicts with previous declaration here

Pozbędziemy się tego w fazie drugiej, gdzie wszystkie biblioteki narzędzia będą wyłącznie własnością tworzonego systemu.

Toolchain

gcc -dumpspecs | sed 's@^/lib/ld-linux.so.2@$TOOLS&@g' 
  > `dirname $(gcc -print-libgcc-file-name)`/specs
 
GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&
find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' ; &&
rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&
unset GCC_INCLUDEDIR

Linker

W w instrukcji np. LFS 6.1 widniała poniższa sekwencja w tym momencie. Pozwalała on na linkowanie nowych programów użytkowych.

W nowszych instrukcjach (6.6) należy w tym momencie umieścić instalację Binutils w przeciwieństwie do tej wersji gdzie instalujemy go po programach testowych.

Nie zmieniła się podmiana linkera w tym momencie :

mv -v $TOOLS/bin/{ld,ld-old}
mv -v $TOOLS/$(gcc -dumpmachine)/bin/{ld,ld-old}
mv -v $TOOLS/bin/{ld-new,ld}
ln -sv $TOOLS/bin/ld $TOOLS/$(gcc -dumpmachine)/bin/ld

W tym momencie w nowszych wersjach instaluję się tu jeszcz raz GCC, w przeciwieństwie do tej wersji gdzie GCC instalowany jest po programach testowych (TCL,Expect),

Podsumowanie Bootstrap

W tym momencie istotna rzecz odnośnie zrozumienia tego co robimy. Ktoś by powiedział, że mamy już 'gcc', biblioteki i inne fajne aplikacje dlaczego ich nie wykorzystać w nowym systemie już teraz. Trochę prawdy w tym jest, mamy już własne wygenerowane biblioteki na ich podstawie możemy budować całkowicie działające narzędzia. Punktem newralgicznym jest tu 'ld' czyli 'linker', który jak na razie linkuje wszystko z hosta. Tak więc wygenerowane w tej fazie narzędzia działają tylko na systemie matce. Używając 'chroot', i wykonując dowolną z katalogu bin, będziemy mieć błąd nie znalezionej biblioteki (np. glibc.so).

Tak na prawdę, na razie mamy biblioteki i kilka narzędzi działających na bibliotekach obecnego systemu .Teraz przekompilujemy jeszcze raz tak, aby nowy system korzystał tylko z bibliotek które już posiada, a nie bibliotek systemu pochodnego.

Chociaż umiejętnie podmieniając ścieżki lub ustawiając zmienne środowiskowe już na tym etapie można odpalić 'gcc' i skompilować program wewnątrz nowego sytemu.

Programy testowe

Służą do przeprowadzania sekwencji testujących w Binutils i GCC fazie trzeciej. Niekoniecznie trzeba je instalować teraz, niekoniecznie wszystkie trzy, a nawet niekoniecznie w ogóle instalować.

TCL

Tcl provides a powerful platform for creating integration applications that tie together diverse applications, protocols, devices, and frameworks. When paired with the Tk toolkit, Tcl provides the fastest and most powerful way to create GUI applications that run on PCs, Unix, and the Macintosh. Tcl can also be used for a variety of web-related tasks and for creating powerful command languages for applications.

Należy rozpakować, a następnie wejść do katalogu unix, dalej make, make install, make install-private-heades (potrzebne dla expect).

cd $LFS
rm -R $LFS_SRC/tcl8.* -R
tar -zxvf $LFS_PKG/tcl8.4.15-src.tar.gz -C $LFS_SRC
 cd $LFS_SRC/tcl8.4.15/unix/
 ./configure --prefix=$TOOLS
make
make install
make install-private-headers  
ln -sv tclsh8.4 $TOOLS/bin/tclsh

cd $LFS_SRC/tcl8.4.15/unix && 
make install &&
make install-private-headers
Installing libtcl8.4.so to $TOOLS/lib/ Installing tclsh as $TOOLS/bin/tclsh8.4 Installing tclConfig.sh to $TOOLS/lib/ Installing libtclstub8.4.a to $TOOLS/lib/ Making directory $TOOLS/lib/tcl8.4 Making directory $TOOLS/lib/tcl8.4/http2.5 Making directory $TOOLS/lib/tcl8.4/http1.0 Making directory $TOOLS/lib/tcl8.4/opt0.4 Making directory $TOOLS/lib/tcl8.4/encoding Making directory $TOOLS/lib/tcl8.4/msgcat1.3 Making directory $TOOLS/lib/tcl8.4/tcltest2.2 Installing header files Installing library files to $TOOLS/lib/tcl8.4 Installing library http1.0 directory Installing library http2.5 directory Installing library opt0.4 directory Installing library msgcat1.3 directory Installing library tcltest2.2 directory Installing library encoding directory Making directory $TOOLS/man/man3 Making directory $TOOLS/man/mann Installing and cross-linking top-level (.1) docs Installing and cross-linking C API (.3) docs Installing and cross-linking command (.n) docs Mogą wystąpić błędy związane z nieprawidłowym wykonaniu poprzednich instrukcji bądź inne np. niepotrzebny obiekt fixstrtod.o (ten sam co strtod.o), błędy syntaktyczne w samym kodzie (sic!). Ja znalazłem iż zwiększany był typ 'void' a nie jego zrzut na char. Na szczęście wszystko da się rozwiązać, przy ciężkich objawach po prostu zaczynamy od nowa.

Expect

Expect za pośrednictwem TLC-a komunikuje się z innymi programami i wykonuje na nich operacje oraz testy.

Po rozpakowaniu przed standardowymi operacjami konfiguracji i instalacji sprawdzamy czy akurat do naszej paczki nie ma jakiś paczy (albo i nie). Jak tak to oczywiście poprawiamy kody źródłowe i kropka.

cd $LFS
rm -R $LFS_SRC/expect-5.4* -R
tar -zxvf $LFS_PKG/expect-5.43.0.tar.gz -C $LFS_SRC
cd $LFS_SRC/expect-5.43
patch -Np1 -i $LFS_PKG/expect-5.43.0-spawn-1.patch 
cp configure{,.bak}
sed 's:/usr/local/bin:/bin:' configure.bak > configure
./configure --prefix=$TOOLS --with-tcl=$TOOLS/lib 
  --with-tclinclude=$TOOLS/include --with-x=no
make
make SCRIPTS="" install
cd $LFS_SRC/expect-5.43 && 
patch -Np1 -i ../expect-5.43.0-spawn-1.patch
patching file exp_chan.c Hunk #1 succeeded at 622 (offset 103 lines). patching file exp_command.h Hunk #1 succeeded at 30 with fuzz 1 (offset 5 lines). Hunk #2 succeeded at 104 (offset 6 lines). patching file expect.c Hunk #2 succeeded at 1628 (offset 1 line). Hunk #3 succeeded at 1712 (offset 1 line). Hunk #4 succeeded at 1730 (offset 1 line). Hunk #5 succeeded at 1787 (offset 1 line). Hunk #6 succeeded at 2864 (offset 5 lines).

Deja GNU

cd $LFS
tar -zxvf $LFS_PKG/dejagnu-1.4.4.tar.gz -C $LFS_SRC
cd $LFS_SRC/dejagnu-1.4.4/
./configure --prefix=$TOOLS
make install

Binutils i GCC po raz drugi

Tu wymagane skupienie 3-ego stopnia. Są to części dość krytyczne. Instalacja poszczególnych wersji GCC i Binutils może się różnić. W razie problemów odsyłam najpierw do strony projektu, potem do dokumentacji oraz googli.Problemu tu wynikające w większym stopni mogą wynikać z błędów przy poprzedniej instalacji tych pakietów, błędów z linkerem lub dostosowywaniem zależności (toolchain)

Rekompilacja GCC

Kompilator gcc jeszcze nie działa (chyb że zastosowano wcześniejsze instrukcję i już go skompilowano to nie trzeba drugi raz robić tego samego, choć na pewnie by nie zaszkodziło w razie czego).

Jest skompilowany na lokalny glibc. Teraz przekompilujemy go jeszcze raz by był autonomiczną, oddzielną całością.

cd $LFS_SRC/gcc-4.1.2
cp -v gcc/Makefile.in{,.orig}
sed 's@./fixinc.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in
cp -v gcc/Makefile.in{,.tmp}
sed 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp 
  > gcc/Makefile.in
patch -Np1 -i $LFS_PKG/gcc-4.1.2-specs-1.patch
rm -R ../gcc-build/*
 cd ../gcc-build
 
../gcc-4.1.2/configure --prefix=$TOOLS 
    --with-local-prefix=$TOOLS --enable-clocale=gnu 
    --enable-shared --enable-threads=posix 
    --enable-__cxa_atexit --enable-languages=c,c++ 
    --disable-libstdcxx-pch
 
make
make -k check
make install

Rekompilacja Binutils

 

cd   $LFS_SRC/binutils-2.17/
rm -Rf ../binutils-build/*
cd ../binutils-build
 ../binutils-2.17/configure --prefix=$TOOLS 
    --disable-nls --with-lib-path=$TOOLS/lib
make
make check
make install
make -C ld clean
make -C ld LIB_PATH=/usr/lib:/lib
cp -v ld/ld-new $TOOLS/bin

Test

Wskazany jest w tym momencie test kompilatora gcc :

echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': $TOOLS'

Wynik operacji readelf powinien wskazywać nasz obrany katalog $TOOLS np. [Requesting program interpreter: $TOOLS/lib/ld-linux.so.2]

Programy użytkowe

Jeśli dotarliśmy do tego momentu można odetchnąć i przygotować się na endless, boring ./configure && make && make install

Aby się tak nie nudzić polecam studiowanie instalowanych pakietów. Wiedza ta może zaprocentować gdy w BLFS będziemy wykorzystywać biblioteki niektórych z nich

Programy te w większości na razie są nam potrzebne do praktycznie całkowitego odizolowania się od hosta i rozpoczęcia dalszego indywidualnego rozwoju

Nie są jakoś specjalnie optymalizowane do jakichś wyszukanych potrzeb, mają tylko spełniać podstawowe funkcję. Samo configure --prefix=$TOOLS powinno w większości nich załatwić sprawę.

Niezmiennie na stronie LFS figurują poniższe programy (perl zajmujący sporą część kompilacji i chyba nawet można go pominąć):

  • Ncurses - obsługa terminala
  • Bash
  • Bzip2 - kompresja
  • Coreutils
  • Diffutils - program diff
  • File
  • Findutils -program find
  • Gawk - gawk, edytor tektu
  • Gettext
  • Grep -
  • Gzip - kompresja
  • M4
  • Make - Makefile
  • Patch - program patch
  • Perl - najczęściej do tekstu
  • Sed - edytor txt inline
  • Tar
  • Texinfo

Ncurses

cd $LFS
tar -zxvf $LFS_PKG/ncurses-5.6.tar.gz -C $LFS_SRC/
cd $LFS_SRC/ncurses-5.6/
./configure --prefix=$TOOLS --with-shared 
    --without-debug --without-ada --enable-overwrite
make
make install

Bash

cd $LFS
tar -zxvf $LFS_PKG/bash-3.2.tar.gz -C $LFS_SRC
cd $LFS_SRC/bash-3.2
./configure --prefix=$TOOLS --without-bash-malloc
make
make install
ln -vs bash $TOOLS/bin/sh

Bzip2

cd $LFS
tar -zxvf $LFS_PKG/bzip2-1.0.4.tar.gz -C $LFS_SRC/
cd $LFS_SRC/
cd bzip2-1.0.4/
make
make PREFIX=$TOOLS install

Coreutils

Czyli wszystkie bash'owe przydatne komendy

cd $LFS
tar -xjvf $LFS_PKG/coreutils-6.9.tar.bz2 -C $LFS_SRC/
cd $LFS_SRC/coreutils-6.9
make
make install
cp -v src/su $TOOLS/bin/su-tools

Diffutils

<p>cd $LFS
tar -zxvf $LFS_PKG/diffutils-2.8.1.tar.gz  -C $LFS_SRC
cd $LFS_SRC/diffutils-2.8.1/
./configure --prefix=$TOOLS
make 
make install

Findutils

cd $LFS
tar -zxvf $LFS_PKG/findutils-4.2.31.tar.gz -C $LFS_SRC/
cd $LFS_SRC/findutils-4.2.31/
./configure --prefix=$TOOLS
make
make install

Gawk

cd $LFS
 tar -xjvf $LFS_PKG/gawk-3.1.5.tar.bz2 -C $LFS_SRC
cd $LFS_SRC/gawk-3.1.5
./configure --prefix=$TOOLS
 
cat >> config.h << "EOF"
#define HAVE_LANGINFO_CODESET 1
#define HAVE_LC_MESSAGES 1
EOF
 
make
 make install

Gettext

cd $LFS
tar -zxvf $LFS_PKG/gettext-0.16.1.tar.gz -C $LFS_SRC
cd $LFS_SRC/gettext-0.16.1/
cd gettext-tools
./configure --prefix=$TOOLS --disable-shared
make -C gnulib-lib
make -C src msgfmt
cp -v src/msgfmt $TOOLS/bin

Grep

cd $LFS
 tar -xjvf $LFS_PKG/grep-2.5.1a.tar.bz2 -C $LFS_SRC/
 cd $LFS_SRC/grep-2.5.1a/
./configure --prefix=$TOOLS 
    --disable-perl-regexp
make
make install

Gzip

cd $LFS
tar -zxvf $LFS_PKG/gzip-1.3.12.tar.gz -C $LFS_SRC/
cd $LFS_SRC/gzip-1.3.12/
./configure --prefix=$TOOLS
 make
 make install

Make

cd $LFS
tar -jxvf $LFS_PKG/make-3.81.tar.bz2 -C $LFS_SRC/
cd $LFS_SRC/make-3.81/
./configure --prefix=$TOOLS
make
make install

Patch

cd $LFS
tar -zxvf $LFS_PKG/patch-2.5.4.tar.gz -C $LFS_SRC/
cd $LFS_SRC/patch-2.5.4/
./configure --prefix=$TOOLS
 make
 make install

Perl

cd $LFS
tar -jxvf $LFS_PKG/perl-5.8.8.tar.bz2 -C $LFS_SRC/
cd $LFS_SRC/perl-5.8.8/
patch  -Np1 -i $LFS_PKG/perl-5.8.8-libc-2.patch 
./configure.gnu --prefix=$TOOLS -Dstatic_ext='Data/Dumper Fcntl IO POSIX'
make perl utilities
cp -v perl pod/pod2man $TOOLS/bin
mkdir -pv $TOOLS/lib/perl5/5.8.8
cp -Rv lib/* $TOOLS/lib/perl5/5.8.8

Sed

cd $LFS
tar -zxvf $LFS_PKG/sed-4.1.5.tar.gz -C $LFS_SRC/
cd  $LFS_SRC/sed-4.1.5/
./configure --prefix=$TOOLS
make
make install

Tar

cd $LFS
tar -jxvf $LFS_PKG/tar-1.18.tar.bz2 -C $LFS_SRC/
cd $LFS_SRC/tar-1.18/
./configure --prefix=$TOOLS
make
 make install

Texinfo

cd $LFS
tar -jxvf $LFS_PKG/texinfo-4.9.tar.bz2 -C $LFS_SRC/
cd $LFS_SRC/texinfo-4.9/
./configure --prefix=$TOOLS
make
 make install

UtilLinux

cd $LFS
tar -jxvf $LFS_PKG/util-linux-2.12r.tar.bz2 -C $LFS_SRC/
 cd $LFS_SRC/util-linux-2.12r/
sed -i 's@/usr/include@$TOOLS/include@g' configure
./configure
make -C lib
make -C mount mount umount
make -C text-utils more
cp -v mount/{,u}mount text-utils/more $TOOLS/bin

Odchudzanie

strip --strip-debug $TOOLS/lib/*
strip --strip-unneeded $TOOLS/{,s}bin/*
rm -rf $TOOLS/{info,man}

Phase Two

Mamy już wszystko co potrzebne. Teraz możemy nagrać system na dysk, zrobić chroot i dalej instalować pakiety. Oczywiście minimalistyczny system jest już gotowy do nagrania na pendriva lub mini płytkę cd.

mkdir -pv $LFS/{dev,proc,sys}
mknod -m 600 $LFS/dev/console c 5 1
mknod -m 666 $LFS/dev/null c 1 3
 
chroot "$LFS" $TOOLS/bin/env -i 
    HOME=/root TERM="$TERM" PS1='u:w$ ' 
    PATH=/bin:/usr/bin:/sbin:/usr/sbin:$TOOLS/bin 
    $TOOLS/bin/bash --login +h
 
 mkdir -pv /{bin,boot,etc/opt,home,lib,mnt,opt}
mkdir -pv /{media/{floppy,cdrom},sbin,srv,var}
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
mkdir -pv /usr/{,local/}{bin,include,lib,sbin,src}
mkdir -pv /usr/{,local/}share/{doc,info,locale,man}
mkdir -v /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
 
for dir in /usr /usr/local; do
  ln -sv share/{man,doc,info} $dir
done
mkdir -v /var/{lock,log,mail,run,spool}
mkdir -pv /var/{opt,cache,lib/{misc,locate},local}
ln -sv $TOOLS/bin/{bash,cat,echo,grep,pwd,stty} /bin
ln -sv $TOOLS/bin/perl /usr/bin
ln -sv $TOOLS/lib/libgcc_s.so{,.1} /usr/lib
ln -sv $TOOLS/lib/libstdc++.so{,.6} /usr/lib
ln -sv bash /bin/sh
 
touch /etc/mtab
 
cat < /etc/passwd >> "EOF"
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
EOF
 
cat < /etc/group >> "EOF"
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
mail:x:34:
nogroup:x:99:
EOF
 
echo "Creating directories for log files";
 
touch /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chgrp -v utmp /var/run/utmp /var/log/lastlog
chmod -v 664 /var/run/utmp /var/log/lastlog

Zakończenie

Kolejna faza bardzo przypominą poprzednią, nic nowego

W tym momencie odsyłam juz z konieczności do stronki z projektem

Po ukończeniu wkraczamy w świat prawdziwego systemu BLFS

Po BLFS, czego nie znajdziecie na tej stronie, należy pomysleć o zarządzaniu pakietami. Na początku trzymać można sugerować się stroną projektu. Można także trzymać zależności jak to napisali w głowie. Więcej informacji na ten temat w rozdziale 3 - Package Management.

Moim rozwiązaniem było package-managere ze slackware'a. Tym samy utorowało to drogę do transformacji BLFS na Slackaware.

Cytaty

- Simplicity is the ultimate sophistication. - Leonardo da Vinci,
- Popularny człowiek wzbudza zawiść potężnych - Thufir Hawat o Leto Atrydzie (na Kaladanie),
- Szczęście następuje po smutku, a smutek po szczęściu; człowiek jest naprawdę wolny, gdy przestaje rozróżniać między smutkiem a szczęściem, między dobrem a złem - Aforyzmy buddyjskie.