Kompilacja i instalacja ze źródeł

Wstęp

Kompilacja źródeł... ach, jak to brzmi! Hoppke nawet twierdzi, że laski na to lecą. Bardziej poważnie, jeśli myślisz dodatkowo o optymalizacji pod procesor, zapoznaj się z podlinkowanym artykułem. Jeśli zaś zamierzasz Linuksa tylko używać, nawet nie czytaj dalej.

Poniższy artykuł ma za zadanie wyjaśnić bardzo przystępnie, dogłębnie i owocnie jak skompilować swój pierwszy program.

Trochę teorii

Kompilacja ze źródeł ma swoje plusy i minusy:

Dlaczego użytkownik musi się bawić w kompilowanie czegokolwiek?

Zwykły użytkownik może używać Linuksa i nigdy w życiu niczego nie kompilować. Dla zwykłego użytkownika są repozytoria pakietów RPM/DEB i innych, z których może korzystać bez żadnej wiedzy. Użytkownicy Linuksa decydują się na nauczenie się kompilacji z kilku powodów:

Jeśli nie bardzo interesuje Cię informatyka, możesz sobie odpuścić naukę kompilacji źródeł. W przeciwnym wypadku, prędzej czy później staniesz przed koniecznością kompilacji czegoś. Zanim jednak wpiszesz magiczne make install, przeczytaj na tej stronie wszystko, co się tyczy kompilacji źródeł. W innym przypadku zrobisz bałagan w systemie.

Pierwszy skompilowany program

Kompilacja wzorcowa – bezproblemowa

Zdobywanie kodu źródłowego

Skompilujemy taką fajną gierkę o nazwie GL-117. Znajduje się ona na witrynie autora w dziale Download. Przyjrzyjmy się dokładnie, co tam jest napisane:

The Sources & pdf documentation
gl-117-1.3.2-src.tar.bz2 (2.4MB)
gl-117-1.3.1-src.tar.bz2 (2.3MB)
gl-117-1.3-src.tar.bz2 (2.3MB)
Linux
Debian Linux deb
(Cedric Delfosse) via Debian download page
Fedora Core 1+2 rpm
(Richard June)
http://yum.bravegnuworld.com/yum/fc/1/
http://yum.bravegnuworld.com/yum/fc/2/
RedHat 9 rpm
(Richard June)
http://yum.bravegnuworld.com/yum/rh/9/
Yellow Dog 3 rpm
(Richard June)
http://yum.bravegnuworld.com/yum/yd/3/


Jak widać, nieźle to pokomplikowane. Szukamy źródeł. No więc źródła znajdują się w dziale The Sources & pdf documentation. Reszta to pakiety dla wybranych dystrybucji. W ww. dziale mamy 3 pozycje:
gl-117-1.3.2-src.tar.bz2 (2.4MB)
gl-117-1.3.1-src.tar.bz2 (2.3MB)
gl-117-1.3-src.tar.bz2 (2.3MB)


Co wybieramy? Oczywiście najnowszą wersję, czyli gl-117-1.3.2-src.tar.bz2. Przyjrzyjmy się bliżej tej nazwie. Pierwszy człon to nazwa programu gl-117. Następnie mamy numer wersji 1.3.2. Kolejny ciąg znaków src oznacza, że chodzi o źródła (src - source). Dalej mamy rozszerzenie tar.bz2. Jest to archiwum tar, skompresowane do bz2. Zamiast tego może być tar.gz. Po więcej informacji możesz się udać do konsoli man tar, ale nie jest to konieczne w tej chwili.

Po kliknięciu w odnośnik, otworzy się kolejna strona. Możesz z niej wybrać żądany serwer lustrzany (mirror). Następnie rozpocznie się ściąganie pliku.

Po ściągnięciu pliku, należy go rozpakować. Wszystkie "poprawne" strony podają tu tekstowe polecenia, ale ja pokażę, jak to zrobić z środowisku graficznym KDE, w programie Ark. Przecież tak jest wygodniej :-). A więc do dzieła:

Dolphin, prawy przycisk myszy/Rozpakuj tutaj archiwum

W Dolphinie klikamy prawym przyciskiem na archiwum.

otwieramy konsolę w rozpakowanym archiwum

Otwieramy konsolę w rozpakowanym archiwum

Konfiguracja kodu źródłowego: ./configure

Czym jest konfiguracja? Najprościej mówiąc, jest to procedura, uruchamiana po wpisaniu do konsoli

