You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java项目中通过Makefile指定make-java目标编译?

解决Makefile中make-java目标无法编译的问题

你遇到的问题核心是对Makefile里$*这个自动变量的适用场景理解有误——$*只在后缀规则(比如你原来的.java.class)或者模式规则(比如%.class: %.java)中才有意义,它用来匹配目标文件名和依赖文件名的共同前缀部分。但在普通自定义目标(比如你写的make-java)里直接用$*,Make根本不知道要匹配哪个文件,自然无法执行正确的编译命令。

下面给你两种可行的修改方案,根据你的需求选择:

方案1:复用原有编译逻辑,让make-java依赖已有的classes目标

这是最简洁的方式,完全保留原Makefile的增量编译能力(只编译修改过的.java文件):

JFLAGS = -g
JC = javac
.SUFFIXES: .java .class
.java.class:
	$(JC) $(JFLAGS) $*.java
CLASSES = \
	Main.java \
	Book.java \
	Library.java
default: classes
classes: $(CLASSES:.java=.class)
clean:
	$(RM) *.class
# 修改后的make-java目标,通过依赖触发编译
make-java: classes
run-java:
	java Main

说明:

原来的classes目标已经实现了所有.java文件的编译逻辑,现在只需要让make-java依赖它,执行make make-java时就会自动触发classes目标的编译流程,和你原来用make classes的效果完全一致,只是换了个命令入口。

方案2:直接在make-java目标中编写编译命令(无需后缀规则)

如果你不想用后缀规则,也可以直接在make-java里指定要编译的所有文件,逻辑更直观:

JFLAGS = -g
JC = javac
CLASSES = \
	Main.java \
	Book.java \
	Library.java
# 直接编译所有指定的Java文件
make-java:
	$(JC) $(JFLAGS) $(CLASSES)
clean:
	$(RM) *.class
run-java:
	java Main

进阶优化(保留增量编译):

如果需要保留增量编译能力,可以把后缀规则换成模式规则,然后让make-java依赖生成的.class文件:

JFLAGS = -g
JC = javac
CLASSES = \
	Main.java \
	Book.java \
	Library.java
# 模式规则,实现增量编译
%.class: %.java
	$(JC) $(JFLAGS) $<
make-java: $(CLASSES:.java=.class)
clean:
	$(RM) *.class
run-java:
	java Main

这样make make-java只会编译那些修改过的.java文件,效率更高。

内容的提问来源于stack exchange,提问作者Will Wost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:47:28