(Updated 2013-07-20: Correctly describe the issue and provide examples)
Make has several useful built-in functions, among which $(patsubst pattern,replacer,string). The pattern can contain the character % which is a wildcard meaning any string and that can be referred in the replacer parameter. Only the first occurrence of % is treated with this special meaning, just as the manual says.
What the manual doesn't say is thatonly the form %bla works, while the form bla% does NOT work GNU Make's '%' is not analogous to shell's '*', so you can't expect to remove substrings in the middle of a string without knowing the exact string until the part you want to remove.
This does not work if you want to obtain '../some/CPU12/include' in OTHERPATH:
Make has several useful built-in functions, among which $(patsubst pattern,replacer,string). The pattern can contain the character % which is a wildcard meaning any string and that can be referred in the replacer parameter. Only the first occurrence of % is treated with this special meaning, just as the manual says.
What the manual doesn't say is that
This does not work if you want to obtain '../some/CPU12/include' in OTHERPATH:
PATH := ../some/prefCPU12/includeThe result will be:
OTHERPATH := $(patsubst pref%,%,$(PATH))
default:
@echo "OTHERPATH = $(OTHERPATH)
OTHERPATH = ../some/prefCPU12/includeThis bahaviour is somewhat asymetric to how subst behaves and how one would expect it to, considering '%' is explained as a glob pattern:
0 eddy@heidi /tmp $ cat makefileNot sure what make developers would say about this, and I am not sure if having % work as a glob pattern and using it, instead of invoking sed would be better for performance, but sure I would like to have the option :-) .
PATH := ../some/prefCPU12/include
OTHERPATH := $(patsubst pref%,%,$(PATH))
SPATH := $(subst pref,,$(PATH))
default:
@echo "PATH = $(PATH)"
@echo "OTHERPATH = $(OTHERPATH)"
@echo "SPATH = $(SPATH)"
0 eddy@heidi /tmp $ make
PATH = ../some/prefCPU12/include
OTHERPATH = ../some/prefCPU12/include
SPATH = ../some/CPU12/include
4 comments:
You didn't say what you tried, so I tried this on GNU Make 3.81 (2006):
words = fee fie foe fum
.PHONY: default
default:
@echo $(patsubst f%,%g,$(words))
@echo $(patsubst %e,q%,$(words))
@echo $(patsubst f%e,x%x,$(words))
It prints:
eeg ieg oeg umg
qfe qfi qfo fum
xex xix xox fum
which is what I expected, showing that % works at the end, start, or even middle of a word. (note that each @echo line must be indented with a tab in order to obey Makefile syntax)
@Jeff: GNU Make version 3.82. I checked on Linux and on Cygwin.
I can not reproduce your issue, either in 3.82 or with the latest version in the git repo. Can you show us what you are doing where you think make gets it wrong?
I wouldn't say % does not behave like shell * because it, in fact, appears to work exactly like that. Your description clearly shows the pattern must match the whole string and so do glob patterns in shell, both for file name generation and case statements.
Post a Comment