在Makefile中写shell脚本

如果你想在Makefile里面直接写bash脚本,你需要做一些特殊处理,而不能直接粘贴复制你的bash脚本。如果你在target行后直接粘贴复制,你会遇到两个问题:

  • 命令行要以tab为缩进
  • $需要转义

如果你用gnu的make,你可以根据multi-line definition syntax来将你的脚本定义为一个变量,然后集合value function来使用。

另外,你还需要告诉你的make将一个target作为一个shell, 而不是一行一个shell. 可参考defining a .ONESHELL target.

下面,我们提到的这几个关键用法,进行讲解和实践

multi-line definition syntax

https://stackoverflow.com/questions/649246/is-it-possible-to-create-a-multi-line-string-variable-in-a-makefile

使用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

https://www.gnu.org/software/make/manual/html_node/One-Shell.html

有时,你希望你在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\n";

 

 

 

你可能感兴趣的:(linux,usages)