<H1>Maak je werk met make!</H1>

<H4>ArticleCategory: []</H4>
Software Development

<H4>AuthorImage:[Hier komt een kleine foto van jou]</H4>
<IMG src="../../common/images/WilbertBerendsen.png" width="108" height="118" alt="[Wilbert Berendsen]">

<H4>TranslationInfo:[Info over schrijver(s) en vertaler(s)]</H4>
<P>original in nl <A HREF="mailto:wbsoft@xs4all.nl">Wilbert Berendsen</A></P>


<H4>AboutTheAuthor:[een korte biografie over de auteur]</H4>
<P>Wilbert Berendsen is professioneel musicus en Linux enthousiast.  Hij
heeft ooit eens intensief Z80 assembly gehackt en gebruikt nu Linux voor
al zijn productiewerk. Voor de lol schrijft hij inleidende artikelen en
hij onderhoudt een kleine website op 
<a href="http://www.xs4all.nl/~wbsoft/">http://www.xs4all.nl/~wbsoft/</a>. 
Viva open source!</P>

<H4>Abstract:[een kleine samenvatting/beschrijving van het artikel]</H4>
Dit artikel over make laat zien, hoe make werkt en toont aan dat het voor meer dan alleen
software ontwikkeling kan ingezet worden.

<H4>ArticleIllustration:[Titel-illustratie van het Artikel]</H4>
<IMG src="../../common/images/illustration181.gif" width="238" height="63" hspace="" alt="[Illustratie]">

<H4>ArticleBody:[Het eigenlijke artikel: zet hier teks en HTML codes]</H4>

<h2>Inleiding</h2>

<p>  Bijna iedereen die Linux gebruikt, is wel eens met het programma make in
  aanraking gekomen.  Het doet zijn werk wanneer we een programma of de kernel
  willen bouwen vanaf de broncode, wanneer we pakketten willen installeren enz.
  'Make' is dus een belangrijke tool voor het ontwikkelen van software.

  Maar make kan nog veel meer!
  
<P>  In dit document zullen we zien dat make een krachtige hulp kan zijn bij
  dagelijks werk zoals het schrijven van artikelen, boeken of het samenstellen
  van een leuke website.

  Terloops zullen veel andere 'unix handigheidjes' de revue passeren.
  
  Aan het slot van dit verhaal nog enkele tips over hoe je make verder nog
  kan gebruiken. Let wel: we hebben het af en toe over Linux, maar in feite kun
  je make op ieder besturingssysteem gebruiken.

<h2>Voorbeeld: Een website maken</h2>

  We willen een website gaan maken, die door verschillende mensen wordt gebouwd.
  Jan zorgt voor een tweetal pagina's en houdt die ook bij, en Piet maakt de
  layout.
  
<p>  We hebben een simpel systeem nodig om de layout en de inhoud van elkaar te
  scheiden.  Een krachtige manier is natuurlijk: de inhoud uit een database
  lezen, telkens als de pagina wordt opgevraagd. Dit is hoe bijvoorbeeld PHP en
  Microsoft Active Server Pages werken.  Maar, we hebben slechts de
  mogelijkheid om simpele HTML (HyperText Markup Language) op te slaan. 
  Bovendien verandert de inhoud in ons simpele geval niet zo vaak dat een
  database effici�nt is.

<p>  Wij gaan dus met een paar simpele commando's een site in elkaar smeden.

<ul>  
<li>Opzet van ons voorbeeld<br>

  Jan heeft enkele artikelen in zijn homedirectory staan: <i>aanbod.html</i> en
  <i>index.html</i>. Beide staan de map <i>/home/jan/Docs/website/</i>. In
  <i>index.html</i> staan wat nieuwtjes en een welkom-bericht, in
  <i>aanbod.html</i> staat het aanbod aan weet-ik-wat aardappelen van die week.

  Piet zorgt voor de layout en bouwt de website. Uiteindelijk worden de pagina's
  in een directory <i>/home/piet/public_html</i> geplaatst.

<li> Een 'template'<br>

  Piet heeft Jan meegedeeld dat hij zijn pagina's gewoon als simpele HTML mag
  schrijven, en hij zorgt er zelf voor dat Jan's pagina's in een passende
  layout worden gegoten.
</ul>

