【问题标题】:Java Makefile ErrorJava Makefile 错误
【发布时间】:2013-02-24 17:44:29
【问题描述】:

我在尝试使用我创建的 Makefile 编译我的 Java 项目时遇到此错误。

错误:

ma​​ke: 没有规则可以创建目标src/edu/osu/lispinterpreter/output/*.class', needed byclasses'。停止。*

Makefile 内容:

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。

【问题讨论】:

  • 文件夹src/edu/osu/lispinterpreter/output好像没有java文件吧?
  • 由于您使用的是 Eclipse,您应该能够自动生成一个 Ant “build.xml”。 Ant 在构建 Java 代码方面远远优于 Make。
  • 但我需要创建一个 Makefile,build.xml 不是一个选项.....@StephenC​​pan>
  • 所有文件都是@uba....谢谢你们!
  • @StephenC 公平地说,并非所有要求都是 (a) 技术或 (b) 合理的。

标签: java makefile package


【解决方案1】:

来自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 不匹配任何文件并保持原样,这不是预期的。使用wildcard function,可以避免这种情况。

解决办法是替换

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

通过

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

我认为其他所有行都以此类推

【讨论】:

    【解决方案2】:

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

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

    所以我建议将Makefile 移动到src 目录并在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 中写入任何显式依赖项。

    【讨论】:

    • 我试过了,但现在它抛出了这个错误:src/edu/osu/lispinterpreter/tokenizer/Tokenizer.java:4: package edu.osu.lispinterpreter.exceptions 不存在
    • 我应该把它们按特定顺序排列吗?
    • 您应该在 Makefile 中定义依赖关系,这就是 Makefile 的用途。 :)
    • 您可以在此行之后定义它:classes: $(CLASSES:.java=.class)。由于这本身就是另一个依赖规则,因此请确保添加一个新行。
    【解决方案3】:

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

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

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


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

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

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

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

    或者只使用 Ant。

    参考资料:

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 2022-01-04
      • 2013-03-10
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多