【问题标题】:Make doesn't resolve outdated dependencies as I would expect it toMake 不会像我期望的那样解决过时的依赖项
【发布时间】:2018-03-12 23:59:09
【问题描述】:

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

这是我最终想出的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)

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

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

现在我的问题是:如果我运行make target.jar(在修改了至少一个源文件之后),第一条规则作为依赖项执行,所以我看到源代码正在编译,但第二条规则永远不会执行,并且我的 .jar 档案没有更新。我必须运行 make clean 才能重建 .jar。

我在链式依赖方面一定做错了什么,请帮助我:-)

【问题讨论】:

    标签: java makefile dependencies


    【解决方案1】:

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

    【讨论】:

    • 哦,好吧,我以为构建目录的时间戳会在 javac 更新其中的文件时更新...谢谢:D
    猜你喜欢
    • 2016-06-19
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2021-04-20
    • 2016-12-03
    • 1970-01-01
    相关资源
    最近更新 更多