我目前正在开发一个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。
我必须对链式依赖关系做错,请帮助我: - )
答案 0 :(得分:1)
使目标依赖于目录的时间戳是一件危险的事情(没有冒犯意味着:如果你这样做,你应该知道你做了什么;))
在你的情况下,它绝对是不洁净的设计:你的目标取决于中间文件,而不是存储它们的地方。您的编译过程不会更新$(BUILDDIR)的时间戳,因此不需要执行$(TARGET)的配方,因为它的先决条件不是更新的。您需要将.class
文件添加到先决条件列表以及这些文件的规则,包括$(BUILDDIR)作为仅订购的先决条件。