[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
make
Recursive use of make
means using make
as a command in a
makefile. This technique is useful when you want separate makefiles for
various subsystems that compose a larger system. For example, suppose you
have a subdirectory ‘subdir’ which has its own makefile, and you would
like the containing directory’s makefile to run make
on the
subdirectory. You can do it by writing this:
subsystem: cd subdir && $(MAKE) |
or, equivalently, this (see section Summary of Options):
subsystem: $(MAKE) -C subdir |
You can write recursive make
commands just by copying this example,
but there are many things to know about how they work and why, and about
how the sub-make
relates to the top-level make
. You may
also find it useful to declare targets that invoke recursive
make
commands as ‘.PHONY’ (for more discussion on when
this is useful, see Phony Targets).
For your convenience, when GNU make
starts (after it has
processed any -C
options) it sets the variable CURDIR
to
the pathname of the current working directory. This value is never
touched by make
again: in particular note that if you include
files from other directories the value of CURDIR
does not
change. The value has the same precedence it would have if it were
set in the makefile (by default, an environment variable CURDIR
will not override this value). Note that setting this variable has no
impact on the operation of make
(it does not cause make
to change its working directory, for example).
5.7.1 How the MAKE Variable Works | The special effects of using ‘$(MAKE)’. | |
5.7.2 Communicating Variables to a Sub-make | How to communicate variables to a sub-make .
| |
5.7.3 Communicating Options to a Sub-make | How to communicate options to a sub-make .
| |
5.7.4 The ‘--print-directory’ Option | How the ‘-w’ or ‘--print-directory’ option
helps debug use of recursive make commands.
|
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
MAKE
Variable WorksRecursive make
commands should always use the variable MAKE
,
not the explicit command name ‘make’, as shown here:
subsystem: cd subdir && $(MAKE) |
The value of this variable is the file name with which make
was
invoked. If this file name was ‘/bin/make’, then the recipe executed
is ‘cd subdir && /bin/make’. If you use a special version of
make
to run the top-level makefile, the same special version will be
executed for recursive invocations.
As a special feature, using the variable MAKE
in the recipe of
a rule alters the effects of the ‘-t’ (‘--touch’), ‘-n’
(‘--just-print’), or ‘-q’ (‘--question’) option.
Using the MAKE
variable has the same effect as using a ‘+’
character at the beginning of the recipe line. See section Instead of Executing the Recipes. This special feature
is only enabled if the MAKE
variable appears directly in the
recipe: it does not apply if the MAKE
variable is referenced
through expansion of another variable. In the latter case you must
use the ‘+’ token to get these special effects.
Consider the command ‘make -t’ in the above example. (The ‘-t’ option marks targets as up to date without actually running any recipes; see Instead of Executing Recipes.) Following the usual definition of ‘-t’, a ‘make -t’ command in the example would create a file named ‘subsystem’ and do nothing else. What you really want it to do is run ‘cd subdir && make -t’; but that would require executing the recipe, and ‘-t’ says not to execute recipes.
The special feature makes this do what you want: whenever a recipe
line of a rule contains the variable MAKE
, the flags ‘-t’,
‘-n’ and ‘-q’ do not apply to that line. Recipe lines
containing MAKE
are executed normally despite the presence of a
flag that causes most recipes not to be run. The usual
MAKEFLAGS
mechanism passes the flags to the sub-make
(see section Communicating Options to a Sub-make
), so your request to touch the files, or print the
recipes, is propagated to the subsystem.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
make
Variable values of the top-level make
can be passed to the
sub-make
through the environment by explicit request. These
variables are defined in the sub-make
as defaults, but do not
override what is specified in the makefile used by the sub-make
makefile unless you use the ‘-e’ switch (see section Summary of Options).
To pass down, or export, a variable, make
adds the
variable and its value to the environment for running each line of the
recipe. The sub-make
, in turn, uses the environment to
initialize its table of variable values. See section Variables from the Environment.
Except by explicit request, make
exports a variable only if it
is either defined in the environment initially or set on the command
line, and if its name consists only of letters, numbers, and underscores.
Some shells cannot cope with environment variable names consisting of
characters other than letters, numbers, and underscores.
The value of the make
variable SHELL
is not exported.
Instead, the value of the SHELL
variable from the invoking
environment is passed to the sub-make
. You can force
make
to export its value for SHELL
by using the
export
directive, described below. See section Choosing the Shell.
The special variable MAKEFLAGS
is always exported (unless you
unexport it). MAKEFILES
is exported if you set it to anything.
make
automatically passes down variable values that were defined
on the command line, by putting them in the MAKEFLAGS
variable.
See section Communicating Options to a Sub-make
.
Variables are not normally passed down if they were created by
default by make
(see section Variables Used by Implicit Rules). The sub-make
will define these for
itself.
If you want to export specific variables to a sub-make
, use the
export
directive, like this:
export variable … |
If you want to prevent a variable from being exported, use the
unexport
directive, like this:
unexport variable … |
In both of these forms, the arguments to export
and
unexport
are expanded, and so could be variables or functions
which expand to a (list of) variable names to be (un)exported.
As a convenience, you can define a variable and export it at the same time by doing:
export variable = value |
has the same result as:
variable = value export variable |
and
export variable := value |
has the same result as:
variable := value export variable |
Likewise,
export variable += value |
is just like:
variable += value export variable |
See section Appending More Text to Variables.
You may notice that the export
and unexport
directives
work in make
in the same way they work in the shell, sh
.
If you want all variables to be exported by default, you can use
export
by itself:
export |
This tells make
that variables which are not explicitly mentioned
in an export
or unexport
directive should be exported.
Any variable given in an unexport
directive will still not
be exported. If you use export
by itself to export variables by
default, variables whose names contain characters other than
alphanumerics and underscores will not be exported unless specifically
mentioned in an export
directive.
The behavior elicited by an export
directive by itself was the
default in older versions of GNU make
. If your makefiles depend
on this behavior and you want to be compatible with old versions of
make
, you can write a rule for the special target
.EXPORT_ALL_VARIABLES
instead of using the export
directive.
This will be ignored by old make
s, while the export
directive will cause a syntax error.
Likewise, you can use unexport
by itself to tell make
not to export variables by default. Since this is the default
behavior, you would only need to do this if export
had been used
by itself earlier (in an included makefile, perhaps). You
cannot use export
and unexport
by themselves to
have variables exported for some recipes and not for others. The last
export
or unexport
directive that appears by itself
determines the behavior for the entire run of make
.
As a special feature, the variable MAKELEVEL
is changed when it
is passed down from level to level. This variable’s value is a string
which is the depth of the level as a decimal number. The value is
‘0’ for the top-level make
; ‘1’ for a sub-make
,
‘2’ for a sub-sub-make
, and so on. The incrementation
happens when make
sets up the environment for a recipe.
The main use of MAKELEVEL
is to test it in a conditional
directive (see section Conditional Parts of Makefiles); this
way you can write a makefile that behaves one way if run recursively and
another way if run directly by you.
You can use the variable MAKEFILES
to cause all sub-make
commands to use additional makefiles. The value of MAKEFILES
is
a whitespace-separated list of file names. This variable, if defined in
the outer-level makefile, is passed down through the environment; then
it serves as a list of extra makefiles for the sub-make
to read
before the usual or specified ones. See section The Variable MAKEFILES
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
make
Flags such as ‘-s’ and ‘-k’ are passed automatically to the
sub-make
through the variable MAKEFLAGS
. This variable is
set up automatically by make
to contain the flag letters that
make
received. Thus, if you do ‘make -ks’ then
MAKEFLAGS
gets the value ‘ks’.
As a consequence, every sub-make
gets a value for MAKEFLAGS
in its environment. In response, it takes the flags from that value and
processes them as if they had been given as arguments.
See section Summary of Options.
Likewise variables defined on the command line are passed to the
sub-make
through MAKEFLAGS
. Words in the value of
MAKEFLAGS
that contain ‘=’, make
treats as variable
definitions just as if they appeared on the command line.
See section Overriding Variables.
The options ‘-C’, ‘-f’, ‘-o’, and ‘-W’ are not put
into MAKEFLAGS
; these options are not passed down.
The ‘-j’ option is a special case (see section Parallel Execution).
If you set it to some numeric value ‘N’ and your operating system
supports it (most any UNIX system will; others typically won’t), the
parent make
and all the sub-make
s will communicate to
ensure that there are only ‘N’ jobs running at the same time
between them all. Note that any job that is marked recursive
(see section Instead of Executing Recipes)
doesn’t count against the total jobs (otherwise we could get ‘N’
sub-make
s running and have no slots left over for any real work!)
If your operating system doesn’t support the above communication, then
‘-j 1’ is always put into MAKEFLAGS
instead of the value you
specified. This is because if the ‘-j’ option were passed down
to sub-make
s, you would get many more jobs running in parallel
than you asked for. If you give ‘-j’ with no numeric argument,
meaning to run as many jobs as possible in parallel, this is passed
down, since multiple infinities are no more than one.
If you do not want to pass the other flags down, you must change the
value of MAKEFLAGS
, like this:
subsystem: cd subdir && $(MAKE) MAKEFLAGS= |
The command line variable definitions really appear in the variable
MAKEOVERRIDES
, and MAKEFLAGS
contains a reference to this
variable. If you do want to pass flags down normally, but don’t want to
pass down the command line variable definitions, you can reset
MAKEOVERRIDES
to empty, like this:
MAKEOVERRIDES = |
This is not usually useful to do. However, some systems have a small
fixed limit on the size of the environment, and putting so much
information into the value of MAKEFLAGS
can exceed it. If you
see the error message ‘Arg list too long’, this may be the problem.
(For strict compliance with POSIX.2, changing MAKEOVERRIDES
does
not affect MAKEFLAGS
if the special target ‘.POSIX’ appears
in the makefile. You probably do not care about this.)
A similar variable MFLAGS
exists also, for historical
compatibility. It has the same value as MAKEFLAGS
except that it
does not contain the command line variable definitions, and it always
begins with a hyphen unless it is empty (MAKEFLAGS
begins with a
hyphen only when it begins with an option that has no single-letter
version, such as ‘--warn-undefined-variables’). MFLAGS
was
traditionally used explicitly in the recursive make
command, like
this:
subsystem: cd subdir && $(MAKE) $(MFLAGS) |
but now MAKEFLAGS
makes this usage redundant. If you want your
makefiles to be compatible with old make
programs, use this
technique; it will work fine with more modern make
versions too.
The MAKEFLAGS
variable can also be useful if you want to have
certain options, such as ‘-k’ (see section Summary of Options), set each time you run make
. You simply put a value for
MAKEFLAGS
in your environment. You can also set MAKEFLAGS
in
a makefile, to specify additional flags that should also be in effect for
that makefile. (Note that you cannot use MFLAGS
this way. That
variable is set only for compatibility; make
does not interpret a
value you set for it in any way.)
When make
interprets the value of MAKEFLAGS
(either from the
environment or from a makefile), it first prepends a hyphen if the value
does not already begin with one. Then it chops the value into words
separated by blanks, and parses these words as if they were options given
on the command line (except that ‘-C’, ‘-f’, ‘-h’,
‘-o’, ‘-W’, and their long-named versions are ignored; and there
is no error for an invalid option).
If you do put MAKEFLAGS
in your environment, you should be sure not
to include any options that will drastically affect the actions of
make
and undermine the purpose of makefiles and of make
itself. For instance, the ‘-t’, ‘-n’, and ‘-q’ options, if
put in one of these variables, could have disastrous consequences and would
certainly have at least surprising and probably annoying effects.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If you use several levels of recursive make
invocations, the
‘-w’ or ‘--print-directory’ option can make the output a
lot easier to understand by showing each directory as make
starts processing it and as make
finishes processing it. For
example, if ‘make -w’ is run in the directory ‘/u/gnu/make’,
make
will print a line of the form:
make: Entering directory `/u/gnu/make'. |
before doing anything else, and a line of the form:
make: Leaving directory `/u/gnu/make'. |
when processing is completed.
Normally, you do not need to specify this option because ‘make’
does it for you: ‘-w’ is turned on automatically when you use the
‘-C’ option, and in sub-make
s. make
will not
automatically turn on ‘-w’ if you also use ‘-s’, which says to
be silent, or if you use ‘--no-print-directory’ to explicitly
disable it.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Davide Tacchella on November 3, 2010 using texi2html 1.82.