makefile中的多行bash命令

我有一个非常舒适的方式来编译我的项目通过几行bash命令。 但是现在我需要通过makefile来编译它。 考虑到每个命令都在自己的shell中运行,我的问题是在makefile中运行多行bash命令的最佳方式是相互依赖的吗? 例如,像这样:

for i in `find` do all="$all $i" done gcc $all 

另外,有人可以解释为什么即使单行命令bash -c 'a=3; echo $a > file' bash -c 'a=3; echo $a > file'在terminal工作正确,但在生成文件的情况下创build空文件?

我会使用反斜线 – 换行符:

 foo: for i in `find`; \ do \ all="$$all $$i"; \ done; \ gcc $$all 

UPD。

或者,如果只是想将find返回的整个列表传递给gcc

 foo: gcc `find` 

如问题所示, 每个子命令都在自己的shell中运行 。 这使得编写不平凡的shell脚本有点混乱 – 但它是可能的! 解决的办法是把你的脚本合并成一个子命令(一行)。

在makefile中编写shell脚本的技巧:

  1. 通过replace$$逃避脚本对$的使用
  2. 通过插入将脚本转换为一行; 在命令之间
  3. 如果要在多行上编写脚本,请使用\
  4. 可以select从set -e开始匹配make的提供,以便在子命令失败时中止
  5. 这是完全可选的,但是您可以用(){}括起脚本来强调多行序列的凝聚力 – 这不是典型的makefile命令序列

以下是OP的一个例子:

 mytarget: { \ set -e ;\ msg="header:" ;\ for i in $$(seq 1 3) ; do msg="$$msg pre_$${i}_post" ; done ;\ msg="$$msg :footer" ;\ echo msg=$$msg ;\ } 

刚才调用这个命令有什么问题?

 foo: echo line1 echo line2 .... 

而对于第二个问题,则需要使用$$来转义$ ,即bash -c '... echo $$a ...'

编辑:你的例子可以被重写为一个单行的脚本,如下所示:

 gcc $(for i in `find`; do echo $i; done) 

当然,编写Makefile的正确方法是实际logging哪些目标取决于哪些源。 在这个微不足道的案例中,所提出的解决scheme将会使foo依赖于自身,但是当然,这个解决scheme足够聪明,可以放弃循环依赖。 但是,如果您将一个临时文件添加到您的目录中,它将“神奇地”成为依赖链的一部分。 最好是一劳永逸地创build一个明确的依赖列表,或许通过脚本。

GNU make知道如何运行gcc从一组.c.h文件中生成可执行文件,所以也许你真正需要的是

 foo: $(wildcard *.h) $(wildcard *.c)