Reputation: 487
I have some rules in a makefile like below
...
$(MODEL_DIR)/2001.model : $(DATA_DIR)/2000.dat
python fit.py --year 2001 --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
$(MODEL_DIR)/2002.model : $(DATA_DIR)/2000.dat $(DATA_DIR)/2001.dat
python fit.py --year 2002 --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
$(MODEL_DIR)/2003.model : $(DATA_DIR)/2000.dat $(DATA_DIR)/2001.dat $(DATA_DIR)/2002.dat
python fit.py --year 2003 --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
$(MODEL_DIR)/2004.model : $(DATA_DIR)/2000.dat $(DATA_DIR)/2001.dat $(DATA_DIR)/2002.dat $(DATA_DIR)/2003.dat
python fit.py --year 2004 --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
...
This basically specifies that the model for a year depends on data from previous years having been created.
I would like a simpler pattern based rule to make this less prone to copy paste errors. I tried
$(MODEL_DIR)/%.model : $(foreach num,$(shell seq 2000 %),$(DATA_DIR)/$(num).dat)
python fit.py --year $* --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
But I get the error
seq: invalid floating point argument: %
indicating that the wildcard is not being expanded in the shell command.
Upvotes: 1
Views: 357
Reputation: 99094
You're very close, but such function calls are expanded before matching the pattern rule to a target, so %
has no value to be fed to seq
. The way to do this kind of calculation in the prerequisite list is by using secondary expansion, and escaping each variable with an extra '$' to prevent it being expanded in the first round:
.SECONDEXPANSION:
$(MODEL_DIR)/%.model : $$(foreach num,$$(shell seq 2000 %),$(DATA_DIR)/$$(num).dat)
...
Finally, notice that seq
will give all years up to and including the year of the model, so we must remove the last prerequisite:
.SECONDEXPANSION:
$(MODEL_DIR)/%.model : $$(filter-out $$*.dat,$$(foreach num,$$(shell seq 2000 %),$(DATA_DIR)/$$(num).dat))
...
Upvotes: 2