java 多个源文件夹:避免使用 Ant 进行隐式编译
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4627913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple source folders: Avoid implicit compilation with Ant
提问by Michael Piefel
Consider the following project layout (assuming A and B depend on each other):
考虑以下项目布局(假设 A 和 B 相互依赖):
.
|-- bin1
|-- bin2
|-- src1
| `-- A.java
`-- src2
`-- B.java
After compilation, I want the classes to reside in their respective folders liike this:
编译后,我希望类像这样驻留在各自的文件夹中:
.
|-- bin1
| `-- A.class
|-- bin2
| `-- B.class
|-- src1
| `-- A.java
`-- src2
`-- B.java
This is quite simple from the command line:
这在命令行中非常简单:
$ javac -implicit:none -sourcepath src1:src2 -d bin1 src1/*
$ javac -implicit:none -sourcepath src1:src2 -d bin2 src2/*
Eclipse also does it that way if so configured. But I cannot figure out how to do it with Ant.
如果这样配置,Eclipse 也会这样做。但我不知道如何用 Ant 做到这一点。
Appendix:My current javac
tasks:
附录:我目前的javac
任务:
<javac destdir="${classes.1.dir}">
<src path="${src.1.dir}" />
<src path="${src.2.dir}" />
</javac>
<javac destdir="${classes.2.dir}">
<classpath path="${classes.1.dir}" />
<src path="${src.2.dir}" />
</javac>
Note the circular dependency. The secondtask works well, it only compiles what's in src2
as it has a classpath
dependency on the other build. The firsttask, however, cannot take a classpath
, since nothing is yet compiled, and with src
it of course compiles too much.
注意循环依赖。在第二个任务的效果很好,它只是编译什么的src2
,因为它有一个classpath
在其他构建依赖。在第一个任务,但是,不能坐classpath
,因为没有什么是尚未编制,并与src
它当然编译的太多了。
采纳答案by Kurt Kaylor
This is extremely ugly and needs some cleaning, but it should do what your looking for
这非常丑陋,需要一些清洁,但它应该可以满足您的需求
<target name="compile" depends="clean,init" description="Compiles all source files.">
<mkdir dir="temp"/>
<javac srcdir="src1" sourcepath="src2" destdir="temp">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
<javac srcdir="src2" sourcepath="src1" destdir="temp">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
<javac srcdir="src1" destdir="bin1">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="temp"/>
</classpath>
</javac>
<javac srcdir="src2" destdir="bin2">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="temp"/>
</classpath>
</javac>
<delete dir="temp"/>
</target>
回答by Vitali Olshevski
I had the same problem. And i found some pretty easy solution.
我有同样的问题。我找到了一些非常简单的解决方案。
You just need to specify several source foulders in srcdir
attribute in javac
task. And you should not specify destdir
attribute.
您只需要在 task.properties 中的srcdir
属性中指定几个源文件夹javac
。你不应该指定destdir
属性。
Something like this:
像这样的东西:
<javac srcdir="src1:src2" />
All the binaries (.class files) will be placed in the same places as sources. So the structure of the class files will be exactly the same. Then you can move all *.class to the separate place, so they won't be stored in the source foulders.
所有二进制文件(.class 文件)都将放置在与源相同的位置。所以类文件的结构将完全相同。然后您可以将所有 *.class 移动到单独的位置,这样它们就不会存储在源文件夹中。
And no double compilation as in Kurt Kaylor's example.
并且没有像 Kurt Kaylor 的例子那样的双重编译。
回答by aphahn
Here is what works for me when dealing with complex source trees with no duplicate compilation. The key is how you build and reference the paths.
这是在处理没有重复编译的复杂源树时对我有用的方法。关键是您如何构建和引用路径。
<path id="src.separate.java.path">
<pathelement path="separate-src1/java" />
<pathelement path="separate-src2/java" />
</path>
<property name="src.separate.java.path" refid="src.separate.java.path" />
<path id="src.java.path">
<pathelement path="src1/java" />
<pathelement path="src2/java" />
<pathelement path="src3/java" />
</path>
<property name="src.java.path" refid="src.java.path" />
<path id="src.java.all.path">
<path refid="src.separate.java.path" />
<path refid="src.java.path" />
</path>
<property name="src.java.all.path" refid="src.java.all.path" />
<target name="compile-java">
<mkdir dir="${separate.classes.dir}" />
<javac srcdir="${src.separate.java.path}" sourcepath="${src.java.all.path}" destdir="${separate.classes.dir}">
<classpath refid="project.class.path" />
<compilerarg value="-implicit:none"/>
</javac>
<mkdir dir="${build.classes.dir}" />
<javac srcdir="${src.java.path}" sourcepath="${src.java.all.path}" destdir="${build.classes.dir}">
<classpath refid="project.class.path"/>
<compilerarg value="-implicit:none"/>
</javac>
</target>
In order for this to work the source paths need to be made up of <pathelement>
s. If you use <fileset>
s the srcdir
attribute for javac will choke on the path. You also need to expand the path into a property for srcdir
and sourcepath
to be able to use it.
为了使其工作,源路径需要由<pathelement>
s 组成。如果您使用<fileset>
s srcdir
,则 javac的属性将在路径上阻塞。您还需要将路径扩展为属性srcdir
并sourcepath
能够使用它。
So srcdir
is the path to the source to compile and sourcepath
is the path to all source the compiler needs to do resolve references. <compilerarg value="-implicit:none"/>
tells the compiler to not generate class files for implicitly loaded source.
所以srcdir
是路径源代码编译,并sourcepath
是通向所有的源编译器需要做的决心引用。<compilerarg value="-implicit:none"/>
告诉编译器不要为隐式加载的源生成类文件。
Of course you can do the same thing using nested <src>
elements in javac instead of the <path>
s and <property>
s, but that will force you to list your source paths twice.
当然,您可以使用<src>
javac 中的嵌套元素而不是<path>
s 和<property>
s来执行相同的操作,但这将迫使您将源路径列出两次。