<p>  Piet stopt bijvoorbeeld de kop van de site in <i>header.html</i> en de voet in
  <i>footer.html</i>. <i>header.html</i> kan er zo uitzien:

<pre>
&lt;html>&lt;!-- de header -->
&lt;head>
&lt;title>Piet en Jan producties&lt;/title>
&lt;/head>
&lt;body bgcolor="white">
&lt;table border="0" width="100%">&lt;tr>
&lt;td bgcolor="#c040ff" valign="top">
Dit is onze website&lt;br>
Hier staat nog wat onzin.&lt;br>
We zijn heel interactief&lt;br>
dus dit is ons telefoonnummer:&lt;br>
&lt;b>0123-456789&lt;/b>
&lt;/td>&lt;td valign="top">
&lt;!-- hier de inhoud -->
</pre>

  En dit is <i>footer.html</i>:
  
<pre>
&lt;!-- de footer -->
&lt;/td>&lt;/tr>&lt;/table>
&lt;/body>&lt;/html>
</pre>

  De unix commando's om dan van Jan's index.html de uiteindelijke pagina te
  bouwen zijn bijvoorbeeld:

<pre>
cat header.html  /home/jan/Docs/website/index.html
echo -n '&lt;hr>Laatst gewijzigd: '
date '+%A %e %B'
cat footer.html
</pre>

  Zie de manual pages van deze commando's. De file die deze commando's tot
  resultaat hebben wordt dus naar de standaard uitvoer geleid, en die kunnen we
  simpel vangen in een file:

<pre>
{
  cat header.html  /home/jan/Docs/website/index.html
  echo -n '&lt;hr>Laatst gewijzigd: '
  date '+%A %e %B'
  cat footer.html
} > /home/piet/public_html/index.html
</pre>

  Hetzelfde kan ook met de andere file, <i>aanbod.html</i>. Hiermee hebben we in
  feite een klein script gebouwd, dat in staat is de website voor ons te maken.

<p>  Echter, telkens dit commando invoeren is natuurlijk ondoenlijk.  We kunnen er
  natuurlijk een uitvoerbaar shellscript van maken en dit telkens runnen als
  Jan zijn index heeft bijgewerkt. Maar ook als Piet besluit de header of footer
  aan te passen moet dit script gerund worden! En als Jan op de een of andere
  dag niets heeft veranderd hoeft het script ook niet te draaien.  En we draaien
  niet voor niets Linux, dus we willen het slimmer kunnen doen (lees: vanzelf)!
  
<p>  Welnu, hier is het, dat make om de hoek komt kijken.
  
<h2>Eerste ontmoeting met make</h2>

  De info-manual van GNU make is een fantastisch document. Echter het richt
  zich van meet af aan op gebruik in een programmeeromgeving. Vandaar dat ik
  hier een poging doe, de functie van make wat algemener aan te geven:

<pre>
   [ ] make bepaalt op grond van de &lt;time-stamp&gt; (de datum dus) van een
   doel-bestand, en de &lt;time-stamps&gt; van bron-bestanden of een reeks commando's
   uitgevoerd moet worden ja of nee.
</pre>

  Met andere woorden: Als ��n van de bron-bestanden, nodig voor het maken van
  het doel-bestand, &lt;&lt;nieuwer&gt;&gt; is dan het doel-bestand, dan wordt een bepaalde
  reeks commando's uitgevoerd. Die commando's zullen dan het doel-bestand vernieuwen.
  
<p>  De doel-file is een `<i>target</i>', de bron-files zijn `<i>prerequisites</i>' (eerste
  vereisten). De commando's worden dus uitgevoerd als een van de
  `prerequisites' nieuwer is dan de `target' (of als de target niet bestaat).
  Zijn alle prerequisites ouder dan of even oud als de target, dan worden de
  commando's niet uitgevoerd, en beschouwt make de target als up-to-date.

