这是我的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和get

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

然而,由于某些原因,运行make测试总是失败

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)
...

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

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

.PHONY: all test clean

注意,您可以在这里声明所有的伪目标。

虚假目标不是真正的文件名称;相反,它只是在您发出显式请求时执行的配方的名称。


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

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

-B,——always-make无条件地制造所有目标。

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


我的错误是使目标名称为“filename.c:”而不是“filename:”


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