Sie sind auf Seite 1von 20

3/30/2015

MakefilesCollectedSlides

MakefilesCollected
Slides

SiteSearch

Slide1
1Title

MakefilesTitle

Title:
Introductionto``make''forHandlingSoftwareProjects

Abstract:
Assoftwareprojectsgrow,thetaskofrecompilingandlinkingthecodetogetherto
produceanexecutableprogrambecomesincreasinglymoredifficultorlengthy.Investing
alittletimeinunderstanding``make''andcreatingyourown``Makefile''paysenormous
dividendsreducingthedebuggingcycleandselfdocumentingthetasksnecessaryto
produceanexecutable.``make''isasimpleandusefultoolthatcomparesthe
dependenciesinthe``Makefile'',withrespecttothesourcefiletimestamps,executingthe
givencommandstocreateanuptodatedependent.Thisdiscussionstartswithvery
simple``Makefiles''tomoreinvolvedandfiendishlycleverones,examiningeachaspect
of``make''.

Slide2
2Introduction

MakefilesIntroduction

make is a useful tool for managing software projects. A Makefile can be the collective
memoryofcommandsnecessarytobuildormanageasoftwareproject.Thereareseveral
flavorsandvariantsofmake.Inthistutorialwe'llconcentrateontheGNUmake,butonly
thosefeaturesthatcanbereasonablyexpectedinoneoftheotherflavors(SysVorBSD).
AMakefilecontainstargets,prerequisites,commands,andmacros.Allofthesetermswill
become clear in the presentation. The first question to ask is why and when should a
Makefilebeused.(Inthistutorial%isthecommandpromptandenteredcommandsare
inbold.)

``WhyshouldIuseaMakefile?''
Whendevelopingsoftwaretheusualcycleistoedit,compile,execute,debugandrepeat
untilallthebugsarefoundorwhensatisfied.Thisinvolveslotsofrepetitivesteps.
Assumingthatthefilesub2.cwasedited,insteadoftyping:
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

1/20

3/30/2015

MakefilesCollectedSlides

%cccsub2.c
%ccomainexemain.osub1.osub2.osub3.o

justtype
%make

ifyouhaveinvestedaminuteortwotocreateaMakefile.
You can save lots of time during the compilation step by breaking up your software
projectintoseparatecompilationunits.Onlythoseunitsthatarechangedgetrecompiled.
Ifthesourceisnontrivial(i.e.large),thiscanresultinsignificanttimesavings.

``WhenshouldIuseaMakefile?''
Whenthereismorethanonefiletohandle.
Ifthecodeisexpectedtobebuiltondifferentmachines.
Therearespecialhandlingsteps.
Ifyouconsideryourtimetobevaluable.
IfyouexpecttorebuildyourexecutableatsomelaterpointtheMakefileretains
thememoryoftheneededsteps.

Slide3
3DoneVerySimply

MakefilesDoneVerySimply

The very simple Makefile contains dependencies, with commands to create the target
fromtheprerequisites.Theentrieslooklikethis:
target:prerequisites_1prerequisites_2...
<tab> commandstobuildtargetfromtheprerequisites
<tab> othercommandstoassociatewithtarget...
...repeatedforeachtargetorcreatedfile...

Supposeyouhaveasimpleproject:
main.cproj.hsub1.csub2.csub3.c

wheremain.cdependsonthesub[13].cfilesandallthe*.csourcefilesdependon
proj.h.ExampleMakefile:

#thisisacomment
mainx:main.osub1.osub2.osub3.o

ccomainxmain.osub1.osub2.osub3.o
main.o:main.cproj.h

cccmain.c
sub1.o:sub1.cproj.h

cccsub1.c
sub2.o:sub2.cproj.h

cccsub2.c
sub3.o:sub3.cproj.h

cccsub3.c
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

2/20

3/30/2015

MakefilesCollectedSlides

Nowifyoutypemakethefollowingcommandsgetexecuted:
%make
cccmain.c
cccsub1.c
cccsub2.c
cccsub3.c
ccomainexemain.osub1.osub2.osub3.o

Ifyoueditproj.handrunmake,thesamecommandsareexecuted.However,ifyouedit
sub2.conlythefollowingcommandsareperformed:
%make
cccsub2.c
ccomainexemain.osub1.osub2.osub3.o

EvensimplerMakefiles
ThefollowingMakefile,whichshowsnothingbutthedependenciesandhowtobuildthe
executable,canbeusedtoperformthesamesetofoperations:
mainx:main.osub1.osub2.osub3.o

ccomainxmain.osub1.osub2.osub3.o
main.osub1.osub2.osub3.o:proj.h

Thisworksbecausemake knowshowtocreate .o files from .cfiles.These are termed


suffixrulesorimplicitrules.Youcancreateyourownoroverridetheonesprovidedby
make.Thiswillbelookedatindetaillater.

