Programowanie Proceduralne
Transkrypt
Programowanie Proceduralne
Wstep ˛ Podstawy budowy Makefile Zmienne Programowanie Proceduralne Makefile Bożena Woźna-Szcześniak [email protected] Akademia im. Jana Długosza Wykład 14 Instrukcja warunkowa Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Co to jest Makefile Makefile jest plikiem reguł dla programu make. Wykorzystywany jest głównie do kompilacji, badź ˛ rekompilacji złożonych projektów, ale nie tylko. Makefile zawiera zbiór zależności miedzy ˛ plikami źródłowymi. Dzieki ˛ temu otrzymujemy możliwość kompilacji tylko poszczególnych plików, czyli tych które sie˛ zmieniły od czasu ostatniej kompilacji. Możliwość ta znacznie skraca czas generowania pliku wynikowego. W zależności od złożoności danego projektu, badź ˛ specyficznych wymagań, możemy posiadać dowolna˛ ilość takich plików. Ogólnie przyjeta ˛ zasada mówi o tym, aby główny plik posiadał jedna˛ z trzech nazw, GNUmakefile, makefile lub Makefile. Wstep ˛ Podstawy budowy Makefile Zmienne Szkielet budowy pliku Typowy plik Makefile zawiera pieć ˛ podstawowych elementów: reguły szczegółowe reguły ogólne definicje zmiennych dyrektywy komentarze Instrukcja warunkowa Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Szkielet budowy pliku Reguły szczegółowe Reguły szczegółowe opisuja˛ zasade˛ rekompilacji jednego badź ˛ wiecej ˛ plików, nazywanych celami. Do osiagni ˛ ecia ˛ celu potrzebujemy listy plików, tzw. zależności. Reguły szczegółowe dotycza˛ pliku wynikowego, jaki mamy otrzymać po zakończeniu działania polecenia make. Cel : zależności Instrukcje Instrukcje Cel to najcześciej ˛ nazwa pliku wynikowego, może to być też nazwa akcji np. clean. Zależności to nazwy plików wymagane do otrzymania pliku wynikowego. Instrukcje to blok instrukcji, po wykonaniu którego otrzymamy cel. Uwaga! Każda instrukcja rozpoczyna sie˛ od tabulatora. Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Szkielet budowy pliku Reguły ogólne Reguły ogólne mówia˛ o kompilacji plików tzw. pośrednich. Charakteryzuja˛ sie˛ tym, iż nazwa celu zazwyczaj jest identyczna z nazwa˛ pliku, który trzeba skompilować, aby otrzymać plik pośredni. Definicje zmiennych Definicje zmiennych znacznie upraszczaja˛ budowe˛ plików oraz wprowadzaja˛ wyższy poziom organizacji. Dyrektywy to nic innego jak polecenie, badź ˛ zbiór poleceń, które ma wykonać make w konkretnym przypadku. Każda linia zaczynajaca ˛ sie˛ od # jest traktowana jako komentarz. Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Oto bardzo prosty plik Makefile, którego zadaniem jest kompilacja program w jezyku ˛ C z podstawowymi opcjami kompilacji. Example program: plik.c gcc -Wall -std=c99 plik.c -o program program – to plik wynikowy jaki otrzymamy po kompilacji plik.c – to plik, którego potrzebujemy do procesu kompilacji instrukcja – uruchamia kompilator wraz z zadanymi opcjami kompilacji Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa main.c #include <stdio.h> #include "functions.h" int main(void){ print_hello(); printf("\n"); printf("The factorial of 5 is %d",factorial(5)); return 0; } hello.c #include <stdio.h> #include "functions.h" void print_hello(){ puts("Hello World!"); } Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa factorial.c #include "functions.h" int factorial(int n){ if(n!=1)return(n * factorial(n-1)); else return 1; } functions.h #ifndef FUNCTIONS_H #define FUNCTIONS_H void print_hello(); int factorial(int n); #endif Szkielet programu all: gcc main.c hello.c factorial.c -o hello Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Makefile all: hello hello: main.o factorial.o hello.o gcc main.o factorial.o hello.o -o hello main.o: main.c gcc -c main.c factorial.o: factorial.c gcc -c factorial.c hello.o: hello.c gcc -c hello.c clean: rm -rf *o hello Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Nadawanie wartości zmiennym Istnieje wiele możliwości nadawania zmiennym wartości. Pierwsza˛ polega na zazsosowaniu znaku „=”. Druga natomiast polega na zdefiniowaniu zmiennej w bloku define. Wartościa˛ zmiennej może być inna zmienna. Example pierwsza = $(druga) druga = $(trzecia) trzecia = zmienna all: ; echo $(pierwsza) Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Nadawanie wartości zmiennym Makefile # I am a comment, and I want to say that the variable CC # will be the compiler to use. CC=gcc CFLAGS = -c -Wall CFLAGS2 = -std=c99 -Wall all: hello hello: main.o factorial.o hello.o $(CC) $(CFLAGS2) main.o factorial.o hello.o -o hello main.o: main.c $(CC) $(CFLAGS) main.c factorial.o: factorial.c $(CC) $(CFLAGS) factorial.c hello.o: hello.c $(CC) $(CFLAGS) hello.c clean: rm -rf *o hello Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Nadawanie wartości zmiennym Przykład na nieskończona˛ petl ˛ e: ˛ CFLAGS = $(CFLAGS) -o Aby uniknać ˛ powyższego problemu można skorzystać z operatora „:=” zamiast „=”. Skutkuje to rozszerzeniem zmiennej o wartość zmiennej która˛ dodajemy. Działa to na zasadzie rozszerzenia tekstowego. Przykład: Example x:= nowy y:= $x tekst x:= inny tekst Powyższy zapis jest równoważny z: Example y= nowy tekst x:= inny tekst Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Nadanie wartości niezainicjalizowanej zmiennej Sa˛ sytuacje, w których chcemy nadać wartość zmiennej, tylko jeśli ta jeszcze nie została zainicjalizowana. Wtedy, zamiast zwykłego operatora przypisania ‘=’ używamy ‘?=’. Wykorzystanie tego operatora gwarantuje, iż wartość zmiennej nie zostanie nadpisana. Przykładowo, instrukcja: Example zmienna ?= object.c spowoduje przypisanie do zmiennej zmienna wartości object.c w przypadku jeśli zmienna nie jest zainicjalizowana. Jeśli natomiast inicjalizacja nastapiła ˛ gdzieś we wcześniejszej cz˛eści pliku Makefile, przypisanie zostanie pominiete. ˛ Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Dodawanie tekstu do zmiennej Operator += przydatny jest np. w przypadku kiedy do istniejacej ˛ listy plików chcemy dodać jeszcze jeden element. Przykład: Example objects = plik1.c plik2.c plik3.c objects += plik4.c Po wykonaniu tych instrukcji zmienna objects bedzie ˛ zawierała nastepuj ˛ ace ˛ elementy: plik1.c plik2.c plik3.c plik4.c. Użycie operatora += jest równoważne zapisowi: Example objects = plik1.c plik2.c plik3.c objects := $(objects) plik4.c Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Poniższy przykład instrukcji warunkowej wskazuje poleceniu make odpowiedni zestaw bibliotek w zależności od tego jak ustawiona jest zmienna CC. Jeśli zmienna CC=gcc, to do polecenia kompilacji zostanie dodany przełacznik ˛ -lgnu. Example libs_for_gcc = -lgnu normal_libs = foo: $(objects) ifeq ($(CC),gcc) $(CC) -o foo $(objects) $(libs_for_gcc) else $(CC) -o foo $(objects) $(normal_libs) endif Wstep ˛ Podstawy budowy Makefile Zmienne Instrukcja warunkowa Dyrektywa ifeq zawiera oraz odpowiada za porównanie warunku. Argumenty oddzielone sa˛ przecinkiem oraz otoczone nawiasami okragłymi. ˛ Kolejna linia po ifeq zostanie wykonana tylko w przypadku, gdy obydwa argumenty porównania sa˛ równe. Dyrektywa else jest opcjonalna i tylko wykonywana w przypadku kiedy warunek w dyrektywie Ifeq nie jest prawdziwy. Dyrektywa endif stosowana jest do wyraźnego zakończenia sekcji warunkowej – każdy blok warunkowy musi być zakończony ta˛ dyrektywa. ˛