[pm-h] use of $$ versus $ in makefile and bash

G. Wade Johnson gwadej at anomaly.org
Thu Aug 30 05:22:12 PDT 2007


On Wed, 29 Aug 2007 17:12:55 -0500
"Russell L. Harris" <rlharris at 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.

According to "Managing Project with make" by Oram and Talbott, $$ in
make is causes a $ to be used in the command instead of being evaluated
as part of a make variable.

> I have spent several hours searching through the documentation for
> BASH and for GNU Make, and I have searched with Google, but I have
> found no answer.
> 
> Here are three examples, all taken from the same makefile:
> 
> EXAMPLE 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> 
>     -(for d in ${SYMLINKDIR};                            \
>      do                                                  \
>          pushd $$d &&                                    \
>              ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \
>          popd;                                           \
>      done;)

If you were working in a regular shell script, this would be something
like:

   (for d in some_dir_name;            \
   do                                  \
       pushd $d &&                     \
           ln -sf some_target_name .;  \
       popd;                           \
   done;)

In order for make not to treat '$d' as a make variable, you need to
double the $.

> 
> EXAMPLE 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> 
>     (for d in $$(find .                   \
>         \( -type d                        \
>             -name '.svn'     -prune    -o \
>             -name 'miscellany' -prune  -o \
>         -type d -print);                  \
>     do mkdir --parents ../stageweb/$$d;   \
>     done;)
> 
> EXAMPLE 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> 
>     (for bn in ${CLEANDIR};                      \
>      do                                          \
>          rm -f $(addprefix $$bn/*.,${CLEANEXT}); \
>      done;)
> 
>     # Why was "bn" chosen as the name of the loop variable?
> 
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> 
> My interest is fueled by the need to create a makefile which automates
> the following commands for any number of files, which necessitates a
> pair of for-loops:
>     
>     hevea -fix -I jan article.hva jan/jan-01.tex
>     hevea -fix -I jan article.hva jan/jan-02.tex
>     ...
>     hevea -fix -I feb article.hva feb/feb-01.tex
>     hevea -fix -I feb article.hva feb/feb-02.tex
>     ...
>     hevea -fix -I mar article.hva mar/mar-02.tex
>     hevea -fix -I mar article.hva mar/mar-02.tex
>     ...
> 
>     # (The hevea command creates files named "jan-01.html", etc.)
>     
>     cp jan/jan-*.html ../stageweb/jan/
>     cp jan/feb-*.html ../stageweb/feb/
>     cp jan/mar-*.html ../stageweb/mar/
>     ...
> 
> Looking at other code in the makefile which I am using for a go-by, I
> expect to start out with variables such as:
> 
>     JAN := $(wildcard jan/jan*.tex)
>     FEB := $(wildcard feb/feb*.tex)
>     MAR := $(wildcard mar/mar*.tex)
>     ...
> 
>     DOCUMENTS := $(JAN) $(FEB) $(MAR) ...
> 
> or else:
> 
>     MONTHS := jan feb mar ...
> 
> RLH

G. Wade
-- 
It's easier to port a shell than a shell script.       -- Larry Wall


More information about the Houston mailing list