GNU Make
GNU make
The make utility automatically determines which pieces of a large
program need to be recompiled, and issues commands to recompile them.
Our examples show C programs, since they are most common, but you
can use make with any programming language whose compiler can be run
with a shell command. Indeed, make is not limited to programs. You can
use it to describe any task where some files must be updated
automatically from others whenever the others change.
These are macro definitions, which will be used later;
# Define library name, an archive of the object files
LIB = libdiffops.a
# Define Name of final executable files
EXE_FILE = GDOcall.exe
# Source files
CFILES = GDO_IO.c compute_diffops.c determine_incident_halfedges.c
determine_opposite_triangle.c eval_curvature_explicit.c eval_vander.c
obtain_nring.c polyfit2.c polyfit2_grad.c polyfit2_grad_point.c
polyfit2_point.c virtual_split.c
# Source files from Agility
AGILITY_CFILES = ct_arith_m2c.c ct_display_m2c.c ct_fxp.c ct_runtime_m2c.c
# Source file containing main funciton
EXTRA_CFILES = GDOcall.c
A substitution reference substitutes the value of a variable with alterations that you specify.
# Define object files
OBJS = $(CFILES:.c=.o) $(AGILITY_CFILES:.c=.o)
# .c=.o change all the suffix of CFILES from .c to .o
# set search path
vpath %.c src test Agility
# search source file in srt test Agility directories
# %.c means all the files with suffix .c
# similarly, VPATH command can also set search path, but can not specify file types;
# VPATH=src test Agility include
# use gcc
CC = gcc
# set search paths for header files
CPPFLAGS = -Iinclude -IAgility
# the compiler will find the header files in include and Agility directories
# Define Optimiation Option
COPT = -O3
# COPT = -g -Wall for debugging
CFLAGS =
# generating archive
AR = ar cr
# cr means create and replace
ARFLAGS =
#ranlib - generate index to archive.
RANLIB = ranlib
# An archive with such an index speeds up linking to the library
# and allows routines in the library to call each other without
# regard to their placement in the archive.
+
targets : prerequisites
command
A target is out of date if it does not exist or if it is older than
any of the prerequisites (by comparison of last-modification times), if
so target need to be updated.
How to update is specified by commands.
# define the final target
all: $(EXE_FILE)
# make = make all
# generate object files for all the source files
%.o : %.c
$(CC) $(CPPFLAGS) $(COPT) $(CFLAGS) -c $< -o $@
# archive command generates library files
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $(LIB) $^
$(RANLIB) $@
# generate executable file
$(EXE_FILE): $(EXTRA_CFILES:.c=.o) $(LIB)
$(CC)
-o $(EXE_FILE) $(COPT) $(CFLAGS) $(EXTRA_CFILES:.c=.o) -L. -ldiffops -lm
+ Phony Targets
# clean is not a file, and no prerequisites files are placed, so if we want to execute the
# following command we must explicit specify the command: make clean
# this will clean all the object(.o) library(.a) and the executable file
clean:
-$(RM)
-rf *.o $(EXE_FILE) $(LIB)
Why use Automatic Variables?
Suppose you are writing a pattern rule to compile a `.c' file into a
`.o' file, how do you write the `cc' command so that it operates on the
right source file name?
You can not use macro because gcc can only compile one object file per time; $(CC) -c $(CFILES) -o $(OBJS) will not work.
You cannot write the name in the command, because the name is different each time the implicit rule is applied.
What you do is use a special feature of make, the automatic
variables. These variables have values computed afresh for each rule
that is executed, based on the target and prerequisites of the rule.
In this example, you would use `$@' for the object file name and `$<' for the source file name.
$(CC) -c $< -o $@
+
Some useful Automatic Variables
$@ The file name of the target of the rule. In
a pattern rule that has multiple targets , `$@' is the name of
whichever target caused the rule's commands to be run.
$< The name of the first prerequisite that are newer than the target.
$? The names of all the prerequisites that are newer than the target, with spaces between them.
$^ The names of all the prerequisites, with spaces between them.
# this will generate object files from source files that has been changed
%.o : %.c
$(CC)
$(CPPFLAGS) $(COPT) $(CFLAGS) -c $< -o $@
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $(LIB) $^
$(RANLIB) $@