2011-01-07 15 views
5

Considérese la siguiente distribución de proyectos (suponiendo que A y B dependen unos de otros):carpetas múltiple Fuente: Evitar la compilación implícita con Ant

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

Después de la compilación, que quieren las clases a residir en sus respectivas carpetas os guste este :

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

Esto es bastante sencillo desde la línea de comandos:

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

Eclipse también lo hace de esa manera si así se configura. Pero no puedo entender cómo hacerlo con Ant.

Apéndice: Mis actuales javac tareas:

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

Nota de la dependencia circular. La segunda tarea funciona bien, solo compila lo que está en src2 ya que tiene una dependencia classpath en la otra compilación. La primera tarea , sin embargo, no puede tomar un classpath, ya que aún no se ha compilado nada, y con src, por supuesto, compila demasiado.

Respuesta

2

Esto es extremadamente feo y necesita una limpieza, pero se debe hacer lo que tu buscas

<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

Puede combinar las dos primeras tareas 'javac'. Aparte de eso, esta solución parece ser lo más limpia posible. La compilación tiende a ser la parte más pequeña de mi ejecución Ant (las pruebas unitarias tardan mucho más), por lo que la compilación doble parece bastante aceptable. –

9

que tenía el mismo problema. Y encontré una solución bastante fácil.

Solo tiene que especificar varios elementos de inserción en el atributo srcdir en la tarea javac. Y no debe especificar el atributo destdir.

Algo como esto:

<javac srcdir="src1:src2" /> 

Todos los binarios (.class archivos) será colocado en los mismos lugares que las fuentes. Entonces la estructura de los archivos de clase será exactamente la misma. Luego puede mover todas las * .class a un lugar separado, para que no se almacenen en los lugares donde se cometieron las incrustaciones.

Y no hay compilación doble como en el ejemplo de Kurt Kaylor.

1

Esto es lo que funciona para mí cuando se trata de árboles fuente complejos sin compilación duplicada. La clave es cómo construir y hacer referencia a los caminos.

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

Para que esto funcione, las rutas de origen tienen que estar formado por <pathelement> s. Si usa <fileset> s, el atributo srcdir para javac se ahogará en la ruta. También necesita expandir la ruta a una propiedad para srcdir y sourcepath para poder usarla.

Así que srcdir es la ruta a la fuente para compilar y sourcepath es la ruta a todas las fuentes que el compilador necesita para resolver las referencias. <compilerarg value="-implicit:none"/> le dice al compilador que no genere archivos de clase para fuente cargada implícitamente.

por supuesto se puede hacer lo mismo utilizando anidados <src> elementos en javac en lugar de los <path> s y <property> s, pero que le obligará a la lista de sus rutas de origen dos veces.

Cuestiones relacionadas