Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

Re: use of $$ versus $ in makefile and bash

From: Michael Marsh <michael.a.marsh(at)gmail.com>
Date: Wed Aug 29 2007 - 11:08:30 EDT


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.

Do you need help?X

> 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/~mmarshhttp://mamarsh.blogspot.comhttp://36pints.blogspot.com


-- 
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Received on Wed Aug 29 11:09:43 2007

This archive was generated by hypermail 2.1.8 : Sun Oct 07 2007 - 03:13:52 EDT


Contact Us  Legal Notices  Order Services Online 
Pantek Home  Privacy Policy  IT news  Site Map  Pantek Library