I understand that you can define pattern-specific variables for rules with no prerequisites, like this:
%.o: var = 2
This will set variable var to 2 for recipes that apply to all targets ending in .o. This is clearly stated in the GNU Make documentation. But how do you define a pattern-specific variable for pattern rules that contain a pattern prerequisite, like this:
%.o: %.c
Say I have this section of makefile:
%.o: %.c
(recipe here)
%.o: %.b
(recipe here)
I want to define a pattern-specific variable only for the %.o: %.b rule, but I don't see how to do it (if it's even possible). I'd like to do something like this, but of course it doesn't work:
%.o: %.c
(recipe here)
%.o: %.b: var = 2
(recipe here)
Is there a way to do this?
I found another solution, although it could get a little difficult to read depending on how many prerequisite comparisons are made. Perhaps there's a way to refactor it.
# Return 1 if prerequisite ends in `.c`.
# Return 2 if prerequisite ends in `.b`.
build-var = $(if $(filter %.c,$<),1,$(if $(filter %.b,$<),2))
%.o: private var = $(build-var)
%.o: %.c
(recipe here)
%.o: %.b
(recipe here)
The instruction var = $(build-var) will be invoked for any target that ends in .o. But when build-var is expanded, its value comes from examining the end of the prerequisite to see what type of file it is.
The if statement evaluates to true if its first argument is a non-empty string, and filter returns a non-empty string if, in my example, the prerequisite contains .c. So, walking through the build-var line, if the prerequisite (denoted by the automatic variable $<) ends in .c, then return the value 1. Else, start a second if statement that returns the value 2 if the prerequisite ends in .b. If the prerequisite doesn't end in either .c or .b then build-var is set to nothing (an empty string).
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