编写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://blduan.top/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 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。