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.
This special significance of ' $ ' is why you must write ' $$ ' to have the effect of a single dollar sign in a file name or recipe. Variable references can be used in any context: targets, prerequisites, recipes, most directives, and new variable values.
There is no difference between () and {} for Make. If you use $$ in a recipe, then $ is "escaped" and passed to the shell. The shell may then make a difference between $() or ${} . But that is entirely up to the shell, and has nothing to do with Make or makefiles.
Inside actions we can use: $@ to represent the full target name of the current target $? returns the dependencies that are newer than the current target $* returns the text that corresponds to % in the target $< returns the name of the first dependency $^ returns the names of all the dependencies with space as the ...
The simple answer is that %.o is a target that matches any file ending in .o. "%.o: %. c" means that any file ending in .o depends on the same filename ending in . c to be present. The following line, starting with a tab, is the rule to use whenever you are generating a file of the form %.o.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With