gnu mak spec

-Wildcard expansion happens automatically in rules. But wildcard expansion does not normally
take place when a variable is set, or inside the arguments of a function. If you want to do wildcard expansion in such places, you need to use the wildcard function, like this:
$(wildcard pattern…)
example
Thus, a makefile to compile all C source files in the directory and then link them together
could be written as follows:

objects := $(patsubst %.c,%.o,$(wildcard *.c))
foo : $(objects)
	cc -o foo $(objects)

-For instance, the value of $ ^ is a list of all the prerequisites of the rule, including the names of the directories in which they were found, and the value of ‘$@’
is the target. Thus:

foo.o : foo.c
	cc -c $(CFLAGS) $^ -o $@

The automatic variable ‘$<’ is just the first prerequisite

4.4.6 Directory Search for Link Libraries

This special
feature comes into play when you write a prerequisite whose name is of the form ‘-lname’.
(You can tell something strange is going on here because the prerequisite is normally the
name of a file, and the file name of a library generally looks like libname.a, not like
‘-lname’.)
When a prerequisite’s name has the form ‘-lname’, make handles it specially by searching for the file libname.so, and, if it is not found, for the file libname.a in the current directory,
in directories specified by matching vpath search paths and the VPATH search path, and then
in the directories /lib, /usr/lib, and prefix/lib
For example, if there is a /usr/lib/libcurses.a library on your system (and no /usr/lib/libcurses.so file), then

foo : foo.c -lcurses
	cc $^ -o $@

The default value for .LIBPATTERNS is ‘lib%.so lib%.a’, which provides the default
behavior described above.

4.5 Phony Targets

A phony target is one that is not really the name of a file; rather it is just a name for a
recipe to be executed when you make an explicit request.

	clean:
		rm *.o temp

In this example, the clean target will not work properly if a file named clean is ever
created in this directory. Sine it has no prerequisites, clean would always be considered
up to date and its recipe would not be executed

5 Writing Recipes in Rules

The recipe of a rule consists of one or more shell command lines to be executed, one at a
time, in the order they appear

  • 5.1 Recipe Syntax
    However, recipes are meant to be interpreted by the shell and so they are written using
    shell syntax. The make program does not try to understand shell syntax: it performs only
    a very few specific translations on the content of the recipe before handing it to the shell

    Some consequences of these rules include:

    • A blank line that begins with a tab is not blank: it’s an empty recipe (see Section 5.9
      [Empty Recipes], page 57).
    • A comment in a recipe is not a make comment; it will be passed to the shell as-is.
      Whether the shell treats it as a comment or not depends on your shell.
    • A variable definition in a “rule context” which is indented by a tab as the first character
      on the line, will be considered part of a recipe, not a make variable definition, and passed
      to the shell.
    • A conditional expression (ifdef, ifeq, etc. see Section 7.2 [Syntax of Conditionals],
      page 78) in a “rule context” which is indented by a tab as the first character on the
      line, will be considered part of a recipe and be passed to the shell.
  • 5.1.2 Using Variables in Recipes
    They also have the same quoting rules: if you want a
    dollar sign to appear in your recipe, you must double it (‘$$’). For shells like the default
    shell, that use dollar signs to introduce variables, it’s important to keep clear in your mind
    whether the variable you want to reference is a make variable (use a single dollar sign) or a
    shell variable (use two dollar signs). For example:

LIST = one two three
all:
for i in $(LIST); do \
echo $$i; \
done

results in the following command being passed to the shell:

for i in one two three; do \
	echo $i; \
done

which generates the expected result:
one
two
three

5.5 Errors in Recipes

If there is an error (the exit status is nonzero), make gives up on the current rule, and
perhaps on all rules.
Sometimes the failure of a certain recipe line does not indicate a problem. For example,
you may use the mkdir command to ensure that a directory exists. If the directory already
exists, mkdir will report an error, but you probably want make to continue regardless.
To ignore errors in a recipe line, write a ‘-’ at the beginning of the line’s text (after the
initial tab). The ‘-’ is discarded before the line is passed to the shell for execution.

For example,

clean:
	-rm -f *.o

This causes make to continue even if rm is unable to remove a file.
When you run make with the ‘-i’ or ‘–ignore-errors’ flag, errors are ignored in all
recipes of all rules. A rule in the makefile for the special target .IGNORE has the same effect,
if there are no prerequisites. These ways of ignoring errors are obsolete because ‘-’ is more
flexible.
When errors are to be ignored, because of either a ‘-’ or the ‘-i’ flag, make treats an
error return just like success, except that it prints out a message that tells you the status
code the shell exited with, and says that the error has been ignored.
if the ‘-k’ or ‘–keep-going’ flag is specified, make continues to consider the
other prerequisites of the pending targets, remaking them if necessary, before it gives up
50 GNU make
and returns nonzero status. For example, after an error in compiling one object file, ‘make
-k’ will continue compiling other object files even though it already knows that linking them
will be impossible.

5.6 Interrupting or Killing make

it need to delete the targets if make is interruptted or killed