Czymże jest magiczne ./configure? Aby to zrozumieć, należy sobie uzmysłowić, że w poprzednim punkcie otworzyliśmy konsolę w rozpakowanym archiwum, co oznacza że bieżącym katalogiem konsoli jest gl-117-1.3.2-src. Napisanie w konsoli ./ oznacza bieżący katalog. Wpisanie ./configure oznacza wykonanie z bieżącego katalogu pliku wykonywalnego configure. Jeśli zajrzysz do wspomnianego katalogu gl-117-1.3.2-src, zobaczysz, że znajduje się tam istotnie plik configure. Dla zaspokojenia ciekawości powiem, że nie jest to plik binarny, tylko skrypt. A więc skonfigurujmy wreszcie te źródła:

Tak wygląda pomyślnie zakończony proces konfiguracji. Poznać to po tym, że skrypt nie wypisał żadnych błędów.

Tym razem udało się bezproblemowo. Oczywiście nie zawsze tak będzie, ale chodziło tylko o przykład. W kolejnych przykładach będzie już trudniej.

Kontynuujmy jednak kompilację gry GL-117. Po poprawnej konfiguracji źródeł, czas na ich kompilację:

Właściwa kompilacja: make

Jeśli proces konfiguracji zakończył się bez błędu, sama kompilacja powinna też przebiec poprawnie. Zwykle tak jest, jednak programy też piszą ludzie i zdarza im się popełnić błąd. Tym razem na szczęście kompilacja przebiegła pomyślnie (również nie widać błędów). Jednak widać ostrzeżenia: menu.h:67: warning: 'class Container' has virtual functions but non-virtual destructor. Nie są to błędy i nie powinniśmy się nimi specjalnie przejmować, o ile program nadal się kompiluje. Teraz czas na instalację programu w systemie:

Instalacja: make install

Jednym z najważniejszych zabezpieczeń Linuksa są uprawnienia. Zwykły użytkownik nie może zapisywać plików nigdzie, poza swoim katalogiem domowym (z kilkoma wyjątkami). Dlatego procesu instalacji nie może przeprowadzić zwykły użytkownik. Musi to zrobić administrator:

Jak widać, proces instalacji nie zakończył się błędami, z czego należy wnioskować, że zakończył się powodzeniem ;)

Możesz teraz zamknąć konsolę. Skompilowaną grę można uruchomić poleceniem gl-117. Dodać grę do menu "start" musisz (lub nie) samodzielnie, w zależności od Twojego środowiska graficznego/menedżera okien.

Problemy z kompilacją – przykład typowy

W tym przykładzie podarujemy już sobie ściąganie programu. Przejdźmy od razu do konkretów:

Tym razem mamy szereg błędów z przewijającym się skrótowcem SDL. W pewnym momencie otrzymujemy nawet czystym tekstem SDL not found - please install SDL. SDL to biblioteka, która używana jest przez gry do komunikacji z kartą graficzną, dźwiękową, klawiaturą... jak widać otwarte źródła to wygoda dla programistów, którzy zamiast skupiać się na rzeczach nieistotnych, używają gotowych programów i bibliotek.

Jak rozwiązać problem z kompilacją? Oczywiście instalując SDL. Procedura różni się dla każdej dystrybucji, ale chyba wiesz gdzie masz menedżer pakietów. SDL często jest rozbite na kilka pakietów, takich jak sdl_mixer, sdl_image, sdl_gfx. Rozbicie na pakiety zależy od filozofii przyjętej przez dystrybutora. W przypadku gier najprawdopodobniej i tak potrzebny będzie każdy z pakietów, którego nazwa rozpoczyna się od sdl. W przypadku kompilacji gier możesz potrzebować pakietów z przyrostkiem -devel, gdzie znajdują się pliki nagłówkowe i inne niezbędne rzeczy. Akurat SDL jako biblioteka sama w sobie zwykle nie będzie rozbita na pakiety -devel, ale warto wiedzieć że takie coś istnieje.

Na moim systemie KateOS pakiety nie są aż tak bardzo porozbijane, a wyszukanie tego co potrzebne zajmuje chwilkę. Na szczęście sdl obecne jest prawie wszędzie pod tą nazwą i jego instalacja powinna wyglądać wszędzie na zasadzie apt-get install sdl lub urpmi sdl. U mnie jest tak:

Po tej operacji etap konfiguracji kończy się bez błędów.

Naturalnie po konfiguracji można przystąpić do dalszych czynności kompilacyjnych.

Kompilacja od zera – przykład ekstremalny

Do stworzenia tego przykładu zainspirował mnie Ubuntu, na którym po instalacji nie ma absolutnie nic przydatnego do kompilacji. Zamiast Ubuntu zainstalowałem KateOS z minimalną liczbą pakietów - właściwie tylko środowisko xfce + najniezbędniejsze rzeczy do działania. Żeby było śmieszniej, skompilujemy na tym systemie K3B (dlatego, że nie ma KDE). Docenisz ten przykład, gdy napotkasz na jedną z sytuacji, które musiałem tu rozwiązać, bowiem komunikaty wyświetlane przez ./configure w przypadku braku kompilatorów są może i całkiem jasne, ale nie dają żadnego punktu zaczepienia co właściwie zainstalować.

