Help you learn how to use the GNU make tool to automate the program build process
Loukides and Oram, Chapter 7
Study a series of examples, each of which introduces a new feature of make
mystring mystring.h mystring.c testmystring.c makefile1 makefile2 makefile3 makefile4 makefile5 makefile
Earlier: Splitting a program into multiple files allows partial builds
Now: How to automate the partial builds?
Consider the program build process...
Approach 1: Use source files to build executable files directly
Example: see Motivation for "make" (Part 1)
But that's not the way it's done in the "real world"...
Approach 2: Use source files to build object files; use object files to build executable files
Example: see Motivation for "make" (Part 2)
Note: After changing a source file, only those files that depend on it must be rebuilt
Observation
Doing partial builds manually would be tedious and error-prone
Would be handy if there were a tool that could do partial builds automatically
How would it work?
Input: dependency graph, commands necessary to do builds of each file, file date/time stamps
Algorithm: if file B depends on A, and the date/time stamp of A is newer than the date/time stamp of B, then rebuild B using the appropriate command
Such a tool exists...
The make tool
Automates program build process
User specifies file dependencies and build commands
make
Analyzes file dependencies and file date/time stamps to determine which files need to be built
Builds them using specified build commands
(make can perform other maintenance tasks as well)
Syntax: make [-f makefile] [target]
makefile
Text file that contains specialized commands to make
make commands specify file dependencies and build commands
Default makefile is "makefile", then "Makefile"
target
What the make tool should build
Example: an object file
Example: an executable binary file
Default target is the first target defined in the makefile
Syntax:
target: dependents commandCommand must be on separate line
Command line must begin with a tab character
Semantics:
Build target iff it is older than any of its dependencies
Use command to do the build
Recursive!!!
Example: See makefile1
make -f makefile1 testmystring ls testmystring make -f makefile1 testmystringgdb ls testmystringgdb touch mystring.c make -f makefile1 testmystring (note that only mystring.o, mystring.do, testmystring, and testmystringgdb are rebuilt make -f makefile1 testmystring (note that no files are rebuilt) make -f makefile1 (note that default target is first one)
Can use "dummy" (non-file) targets
A non-file target is always out of date
Example: See makefile2
make -f makefile2 clean make -f makefile2 clobber make -f makefile2 release make -f makefile2 all make -f makefile2
Note: Can use non-file targets for all program maintenance tasks
release, install, submit, print, test
$@ stands for the target
Somewhat useful as shown
More useful in pattern rules (as described later)
$< stands for the first dependency file
Somewhat useful as shown
More useful in pattern rules (as described later)
Example: See makefile3
More succinct, but less understandable
make has default commands
Can omit command from dependency rules
Example: default for producing a .o file from a .c file is: cc -o whatever.o whatever.c
Note: Default uses cc command, not gcc command
Best not to rely on default
You can define your own "pattern rules" to override default rules
Can eliminate much redundancy
Example: See makefile4
Behavior is exactly same as makefile3
More succinct, less redundant, more maintainable
make tool macro facility: similar to C preprocessor #define facility
To define a macro:
macroname = macrodefinition
To call a macro
$(macroname)
Example: See makefile5
Perhaps more maintainable
Less understandable; I don't like
Example: See makefile
make clobber make
Copyright © 2002 by Robert M. Dondero, Jr.