Howdoesmakeknowwhichonetobuild?
Ifyoutypemake,theprogramlooksforafilenamedmakefileinthecurrentworking
directoryandifitdoesn'texistthenlooksforonenamedMakefile(thisistheprefered
nametouse).Itreadsthisfilecreatingadependencytree.Thefirsttargetlistedinthefile
isthedefaultonetobuildwhennotargetisgivenonthecommandline.
make checks the time/date stamp of the target compared to the prerequisites. If the
prerequisiteislaterthanthetargetthenmaketheassociatedactions.
Suppose you want to compile sub3.c and nothing else, then just type the target on the
commandline:
%makesub3.o

Makefiletricks

Targetsdon'trequireprerequisites,whichmeansthatiftheyaretargeted(onthe
commandline)theywillbeexecutedregardless.Thisisfarmoreusefulthanrealized.
Thisgivesyouawaytoexecuteoftenusedgroupsofcommands.ThefollowingMakefile
addsthetargetshelp,clean,andthetargetclobberwhichdependsonclean:
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

3/20

3/30/2015

MakefilesCollectedSlides

mainx:main.osub1.osub2.osub3.o

ccomainxmain.osub1.osub2.osub3.o
main.osub1.osub2.osub3.o:proj.h
clobber:clean

rmfmainx
clean:

rmfa.outcore*.o
help:

@echo""

@echo"make

@echo"makeclean

@echo"makeclobber

@echo"makehelp

@echo""

buildsmainx"
remove*.ofiles"
removesallgeneratedfiles"
thisinfo"

Givethefollowingcommand,whichgivesthefollowingresult
%makehelp
makebuildsmainexe
makecleanremove*.ofiles
makeclobberremovesallgeneratedfiles
makehelpthisinfo

NoticethattheMakefilecontainsacoupleofspecialcharacters(@and)priortothe
commands.First,weneedtounderstandhowmakeexecutesthecommandsinthe
Makefile.Eachlinethathasanunescapednewlineisechoedtothescreenandispassed
offtoashellchildprocessshellwhichthenexecutesit.Iftheshellreturnsanonzeroexit
valuemakewillthengenerallyabortanyfurtherprocessingwithawarning.
The``''tellsmaketoignoreanyreturnvalueandtocontinueontothenextcommand.
Disregarding return values can besetglobally with either the ``i''optionorthe``fake''
target.IGNOREintheMakefile.
Theotherspecialcharacter``@''tellsmakenottoechothecommandtostdout.Echoing
canbedisabledgloballywitheitherthe``s''optionorthefaketarget.SILENT.

Slide4
4MacrosandMore

MakefilesMacrosandMore

The previous examples generally have a lot of repetitive text. make provides a simple
macromechanism.Macrosaredefinedinanumberofways(listedinincreasingorderof
precedence):
1. Internallydefinedbymake
2. Shellenvironmentvariables

setenvCC"gcc"

3. MacrosdefinedintheMakefile:
OBJS

=main.osub1.osub2.osub3.o

http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

4/20

3/30/2015

MakefilesCollectedSlides

Therecanbeno<tab>sbeforethemacronameandnocolonsbeforetheequal(=)
sign.
4. Macroscanbedefinedonthecommandline:

makeCC=gcc

Thereisaspecialcircumstance(usingtheeoption)whenthesecondandthirdentriesin
thelistareswappedinprecedence.
Macros are used in the Makefile by bracketing the macro name with either parentheses
``()'' or braces ``{}'' and prepending a dollar sign ``$''. If the macro name is a single
charactertheparenthesesandbracescanbeneglected.Thisisalikelysourceoferrorsin
Makefiles.
By convention macro names should be uppercase, but lowercase letters, numbers and
underscoresaresafetousealso.
Ifamacronameisnotdefinedmakewilljustuseanullstringinsteadandnotcomplain.
Thisisnotanerror.

CanNotDynamicallyResetMacros
Oneoftheproblemswithmacrosisthat,unlikeascript,macroscannotbereassigneda
differentvaluehalfwaythroughtheprocessing.Amacrocannothaveonevaluewhen
operatingononetargetandadifferentvalueforanother.``Why?''Thishighlightsthe
differencebetweenscriptsandmake.Scriptsareexecutedinalinearfashionwherethere
isaclearsequenceofeventstoexecute.make,ontheotherhand,definesaninvertedtree
structureofdependencieswithassociatedcommandstocreatetargets.Thetreecanbe
traversedeitherdepthfirstorleveldescenttherefore,theorderofoperationsisnot
necessarilylinear.makemustreadthroughtheentireMakefilebeforestartingany
dependencyanalysis.Thelastmacrodeclarationdefinestheoverallmacrodefinitionto
beusedeverywhere.
There are ways to get around this limitation by using a recursive make invocation.
However,formostapplicationsitwon'tbenecessaryifyoudesignyour Makefilescript
accordingly.

