Kratak uvod u 'Makefiles' u razvoju softvera otvorenog koda uz GNU Make


GNU Make je razvojni program koji određuje dijelove određene baze koda koji se trebaju ponovo kompajlirati i može izdati naredbe za izvođenje tih operacija na bazi koda. Ovaj konkretan make uslužni program može se koristiti sa bilo kojim programskim jezikom pod uslovom da se njihova kompilacija može obaviti iz ljuske izdavanjem naredbi.

Da bismo koristili GNU Make, moramo imati neki skup pravila koja definiraju odnos između različitih datoteka u našem programu i naredbe za ažuriranje svake datoteke. Oni su upisani u posebnu datoteku pod nazivom „makefile“. Komanda 'make' koristi bazu podataka 'makefile' i vrijeme posljednje izmjene fajlova za odlučivanje koje sve datoteke treba ponovo kompajlirati.

Sadržaj Makefile-a

Općenito 'makefiles' sadrži 5 vrsta stvari i to: implicitna pravila, eksplicitna pravila, definicije varijabli , smjernice i komentari.

  1. Izričito pravilo specificira kako napraviti/prepraviti jedan ili više fajlova (koji se nazivaju ciljevima, biće objašnjeno kasnije) i kada treba učiniti isto.
  2. Implicitno pravilo određuje kako napraviti/prepraviti jednu ili više datoteka na osnovu njihovih imena. Opisuje kako je ime ciljne datoteke povezano s jednom datotekom s imenom sličnim ciljnom.
  3. Definicija varijable je linija koja specificira vrijednost niza za varijablu koja će se kasnije zamijeniti.
  4. Direktiva je instrukcija za make da uradi nešto posebno dok čita makefile.
  5. Koristi se simbol '#' koji predstavlja početak komentara unutar makefiles . Red koji počinje sa '#' jednostavno se zanemaruje.

Struktura Makefiles-a

Informacije koje govore make kako da ponovo kompajliraju sistem dolaze iz čitanja baze podataka koja se zove makefile. Jednostavan makefile će se sastojati od pravila sljedeće sintakse:

target ... : prerequisites ... 
	recipe 
... 
...

Cilj je definiran kao izlazna datoteka koju generira program. To mogu biti i lažne mete, što će biti objašnjeno u nastavku. Primjeri ciljnih datoteka uključuju izvršne, objektne datoteke ili lažne mete kao što su clean, instaliraj, deinstaliraj itd.

Preduslov je datoteka koja se koristi kao ulaz za kreiranje ciljnih datoteka.

recept je radnja koju make izvodi za kreiranje ciljne datoteke na osnovu preduvjeta. Potrebno je staviti znak tab ispred svakog recepta unutar makefiles osim ako ne navedemo varijablu '.RECIPEPREFIX' da definiramo neki drugi znak kao prefiks po receptu.

Uzorak Makefile-a

final: main.o end.o inter.o start.o
	gcc -o final main.o end.o inter.o start.o
main.o: main.c global.h
	gcc -c main.c
end.o: end.c local.h global.h
	gcc -c end.c
inter.o: inter.c global.h
	gcc -c inter.c
start.o: start.c global.h
	gcc -c start.c
clean:
	rm -f main.o end.o inter.o start.o

U gornjem primjeru koristili smo 4 C izvorne datoteke i dvije datoteke zaglavlja za kreiranje izvršnog final. Ovdje je svaka datoteka „.o” i cilj i preduvjet unutar makefile. Sada pogledajte naziv posljednjeg cilja clean. To je samo radnja, a ne ciljna datoteka.

Pošto nam to obično nije potrebno tokom kompilacije, to nije napisano kao preduvjet ni u jednom drugom pravilu. Ciljevi koji se ne odnose na datoteke već su samo akcije nazivaju se lažni ciljevi. Oni neće imati nikakve preduvjete kao druge ciljne datoteke.

Kako GNU Make obrađuje Makefile

Prema zadanim postavkama make počinje s prvim ciljem u 'makefile' i naziva se ' zadani cilj'. Uzimajući u obzir naš primjer, imamo final kao našu prvu metu. Budući da njegovi preduslovi uključuju druge objektne datoteke, one se moraju ažurirati prije kreiranja konačnog. Svaki od ovih preduvjeta se obrađuje prema vlastitim pravilima.

Do ponovne kompilacije dolazi ako su napravljene modifikacije izvornih datoteka ili fajlova zaglavlja ili akoobjektni fajl uopće ne postoji. Nakon ponovnog kompajliranja potrebnih objektnih datoteka, make odlučuje hoće li ponovo povezati final ili ne. Ovo se mora uraditi ako datoteka final ne postoji, ili ako je bilo koja od objektnih datoteka novija od nje.

Dakle, ako promijenimo datoteku inter.c, tada će se prilikom pokretanja make ponovo kompajlirati izvorni fajl za ažuriranje objektni fajl inter.o, a zatim vezu final.

Korištenje varijabli unutar Makefiles-a

U našem primjeru, morali smo dva puta navesti sve objektne datoteke u pravilu za final kao što je prikazano ispod.

final: main.o end.o inter.o start.o
	gcc -o final main.o end.o inter.o start.o

Da bismo izbjegli takva dupliciranja, možemo uvesti varijable za pohranjivanje liste objektnih datoteka koje se koriste unutar makefile. Korištenjem varijable OBJ možemo prepisati uzorak makefile na sličan koji je prikazan ispod.

OBJ = main.o end.o inter.o start.o
final: $(OBJ)
	gcc -o final $(OBJ)
main.o: main.c global.h
	gcc -c main.c
end.o: end.c local.h global.h
	gcc -c end.c
inter.o: inter.c global.h
	gcc -c inter.c
start.o: start.c global.h
	gcc -c start.c
clean:
	rm -f $(OBJ)

Pravila za čišćenje izvornog direktorija

Kao što smo vidjeli u primjeru makefile, možemo definirati pravila začišćenje izvornog direktorija tako što ćemo ukloniti neželjene objektne datoteke nakon kompilacije. Pretpostavimo da slučajno imamo ciljnu datoteku pod nazivom clean. Kako natjerati da razlikujemo gornje dvije situacije? Ovdje dolazi koncept lažnih meta.

Lažni cilj je onaj koji zapravo nije naziv datoteke, već je to samo ime za recept koji se izvršava svaki put kada se iz makefile-a uputi eksplicitni zahtjev<. Jedan od glavnih razloga za korištenjelažnog cilja je izbjegavanje sukoba s fajlom istog imena. Drugi razlog je poboljšanje performansi.

Da bih objasnio ovu stvar, otkriću jedan neočekivani obrt. Recept za čišćenje se neće izvršavati prema zadanim postavkama pri pokretanju make. Umjesto toga, potrebno je isto pozvati izdavanjem naredbe make clean.

.PHONY: clean
clean:
	rm -f $(OBJ)

Sada pokušajte kreirati makefile za svoju bazu kodova. Slobodno komentirajte ovdje sa svojim nedoumicama.