Reputation: 312038
I am using a Makefile to generate templates from a set of parameter files. The parameter files are named values-<something>.yml
, and the resulting templates are named template-<something>-<network_mode>.yml
, where <network_mode>
can be either pod
or bridge
.
The command to generate the two templates is identical with the exception of the network mode parameter (which can be derived from the target filename).
I was hoping I could write a rule like this:
%-template-bridge.yml %-template-pod.yml: values-%.yml
NM=$@; NM=$${NM#*template-}; NM=$${NM%.yml}; \
echo "something something network mode $$NM" > $@ || {rm -f $@; exit 1}
Unfortunately, while this works great when asking for individual files:
$ make cirros-template-bridge.yml
touch "cirros-template-bridge.yml"
$ make cirros-template-pod.yml
touch "cirros-template-pod.yml"
It doesn't work when asking for multiple files:
$ make cirros-template-bridge.yml cirros-template-pod.yml
touch "cirros-template-bridge.yml"
make: Nothing to be done for 'cirros-template-pod.yml'.
$ make cirros-template-bridge.yml cirros-template-pod.yml
make: 'cirros-template-bridge.yml' is up to date.
touch "cirros-template-pod.yml"
Note the first time it generate cirros-template-bridge.yml
, but refused to generate cirros-template-pod.yml
until it was invoked a second time. I assume this is because the syntax I'm trying to use means "the following recipe will generate both of these files", which isn't true.
What's the solution here? I can obviously create two separate pattern rules, like this...
%-template-pod.yml: values-%.yml
echo "something something network mode pod" > $@ || {rm -f $@; exit 1}
%-template-bridge.yml: values-%.yml
echo "something something network mode bridge" > $@ || {rm -f $@; exit 1}
...but this means I need to keep the command line for the two recipes in sync. I really want something like a Make "subroutine". Is there a better option?
Upvotes: 0
Views: 54
Reputation: 100956
If you had lots of these you could do something like create a foreach
loop with eval
etc. but since you just have two rules my opinion is that the simplest solution is to put the recipe into a variable and use it in both rules like this:
MAKE_TEMPLATE = NM=$@; NM=$${NM\#*template-}; NM=$${NM%.yml}; \
echo "something something network mode $$NM" > $@ || { rm -f $@; exit 1; }
%-template-pod.yml: values-%.yml
$(MAKE_TEMPLATE)
%-template-bridge.yml: values-%.yml
$(MAKE_TEMPLATE)
Upvotes: 1