我正在使用javac编译器来编译项目中的java文件。这些文件分布在几个软件包上:com.vistas.util
,com.vistas.converter
,com.vistas.LineHelper
,com.current.mdcontect
。
每个包都有几个java文件。我正在使用这样的javac:
javac com/vistas/util/*.java com/vistas/converter/*.java
com.vistas.LineHelper/*.java com/current/mdcontect/*.java
(在一行)
而不是提供这么多路径,我怎么能要求编译器递归编译来自父com目录的所有java文件?
我还建议使用某种构建工具(Ant或Maven,已经建议使用Ant并且更容易开始)或者处理编译的IDE(Eclipse使用渐进式编译和协调策略,你甚至不需要小心按任何“编译”按钮)。
如果你需要为更大的项目尝试一些东西并且附近没有任何正确的构建工具,你总是可以使用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
文件,这是一个容易忘记(因此容易出错)和令人烦恼的任务。从长远来看,最好使用专为构建软件而设计的工具。
如果您创建一个简单的build.xml
文件,该文件描述了如何构建软件:
<project default="compile">
<target name="compile">
<mkdir dir="bin"/>
<javac srcdir="src" destdir="bin"/>
</target>
</project>
您可以通过运行以下命令来编译整个软件:
$ ant
Maven建立和合作并不是那么微不足道,但学习它会很有成效。这是start a project within 5 minutes的一个很棒的教程。
现在,这可以提高您的开发效率。有一些开源替代品(如Eclipse和NetBeans,我更喜欢前者)甚至是商业用途(如IntelliJ),它们非常受欢迎且功能强大。
他们可以在后台管理项目构建,因此您不必处理所有命令行内容。但是,如果您知道背景中实际发生的事情,那么它总是很方便,因此您可以像ClassNotFoundException
一样寻找偶然的错误。
对于较大的项目,始终建议使用IDE和构建工具。前者可以提高您的工作效率,而后者可以在项目中使用不同的IDE(例如,Maven可以使用简单的mvn eclipse:eclipse
命令生成Eclipse项目描述符)。此外,具有可以使用单行命令进行测试/构建的项目很容易引入新同事和持续集成服务器。小菜一碟 :-)
find . -name "*.java" -print | xargs javac
有点野蛮,但工作就像地狱。 (仅用于小程序,绝对没有效率)
如果你的shell支持它,这样的工作会起作用吗?
javac com/**/*.java
如果你的shell不支持**
,那么也许吧
javac com/*/*/*.java
工作(对于所有包含3个组件的包 - 适应或多或少)。
在通常情况下,您希望编译整个项目,您可以简单地为您的主类提供javac,并让它编译所有必需的依赖项:
javac -sourcepath . path/to/Main.java
我建议你学习使用ant,它非常适合这项任务,非常容易掌握和记录。
您只需要在build.xml文件中定义这样的目标:
<target name="compile">
<javac srcdir="your/source/directory"
destdir="your/output/directory"
classpath="xyz.jar" />
</target>
javac -cp "jar_path/*" $(find . -name '*.java')
(我不想使用xargs,因为它可以将它们拆分并多次运行javac,每个都有一个java文件的子集,其中一些可能导入在同一个javac命令行中未指定的其他文件)
如果你有一个App.java入口点,那么最好使用-sourcepath。它根据导入依赖性编译它需要的所有其他java文件。例如:
javac -cp "jar_path/*" -sourcepath src/ src/com/companyname/modulename/App.java
您还可以指定目标类文件目录:-d target/
。
我只是使用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 -classpath "${CLASSPATH}" @java_sources.txt
我一直在Xcode JNI项目中使用它来递归构建我的测试类:
find ${PROJECT_DIR} -name "*.java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}