编写Makefile
Makefiles中包含5种内容,分别是显式规则、隐含规则、变量定义、指令以及注释。
Makefiles中包含什么
Makefiles中包含5种内容,分别是显式规则、隐含规则、变量定义、指令以及注释。
显式规则明确了何时以及如何生成target,它会列出target的所有prerequisites和recipes。
隐含规则说明了如何根据与target名称相应的依赖文件来生成target。
变量定义是指为变量指定文本字符串值得行,可以在其他地方将变量替换到文本中。
指令是make在读取Makefile时执行的某些特殊操作的指令。包括引用其他Makefile、决定是否根据变量值使用还是忽略相关部分(ifdef)等
Makefile以#开头的行是注释。如果需要字符#,需要进行转义\#。recipes中的注释会被传递给shell。
Makefile名称
make默认查找文件名顺序为GNUmakefile、makefile以及Makefile。
通常建议使用Makefile,因为首字母大写名称更加明显。如果想要使用其他名称,可以手动指定名称-f name或--file=name告诉make。当通过-f或--file指定文件之后,GNUmakefile、makefile以及Makefile则不会检查读取。
引用其他Makefiles
make遇到include指令会停止读取当前的makefile,先将include包含的makefile读入。
include filenames...
filenames是shell的文件名通配符。如果为空,不会被读入也不报错。
使用include指令的一种情况是,不同目录下的多个程序的makefile使用一组通用的变量定义。
如果指定的filenames没有找到,则会搜索-I或--include-dir指定的目录,要是还没有找到就会搜索/usr/local/include。
如果filenames指定的文件没有找到会产生一条警告,然后继续执行。
Makefiles变量
如果环境变量Makefiles变量被定义,那么make会优先读取Makefiles变量定义的文件。这个和include指令是相同的功能。但是默认target不会从这些文件中指定。当然,如果没有找到文件也不会保存。
Makefiles变量的调用通常是支持make的递归调用。
make如何读入Makefile
make读入Makefile分为两个阶段,分别如下:
第一阶段:
- 读入所有
Makefiles。 - 读入
include指令引用的Makefile。 - 初始化变量。
- 推导隐含规则。
- 为所有
target构建依赖关系图。
第二阶段:
make根据依赖关系决定哪些target需要更新。- 执行
recipe生成相应target。
变量的扩展阶段如下
immediate = deferred
immediate ?= deferred
immediate := immediate
immediate ::= immediate
immediate += deferred or immediate
immediate != immediate
define immediate
deferred
endef
define immediate =
deferred
endef
define immediate ?=
deferred
endef
define immediate :=
immediate
endef
define immediate ::=
immediate
endef
define immediate +=
deferred or immediate
endef
define immediate !=
immediate
endef
如果变量被使用,则根据上述方式决定是立即扩展还是延迟扩展。
如何解析Makefiles
- 读取完整的逻辑行,包含
\转义的行。 - 移除注释。
- 如果改行是以
recipe前缀开头并处于规则上下文中,则将其添加到当前recipe中,并读取下一行。 - 展开
immediate元素。 - 查找分隔符,比如
:或=,确定该行是赋值还是规则。 - 读取下一行。
- 原文作者:生如夏花
- 原文链接:https://DBL2017.github.io/post/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/%E6%9E%84%E5%BB%BA%E5%B7%A5%E5%85%B7/makefile/%E7%BC%96%E5%86%99makefile/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。