一、Makefile重建是什么?
Makefiles是一种用于构建和维护软件项目的工具。它们是文本文件,包含了一系列规则和指令,告诉计算机如何编译、链接和生成可执行文件。
当我们使用make命令时,它会检测当前目录下的makefile文件,并根据其中的规则执行相应的操作。Makefile可以从其他文件中重新生成,比如RCS或SCCS文件。为了获取最新的makefile版本进行读取,在读取所有makefiles之后,make会尝试更新每个makefile
。
如果一个makefile有规则来描述如何更新它自己,或者适用一个隐含规则,那么它将在必要时被更新。在检查完所有makefile之后,如果任何一个实际上发生了变化,make会从头开始读取所有makefile,并重新构建项目。这个过程会持续进行,直到没有任何makefile发生变化。
有时候,我们想阻止make对某些makefiles进行隐含规则搜索,以提高效率。为了实现这个目的,可以使用一些方法来阻止隐含规则的查找。例如,我们可以编写一个显式规则,将makefile作为目标,并且命令体为空。
另一种方法是使用双冒号规则。如果一个makefile有一个双冒号规则,并且没有前置条件但有命令体,那么该文件将总是被重新生成。在make重新启动并再次读取makefiles之后,这个makefile会再次被重新生成。为了避免无限循环,make不会尝试重新生成作为双冒号规则的目标且没有前置条件的makefile。
虚拟目标也具有相同的效果。如果一个makefile被标记为虚拟目标,它永远不会被认为是最新的,这会导致make持续重新启动。为了避免这种情况,make不会尝试重新生成被标记为虚拟目标的makefiles。
如果我们没有使用’-f’或’–file’选项指定任何makefiles,make将尝试使用默认的makefile名称。如果默认的makefile不存在,但可以通过运行make规则来创建,make将尝试制作每个默认的makefile,直到成功制作一个,或者用尽了可尝试的名称。
当使用’-t’或’–touch’选项时,我们不希望使用过时的makefile决定触发哪些目标。因此,‘-t’选项对更新makefiles没有影响;即使指定了’-t’,它们仍然会被实际更新。同样地,‘-q’(或’–question’)和’-n’(或’–just-print’)也不会阻止makefiles的更新。
然而,有时我们确实希望阻止或更新makefiles。可以通过在命令行中指定makefile名称作为目标,并同时将它们指定为makefiles来实现这一点。当指定makefile名称作为目标时,选项’-t’等会应用于它们。
总之,Makefiles是一种用于构建软件项目的工具,可以通过规则和指令告诉计算机如何编译、链接和生成可执行文件。Make命令可以根据Makefile中的规则执行操作,而且可以控制重新生成和更新过程,以提高效率和准确性。
二、Makefile示例
假设有以下4个文件:a.mk
, b.mk
, depend
和 Makefile
。
其中前三个文件都是空的,并且depend
文件要在 a.mk
和 b.mk
建立之后再建立,即depend
文件比 a.mk
和 b.mk
新。
Makefile
文件内容如下:
a.mk: depend
echo "name=John" > a.mk
b.mk: depend
echo "city=New York" > b.mk
include a.mk b.mk
.PHONY: show
show:
echo $(city)
echo $(name)
然后执行 make show
。
执行 make show
将会输出:
New York
John
解析过程如下:
- Makefile 读取并解析
include a.mk b.mk
这一行,加载了a.mk
和b.mk
两个文件。 - Makefile 寻找
a.mk
的生成规则,发现依赖关系为depend
,因此执行depend
规则,将"name=John"
写入a.mk
。 - 同样地,Makefile 寻找
b.mk
的生成规则,发现依赖关系为depend
,因此执行depend
规则,将"city=New York"
写入b.mk
。 - 所有被
include
的文件都重新生成后,Make 会清空状态并重新读取 Makefile。 - 再次处理
include a.mk b.mk
这一行,这次会将a.mk
和b.mk
中的内容替换到include
的位置。 - Make 为被
include
的文件再次寻找生成规则,但由于文件已经是最新的,不需要重新生成。 - 接着,Make 执行
show
目标,输出变量city
和name
的值。