Spis treści

Program make – kilka zaawansowanych technik

W tym artykule pokażę kilka bardziej zaawansowanych, a często wykorzystywanych możliwości programu. To oczywiście wciąż niewielka część jego wszystkich funkcji, po poznaniu podstaw warto sięgnąć do obszernej instrukcji obsługi make.

Zmienne automatyczne

Kolejnym etapem ułatwiania sobie programistycznego życia są zmienne automatyczne. Jak sama nazwa wskazuje, są to zmienne, których wartość jest ustalana automatycznie przez program make. Nazwa zmiennej automatycznej to jeden znak. Używając jej nie musimy tego znaku umieszczać w nawiasach. W praktyce początkującego programisty przydają się trzy zmienne automatyczne:

Przykładowo, jeżeli mamy taką oto regułę:

main.o: main.c main.h funkcje.h

to zmienne będą zawierały odpowiednio:

$@ = main.o
$< = main.c
$^ = main.c main.h funkcje.h

Ponieważ zmienne automatyczne zawierają elementy reguły, to oczywiście ich wartość jest ustalana dla każdej reguły od nowa. Można więc je traktować jako „zmienne lokalne” dla reguły, podczas gdy zwykłe zmienne z nazwą są „globalne”.

Popatrzmy teraz jak nasz przykład dwustopniowej kompilacji może zostać zapisany z użyciem zmiennych, zwykłych i automatycznych:

CC = gcc
CFLAGS = -c -O2 -nostdlib
LD = gcc
LDFLAGS = -s -O2 -nostdlib

ProgramX: main.o funkcje.o
    $(LD) $(LDFLAGS) -o $@ $^

main.o: main.c main.h funkcje.h
    $(CC) $(CFLAGS) -o $@ $<

funkcje.o: funkcje.c funkcje.h
    $(CC) $(CFLAGS) -o $@ $<

Dzięki rozdzieleniu opcji kompilacji i opcji linkowania mogliśmy opcję −c (kompiluj do obiektu z kodem) oraz −s (usuń tablicę symboli) włączyć do odpowiednich zmiennych. W tym momencie widzimy, że polecenie reguły drugiej i trzeciej jest identyczne. Autorzy make nie byliby sobą, gdyby nie wykorzystali tej okazji do dalszego uproszczenia skryptu, o czym poniżej.

Reguły z wzorcami nazw

W praktyce pisząc większy program, często mamy do czynienia z sytuacją, gdy polecenia reguł dla wielu plików – dzięki użyciu zmiennych automatycznych – są identyczne. Możemy wtedy te polecenia zgrupować tworząc pseudoregułę używającą wzorca nazwy. W przykładzie mamy identyczne polecenia w dwóch różnych regułach, które można zgrupować następująco:

main.o: main.c main.h funkcje.h
funkcje.o: funkcje.c funkcje.h

%.o: %.c
    $(CC) $(CFLAGS) -o $@ $<

Zwróćmy uwagę na fakt, że nastąpiło rozdzielenie zależności (które są inne dla każdego pliku) i poleceń (które są takie same dla wszystkich plików). Znak procenta zastępuje tu dowolny ciąg znaków. Nazwa reguły z wzorcem musi zawierać dokładnie jeden znak procenta.

ciąg dalszy nastąpi

Wykonywanie makefiles w podkatalogach

Automatyczne generowanie zależności dla reguł