用Ant構建指令碼(2)

chszs發表於2007-01-26
版權宣告:本文為博主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}”/>
</target>
通過“${}”標識引用變數。

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}”/>
  <echo message=”${user.name}”/>
 </target>
</project>

※※注意:
1、我們是在任何target外部宣告的property。<property>、<typedef>和<taskdef>任務是特殊的,它們能在任何target外部來宣告。當你這樣做時,在任何target被執行前它們先進行求值。除此之外,沒有任何其它的task能在target外部進行宣告。
2、我們還有一些target描述,這會產生專案幫助請求選項為任何target列出它們,其它的target是內部的並且不會被列出。
3、最後,為了這個target,在src子目錄下工作的原始檔應該被儲存在一個目錄樹下,用於匹配包名。檢查<javac>任務可獲得詳情。


相關文章