#define the suffixes
.SUFFIXES: .java .class
#compile all java files to .class
.java.class:
javac -g *.java
#CounterStatTester is a tester class for CounterStat
CounterStatTester.class: CounterStat.class
test: CounterStatTester.class CounterStat.class
java CounterStatTester
当我尝试"进行测试"时,shell说" make:***没有规则来制作目标`test'。停止&#34。 但是我确实写过" java CounterStatTester",为什么它仍然无法找到规则?
答案 0 :(得分:1)
这里有很多不良风格的例子。我将尝试按照外观顺序列出所有问题,而不仅仅是回答问题。如果你做了我建议的所有事情,你原来的问题肯定会消失。
如果你知道自己在做什么并且有充分的理由这样做就可以使用“穷人风格”,并且已经学会了很好的风格。在你的情况下,这些都不是。
.SUFFIXES
已过时,不应用于新代码
同样,.java.class:
之类的“后缀规则”已过时,不应使用。
在任何情况下,您的.java.class:
规则都应该生成一个.java
文件并生成一个.class
文件。 makefile中的好样式,是每个规则配方一次生成一个目标,而不是多个目标。
所以,你应该有这样的东西:
%.class: %.java Makefile
javac -g $<
CounterStatTester.class
没有理由“依赖”CounterStat.class
,所以你不应该有这个规则。在这种情况下,“依赖性”意味着CounterStatTester.class
的方法读取CounterStat.class
。 CounterStatTester.class
实际上取决于CounterStatTester.java
(和Makefile,这不太明显),这已经被我向你展示的规则捕获了。
如上所述,每个规则配方都应该写一个目标。由于test
不是文件,而是抽象概念,因此无法编写,因此,它不应具有带有配方的规则。
编写makefile的重点是,除非必要,否则不必执行配方,从而节省时间。在您的情况下,test
根本不存在,因此将始终执行配方,这对于makefile来说毫无意义。
相反,您应该拥有一个名称为CounterStat_tested
的文件和一个如下规则:
CounterStat_tested: CounterStatTester.class CounterStat.class Makefile
java CounterStatTester && touch $@
最后,makefile的顶部应该有一个all
目标:
.PHONY: all
all: CounterStatTester.class CounterStat.class CounterStat_tested