在Makefile中写shell脚本
如果你想在Makefile里面直接写bash脚本,你需要做一些特殊处理,而不能直接粘贴复制你的bash脚本。如果你在target行后直接粘贴复制,你会遇到两个问题:
-
命令行要以tab为缩进 $需要转义
如果你用gnu的make,你可以根据来将你的脚本定义为一个变量,然后集合来使用。
另外,你还需要告诉你的make将一个target作为一个shell, 而不是一行一个shell. 可参考.
下面,我们提到的这几个关键用法,进行讲解和实践
multi-line definition syntax
使用define关键字去声明多行变量,然后export其作为环境变量,然后在shell脚本中直接引用。如下:
export ANNOUNCE_BODY all: @echo "$$ANNOUNCE_BODY" define ANNOUNCE_BODY Version $(VERSION) of $(PACKAGE_NAME) has been released. It can be downloaded from $(DOWNLOAD_URL). etc, etc. endef
需要注意:
-
$$ANNOUNCE_BODY作为一个被引用的shell的环境变量,而不是$(ANNOUNCE_BODY), $()是make的语法,引用的是make的变量。 一定要用引号将该变量包括,防止多行的字符串被shell自己转义 这种用法并不一定通用。还要根据你的平台进行测试。
value function
这个函数使得你可以直接使用一个变量的值,而不是一个展开后的值。如下:
FOO = $PATH test_value_function: @echo $(FOO) @echo $(value FOO)
第一个输出为ATH,因为“$P”会被作为一个make变量展开,这个输出则为正确的PATH的值,因为value函数逼民了这种展开。
Using one shell
有时,你希望你在target下多行shell可以作为一个shell运行。这样做的好处是:
-
提高makefile的性能 你希望多行直接可以共享信息。
.ONESHELL 可以帮助我们。如下:
.ONESHELL: test_one_shell: a=testing; echo $$a
这里的ONESHELL并不一定就是shell.也可以指定为其他的语言。例如,perl.如下
.ONESHELL: SHELL = /usr/bin/perl .SHELLFLAGS = -e show : # Make sure "@" is not the first character on the first line @f = qw(a b c); print "@f ";