這篇文章整理我在寫 Apache Ant 建構腳本(build.xml)時最核心的三個元素:`project`、`target`、`property`。我會逐一說明每個元素有哪些屬性、怎麼用,並附上可以直接執行的 XML 範例與實際輸出結果,讓你快速看懂 Ant 腳本的運作方式。
Ant 建構腳本的根元素 project 是什麼?有哪些屬性?
`project` 元素是 Ant 構建檔的根項目,Ant 構建檔至少應該包含一個 `project` 元素,否則會發生錯誤。在每個 `project` 元素下,可包含多個 `target` 元素。它的屬性有三個:
| 屬性 | 用途 |
|---|---|
| `name` | 指定 project 元素的名稱 |
| `default` | 指定 project 預設執行時所要執行的 target 名稱 |
| `basedir` | 指定基準路徑的位置;未指定時,使用 Ant 構建檔的所在目錄作為基準目錄 |
舉例:
```xml
```
從上例可以看出,我在這裡定義了 `default` 屬性的值為 `getBaseDir`,也就是當執行 `ant` 命令時,如果沒有指明待執行的 target,就會執行預設的 target——`getBaseDir`。此外,我也定義了 `basedir` 屬性的值為 `C:/ThinkInJAVACode`,進入 `C:/ThinkInJAVACode` 後執行 `ant` 命令,會得到以下結果:
```text
Buildfile: C:\ThinkInJAVACode\build.xml
sayBaseDir:
[echo] The base dir is: C:\ThinkInJAVACode
BUILD SUCCESSFUL
Total time: 0 seconds
```
target 元素怎麼運作?depends、if、unless 屬性差在哪?
`target` 是 Ant 的基本執行單元,它可以包含一個或多個具體的任務,多個 target 之間可以存在相互依賴關係。它有如下屬性:
| 屬性 | 用途 |
|---|---|
| `name` | 指定 target 的名稱,這個名稱在同一個 project 中必須是唯一的。我們可以透過指定 target 名稱來執行某個 target |
| `depends` | 描述 target 之間的依賴關係;若依賴多個 target,以「,」間隔。Ant 會依照 depends 屬性中 target 出現的順序依次執行,被依賴的 target 會先執行 |
| `if` | 驗證指定的屬性是否存在;若存在,所在的 target 才會被執行 |
| `unless` | 功能與 `if` 相反:驗證指定的屬性是否存在;若不存在,所在的 target 才會被執行 |
| `description` | 關於 target 功能的簡短描述與說明 |
舉例說明:
```xml
a depend example!
```
從以下執行結果可以看到,我們執行的是名為 `targetB` 的 target。由於它依賴 `targetA`,所以 `targetA` 會首先被執行;同時因為系統配置了 JDK,`ant.java.version` 屬性存在,所以 `targetA` 被執行,輸出資訊 `[echo] JAVA Version: 1.6`。`targetA` 執行完畢後接著執行 `targetB`——因為 `philander` 屬性不存在,而 `unless` 屬性是在屬性不存在時才進入所在 target 的,由此可知 `targetB` 得以執行:
```text
Buildfile: C:\ThinkInJAVACode\build.xml
targetA:
[echo] JAVA Version: 1.6
targetB:
[echo] The base dir is: C:\ThinkInJAVACode
BUILD SUCCESSFUL
Total time: 0 seconds
```
property 元素怎麼定義參數?有哪些內置屬性可用?
`property` 元素可以看作參量或參數的定義。project 的屬性可以透過 `property` 元素來設定,也可以在 Ant 之外設定。若要在外部引入某個檔案,例如 `build.properties`,可以透過如下內容將其引入:
```xml
```
`property` 元素可用作 task 的屬性值:在 task 中把屬性名放在 `${` 和 `}` 之間,放在 task 屬性值的位置即可取值。
Ant 提供了一些內置屬性,其中能得到系統屬性的清單與 Java 文件中 `System.getProperties()` 方法得到的屬性一致,這些系統屬性可參考 Sun 網站的說明。同時,Ant 還提供了一些它自己的內置屬性:
- `basedir`:project 基目錄的絕對路徑
- `ant.file`:buildfile 的絕對路徑,上例中 `ant.file` 的值為 `C:\ThinkInJAVACode\build.xml`
- `ant.version`:Ant 的版本資訊,本文為 1.8.1
- `ant.project.name`:當前指定的 project 名字,即前文提到的 project 的 `name` 屬性值
- `ant.java.version`:Ant 檢測到的 JDK 版本,本文為 1.6
舉例說明:
```xml
```
上例中我設置了名為 `name` 和 `age` 的兩個屬性,這兩個屬性設置後,在下文中可以透過 `${name}` 和 `${age}` 分別取得這兩個屬性值。
延伸閱讀
- ant 腳本編寫 – 關鍵元素:同樣聚焦 Ant、Java,可接著比較不同情境的做法。
- Apache Ant 常用命令整理:copy、delete、mkdir、move、echo 用法範例:同樣聚焦 Ant、Java,可接著比較不同情境的做法。
- 利用 Ant 構建和部署 Java 專案:同樣聚焦 Ant、Java,可接著比較不同情境的做法。
常見問題
build.xml 中一定要有 project 元素嗎?
一定要有。`project` 是 Ant 構建檔的根元素,一個 build.xml 至少要包含一個 `project` 元素,否則 Ant 會直接報錯。所有 `target` 都必須定義在 `project` 底下。
target 的 depends 屬性可以依賴多個 target 嗎?
可以。多個依賴 target 之間用逗號「,」間隔,Ant 會依照 depends 屬性中 target 出現的順序依次執行,所有被依賴的 target 都會在目標 target 之前先執行完畢。
target 的 if 和 unless 屬性有什麼差別?
`if` 是「屬性存在才執行」,`unless` 則相反,是「屬性不存在才執行」。兩者都用來驗證指定屬性是否存在,藉此控制 target 是否執行,常用於依環境條件切換建構流程。
怎麼在 Ant task 中引用 property 的值?
把屬性名放在 `${` 和 `}` 之間,寫在 task 的屬性值位置即可,例如 `${name}`。property 可以用 `<property>` 元素直接定義,也可以透過 `<property file="build.properties"/>` 從外部檔案引入。
Ant 提供哪些常用的內置屬性?
常用的有 `basedir`(project 基目錄絕對路徑)、`ant.file`(buildfile 絕對路徑)、`ant.version`(Ant 版本)、`ant.project.name`(project 名稱)、`ant.java.version`(偵測到的 JDK 版本)。此外所有可由 `System.getProperties()` 取得的系統屬性也都可用。
參考資料
最後更新
2026-08-28(原文發布於 2013-07-25,本文保留原始筆記內容並補上 GEO 結構。)
關於作者 {#author}
Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。
首次發布:2013-07-25
