Unix – Makefile and use of $$

makefileunixvariables

So I have a Makefile in which I have the follwoing code that I try to understand:

for file_exe in `find . -name "zip_exe-*"`; do \
    ./$${file_exe} -d $(UNZIP_PATH)/lib; \
done

As I understand this piece of code will try to find some executable zip and the extract those zip files to a locations. But what puzzles me is how $${file_exe} is working. Why is the double $$ needed? I guess it has something to do with the fact that some bash commands are running from a makefile, but I can't explain to myself why the $$ is needed and a simple $ does not work since this command is running a sub-shell anyway.

Best Answer

Make needs to distinguish whether you want a $ to use as introducing a make-variable reference, such as ${FOOBAR} or as a plain $ passed on to the shell. The make specification (Section Macros) says that to do the latter, you must use $$ which is replaced by a single $ and passed to the shell. In effect, your snippet reads as

for file_exe in `find . -name "zip_exe-*"`; do \
   ./${file_exe} -d some/unzip/path/lib; \
done

to the shell.

Style note: Iterating over file lists created by backticks is considered bad style, since it may overflow the ARG_MAX limit. Better to read the file names one-by-one with

find . -name "zip_exe-*" | \
while read -r file_exe; do \
   ./${file_exe} -d some/unzip/path/lib; \
done