2011-01-07 41 views
5

考虑以下项目布局隐式编译(假设A和B是互相依赖的):多个源文件夹:避免与蚂蚁

. 
|-- bin1 
|-- bin2 
|-- src1 
| `-- A.java 
`-- src2 
    `-- B.java 

编译之后,我想的类驻留在liike该各自的文件夹:

. 
|-- bin1 
| `-- A.class 
|-- bin2 
| `-- B.class 
|-- src1 
| `-- A.java 
`-- src2 
    `-- B.java 

这是通过命令行相当简单:

$ javac -implicit:none -sourcepath src1:src2 -d bin1 src1/* 
$ javac -implicit:none -sourcepath src1:src2 -d bin2 src2/* 

如果这样配置,Eclipse也是这样做的。但我无法弄清楚如何用Ant来做到这一点。

附录:我现在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> 

注意循环依赖。 第二个任务运行良好,它只编译src2中的内容,因为它对另一个内部版本具有classpath依赖关系。 第一个任务,但是,不能采取classpath,因为还没有编译,并且src它当然编译太多。

回答

2

这是非常丑陋的,需要一些清洁,但它应该做你要找的

<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> 
+0

您可以结合前两个`javac`任务。除此之外,这个解决方案似乎尽可能的干净。编译往往是我的Ant运行的最小部分(单元测试需要更长的时间),所以双编译看起来完全可以接受。 – 2011-01-10 08:02:04

9

我有同样的问题。我发现了一些非常简单的解决方案。

您只需在javac任务中的srcdir属性中指定多个源代码犯。而且您不应指定destdir属性。

事情是这样的:

<javac srcdir="src1:src2" /> 

所有二进制文件(.class文件)将被放置在同一个地方的来源。所以类文件的结构将完全相同。然后你可以将所有* .class移动到不同的地方,这样它们就不会被存储在源代码中。

并没有像Kurt Kaylor的例子那样进行双重编辑。

1

下面是处理复杂的源代码树时没有重复编译的问题。关键是你如何建立和参考路径。

<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> 

为了使其工作,源路径需要由<pathelement>组成。如果使用<fileset>,则javac的srcdir属性将在路径上窒息。您还需要将路径扩展为srcdirsourcepath以便能够使用它。

所以srcdir是编译源的路径,而sourcepath是编译器需要做的所有源的路径解析引用。 <compilerarg value="-implicit:none"/>指示编译器不为隐式加载的源生成类文件。

当然你也可以使用javac的替代<path> S和<property>小号嵌套<src>元素做同样的事情,但是这将迫使你列出两次你的源路径。