module.o: module.c module.h useful.h cc -c -g module.cspecifies that module.o can be created if the files named module.c, module.h, & useful.h all exist. The command(s) to create module.o appear below.
T: p0 p1 ... pN B where T is a target p0, p1, ..., pN are prequisites B is a build action
boolean make(group G) buildFlag = false foreach p in {p0, p1, ..., pN} if there is a target for p if make(p) buildFlag = true else if there is a file p if T < p buildFlag = true else Error: cannot make p if buildFlag or file T does not exist execute B return true else return false
NAME = DEFINITIONFor example, we can put the following definition near the top of the Makefile:
CFLAGS = -gand rewrite our target/prerequisite groups like this:
module.o: module.c module.h useful.h cc -c $(CFLAGS) module.c
make CFLAGS=-O
CFILES = main.c module.c useful.c useless.c input.c output.c HFILES = module.h useful.h useless.h input.h output.h SRCFILES = $(CFILES) $(HFILES) OBJFILES = main.o module.o useful.o useless.o input.o output.o TARGET = bigProg CFLAGS = -g $(TARGET): $(OBJFILES) cc -o $(TARGET) $(CFLAGS) $(OBJFILES) printAll: $(SRCFILES) lpr -Pmyprinter $(SRCFILES) module.o: module.c module.h useful.h cc -c $(CFLAGS) module.c ## remainder of Makefile omittedNote that macros have been used for both targets and prerequisites where appropriate. Further note the target printAll in the above example. When the command
make printAllis executed, make will look for a file named printAll and it will presumably not find one. It therefore executes the Unix command listed below the target name. The command causes all the source code files to be printed. It does not create a file named printAll. This is OK. If we subsequently type
make printAllagain, we will produce another source code listing. I.e., we have tricked make into performing a useful task without actually making anything.
module.o: module.h useful.hI.e., we do not have to say that module.c is needed as a prerequisite for module.o. If make is asked to build module.o (either directly or indirectly), it will check to see if there are any files named module.c, module.f, module.p ... in the current directory. If it finds a file named module.c, it will automatically execute the command:
$(CC) $(CFLAGS) $(CPPFLAGS) -c module.cwhere CC is a macro that is defined, by default, to be cc, and CFLAGS and CPPFLAGS are defined to be empty strings.
$(FC) $(FFLAGS) $(CPPFLAGS) -c module.fand so on.
.c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $<This says that if make needs to create a file with the `.o' suffix from a file with the `.c' suffix then it should run the command(s) listed below.
$< | the full name of the input file to the dependency rule. |
$* | same as $< but with the suffix removed. |
$@ | the full name of the current target. |
$? | a list of prerequisites for the rule that are newer than the target. |
.SUFFIXES: .tex .dvi .tex.dvi: latex $<The first line tells make that it now has to handle files with ``.tex'' and ``.dvi'' suffixes in addition to all the suffixes that it already handles.
make mydoc.dviIf no explicit rule specifying mydoc.dvi appears in the Makefile, and if a file named mydoc.tex exists in the current directory, make will apply our default rule and execute:
latex mydoc.tex
SHELL = /bin/cshnear the beginning of the Makefile.
module.o: module.c module.h useful.h -cc -c $(CFLAGS) module.c
module.o: module.c module.h useful.h @cc -c $(CFLAGS) module.c
makeNow suppose that you decide to fix up the comments in file foo.h. The next time you run make, all the files that depend on foo.h will be re-compiled unnecessarily. (The comment changes should not affect the program at all.)
make -tthen make will reset all the timestamps on the files so that everything will appear to be up-to-date (and nothing needs to be recompiled). Make accomplishes this task by executing commands like:
touch subr.oThe touch command updates the named file by replacing the first byte in the file with itself. I.e., the file's contents do not change, but the modification time does.
make -d myprogcauses debugging information to be output.
make -nwill display all the actions that make would perform in creating its target without actually performing those actions. The ``-n'' flag is useful for debugging Makefiles.