版權聲明:本文為部落客chszs的原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/chszs/article/details/1494372
用Ant建構腳本(2)
二、用Ant寫buildfile
Ant的buildfile是用xml寫的。每一個buildfile包含了一個項目和一個及一個以上的對象。對象包含了多個任務元素。buildfile的每一個任務元素能有一個id屬性,能在之後通過值來引用。這個值是唯一的。
build.xml檔案是區分大小寫的。其使用關鍵是編寫build.xml檔案,build.xml檔案有五個主要的辨別,如下:
1、Project元素
定義項目的屬性,該辨別有三個可以選擇的屬性:
Name項目的名稱;
Default預設執行的target對象;
Basedir用于計算所有其它路徑的基本路徑(“.”表示目前路徑)。該屬性可以被basedir property覆寫,當覆寫時,該屬性會被忽略。
示例:
<project name="examples" default="all" basedir=".">
2、Target元素
定義Ant指令的編譯對象。
如Ant converter的編譯對象是<target name="converter">
Target辨別的屬性解釋如下:
Name,定義target的名字,供Ant指令使用;
Depends,定義它所依賴的其它執行對象,多個時用“,”隔開,即依賴表;
If,條件執行,執行target所需要設定的屬性名,其property的值被設定後執行;
Unless,條件執行,執行target需要清除設定的屬性名;其property的值未被設定時執行;
Description,該target功能的簡單描述。
如:
<target name="converter" depends="init,compile,link,build">
Ant程式執行的先後順序是init, compile, link, build。
一個target可以依賴于其它的target。在定義時要注意它們的依賴關系和順序。如下:
<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
假定我們想執行目标D,從它的依賴屬性看,你可以認為第一個目标是C,然後是B,再是A。不對,C依賴于B,B又依賴于A,是以,首先執行A,接着B,再是C,最後是D。
一個target隻執行一次,即使有多個target依賴于它。
一個target還有完成它的執行的能力,除非對它單獨設定了一個屬性。這個屬性允許你更好的控制建立過程,它依靠系統的狀态,如:java版本,作業系統,指令行的屬性定義等。
※※注意:Ant隻檢查是否設定了property,而不管它們的值。即便你設定的property是空字元串,也表示property存在。如:
<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless=module-A-present"/>
在第一個例子中,如果設定了property的module-A-present值(任意值),target将被運作。
在第二個例子中,如果設定了property的module-A-present值(任意值),target則不能被執行。
3、Task元素
Tasks,定義要執行的指令的代碼,一個task可以有多個屬性或者參數,所有的task都有一個task名字屬性。attribute的值可以包含一個property的引用。在task被執行前這些引用都會被處理。target有如下的通用結構:
<name attribute1="value1" attribute2="value2".../>
name是target的名字,attributeN是attribute的名字,valueN是attribute的值。
所有的task共享一個task名attribute。attribute的值将被輸出的log消息中,在Ant執行時實作。
Ant有一套内置的task,以及一些可選的task,你也可以編寫自己的task。task能夠指定ID屬性,如下:
<taskname id="taskID".../>
taskname是task的名字,taskID是這個task唯一的識别符。通過它你能更好地在腳本中或其它task中引用該task。例如:
<script...>
task1.setFoo("bar");
</script>
為這個特殊的task執行個體設定foo的attribute。在另一個task中,你通過project.getReference("task1")可以通路這個執行個體。
再如:
<javac srcdir="ejb/account" destdir="build/ejb/account" classpath="c:/j2sdk1.5/lib/j2ee.jar"/>
相當于執行指令javac -d build/ejb/account -classpath c:/j2sdk1.5/lib/j2ee.jar。
※※注意一:如果task1還沒有運作,那麼它還沒有被配置;如果它在後面被配置,那麼你對執行個體做的任何操作都将重來。
※※注意二:Ant未來的版本不喜歡反向相容這個操作,因為這兒根本沒有任何task執行個體。
4、Properties
定義tasks指令可以使用的屬性,一個項目可以由一套property。property是固定不變的。無論誰設定了一個property,那麼它就是固定不變的了。Ant定義的原則是先定義的有效,也就是說相同的屬性,定義了多次,隻有第一次的值是有效的。
有五種方式來設定property:
(1)通過name和value的attribute來設定;
(2)通過name和refid的attribute來設定;
(3)通過檔案的attribute,如檔案名、檔案property來載入。這個property檔案有一定的格式,通過使用類java.util.Properties來定義;
(4)通過用使用的property檔案的resource名來設定resource的attribute。property檔案的格式通過使用類java.util.Properties來定義;
(5)通過用使用的字首來設定envirenment的attribute。通過字首提供的名字和變量名的期限,為每一個環境變量定義property。
盡管這些方式的組合是可能的,但最好一次使用一種設定方式。
其屬性參數如下:
name,設定的property名;
value,property的值;
location,路徑;
refid,其它地方定義的對象的引用;
resource,property檔案的源檔案名;
file,property檔案的檔案名;
environment,當重新載入環境變量時使用的字首;
classpath,要使用的源檔案的路徑;
classpathref,帶引用的要使用的源檔案的路徑;
prefix,字首。“.”表示目前的字首。
舉例:
<property name="buoo.dist" value="dest"/>
<property file="buoo.properties"/>
<property resource="buoo.properties"/>
<property file="${user.home}/.Ant-global.properties"/>
<property environment="env"/>
<echo message="Number of Processors=${env.NUMBER_OF_PROCESSORS}"/>
<echo message="Ant_HOME is set to =${env.Ant_HOME}"/>
一個property有一個名字和一個值,名字是大小寫敏感的。property可以被用在task的attribute中。用${}來代替。
例如:一個名為“builddir”的property,值為“build”,那麼它可以象這樣使用:${builddir}/classes。它在運作時被作為build/classes。
property此辨別在target辨別下使用,如:
<target name="init">
<property name="build" value="build"/>
</target>
使用properties辨別的代碼如下:
<target name="prepare" depends="init">
<mkdir dir="${build}"/>
通過“${}”辨別引用變量。
5、Built-in Properties
Ant提供了通路所有的系統property的方法,即build-in properties。似乎它們是用<property>定義的,例如,${os.name}擴充了作業系統名。
系統properties指的是可以檢視System.getProperties傳回的值,下面列出一些Java的系統屬性:
(1)java.version:Java運作環境的版本;
(2)java.home:Java的安裝目錄;
(3)java.class.path:Java的CLASSPATH值;
(4)java.io.tmpdir:預設的臨時路徑;
(5)os.name:作業系統的名字;
(6)file.separator:檔案分隔符(UNIX用“/”);
(7)path.separator:路徑分隔符(UNIX用“:”);
(8)user.name:登陸作業系統的使用者名;
(9)user.dir:使用者目前的工作目錄。
這些内建屬性(build-in properties)可以直接像property那樣引用。
除此之外,Ant還提供了自身的内建屬性(build-in properties)供使用。
(1)basedir:項目的basedir的絕對路徑,用<project>的basedir屬性來定義;
(2)ant.file:buildfile的絕對路徑;
(3)ant.version:Ant的版本;
(4)ant.project.name:目前執行的項目名;它通過<project>的name屬性來設定;
(5)ant.java.version:Ant檢測到的Java虛拟機的版本,目前它能有“1.1”,“1.2”,“1.3”,“1.4”等值。
如下所示:使用<echo>标簽将這些内置的特性值輸出。
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="run">
<target name="run">
<echo message="${java.class.path}"/>
<echo message="${java.io.tmpdir}"/>
<echo message="${user.name}"/>
<echo message="${os.name}"/>
<echo message="${basedir}"/>
<echo message="${ant.file}"/>
<echo message="${ant.version}"/>
<echo message="${ant.project.name}"/>
<echo message="${ant.java.version}"/>
</target>
</project>
※※注意:
1、我們是在任何target外部聲明的property。<property>、<typedef>和<taskdef>任務是特殊的,它們能在任何target外部來聲明。當你這樣做時,在任何target被執行前它們先進行求值。除此之外,沒有任何其它的task能在target外部進行聲明。
2、我們還有一些target描述,這會産生項目幫助請求選項為任何target列出它們,其它的target是内部的并且不會被列出。
3、最後,為了這個target,在src子目錄下工作的源檔案應該被存儲在一個目錄樹下,用于比對包名。檢查<javac>任務可獲得詳情。