Chapter 5: Writing Recipes in Rules
51
system. For example, suppose you have a sub-directory subdir which has its own makefile,
and you would like the containing directory’s makefile to run make on the sub-directory.
You can do it by writing this:
subsystem:
cd subdir && $(MAKE)
or, equivalently, this (seeSection9.7[SummaryofOptions],page104):
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, seeSection4.5[Phony
Targets], page 29).
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
Recursive 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.
SeeSection9.3[InsteadofExecutingtheRecipes],page101. 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; seeSection9.3[InsteadofExecution],
page 101.) Following g the usualdefinitionof ‘-t’, a ‘make-t’commandin 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
Pdf to web converter - control SDK system:C# PDF Convert to HTML SDK: Convert PDF to html files in C#.net, ASP.NET MVC, WinForms, WPF application
How to Convert PDF to HTML Webpage with C# PDF Conversion SDK
www.rasteredge.com
Pdf to web converter - control SDK system:VB.NET PDF Convert to HTML SDK: Convert PDF to html files in vb.net, ASP.NET MVC, WinForms, WPF application
PDF to HTML Webpage Converter SDK for VB.NET PDF to HTML Conversion
www.rasteredge.com
52
GNU make
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
(seeSection5.7.3[CommunicatingOptions toa Sub-make],page54), so your request to
touch the files, or print the recipes, is propagated to the subsystem.
5.7.2 Communicating Variables to a Sub-make
Variable values of the top-level make can be passedto the sub-make throughthe environment
by explicit request. These variables are defined in the sub-make as defaults, but they do
not override variables defined in the makefile used by the sub-make unless you use the ‘-e’
switch (seeSection9.7[SummaryofOptions],page104).
To pass down, or export, a variable, make adds the variable and its value to the envi-
ronment for running each line of the recipe. The sub-make, in turn, uses the environment
to initialize its table of variable values. SeeSection6.10[VariablesfromtheEnvironment],
page 70.
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 let-
ters, 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. SeeSection5.3.2
[Choosing the Shell], page 45.
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 the next section.
Variables are not normally passed down if they were created by default by make (see
Section 10.3 [Variables Used by Implicit Rules], page 115). Thesub-makewilldefinethese
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:
control SDK system:C# PDF: How to Create PDF Document Viewer in C#.NET with
NET Framework version 2.0 and above. Creating C# PDF Web / Windows / Mobile Viewer. C#.NET PDF Document Web Viewer, C#.NET PDF Document Mobile Viewer.
www.rasteredge.com
control SDK system:Online Convert PDF to Jpeg images. Best free online PDF JPEG
Online PDF to JPEG Converter. Download Free Trial. Web Security. Your PDF and JPG files will be deleted from our servers an hour after the conversion.
www.rasteredge.com
Chapter 5: Writing Recipes in Rules
53
variable := value
export variable
Likewise,
export variable += value
is just like:
variable += value
export variable
SeeSection6.6[AppendingMoreTexttoVariables],page66.
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 makes, 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 (seeChapter7[Con-
ditional Parts of Makefiles], page 77);thiswayyoucanwriteamakefilethatbehavesone
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-levelmakefile, is passed downthrough 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 3.4 [The Variable MAKEFILES], page 14.
control SDK system:DocImage SDK for .NET: Web Document Image Viewer Online Demo
Please click Browse to upload a file to display in web viewer. Suppported files are Word, Excel, PowerPoint, PDF, Tiff, Dicom and main raster image formats.
www.rasteredge.com
control SDK system:C# Image: Guide for Customizaing Options in Web Viewer
RasterEdge .NET Web Viewer Library for C# provides Visual C# programmers with two modes to display PDF, Office Word, Excel, and PowerPoint files.
www.rasteredge.com
54
GNU make
5.7.3 Communicating Options to a Sub-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. SeeSection9.7[SummaryofOptions],page104.
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 9.5 [Overriding
Variables], page 103.
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 (seeSection5.4[ParallelExecution],page47). 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-makes 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 (seeSection9.3[InsteadofExecutingRecipes],page101)
doesn’t count against the total jobs (otherwise we could get ‘N’ sub-makes 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-makes, 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, youmust 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 defini-
tions, 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
control SDK system:C# Image: Create Web Image Viewer in C#.NET Application
If needed, you can view detailed guidance on how to create a PDF web viewer, how to view TIFF document image file online and how to create an online web
www.rasteredge.com
control SDK system:C#: How to Add HTML5 Document Viewer Control to Your Web Page
are to load the necessary resources for creating web document viewer events take RE default var _userCmdDemoPdf = new UserCommand("pdf"); _userCmdDemoPdf.addCSS
www.rasteredge.com
Chapter 5: Writing Recipes in Rules
55
‘--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 compat-
ible 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’ (seeSection9.7[SummaryofOptions],page104), 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 make-
files 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.
If you’d like to run other implementations of make in addition to GNU make, and hence
do not want to add GNU make-specific flags to the MAKEFLAGS variable, you can add them
to the GNUMAKEFLAGS variable instead. This variable is parsed just before MAKEFLAGS, in
the same way as MAKEFLAGS. When make constructs MAKEFLAGS to pass to a recursive make
it will include all flags, even those taken from GNUMAKEFLAGS. As a result, after parsing
GNUMAKEFLAGS GNU make sets this variable to the empty string to avoid duplicating flags
during recursion.
It’s best to use GNUMAKEFLAGS only with flags which won’t materially change the be-
havior of your makefiles. If your makefiles require GNU make anyway then simply use
MAKEFLAGS. Flags such as ‘--no-print-directory’ or ‘--output-sync’ may be appropri-
ate for GNUMAKEFLAGS.
5.7.4 The ‘--print-directory’ Option
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.
control SDK system:C#: How to Determine the Display Format for Web Doucment Viewing
All Formats. XDoc.HTML5 Viewer. XDoc.Windows Viewer. XDoc.Converter. View & Process. RasterEdge web document viewer for .NET can convert PDF, Word, Excel and
www.rasteredge.com
control SDK system:C# Image: How to Integrate Web Document and Image Viewer
0.pdf: from this user manual, you can find the detailed instructions and explanations for why & how to create & insert a professional .NET web document image
www.rasteredge.com
56
GNU make
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-makes. 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.
5.8 Defining Canned Recipes
When the same sequence of commands is useful in making various targets, you can define
it as a canned sequence with the define directive, and refer to the canned sequence from
the recipes for those targets. The canned sequence is actually a variable, so the name must
not conflict with other variable names.
Here is an example of defining a canned recipe:
define run-yacc =
yacc $(firstword $^)
mv y.tab.c $@
endef
Here run-yacc is the name of the variable being defined; endef marks the end of the
definition; the lines in between are the commands. The define directive does not expand
variable references and functioncalls in the canned sequence; the ‘$’characters, parentheses,
variable names, and so on, all become part of the value of the variable you are defining. See
Section 6.8 [Defining Multi-Line Variables], page 69,foracompleteexplanationofdefine.
The first command in this example runs Yacc on the first prerequisite of whichever rule
uses the canned sequence. The output file from Yacc is always named y.tab.c. The second
command moves the output to the rule’s target file name.
To use the canned sequence, substitute the variable into the recipe of a rule. You
can substitute it like any other variable (see Section6.1 [Basics of Variable References],
page 59). Becausevariablesdefinedbydefine e arerecursivelyexpandedvariables,allthe
variable references you wrote inside the define are expanded now. For example:
foo.c : foo.y
$(run-yacc)
‘foo.y’ will be substituted for the variable ‘$^’ when it occurs in run-yacc’s value, and
‘foo.c’ for ‘$@’.
This is a realistic example, but this particular one is not needed in practice because
make has an implicit rule to figure out these commands based on the file names involved
(seeChapter10[UsingImplicitRules],page111).
In recipe execution, each line of a canned sequence is treated just as if the line appeared
on its own inthe rule, preceded by a tab. In particular, make invokes a separate sub-shellfor
each line. You can use the special prefix characters that affect command lines (‘@’, ‘-’, and
‘+’) on each line of a canned sequence. SeeChapter5[WritingRecipesinRules],page41.
For example, using this canned sequence:
define frobnicate =
@echo "frobnicating target $@"
frob-step-1 $< -o $@-step-1
frob-step-2 $@-step-1 -o $@
endef
control SDK system:C# Image: Save or Print Document and Image in Web Viewer
If there's no printer connected or your web browser doesn't support document or image printing, you can only preview it on web viewer in PDF or TIFF format.
www.rasteredge.com
Chapter 5: Writing Recipes in Rules
57
make will not echo the first line, the echo command. But it will echo the following two
recipe lines.
On the other hand, prefix characters on the recipe line that refers to a canned sequence
apply to every line in the sequence. So the rule:
frob.out: frob.in
@$(frobnicate)
does not echo any recipe lines. (See Section 5.2 [Recipe e Echoing], , page e 43, for a full
explanation of ‘@’.)
5.9 Using Empty Recipes
It is sometimes useful to define recipes which do nothing. This is done simply by giving a
recipe that consists of nothing but whitespace. For example:
target: ;
defines an empty recipe for target. You could also use a line beginning with a recipe prefix
character to define an empty recipe, but this would be confusing because such a line looks
empty.
You may be wondering why you would want to define a recipe that does nothing. The
only reason this is useful is to prevent a target from getting implicit recipes (from implicit
rules or the .DEFAULT special target; see Chapter 10 [Implicit Rules], , page 111 and see
Section 10.6 [Defining Last-Resort Default Rules], page 125).
You may be inclined to define empty recipes for targets that are not actual files, but
only exist so that their prerequisites can be remade. However, this is not the best way to
do that, because the prerequisites may not be remade properly if the target file actually
does exist. SeeSection4.5[PhonyTargets],page29, for a better way to do this.
Chapter 6: How to Use Variables
59
6 How to Use Variables
Avariable is a name defined in a makefile to represent a string of text, called the variable’s
value. These values are substituted by explicit request into targets, prerequisites, recipes,
and other parts of the makefile. (In some other versions of make,variables are called macros.)
Variables and functions in all parts of a makefile are expanded when read, except for
in recipes, the right-hand sides of variable definitions using ‘=’, and the bodies of variable
definitions using the define directive.
Variables can represent lists of file names, options to pass to compilers, programs to run,
directories to look in for source files, directories to write output in, or anything else you can
imagine.
Avariable name may be any sequence of characters not containing ‘:’, ‘#’, ‘=’, or white-
space. However, variable names containing characters other than letters, numbers, and
underscores should be considered carefully, as in some shells they cannot be passed through
the environment to a sub-make (seeSection5.7.2[CommunicatingVariablestoaSub-make],
page 52). Variablenamesbeginningwith‘.’andanuppercaselettermaybegivenspecial
meaning in future versions of make.
Variable names are case-sensitive. The names ‘foo’, ‘FOO’, and ‘Foo’ all refer to different
variables.
It is traditionalto use upper caseletters in variable names, but we recommendusinglower
case letters for variable names that serve internal purposes in the makefile, and reserving
upper case for parameters that control implicit rules or for parameters that the user should
override with command options (seeSection9.5[OverridingVariables],page103).
Afew variables have names that are a single punctuation character or just a few char-
acters. These are the automatic variables, and they have particular specialized uses. See
Section 10.5.3 [Automatic Variables], page 120.
6.1 Basics of Variable References
To substitute a variable’s value, write a dollar sign followed by the name of the variable in
parentheses or braces: either ‘$(foo)’ or ‘${foo}’ is a valid reference to the variable foo.
This special significance of ‘$’ is why you must write ‘$$’ to have the effect of a single dollar
sign in a file name or recipe.
Variable references can be used in any context: targets, prerequisites, recipes, most
directives, and new variable values. Here is an example of a common case, where a variable
holds the names of all the object files in a program:
objects = program.o foo.o utils.o
program : $(objects)
cc -o program $(objects)
$(objects) : defs.h
Variable references work by strict textual substitution. Thus, the rule
foo = c
prog.o : prog.$(foo)
$(foo)$(foo) -$(foo) prog.$(foo)
60
GNU make
could be used to compile a C program prog.c. Since spaces before the variable value are
ignored in variable assignments, the value of foo is precisely ‘c’. (Don’t actually write your
makefiles this way!)
Adollar sign followed by a character other than a dollar sign, open-parenthesis or open-
brace treats that single character as the variable name. Thus, you could reference the
variable x with ‘$x’. However, this practice is strongly discouraged, except in the case of
the automatic variables (seeSection10.5.3[AutomaticVariables],page120).
6.2 The Two Flavors of Variables
There are two ways that a variable in GNU make can have a value; we call them the two
flavors of variables. The two flavors are distinguished in how they are defined and in what
they do when expanded.
The first flavor of variable is a recursively expanded variable. Variables of this sort are
defined by lines using ‘=’ (seeSection6.5 [SettingVariables],page65) or by the define
directive (seeSection6.8[DefiningMulti-LineVariables],page69). The value you specify is
installed verbatim; if it contains references to other variables, these references are expanded
whenever this variable is substituted (in the course of expanding some other string). When
this happens, it is called recursive expansion.
For example,
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo)
will echo ‘Huh?’: ‘$(foo)’ expands to ‘$(bar)’ which expands to ‘$(ugh)’ which finally
expands to ‘Huh?’.
This flavor of variable is the only sort supported by most other versions of make. It has
its advantages and its disadvantages. An advantage (most would say) is that:
CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar
will do what was intended: when ‘CFLAGS’ is expanded in a recipe, it will expand to ‘-Ifoo
-Ibar -O’. A major disadvantage is that you cannot append something on the end of a
variable, as in
CFLAGS = $(CFLAGS) -O
because it will cause an infinite loop in the variable expansion. (Actually make detects the
infinite loop and reports an error.)
Another disadvantage is that any functions (seeChapter8[FunctionsforTransforming
Text], page 83) referenced in the definition will be executed every time the e variable e is
expanded. This makes make run slower; worse, it causes the wildcard and shell functions
to give unpredictable results because you cannot easily control when they are called, or
even how many times.
To avoid all the problems and inconveniences of recursively expanded variables, there is
another flavor: simply expanded variables.
Documents you may be interested
Documents you may be interested