JustPaste.it

Tworzenie pliku Makefile

Do czego służy plik Makefile? Otóż jest to zbiór reguł dla kompilatora, wykorzystywanych podczas kompilacji programu z użyciem polecenia 'make'. Pliki Makefile zostały stworzone, żeby ułatwić pracę przy kompilacji programów ze źródłami w wielu plikach i wielu nagłówkach. Każdy, kto miał do czynienia z takim programem, wie jaka żmudna jest praca przy wpisywaniu ciągłego 'gcc -o program plik1.o plik2.o ...'. Narzędzie 'make' razem z odpowiednim plikiem Makefile bardzo ułatwia tą sprawę. Zapewne każdy, kto kiedykolwiek kompilował jądro zauważył, że po zmianie konfiguracji tylko nowododane i zmodyfikowane źródła było ponownie przekompilowywane. To właśnie dzięki plikom Makefile.

Najprościej nauczyć się na przykładzie, więc wyobraźmy sobie taki przykład:

Program składa się z trzech plików 1.c, 2.c, 3.c i trzech nagłówków a.h, b.h, c.h. Do pliku 1.c włączane są pliki a.h i b.h, do pliku 2.c pliki b.h i c.h, a do pliku 3.c wszystkie trzy nagłówki. Funkcja main() znajduje się w pliku 1.c. Ręcznym sposobem stworzenia programu byłoby:
gcc -c 1.c

gcc -c 2.c

gcc -c 3.c

gcc -o program 1.o 2.o 3.o


Nie jest to sposób zły, ale wysoce męczący. Co jeśli zmieni się zawartość pliku b.h, który jest włączany do wszystkich trzech plików .c? Trzeba wszystkie te pliki przekompilować i zlinkować, czyli znowu trzeba wydać te cztery polecenia. Inny przykład. Zmieniamy zawartość pliku 3.c. Żeby program ponownie stworzyć trzeba wykonać dwa ostatnie z wyżej wymienionych poleceń. To jest naprawdę męczące. Przy pomocy narzędzia make można stworzyć program, niezależnie od wcześniej wprowadzonych zmian, używając tylko jednego polecenia, konkretnie polecenia 'make'.

Do stworzenia pliku Makefile musimy znać zależności między plikami. W naszym przypadku cały program zależy od plików 1.o, 2.o i 3.o. Plik 1.o zależy od 1.c, a.h i b.h. Plik 2.o zależy od 2.c, b.h i c.h, a plik 3.o zależy od 3.c, a.h, b.h i c.h. Jak to zapisać w pliku Makefile? Bardzo prosto:

#To jest linia komentarza, nie będzie ona brana pod uwagę przez make.
program: 1.o 2.o 3.o
#Obiekt "program" zależny jest od plików 1.o, 2.o i 3.o
    gcc -o program 1.o 2.o 3.o
#Do stworzenia tego obiektu używa się wyżej napisanego polecenia
1.o: 1.c a.h b.h
    gcc -c 1.c
2.o: 2.c b.h c.h
    gcc -c 2.c
3.o 3.c a.h b.h c.h
    gcc -c 3.c



Te kilka linijek opisuje zależności w naszym programie. Po ich zapisaniu w pliku Makefile będziemy mogli kompilować program przy pomocy komendy 'make'.

Jednak 'make' jest bardzo rozbudowanym programem. Można w nim stosować naprawdę skomplikowane reguły. Nie będę ich tutaj omawiał, bo szczegóły na ich temat zawarte są w dokumentacji, ale napiszę jeszcze o makrach. Mianowicie często chcemy, aby wszystkie pliki zostały skompilowane z pewnymi opcjami lub zlinkowane z konkretnymi bibliotekami. Wpisywanie tego linijka po linicje może być bardzo męczące, dlatego można używać makr. Czym jest makro? Makro po prostu jest krótszym tekstowym zamiennikiem jakiegoś dłuższego ciągu, w naszym przypadku polecenia. Ale najlepiej wytłumaczyć na przykładzie:

CC=gcc
#Makro CC zawiera nazwę kompilatora
CFLAGS=-Wall -ansi -pedantic
#Makro CFLAGS zawiera parametry kompilatora
CLINK=-lm
#Makro CLINK zawiera opcje linkera.
program: 1.o 2.o 3.o
    $(CC) -o program 1.o 2.o 3.o $(CLINK)
#Wykorzystanie kompilatora gcc (makro CC) do zlinkowania
#programu z opcją -lm (CLINK)
1.o: 1.c a.h b.h
    $(CC) -c  $(CFLAGS) 1.c
2.o: 2.c b.h c.h
    $(CC) -c  $(CFLAGS) 2.c
3.o: 3.c a.h b.h c.h
    $(CC) -c  $(CFLAGS) 3.c



Wykorzystanie makr ułatwia zmiany w pliku reguł. Jeśli chcemy skompilować program z nową opcją wystarczy dopisać ją do odpowiedniej linijki, a nie w każdej linijce zawierającej polecenia.

 

Źródło: http://www.antylameriada.net/pmakefile/