《跟我一起写Makefile》读书笔记(3)
一个Makefile例子
五、书写规则
一般来说,定义在 Makefile 中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。
1、规则的语法
(1)如果命令太长,你可以使用反斜框(‘\’)作为换行符。make 对一行上有多少个字符没有限制。
(2)一般来说,make 会以 UNIX 的标准 Shell,也就是/bin/sh 来执行命令。
2、在规则中使用通配符
(1)make支持三各通配符: “*”,“?”,“[...]”;
(2)objects = *.o ,这里objects的值就是“*.o” ,并不会展开。
如果想让 objects 的值是所有[.o]的文件名的集合,那么需要写成objects := $(wildcard *.o) 。
3、文件搜索
(1)在哪里寻找依赖的文件?
(2)Makefile 文件中的特殊变量“VPATH”就是完成这个功能的。
- 如果没有指明这个变量,make 只会在当前的目录中去找寻依赖文件和目标文件。
- 如果定义了这个变量,那么make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件。
- 如VPATH = src:../headers, 指定两个目录,“src”和“../headers”,make 会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)
- 如vpath %.h ../headers,该语句表示,要求 make 在“../headers”目录下搜索所有以“.h”结尾的文件。(如果某文件在当前目录没有找到的话)
4、多目标
我们的可以使用一个自动化变量“[email protected]”,这个变量表示着目前规则中所有的目标的集合
5、静态模式
<commands>
....
目标集合:目标集合的模式:依赖集合的模式
- 意思是我们的<target>集合中都是以“.o”结尾的;
- 意思是对<target-parrtern>所形成的目标集进行二次定义;
- 即,取<target-parrtern>模式中的“%”(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合。
六、书写命令
1、显示命令
(1)通常,make把它要执行的命令行,在命令执行前输出到屏幕上。但如果我们用“@”字符在命令行前,那么这个命令将不被 make 显示出来,但命令还是被运行的。(这叫静默执行)
(2)如果 make 执行时,带入 make 参数“-n”或“--just-print”,那么其只是显示命令,但不会执行命令
- 这个功能很有利于我们调试我们的 Makefile,看看我们书写的命令执行起来是什么样子的或是什么顺序的。
2、命令错处处理
- 如果一个规则中的某个命令出错了(命令退出码非零),那么 make 就会终止执行当前规则,这将有可能终止所有规则的执行。
如:
clean:
-rm -f *.o
(3)给 make 加上“-i”或是“ --ignore-errors”参数,那么,Makefile 中所有命令都会忽略错误 。
(4)make 的参数的是“-k”或是“--keep-going”,这个参数的意思是,如果某规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。
3、嵌套执行make
(1)总控 Makefile 的变量可以传递到下级的 Makefile 中(如果你显示的声明),但是不会覆盖下层的 Makefile 中所定义的变量,除非指定了“-e”参数。
(2)一些细节
- 如果你要传递变量到下级 Makefile 中,那么你可以使用这样的声明:export <variable ...>;
- 如果你不想让某些变量传递到下级 Makefile 中,那么你可以这样声明:unexport <variable ...> ;
- 如果你要传递所有的变量,那么,只要一个 export 就行了,后面什么也不用跟,表示传递所有的变量;
- 有两个变量,一个是 SHELL,一个是 MAKEFLAGS,这两个变量不管你是否 export,其总是要传递到下层 Makefile 中,特别是 MAKEFILES 变量,其中包含了 make的参数信息,如果我们执行“总控 Makefile”时有 make 参数或是在上层 Makefile 中定义了这个变量,那么 MAKEFILES 变量将会是这些参数,并会传递到下层 Makefile 中,这是一个系统级的环境变量。
4、定义命令包
七、使用变量
- 变量是大小写敏感的, “foo”、 “Foo”和“FOO”是三个不同的变量名;
- 变量的命名字可以包含字符、数字,下划线(可以是数字开头);
-
在 Makefile 中的定义的变量,就像是 C/C++语言中的宏一样,他代表了一个文本字串,在 Makefile 中执行的时候其会自动原模原样地展开在所使用的地方。其与 C/C++所不同的是(字符串常量不能修改?),你可以在 Makefile 中改变其值。
1、变量的基础
类似shell中变量的定义和使用方法,需要用$来使用,强烈建议使用()或者{ }将变量包起来使用。
2、变量中的变量
在 Makefile 中有两种方式来在用变量定义变量的值
(1)简单的使用“=”号
- 在“=”左侧是变量,右侧是变量的值;
- 右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,也可以使用后面定义的值。
- 前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
- 如果前面已经定义,则本句什么也不做,跳过
- 接续赋值