<P>  In de directory waarin we werken moet een bestand met de naam <i>Makefile</i>
  worden aangemaakt, dat deze informatie voor make bevat. Als dat eenmaal
  gebeurd is hoeven we nog slechts `make' in te typen en de commando's
  nodig voor het bijwerken van de targets worden automatisch uitgevoerd.

<p>  Make wordt aangeroepen met

<pre>
make <target> ?<target>? ....
</pre>

<p>  waarbij de target optioneel is (bij weglating wordt de eerste target in de
  Makefile gebruikt). Make kijkt altijd in de huidige directory voor de
  Makefile. Meer dan ��n target kan tegelijk worden opgegeven.

<h2>Syntax van de Makefile</h2>

  De Makefile kan gewoon met een editor worden gemaakt en ziet er alsvolgt uit:

<pre>
# Dit is een voorbeeld van een Makefile.
# Commentaar mag achter hekjes (#) staan.

target: prerequisites
	commando
        
target: prerequisites
	commando  
        
# enz enz.
</pre>

  De target staat dus steeds vooraan, gevolgd door een dubbele punt (:) en de
  prerequisites die nodig zijn. Als er veel prerequisites zijn, kun je de regel
  eindigen met een backslash (\) en op de volgende regel verder gaan.

<p>  Op de volgende regel(s) staan ��n of meer commando's. Elke regel wordt door
  make gezien als een afzonderlijk commando. Wil je meerdere regels in ��n
  commando hebben, dan moet je de regels weer met een backslash (\) eindigen.
  Make zal de commando's dan verbinden door ze als het ware op 1 regel te
  zetten. Daarom moeten we in dat geval de commando's ook scheiden met een
  puntkomma (;), voor de shell die ze uitvoert.

<p><b>Let op:</b> de commando's moeten worden ingesprongen met een <b>TAB</b>, dus niet 8
  spaties!

<p>  Make leest de Makefile, en bepaalt voor elke gevraagde target (beginnend bij
  de eerste) of de commando's moeten worden uitgevoerd. Elke target, samen met
  zijn prerequisites en commando's wordt een `rule' (regel) genoemd.

<p>  Wanneer make zonder argumenten wordt aangeroepen, zal hij enkel de eerst
  gevonden target uitvoeren.

<h2>Een Makefile voor ons voorbeeld</h2>

  Voor ons voorbeeld zou de Makefile er dus zo uit kunnen zien:
  
<pre>
# Deze Makefile bouwt de website van Piet en Jan, de aardappeleters.

all: /home/piet/public_html/index.html /home/piet/public_html/aanbod.html

/home/piet/public_html/index.html:  header.html footer.html \
                                    /home/jan/Docs/website/index.html
	{ \
          cat header.html  /home/jan/Docs/website/index.html ;\
          echo -n '&lt;hr>Laatst gewijzigd: '                   ;\
          date '+%A %e %B'                                   ;\
          cat footer.html                                    ;\
        } > /home/piet/public_html/index.html

/home/piet/public_html/aanbod.html:  header.html footer.html \
                                    /home/jan/Docs/website/aanbod.html
	{ \
          cat header.html  /home/jan/Docs/website/index.html ;\
          echo -n '&lt;hr>Laatst gewijzigd: '                   ;\
          date '+%A %e %B'                                   ;\
          cat footer.html                                    ;\
        } > /home/piet/public_html/aanbod.html

# the end
</pre>

<p>  We hebben nu drie targets, `all' en de bestanden <i>index.html</i> en
  <i>aanbod.html</i> van de website. De target `all' hebben we enkel gemaakt zodat hij
  de beide andere als prerequisite kan hebben. Die worden dus beide getest. Omdat
  `all' zelf niet de naam van een bestaande file is, wordt de target `all' dus
  altijd uitgevoerd. (Later zullen we een elegantere manier zien waarmee
  targets die geen file zijn kunnen worden gedefini�erd.)

