如何通过循环 Makefile 列表来创建多个配方?

发布于 2025-01-10 03:31:32 字数 1317 浏览 0 评论 0原文

我有以下 makefile,其中包含多个 cp 命令,用于将目录从源复制到目标。

process:
   cp dir/level/2000/config.json output/2000/config.json
   cp dir/level/2001/config.json output/2001/config.json
   cp dir/level/2002/config.json output/2002/config.json

stage:
   mkdir -p output/2000 output/2001 output/2002
   cp dir/common/2000/esc output/2000/esc
   cp dir/common/2001/esc output/2001/esc
   cp dir/common/2002/esc output/2002/esc

apply: stage process

我想通过引入 2000 2001 2002 的变量列表来使上面的 Makefile 更加动态,然后它会循环该变量并在每次迭代时运行规则。类似...

var := 2000 2001 2002
process:
   cp dir/level/${var}/config.json output/${var}/config.json

stage:
   mkdir -p output/${var}
   cp dir/common/${var}/esc output/${var}/esc

apply: stage process

现在,如果我运行 make apply 它应该重新创建与第一个 makefile 相同的步骤。 我尝试使用多个目标作为 ${var} ,它按照我想要的方式工作,但它只能用于代替其中一个目标,不能同时用于 stage处理。我

process:
   cp dir/level/2000/config.json output/2000/config.json
   cp dir/level/2001/config.json output/2001/config.json
   cp dir/level/2002/config.json output/2002/config.json

${var}:
   mkdir -p output/$@ 
   cp dir/common/$@/esc output/$@/esc

apply: ${var} process

现在如果我运行 make apply,它将按我的预期运行,但是如何使用相同的多个目标来代替 process 呢?

I have the following makefile that has multiple cp commands to copy directories from source to destination.

process:
   cp dir/level/2000/config.json output/2000/config.json
   cp dir/level/2001/config.json output/2001/config.json
   cp dir/level/2002/config.json output/2002/config.json

stage:
   mkdir -p output/2000 output/2001 output/2002
   cp dir/common/2000/esc output/2000/esc
   cp dir/common/2001/esc output/2001/esc
   cp dir/common/2002/esc output/2002/esc

apply: stage process

I want to make the above Makefile more dynamic by introducing a variable list of 2000 2001 2002 and it would then loop over the variable and run the rule every iteration. Something like...

var := 2000 2001 2002
process:
   cp dir/level/${var}/config.json output/${var}/config.json

stage:
   mkdir -p output/${var}
   cp dir/common/${var}/esc output/${var}/esc

apply: stage process

Now if I run make apply it should recreate the same steps as the first makefile.
I tried using multiple targets as ${var} and it worked the way I wanted but it can only be used in place of one of the targets, not for both stage and process. I did

process:
   cp dir/level/2000/config.json output/2000/config.json
   cp dir/level/2001/config.json output/2001/config.json
   cp dir/level/2002/config.json output/2002/config.json

${var}:
   mkdir -p output/$@ 
   cp dir/common/$@/esc output/$@/esc

apply: ${var} process

Now if I run make apply, it will run as I expected but how to use the same multiple targets in place of process too?

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

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

发布评论

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

评论(2

月亮是我掰弯的 2025-01-17 03:31:32

您最有可能使用模式规则:

apply: stage process

var := 2000 2001 2002

process: $(foreach V,$(var),output/$V/config.json)
stage: $(foreach V,$(var),output/$V/esc)

output/%/config.json: dir/level/%/config.json
        cp 
lt; $@

output/%/esc : dir/common/%/esc
        mkdir -p $(@D)
        cp 
lt; $@

You would use pattern rules most likely:

apply: stage process

var := 2000 2001 2002

process: $(foreach V,$(var),output/$V/config.json)
stage: $(foreach V,$(var),output/$V/esc)

output/%/config.json: dir/level/%/config.json
        cp 
lt; $@

output/%/esc : dir/common/%/esc
        mkdir -p $(@D)
        cp 
lt; $@
故事与诗 2025-01-17 03:31:32

最简单的解决方案可能是在您的配方中使用 shell for 循环:

var := 2000 2001 2002

process:
  for year in $(var); do \
    cp dir/level/$year/config.json output/$year/config.json; \
  done

请注意,在配方中我们需要编写 $$year 来引用
名为 year 的 shell 变量,因为单个 $ 会引入
makefile 变量引用。


仅使用 make 语法,您可以执行以下操作:

var = 2000 2001 2002
outputs = $(patsubst %,output/%/config.json,$(var))

output/%/config.json: dir/level/%/config.json
    echo cp 
lt; $@

all: $(outputs)

这将创建一个具有以下内容的变量 outputs

output/2000/config.json output/2001/config.json output/2002/config.json

然后使用模式规则隐式创建配方,以从相应的输入。

The simplest solution is probably to use a shell for loop in your recipe:

var := 2000 2001 2002

process:
  for year in $(var); do \
    cp dir/level/$year/config.json output/$year/config.json; \
  done

Note that within the recipe we need to write $$year to refer to the
shell variable named year because a single $ would introduce a
makefile variable reference.


Using just make syntax, you could do this:

var = 2000 2001 2002
outputs = $(patsubst %,output/%/config.json,$(var))

output/%/config.json: dir/level/%/config.json
    echo cp 
lt; $@

all: $(outputs)

This creates a variable outputs that has the content:

output/2000/config.json output/2001/config.json output/2002/config.json

And then uses a pattern rule to implicitly create recipes for creating those outputs from the corresponding inputs.

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