4

尝试使用我创建的 Makefile 编译我的 Java 项目时出现此错误。

错误:

制作:没有制定目标src/edu/osu/lispinterpreter/output/*.class', needed by课程的规则。停止。*

生成文件内容:

JFLAGS = -g
JC = javac
.SUFFIXES: .java .class
.java.class:
    $(JC) $(JFLAGS) $*.java

CLASSES = \
        src/edu/osu/lispinterpreter/tokenizer/*.java \
        src/edu/osu/lispinterpreter/core/*.java \
        src/edu/osu/lispinterpreter/output/*.java \
        src/edu/osu/lispinterpreter/exceptions/*.java \
        src/edu/osu/lispinterpreter/input/InputParser.java \
        src/edu/osu/lispinterpreter/input/ReadInputString.java 

default: classes

classes: $(CLASSES:.java=.class)

clean:
    $(RM) *.class

有人可以帮我看看Makefile吗?

我正在使用 Eclipse 顺便说一句。

4

3 回答 3

2

来自http://www.gnu.org/software/make/manual/html_node/Wildcard-Pitfall.html#Wildcard-Pitfall

当通配符不匹配任何文件时,它会保持原样

似乎 src/edu/osu/lispinterpreter/output 是空的,所以 src/edu/osu/lispinterpreter/output/*.java 不匹配任何文件并保持原样,这不是预期的。使用通配符功能,可以避免这种情况。

解决方案是更换

src/edu/osu/lispinterpreter/output/*.java

经过

$(wildcard src/edu/osu/lispinterpreter/output/*.java)

依此类推,我认为所有其他行

于 2013-03-09T02:56:52.817 回答
1

我认为问题在于您*CLASSES变量中的使用。您编写该变量的方式是使用其中包含字符的“文件名”列表填充*......这将在其余的处理过程中传播。

你要么需要单独列出这些类,要么做一些事情来告诉 Make “glob”这个列表。如果您使用的是 GNU Make,那么通配符功能应该可以解决问题。

但请注意,这不适用于其他版本的 Make,因此您遇到了 Makefile 可移植性问题。(这让我回到了我认为 Ant 更好的评论。)


一旦你克服了这个问题,你就会遇到一个问题,如果你一次编译一个 Java 类:

  • 你的构建会很慢......'因为每个javac命令都会导致 JVM 启动(假设你使用的是 Hotspot 或 OpenJDK 工具链),
  • 您必须以正确的顺序构建类...根据源代码中固有的依赖关系,
  • 您必须将这些依赖项添加到 Makefile (!!!),并且
  • 如果你有依赖循环,你就有问题了!

如果有足够的耐心,您可以构建一个应对此问题的 Makefile,但这确实很棘手,并且生成的 Makefile 会很脆弱。现实的选择是:

  • 只需在一个命令中构建所有/ .java 文件javac,而不考虑依赖关系,
  • 添加一个“makedepend”规则,该规则使用某些东西来分析源代码或字节码文件并在 Makefile 中生成依赖关系。

或者只是使用蚂蚁。

参考:

于 2013-03-09T02:57:39.803 回答
1

您可以单独列出所有源文件,也可以使用wildcardMakefile 中的指令自动匹配文件。

此外,从您的评论看来,java 文件的包名称是edu.osu.lispinterpreter.*.

所以我建议将 移动Makefilesrc目录并在 Makefile 中进行这些更改。

CLASSES := $(wildcard edu/osu/lispinterpreter/tokenizer/*.java)
CLASSES += $(wildcard edu/osu/lispinterpreter/core/*.java)
CLASSES += $(wildcard edu/osu/lispinterpreter/output/*.java)
CLASSES += $(wildcard edu/osu/lispinterpreter/exceptions/*.java)
CLASSES += edu/osu/lispinterpreter/input/InputParser.java
CLASSES += edu/osu/lispinterpreter/input/ReadInputString.java

只要包名与目录结构相对应,java 编译器应该能够从其他包中获取类的定义,而无需在Makefile.

于 2013-03-09T03:04:42.617 回答