5.7.2 Communicating Variables to a Sub-make

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

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.
As a consequence, every sub-make gets a value for MAKEFLAGS in its environment.
Likewise variables defined on the command line are passed to the sub-make through
MAKEFLAGS.
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=

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.

5.8 Defining Canned Recipes

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.
endef

equal to

run-yacc =yacc $(firstword $^); mv y.tab.

To use the canned sequence, substitute the variable into the recipe of a rule. You
can substitute it like any other variable (see Section 6.1 [Basics of Variable References],
page 59). Because variables defined by define are recursively expanded variables, all the
variable references you wrote inside the define are expanded now. For example:

foo.c : foo.y
	$(run-yacc)

6 How to Use Variables

A variable is a name defined in a makefile to represent a string of text, called the variable’s value.
Variable references can be used in any context: targets, prerequisites, recipes, most directives, and new variable values.
spaces before the variable value are ignored in variable assignments.

6.2 The Two Flavors of Variables

  • recursive expansion:

    	va = a
    	vb = $(va)
    	va = aa
    	all: ; @echo $(vb)
    

    vb will be aa , not a

  • simply expanded variables:
    Simply expanded variables are defined by lines using ‘:=’ or ‘::=’

    	va = a
    	vb := $(va)
    	va = aa
    	all: ; @echo $(vb)
    

    vb will be a , not aa

  • There is another assignment operator for variables, ‘?=’. This is called a conditional
    variable assignment operator, because it only has an effect if the variable is not yet defined.
    This statement:

	FOO ?= bar

is exactly equivalent to this (see Section 8.10 [The origin Function], page 94):

ifeq ($(origin FOO), undefined)
	FOO = bar
endif

Note that a variable set to an empty value is still defined, so ‘?=’ will not set that variable.

6.3.1 Substitution References

It has the form ‘ ( v a r : a = b ) ’ ( o r ‘ (var:a=b)’ (or ‘ (var:a=b)(or{var:a=b}’) and its meaning is to take the value of the variable var, replace every a at the end of a word with b in that value, and substitute the resulting string.
When we say “at the end of a word”, we mean that a must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of a in the value are unaltered. For example:

foo := a.o b.o c.o
bar := $(foo:.o=.c)

sets ‘bar’ to ‘a.c b.c c.c’. See Section 6.5 [Setting Variables], page 65
another type
For example:

foo := a.o b.o c.o
bar := $(foo:%.o=%.c)

sets ‘bar’ to ‘a.c b.c c.c’.
A substitution reference is actually an abbreviation for use of the patsubst expansion function (see Section 8.2 [Functions for String Substitution and Analysis], page 84). We provide substitution references as well as patsubst for compatibility with other implementations of make.

6.7 The override Directive

Variable assignments marked with the override flag have a higher priority than all other
assignments, except another override. Subsequent assignments or appends to this variable
which are not marked override will be ignored.
example:

objects = init
override objects += override
objects = lastset
all:; echo $(objects)

will print “init override” instead of “lastset”

7 Conditional Parts of Makefiles

example:

libs_for_gcc = -lgnu
normal_libs =
foo: $(objects)
ifeq ($(CC),gcc)
	$(CC) -o foo $(objects) $(libs_for_gcc)
else
	$(CC) -o foo $(objects) $(normal_libs)
endif

This conditional uses three directives: one ifeq, one else and one endif.

formats:

  • ifeq (arg1, arg2)
  • ifneq (arg1, arg2)
  • ifdef variable-name
    variable-name
    The ifdef form takes the name of a variable as its argument, not a reference to a variable. If the value of that variable has a non-empty value, the text-if-true
    is effective; otherwise, the text-if-false, if any, is effective. Variables that have never been defined have an empty value.
    Note that ifdef only tests whether a variable has a value. It does not expand the variable to see if that value is nonempty.
    For example,
    bar =
    foo = $(bar)
    ifdef foo
    frobozz = yes
    else
    frobozz = no
    endif
    
    sets ‘frobozz’ to ‘yes’, while:
    foo =
    ifdef foo
    frobozz = yes
    else
    frobozz = no
    endif
    
    sets ‘frobozz’ to ‘no’.
  • ifndef variable-name

8 Functions for Transforming Text

Function Call Syntax:
$(function arguments)
or
${function arguments}

8.2 Functions for String Substitution and Analysis

many usefull function for processing string like

  • $(subst from,to,text)
  • $(patsubst pattern,replacement,text)
    Finds whitespace-separated words in text that match pattern and replaces them with replacement. Here pattern may contain a ‘%’ which acts as a wildcard,
    matching any number of any characters within a word. If replacement also contains a ‘%’, the ‘%’ is replaced by the text that matched the ‘%’ in pattern. Only the first ‘%’ in the pattern and replacement is treated this way; any subsequent ‘%’ is unchanged.
  • $(strip string)

8.xx Functions for File Names, and so on.

9.7 Summary of Options

maybe it is usefull

  • ‘-n’ : uesfull to check the recipe
    Print the recipe that would be executed, but do not execute it
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值