Zainstalowany z miniiso system po prostu zieje pustką. Nie ma nawet na czym posłuchać muzyki. Przeglądarkę WWW i jakiś emulator terminala musiałem sobie doinstalować, bo ich tam nie było. Nic więc dziwnego, że tym razem rozpakowujemy archiwum tekstowo:

Kolejno wchodzimy do katalogu ze źródłami (znajduje się on w katalogu domowym, nie na pulpicie, gdyż konsola w tym momencie została uruchomiona z katalogu domowego):

Z ciężkim sercem, ale wstukujemy:

Uff, nie jest tak źle. Brak KDE to akurat najmniejszy kłopot.

Instalujemy KDE (oczywiście wszystko instalujemy z roota, co nie zostanie tu jednak pokazane). Ale zaraz, chwila! Przecież KDE rozbite jest na kilkanaście pakietów (oryginalnie, a w dystrybucjach i na kilkadziesiąt). Jak znaleźć odpowiedni? Ano przez wyszukanie pliku wskazanego przez configure: configure: error: The important program kde-config was not found!. Szukamy:

Jak widać, dokładny wynik znajdziemy w kdelibs. Z mojego doświadczenia wiem, że kdelibs to podstawowy pakiet, wraz z kdebase i arts tworzą działające środowisko KDE, więc nie ma tu wątpliwości. Takie informacje można sobie doczytać również w Internecie, choć tym razem nie ma takiej potrzeby.

Jak widać na listingu, zadziałały zależności i wymusiły instalację kilku innych pakietów niezbędnych do działania kdelibs. Jednym z nich jest qtlib, biblioteka graficzna dzięki której KDE w ogóle istnieje. Nie musimy się więc nią kłopotać już później.

Wykonajmy kolejne podejście:

A oto najciekawszy problem. Niby brakuje kompilatora, a jednak instalacja wszystkich możliwych w niczym nie pomoże. Połowa plików na dysku ma rozszerzenie cpp, więc wyszukiwarką też nic nie zdziałamy. Należy przyjąć na wiarę, że rozwiązaniem jest instalacja gcc-g++ i kernel-headers. Oczywiście w razie napotkania niestandardowych problemów, pierwszą instancją do której się kierujemy jest wyszukiwarka; mnie się jednak nie udało nigdzie znaleźć notki, że powyższy problem powodowany jest jednocześnie przez brak 2 pakietów. Zwykle powyższy komunikat omija się przez instalację wszystkiego ze stajni gcc, licząc że któryś z tych pakietów będzie zawierał w zależnościach to co trzeba, a po ominięciu feralnego komunikatu nikogo już nie interesuje co właściwie go powodowało.

Rozwiązujemy problem:

Ponieważ ten błąd wyjątkowo daje się we znaki nawet doświadczonym użytkownikom, zamieszczam na wszelki wypadek pełen listing pakietów w systemie po instalacji i poprawnym skompilowaniu K3B:

Posuwamy się dalej w naszym przykładzie:

Jak widać kompilator działa poprawnie, ale czego nam też może jeszcze brakować? Przecież X serwer jest zainstalowany! Niby jakim cudem uruchomione jest środowisko graficzne? W komunikacie wyświetlonym przez configure widać jednak wyraźnie, że chodzi o includes, czyli wszelkie pliki nagłówkowe (te znowu mają nazwę headers, jak kernel-headers) i programistyczne. Na szczęście Kasia nie posiada zbyt wielu pakietów i rozwiązanie tego problemu sprowadza się do instalacji pakietu deweloperskiego X serwera:

Podchodzimy do konfiguracji ponownie:

A oto jeden z moich "ulubionych" problemów, pakiet niby jest zainstalowany, ale nie jest widziany przez configure (jak wiadomo qtlib zostało zainstalowane wcześniej). W tym przypadku jest to błąd skryptu configure, który choć znalazł KDE w nietypowej lokalizacji checking where to install... /opt/kde3 (as returned by kde-config), nie wpadał na to, że Qt może być na przykład w /opt/qt. W Kasi Qt właśnie tam umieszczono, co jest podobnoż jest zgodne z zaleceniami freedesktop. Musisz wiedzieć, że większość programów instalowana jest w /usr i właśnie tam szukają swoich zależności (tak, jak zrobiłby K3B, gdyby nie znalazł KDE w innym miejscu dzięki kde-config. Za to ze znalezieniem Qt już sobie nie poradził). Niektóre programy lubią robić bałagan instalując się do /usr/local, co można oczywiście nadpisać parametrem ./configure --prefix=/usr.

