Heye
Heye

Reputation: 623

GNU Makefile - Generate targets of several combinations

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

Answers (1)

raspy
raspy

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

Related Questions