PredefinedandInternalMacros
makehasseveralpredefinedmacrosthatmakesrulewritingeasierandmoregeneralized.
However,becareful.Theaccidentalsubstitutionofthewrongmacromaycausethe
overwritingofthesourcefile.Inparticular,if$<or$?isusedwhen$@shouldhavebeen
usedintheaction.Themacrosofmostinterestare:
$@ thenameofthefiletobe``made''
$? thesetofdependentnamesthatareyoungerthanthetarget
thenameoftherelatedfilethatcausedtheaction(theprecursortothetarget)this
$<
isonlyforsuffixrules
$* thesharedprefixofthetargetanddependentonlyforsuffixrules
$$ escapesmacrosubstitution,returnsasingle``$''.
Suffixruleswillbediscussedlater.
ThefollowingexampleMakefiledemonstratessomeofthesespecialmacros:
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

5/20

3/30/2015

MakefilesCollectedSlides

#testsofthevariousbuiltinmacros
SRCS
=aaa.cbbb.cccc.c
OBJS
=${SRCS:.c=.o}
.SILENT:
all:xxxyyy
xxx:$(SRCS)

echo"target========$@"

echo"allsources=$(SRCS)"

echo"newersources=$?"

echo"allobjects=$(OBJS)"
yyy:*.c

echo"target========$@"

echo"allsources=$(SRCS)"

echo"newersources=$?"

Whichgivesthefollowingoutput:
%make
target========xxx
allsources=aaa.cbbb.cccc.c
newersources=aaa.cbbb.cccc.c
allobjects=aaa.obbb.occc.o
target========yyy
allsources=aaa.cbbb.cccc.c
newersources=aaa.cbbb.cccc.cxxx.c

Theaboveexampleshowsacoupleofnewfeatures.

EditingMacros
Thefirstisthelimitedmacrosubstitution
OBJS=${SRCS:.c=.o}

Whichsaystosubstitute``.o''forthelasttwocharacters,iftheyhappentobe``.c'',inthe
listgivenby$(SRCS).Thisprovidesaneasywaytocreatelistsofobjectfiles,manpage
files,executables,etc.fromasinglelistofsources.However,noteverymakeallowsthis
typeofsubstitution.(TheCray,IBMSP,andGNUonesdo.)

DependencyGlobbing
Thetargetorprerequisitescouldusefile``globbing''symbols.Theaboveexampleshows
theprerequisitesforyyyas*.c,where*matchesanynumberofcharacters.Theother
globbingcharacteris?,whichmatchesanysinglecharacter.Notethatthisdoesnotwork
reliablyifthetargetusesglobbingcharacters.ItworksforGNUmake,butnotforthe
CrayorIBMSP.It'sgenerallynotagoodideatouseglobbingatallandIhaverarely
seenMakefileswithit.

HostsofOtherMacros
Thereareanumberofbuiltinmacros,andtheycanbelistedoutwithallthevarious
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

6/20

3/30/2015

MakefilesCollectedSlides

suffixrulesandenvironmentvariableswith:
makepf/dev/null

TheonesIconsidertobethemostimportare:
SHELL

Theshelltouseforexecutingcommands.Somemakesdon'thonoritanduse
/bin/shanyways.Otherswilltaketheusersloginshell.Youshouldalwayssetthis
macroanddefineitto/bin/shandwriteyouractionsappropriately.

MAKE

thenameofthemakecommand.OnlyGNUusesthefullpathnameifspecifiedon
thecommandline,elsejustusescommandname.Therefore,needtomakesurethe
desiredmakeisfoundfirstinthecommandPATHiftryingtouseanotherversionof
make.
MAKEFLAGSorMFLAGS
theoptionspassedtotheMakefile.However,it'snotdoneconsistently.GNUand
Craypassonlytheoptionletterscollectedtogether(e.g.ni).IBMSPpassesdashed
optionseachseparate(e.g.ni).GNUputsthedashedoptionsintoMFLAGS,a
macronotusedbytheothertwo!
VPATH

acolon(:)separatedpathofdirectoriestosearchforprerequisites.

Therearenumerousmacrosthatrefertovariouscompilersandtoolswiththeirassociated
macroforpassingoptions.
Macro
FC/CF/F77

Flags
FFLAGS

CC

CFLAGS

AS

ASFLAGS

LD

LDFLAGS

AR

ARFLAGS

LEX

LFLAGS

YACC

YFLAGS

Tool
Fortrancompiler
Ccompiler
assembler
objectloader
archiver
lexicalparser
grammarparser

This is just a small portion. Except for the Fortran compiler, the rest listed are fairly
standardtoeachimplementation.Thesemacrosareusedbythesuffixrulesdescribedin
thenextsection.

Slide5
5ImplicitorSuffixRules

MakefilesImplicitorSuffixRules

Inearlierexamplesweeitherexplicitlyspelledouthoweachtargetis``made''fromthe
prerequisitesorreliedonmakemagictodotherightthing.
This section looks into how to write and provide suffix rules, which are also called
``implicitrules''.
Writing your own rules frees the Makefile from being intimately dependent on any
particularmakeorplatformandcanshortenMakefilesforlargeprojects.
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

7/20

3/30/2015

MakefilesCollectedSlides

Suffixrulesare,inasense,genericrulesforconverting,say.cfilesto.ofiles.
Suffixrulesareoftheform:
s1s2:

commandstogets2froms1