<p>  Als de header of footer werden gewijzigd, worden beide pagina's opnieuw
  gemaakt. Wijzigt Jan een van de pagina's, dan wordt alleen die pagina opnieuw
  gemaakt. Simpelweg `make' intypen is nu voldoende!

<p>  Het nadeel is natuurlijk, dat de Makefile nu niet bepaald overzichtelijk is.
  Gelukkig zijn er veel manieren om alles simpeler te maken!
  
<h2>Stroomlijnen van de Makefile</h2>

<h3>Variabelen</h3>

  Dankzij variabelen kan de Makefile een stuk overzichtelijker worden gemaakt.
  Variabelen worden alsvolgt in de Makefile gedefinieerd: 
  
<pre>
variabele = waarde
</pre>

  We refereren naar een variabele met de uitdrukking <i>$(variabele)</i>. Als we
  hiermee de Makefile bewerken, ziet het er al vriendelijker uit:

<pre>
# Deze Makefile bouwt de website van Piet en Jan, de aardappeleters.

# Directory waar de website staat:
TARGETDIR = /home/piet/public_html

# Jan's directory:
JANSDIR = /home/jan/Docs/website

# Bestanden nodig voor de layout:
LAYOUT = header.html footer.html

all: $(TARGETDIR)/index.html $(TARGETDIR)/aanbod.html

$(TARGETDIR)/index.html:  $(LAYOUT) $(JANSDIR)/index.html
	{ \
          cat header.html $(JANSDIR)/index.html     ;\
          echo -n '&lt;hr>Laatst gewijzigd: '          ;\
          date '+%A %e %B'                          ;\
          cat footer.html                           ;\
        } > $(TARGETDIR)/index.html

$(TARGETDIR)/aanbod.html:  $(LAYOUT) $(JANSDIR)/aanbod.html
	{ \
          cat header.html  $(JANSDIR)/index.html    ;\
          echo -n '&lt;hr>Laatst gewijzigd: '          ;\
          date '+%A %e %B'                          ;\
          cat footer.html                           ;\
        } > $(TARGETDIR)/aanbod.html

# the end
</pre>

  Een goede gewoonte is het om hoofdletters te gebruiken voor variabelen. Het is
  nu ook veel eenvoudiger om bijvoorbeeld de doel-directory snel te wijzigen.

<p>  Je kunt als je dat wilt voor elk document een andere manier defini�ren
  waarmee het in de goede layout wordt gezet. Maar wat als we nu vele
  documenten hebben die allemaal in dezelfde layout moeten? De Makefile zou wel
  erg lang worden, terwijl er veel herhalingen in zitten.
  
  Ook dit kunnen we weer vereenvoudigen!
  
<h3>Pattern Rules</h3>

  `Pattern Rules' maken het ons mogelijk om eenzelfde commandoreeks los te
  laten op allerlei targets.

<p>  Bij het gebruik van pattern rules verandert de syntax van een regel; er wordt
  een extra patroon veld ingevoegd:
 
<pre>
meerdere targets: patroon : prerequisite prerequisite ...
	commando
</pre>

  Het patroon is een uitdrukking die op alle targets zou moeten kunnen passen,
  waarbij een procentteken wordt gebruikt om variabele gedeelten van een
  target-naam te vatten.

<p>  Een voorbeeld:

<pre>
/home/bla/target1.html /home/bla/target2.html: /home/bla/% : %
	commando's
</pre>

  Als make dit leest, wordt het ge�xpandeerd tot 2 regels, waarbij het
  patroon bepaalt welk gedeelte van de target-naam in het procentteken wordt
  gevat.
  
<p>  In het prerequisites-veld staat het procentteken voor het deel dat in het
  patroon door datzelfde procentteken gevat werd.
  
<p>  Make expandeert het bovenstaande dus aldus:
  
<pre>
/home/bla/target1.html:	target1.html
	commando's
        
/home/bla/target2.html: target2.html
	commando's
</pre>

  Het procentteken in het patroon `<i>/home/bla/%</i>' krijgt bij target
  `<i>/home/bla/target1.html</i>' dus de waarde `<i>target1.html</i>', waardoor
  de prerequisite `<i>%</i>'  expandeert tot `<i>target1.html</i>'.

<p>  Voor onze website komt een rule er nu alsvolgt uit te zien:
  
<pre>
$(TARGETDIR)/index.html $(TARGETDIR)/aanbod.html: $(TARGETDIR)/% : $(JANSDIR)/% \
                                                  $(LAYOUT)
</pre>
  
  Nu zitten we nog met 1 probleem: Hoe kunnen we deze variabelen in de
  commando's gebruiken? De commando's waren immers ook voor de beide targets
  enigszins verschillend?

<h3>Automatische Variabelen</h3>

  Make defini�ert gelukkig zelf ook enige variabelen. Sommige daarvan worden
  automatische variabelen genoemd, en die bevatten tijdens de uitvoering van
  commando's (of liever vlak daarvoor) de waarde van de target en/of
  prerequisite.
  
<p>  De speciale variabele <i>$</i> wordt gebruikt om de eerste prerequisite aan
  te geven, en de variabele <i>$@</i> expandeert altijd tot de huidige target.

