协慌网

登录 贡献 社区

makefile 中. PHONY 的目的是什么?

什么.PHONY在 Makefile 中的.PHONY是什么?我已经完成了这个 ,但它太复杂了。

有人可以用简单的语言向我解释一下吗?

答案

默认情况下,Makefile 目标是 “文件目标” - 它们用于从其他文件构建文件。假设它的目标是一个文件,这使得编写 Makefile 相对容易:

foo: bar
  create_one_from_the_other foo bar

但是,有时您希望 Makefile 运行不代表文件系统中的物理文件的命令。这方面的好例子是 “清洁” 和 “全部” 的共同目标。 可能情况并非如此,但您可能在主目录中有一个名为clean的文件。在这种情况下,Make 会被混淆,因为默认情况下, clean目标将与此文件关联,而 Make 只会在文件看起来与其依赖关系不相关时才运行它。

这些特殊目标称为假冒 ,您可以明确告诉他们与文件无关,例如:

.PHONY: clean
clean:
  rm -rf *.o

现在make clean将按预期运行,即使你有一个名为clean的文件。

就 Make 而言,一个虚假的目标只是一个总是过时的目标,所以无论何时你问make <phony_target> ,它都会运行,独立于文件系统的状态。一些常见的make是经常假目标是: allinstallcleandistcleanTAGSinfocheck

假设您有install目标,这在 makefile 中非常常见。如果使用.PHONY ,并且名为install的文件与 Makefile 位于同一目录中,则make install将不执行任何操作 。这是因为 Make 将规则解释为 “执行这样的配方以创建名为install的文件”。由于文件已经存在,并且其依赖关系没有改变,因此不会做任何事情。

但是,如果您将install目标设为 PHONY,它将告诉 make 工具目标是虚构的,并且 make 不应指望它创建实际文件。因此,它不会检查install文件是否存在,这意味着:a)如果文件存在则不会改变其行为,并且 b)不会调用额外的stat()

通常,Makefile 中不生成与目标名称同名的输出文件的所有目标都应该是 PHONY。这通常包括allinstallcleandistclean等。

注意 :make 工具读取 makefile 并检查规则中 “:” 符号两侧的文件的修改时间戳。

在目录'test' 中存在以下文件:

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 中存在任何名为'hello' 的文件,它将忽略每次执行命令。

现在假设如果 makefile 中没有 target 的依赖项:

hello:
    cc hello.c -o hello

'hello' 文件已存在于 pwd'test' 中,然后'make hello' 将始终显示为:

make: `hello' is up to date.