Większość oprogramowania dla Linuksa jak i sam system dostępne jest w postaci kodu źródłowego. Program komputerowy jest zapisany w pewnym języku programowania, zazwyczaj jako tekst, ale też jako inne dane (np. litery, cyfry, symbole) w postaci czytelnej dla człowieka. W takiej postaci program jest zrozumiały dla człowieka (programisty znającego język programowania) jednakże bezpośrednio jest bezużyteczny dla maszyny np. komputera.

Kod źródłowy jest przetwarzany na kod maszynowy zrozumiały dla (procesora) maszyny, przez translator (kompilator lub asembler), lub jest analizowany i wykonywany przez specjalny program zwany interpreterem, może być też przetworzony na kod pośredni. W tym artykule zajmiemy się kompilacją programów pod Linuksem.

Pierwszym krokiem będzie oczywiście pobranie jakiejś aplikacji. Ogromną bazę programów można znaleźć na stronie SourceForge.net. Zamieszczone tam pliki najczęściej są w postaci archiwów tar.gz lub tar.bz2. W archiwach tych znajdują się pliki zawierające źródła, pliki Makefile, instrukcje jak kompilować dany program lub inne pliki zawierające informacje od autora (TODO, ChangeLog).

Pobraną aplikację kopiujemy do katalogu /usr/src, gdzie ją rozpakujemy. Operacje te powinniśmy wykonywać jako użytkownik root, gdyś zazwyczaj tylko on ma tam prawa do zapisu. W katalogu tym należy rozpakować dane archiwum. Możemy skorzystać z aplikacji graficznych takich jak Ark, czy file-roller. W przypadku konsoli pomoże nam Midnight Commander (polecenie mc) lub tar, gzip, bzip2. W przypadku archiwum tar.gz wydajemy polecenie: tar -xvzf archiwum.tar.gz np:

[root@muszelka src]# tar -xvzf ekg-current.tar.gz
ekg-20080114/
ekg-20080114/configure
ekg-20080114/config.sub
ekg-20080114/config.guess
ekg-20080114/examples/
ekg-20080114/examples/.cvsignore
ekg-20080114/examples/httphash.c
ekg-20080114/examples/conn-async.c
ekg-20080114/examples/register.c
...

Opis przełączników dla tar:

  • x – oznacza, żeby dany plik został rozpakowany
  • v – pokaże nam listę plików i szczegóły
  • z – filtrowanie pakietów przez gzip
  • f – oznacza, że plik archiwum jest plikiem lokalnym

W wyniku powyższych operacji otrzymaliśmy katalog, w którym znajdują się źródła programu, licencje oraz pliki informujące jak dany program skompilować i zainstalować. Najczęściej jest to plik INSTALL lub README. Warto je poczytać, gdyż znajdziemy tam szczegółowe informacje na temat kompilacji danej aplikacji. Typowa kompilacja rozpoczyna się od wydania polecenia ./configure w katalogu ze źródłami. Jest to prosty skrypt Configure, który sprawdza nasz system pod względem, czy posiada wszystkie potrzebne biblioteki, sprawdza dostępność kompilatorów, przygotowuje źródła do kompilacji w danym systemie. Cały proces wygląda mniej więcej tak:

[root@muszelka ekg-20080114]# ./configure
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking how to run the C preprocessor... gcc -E
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln -s works... yes
checking for an ANSI C-conforming const... yes
checking for gmake... /usr/bin/gmake
checking for ar... ar
checking for strip... strip
checking for t_accept in -lnsl... no
checking for socket in -lsocket... no
checking for __inet_addr in -lbind... no
checking for inet_pton... yes
checking for pkg-config... pkg-config
...

Bardzo często zdarza się, że configure zatrzyma się w pewnym momencie i pokaże listę błędów, które uniemożliwiają nam skompilowanie programu:

checking for libgnutls-config... no
checking for libgnutls - version >= 1.0.0... no
*** The libgnutls-config script installed by LIBGNUTLS could not be found
*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in
*** your path, or set the LIBGNUTLS_CONFIG environment variable to the
*** full path to libgnutls-config.
configure: WARNING:
***
*** libgnutls was not found. You may want to get it from
*** ftp://ftp.gnutls.org/pub/gnutls/

Jak widać powyżej brakuje nam biblioteki libgnutls w wersji większej lub równej 1.0.0. Configure również pokazało, gdzie należy szukać podanych plików. Po zainstalowaniu biblioteki odpalamy jeszcze raz ten skrypt i czytamy na rezultaty. Być może teraz znajdzie brak innych plików, pakietów, które również będzie trzeba doinstalować lub skompilować. Jeśli wszystkie zależności zostaną spełnione naszym oczom powinien pokazać się następujący efekt:

