Beruflich Dokumente
Kultur Dokumente
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
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
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