Reputation: 623
I have a number of strategies (strategy_a.py
, strategy_b.py
, etc) and a number of inputs (input_x.csv
, input_y.csv
).
I now want to recalculate the results of each strategy with each input whenever either the strategy or the input file changes, but not if both haven't change. Manually it can be expressed like so:
result_of_a_with_x.txt: strategy_a.py input_x.csv
python strategy_a.py --data input_x.csv > result_of_a_with_x.txt
result_of_a_with_y.txt: strategy_a.py input_y.csv
python strategy_a.py --data input_y.csv > result_of_a_with_y.txt
result_of_b_with_x.txt: strategy_b.py input_x.csv
python strategy_b.py --data input_x.csv > result_of_b_with_x.txt
result_of_b_with_y.txt: strategy_b.py input_y.csv
python strategy_b.py --data input_y.csv > result_of_b_with_y.txt
But instead of writing out this list I would like to generate it, however I can't figure out how. I already tried using %
but it does not seem to be the right tool for this problem as it only works for a single position, not for two.
Upvotes: 0
Views: 131
Reputation: 4261
You could try to go with a template that will be instantiated with a loop for every strategy, like so:
$ cat Makefile
STRATEGIES := a b
define strategy_template
result_of_$(1)_with_%.txt: strategy_$(1).py input_%.csv
echo python $$< --data $$(word 2,$$^) > $$@
endef
$(foreach strategy,$(STRATEGIES),$(eval $(call strategy_template,$(strategy))))
all: result_of_a_with_x.txt result_of_b_with_y.txt
Within a template $(1)
will be replaced with actual parameter value, resulting in dynamic creation of pattern rules of result_of_a_with_%.txt
and result_of_b_with_%.txt
. Due to $(eval)
call which will expand variables, actuals that should be expanded at recipe runtime need to be escaped (thus $$<
etc. within the template).
Output:
$ make
echo python strategy_a.py --data input_x.csv > result_of_a_with_x.txt
echo python strategy_b.py --data input_y.csv > result_of_b_with_y.txt
Upvotes: 1