configure: creating ./config.status
config.status: creating src/Makefile
config.status: creating Makefile
config.status: creating examples/Makefile
config.status: creating config.h

configured options:
 - openssl: enabled
 - ioctld: disabled
 - python: disabled
 - zlib: enabled
 - pthread: disabled
 - libungif: disabled
 - libjpeg: enabled
 - ui-readline: disabled
 - ui-ncurses: enabled (default)
 - ui-gtk: enabled
 - aspell: disabled

Good - your configure finished. Start make now

Sama kompilacja ogranicza się do wydania polecenia make:

[root@muszelka ekg-20080114]# make
cd src && /usr/bin/gmake all
gmake[1]: Wejście do katalogu `/usr/src/ekg-20080114/src'
gcc  -MM -I.. -g -O2 -Wall    -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include   -DDATADIR=\"/usr/local/share/ekg\" -DSYSCONFDIR=\"/usr/local/etc\" stuff.c commands.c events.c themes.c vars.c dynstuff.c userlist.c ekg.c xmalloc.c mail.c msgqueue.c emoticons.c configfile.c simlite.c ../compat/strlcat.c ../compat/strlcpy.c ui-ncurses.c ui-gtk.c ui-gtk-maingui.c ui-gtk-xtext.c ui-gtk-chanview.c ui-gtk-palette.c ui-gtk-bindings.c ui-batch.c ui-none.c log.c comptime.c 1> .depend
gcc  -I.. -g -O2 -Wall    -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include   -DDATADIR=\"/usr/local/share/ekg\" -DSYSCONFDIR=\"/usr/local/etc\"   -c -o stuff.o stuff.c
gcc  -I.. -g -O2 -Wall    -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include   -DDATADIR=\"/usr/local/share/ekg\" -DSYSCONFDIR=\"/usr/local/etc\"   -c -o commands.o commands.c</pre>
Wszystko w tym momencie powinno kompilować się bez problemu. Jeśli wystąpią jakieś problemy, moga one wynikać ze starszej wersji kompilatora jaką posiadamy lub błędnie napisanych źródeł. Warto wtedy poczytać instrukcje dołączone do porgramu, lub przeszukać Internet, aby znaleźć rozwiązanie. Z reguły kompilacja kończy się poprawnie. Na konsoli powinniśmy zobaczyć następujący wynik:
<pre>make[2]: Nie nic do roboty w `all-am'.
make[2]: Leaving directory `/usr/src/ekg2-20050812'
make[1]: Leaving directory `/usr/src/ekg2-20050812'

Nasz program jest skompilowany. Czas go zainstalować. Instalacja skompilowanych źródeł musi odbywać się z poziomu użytkownika root dlatego. Teraz wystarczy wydać polecenie: make install. Teraz system kopiuje odpowiednie pliki binarne do katalogów systemu. Proces instalacji wygląda mniej więcej tak:

...
Making install in tests
make[3]: Wejście do katalogu `/usr/src/pidgin-2.3.1/libpurple/tests'
make[4]: Wejście do katalogu `/usr/src/pidgin-2.3.1/libpurple/tests'
make[4]: Nie ma nic do zrobienia w `install-exec-am'.
make[4]: Nie ma nic do zrobienia w `install-data-am'.
make[4]: Opuszczenie katalogu `/usr/src/pidgin-2.3.1/libpurple/tests'
make[3]: Opuszczenie katalogu `/usr/src/pidgin-2.3.1/libpurple/tests'
...

Po całej tej operacji wystarczy w konsoli napisać nazwę programu i się on uruchomi. Jeśli program się nam znudzi i chcemy go usunąć to wystarczy wejść do katalogu ze źródłem programu (domyślnie /usr/src/nazwa_programu) i jako root wydajemy polecenie make uninstall.

  • Michał Olber

    Ach, ten artykuł bardzo mi się przyda.Zawsze miałem problemy z zapamiętaniem, co i jak się robi. No i ten literki przy archiwach…wiedziałem, że to rozpakowuje, ale dokładnego znaczenia nie.

    Dzięki Kamil za taki krótki artykuł.

  • EstoyDeAcuerdo

    'Pokaże' piszemy przez 'z' z kropką ;-)

  • Od kiedy to kompilujemy na rootcie? Nie ucz nowicjuszy glupot!

  • A czemu nie? Na wielu serwerach dostęp do /usr/src oraz kompilatorów ma tylko root, a nie zwykły user. Więc jak kompilować inaczej?