On Fri, 2022-07-15 at 20:25 +0100, Sean Hammond wrote: > requirements/%.txt: requirements/$(shell grep --color=never > '^[[:blank:]]*-r\|^[[:blank:]]*-c' requirements/%.in | sed > 's/^[[:blank:]]*\(-r\|-c\)[[:blank:]]*//')
Unless you're sure that the shell generates only one single filename every time, it can't be correct to just prefix it with "requirements/" like this, even if the shell function did work as you wanted. That would prepend "requirements/" only to the first word in the output: BAR = one two three FOO = foo/$(BAR) gives "foo/one two three"; it doesn't give "foo/one foo/two foo/three". > But it doesn't work: > > grep: %.in: No such file or directory > > It seems that make didn't expand the % within the $(shell ...) > command. Correct. See How make Reads a Makefile[1] from the documentation. Here you will see that the prerequisites section of a rule is expanded (all variables and functions are resolved) as make reads in the makefile, right after this line exists. That happens long, long before make uses this pattern rule to try to build the target, and discovers what the value of the % pattern should be. There are multiple ways to work around this. One way is to use secondary expansion[2], which would mean doing something like this: REQS = $(addprefix requirements/,$(shell grep ... requirements/$*.in | sed '...')) .SECONDEXPANSION: requirements/%.txt: $$(REQS) Note I just used a separate function for simplicity and readability: you could inline the value as you did before but you have escape ALL the "$" with "$$". Also if you use a separate variable, ensure you use "=" above NOT ":=", which would break everything. [1] https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html [2] https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html