java Makefile问题

时间:2012-02-15 07:29:38

标签: java file makefile javac

对于家庭作业,我必须为我编写的一系列.java文件制作一个makefile(物理和软件)。

我写了一个make文件:

JFLAGS = -d -g bin/
JC = javac

.SUFFXES: .java .class

CLASSES = \
    cdn\communications\CommandReader.java \
    cdn\communications\CommandReaderFactory.java \
    cdn\communications\CommandReaderThread.java \
    cdn\communications\DiscoveryCommandReader.java \
    cdn\communications\Link.java \
    cdn\communications\RefreshThread.java \
    cdn\communications\RouterCommandReader.java \
    cdn\node\Discovery.java \
    cdn\node\Node.java \
    cdn\node\Router.java \
    cdn\utility\Utility.java \
    cdn\wireformats\DeRegisterRequest.java \
    cdn\wireformats\DeRegisterResponse.java \
    cdn\wireformats\LinkInfo.java \
    cdn\wireformats\LinkWeightUpdate.java \
    cdn\wireformats\MessageType.java \
    cdn\wireformats\PeerRouterList.java \
    cdn\wireformats\RegisterRequest.java \
    cdn\wireformats\RegisterResponse.java \
    cdn\wireformats\RouterInfo.java \
    cdn\wireformats\WireFormatFactory.java \

all : $(CLASSES)

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

但是当我运行它时,我收到消息“make:没有什么可以为'all'做的。”并且没有我的文件。

这里有什么我想念的吗?我正在从包含“cdn”目录层次结构的目录运行该文件?

任何想法都会受到赞赏。

3 个答案:

答案 0 :(得分:2)

您尚未指定如何在Makefile中构建java类。基本上就像下面的东西......

.java.class:
        $(JC) $(JFLAGS) $*.java

请参阅this link,其中有一个很好的例子。

答案 1 :(得分:1)

修复你的all目标以依赖.class文件而不是.java文件(已经存在,因此“无需做任何事”)。

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

此外,您必须添加规则以将.java文件编译为.class文件:

%.class : %.java
    $(JC) $(JFLAGS) $<

如果使用上述规则(所谓的pattern rule),则不再需要.SUFFXES:,您可以将其删除。

答案 2 :(得分:0)

如上文其他人所述,您可以轻松地执行以下操作:

%.class : %.java
  javac flags_go_here

...但是这有一些问题:

  • 如果类之间存在任何依赖关系 - 并且会有 - 那么您必须得到正确的顺序。没有任何工具或命令行选项,例如GCC为您生成依赖项所提供的选项
  • Java允许类之间的循环依赖。除非您将它们一起编译,否则无法编译依赖于彼此的两个类,例如:
    • $ {JAVAC} $ {FLAGS} class1.java class2.java
  • javac启动时间很长。对于小型项目,您不会注意到它,但对于任何有足够类别的项目,它会快速加起来,并且您的构建时间会快速下降。

我提出的最佳解决方案如下(使用GNU-make样式语法):

all: my.jar

my.jar : c1.java c2.java ... cN.java
  ${JAVAC} ${JAVAC_FLAGS} ${^}
  ${JAR} cf ${JAR_FLAGS} ${@} -C src ${^:%.java=%.class}

# As a bonus, here's how you could do JNI stuff based on individual class files.
# This is necessary because nothing in the build actually depends directly on
# the .class files; if they don't exist and the .jar does, then you need some
# way to get the .class files without rebuilding the jar.

# It's written this way so it's re-usable.
# I'm using 'unzip' instead of 'jar' because it has the -j option so it won't
# dump some/irritating/path/to/work/with/when/all/I/need/is/the/.class/file
define CANNED_JAVAH_TARGET =
$(if $(filter %.java,${^}),,\
  $(error When building ${@}: No jar dependency provided))
unzip -j -d /somewhere/to/put/temp/class/file \
  $(filter %.jar,${^}) ${PKG_PATH}/${@F:%.h=%.class}
${JAVAH} ${JAVAH_FLAGS} <whatever flags are needed to make the header>
endef

${JNI_HEADER_TARGETS} : my.jar
  ${CANNED_JAVAH_TARGET}

javah部分存在问题:对于JAVAH事情,如果有人让它依赖于多个jar,它就会破坏。上面可能会有一些小的错误或事情需要解决(从内存开始),但总而言之,这对我来说没有太多麻烦。