Make不会像我期望的那样解决过时的依赖关系

时间:2017-10-01 20:30:25

标签: java makefile dependencies

我目前正在开发一个Java项目,我选择使用Make进行编译(请不要评判我)。

这是我最终提出的Makefile :(我在Windows上编译)

rwildcard = $(strip $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)))

SRCDIR := src
RESOURCESDIR := resources
LIBDIR := lib
BUILDDIR := build

SRCFILES := $(call rwildcard,$(SRCDIR)/,*.java)
CLASSPATH := $(subst $(eval) ,;,$(wildcard $(LIBDIR)/*.jar))
TARGET := target.jar

.PHONY: default install clean

default: $(TARGET)

$(BUILDDIR): $(SRCFILES)
    @if not exist $(BUILDDIR) mkdir $(BUILDDIR)
    javac -d $(BUILDDIR) -cp $(CLASSPATH) -sourcepath $(SRCDIR) $(SRCFILES)
    copy /y $(RESOURCESDIR) $(BUILDDIR)

$(TARGET): $(BUILDDIR)
    jar -cvf $(TARGET) -C $(BUILDDIR) .

install: $(TARGET)
    copy /y $(TARGET) "C:/path/to/installation/directory/"

clean:
    @if exist $(BUILDDIR) rmdir /s /q $(BUILDDIR)
    @if exist $(TARGET) del /q $(TARGET)

N.B。:如果你想知道,第一行定义了一个用于查找所有.java文件的递归wildcard函数。

因此,我们的想法是让一个规则同时编译所有源文件,并将资源文件复制到build文件夹,另一个规则从该文件夹创建.jar目标存档。您可以忽略其他规则。

现在这是我的问题:如果我运行make target.jar(在修改了至少一个源文件之后),第一个规则作为依赖项执行,所以我看到编译的源,但第二个规则从不执行,我的.jar存档未更新。我必须运行make clean才能重建.jar。

我必须对链式依赖关系做错,请帮助我: - )

1 个答案:

答案 0 :(得分:1)

使目标依赖于目录的时间戳是一件危险的事情(没有冒犯意味着:如果你这样做,你应该知道你做了什么;)) 在你的情况下,它绝对是不洁净的设计:你的目标取决于中间文件,而不是存储它们的地方。您的编译过程不会更新$(BUILDDIR)的时间戳,因此不需要执行$(TARGET)的配方,因为它的先决条件不是更新的。您需要将.class文件添加到先决条件列表以及这些文件的规则,包括$(BUILDDIR)作为仅订购的先决条件。