Suffixescanbeanystringofcharacters,andbyconventionusuallyincludea``dot''(.),
butdoesnotrequireit.Theallowedsuffixesaregivenbythe.SUFFIXESfaketarget.
Thefollowingisareworkingofanearlierexamplewithhelpfulcomments:

CC
=gcc
CFLAGS =g
LD
=$(CC)
LDFLAGS=
RM
=rm
EXE
SRCS
OBJS

=mainx
=main.csub1.csub2.csub3.c
=${SRCS:.c=.o}

#clearoutallsuffixes
.SUFFIXES:
#listonlythoseweuse
.SUFFIXES:.o.c
#defineasuffixrulefor.c>.o
.c.o:

$(CC)$(CFLAGS)c$<
#defaulttargetbyconventionis``all''
all:$(EXE)
$(EXE):$(OBJS)

$(LD)o$@$(OBJS)
$(OBJS):proj.h
clean:

$(RM)f$(EXE)$(OBJS)

Strongly recommend that you write your own suffix rules for all those used within the
softwareproject.Theneedforthisisdemonstratedbythelackofconsistencyinmacro
namesfortheFortrancompilershowninthelastsection.
However,ifyouareonlyusingCandtheassociatedtools(lex,yacc,ar,andld)thenthe
defaultmacrosandsuffixrulesareprobablysufficientsincetheyarefairlystandard.

LookingatPredefinedRulesandMacros
Thefollowingcommandwilllistthepredefinedrulesandmacros.Theoption``f''tells
makewhichMakefiletouse,inthiscase/dev/nulltheemptyfile.Theoutputis
somewhatlengthysoit'sagoodideatopipeitintoapagerorintoafile.
%makepf/dev/null

http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

8/20

3/30/2015

MakefilesCollectedSlides

Lookingatthepredefinedsuffixrulesareusefulforcomposingyourownandtoobserve
whichmacrosareusedforeachcompilingtool.

Slide6
6VPATHandRCS

MakefilesVPATHandRCS

The macro VPATH tells make where, in addition to the local directory, to search for
prerequisites to satisfy the make rules. VPATH has the same format as the shell PATH, a
colon (:) delimited selection of directory paths. Don't include ``.'' since the current
directoryisalwayssearched.
VPATH

=./RCS:../:../RCS:$(HOME)/sources

The following example keeps the sources under RCS source control. If a source, say
sub1.c, is put under RCS control and the RCS directory exists then it is kept in
RCS/sub1.c,vandthecompilablesourceonlyexistswhencheckedoutwith``co''.

CC
=gcc
CFLAGS =g
LD
=$(CC)
LDFLAGS=
RM
ECHO

=rm
=echo

EXE
SRCS
OBJS

=mainx
=main.csub1.csub2.csub3.c
=${SRCS:.c=.o}

VPATH

=./RCS

.SUFFIXES:
.SUFFIXES:.o.c.c,v
.c.o:

@$(ECHO)"=====.c>.orule"
$(CC)$(CFLAGS)c$<

.c,v.o:

@$(ECHO)"=====usingRCSfor.cto.o"

cou$*.c2>/dev/null

$(CC)$(CFLAGS)c$*.c

$(RM)f$*.c
all:$(EXE)
$(EXE):$(OBJS)

$(LD)o$@$(OBJS)
$(OBJS):proj.h
clean:

$(RM)f$(EXE)$(OBJS)

Supposethedirectorylookslikethis:
%lsl
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

9/20

3/30/2015

MakefilesCollectedSlides

rwr1rkowen465Jun1708:29Makefile
drwxrx2rkowen1024Jun1708:31RCS/
rwr1rkowen36Jun1708:31proj.h
rwr1rkowen44Jun1708:27sub2.c

Whichshowsthatsub2.cischeckedout,presumably,formodifying.The``r''option
belowsaystonotuseanyofthepredefinedimplicitrules.Itwasnecessaryinthis
exampletoforcetheuseoftheimplicitrulesdefinedintheMakefilesincethepre
definedonesinterferewithours.TheMakefilegivesthefollowingresults:
%maker
=====usingRCSfor.cto.o
coumain.c2>/dev/null
gccgcmain.c
rmfmain.c
=====usingRCSfor.cto.o
cousub1.c2>/dev/null
gccgcsub1.c
rmfsub1.c
=====.c>.orule
gccgcsub2.c
=====usingRCSfor.cto.o
cousub3.c2>/dev/null
gccgcsub3.c
rmfsub3.c
gccomainxmain.osub1.osub2.osub3.o

NoticethatforsourcesinRCSthattheyarecheckedout,compiled,andthesourceis
removed,sincethey'renotnecessarytokeeparound.Supposewe'vebeenmodifying
sub2.candrerunmake.
%make
=====.c>.orule
gccgcsub2.c
gccomainxmain.osub1.osub2.osub3.o

Slide7
7RedefiningMacros

MakefilesRedefiningMacros

