I have a makefile like the following:
m1:
@echo building m1
m1_:
@echo building m1_
m2:
@echo building m2
m2_:
@echo building m2_
m3_DEPS = m2 m1
SUBSTITUTE=$(patsubst %,%_,$($@_DEPS))
.SECONDEXPANSION:
#%: $$(SUBSTITUTE)
%: $$(patsubst \%,\%_,$$($$@_DEPS))
@echo Building $@
@echo Dependencies are $^
The key line is
%: $$(patsubst \%,\%_,$$($$@_DEPS))
I am using both a pattern rule and patsubst, which itself uses percentage signs. I thought I could escape the %
character with a \
, but I am still not getting the expected behaviour. Running "make m3" gives the output
building m2
building m1
Building m3
Dependencies are m2 m1
However, I expect to get
building m2_
building m1_
Building m3
Dependencies are m2_ m1_
Commenting out that line and calling patsubst
indirectly through a variable does in fact produce that output.
SUBSTITUTE=$(patsubst %,%_,$($@_DEPS))
%: $$(SUBSTITUTE)
Also, I have tested that using a non-pattern rule works, which makes me think it is something to do with the interaction of pattern rules and percentage signs:
m3: $$(patsubst %,%_,$$($$@_DEPS))
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.
Commands and executionIf you want a string to have a dollar sign, you can use $$ . This is how to use a shell variable in bash or sh . Note the differences between Makefile variables and Shell variables in this next example.
Special characters in a makefile In macros, a backslash ( \ ) followed by a newline character is replaced by a space. In commands, a percent symbol ( % ) is a file specifier. To represent % literally in a command, specify a double percent sign ( %% ) in place of a single one.
Finds whitespace-separated words in TEXT that match PATTERN and replaces them with REPLACEMENT. Here PATTERN may contain a % which acts as a wildcard, matching any number of any characters within a word.
\
in makefile context is for line continuation, not for "escaping". To escape things you hide them in a variable:
PERCENT := %
The idea is, at the time a makefile fragment is parsed where the escaped character is meaningful, you escape it.
So, in your situation, you have to use $$(PERCENT)
:
$$(patsubst $$(PERCENT),$$(PERCENT)_,$$($$@_DEPS))
I don't know of a way to hide '%' from the pattern rule, but in this case you can work around it:
%: $$(addsuffix _,$$($$*_DEPS))
@echo Building $@
@echo Dependencies are $^
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