<p>  Met behulp van deze variabelen kunnen we de complete rule dus als volgt
  `generaliseren':

<pre>
$(TARGETDIR)/index.html $(TARGETDIR)/aanbod.html: $(TARGETDIR)/% : $(JANSDIR)/% \
                                                  $(LAYOUT)
	{ \
          cat header.html  $<                       ;\
          echo -n '&lt;hr>Laatst gewijzigd: '          ;\
          date '+%A %e %B'                          ;\
          cat footer.html                           ;\
        } > $@
</pre>

  Voil�! Deze ene regel werkt nu dus voor beide files!

<p>  Voor de volledigheid nu weer eens de volledige Makefile, met nog wat
  optimalisaties:

<pre>
# Deze Makefile bouwt de website van Piet en Jan, de aardappeleters.

# Directory waar de website staat:
TARGETDIR = /home/piet/public_html

# Jan's directory:
JANSDIR = /home/jan/Docs/website

# Bestanden nodig voor de layout:
LAYOUT = header.html footer.html

# Dit zijn de web pagina's:
DOCS = $(TARGETDIR)/index.html $(TARGETDIR)/aanbod.html


# beneden deze lijn niets veranderen;-)
# -------------------------------------------------------------

all: $(DOCS)

$(DOCS): $(TARGETDIR)/% : $(JANSDIR)/% $(LAYOUT)
	{ \
          cat header.html  $<                       ;\
          echo -n '&lt;hr>Laatst gewijzigd: '          ;\
          date '+%A %e %B'                          ;\
          cat footer.html                           ;\
        } > $@

# the end
</pre>

  Dit begint erop te lijken. Als er meerdere documenten bijkomen, kunnen die
  vrij eenvoudig in de Makefile (aan de DOCS variabele) worden toegevoegd,
  zonder al te veel typwerk.

<p>  Uiteindelijk moet zelfs degene die de Makefile onderhoudt gemakkelijk kunnen
  zien hoe het werkt, zonder telkens weer de werking ervan te moeten
  ontcijferen!

<h3>Laatste kleine optimalisaties</h3>

  We zouden natuurlijk liever willen dat we de documenten gewoon konden noemen
  in DOCS, zonder steeds de hele directory erbij. Dat kan alsvolgt (we
  veranderen DOCS in het begin van de makefile in TEKSTEN):
  
<pre>
TEKSTEN = index.html  aanbod.html  nogeenbestand.html

# beneden deze lijn niets veranderen;-)
# -------------------------------------------------------------
DOCS =  $(addprefix $(TARGETDIR)/,$(TEKSTEN))

all: $(DOCS)

# enz
</pre>

  Wat we hier zien, is een specialistische functie van make:  
  In plaats van een variabele-naam kan tussen de haakjes ook een complete
  uitdrukking staan, waarmee tekst op allerlei manieren kan worden bewerkt.
  
<p>  Het speciale commando <i>$(addprefix prefix,lijst)</i> voegt aan elk element
  van de lijst een prefix toe, in het voorbeeld de inhoud van de TARGETDIR
  variabele plus een slash (/).
  
<p>  De items in de lijst worden door spaties gescheiden, vandaar dat het niet echt
  een goed idee is om bestandsnamen waar spaties in voorkomen met make te
  bewerken.

<p>  Tot slot: in het begin zeiden we al dat de target `all' geen bestand cre�ert
  met de naam `all' (er zijn immers geen commando's in die regel) en daarom
  telkens wordt uitgevoerd.  Maar wat als er <toevallig> een bestand in de
  directory staat met die naam, nieuwer dan de andere ...?
  
<p>  Er is een simpele manier om make te vertellen dat een bepaalde target
  altijd moet worden uitgevoerd en niet verwijst naar een file op de harde
  schijf. Dit doen we door die target als `<i>phony</i>' (onecht) te markeren. Dat gaat
  alsvolgt:
  
<pre>
.PHONY: all
</pre>

  De hele Makefile ziet er nu alsvolgt uit:

<pre>
# Deze Makefile bouwt de website van Piet en Jan, de aardappeleters.

# Directory waar de website staat:
TARGETDIR = /home/piet/public_html

# Jan's directory:
JANSDIR = /home/jan/Docs/website

