gnu make - How do you define pattern-specific variables for makefile pattern rules containing a patterned prerequisite? -
i understand can define pattern-specific variables rules no prerequisites, this:
%.o: var = 2 this set variable var 2 recipes apply targets ending in .o. stated in gnu make documentation. how define pattern-specific variable pattern rules contain pattern prerequisite, this:
%.o: %.c say have section of makefile:
%.o: %.c (recipe here) %.o: %.b (recipe here) i want define pattern-specific variable %.o: %.b rule, don't see how (if it's possible). i'd this, of course doesn't work:
%.o: %.c (recipe here) %.o: %.b: var = 2 (recipe here) is there way this?
you can set variable targets, not rules. %.o: %b rule %.o target pattern (hence "pattern-specific" name).
the usual way solve ether hard coding values in recipes or using rule-specific flags (maybe cvar , bvar in case).
edit: scratch that. came workaround.
it can done leveraging variables' recursive evaluation.
all: a.o b.o c.o $(shell touch a.xx b.yy c.zz) ## # create rule-specific variable... rules # # @param 1 target. # @param 2 prerequisite. # @param 3 variable name. # @param 4 variable value. # rule-var = $(eval $(rule-var-body)) define rule-var-body $1: private $3 = $$(if $$(<:$2=),$(or $(value rule-var-$1-$3),$(value $3)),$4) $2: $3 = $4 rule-var-$1-$3 = $$(if $$(<:$2=),$(or $(value rule-var-$1-$3),$(value $3)),$4) endef var = $(var_default) # declare couple of test values $(call rule-var,%.o,%.x,var,x-value) $(call rule-var,%.o,%.y,var,y-value) var_default := z-value echo_rule_recipe = @echo -e '$@: $^\t(var = $(var))' %.o: %.x $(echo_rule_recipe) %.o: %.y $(echo_rule_recipe) %.o: %.z $(echo_rule_recipe) %.x: %.xx $(echo_rule_recipe) %.y: %.yy $(echo_rule_recipe) %.z: %.zz $(echo_rule_recipe) the output is:
a.x: a.xx (var = x-value) a.o: a.x (var = x-value) b.y: b.yy (var = y-value) b.o: b.y (var = y-value) c.z: c.zz (var = z-value) c.o: c.z (var = z-value) the brains of operation macro rule-var. wrap variable value in prerequisite matching if-else expression. expression saved in rule-var-$1-$3 variable other rule-specific values.
$$(if $$(<:$2=),$(or $(value rule-var-$1-$3),$(value $3)),$4) deobfuscation:
$$(if $$(<:$2=), test first prerequisite value ($<) replacing it's pattern ($2) empty string.
if pattern doesn't match, use
$(or $(value rule-var-$1-$3),$(value $3)). workaround global variable shadowing. in example%.o: %.cdoesn't havevardeclared should use global value both rules share same target, it's not visible. both referenced value , single$expands expression during variable substitution phase. result neat ,orfree.- use
$(value rule-var-$1-$3)if it's nonzero. function has been called before target , variable name. - otherwise use variable's global value (
$(value $3)).
- use
otherwise use value provided (
$4).
unfortunately, when inherited, if-else monstrosity won't expand it's declared private , fixed straightforward second rule.
in example following 3 rules declared.
%.o: private var = $(if $(<:%.y=),$(if $(<:%.x=),$(var_default),x-value),y-value) %.y: var = y-value %.x: var = x-value limitations
even workaround, variable's global counterpart still shadowed. if need default value, assign before calling rule-var. global value copied part of rule-specific variable not expanded until use.
Comments
Post a Comment