Introduction to Make
Pages: 1, 2
In software development, it's very convenient to create a script to remove old compiled code so that the next build recompiles everything. It's also convenient to have a script for installing the code. Make allows scripts like this to be included in the makefile, as phony targets. Phony targets may have prerequisites, and may themselves be prerequisites.
The special rule
.PHONY tells Make which targets are not files. This avoids conflict with files of the same name, and improves performance.
If a phony target is included as a prerequisite for another target, it will be run every time that other target is required. Phony targets are never up-to-date.
To run a phony target from the command line, call Make with the name of the phony target, e.g.:
# Naming our phony targets .PHONY: clean install # Removing the executable and the object files clean: rm sample main.o example.o echo clean: make complete # Installing the final product install: cp sample /usr/local echo install: make complete
As a project gets larger, more files are usually added. If you repeat a list of files, you can accidentally leave files out of the list. It's simpler to make use of a variable that expands into the list.
The syntax for declaring and setting a makefile variable is
varname = variable contents. To call the variable, use
# Defining the object files objects = main.o example.o # Linking object files sample: $(objects) cc -o sample $(objects) echo sample: make complete # Compiling source files main.o: main.c main.h cc -c main.c example.o: example.c defs.h cc -c example.c # Removing the executable and the object files clean: rm sample $(objects) echo clean: make complete
There are a few touches which make the difference between a usable and a professional makefile. The next example adds those extra touches.
# 1 # Defining the compiler: CC=gcc # Defining the object files: objects = main.o example.o # 2 # The default rule - compiling our main program: all: sample echo all: make complete # 3 sample: $(objects) # If we get here, all the dependencies are now built. # Link it: $(CC) -o $@ $+ # 4 # Tell make how to build .o files from .c files: %.o:%.c $(CC) -c $+ # 5 #Now make sure that make rebuilds files if included headers change: main.o: main.h defs.h example.o: example.h defs.h
Use a variable for the compiler, in case you want to use the same makefile with a different compiler.
When called without a rule parameter, Make runs the first rule it encounters. It is more human-readable to explicitly state your first rule.
allis a common name for a first rule.
The automatic variable
$@means "the name of the target." The automatic variable
$+means "all prerequisites, space-separated." Automatic variables are pre-defined in Make.
A pattern rule tells make how to convert the prerequisite to the target. The
%in the pattern means "one or more characters," and refers to the same string in the prerequisite and the target. This particular pattern tells make how to convert a
*.cfile to a
*.ofile of the same name.
The automatic variable
$+means "all prerequisites, space-separated."
These rules are relying on "implicit rules." Make has built-in patterns for converting a
*.hfile to the dependent
*.o. These rules are included to define the prerequisites for the relevant
Caveats and Gotchas
- This article is written about GNU Make. Other Unix systems use different versions of Make, which may have minor variations.
- Make rules require a tab at the beginning of each command. A series of spaces doesn't work.
- Make works backwards from the target to the prerequisites.
Make has many features I haven't mentioned, and is useful in any situation where a file is dependent on files that may change. Experiment, and develop your own interesting variations on makefiles.
- The University of Utah's document on makefile conventions, at http://www.math.utah.edu/docs/info/make-stds_toc.html
- The University of Hawaii's makefile tutorial
- Run a Web search with the keyword "makefile."
Jennifer Vesperman is the author of Essential CVS. She writes for the O'Reilly Network, the Linux Documentation Project, and occasionally Linux.Com.
Return to the Linux DevCenter.