The first target defined in the Makefile is the default goal, but you can pass one or more goals on the command-line instead, in which case they will be built in the order specified (and available in
lower_case names for private variables, and
UPPER_CASE names for variables used by implicit rules (like
CFLAGS) or for variables meant to be overridden by command-line parameters (like
Make variables come in two flavors: recursively expanded (
foo = bar) and simply expanded (
foo := bar).
Recursively expanded variables are expanded every time they’re substituted. Consequently, something like this won’t work (because it’s infinite recursion):
foo = $(foo) bar
but this will work (because of the lazy evaluation):
foo = $(bar) bar = blee
Simply expanded variables are expanded just once, during the first pass.
To define a variable iff it doesn’t already exist, use the conditional definition operator:
foo ?= bar
Passing a variable on the command-line overrides any definitions of that variable in the Makefile:
$ cat Makefile FOO = bar all: $(info $(FOO)) $ make bar $ make FOO=blee blee
Environment variables are automatically defined as make variables, unless a variable of the same name is explicitly defined in the Makefile or passed on the make command-line. All make variables are passed as environment variables to recipe sub-shells, except for recursive make invocations, which only receive variables in the parent environment or passed on the command-line (although you can use
export to communicate variables to sub-makes).
Makefiles can include other Makefiles:
other.mk doesn’t have to exist, so long as there’s a rule to build it. If an included Makefile is rebuilt, Make will start over from scratch in order to pick up the changes.