2017-03-21 140 views
1

即使未做任何更改,我的makefile也会始终重建项目。即使未做任何更改,Java Makefile也会始终重建

我该如何解决?

我的项目结构遵循通常的bin /,src /,Makefile模式。

的Makefile:

# output directory 
BIN = bin/ 

# input directory 
SRC = src/ 

# java compiler 
JC = javac 

# compile flags 
JFLAGS = -d $(BIN) -cp $(SRC) 

sourcefiles = $(addprefix $(SRC), \ 
    A.java \ 
    B.java \ 
    C.java) 

classfiles = $(sourcefiles:.java=.class) 

all: $(classfiles) 

%.class: %.java 
    $(JC) $(JFLAGS) $< 

clean: 
    $(RM) $(BIN)*.class 

我从例子我在网上找到做此生成的文件,但我不知道我明白了一切正在做的,所以,如果我也可以得到一个解释,那将是巨大的:3

+0

为什么使用make for Java?有一些Java构建工具(Maven和Gradle)更容易和更可靠。 – chrylis

+0

你怎么调用'make'?如果您的调用触发了可以解释您观察到的“干净”目标。此外,'$(SRC)'不是类路径,它是源路径。你通过替换文件的后缀来定义'classfiles',但它们也应该放在不同的目录中,是吗?所以这可以解释你观察到的,因为'$(classfiles)'将永远是空的。正如@ chrylis让你知道的,“make”是这项工作的错误工具。 –

回答

2

一般而言,make不适合Java。使用与传统编译器类似的工具可以发挥最佳效果:它们采用输入文件foo.X(也可能包含其他一些输入文件),并生成单个输出文件foo.Y。对于C编译器,例如XcYofoo.c编译为foo.o)。

在编译器的单个调用会生成多个输出文件的情况下,很难使用Make,并且当输出文件的名称与输入文件的名称没有直接关系时使用它并不容易(在这种情况下,您必须编写所有明确的规则,而不是模式规则)。

对于Java编译一个.java输入文件可以产生多个不同.class文件和.class文件的名称并不一定与.java文件的名称。

在你的情况下,我敢打赌,如果你看看javac为你的A.java文件生成的输出文件,你会发现它不会生成A.class。因为A.class不存在,make会一直尝试重建它。

哦。也。你正在把文件放在不同的目录中。所以,即使你限制自己的情景,名称是相同的,你必须写你的模式是这样的:

# ... Keep the first part as in your example 

classfiles = $(patsubst $(SRC)%.java,$(BIN)%.class,$(sourcefiles)) 

all: $(classfiles) 

$(BIN)%.class : $(SRC)%.java 
     $(JC) $(JFLAGS) $< 

# ... Keep the clean rule as in your example 

的模式%必须相同;如果你把东西放在不同的目录中,它们就不一样了。

+0

是的,我限制了''.java''和''.class''具有相同名称的情况。我确实理解你的意思,所以也许我会研究其他方式来构建除了Makefile之外的项目。然而,你的解决方案不起作用,现在''make''总是说没有什么可以构建的。 – Tirafesi

+0

你确实保留了“全部”目标,对吧?我的意思并不是要你把它拿出来,而是包括需要改变的线条,而不是不需要改变的线条。我会更新。 – MadScientist

+0

哦。您将反斜杠放入变量SRC/BIN中。我从来不这样做,我忘了有时候人们会这样做。你需要一个稍微不同的patsubst。我会解决的。 – MadScientist

相关问题