ResettingMacrosForDifferentConditions
Inanearliersectionitwasstatedthatmacroscouldnotberedefineddynamicallywithina
Makefile.ThelastsettingforamacroisthevalueusedthroughouttheMakefile.
There is a way around this by using a recursive make. In other words, a Makefile that
calls itself with different targets or macro definitions. In the following example, if the
make is not called with a proper argument or no argument it uses the ``fake'' target
.DEFAULTtoexecutethecommandgiventhere.Forthesakeofeconomyitjustrecursively
callsthemakeitselfwiththetargethelp.
Ifit'sgivenatargetoflinux,unicos,oraixitthenrecursivelycallsitselfwiththemacros
CCandLDappropriatelysetforthoseplatforms.

RM
ECHO

=rm
=echo

http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

10/20

3/30/2015

MakefilesCollectedSlides

EXE
SRCS
OBJS

=mainx
=main.csub1.csub2.csub3.c
=${SRCS:.c=.o}

#dothisifgivenaninvalidtarget
.DEFAULT:

@$(MAKE)help
help:

@$(ECHO)""
@$(ECHO)"do'makexxx'wherexxx=linux|unicos|aix"
@$(ECHO)""

all:$(EXE)
######################################################################
#thisonlyworksreliablywithGNU``make''whichcorrectlyhandles
#MAKE&MFLAGS
######################################################################
linux:

$(MAKE)$(MFLAGS)CC=gccLD=gcc
all
unicos:

$(MAKE)$(MFLAGS)CC=ccLD=segldr

all

aix:

all

$(MAKE)$(MFLAGS)CC=xlcLD=ld

$(EXE):$(OBJS)

$(LD)o$@$(OBJS)
$(OBJS):proj.h
clean:

$(RM)f$(EXE)$(OBJS)

Inthisexamplewegiveaninvalidtargettoexercisethe.DEFAULTtarget,andweusethe
soptionwhichisequivalenttoaddingthe.SILENTtargettosuppresscommandechoing.
%makesxxx

do'makexxx'wherexxx=linux|unicos|aix

Nowwetrythefollowing,wheretheoptionnsaystoechoanyexecutedcommands,but
donotperformthem(exceptfortherecursivemakeifusingGNU):
%makesnaix
makesnCC=xlcLD=ldall
xlccmain.comain.o
xlccsub1.cosub1.o
xlccsub2.cosub2.o
xlccsub3.cosub3.o
ldomainxmain.osub1.osub2.osub3.o

UsingthistechniqueaddsflexibilityandallowsyoutotailoryourMakefileforeach
platformyouanticipateusing.
AsindicatedintheMakefileitwillreliablyrunwiththeGNUmakeonlysincethereisno
realstandardregardingthemacros MAKEand MAKEFLAGS.TheGNUmake generally ports
welltoallcommonUNIXplatformssoobtainingoneisnotdifficult.However,allisnot
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

11/20

3/30/2015

MakefilesCollectedSlides

lost if you don't or can't have a GNU make if you use environment variables. The
following example shows a passable way. The /bin/env temporarily sets environment
variablesthatarepassedontotheexecutableonly.
%envMAKE=/bin/makeMFLAGS=ni/bin/makeaix
/bin/makeniCC=xlcLD=ldall
xlccomain.omain.c
xlccosub1.osub1.c
xlccosub2.osub2.c
xlccosub3.osub3.c
ldomainxmain.osub1.osub2.osub3.o

8RecursiveMakeForSub
directories

Slide8
MakefilesRecursiveMakeForSub
directories

Large software projects generally are broken into several subdirectories, where each
directorycontainscodethatcontributestothewhole.
Thewayitcanbedoneistodoarecursivemakedescendingintoeachsubdirectory.To
keep a common set of macros that are easily maintained we use the include statement
whichisfairlycommoninmostmakes
Thefollowingisthedirectorystructureofthesources:
rwr1rkowen625Jun1716:42Makefile
rwr1rkowen142Jun1716:43Makefile.inc
rwr1rkowen133Jun1714:32main.c
rwr1rkowen120Jun1714:34proj.h
drwxrx2rkowen1024Jun1716:54subdira
rwr1rkowen45Jun1714:28subdira/sub2a.c
rwr1rkowen45Jun1714:28subdira/sub3a.c
rwr1rkowen346Jun1716:34subdira/Makefile
rwr1rkowen45Jun1714:25subdira/sub1a.c
drwxrx3rkowen1024Jun1716:54subdir
rwr1rkowen524Jun1716:07subdir/Makefile
rwr1rkowen52Jun1714:33subdir/sub1.c
rwr1rkowen52Jun1714:33subdir/sub2.c
rwr1rkowen52Jun1714:33subdir/sub3.c
drwxrx2rkowen1024Jun1716:54subdir/subsubdir
rwr1rkowen47Jun1714:28subdir/subsubdir/subsub3.c
rwr1rkowen390Jun1716:35subdir/subsubdir/Makefile
rwr1rkowen47Jun1716:53subdir/subsubdir/subsub1.c
rwr1rkowen47Jun1714:28subdir/subsubdir/subsub2.c

HereistheMakefile.incandMakefileintheroot:
Makefile.inc