# Bestanden nodig voor de layout:
LAYOUT = header.html footer.html

# Dit zijn de namen van de web pagina's:
TEKSTEN = index.html  aanbod.html  nogeenbestand.html

# beneden deze lijn niets veranderen;-)
# ------------------------------------------------------
DOCS =  $(addprefix $(TARGETDIR)/,$(TEKSTEN))
.PHONY: all

all: $(DOCS)

$(DOCS): $(TARGETDIR)/% : $(JANSDIR)/% $(LAYOUT)
	{ \
          cat header.html  $<                       ;\
          echo -n '&lt;hr>Laatst gewijzigd: '          ;\
          date '+%A %e %B'                          ;\
          cat footer.html                           ;\
        } > $@

# the end
</pre>

  Die sla je op en vergeet je! Nu kun je met een simpele make, desnoods in je
  crontab, altijd je webpagina up-to-date houden, en de layout netjes van de
  inhoud scheiden!

<h2>Slotopmerkingen</h2>

  Dit voorbeeld kan natuurlijk worden aangepast voor andere situaties.

<p>  Bijvoorbeeld de simpele manier waarop het document in elkaar wordt gezet is
  niet waterdicht: Als Jan zijn artikelen per ongeluk met
  <i>&lt;/body>&lt;/html></i> eindigt, wordt (door de meeste browsers) de door Piet
  gemaakte footer.html niet afgebeeld.  Met grep, perl of tcl kunnen we nog wat
  handiger titels uit Jans documenten overbrengen in de header van de site.

<p>  Jan kan natuurlijk ook gewoon platte tekst schrijven, en met een sed commando
  worden dan alle wit-regels in &lt;P&gt; veranderd:

<pre>
sed -e 's/^\s*$/&lt;p>/g'
</pre>
  
  Daarnaast kan Jan natuurlijk ook zijn teksten in <a href="http://www.lyx.org/">LyX</a>
  schrijven, en gebruike
  men een programma als lyx2html om er html van te maken. Mogelijkheden te
  over!

<p>  Een andere template-constructie is natuurlijk ook mogelijk.
  
<p>  We hebben ook niet stil gestaan bij hoe eventuele plaatjes worden overgebracht
  (geschaald, geconverteerd of gecomprimeerd) naar de web directory. Dat kan
  natuurlijk ook automatisch!
  
<p>  In dit voorbeeld moet Piet leestoegang hebben in Jans website directory.  Het
  interessante van deze scheiding van taken is, dat zij vertaald kan worden
  naar zeer grote organisaties!  Piet kan zelfs aan de andere kant van de
  wereld inloggen, of zijn homedir over NFS mounten. De voorbeelden kunnen
  echter ook gebruikt worden voor werk door ��n gebruiker.

<p>  Het basisidee over hoe een Makefile werkt, en hoe simpel je dagelijks
  werk ineens wordt als je een goede Makefile hebt, is hopelijk een beetje
  duidelijk geworden!

<h2>Tips</h2>

