A very common way to influence the operation of a Makefile
is through the use of variables,
so it's useful to know the tricky rules regarding them.
Specifying variables
Values can come from command line parameters, assignment in the Makefile, from the environment, or be predefined. In addition the precedence from highest to lowest follows that order. I.E. if you do make CFLAGS=blah, that will override any CFLAGS assigned in the Makefile, whereas if you do CC=gcc in the Makefile, then any CC environment variable will be ignored which is often problematic. There are also predefined variables which one can see with make -p.To demonstrate the various methods for specifying variables and the associated precedence rules I'll use this Makefile:
static := $(recurse) #empty at assignment time, so 'static' remains empty recurse = $(_recurse) _recurse = recurse condit ?= condit append += append override pappend += pappend #handle parameters to `make` .PHONY: all all: @echo $(CC) $(recurse) $(condit) $(append) $(pappend)
Running the Makefile above with various command lines gives this output:
command | builtin | = | ?= | += | override |
make | cc | recurse | condit | append | pappend |
recurse=RECURSE make | cc | recurse | condit | append | pappend |
recurse=RECURSE make -e | cc | RECURSE | condit | append | pappend |
CC=CC make | CC | recurse | condit | append | pappend |
condit=CONDIT make | cc | recurse | CONDIT | append | pappend |
make recurse=RECURSE | cc | RECURSE | condit | append | pappend |
append=APPEND make | cc | recurse | condit | APPEND append | pappend |
make append=APPEND | cc | recurse | condit | APPEND | pappend |
make pappend=PAPPEND | cc | recurse | condit | append | PAPPEND pappend |
Common variables
There are a few defacto standard variables for controlling Makefile operationCC
This is a builtin variable which on my system with ccache installed is resolved as: $(CC) = cc => /usr/lib/ccache/cc -> ccache => /usr/bin/cc -> gcc. Alternatively the variable can be overridden using the environment which is the case when running the clang static analyzer like: scan-build -o clang makeCFLAGS
This usually specifies compiler flags and is often appended to, so take special note of the append examples in the table above. Here is an example to issue a build with the same CFLAGS as what the coreutils package was built with: CFLAGS=$(rpm -q --qf="%{OPTFLAGS}" coreutils) makeDESTDIR
This often controls the prefix used by the install target. I.E. where the files are temporarily installed to, which is useful for testing or for package creation scripts etc. Note this doesn't influence relative references within a project, which is usually controlled with ./configure --prefix=...Inspecting variables
[Update Dec 2010: This excellent post on inspecting make variables details a wrapper script you can use with any Makefile to output values and even the origins of a variable. In summary, you can add the following to your Makefile to support make print-MAKE_VERSION.# sed is used to highlight "unusual" chars like (trailing) spaces etc. # This works on GNU and BSD and falls back to cat on solaris. print-%: @printf '%s=%s\n' '$*' '$($*)' | \ { ESC=$$(printf '\033'); \ sed "s/[^[:digit:][:alpha:].=/_-]/$$ESC[7m&$$ESC[m/g" \ 2>/dev/null || cat; } @echo ' origin = $(origin $*)' @echo ' flavor = $(flavor $*)' @echo ' value = $(value $*)'Also useful to inspect make variables is the gmake --print-data-base option.]
© Nov 14 2009