The previous examples generally have a lot of repetitive text. make provides a simple macro mechanism. Macros are defined in a number of ways (listed in increasing order of precedence):
setenv CC "gcc"
There can be no <tab>s before the macro name and no colons before the equal (=) sign.OBJS = main.o sub1.o sub2.o sub3.o
make CC=gcc
There is a special circumstance (using the -e option) when the second and third entries in the list are swapped in precedence.
Macros are used in the Makefile by bracketing the macro name with either parentheses ``()'' or braces ``{}'' and prepending a dollar sign ``$''. If the macro name is a single character the parentheses and braces can be neglected. This is a likely source of errors in Makefiles.
By convention macro names should be uppercase, but lowercase letters, numbers and underscores are safe to use also.
If a macro name is not defined make will just use a null string instead and not complain. This is not an error.
One of the problems with macros is that, unlike a script, macros can not be reassigned a different value halfway through the processing. A macro can not have one value when operating on one target and a different value for another. ``Why?'' This highlights the difference between scripts and make. Scripts are executed in a linear fashion where there is a clear sequence of events to execute. make, on the other hand, defines an inverted tree structure of dependencies with associated commands to create targets. The tree can be traversed either depth-first or level descent; therefore, the order of operations is not necessarily linear. make must read through the entire Makefile before starting any dependency analysis. The last macro declaration defines the overall macro definition to be used everywhere.There are ways to get around this limitation by using a recursive make invocation. However, for most applications it won't be necessary if you design your Makefile script accordingly.
make has several predefined macros that makes rule writing easier and more generalized. However, be careful. The accidental substitution of the wrong macro may cause the overwriting of the source file. In particular, if $< or $? is used when $@ should have been used in the action. The macros of most interest are:Suffix rules will be discussed later.
$@ the name of the file to be ``made'' $? the set of dependent names that are younger than the target $< the name of the related file that caused the action (the precursor to the target) - this is only for suffix rules $* the shared prefix of the target and dependent - only for suffix rules $$ escapes macro substitution, returns a single ``$''. The following example Makefile demonstrates some of these special macros:
Which gives the following output:
# tests of the various built-in macros SRCS = aaa.c bbb.c ccc.c OBJS = ${SRCS:.c=.o} .SILENT : all : xxx yyy xxx : $(SRCS) echo "target ======== $@" echo "all sources = $(SRCS)" echo "newer sources = $?" echo "all objects = $(OBJS)" yyy : *.c echo "target ======== $@" echo "all sources = $(SRCS)" echo "newer sources = $?"The above example shows a couple of new features.% make target ======== xxx all sources = aaa.c bbb.c ccc.c newer sources = aaa.c bbb.c ccc.c all objects = aaa.o bbb.o ccc.o target ======== yyy all sources = aaa.c bbb.c ccc.c newer sources = aaa.c bbb.c ccc.c xxx.c
The first is the limited macro substitutionWhich says to substitute ``.o'' for the last two characters, if they happen to be ``.c'', in the list given by $(SRCS). This provides an easy way to create lists of object files, man page files, executables, etc. from a single list of sources. However, not every make allows this type of substitution. (The Cray, IBM SP, and GNU ones do.)OBJS = ${SRCS:.c=.o}
The target or prerequisites could use file ``globbing'' symbols. The above example shows the prerequisites for yyy as *.c, where * matches any number of characters. The other globbing character is ?, which matches any single character. Note that this does not work reliably if the target uses globbing characters. It works for GNU make, but not for the Cray or IBM SP. It's generally not a good idea to use globbing at all and I have rarely seen Makefiles with it.
There are a number of built-in macros, and they can be listed out with all the various suffix rules and environment variables with:The ones I consider to be the most import are:make -p -f /dev/null
- SHELL
- The shell to use for executing commands. Some makes don't honor it and use /bin/sh anyways. Others will take the users login shell. You should always set this macro and define it to /bin/sh and write your actions appropriately.
- MAKE
- the name of the make command. Only GNU uses the full pathname if specified on the command-line, else just uses command name. Therefore, need to make sure the desired make is found first in the command PATH if trying to use another version of make.
- MAKEFLAGS or MFLAGS
- the options passed to the Makefile. However, it's not done consistently. GNU and Cray pass only the option letters collected together (e.g. ni). IBM SP passes dashed options each separate (e.g. -n -i). GNU puts the dashed options into MFLAGS, a macro not used by the other two!
- VPATH
- a colon (:) separated path of directories to search for prerequisites.
There are numerous macros that refer to various compilers and tools with their associated macro for passing options.
Macro Flags Tool FC/CF/F77 FFLAGS Fortran compiler CC CFLAGS C compiler AS ASFLAGS assembler LD LDFLAGS object loader AR ARFLAGS archiver LEX LFLAGS lexical parser YACC YFLAGS grammar parser This is just a small portion. Except for the Fortran compiler, the rest listed are fairly standard to each implementation. These macros are used by the suffix rules described in the next section.