#putcommondefinitionsinhere
CC
=gcc
PRJCFLAGS
=g
LD
=gcc
LDFLAGS=
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

12/20

3/30/2015

MakefilesCollectedSlides

AR
=ar
ARFLAGS=
RANLIB =ranlib
RM
=rm
ECHO
=echo
SHELL

=/bin/sh

.SILENT:

Makefile

includeMakefile.inc
DIRS
=subdirsubdira
EXE
=mainx
OBJS
=main.o
OBJLIBS=libsub.alibsuba.alibsubsub.a
LIBS
=L.lsublsubalsubsub
all:$(EXE)
$(EXE):main.o$(OBJLIBS)

$(ECHO)$(LD)o$(EXE)$(OBJS)$(LIBS)

$(LD)o$(EXE)$(OBJS)$(LIBS)
libsub.alibsubsub.a:force_look

$(ECHO)lookingintosubdir:$(MAKE)$(MFLAGS)

cdsubdir;$(MAKE)$(MFLAGS)
libsuba.a:force_look

$(ECHO)lookingintosubdira:$(MAKE)$(MFLAGS)

cdsubdira;$(MAKE)$(MFLAGS)
clean:

$(ECHO)cleaningupin.

$(RM)f$(EXE)$(OBJS)$(OBJLIBS)

fordin$(DIRS);do(cd$$d;$(MAKE)clean);done
force_look:

true

Whichproducesthisoutput:
%make
lookingintosubdir:makes
arrv../libsub.asub1.osub2.osub3.o
asub1.o
asub2.o
asub3.o
ranlib../libsub.a
lookingintosubsubdir:makes
arrv../../libsubsub.asubsub1.osubsub2.osubsub3.o
asubsub1.o
asubsub2.o
asubsub3.o
ranlib../../libsubsub.a
lookingintosubdira:makes
arrv../libsuba.asub1a.osub2a.osub3a.o
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

13/20

3/30/2015

MakefilesCollectedSlides

asub1a.o
asub2a.o
asub3a.o
ranlib../libsuba.a
lookingintosubdir:makes
lookingintosubsubdir:makes
gccomainxmain.oL.lsublsubalsubsub

Supposewetouchafiledeepinthedirectorystructure:
%touchsubdir/subsubdir/subsub2.c
%make
lookingintosubdir:makes
lookingintosubsubdir:makes
arrv../../libsubsub.asubsub2.o
rsubsub2.o
ranlib../../libsubsub.a
lookingintosubdira:makes
lookingintosubdir:makes
lookingintosubsubdir:makes
gccomainxmain.oL.lsublsubalsubsub

Noticethatthe Makefilehasadummytargetnamed force_lookthatthelibrariesdepend


on.This``file''isnever createdhencemake will always execute that target and all that
depend on it. If this was not done then make would have no idea that libsubsub.a
depends on subdir/subdir/subsub2.c unless we include these dependencies in the root
Makefile.Thisdefeatsthepurposeofbreakingupaprojectintoseparatedirectories.This
mechanismpushesthedependencycheckingintolowerlevelMakefiles.
HereisarepresentivesubdirectoryMakefile:

include../Makefile.inc
CFLAGS =$(PRJCFLAGS)I..
OBJLIBS=../libsub.a../libsubsub.a
OBJS
=sub1.osub2.osub3.o
all:$(OBJLIBS)
../libsub.a:$(OBJS)

$(ECHO)$(AR)$(ARFLAGS)rv../libsub.a$?

$(AR)$(ARFLAGS)rv../libsub.a$?

$(ECHO)$(RANLIB)../libsub.a

$(RANLIB)../libsub.a
../libsubsub.a:force_look

$(ECHO)lookingintosubsubdir:$(MAKE)$(MFLAGS)

cdsubsubdir;$(MAKE)$(MFLAGS)
clean:

$(ECHO)cleaningupinsubdir

$(RM)f$(OBJS)

cdsubsubdir;$(MAKE)$(MFLAGS)clean
force_look:

true

We use the predefined implicit rules, and define CFLAGS with project wide options and
wheretofindtheincludefiles.
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

14/20

3/30/2015

MakefilesCollectedSlides

Noticethegangedshellcommandstocdintoasubdirectoryandtoexecuteamake. It's
not for compactness or convenience ... it's required for correct behavior. The following
sectionwilldetailsomeoftheseissues.

Slide9
9MakeandtheShell

MakefilesMakeandtheShell

