How to use a for loop in make recipe

随声附和 提交于 2019-12-04 04:24:49

There are two main things you need to know when putting non-trivial shell fragments into make recipes:

  1. Commands in the recipe are (of course!) executed one at a time, where command means "tab-prefixed line in the recipe", possibly spread over several makefile lines with backslashes.

    So your shell fragment has to be written all on one (possibly backslashed) line. Moreover it's effectively presented to the shell as a single line (the backslashed-newlines are not plain newlines so are not used as command terminators by the shell), so must be syntactically correct as such.

  2. Both shell variables and make variables are introduced by dollar signs ($@, $i), so you need to hide your shell variables from make by writing them as $$i. (More precisely, any dollar sign you want to be seen by the shell must be escaped from make by writing it as $$.)

Normally in a shell script you would write separate commands on separate lines, but here you effectively only get a single line so must separate the individual shell commands with semicolons instead. Putting all this together for your example produces:

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

or equivalently:

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

Notice that the latter, even though it's laid out readably on several lines, requires the same careful use of semicolons to keep the shell happy.

I found this useful, trying to use for loops to build multiple files:

PROGRAMS = foo bar other

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

It will compile foo.c, bar.c, other.c into foor bar other executables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!