【问题标题】:Without .PHONY target is getting built when a file named as target already exists in current directory当当前目录中已存在名为 target 的文件时,将构建没有 .PHONY 目标
【发布时间】:2014-09-02 07:16:50
【问题描述】:

在浏览 MakeFiles 时,我发现即使在不使用 .PHONY 的情况下仍存在名为目标的文件时,目标正在构建。 但是当我对另一个目标(即干净)做同样的事情时,目标不会被构建并说“干净是最新的”,这没关系。 我只想知道当文件存在于当前目录中时,为什么要构建另一个目标。

制作文件:

CC:= gcc
CCFLAGS:=-Wall -Wextra
hello: hellomake.o hellofunc.o
        $(CC) $(CCFLAGS) hellomake.c hellofunc.c -o file
hellomake.o : hellomake.c
        $(CC) $(CCFLAGS) -c hellomake.c
hellofunc.o : hellofunc.c
        $(CC) $(CCFLAGS) -c hellofunc.c
clean:
        rm -rf *.o
        rm -rf file

我当前目录的文件名与目标相同,为“hello”。 它应该给出结果为“你好是最新的”,但它没有这样做并且输出为: 打个招呼

gcc  -Wall -Wextra  hellomake.c hellofunc.c -o file 

当 TARGET 不是 .PHONY 并且名为 TARGET 的文件已经存在于当前目录中时,请说明为什么要构建目标。

【问题讨论】:

  • 如果hellomake.chellofunc.chello 最新,它将重建。运行make hello 两次你可以看到第二次它会给你好是最新的
  • I just want to know why the other target is getting built when the file exists in the current directory 即使没有修改依赖项,您也应该检查目标是否已重建。
  • 在创建了我在 makefile 中使用过的文件之后,我正在我的目录中创建“hello”文件。但是 makefile 仍然没有给出任何错误,即使它没有 .PHONY。通常,当当前目录中存在与目标相同的文件时,它不应该运行目标的命令,而不使用 .PHONY 但在我的情况下它正在执行此操作。 :)

标签: makefile


【解决方案1】:

因为make 查看最后修改时间来决定构建什么。来自make manual

make 程序使用 makefile 数据库和文件的最后修改时间来决定哪些文件需要更新。

命令make 检查目标与其先决条件之间的时间关系。如果在目标之后修改了先决条件,则意味着目标已过期,即使文件存在,也会触发重建。所以很可能你的依赖项在目标之后被修改了。

为了避免这种行为,您可以:

  • 使用touch 更改目标时间戳。
  • 在调用make hello 之前使用make -t hellomake --touch hello。来自docs
‘-t’
‘--touch’
Marks targets as up to date without actually changing them. In other words,
make pretends to update the targets but does not really change their
contents; instead only their modified times are updated.

【讨论】:

  • 避免这种行为的最佳方法是简单地使用配方创建的文件的名称作为目标,这就是 make 的工作方式。因此,如果您的配方构建了一个名为 file 的文件,就像上面的配方 (gcc ... -o file),那么目标名称应该是 file,而不是 hello。然后一切都会按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多