目录
官网:http://www.gnu.org/software/make/manual/make.html
官网:http://www.gnu.org/software/make/manual/make.html
PDF-makefile教程-链接记不清了
自己的理解:makefile是make.exe调makefile脚本执行其他exe文件(加载路径)
Makefile介绍
target...:prerquisites... (target是目标文件,包含obj,.c,Label)(prequisites生成的目标)
command make执行的命令
...
...
说明:prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行
后续的command定义了如何生成目标文件的操作系统命令,一定要以一个Tab键开头。make会比较targets文件和
prerequisites文件的修改日期
makefile命令,必须要以Tab键开始。默认情况下会寻找makefile文件。
如果使用自己的名字,则使用命令:make -f(file) 文件名
Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的#include,被包含的文件会原模原样的放在当前
文件的包含位置,和TLC类似。
在include前面可以有一些空字符,但是绝不能是Tab键开始。例如include foo.make *.mk
如果文件没有找到,make会生成一条警告信息,但是不会马上出现致命错误。继续载入其他的文件,
一旦完成makefile的读取,make会再重试这些没有找到,或者不能读取的文件,如果还是不行,make
会出现一条致命错误。
-include <filename>
其表示,无论include过程中出现什么错误,都不要报错执行。
make的工作方式
- 1:读入所有makefile
- 2:读入被include的其他makefile
- 3:初始化文件中的变量
- 4:推导隐晦规则
- 5:生成依赖关系链
- 6:工具关系链决定哪些目标要重新生成
- 7:执行生成命令
Makefile细则
-
书写规则
- 规则语法
targets:prerequisites;command(targets是文件名,以空格分开,可以使用通配符。)
command(command,命令行,如果可以在preprequisites在一行,用分号隔开)
...
- 在规则中的通配符
- 文件搜索
文件搜索路径的方法是使用make的"vpath"关键字(注意,它是全小写的),这不是变量,这是一个make关键字,这和
上面提到的那个VPATH变量很类似,但是它更为灵活。它的使用方法有
vpath <pattern><directories>
为符合模式<pattern>的文件指定搜索目录<directories>.
我们可以连续地使用vpath语句,以指定不同搜索策略。如果连续的vpath语句中出现了相同的<pattern>,或是被重复
了的<pattern>,那么,make会按照vpath语句的先后顺序来执行搜索。
- 伪目标
- 多目标
Makefile的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似。于是我们就能把其合并起来。当然,多个目标的生成规则的执行命令是同一个,这可能会给我们带来麻烦。
- 静态模式
<targets...>:<target-pattern>:<prereq-patterns...>
<commands>
...
如果我们的<target-parrtern>定义成"%.o",意思是我们的<target>集合都是以".o"结尾的,
而如果我们的<prereq-parrterns>定义成"%.C",意思是对<target-parrtern>所形成的目标集进行二次定义,
其计算方法是,取<target-parrtern>模式中的"%"(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合
$< 表示所有的依赖目标集 $@ 表示目标集
- 自动生成依赖性
-
书写命令
-
使用变量
- 变量中的变量
MAEKLEVEL是记录了我们的当前makefile的调用层数
- 目标变量
<target...>:<variable-assignment>
<target...>:overide<variable-assignment>
<variable-assignment>可以是前面讲过的各种赋值表达式,如"="、":="、"+="或是"?="。
第二个语法是针对于make命令行带入的变量,或是系统环境变量
这个特性非常有用,当我们设置了这样一个变量,这个变量会作用到由这个目标所引发的所有规则中去。
- 模式变量
在GNU的make中,还支持模式变量(Pattern-specfic Variable),通过上面的目标变量中,我们知道,
变量可以定义在某个目标上。模式变量的好处就是,我们可以给定一种模式,可以把变量定义在符合
这种模式的所有目标上
- 自动变量
自动变量在运行命令时才会有
-
使用条件判断
-
使用函数
-
make的运行
-
隐含规则
在使用makefile时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标
文件。
-
使用隐含规则
如果要使用隐含规则生成你需要的目标,你所需要做的是不要写出这个目标的规则
在make的隐含规则库中,每一条隐含规则都在库中有其顺序,越靠前的则是越被经常使用的,
所以,这会导致我们有些即使我们显示到指定了目标依赖,make也不会管。如下面这条规则
-
隐含规则一览
这里我们将讲述所有预先设置的隐含规则,如果我们不明确地写下规则,那么,make就会在
这些规则中寻找所需要规则和命令。当然,我们也可以使用make的参数 "-r"或"--no-builtin-rules"
选项来取消所有的预设置的隐含规则。
-
隐含规则使用的变量
-
隐含规则链
有些时候,一个目标可能被一系列的隐含规则所作用。例如,一个[.o]的文件生成,可能会是被Yacc的.y文件生成.c,然后
再被C的编译器生成。我们把这一系列的隐含规则叫做"隐含规则链"
在上面的例子中,如果文件.c存在,那么就直接调用C的编译器的隐含规则
通常,一个被makefile指定成目标或是依赖目标的文件不能被当作中介。然而,
你可以明显地说明一个文件或是目标是中介目标,你可以使用伪目标.INTERMEDIATE来强制声明。
-
定义模式规则
-
-
老式风格的“后缀规则”
-
隐含规则搜索算法
-
使用make更新函数文件