<ul>
  <li>Make als gebruikersinterface

  <P>Een verzameling bestanden kan ook functioneren als bron voor het op
  verschillende manieren samenstellen van een eindproduct of actie.
  
  <p>Door middel van `phony' targets (.PHONY: target) kunnen eenvoudige
  functies makkelijk worden gebundeld. Een voorbeeld hiervan is de configuratie
  van de Linux kernel.
  
  <p>Met <i>make menuconfig</i> wordt de configuratie gestart via een interactief
  menu. Met <i>make xconfig</i> wordt de configuratie gestart via een Tcl/Tk
  interface onder X.
  
  <p>Deze beide targets hebben dus niets met de eigenlijke bouw van de kernel te
  maken, zij vormen gewoon een makkelijke interface naar de noodzakelijke
  functies (zoals configuratie van de kernel).

  <h3>Een voorbeeld</h3>

  Stel je voor: Je hebt een grote verzameling documenten, die je als ��n geheel
  bewaart, onderhoudt en distribueert.  Je wil samenvattingen kunnen maken, in
  draft en verkleind kunnen printen, in topkwaliteit printen, publiceren naar
  het web etc. alles vanuit dezelfde bronbestanden (bijvoorbeeld
  LaTeX!).
  
  <p>Je zou dan een Makefile moeten maken met bijvoorbeeld de volgende PHONY
  targets:

  <dl>
    <dd>[help:] Print een eenvoudig overzicht van de in deze Makefile opgenomen
    functies (targets).

    <dd>[print-draft:]  Print bijvoorbeeld een verkleinde versie van het document (met
    behulp van de ps-utils) naar een printer met een grove resolutie.

    <dd>[print-full:] Print het volledige document.

    <dd>[ps:] Exporteert het volledige document naar een PostScript file.

    <dd>[report:] Vat titel, abstract en summary van een document samen en
    mail dat naar iemand toe die de ontwikkeling van je werk moet volgen.

    <dd>[html:] Werkt de html-versie van je werk automatisch bij.
  </dl>
  
  enz. enz. Zo kunnen complexe handelingen worden gedefini�erd in een Makefile,
  en vervolgens aangeroepen via een simpel te onthouden interface.<br><br>

  <li>Prerequisites kunnen ook weer target zijn
  
  <P>Bestanden die voor een bepaalde target als prerequisite genoemd worden, kunnen
  zelf ook weer target zijn voor een volgende bewerking.
  
  <p>Zo kun je bijvoorbeeld uit een tekstbestand HTML genereren, en die HTML weer
  in een completere layout zetten. Een voorbeeld:
  
<pre>

TEMPLATE = layout1/Template1.txt

/home/httpd/sales/sales.html: sales.html $(TEMPLATE)
	perl Scripts/BuildPage.pl -template $(TEMPLATE) $< > $@-new
        mv -f $@-new $@

sales.html:	sales.txt
	aptconvert -toc $@ $<

</pre>
  
  Zie hoe de file ook wordt bijgewerkt als de Template1.txt was veranderd.

<li>Commando echo, foutmeldingen en testen

  <P>Als je een commando met een `@' laat beginnen, wordt het niet afgebeeld door
  Make:

<pre>
target: prerequisite
	@cc -o target prerequisite
</pre>
  
  Als je een commando met een `-' laat beginnen, wordt het Make proces niet
  afgebroken als dat commando een fout veroorzaakt (bijvoorbeeld probeert een
  niet bestaande file te wissen):

<pre>
.PHONY: clean

clean:
	-rm -r $(tempdir)
</pre>

  Als je wilt zien wat een bepaalde `make' aanroep doet, (bijvoorbeeld
  <i>make install</i>) maar je wilt per se niet dat het echt gedaan wordt,
  gebruik dan de -n optie op de prompt:
  
<pre>
wilbert@nutnix:~ > make -n install
install -m 755 program /usr/local/bin
install -m 644 program.1 /usr/local/man/man1
wilbert@nutnix:~ >
</pre>

<li>Substitutie van make-variabelen voorkomen

  <P>Als je het dollarteken ($) nodig hebt als onderdeel van bijvoorbeeld een
  filenaam of een shell commando, gebruik het dan dubbel ($$):

<pre>
# A Makefile
# Don't try this at home! :-)
source = menu.txt help.txt

target: $(source)
	for i in $(source)             ;\
        do                              \
          if [ "$$i" = "menu.txt" ]    ;\
          then                          \
            doThis $$i                 ;\
          else                          \
            doThat $$i                 ;\
          fi                           ;\
        done > target
</pre>

  Make zal, voordat het commando naar de shell wordt gestuurd om te worden
  uitgevoerd, netjes zijn eigen variabelen substitueren, en alle dubbele
  dollartekens door enkele vervangen.
</ul>

<h2>Meer informatie</h2>

  Meer informatie over de werking van make en alle mogelijkheden is te vinden in
  de `GNU Make Manual'. Op je Linux systeem kan die worden bekeken met:
  
<pre>
info make
</pre>

  Natuurlijk kan je de GNU Make Manual ook bestuderen met de GNOME en KDE
  helpbrowsers of het handige programma tkinfo.

  <p>Links naar meer informatie over make:
  
  <ul>
    <li>Een <a href="http://nl.linux.org/boeken/lees.php?recensie_id=25">recensie</a> van
    Armijn Hemel over het boek `Managing your projects with make'.

    <li>Een <a href="http://www.google.com/search?q=make%2Btutorial">Google zoektocht</a>
    op de term `make tutorial'.
  </ul>


  <p>Veel plezier!