I am reading the document of GNU Make. Here is an example
%.d: %.c
@set -e; rm -f $@; \ $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ sed ’s,\($*\)\.o[ :]*,\1.o $@ : ,g’ < $@.$$$$ > $@; \ rm -f $@.$$$$
I tried this on a C++ program, and got the list of files
init3d.d init3d.d.18449 input.d input.d.18444 main.d main.d.18439
Here is what I found but don't understand in the same document
If you have enabled secondary expansion and you want a literal dollar sign in the prerequisites list, you must actually write four dollar signs (‘$$$$’).
I wonder what the four dollar signs "$$$$" mean actually? How do they 18449, 18444 or 18439?
Thanks and regards!
Variable and function references in recipes have identical syntax and semantics to references elsewhere in the makefile. They also have the same quoting rules: if you want a dollar sign to appear in your recipe, you must double it ('$$').
$@ (“dollar at”) is part of the Makefile language. In your recipe, it refers to the thing it is going to build (above, that's prog ). Mnemonic: it's the target you're aiming at. $^ (“dollar caret”) refers to the dependencies/inputs (above, that's main. c ).
?= indicates to set the KDIR variable only if it's not set/doesn't have a value. For example: KDIR ?= "foo" KDIR ?= "bar" test: echo $(KDIR)
I just learned that if you want to use a dollar sign inside a Makefile you need to escape $ with an extra $ , so double it. Otherwise make will think that you are accessing a make variable, not a shell one.
If make "secondary expansion" is enabled, $$$$
is required in order to generate a single $
in the actual output. $
is normally used to expand variables, call make functions, etc. $$
with secondary expansion enabled does something else, but otherwise it generates an actual $
in the output.
The shell that make uses to execute command-lines on Unix-like systems normally interprets $$
as expand to shell process ID. So, without secondary expansion enabled, $$$$
will turn into $$
in the output, which the shell will expand to the process ID.
(Using the shell process ID as a suffix is a simple way of trying to guarantee uniqueness of file name for a temporary file.)
$$
will be converted to $
, but in Makefile rules (which are shell expressions) you'll have to also escape the resulting $
using a \
or by using single quotes '
around your expression.
Here is an example that demonstrates it:
DOLLAR:=$$ dollar: echo '$$' > $@ echo "\$$" >> $@ echo '$(DOLLAR)' >> $@ echo "\$(DOLLAR)" >> $@ cat dollar
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