Trumpas „Makefiles“ atvirojo kodo programinės įrangos kūrimo su GNU Make įvadas


GNU Make yra kūrimo priemonė, kuri nustato tam tikros kodo bazės dalis, kurios turi būti perkompiliuotos, ir gali duoti komandas, kad būtų atliktos tos operacijos kodo bazėje. Šią konkretų make įrankį galima naudoti su bet kuria programavimo kalba, su sąlyga, kad jų kompiliavimas gali būti atliekamas iš apvalkalo, išduodant komandas.

Kad galėtume naudoti GNU Make, turime turėti tam tikrą taisyklių rinkinį, kuris apibrėžia skirtingų mūsų programos failų ryšį ir kiekvieno failo atnaujinimo komandas. Jie įrašomi į specialų failą, vadinamą makefile. Komanda „make“ naudoja „makefile“ duomenų bazę ir paskutinius failų modifikavimo laikus, kad nuspręstų kuriuos visi failai turi būti iš naujo sukompiliuoti.

Makefile turinys

Paprastai „makefiles“ yra 5 rūšių dalykų, būtent: numanomos taisyklės, aiškios taisyklės, kintamieji apibrėžimai , direktyvas ir komentarus.

  1. Aiškia taisyklė nurodo, kaip sukurti/perdaryti vieną ar daugiau failų (vadinamus taikiniais, bus paaiškinta vėliau) ir kada tai padaryti.
  2. Numanoma taisyklė nurodo, kaip sukurti/perdaryti vieną ar daugiau failų pagal jų pavadinimus. Jame aprašoma, kaip tikslinio failo pavadinimas yra susijęs su vienu failu, kurio pavadinimas panašus į taikinį.
  3. Kintamojo apibrėžimas yra eilutė, nurodanti kintamojo, kuris vėliau bus pakeistas, eilutės reikšmę.
  4. Direktyva yra instrukcija, skirta padaryti ką nors ypatingo skaitant makefile.
  5. Naudojamas simbolis „#“, reiškiantis komentaro pradžią makefailuose . Eilutė, prasidedanti raide „#“, tiesiog nepaisoma.

Makefilų struktūra

Informacija, nurodanti make, kaip perkompiliuoti sistemą, gaunama perskaičius duomenų bazę, vadinamą makefile. Paprastą makefile sudaro šios sintaksės taisyklės:

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

Taikinys apibrėžiamas kaip programos sugeneruotas išvesties failas. Tai taip pat gali būti apgaulingi taikiniai, kurie bus paaiškinti toliau. Tikslinių failų pavyzdžiai yra vykdomieji failai, objektų failai arba apgaulingi tikslai, pvz., clean, įdiegti, pašalinti ir kt.

Būtina sąlyga yra failas, kuris naudojamas kaip įvestis kuriant tikslinius failus.

Receptas yra veiksmas, kurį padaro atlieka kuriant tikslinį failą pagal būtinas sąlygas. Prieš kiekvieną receptą makefiles viduje būtina įdėti tabuliavimo simbolį, nebent nurodytume kintamąjį „.RECIPEPREFIX“, kad kaip priešdėlį apibrėžtume kitą simbolį į receptą.

Makefile pavyzdys

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

Anksčiau pateiktame pavyzdyje naudojome 4 C šaltinio failus ir du antraštės failus, kad sukurtume vykdomąjį galutinį. Čia kiekvienas „.o“ failas yra ir tikslas, ir būtina sąlyga makefile. Dabar pažvelkite į paskutinės paskirties pavadinimą švarus. Tai tik veiksmas, o ne tikslinis failas.

Kadangi paprastai mums to nereikia kompiliavimo metu, tai nėra parašyta kaip būtina sąlyga jokiose kitose taisyklėse. Taikiniai, kurie nesusiję su failais, o yra tik veiksmai, vadinami apgaulingais taikiniais. Jie neturės jokių prielaidų kaip kiti tiksliniai failai.

Kaip GNU Make apdoroja Makefile

Pagal numatytuosius nustatymus make prasideda nuo pirmosios paskirties vietos „makefile“ ir vadinama „ numatytasis tikslas“. Atsižvelgiant į mūsų pavyzdį, pirmasis tikslas yra galutinis. Kadangi jos būtinos sąlygos apima kitus objektų failus, juos reikia atnaujinti prieš sukuriant galutinį. Kiekviena iš šių būtinųjų sąlygų tvarkoma pagal savo taisykles.

Kompiliacija įvyksta, jei yra modifikuotų šaltinio failų arba antraštės failų arba jei objekto failas iš viso neegzistuoja. Perkompiliavus reikiamus objekto failus, make nusprendžia, ar iš naujo susieti galutinį , ar ne. Tai reikia padaryti, jei failo galutinis nėra arba jei kuris nors iš objektų failų yra naujesnis už jį.

Taigi, jei pakeisime failą inter.c, paleidus make jis iš naujo sukompiliuos šaltinio failą, kad būtų atnaujintas objekto failą inter.o ir susiekite galutinį.

Kintamųjų naudojimas Makefiles viduje

Mūsų pavyzdyje visus objektų failus turėjome du kartus įtraukti į galutinio taisyklę, kaip parodyta toliau.

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

Siekdami išvengti tokių pasikartojimų, galime įvesti kintamuosius, skirtus saugoti objektų failų, kurie naudojami makefile, sąrašą. Naudodami kintamąjį OBJ galime perrašyti pavyzdį makefile į panašų, kaip parodyta toliau.

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)

Šaltinio katalogo valymo taisyklės

Kaip matėme pavyzdyje makefile, galime apibrėžti taisykles, skirtasvalyti šaltinio katalogą, pašalindami nepageidaujamus objekto failus po kompiliavimo. Tarkime, kad turime tikslinį failą, pavadintą clean. Kaip galima priversti atskirti pirmiau minėtas dvi situacijas? Čia pateikiama apgaulingų taikinių koncepcija.

Netikras tikslas yra toks, kuris iš tikrųjų nėra failo pavadinimas, o tik recepto pavadinimas, kuris turi būti vykdomas, kai tik pateikiamas aiškus prašymas iš makefile<.. Viena iš pagrindinių priežasčių naudotiapgaulingą taikinį yra išvengti konflikto su to paties pavadinimo failu. Kita priežastis – pagerinti našumą.

Norėdami paaiškinti šį dalyką, atskleisiu vieną netikėtą posūkį. Clean receptas pagal numatytuosius nustatymus nebus vykdomas vykdant make. Vietoj to būtina iškviesti tą patį, išduodant komandą make clean.

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

Dabar pabandykite sukurti makefailus savo kodų bazei. Nedvejodami komentuokite čia su savo abejonėmis.