天天看點

用Ant建構腳本(2)

版權聲明:本文為部落客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>任務可獲得詳情。