Re: use of $$ versus $ in makefile and bash
On 8/29/07, Russell L. Harris <rlharris@oplink.net> wrote:
> I am puzzled concerning the use of the symbols "$" and "$$" in a
> makefile. I do not understand why "$$" is required in some instances,
> and "$" in other instances.
"$" is a special character to make, so in cases where you need make to
pass an actual "$" to something else, you have to use the special
variable "$$".
> I have spent several hours searching through the documentation for
> BASH and for GNU Make, but I have found no answer.
>
> Here are three examples, all taken from the same makefile:
>
> EXAMPLE 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>
> -ln -s ../journal.cls ../journal.hlx .
> -(for d in ${SYMLINKDIR}; \
> do \
> pushd $$d && \
> ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \
> popd; \
> done;)
In this case, "d" is a shell variable defined within a rule. The
shell refers to it as "$d", but using "$d" in your makefile would
cause make to look for one of its own variables named "d". "$$d"
becomes a literal "$d" to make, which is then passed to sh.
"$(addprefix ...)" is a make command, and "${SYMLINKDIR}" and
"${SYMLINKTARGET}" are makefile variables, which will be expanded by
make and passed to the shell as literals.
> EXAMPLE 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>
> (for d in $$(find . \
> \( -type d \
> -name '.svn' -prune -o \
> -name 'hevea' -prune -o \
> -name 'metatags' -prune \) -o \
> -type d -print); \
> do mkdir --parents ../stageweb/$$d; \
> done;)
The difference in this example is that find is being run, and its
stdout returned as a string. The shell pattern is "$(command)", which
is equivalent to "`command`". Again, since the "$" is relevant to the
shell, not make, we have to use the special "$$".
> EXAMPLE 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>
> (for bn in ${CLEANDIR}; \
> do \
> rm -f $(addprefix $$bn/*.,${CLEANEXT}); \
> done;)
> rm -f ${CLEANOTHER}
>
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hopefully this example is clearer now.
> Also, in the third example, does the variable name "bn" have
> significance? Could the name "b" or "c" or "x" be used instead? The
> name "f" commonly is used in a for-loop when working with files, and
> the name "d", when working with directories. The name "bn" appears
> nowhere else in the makefile.
It's defined locally to the for loop (well, not *really* locally, but
effectively). Any name that isn't already being used should be fine
here. Not knowing what the context around that snippet is, I couldn't
say if "bn" was chosen for some mnemonic reason.
--
Michael A. Marsh
http://www.umiacs.umd.edu/~mmarsh
http://mamarsh.blogspot.com
http://36pints.blogspot.com
Reply to: