为啥 make 认为目标是最新的?

Posted

技术标签:

【中文标题】为啥 make 认为目标是最新的?【英文标题】:Why does make think the target is up to date?为什么 make 认为目标是最新的? 【发布时间】:2011-04-25 07:24:47 【问题描述】:

这是我的 Makefile:

REBAR=./rebar
REBAR_COMPILE=$(REBAR) get-deps compile

all: compile

compile:
    $(REBAR_COMPILE)

test:
    $(REBAR_COMPILE) skip_deps=true eunit

clean:
    -rm -rf deps ebin priv doc/*

docs:
    $(REBAR_COMPILE) doc

ifeq ($(wildcard dialyzer/sqlite3.plt),)
static:
    $(REBAR_COMPILE) build_plt analyze
else
static:
    $(REBAR_COMPILE) analyze
endif

我可以多次运行make compile并得到

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ make compile
./rebar get-deps compile
==> erlang-sqlite (get-deps)
==> erlang-sqlite (compile)

但是,由于某种原因,运行 make test 总是给出

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ make test
make: `test' is up to date.

即使文件没有被编译。问题是,为什么?

直接运行相同的命令即可:

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ ./rebar get-deps compile skip_deps=true eunit
==> erlang-sqlite (get-deps)
==> erlang-sqlite (compile)
Compiled src/sqlite3_lib.erl
Compiled src/sqlite3.erl
==> erlang-sqlite (eunit)
...

【问题讨论】:

【参考方案1】:

也许您的目录中有一个名为test 的文件/目录。如果此目录存在,并且没有更新的依赖项,则不会重建此目标。

要对这些与文件无关的目标强制重建,您应该将它们设置为假的,如下所示:

.PHONY: all test clean

请注意,您可以在此处声明所有虚假目标。

虚假目标是不是真正的文件名;相反,它只是您提出明确请求时要执行的配方的名称。

【讨论】:

我有一个名为 build 的目录和另一个名为 lib 的目录。事后看来,这些并不是完美的目标名称。呃......制作。 *alltestclear 是您的 makefile 目标名称 另一种解决方案是更改标签。在您的情况下,将test 更改为test_rule 或其他其他内容。 @MattD 我也是,这是 make 的问题吗? @Birger 如果您有要调用的目标,例如“make build”和“make lib”,并且存在这些目录,那么您将需要使用此策略或类似的策略。 【参考方案2】:

编辑:这仅适用于 make 的某些版本 - 你应该检查你的手册页。

您也可以将-B 标志传递给make。根据手册页,这样做:

-B, --always-make无条件使所有目标。

因此,如果您不想编辑 Makefile 或更改测试文件夹的名称,make -B test 将解决您的问题。

【讨论】:

-B 对我来说是向后兼容的模式...(似乎没有指定 FreeBSD、OS / GNU 工具包) 哦,有趣...--always-make 适合你吗? 不。 .PHONY 目标似乎有点便携...(至少对于 FreeBSD,不确定 Solaris 之类的东西) 这违背了 make 的目的——自动确定程序的哪些部分在更改后需要重新构建。如果您的 makefile 需要 --always-make 选项才能工作,则您的 makefile 已损坏。 @GertvandenBerg .PHONY 将成为 POSIX 标准第 8 期的一部分 austingroupbugs.net/view.php?id=523【参考方案3】:

当您在 Makefile 所在的目录中有一个与 Makefile 目标名称相同的文件时,就会发生这种情况。

【讨论】:

这是我的问题。谢谢!【参考方案4】:

我的错误是将目标名称设为“filename.c:”,而不仅仅是“filename:”

【讨论】:

以上是关于为啥 make 认为目标是最新的?的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中运行 make 文件时的最新消息

第15课 - make的隐式规则(上)

为啥最新版的VS2017没有net framework 4.6.2,且我无法安装

Mac SDK:使用最新的SDK,但确保与早期部署目标的向后兼容性

为啥这个makefile在'make clean'上执行一个目标

为啥最新的MinGW gcc版本是6.3.0