2012-05-07 14 views
5

Tengo un script de compilación construido en Ant que tiene una macrodef que toma algunos parámetros predeterminados, destino, raíz y similares, y luego un dos opcional , extrasrc-f y extrasrc-c. Después de que han entrado, me gusta hacer un control actualizado de todos los recursos relevantes, y luego solo hacer una compilación si el objetivo está desactualizado.Crear un elemento estilo Unión y Macrodef con contenido dinámico en tiempo de ejecución en Ant

Lo que tengo en este momento,

<?xml version="1.0" encoding="UTF-8"?> 
<project name="Custom build" default="default"> 

    <taskdef resource="net/sf/antcontrib/antlib.xml" 
     classpath="C:/dev/ant/ant-contrib/ant-contrib-1.0b3.jar"/> 

    <macrodef name="checkuptodate"> 
     <attribute name="target" /> 
     <element name="resource" /> 
     <sequential> 
      <condition property="needbuild"> 
       <and> 
        <resourcecount when="greater" count="0"> <resource /> </resourcecount> 
        <not> 
         <uptodate targetfile="@{target}"> 
          <srcresources> <resource /> </srcresources> 
         </uptodate> 
        </not> 
       </and> 
      </condition> 
     </sequential> 
    </macrodef> 

    <macrodef name="projbuild"> 
     <attribute name="root" /> 
     <attribute name="target" /> 

     <element name="extrasrc-f" optional="true" /> 
     <element name="extrasrc-c" optional="true" /> 
     <sequential> 
      <local name="needbuild" /> 
      <checkuptodate target="@{root}/bin/@{target}"> 
       <resource> 
        <union> 
         <extrasrc-f /> 
         <fileset dir="@{root}/src" includes="**/*.java" /> 
        </union> 
       </resource> 
      </checkuptodate> 

      <if> 
       <istrue value="${needbuild}" /> 
       <then> 
        <javac 
         srcdir="@{root}/src" 
         destdir="@{root}/bin" 
         includeantruntime="false" 
        > 
         <extrasrc-c /> 
        </javac> 
       </then> 
      </if> 

     </sequential> 
    </macrodef> 

    <target name="default"> 

     <projbuild root="." target="EntryPoint.class"> 
      <extrasrc-f> 
       <fileset dir="Proj2/src" includes="**/*.java" /> 
       <fileset dir="Proj3/src" includes="**/*.java" /> 
      </extrasrc-f> 
      <extrasrc-c> 
       <classpath location="Proj2/src" /> 
       <classpath location="Proj3/src" /> 
      </extrasrc-c> 
     </projbuild> 

    </target> 

</project> 

Pero como se puede ver, en este punto en el tiempo, para mí es ineficiente, a hacer lo que quiero, no tengo para crear y transmitir en al al menos un conjunto de archivos y múltiples classpaths. Lo que realmente me gustaría hacer es simplemente pasar una lista de directorios, luego crear los elementos extrasrc-f y extrasrc-c sobre la marcha a partir de esa información, pero por mi vida, no tengo idea de cómo lo hice. Soy capaz de hacer eso.

He leído mucho sobre muchas de las clases funky Ant y Ant-Contrib, pero no he leído nada que me permita hacer algo como esto, lo que me parece extraño, porque para mí se ve una situación obvia.

¿Me estoy acercando a esto de una manera muy incorrecta, o hay algo que me falta? Si realmente estoy usando mal a Ant, me encantaría que los punteros en la dirección correcta sobre cómo hacer esto correctamente, crear un catchall, construir plantilla en un macrodef (o destino, si esa es la única manera de hacerlo) que prueba múltiples fuentes archivos contra un archivo que se genera, mientras que también se transfieren clases adicionales o rutas de biblioteca, preferiblemente en una sola lista.

Respuesta

0

Quizás pueda usar un par de tareas <scriptdef> para ayudar a descomponer esas macros.

Primero, uno que toma una lista de directorios separados por comas y genera el <union> de ellos. Proporciona el refid que desea utilizar para referirse a la unión como el atributo id. Hay inclusiones y exclusiones opcionales.

<scriptdef name="dirs2union" language="javascript"> 
    <attribute name="dirs" /> 
    <attribute name="id" /> 
    <attribute name="includes" /> 
    <attribute name="excludes" /> 
    <![CDATA[ 
     var dirs = attributes.get("dirs").split(","); 
     var includes = attributes.get("includes"); 
     var excludes = attributes.get("excludes"); 

     var union = project.createDataType("union"); 
     project.addReference(attributes.get("id"), union); 

     for (var i = 0; i < dirs.length; i++) { 
      var fs = project.createDataType("fileset"); 
      fs.setDir(new java.io.File(dirs[i])); 
      if (includes) 
       fs.setIncludes(includes); 
      if (excludes) 
       fs.setExcludes(excludes); 

      union.add(fs); 
     } 
    ]]> 
</scriptdef> 

El segundo - muy similar - script hace el equivalente de generación de rutas:

<scriptdef name="dirs2path" language="javascript"> 
    <attribute name="dirs" /> 
    <attribute name="id" /> 
    <![CDATA[ 
     var dirs = attributes.get("dirs").split(","); 

     var path = project.createDataType("path"); 
     project.addReference(attributes.get("id"), path); 

     for (var i = 0; i < dirs.length; i++) { 
      var pe = project.createDataType("path"); 
      pe.setLocation(new java.io.File(dirs[i])); 
      path.add(pe); 
     } 
    ]]> 
</scriptdef> 

Un ejemplo de uso podría ser entonces algo así como:

<property name="dirs" value="Proj2/src,Proj3/src" /> 

<dirs2union dirs="${dirs}" id="my.union" includes="**/*.java" /> 
<dirs2path dirs="${dirs}" id="my.path" /> 

... later (e.g.) ... 

<union refid="my.union" /> 
<classpath refid="my.path" /> 

A continuación, puede modificar las macros tomar el atributo dirs y generar la unión y classpath internamente, o quizás generar estos una vez en otro lugar y simplemente pasar las referencias.

No he intentado incluir los directorios @{root} en esta ilustración, pero debería ser posible adaptar lo anterior para eso.

+0

Disculpas por la, lenta respuesta. –

+0

Jaja, no se preocupe Martin, siempre se agradece una respuesta, aunque sea tarde. Desde que hice esta pregunta, ya no estoy con la misma compañía, pero sí juego con los guiones de Ant con regularidad, y no tenía ni idea de Scriptdef, ¡muchas gracias por eso! – seaders

Cuestiones relacionadas