本文為翻譯官方文檔而來,不當之處請指正。
Ant的建構檔案寫在xml檔案當中,每一個建構檔案包含一個project和至少一個(預設的)target。Targets包含task elements。每一個task element都有一個id屬性,可以提供給此值的引用。當然id屬性是唯一的。
Project
一個project有三個屬性
屬性 | 描述 | 必須的 |
---|---|---|
name | 項目名稱 | 否 |
default | 如果沒有任何target的話,需要這個預設的target | 否,自從螞蟻1.6.0,每個項目包括一個隐含的目标,包含所有的頂級任務和/或類型。這一目标将永遠作為項目的初始化部分執行,即使當螞蟻運作時有projecthelp選項。 |
basedir | 用于指定基路徑的位置。該屬性沒有指定時,使用 Ant 的構件檔案的父目錄作為基準目錄 | 否 |
<project name="XXX" default="xxxx" basedir=".">
…
</project>
Target
屬性 | 描述 | 必須的 |
---|---|---|
name | Target名 | 是 |
depends | 依賴 | 否 |
if | 某property必須設定了才可以運作這個target或者property擴充屬性評估是true | 否 |
unless | 某property必須沒有設定才可以運作這個target或者property擴充屬性評估是false | 否 |
description | Target功能的描述 | 否 |
extensionOf | 當這個target添加到extension-point的依賴清單中,1.8.0開始 | 否 |
onMissingExtensionPoint | 如果這個target視圖擴充丢失的extension-point該怎麼辦 | 否 |
命名name
可以是任何xml檔案中合法的string,例如空字元串””,逗号”,”和空格” ”,盡量避免用這些字元串命名你的target,ant将來的版本可能不會支援因為不同的IDE中對這些字串的解釋并不相同。
以連字元開始是不合法的,例如”-restart”,因為他們不能被指令行直接指令。因為ant會預設連字元開始的是它自己的而不是一個target。
依賴depends
一個target可以依賴其他的targets.例如,你有一個編譯的target,還有一個建立可配置設定的target,你隻能在你已經編譯的時候才能建構一個可配置設定的,因為這個可配置設定的target依賴編譯target。Ant可以解決這些依賴關系。
依賴隻影響順序,而不規定是否執行
需要注意的是,ant依賴屬性隻指定了執行targets的順序,如果依賴的目标不需要執行,則不影響指定依賴關系的目标是否執行,即雖然我隻能在你後面執行,如果你不執行,那麼我就直接執行。
<target name="clean">
…
</target>
<target name="init" depends="clean">
…
</target>
如果因為某些原因clean這個target不會執行,那麼init這個target依舊執行
基準的依賴最先執行
<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
D的時候,執行的順序是A --> B --> C --> D
為什麼呢?因為D依賴C,C又依賴B,B又依賴A,是以順序是這樣的。
<target name="A"/>
<target name="B"/>
<target name="C"/>
<target name="D" depends="C,B,A"/>
這樣寫的話,順序才是C,B,A,D
可以控制target是否執行-if / unless
<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless="module-A-present"/>
第一句話意思是如果module-A-present這個屬性被設定了,我就執行build-module-A這個target
第二句話的意思是如果module-A-present這個屬性沒有被設定,我就執行build-own-fake-module-A這個target
隻根據property是否存在控制,并不規定值
需要注意的是隻要設定了這個屬性就被控制,而沒有規定其中設定什麼值,例如
<property name=” module-A-present”/>
即使沒有設定什麼值,我也會運作第一個target,也就是build-module-A
如果想要根據值來控制,可以運用if/unless attributes 屬性擴充
1.7.1前不支援,即使這個property中沒有設定value或是空字串,1.8.0ant支援屬性擴充。即true,on,yes(相反值:false,off,no)可以讓他運作(不運作)
<target name="build-module-A" if="{module-A-present}"/>
隻可以有一個property
If/unless中隻可以有一個property
不影響他們一來的target是否運作
If/unless隻控制他們自己,其實他們的depends在他們之前都已經運作完畢了。
Extension-Pints
和target類似的是他們擁有一個name和依賴清單,可以從指令行直接執行,他們在建構過程中代表着一種狀态。
和target不同的是他們不包含任何tasks,他們主要的目的就是收集那些在他們的依賴清單中為所需狀态做出貢獻的targets 。
Targets可以通過extensionOf屬性把他們自己加到extension-points的依賴清單中,如果多個target寫在一起,相對位置沒有意義。
擴充點的主要用途是充當要導入
(Import詳見http://ant.apache.org/manual/Tasks/import.html)的建構檔案的擴充點。在導入的檔案中,擴充點定義必須到達的狀态,并且來自其他建構檔案的目标可以加入所述擴充點的依賴清單,以便對該狀态作出貢獻。
例如你要導入的建構檔案可能需要編碼:
<target name="create-directory-layout">
...
</target>
<extension-point name="ready-to-compile"
depends="create-directory-layout"/>
<target name="compile" depends="ready-to-compile">
...
</target>
create-directory-layout --> 'empty slot' --> compile
需要在編譯之前生成一些源代碼,然後在主建構檔案中使用類似于
<target name="generate-sources"
extensionOf="ready-to-compile">
...
</target>
create-directory-layout --> generate-sources --> compile
這樣可以確定generate-sources這個target在compile target之前執行。
不要使用依賴清單,如果使用了依賴清單,generate-sources這個target隻能通過它自己的依賴屬性顯示地依賴他們。
Task
一個task是一段可以執行的代碼。一個task可以有很多屬性attribute,屬性attribute的值可以包含property的引用。在task執行前,這些相關的property就可以被解決。Task的id屬性用來辨別這個task
如果“任務”還沒有運作,那麼它沒有配置(即,沒有屬性已設定),如果是要配置後,任何你所做的執行個體可以被改寫。
Ant有一系列内置的task(詳見:http://ant.apache.org/manual/tasklist.html),想寫自己的task也很容易(詳見:http://ant.apache.org/manual/develop.html#writingowntask)
Properties特性
屬性是自定義建構過程的一種重要方式,或者隻為在建構檔案中重複使用的字元串提供快捷方式。在最簡單的表單中,屬性在生成檔案中定義(例如,屬性任務),也可以在Ant之外設定。屬性有名稱和值;名稱區分大小寫。屬性可用于任務屬性值或支援它們的任務的嵌套文本中。這是通過将屬性名放在屬性值中的“”和“}”之間完成的。例如,如果有一個“builddir”屬性的值“建立”,那麼這可能是用于屬性是這樣的:”和“}”之間完成的。例如,如果有一個“builddir”屬性的值“建立”,那麼這可能是用于屬性是這樣的: { builddir } /classes。這在運作時作為buld/classes。
<property name="classes.dir" value="${webcontent.webinf.dir}/classes" description="原項目預設編譯位置"/>
<!--清理目标位置 -->
<target name="clean">
<delete dir="${classes.dir}" />
</target>
從ant1.8.0開始屬性擴充比簡單的鍵值對變得更加強大
許多task都可以設定properties,最常用的就是property 這個task,此外,屬性可以通過指令行參數或來自Ant外部的類似機制定義。
它隻表示字元串資料的名-值對。除了字元串以外,任何其他資料類型均不能與特性相關聯。
優先級
Ant指令行聲明的特性總是比其他位置定義的特性有更高的優先級。在此之後,ant會根據其何時首次發現所聲明的特性來确定優先級。
順序性
<property name=”property.one” value=”${property.two}:one”>
<property name=”property.two” value=”two”>
Property.one的值時什麼呢,由于順序,它的值是${property.two}:one而不是two:one
全局作用域
<target name=”target1”>
<property name=”prop2” value=”two”>
</target>
一旦建構了property prop2那麼剩餘的建構檔案部分都可以使用prop2特性。
内置特性
系統特性
Ant提供對所有系統屬性的通路,就像它們是使用< property >任務定義的一樣。例如,${os.name }作業系統的名稱。系統屬性詳見:https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getProperties%28%29
内置特性清單
basedir
作為的屬性,它表示該項目的絕對路徑
ant.file
建構檔案的絕對路徑
ant.version
Ant的版本
ant.project.name
目前運作的項目名稱,的屬性
ant.project.default-target
目前運作的項目預設target,的屬性
ant.project.invoked-targets
當調用目前的項目時,指令行或IDE指定的以逗号分隔的targets清單
當第一個目标被執行時,此屬性将被正确設定。
如果您在隐式目标中使用它(直接在“項目”标簽下)清單将為空。
如果沒有指定目标,将包含該項目的預設目标。
ant.java.version
JVM版本,目前它持有, “9”, “1.8”,”1.7”, “1.6”, “1.5”, “1.4”, “1.3” “1.2”.
ant.core.lib
ant.jar檔案的絕對路徑
還有另一個屬性,但這是由Launcher 的腳本,是以也許不在IDE:
ant.home
ant的home目錄
下面的屬性隻設定如果螞蟻開始通過發射類(這意味着它可能沒有設定在IDE的):
ant.library.dir
下載下傳的ant的jar包的目錄,大多數情況下是ANT_HOME/lib
路徑形式
類似路徑的結構
您可以指定路徑和路徑的類型引用使用“:”和“;”分隔符。Ant将将分隔符轉換為目前作業系統的正确字元。
Property特性定義允許我們避免在建構檔案中将目錄名寫死。這些路徑通常都是相對于
<project>
元素所指定的基目錄
<project name="XXX" default="xxxx" basedir=".">
<property name=”src.dir” value=”src”>
</project>
在需要指定路徑值的地方,可以使用嵌套元素。這是一般形式的:
<classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>
classpath屬性指定與項目的基目錄(或絕對檔案名)相關的單個檔案或目錄,而path屬性接受冒号或分号分隔的location清單。path屬性意在與預定義路徑一起使用——在任何其他情況下,都應該首選具有location屬性的多個元素
從1.8.2開始location屬性可以以通配結束為了java6 介紹的classpaths通配符使用。Java6以前的jvm使用時,ant将不會解釋這個通配符,即path不能正常工作(以通配符結束)。
作為一種快捷方式,
<classpath>
标簽支援path和自己的location屬性,是以:
<classpath>
<pathelement path="${classpath}"/>
</classpath>
可以被縮寫為:
<classpath path="${classpath}"/>
此外,一個或多個資源集合可以指定為嵌套元素(這些必須僅包含檔案類型資源)。此外,應該指出的是,雖然資源集合的順序處理遇到的,一定的資源的集合類型,如fileset,dirset和files方面的順序是不确定的。
<classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
<dirset dir="${build.dir}">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
</dirset>
<filelist refid="third-party_jars"/>
</classpath>
如果您想要為幾個任務使用相同的路徑結構,您可以在與目标相同的級别上使用一個元素來定義它們,并通過它們的id屬性引用它們.
<project ... >
<target ... >
<rmic ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</rmic>
</target>
<target ... >
<javac ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</javac>
</target>
</project>
可以這樣簡寫:
<project ... >
<path id="project.class.path">
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</path>
<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>
<target ... >
<javac ...>
<classpath refid="project.class.path"/>
</javac>
</target>
</project>
預設情況下,一個類似路徑的結構将在使用時重新評估所有嵌套的資源集合,這可能導緻對檔案系統進行不必要的重新掃描。因為螞蟻1.8.0路徑有一個可選的緩存屬性,如果設定為true,該路徑執行個體隻會掃描其嵌套資源集合一次,假設它不會改變在建立了(緩存預設仍然是錯誤的)。即使隻在單個任務中使用路徑,如果使用複雜的嵌套結構,則可以提高整體性能,将緩存設定為true。
一個類似路徑的結構可以通過嵌套的<路徑>元素包括對另一個路徑結構(路徑本身就是資源集合)的引用:
<path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>
<path id="tests.path" cache="true">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>
前面提到的<路徑>快捷方式也适用于<路徑>。例如:
<path id="base.path">
<pathelement path="${classpath}"/>
</path>
可以簡寫為:
<path id="base.path" path="${classpath}"/>
Path快捷方式
Ant1.6中path增加了一個快捷方式
${toString:pathreference}
<path id="lib.path.ref">
<fileset dir="lib" includes="*.jar"/>
</path>
<javac srcdir="src" destdir="classes">
<compilerarg arg="-Xbootclasspath/p:${toString:lib.path.ref}"/>
</javac>
datatype
一類表示複雜資料集合的元素,例如fileset和path
資料元素data element這個詞包含了特性property和datatype
比如:
<property file=”user.properties”>
可表示在目前目錄下找user.properties檔案
有的時候property來表示檔案路徑非常麻煩:
<property name=”classpath” value=”${lib.dir}/j2ee.jar:${lib.dir}/activation.jar:${lib.dir}/servlet.jar:${lib.dir}/jasper.jar”>
而且在這個庫中增加和删除jar都意味着你必須對此路徑字元串做相應的增加和删除
這個時候你使用datatype就是非常好的辦法:
<path id=”classpath”>
<fileset dir=”${lib.dir}”>
<include name=”j2ee.jar”/>
<include name=”activation.jar”/>
<include name=”servlet.jar”/>
…
</fileset>
</path>
當然jar都在同一個目錄下,使用通配符指定一個模式(而property卻不可以指定模式)
<path id=”classpath”>
<fileset dir=”${lib.dir}”>
<include name=”**/*.jar”/>
</fileset>
</path>
類型
Fileset隻是可用DataType中的一種,以下列出其他可用的DataType:
argument
對于由一個ant建構檔案調用的程式,向其傳遞指令行參數
environment
對于由一個ant建構檔案調用的外部指令或程式,指定向其傳遞的環境變量
filelist
定義一個檔案的命名清單,這些檔案無需确實存在
fileset
定義一個檔案的命名清單,這些檔案必須确實存在
patternset
将一組模式分組在一起
filterset
将一組過濾分組在一起
path
以某種在不同作業系統間可移植的方式指定路徑
mapper
定義一組輸入檔案和一組輸出檔案間的複雜關系。
簡易指令行參考
文法:ant [option [option…]] [target[target…]]
ant -help可查出所有指令行指令
我們從包括build.xml檔案的目錄鍵入以下指令:
ant
Ant将打開一個預設的建構檔案,即build.xml并執行此建構檔案的預設目标(即project的default屬性)(如果預設目标有依賴目标就會先去執行依賴目标再執行預設目标;如果預設目标不存在會傳回一個錯誤)
指定建構檔案名
ant -buildfile proj.xml
執行指定的target
ant -buildfile proj.xml clean
關于這個工程的建構詳情
ant -projecthelp
Buildfile:build.xml
Default target:
Compile Compiles all sources code
Main targets:
All cleans,compiles,then builds the jar file
Clean removes all generated files
Compile compiles all source codes
Substargets:
Prepare
BUILD SUCCESSFUL
Total time:2 seconds
這個工程的幫助詳情,其中targets被分為主目标和子目标,是根據有無描述descrption來區分的,但是執行的時候并無差別。在此隻是為了顯示。
All cleans,compiles,then builds the jar file
右側的為all這個target的descrption屬性
原文出處:
cc-lady, Ant筆記(二)Ant使用, https://blog.csdn.net/cc907566076/article/details/78604487