如何在Makefile目标中使用Bash语法?
我经常发现Bash语法非常有用,例如像diff <(sort file1) <(sort file2)
这样的进程replace。
是否有可能在Makefile中使用这样的Bash命令? 我在想这样的事情:
file-differences: diff <(sort file1) <(sort file2) > $@
在我的GNU Make 3.80中,由于它使用shell
而不是bash
来执行命令,所以会出现错误。
从GNU Make文档中,
5.3.1 Choosing the Shell ------------------------ The program used as the shell is taken from the variable `SHELL'. If this variable is not set in your makefile, the program `/bin/sh' is used as the shell.
所以把SHELL := /bin/bash
放在你的makefile的顶部,你应该很好。
顺便说一句:你也可以为一个目标做到这一点,至less对于GNU Make来说。 每个目标都可以有自己的variables赋值,如下所示:
all: ab a: @echo "a is $$0" b: SHELL:=/bin/bash # HERE: this is setting the shell for b only b: @echo "b is $$0"
这将打印:
a is /bin/sh b is /bin/bash
有关更多详细信息,请参阅文档中的“特定于目标的variables值”。 该行可以在Makefile中的任何位置,它不一定要在目标之前。
你可以直接调用bash
,使用-c
标志:
bash -c "diff <(sort file1) <(sort file2) > $@"
当然,你可能无法redirect到variables$ @,但是当我试图做到这一点,我得到了-bash: $@: ambiguous redirect
作为一个错误消息,所以你可能想要看看之前,你会得到也进入这个(虽然我使用bash 3.2.something,所以也许你的工作方式不同)。
如果可移植性很重要,你可能不想依赖你的Makefile中的特定shell。 并不是所有的环境都有可用的bash。
你可以在Makefile中直接调用bash,而不是使用默认的shell:
bash -c "ls -al"
代替:
ls -al
有一种方法可以做到这一点,而不必明确地设置你的SHELLvariables指向bash。 如果你有许多makefile文件,这可能是有用的,因为SHELL没有被后续的makefile所inheritance,或者从环境中获取。 您还需要确保编译您的代码的人以这种方式configuration他们的系统。
如果运行sudo dpkg-reconfigure dash
并在提示中回答“no”,系统将不会使用短划线作为默认shell。 然后它会指向bash(至less在Ubuntu中)。 请注意,使用破折号作为您的系统shell是更有效率,虽然。