0

I want to use the match pattern of a Makefile rule in a text function in the perquisites list.

Let's say I want to build a file, and that files perquisites are any other files with the same name in a list.

list_of_files=a/x b/x a/y b/y c/z 

%:
    echo 0 $@
    touch $@

build/%: $(filter %/$*,$(list_of_files))
    echo 1 target $@
    echo 1 prereq $?
    touch $@

.PHONY:
all: build/x
    echo 

In the above case, I want for a/x and b/x rules to also be triggered as they are filtered out of the list, however they are not.

111111
  • 15,686
  • 6
  • 47
  • 62

1 Answers1

1

The docs are pretty clear that what you're trying won't work as-is:

It’s very important that you recognize the limited scope in which automatic variable values are available: they only have values within the recipe. In particular, you cannot use them anywhere within the target list of a rule; they have no value there and will expand to the empty string. Also, they cannot be accessed directly within the prerequisite list of a rule.

One way to deal with this (as mentioned in the above documentation) is to use the secondary expansion capability:

.SECONDEXPANSION:

getprereqs = $(filter %/$*,$(list_of_files))

build/%: $$(getprereqs)
MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • Thanks for your answer. What I don't understand is why this works if you assign the expression to `getrprereqs` but when I just put the expression (with two dollar signs) `$$(filter %/$*,$(list_of_files))` as a prereq it just doesn't work. – 111111 Sep 16 '22 at 15:26
  • Because the `%` is being interpreted as a pattern for the pattern rule, not as a pattern for the `filter` function. By putting the pattern in the variable it "hides" it from the parser. I can't remember if there's any way to escape a pattern from a pattern rule other than putting it into a variable. Anyway, I usually find putting the entire thing into a separate variable, then escaping that variable, is a much more readable way to handle things like this than trying to escape every `$` etc. individually. – MadScientist Sep 16 '22 at 17:03
  • Also note your example in your comment is wrong. You have to escape the `$*` as `$$*` at least, as well (since `$(list_of_files)` doesn't change it doesn't matter if you escape that or not). Just escaping the start of a function doesn't escape all the things in that function call. – MadScientist Sep 16 '22 at 17:09