Tu jednak jako żywo widać, że K3B wykrył niestandardową ścieżkę KDE i tam się zamierza zainstalować, nie potrafił jednak znaleźć Qt. Co z tym począć? Normalnie w takich przypadkach należy linkować biblioteki (ln -s) do miejsca, w którym configure spodziewa się je znaleźć, co być może zostanie również kiedyś pokazane na tej stronie. Sprawdza się to w przypadku jednego, dwóch plików, ale nie w przypadku całej dystrybucji Qt. Configure powinno mieć gdzieś możliwość przekazania lokalizacji Qt. Szukamy:

Odpowiednia opcja z pomocy została wytłuszczona w listingu. Czas zastosować ją w praktyce:

Hurra! Naturalnie brakuje nam jeszcze połowy rzeczy, ale nie są one krytycznie potrzebne do dalszej kompilacji. Jednak jeśli w tej chwili ich nie zainstalujesz, późniejsza ich instalacja celem użycia w K3B wymusza jego rekompilację.

Nam się jednak już nie chce bawić w kolejne zalezności, więc zgodnie z sugestią skryptu wpisujemy make:

Ha, ha! No pewnie, a niby czemu miałoby tu być? ;) W końcu make to osobny program (w przeciwieństwie do skryptu ./configure, który znajduje się już w źródłach i jest uruchamiany przez basha, który znowu jest wymagany w ogóle do działania systemu).

Rozwiązanie tego nie będzie na szczęście zbyt skompilowane:

No to czadu:

Auć. To nie powinno było się zdarzyć! (tm). W końcu configure służy do wykrywania takich rzeczy. Po wyszukaniu pliku libxslt.so.1 w bazie pakietów dochodzimy do wielce odkrywczego wniosku, że zainstalować należy:

Oby to była ostatnia niespodzianka dzisiaj:

No nareszcie! Można instalować:

Aby zobaczyć efekt naszych dokonań należy z powrotem przelogować się na użytkownika (pamiętamy, uruchamianie programów graficznych z roota tylko w ostateczności):

No i tym razem znowu nie obyło się bez niespodzianek ;). Zawiniła dystrybucja, która nie posiada /opt/kde w zmiennej $PATH (/usr się w niej znajduje). No cóż, wpiszmy zatem ścieżkę ręcznie:

Naturalnie musimy je doinstalować podobnie jak zależności. Ale K3B działa. I marudzi:

K3B marudzi o swoje programy do nagrywania

Jeśli potrzebujesz spolszczenia, musisz je doinstalować na podobnej zasadzie. Zdradzę od razu, że potrzebny będzie gettext.

Make bajzel

Tudzież make burdel, jak niektórzy mówią. Użycie make install na źródłach spowoduje przykopiowanie skompilowanych binariów i innych plików wraz z nadaniem odpowiednich uprawnień do drzewa systemu plików. Jak można usunąć później taki program? Wszak jego pliki są porozrzucane po wielu katalogach, a menedżer pakietów nie posiada informacji o nim. Otóż wraz ze skryptem instalacyjnym w źródłach powinien być także skrypt deinstalacyjny, który uruchamiamy poleceniem:

Nie wszystkie programy jednak udostępniają taki skrypt, a już całkiem spora liczba nie posiada nawet skryptu instalacyjnego. Poza tym trzymanie na dysku rozpakowanych i skompilowanych źródeł celem odinstalowania czegoś w przyszłości jest bardzo nieekonomiczne. Istnieje kilka rozwiązań tego problemu.

Checkinstall

Checkinstall to najprostsze z rozwiązań i jednocześnie dosyć dobre dla przeciętnego użytkownika. Cały trick polega na zastąpieniu polecenia make install poleceniem checkinstall. Checkinstall to odrębny program monitorujący proces instalacji i tworzący pakiet właściwy danej dystrybucji. Domyślnie polecenie checkinstall także zainstaluje kompilowany program, który będzie od tego momentu widoczny w bazie pakietów dystrybucji. Nie wszystkie dystrybucje jednak są skonfigurowane do działania z checkinstall, więc stworzenie odpowiedniego pakietu może wymagać przeczytania man checkinstall.

Pakiet dla dystrybucji

Stworzenie pakietu dedykowanego dla swojej dystrybucji ze wszystkimi dodatkami (skrypty przed instalacją, po instalacji, przy usuwaniu, opisy pakietu w różnych językach, skrypt budujący, itd.) może być źródłem satysfakcji, nie tylko z racji dokształcenia się, ale przede wszystkim z możliwości udostępnienia swojej pracy innym. Jest to jednak trudne i mozolne zadanie, przynajmniej za pierwszym razem. Przy aktualizacjach programu będzie można skorzytać bowiem z istniejącego już skryptu budującego (tzw. build) do szybkiego zbudowania nowszego pakietu. Szczegółowych informacji należy szukać w dokumentacji swojej dystrybucji.