help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to explain this line ?


From: Paul Smith
Subject: Re: how to explain this line ?
Date: Tue, 05 Feb 2013 13:01:01 -0500

On Tue, 2013-02-05 at 15:45 +0800, horseriver wrote:
>   When I read the makefile,usually find some shell-like code .
>   I can not distinguish it from makefile syntax.
> 
>   for example:
> 
>           quiet_cmd_gzip = GZIP    $@
>               cmd_gzip = gzip -f -9 < $< > $@
>     
>    the "< $<" is whose syntax? what is its meaning ?

Please keep the GNU make mailing lists on the CC line, rather than going
private.

It may help you to choose a better editor, such as Emacs, which can
colorize your makefiles based on syntax.  Otherwise you'll just have to
get used to it; that's part of the learning process.

The reason you see "shell-like code" is that make does not try to create
its own scripting language: UNIX already has a perfectly respectable,
and flexible, scripting language: the shell.  So, when make needs to
rebuild a target, it invokes the shell and passes whatever string
appears in the makefile to the shell.  Make doesn't try to understand
what the string does.  So the code is not just "shell-like", it's actual
shell code.

The short answer is that any line which does NOT start with a TAB
character, is "makefile syntax" and any line which DOES start with a TAB
character is part of a rule, and thus it's shell syntax and will be
passed to the shell.

However the full answer is not that simple: for example, a make variable
assignment is "makefile syntax", but the contents of the make variable
may well be "shell syntax", if that variable is used in a shell context.

In the above examples, those are make variables and the assignment is a
make variable assignment, which puts the string "GZIP $@" into the make
variable "quiet_cmd_gzip" and the string "gzip -f -9 < $< > $@" into the
make variable "cmd_gzip".

However, to understand how those strings are interpreted you'll have to
look at where the variable is USED; presumably you have some rule like:

        foo.tar.gz : foo.tar
                $(cmd_gzip)

Thus the make variable is used in a shell command context, so it will be
passed to the shell for execution.

The fact that both makefile syntax and shell syntax appear inside the
same file, and that their syntaxes are not completely disjoint, is where
the confusion comes from.  In particular, make syntax uses "$" to
introduce a variable reference, and shell ALSO uses "$" to introduce a
variable reference.

When make expands the string to prepare it for sending to the shell, it
will expand any "$" references as if they were make variables.  If you
want to pass "$" to the shell, you must double it, like "$$".  Luckily,
"$" is the ONLY special character that make interprets.  Every other
character in the string (that is not part of a make variable name) is
not touched by make before it's sent to the shell.

So, in the above example, when make expands the string "gzip -f -9 < $<
> $@" it will replace "$<" and "$@" with the expansion of the make
variable, then take the resulting string and pass it to the shell.

When reading a string in the makefile that will be passed to the shell,
if you see a single "$" it's ALWAYS referring to a make variable, and
when you see a double "$$" it means a single "$" is passed to the shell.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]