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有了基本的程式設計能力. 至於以上部分有看不明白的朋友,可以留言交流. 歡迎批評指正.