3 回答
TA贡献2051条经验 获得超10个赞
默认情况下,Makefile目标是“文件目标”-用于从其他文件构建文件。Make假设其目标是文件,这使得编写Makefile相对容易:
foo: bar
create_one_from_the_other foo bar
但是,有时您希望Makefile运行不代表文件系统中物理文件的命令。常见的目标“干净”和“全部”就是很好的例子。可能不是这种情况,但是您可能clean在主目录中有一个命名的文件。在这种情况下,Make会感到困惑,因为默认情况下clean目标将与此文件关联,而Make仅在文件的依赖关系似乎不是最新时才运行它。
这些特殊的目标称为phony,您可以明确地告诉Make与文件无关,例如:
.PHONY: clean
clean:
rm -rf *.o
make clean即使您有一个名为的文件,Now 也将按预期运行clean。
就Make而言,伪造目标只是一个始终过期的目标,因此,只要您询问make <phony_target>,它就可以独立于文件系统的状态运行。一些常见的make是经常假目标是:all,install,clean,distclean,TAGS,info,check。
TA贡献1788条经验 获得超4个赞
假设您有install
目标,这在makefile中很常见。如果不使用.PHONY
,并且install
与Makefile所在的目录中存在一个名为的文件,make install
则将不执行任何操作。这是因为Make将规则解释为“执行某类配方以创建名为install
” 的文件。由于该文件已经存在,并且其依存关系没有更改,因此不会执行任何操作。
但是,如果将install
目标设为PHONY,它将告诉make工具该目标是虚构的,并且该make不应该期望它创建实际的文件。因此,它将不会检查install
文件是否存在,这意味着:a)如果文件确实存在,其行为不会改变; b)stat()
不会调用多余的行为。
通常,Makefile中所有不会产生与目标名称相同名称的输出文件的目标都应为PHONY。这通常包括all
,install
,clean
,distclean
,等。
TA贡献1859条经验 获得超6个赞
注意:make工具读取makefile并检查规则中':'符号两侧的文件的修改时间戳。
例
在目录“测试”中,存在以下文件:
prerit@vvdn105:~/test$ ls
hello hello.c makefile
在makefile中,规则定义如下:
hello:hello.c
cc hello.c -o hello
现在假设文件“ hello”是一个包含一些数据的文本文件,该文件是在“ hello.c”文件之后创建的。因此,“ hello”的修改(或创建)时间戳将比“ hello.c”的时间戳更新。因此,当我们从命令行调用“ make hello”时,它将显示为:
make: `hello' is up to date.
现在访问“ hello.c”文件,并在其中添加一些空格,这不会影响代码语法或逻辑,然后保存并退出。现在,hello.c的修改时间戳比“ hello”的修改时间戳新。现在,如果您调用“ make hello”,它将执行以下命令:
cc hello.c -o hello
文件“ hello”(文本文件)将被新的二进制文件“ hello”(上述编译命令的结果)覆盖。
如果我们在makefile中使用.PHONY,如下所示:
.PHONY:hello
hello:hello.c
cc hello.c -o hello
然后调用“ make hello”,它将忽略pwd“ test”中存在的任何文件,并每次执行命令。
现在假设,“ hello”目标没有声明依赖项:
hello:
cc hello.c -o hello
并且pwd“测试”中已经存在“ hello”文件,那么“ make hello”将始终显示为:
make: `hello' is up to date.
添加回答
举报