CSc 352 An Introduction to make Saumya Debray
CSc 352 An Introduction to make Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs. arizona. edu
Structuring large applications • So far, all of our programs have involved a single source file – obviously impractical for large(r) programs – even where practical, may not be good from a design perspective • If an application is broken up into multiple files, we need to manage the build process: – how do we (re)compile the various different files that make up the application? 2
Structuring large applications • When one file is edited, other files may need to be recompiled – changes to typedefs or macros in header files – changes to types of shared variables • Applications can contain a lot of files – E. g. : Linux kernel source code: 4, 900 files • Recompiling all files whenever any file is changed can be very time-consuming. 3
Structuring large applications • Obvious idea: only recompile those files that need to be recompiled. 4
Structuring large applications • Obvious idea: only recompile those files that may be affected by a change. affected changed 5
Structuring large applications • “Smart recompilation” : issues – need to be able to express, keep track of dependencies between files • “dependency” which files are (might be) affected by a change to a file? – need to make sure that all (and only) affected files are recompiled • doing this manually is tedious and error-prone • want an automated solution • make: a tool to automate recompilation of parts of a project based on a file of dependencies (“make file”) 6
Digression: compiling multi-file programs file 1. c gcc OPTS -c file 1. o file 2. c gcc OPTS -c file 2. o … file. N. c gcc OPTS -c gcc executable file. N. o 7
Digression: compiling multi-file programs file 1. c gcc OPTS -c file 1. o file 2. c gcc OPTS -c file 2. o … file. N. c gcc OPTS -c gcc executable file. N. o source files Only one of these files contains main() 8
Digression: compiling multi-file programs file 1. c gcc OPTS -c file 1. o file 2. c gcc OPTS -c file 2. o … file. N. c gcc OPTS -c gcc executable file. N. o object files machine code, but not executable 9
Digression: compiling multi-file programs file 1. c gcc OPTS -c file 1. o file 2. c gcc OPTS -c file 2. o gcc … file. N. c gcc OPTS -c executable file. N. o linker invocation combines various *. o files together 10
Digression: compiling multi-file programs file 1. c gcc OPTS -c file 1. o file 2. c gcc OPTS -c file 2. o … file. N. c gcc OPTS -c gcc executable file. N. o gcc -c compile to a linkable object don’t worry about main() 11
make files • make files specify: – dependencies between files – how to update dependent files 12
make files • make files specify: – dependencies between files – how to update dependent files dependency how to update the dependent file to satisfy this dependency 13
make files • make files specify: – dependencies between files – how to update dependent files dependency how to update the dependent file to satisfy this dependency 14
make files: structure Structure of a make file: rule Macros (optional) target … : prerequisites … t (tab) command. . . target: (usually) the name of a file that is created by a program prerequisite: a file used as input to create the target command: an action carried out by make to (re)construct target 15
make files: an elementary example Dependency structure: spellcheck. h make file: include spellcheck. c dependencies compile spellcheck: spellcheck. c spellcheck. h gcc –Wall spellcheck. c spellcheck must be a tab! 16
Creating a makefile 1. What are the targets? – figure out which files are created from other files and which need to be re-created when any of those files change. 2. For each target foo: – what are the files which, if changed, would require us to re-create foo? These are the prerequisites for foo (let’s say bar 1. . . barn) 3. What commands do we use to (re-)create foo? – say: cmd 1. . . cmdm 17
Creating a makefile • The resulting rule for foo is: foo: bar 1 bar 2. . . barn tab cmd 1 tab cmd 2. . . tab cmdm or: foo: bar 1 bar 2. . . barn tab cmd 1 ; cmd 2 ; . . . cmdm 18
make files: an elementary example Dependency structure: spellcheck. h include why is this not a dependency? spellcheck. c dependencies compile spellcheck 19
make files: example 2 file 1. o : file 1. c hdrfile 1. h gcc -Wall -g -c file 1. c file 2. o : file 2. c hdrfile 1. h hdrfile 2. h gcc -Wall -g -c file 2. c exec. File : file 1. o file 2. o gcc file 1. o file 2. o -o exec. File 20
make files: Macros • Makes make files easier to write, modify – define: – use: Name = replacement list $(Name) • Example: CC = gcc OPTLEV = –O 2 # optimization level CFLAGS = –Wall –g –D DEBUG $(OPTLEV) – c. . . file 1. o : file 1. c hdrfile 1. h $(CC) $(CFLAGS) file 1. c 21
Internal Macros These are macros that are predefined in make. – Examples: • CC = cc • CXX = g++ • LD = ld Execute “make –p” to get a complete list – Unix environment variables are inherited by make as predefined macros • execute “printenv” to get a complete list 22
Using make • Invocation: make [ -f make. File. Name ] [ target ] default: make searches (in order) for: makefile Makefile default: builds the first target in the make file 23
How make works • When invoked, begins processing the appropriate target • For each target, considers the prerequisites it depends on: target : file 1 file 2 … – checks (recursively) whether each of filei (1) exists and (2) is more recent than the files that filei depends on; • if not, executes the associated command(s) to update filei – checks whether target exists and is more recent that filei • if not, executes the commands associated with target 24
How make works Make filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd Dependence structure filea filec fileb filee fileg filed filef 25
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea filec fileb filee changed fileg current? filed filef 26
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea fileb current? filee changed fileg current? filec current? filed filef 27
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea changed fileb current? filee current? fileg current? filec current? filed filef 28
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea fileb ok changed current? filee fileg filed current? filec current? filef 29
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea fileb current? filee changed fileg filed current? filec current? update! filef 30
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea fileb update! filee changed fileg current? filec current? filed filef 31
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea filec fileb filee changed fileg current? update! filed filef 32
How make works Make filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd make execution filea filec fileb filee changed fileg update! filed filef 33
How make works Make file make execution filea : fileb filec cmda fileb : filee filed cmdb filec : filed filef cmdc filed : filef fileg cmdd filea filec fileb filee changed fileg filed filef 34
Phony Targets • A phony target is one that is not the name of a file, e. g. : clean: rm –f *. o a. out phony target • “make clean” will remove a. out and *. o files 35
Phony Targets clean: rm –f *. o a. out • This won’t work if we (accidentally) create a file named “clean” • Fix: . PHONY: clean: rm *. o a. out cleanup actions will be executed even if there is a file named “clean” 36
Command execution • Commands to update a target are executed by invoking a new subshell for each command line – invoking commands like “cd” on one command line won’t affect other command lines – to have one command affect the next, put them on the same line, e. g. : cd target. Dir ; cmd • If a command returns an error (nonzero exit status), make abandons that rule ― to ignore errors in a command, precede with ‘-’ 37
Command execution • The shell used is given by the macro SHELL – defaults to /bin/sh [Ubuntu]: /bin/sh points to dash, a stripped-down version of bash – to use a different shell, define SHELL appropriately, e. g. : SHELL = /bin/csh 38
Telling make how to process files • Suffix Rules: Structure: . suf 1. suf 2: recipe Example: • Pattern Rules: To create a file foo. suf 2 from foo. suf 1, execute recipe (suf 1 comes before suf 2: confusing) . c. o: … Structure: %. suf 2 : %. suf 1 recipe Example: %. o : %. c … Need a way to refer to a particular C file “compile this file in this way…” 39
Telling make how to process files • Suffix Rules: Structure: . suf 1. suf 2: recipe Example: • Pattern Rules: To create a file foo. suf 2 from foo. suf 1, execute recipe (suf 1 comes before suf 2: confusing) . c. o: … Structure: %. suf 2 : %. suf 1 recipe Example: %. o : %. c … • make has a list of known suffixes. These include. c and. o • To create your custom suffix rules for other suffixes, mention the suffixes to make, e. g. : . SUFFIX: . foo. bar 40
Special Macros • These are macros defined internally for each dependency line: $@ full name of current target $* basename of current target (i. e. , target without its file extension) $< (inference rules) the single prerequisite that causes execution of the rule $? list of all prerequisites newer than target • Example: . dvi. ps: dvips $< -o $*. ps describes how to create a. ps file from a. dvi file. 41
Gnu Make String Functions • General syntax: $(func. Name args or ${func. Name args} • Most useful for us: – $(subst from. Str, to. Str, txt. Str) • replaces each occurrence of from. Str by to. Str in txt. Str – $(patsubst pattern, replacement, txt. Str) • finds whitespace-separated words in txt. Str that match pattern and replaces them with replacement. “%” can be used as a wildcard. – $(var: suffix=replacement) • replaces suffix at the end of filenames in var by replacement – $(wildcard pattern) • replaced by a space-separated list of file names that match pattern 42
Examples Goal: convert PDF files to HTML using pdftohtml Suffix rules: subst: . pdf. html: pdftohtml $< PDFS = file 1. pdf file 2. pdf file 3. pdf HTMLS = $(subst. pdf, . html, $(PDFS)) all : $(HTMLS) pdftohtml $< patsubst: Suffix replacement: PDFS = file 1. pdf file 2. pdf file 3. pdf HTMLS = $(patsubst %. pdf, %. html, $(PDFS)) PDFS = file 1. pdf file 2. pdf file 3. pdf HTMLS = $(PDFS: pdf=html) all : $(HTMLS) pdftohtml $< 43
Examples • getting all the C files in the directory: CFILES = $(wildcard *. c) 44
Topics not covered • make has a lot of functionality we won’t get to cover, e. g. : – – implicit rules implicit variables conditional parts of make files recursively running make in subdirectories • See online make tutorials for more information 45
- Slides: 45