1. 程式人生 > >ant-contrib 包擴充套件功能之

ant-contrib 包擴充套件功能之

   最近接手一個C/C++專案, 編譯環境早就有了, 是使用bat來寫的.其編譯器又選擇了arm編譯器.在看整合指令碼的時候,感覺bat指令碼晦澀難懂,需認真揣摩才可以明白其編譯流程.

   大體流程如下: 一個大的專案下面又分成了N個小專案,每個小專案對應一個整合bat指令碼,然後在bat裡面呼叫arm編譯器,根據不同的條件對不同的原始碼進行編譯,如編譯引數設定等,其中最讓xiaoxiang惱火的是編譯的原始碼必須要一個一個的寫明在bat的arm編譯引數裡面.

   於是xiaoxiang想到了ant的條件編譯和for迴圈, 並嘗試研究了一下.

現總結如下,一者方便後來者,二者方便自己備查.

此處為build.properties中的內容,其中內容可根據不同環境進行不同的引數值修改,xiaoxiang的想法是通過java應用介面來實現不同值的填寫,並生成build.properties內容.

build.properties

compiled.codes = test.c,test1.c,test2.c,test3.c

compile.codes.fb = fb.c,fb1.c,fb2.c,fb3.c

compile.arg = true

switch.value = true

需要下載ant的擴充套件包ant-contrib.jar

ant <for>

<project name="compile-codes" default="main">

 <property file="./build.properties"/>

//使用taskdef定製ant-contrib任務

 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>

   <target name="init">

     <delete dir="../workspace"/>

     <mkdir dir="../workspace"/>

   </target>

   <target name="compile">

     <for list="${compile.codes}" param="cfile"> // cfile等價於java程式中的引數.

     <sequential> //執行for的迴圈體, 若有多個迴圈體,需要寫多個<sequential>

         <exec executable="cmd"> //呼叫cmd視窗

           <arg value="/c"/>

           <arg value="armcc"/> //啟動armcc

           <arg value="-c"/>

           <arg value="@{cfile}"/> //上面的cfile引數,通過此處的@{cfile}格式來取值

         </exec>         

     </sequential>

     </for>

   </target>

   <target name="main" depends="init,compile">

   </target>

</project>

ant <if> <elseif>

<project name="compile-codes-if" default="main">

 <property file="./build.properties"/>

//使用taskdef定製ant-contrib任務

 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>

   <target name="init">

     <delete dir="../workspace"/>

     <mkdir dir="../workspace"/>

   </target>

   <target name="condition">

     <if>

//條件判斷,判斷arg1 與 arg2兩者的值是否相符, 其中arg2為從build.properties中取出的值

       <equals arg1="true" arg2="${compile.arg}" />

     <then>

//若符合判斷條件,即條件成功,使用antcall命令來執行某個target

       <antcall target="compile.codes.main"/>

     </then>

     <elseif>

       <equals arg1="${compile.arg}" arg2="false" />

     <then>

       <antcall target="compile.codes.fb"/>

     </then>

     </elseif>

     <else>

//若所判斷條件沒有成功,則輸出提示資訊.

       <echo message="The value of the compile.arg can not be matched." />

     </else>

     </if>

   </target>

   <target name="compile.codes.main">

     <for list="${compile.codes.main}" param="mainfile">

     <sequential>

         <exec executable="cmd">

           <arg value="/c"/>

           <arg value="armcc"/>

           <arg value="-c"/>

           <arg value="@{mainfile}"/>

         </exec>       

     </sequential>

     </for>

   </target>

   <target name="compile.codes.fb">

     <for list="${compile.codes.fb}" param="fbfile">

     <sequential>

         <exec executable="cmd">

           <arg value="/c"/>

           <arg value="armcc"/>

           <arg value="-c"/>

           <arg value="@{fbfile}"/>

         </exec>         

     </sequential>

     </for>

   </target>

   <target name="main" depends="init,condition">

   </target>

</project>

這個ant-if條件判斷主要依據是build.properties中compile.arg的值的設定.然後根據判斷出的不同的條件去執行不同的<for>迴圈體. 兩個<for>迴圈體就不做過多的介紹了,可以參看ant-for的內容.

ant-switch

<project name="switch-test" default="switch">
 <property file="./build.properties"/>


 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
 <target name="switch">
  <switch value="${switch.value}">
    <case value="true">
      <ant dir="." target="main"/>
    </case>
    <case value="false">
      <ant dir="." target="main"/>
    </case>
    <default>
      <echo message="Please check the value of the switch.value, it can not match to anything." />
    </default>
  </switch>
 </target>
</project>

 相信學過java或者C的朋友,一看這個<switch>便知其實現的功能和<if>是差不多的,主要也是用於條件判斷, 哪個符合便去執行哪個迴圈體. 不做過多的說明了, 若覺得<switch>不好用,建議使用<if><elseif>.

<if><elseif>通過合理的排版,加之以適當的條件判斷值(可以在build.properties中寫多個值用於判斷), 相信<if><elseif>功能可以滿足大部分xiaoxiang的需求.

稍做說明: ant提供了,<for> <if> <elseif> <switch>等擴充套件功能, 這樣也就使得ant有了基本的程式設計能力. 至於以上部分有看不明白的朋友,可以留言交流. 歡迎批評指正.