编写Makefile总结

以下的记录都是本人在编写和阅读Makefile过程中所遇到疑问。


1. makefile中的shell脚本语句需要在目标里才有效

否则无效被忽略或者发生错误。

2. makefile中执行shell条件判断语句出现错误:“syntax error : unexpected end of file”

如下所示:

DEL_DIR:
@if [ -d /tmp/test ]; then rm -rf /tmp/test fi

执行make时,出错:“syntax error : unexpected end of file”
解决办法:在fi前加入";",则OK,即:

DEL_DIR:
@if [ -d /tmp/test ]; then rm -rf /tmp/test; fi

3. Makefile中的变量

 具体使用详见:
http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E4%BD%BF%E7%94%A8%E5%8F%98%E9%87%8F
写得非常详细和具体。

说下目标变量

前面我们所讲的在Makefile中定义的变量都是“全局变量”,在整个文件,我们都可以访问这些变量。当然,“自动化变量”除外,如“$<”等这种类量的自动化变量就属于“规则型变量”,这种变量的值依赖于规则的目标和依赖目标的定义。

当然,我也同样可以为某个目标设置局部变量,这种变量被称为“Target-specific Variable”,它可以和“全局变量”同名,因为它的作用范围只在这条规则以及连带规则中,所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。

其语法是:

<target ...> : <variable-assignment>;

<target ...> : overide <variable-assignment>

<variable-assignment>;可以是前面讲过的各种赋值表达式,如“=”、“:=”、“+=”或是“?=”。第二个语法是针对于make命令行带入的变量,或是系统环境变量。

这个特性非常的有用,当我们设置了这样一个变量,这个变量会作用到由这个目标所引发的所有的规则中去。如:

prog : CFLAGS = -g
prog : prog.o foo.o bar.o
        $(CC) $(CFLAGS) prog.o foo.o bar.o

prog.o : prog.c
        $(CC) $(CFLAGS) prog.c

foo.o : foo.c
        $(CC) $(CFLAGS) foo.c

bar.o : bar.c
        $(CC) $(CFLAGS) bar.c

在这个示例中,不管全局的$(CFLAGS)的值是什么,在prog目标,以及其所引发的所有规则中(prog.o foo.o bar.o的规则),$(CFLAGS)的值都是“-g”

4. shell命令的执行

 规则中,当目标需要被重建时。此规则所定义的命令将会被执行,如果是多行命令,那么每一行命令将在一个独立的子shell进程中被执行(就是说,每一行命令的执行是在一个独立的shell进城中完成)。因此,多行命令之间的执行是相互独立的,相互之间不存在依赖(多条命令行的执行为多个相互独立的进程)。

在Makefile中书写在同一行中的多个命令属于一个完整的shell命令行,书写在独立行的一条命令是一个独立的shell命令行。因此:在一个规则的命令中,命令行“cd”改变目录不会对其后的命令的执行产生影响。就是说其后的命令执行的工作目录不会是之前使用“cd”进入的那个目录。如果要实现这个目的就不能把“cd”和其后的命令放在两行来书写。而应该把这两条命令写在一行上,用分号分隔。这样它们才是一个完整的shell命令行。如:

 

foo : bar/lose

cd bar; gobble lose > ../foo

 

如果希望把一个完整的shell命令行书写在多行上,需要使用反斜杠(\)来对处于多行的命令进行连接,表示他们是一个完整的shell命令行。例如上例我们以也可以这样书写:

foo : bar/lose

cd bar;  \

gobble lose > ../foo

 

make对所有规则命令的解析使用环境变量“SHELL”所指定的那个程序,在GNU make中,默认的程序是“/bin/sh”。

不像其他绝大多数变量,它们的值可以直接从同名的系统环境变量那里获得。make的环境变量“SHELL”没有使用系统环境变量的定义。因为系统环境变量“SHELL”指定那个程序被用来作为用户和系统交互的接口程序,它对于不存在直接交互过程的make显然不合适。在make的环境变量中“SHELL”会被重新赋值;它作为一个变量我们也可以在Makefile中明确地给它赋值(指出解释程序的名字,当明确指定时需要使用完整的路径名。如“/bin/sh”),变量“SHELL”的默认值是“/bin/sh”。

5. 待补充

 待补充



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值