2012-05-07 19 views
5

Mam wbudowany skrypt budujący w Ant, który ma makrodefinię, która pobiera kilka domyślnych parametrów, cel, root i tym podobne, a następnie opcjonalne dwa , extrasrc-f i extrasrc-c. Po ich wejściu lubię sprawdzać wszystkie odpowiednie zasoby, a następnie wykonać kompilację, jeśli cel jest nieaktualny.Tworzenie elementu typu Union i Macrodef z dynamiczną zawartością w czasie wykonywania w Ant

Co mam w tej chwili,

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

Ale jak widać, w tym momencie, dla mnie jest to nieskuteczne, aby robić to, co chcę, mam do tworzenia i przejść w co przynajmniej jeden zestaw plików i wiele ścieżek klas. Naprawdę chciałbym tylko przekazać listę katalogów, a następnie utworzyć elementy extrasrc-f i extrasrc-c w locie z tych informacji, ale dla mojego życia nie mam pojęcia, jak to zrobić ". jestem w stanie to zrobić.

Przeczytałem dużo o wielu funky klas Ant i Contrib, ale nie czytałem niczego, co pozwoliłoby mi zrobić coś takiego, co dziwię się, bo dla mnie wygląda oczywistą sytuację.

Czy podchodzę do tego w bardzo zły sposób, czy jest coś, czego mi brakuje? Jeśli naprawdę źle wykorzystuję Anta, chciałbym, aby wskazówki we właściwym kierunku uczyły to poprawnie, stworzyć catchall, szablon zbudowany w makrodeficie (lub celu, jeśli to jedyny sposób, aby to zrobić), który testuje wiele źródeł pliki przeciwko jednemu plikowi, który zostanie skompilowany, a także przekazuje dodatkowe ścieżki klas lub bibliotek, najlepiej na jednej liście.

Odpowiedz

0

Być może możesz użyć kilku zadań <scriptdef>, aby pomóc w rozbiciu tych makr.

Po pierwsze, jedna lista rozdzielonych przecinkami katalogów i generuje od nich <union>. Dostarczasz refid, którego chcesz użyć, aby odnieść się do związku jako atrybutu id. Dostępne są opcjonalne uwzględnienia i wykluczenia.

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

Druga - bardzo podobna - skrypt robi ekwiwalent dla pokolenia Ścieżka:

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

Przykładem stosowanie może wtedy coś takiego:

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

Następnie można zmodyfikować makra aby użyć atrybutu dirs i wygenerować wewnętrzną i klasową ścieżkę wewnętrznie lub wygenerować je raz jeszcze w innym miejscu i po prostu przekazać referencje.

Nie próbowałem zawierać katalogów @{root} na tej ilustracji, ale powinno być możliwe dostosowanie powyższego do tego.

+0

Przepraszam za powolną odpowiedź. –

+0

Haha, nie martw się, Martin, odpowiedź jest zawsze ceniona, nawet jeśli jest spóźniona. Ponieważ zadałem to pytanie, nie jestem już z tą samą firmą, ale wciąż gram w mrówki i nie miałem pojęcia o scriptdef, bardzo dziękuję za to! – seaders

Powiązane problemy