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