如何在make recipe中使用for循环

Ste*_*ang 8 shell makefile recipe

我想使用循环来查找一些文件并重命名它们:

  for i in `find $@  -name *_cu.*`;do mv $i "$(echo $i|sed s/_cu//)"
  done
Run Code Online (Sandbox Code Playgroud)

这适用于shell.但是如何在makefile配方中执行此操作?

Joh*_*all 30

将非平凡的shell碎片放入make配方时,您需要了解两件事:

  1. 配方中的命令(当然!)一次执行一个,其中命令意味着"配方中带有选项卡前缀的行",可能分布在带有反斜杠的几个makefile行上.

    所以你的shell片段必须全部写在一条(可能是backslashed)行上.此外,它有效地呈现给shell作为单行(backslashed-newlines不是简单的换行符,因此不被shell用作命令终止符),因此必须在语法上正确.

  2. shell变量和make变量都是由美元符号($@,$i)引入的,因此你需要通过编写它们来隐藏你的shell变量$$i.(更确切地说,任何你想要被shell看到的美元符号都必须通过写入来从make中转义$$.)

通常在shell脚本中,您可以在单独的行上编写单独的命令,但在这里您实际上只获得一行,因此必须用分号分隔各个shell命令.将所有这些放在一起为您的示例产生:

foo: bar
    for i in `find $@  -name *_cu.*`; do mv $$i "$$(echo $$i|sed s/_cu//)"; done
Run Code Online (Sandbox Code Playgroud)

或等效地:

foo: bar
    for i in `find $@  -name *_cu.*`; do      \
        mv $$i "$$(echo $$i|sed s/_cu//)";    \
    done
Run Code Online (Sandbox Code Playgroud)

请注意,后者即使在几行上可读地布局,也需要同样小心地使用分号来保持shell的快乐.


fed*_*deb 5

我发现这很有用,尝试使用 for 循环来构建多个文件:

PROGRAMS = foo bar other

.PHONY all
all: $(PROGRAMS)
$(PROGRAMS):
    gcc -o $@ $@.c
Run Code Online (Sandbox Code Playgroud)

它将把 foo.c, bar.c, other.c 编译成 foo bar 其他可执行文件