如何在make recipe中使用for循环

时间:2012-01-06 10:37:08

标签: shell makefile recipe

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

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

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

2 个答案:

答案 0 :(得分:29)

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

  1. 配方中的命令(当然!)一次执行一次,其中命令表示“配方中带有选项卡前缀的行”,可能会分布在带有反斜杠的几个makefile行中

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

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

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

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

    或等效地:

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

    请注意,后者即使在几行上可读取,也需要同样小心地使用分号来保持外壳的快乐。

答案 1 :(得分:1)

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

PROGRAMS = foo bar other

.PHONY all
all: $(PROGRAMS)
$(PROGRAMS):
    gcc -o $@ $@.c

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