Het programma make wordt als sinds eind jaren 70 gebruikt en is voor distributie, bouwen en installeren van UNIX-programma's nog steeds een zeer veel gebruikte manier. Dan zal het wel iets hebben dat het aantrekkelijk maakt, zou je zeggen.
Redenen om make te gebruiken:
- Je kunt meerdere targets aangeven en die kunnen overlappende sets bron-files gebruiken, zelfs uit een en dezelfde directory
- Bij bv. C++: alleen de bronnen die gecompileerd moeten worden omdat ze veranderd zijn, worden opnieuw gecompileerd
- make kan veel meer dan een programma bouwen. Denk aan installeren van een project of het uitvoeren van andere programma's
Een Makefile bestaat uit een of meer 'targets'. Een target is meestal een file die gemaakt moet worden. Laten we eenvoudig beginnen en wat met text-files doen. We gaan eerst een file 'target' maken uit een file 'source'. Je mag ze ook 'target.txt' en 'source.txt' noemen.
Verder moet make weten op welke manier source bewerkt moet worden om target op te leveren, ofwel: welk programma kan door make aangeroepen worden om dat te doen ? Make heeft zelf namelijk geen idee wat C++ is of JPG of AIFF. Make is ook geen compiler. Het heeft zelfs geen ingebouwde compiler. Make houdt slechts bij wat er gebouwd moet worden en welke programma's daarvoor gebruikt moeten worden. Daar is het goed in en het gebruikt andere programma's die goed zijn in andere dingen.Voor elke target in de Makefile wordt aangegeven van welke bron of bronnen het afgeleid wordt en welke programma's uitgevoerd moeten worden om het target te bouwen.
In dit voorbeeld maken we target uit source door een kopie te maken:
target: source
cp source target
De blauwe balk geeft aan dat je daar een TAB-teken moet zetten, dus niet een rijtje spaties. Dat is om aan te geven dat op die regel een commando staat.
Bij uitvoeren probeert make de eerste target te maken. Als eerste wordt daarvoor de hele afhankelijkheidsstructuur in kaart gebracht. Het eerste target kan namelijk afhangen van andere targets die eerst gemaakt moeten en die kunnen op hun beurt weer afhangen van andere targets die eerst gemaakt moeten worden.
Na het construeren van de graph die alle afhankelijkheden (dependencies) duidelijk maakt gaat make vanaf het onderste niveau alle afhankelijkheden oplossen en target voor target construeren tot alle targets gerealiseerd zijn.
Om te weten of een target "gerealiseerd" is kijkt make naar de timestamps van de files. Als een bron nieuwer is dan een target die van die bron afhangt, dan moet er iets gebeuren om de target opnieuw te maken uit die bron. Daarna is de target nieuwer dan de bron en als je tussentijds geen bronnen van die target verandert zal make de eerstvolgende keer besluiten dat -omdat de target nieuwer is dan al zijn bronnen- er niks hoeft te gebeuren.
Om dit te demonstreren breiden we de bovenstaande Makefile uit. Maak ook twee kopietjes van source en noem die source1 en source2.
all: target1 target2
target1: source1
cp source1 target1
target2: source2
cp source2 target2
N.B.: In plaats van
all
zie je ook wel .PHONY
omdat dat impliceert dat het niet om een file gaat.
Je kunt aan make ook vertellen welke target gebouwd moet worden. Probeer dat eens uit door alle targets te verwijderen en dan te typen "make target2"
Stel dat target1 afhankelijk is van target 2. Dan ziet de Makefile er zo uit:
all: target1 target1: source1 target2 cp source1 target1 target2: source2 cp source2 target2