Inthe Makefileeachactionlineisaseparateinvocationofashellchildprocessandany
shellvariablesorcurrentworkingdirectorychangesareindependentofeachother.
ThefollowingtableshowshowtocompressthevariousBourneshellstatementsontoa
singlelogicalline.However,it'sagoodideatobreakupthestatementswithwhitespace
formattingontoseparatelines.Thiscanbedonebyescapingthenewline.
Otherhints:
SetthemacroSHELL=/bin/shtomakesurewhichshellwillbeinvoked.(Ifyoupick
someothershellthere'snoguaranteethattheimplementationofmakewillhonor
it.)
Use$$variabletoreferenceashellvariable(suchasintheforloop).The``$$''
tellsmaketonotdoanymacroexpansion.
Usetestinsteadof[and],sinceerrorsoccurwhenthereisinadequatespacing
givenforthebrackets.
Eitherquoteorrelyonstringcatenationforcomparisons,e.g.
test"$$x"="abc"or
testx$$x=xabc
testdoesn'thandleemptyargumentstoowell!
Becomefamiliarwithexprfordoingsimplemathoperationsandparsing.
Likewisewithbasenameanddirnameforparsingoutpartsofthefilenameand
path.
Understandwhentousequotes(")orapostrophes(').

BourneShellconditionalandloopingstatements
Expanded

Condensed

ifcom1
then

com2
fi

ifcom1;thencom2;fi

ifcom1
then

com2
else

com3
fi

ifcom1;thencom2;elsecom3;fi

ifcom1
then

com2
elifcom3
then

com4
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

ifcom1;thencom2;elifcom3;\

thencom4;elsecom5;fi
15/20

3/30/2015

MakefilesCollectedSlides

else

fi

com5

casevaluein
pattern1)
pattern2)
pattern3)
esac

com1;;
com2;;
com3;;

casevalueinpattern1)com1;;\

pattern2)com2;;\

pattern3)com3;;esac

forvariableinlist
do

command
done

forvariableinlist;docommand;done

whilecom1
do

com2
done

whilecom1;docom2;done

untilcom1
do

com2
done

untilcom1;docom2;done

10MakeandtheDoublecolon

Slide10
MakefilesMakeandtheDoublecolon

makehasalittleusedfeaturethatissignifiedwiththedoublecolon(::).Thistellsmake
toassociatemorethanoneactionforatarget.Normally,withathesinglecolon(:),you
canhavemultipletargetandprerequisitestomapthedependencies,butonlyoneofthem
canhaveanassociatedaction.Forexample:
aaa.o:aaa.cin.h

cccaaa.c
aaa.o:another.h
aaa.o:yetanother.h

Thedoublecolonallowsyourtodosomethinglikethis:
libxxx.a::sub1.o

arrvlibxxx.asub1.o
libxxx.a::sub2.o

arrvlibxxx.asub2.o

Wherethelibrarylibxxx.adependsonsub[12].oandwilladdthemintothelibrary
collectionasneeded.
The double colon mechanism is very usefulforautomatically generated Makefiles.The
actionscanbecollectedtogetherinaverticlesense,asopposedtotheusualapproachthat
lists prerequisites in a horizontal sense. The latter is more efficient from a make
operational view, but can be difficult to automate Makefile generation for a batch of
sourcefiles.
The following is a very contrived example that demonstrate some of the shell looping
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

16/20

3/30/2015

MakefilesCollectedSlides

tricksandhowtoautomaticallyselfgenerateaMakefile.
The``header''partoftheMakefileisnotautomaticallygeneratedandiscarriedfromone
version to the next. It has the executable mainx depend on the Makefile and below it
depends on the .o files. The Makefile itself depends on the sources in the current
directory.Ifyouaddanewsourcefile,say sub4.c,makewillthenexecutetheactionfor
the Makefiletarget.Theactionisaverysophisticateduseofshelllooping.Itpassesthe
Makefilethroughsedtocutouttheheaderpart,thenechoandappendthesentinellinesto
Makefile.Theforloopkeysonevery .cfileinthecurrentdirectory.Itusesbasenameto
create variables with the .o name. The action uses gcc MM to parse a source file to
generateatargetwithprerequisites.Thefollowingechosgeneratedependenciesfor
mainx<.ofile<.cfile,etc.

Next,itcreatesacollectedaction,clean,forremovingthe.ofile.Finally,theactiondoes
arecursivemaketobuildtheexecutablewiththenewMakefile!

#
LD
=gcc
SHELL =/bin/sh
mainx:Makefile

$(LD)omainx*.o
clean::

$(RM)mainx
Makefile:*.c

@sede'/^###DoNoteditthisline$$/,$$d'Makefile\

>MMM.$$$$&&mvMMM.$$$$Makefile

@echo"###DoNoteditthisline">>Makefile

@echo"###Everythingbelowisautogenerated">>Makefile

@forfin*.c;doecho===$$f===1>&2;ff=`basename$$f.c`.o;\

gccMM$$f;echo"";echo"mainx:$$ff";echo"$$ff:$$f";\

echo' $$(CC)$$(CFLAGS)c'"$$f";echo"";echo"clean::";\

echo' $$(RM)'"$$ff";echo"";done>>Makefile

@$(MAKE)
###DoNoteditthisline
###Everythingbelowisautogenerated
main.o:main.cproj.h
mainx:main.o
main.o:main.c

$(CC)$(CFLAGS)cmain.c
clean::

$(RM)main.o
sub1.o:sub1.cproj.h
mainx:sub1.o
sub1.o:sub1.c

$(CC)$(CFLAGS)csub1.c
clean::

