如何在 Makefile 的 foreach 语句中包含通配符模式

发布于 2025-01-14 08:11:44 字数 1079 浏览 3 评论 0原文

我在 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 命令中扩展。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人的旅程 2025-01-21 08:11:44

您已经非常接近了,但是此类函数调用在将模式规则与目标匹配之前会进行扩展,因此 % 没有值可提供给 seq.在先决条件列表中进行这种计算的方法是使用 二次扩展,并使用额外的“$”转义每个变量,以防止其在第一轮中扩展:

.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))
    ...

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))
    ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文