如何在 Makefile 的 foreach 语句中包含通配符模式
How to include wildcard pattern in foreach statement of Makefile
我在 makefile 中有一些规则,如下所示
...
$(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)
...
这基本上指定了一年的模型取决于已创建的前几年的数据。
我想要一个更简单的基于模式的规则,以减少复制粘贴错误的发生。我试过了
$(MODEL_DIR)/%.model : $(foreach num,$(shell seq 2000 %),$(DATA_DIR)/$(num).dat)
python fit.py --year $* --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
但是我得到了错误
seq: invalid floating point argument: %
表示通配符未在shell命令中展开。
您非常接近,但是在将模式规则与目标匹配之前扩展了此类函数调用,因此%
没有价值可以提供给seq
。在先决条件列表中进行这种计算的方法是使用 secondary expansion,并用额外的 '$' 转义每个变量以防止它在第一轮中被扩展:
.SECONDEXPANSION:
$(MODEL_DIR)/%.model : $$(foreach num,$$(shell seq 2000 %),$(DATA_DIR)/$$(num).dat)
...
最后,请注意 seq
将给出所有年份 并包括 型号的年份,因此我们必须删除最后一个先决条件:
.SECONDEXPANSION:
$(MODEL_DIR)/%.model : $$(filter-out $$*.dat,$$(foreach num,$$(shell seq 2000 %),$(DATA_DIR)/$$(num).dat))
...
我在 makefile 中有一些规则,如下所示
...
$(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)
...
这基本上指定了一年的模型取决于已创建的前几年的数据。
我想要一个更简单的基于模式的规则,以减少复制粘贴错误的发生。我试过了
$(MODEL_DIR)/%.model : $(foreach num,$(shell seq 2000 %),$(DATA_DIR)/$(num).dat)
python fit.py --year $* --data-dir $(DATA_DIR) --output-dir $(MODEL_DIR)
但是我得到了错误
seq: invalid floating point argument: %
表示通配符未在shell命令中展开。
您非常接近,但是在将模式规则与目标匹配之前扩展了此类函数调用,因此%
没有价值可以提供给seq
。在先决条件列表中进行这种计算的方法是使用 secondary expansion,并用额外的 '$' 转义每个变量以防止它在第一轮中被扩展:
.SECONDEXPANSION:
$(MODEL_DIR)/%.model : $$(foreach num,$$(shell seq 2000 %),$(DATA_DIR)/$$(num).dat)
...
最后,请注意 seq
将给出所有年份 并包括 型号的年份,因此我们必须删除最后一个先决条件:
.SECONDEXPANSION:
$(MODEL_DIR)/%.model : $$(filter-out $$*.dat,$$(foreach num,$$(shell seq 2000 %),$(DATA_DIR)/$$(num).dat))
...