Javac 选项递归地编译给定目录下的所有 java 文件

我在我的项目中使用 javac 编译器来编译 java 文件。这些文件分布在几个类似这样的包中: com.vistas.utilcom.vistas.convertercom.vistas.LineHelpercom.current.mdcontect

每个包都有几个 java 文件:

javac com/vistas/util/*.java com/vistas/converter/*.java
com.vistas.LineHelper/*.java com/current/mdcontect/*.java

(一行)

如何让编译器递归地编译来自父 com 目录的所有 java 文件,而不是给出这么多路径?

190952 次浏览

如果您的 shell 支持它,那么像这样的东西会起作用吗?

javac com/**/*.java

如果您的 shell 不支持 **,那么可能

javac com/*/*/*.java

工程(为所有包含3个组件-适应或多或少)。

我建议你学习使用 蚂蚁,这是非常非常适合这项任务,是非常容易掌握和良好的文档。

您只需在 build.xml 文件中定义这样的目标:

<target name="compile">
<javac srcdir="your/source/directory"
destdir="your/output/directory"
classpath="xyz.jar" />
</target>
find . -name "*.java" -print | xargs javac

有点残忍,但工作像地狱。(只使用在小程序,这是绝对没有效率)

我还建议使用某种构建工具(蚂蚁或者 玛文,已经建议使用 Ant,这样更容易开始) ,或者使用 IDE 来处理编译(Eclipse 使用增量编译和协调策略,你甚至不需要按任何 “编译”按钮)。

使用 Javac

如果您需要为一个更大的项目尝试一些东西,而且附近没有任何合适的构建工具,那么您总是可以使用 javac提供的一个小技巧: 可以在文件中指定要编译的类名。您只需将文件的名称传递给带有 @前缀的 javac

如果您可以创建项目中所有 *.java文件的列表,那么很简单:

# Linux / MacOS
$ find -name "*.java" > sources.txt
$ javac @sources.txt


:: Windows
> dir /s /B *.java > sources.txt
> javac @sources.txt
  • 的优点是它是一个快速而简单的解决方案。
  • 缺点 是,每次创建新源代码或重命名现有的一个文件时,都必须重新生成 sources.txt文件,这是一个容易忘记(因此容易出错)和令人厌烦的任务。

使用构建工具

从长远来看,最好使用设计用于构建软件的工具。

使用 Ant

如果你创建一个简单的 build.xml文件来描述如何构建软件:

<project default="compile">
<target name="compile">
<mkdir dir="bin"/>
<javac srcdir="src" destdir="bin"/>
</target>
</project>

你可以运行以下命令编译整个软件:

$ ant
  • 的优势在于,您使用的是易于扩展的标准构建工具。
  • 缺点是您必须下载、设置和学习其他工具。注意,大多数 IDE (如 NetBeans 和 Eclipse)都为编写构建文件提供了很好的支持,所以在这种情况下您不必下载任何东西。

利用玛文

Maven 的设置和使用并不是那么简单,但是学习它会带来很好的回报。这里有一个很棒的 在5分钟内开始一个项目教程。

  • 它的主要优点 (对我来说)是它也可以处理依赖关系,所以您不需要下载更多的 Jar 文件并手动管理它们,我发现它对于构建、打包和测试更大的项目更有用。
  • 缺点是它有一个陡峭的学习曲线,如果 Maven 插件喜欢抑制错误: ——另一件事情是,相当多的工具也使用 Maven 存储库(如用于 Scala 的 ,用于 Ant 的 艾薇,用于 Groovy 的 格拉德尔)。

使用 IDE

现在,什么可以提高您的开发生产力。有一些开源的替代品(如 日食NetBeans,我更喜欢前者) ,甚至是商业的替代品(如 情报) ,它们非常流行和强大。

他们可以在后台管理项目构建,这样您就不必处理所有的命令行内容。但是,如果您知道背景中的 真的发生了是什么,那么它总是很方便,这样您就可以查找像 ClassNotFoundException这样的偶然错误。

还有一点

对于较大的项目,建议使用 IDE 还有作为构建工具。前者提高了您的生产力,而后者使您可以在项目中使用不同的 IDE (例如,Maven 可以通过一个简单的 mvn eclipse:eclipse命令生成 Eclipse 项目描述符)。此外,拥有一个可以用单行命令测试/构建的项目很容易介绍给新同事,例如可以介绍给持续集成服务器。小菜一碟: -)

Javac 命令不遵循递归编译过程,因此在运行命令时必须指定每个目录,或者提供一个文本文件,其中包含希望包含的目录:

javac -classpath "${CLASSPATH}" @java_sources.txt

我一直在 Xcode JNI 项目中使用它来递归地构建我的测试类:

find ${PROJECT_DIR} -name "*.java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}

我只是使用 make 和一个简单的 makefile,它看起来像这样:

JAVAC = javac -Xlint:unchecked
sources = $(shell find . -type f -name '*.java')
classes = $(sources:.java=.class)


all : $(classes)


clean :
rm -f $(classes)


%.class : %.java
$(JAVAC) $<

它一次编译一个源代码,只在必要时重新编译。

在通常的情况下,如果你想编译整个项目,你可以简单地提供 javac 与你的主类,让它编译所有必需的依赖项:

javac -sourcepath . path/to/Main.java

javac -cp "jar_path/*" $(find . -name '*.java')

(我不喜欢使用 xargs,因为它可以将它们分开并多次运行 javac,每个都带有一个 java 文件子集,其中一些可能导入在同一 javac 命令行中未指定的其他文件)

如果您有一个 App.java 入口点,那么 freaker 的-source cepath 方法是最好的。它根据导入依赖关系编译它需要的所有其他 Java 文件。例如:

javac -cp "jar_path/*" -sourcepath src/ src/com/companyname/modulename/App.java

还可以指定目标类文件目录: -d target/

这个很酷: 我位于项目根目录。

find . -name *.java -exec javac {} -d ../out \;