$(RM)sub1.o
sub2.o:sub2.cproj.h
mainx:sub2.o
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

17/20

3/30/2015

MakefilesCollectedSlides

sub2.o:sub2.c

$(CC)$(CFLAGS)csub2.c
clean::

$(RM)sub2.o
sub3.o:sub3.cproj.h
mainx:sub3.o
sub3.o:sub3.c

$(CC)$(CFLAGS)csub3.c
clean::

$(RM)sub3.o

Supposethesourcesub4.cisaddedtotheexistingproject.Itneednotbeexplicitlyadded
totheMakefile,justtype``make''.ItregeneratestheMakefileandbuildstheexecutable
accordingly.
%make
===main.c===
===sub1.c===
===sub2.c===
===sub3.c===
===sub4.c===
make[1]:Enteringdirectory`/u/owen/rk/make/src/ex5
'
cccsub4.c
gccomainx*.o
make[1]:Leavingdirectory`/u/owen/rk/make/src/ex5'
make:`mainx'isuptodate.

Thisisafiendishlyclever Makefile.normallyIstayawayfromsuchoverlyclevermake
tricks,optingforexplicitsimplicityandcontrol.However,itdoesdemonstratethepower
makeandwhatispossible.

Slide11
11``Make''Summary

Makefiles``Make''Summary

AMakefilecontains:

DependencyandActionLines
Comments
#commentsstartwith`#'andendwiththenewline

MacroDefinitions
macro_name=string

Themacro_namecancontainanyupperorlowercaseletters,digits,andthe
underscore(_).Uppercaselettersarepreferedbyconvention.Macrosubstitution
occurswhengivenas$(macro_name)or${macro_name}.Singlecharacter
$(macro_name)sarespecialanddon'trequiretheparentheses``()''orbrackets``{}''
http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

18/20

3/30/2015

MakefilesCollectedSlides

forsubstitution.
DependencyLines
targets:[:][prerequisites][;[commands]]

Definesthedependencyrelationships.Actionsfollow.Therecannotbeanyspace
beforethetargets.
SuffixorImplicitRules
suffix[suffix]:[:]

Definesimplicitorgenericrulesforcreatingafilewiththesecondsuffix
dependentonafilewiththesamebasenameandthefirstgivensuffix.Nospaces
beforeorbetweensuffices
Actions
<tab>[@]shellcommand

Actionsmuststartwithatab,elsenotrecognized.Theshellcommandmustbea
validsinglelinecommand.TheshellinvocationisusuallytheBourneshell
(/bin/sh).
IncludeStatement
includefile

readsandevaluatesfileasifpartofthecurrentMakefile.Mustnothaveany
whitespaceatbeginningofline.

InternalMacros
$@
$?
$<
$*
$$

thenameofthefiletobe``made''
thesetofdependentnamesthatareyoungerthanthetarget
thenameoftherelatedfilethatcausedtheaction(theprecursorto
thetarget)thisisonlyforsuffixrules
thesharedprefixofthetargetanddependentonlyforsuffixrules
escapesmacrosubstitution,returnsasingle``$''.

MacroStringSubstitution
${macro_name:s1=s2}

substitutess2foranys1stringthatoccursinthelistatthe
endanyworddelimitedbywhitespace.

SpecialMacros
SHELL
VPATH

tellsmakewhichcommandshelltoinvokeforactions.Thisisnot
alwayshonored,andingeneralsetitto/bin/shandwriteall
actionsfortheBourneshell.
thepathincludingthecurrentworkingdirectorythatmakewill
searchforprerequisitestosatisfytherules.

http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

19/20

3/30/2015

MakefilesCollectedSlides

SpecialTargets
.DEFAULT
.IGNORE

.SILENT
.SUFFIXES

Itsassociatedactionsareinvokedwhenevermakeisgivenatarget
thatisnotdefined.
Ignoresallreturncodesfromactions.Sameascommandline
option``l''.Bydefaultmakewillstopprocessingwheneveranon
zeroreturnstatusisreceivedfromanaction.
Willnotechotheactionasitsprocessed.Sameascommandline
option``s''.Bydefaultmakewillechotheactiontostdoutpriorto
invocation.
Appendsanygiven``prerequisites''tothelistofsuffixeswith
implicitrules.Ifnonearegiventhenwipethelistofsuffixes.

Slide12
12Conclusion

MakefilesConclusion

makeandMakefilesareveryusefulfor:
Managingsoftwareprojects
Reducingbuildtimesduringdebuggingcycles
Keepingarecordofcompilationstepsandoptions
Notallofthefeaturesweregivenhere,butthesearethemajorones.Theotherfeatures
arenotuniversalandareimplementationdependent.
Ausefulmasteryofmaketakesverylittletimetoacquire.Timewellspent!
LastModified:

Broughttoyouby:R.K.Owen,Ph.D.
Thispageishttp://owen.sj.ca.us/rkowen/howto/slides/make/slides/ALL.html

http://owen.sj.ca.us/~rk/howto/slides/make/slides/ALLF.html

20/20

Das könnte Ihnen auch gefallen