Kratki uvod u Makefile u razvoju softvera otvorenog koda s GNU Make


GNU Make je razvojni program koji određuje dijelove određene baze koda koji se trebaju prekompajlirati i može izdavati naredbe za izvođenje tih operacija na bazi koda. Ovaj konkretni uslužni program make može se koristiti s bilo kojim programskim jezikom pod uvjetom da se njihova kompilacija može izvršiti iz ljuske izdavanjem naredbi.

Da bismo mogli koristiti GNU Make, moramo imati određeni skup pravila koji definiraju odnos između različitih datoteka u našem programu i naredbe za ažuriranje svake datoteke. Oni se zapisuju u posebnu datoteku nazvanu ‘ makefile ’. Naredba ‘ make ’ koristi bazu podataka ‘ makefile ’ i posljednja vremena izmjene datoteka kako bi odlučila koje će datoteke ponovno prevesti.

Sadržaj Makefile-a

Općenito ‘ makefiles ’ sadrže 5 vrsta stvari, naime: implicitna pravila, eksplicitna pravila, definicije varijabli, direktive i komentari.

  1. Izričito pravilo navodi kako napraviti/preraditi jednu ili više datoteka (nazvane ciljevi, bit će objašnjeno kasnije) i kada to učiniti.
  2. Implicitno pravilo određuje kako napraviti/preraditi jednu ili više datoteka na temelju njihovih imena. Opisuje kako je ime ciljne datoteke povezano s jednom datotekom s imenom sličnim ciljnoj.
  3. Definicija varijable linija je koja određuje vrijednost niza za varijablu koja će se kasnije zamijeniti.
  4. Direktiva je uputa za make da učini nešto posebno tijekom čitanja make datoteke.
  5. Upotrijebljen je simbol „#“ predstavlja početak komentara unutar make-fajlova . Redak koji započinje s "#" jednostavno se zanemaruje.

Informacije koje govore make kako rekompajlirati sustav potječu od čitanja baze podataka koja se naziva makefile . Jednostavna makefile volja sastoji se od pravila sljedeće sintakse:

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

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

Preduvjet je datoteka koja se koristi kao ulaz za stvaranje ciljnih datoteka.

Recept je radnja koju make izvodi za stvaranje ciljne datoteke na temelju preduvjeta. Znak kartice potrebno je staviti ispred svakog recepta unutar make datoteka osim ako ne navedemo varijablu ‘.RECIPEPREFIX’ da bismo definirali neki drugi znak kao prefiks receptu.

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 stvaranje izvršne final . Ovdje je svaka datoteka „.o“ i cilj i preduvjet unutar makefile . Sada pogledajte prezime zadanog cilja čist . To je samo akcija, a ne ciljana datoteka.

Budući da nam to obično nije potrebno tijekom kompilacije, to nije zapisano kao preduvjet ni u jednom drugom pravilu. Ciljevi koji se ne odnose na datoteke, već su samo akcije, nazivaju se lažnim ciljevima. Neće imati preduvjete kao ostale ciljne datoteke.

Prema zadanim postavkama make započinje s prvim ciljem u ‘ datoteci izrade ’ i naziva se ‘ zadani cilj ’. Uzimajući u obzir naš primjer, kao prvo ciljanje imamo final . Budući da njegovi preduvjeti uključuju i druge objektne datoteke, one se trebaju ažurirati prije stvaranja final . Svaki od ovih preduvjeta obrađuje se prema vlastitim pravilima.

Do ponovne kompilacije dolazi ako postoje promjene u izvornim datotekama ili datotekama zaglavlja ili ako objektna datoteka uopće ne postoji. Nakon ponovnog prevođenja potrebnih objektnih datoteka, make odlučuje hoće li se ponovno povezati final ili ne. To se mora učiniti ako datoteka final ne postoji ili ako je bilo koja od objektnih datoteka novija od nje.

Stoga, ako promijenimo datoteku inter.c , tada će se na pokretanju make ponovno sastaviti izvornu datoteku kako bi ažurirala objektnu datoteku inter.o i zatim link final .

U našem primjeru morali smo dvaput navesti sve datoteke objekata u pravilu za final kao što je prikazano u nastavku.

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 spremanje popisa objektnih datoteka koje se koriste unutar makefile . Korištenjem varijable OBJ možemo prepisati uzorak makefile na sličan prikazan u nastavku.

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)

Kao što smo vidjeli u primjeru makefile , možemo definirati pravila za čišćenje izvornog direktorija uklanjanjem neželjenih objektnih datoteka nakon kompilacije. Pretpostavimo da slučajno imamo ciljanu datoteku koja se zove čista . Kako natjerati razlikovanje gornje dvije situacije? Ovdje dolazi koncept lažnih meta.

Lažni cilj je onaj koji zapravo nije naziv datoteke, već je to samo naziv za recept koji se izvršava kad god se iz makefile uputi izričit zahtjev. Jedan od glavnih razloga za upotrebu lažnih ciljeva je izbjegavanje sukoba s istoimenom datotekom. Drugi razlog je poboljšanje performansi.

Da bih objasnio ovu stvar, otkrit ću jedan neočekivani obrat. Recept za čist neće se izvršiti prema zadanim postavkama pri pokretanju make . Umjesto toga, potrebno je istu pozvati izdavanjem naredbe make clean .

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

Sada pokušajte stvoriti datoteke datoteka za vlastitu bazu koda. Slobodno ovdje komentirajte sa svojim sumnjama.