如何在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
相关产品推荐
相关产品推荐

