Apache Ant 是一種建置工具,在 Java 世界中擁有悠久的歷史,儘管團隊數量不斷減少,但仍廣泛使用。雖然靈活,但它缺乏慣例和 Gradle 提供的許多強大功能。移轉到 Gradle 是值得的,這樣您的建置可以變得更精簡、更簡單、更快速,同時仍然保留您在 Ant 中享有的靈活性。您還將受益於對多專案建置的強大支援以及易於使用且靈活的相依性管理。
從 Ant 移轉到 Gradle 的最大挑戰在於沒有標準的 Ant 建置。這使得難以提供具體的說明。幸運的是,Gradle 有一些與 Ant 很棒的整合功能,可以讓這個過程相對順利。從 Ivy 為基礎的相依性管理移轉並不困難,因為 Gradle 有類似的模型,基於 相依性設定,適用於相容於 Ivy 的儲存庫。
我們將從概述在從 Ant 移轉建置到 Gradle 時您應該考慮的事項開始,並提供一些關於如何進行的一般準則。
一般準則
當您從 Ant 移轉建置到 Gradle 時,您應該記住您已經擁有的性質以及您希望在哪裡結束。您是否想要一個反映現有 Ant 建置結構的 Gradle 建置?或者您想要轉移到更符合 Gradle 慣例的東西?您正在尋找的主要好處是什麼?
為了更了解,請考慮以下相反的場景
-
透過
ant.importBuild()
匯入的建置這種方法快速、簡單,而且適用於許多基於 Ant 的建置。最後會得到一個與原始 Ant 建置實際上相同的建置,只不過 Ant 目標會變成 Gradle 任務。目標之間的相依性也會保留。
缺點是您仍然使用 Ant 建置,而且必須持續維護。您也會失去 Gradle 約定的優點、許多外掛程式、相依性管理等等。您仍然可以使用 增量建置資訊 來增強建置,但這比一般 Gradle 建置需要更多功夫。
-
慣用的 Gradle 建置
如果您想讓建置具備未來性,這會是您的最終目標。利用 Gradle 的慣例和外掛程式,會產生一個較小、較容易維護的建置,其結構對許多 Java 開發人員來說都很熟悉。您也會發現更能利用 Gradle 的強大功能來改善建置效能。
主要的缺點是執行移轉所需的額外工作,特別是如果現有的建置很複雜,而且有許多專案間相依性時。不過,這些建置通常會從轉換成慣用的 Gradle 中受益最多。此外,Gradle 提供許多可以簡化移轉的功能,例如直接從 Gradle 建置中 使用核心和自訂 Ant 任務 的功能。
從長遠來看,您理想上希望最終接近第二個選項,但您不必一次到位。
以下是協助您決定要採取的方法以及如何進行的一系列步驟
-
並列保留舊的 Ant 建置和新的 Gradle 建置。
您知道 Ant 建置有效,因此您應該保留它,直到您確定 Gradle 建置產生所有相同的成品,而且執行您需要的所有其他工作。這也表示使用者可以嘗試 Gradle 建置,而不需要建立原始碼樹的新副本。
在準備好切換之前,不要嘗試變更建置的目錄和檔案結構。
-
開發一種機制來驗證兩個建置是否產生相同的成品。
這是確保您的部署和測試不會中斷的重要步驟。即使是像 JAR 中的清單檔案內容等小變更,都可能造成問題。如果您的 Gradle 建置產生與 Ant 建置相同的輸出,這會讓您和其他人在切換時更有信心,而且更容易實作將提供最大好處的大變更。
-
決定您是否有跨專案建置。
跨專案建置通常較難移轉,而且需要比單一專案建置更多的工作。我們在 移轉跨專案建置 部分中提供了一些專門建議,以協助您進行此程序。
-
找出要為每個專案使用的外掛程式。
我們預期絕大多數的 Ant 建置都是針對 基於 JVM 的專案,而這些專案有豐富的外掛程式可提供您所需的大量功能。Gradle 外掛程式包含 核心外掛程式,這些外掛程式會與 Gradle 一起封裝,以及 外掛程式入口網站 上有用的社群外掛程式。
即使 Java 外掛程式 或其衍生品(例如 Java 函式庫外掛程式)不適合您的建置,您至少應該考量 基本外掛程式 的生命週期任務。
-
匯入 Ant 建置或從頭建立 Gradle 建置。
此步驟在很大程度上取決於您的建置需求。如果 Gradle 外掛程式選取可以執行 Ant 建置的大部分工作,那麼建立不依賴 Ant 建置的新 Gradle 建置指令碼可能比較有意義。您可以自行實作遺失的部分,或 使用現有的 Ant 任務。
-
針對現有的目錄和檔案結構設定您的建置
Gradle 使用慣例來消除與舊建置相關的大量樣板程式碼,並讓使用者在熟悉這些慣例後,更容易處理新建置。但這並不表示您必須遵循這些慣例。
-
如果您願意,可以移轉到標準 Gradle 慣例
一旦您確信 Gradle 建置產生與 Ant 建置相同的成品和其他資源,您可以考慮移轉到標準慣例,例如來源目錄路徑。這樣做可以讓您移除覆寫這些慣例所需的額外設定。在變更後,新的團隊成員也會發現建置比較容易處理。
是否值得花費力氣和承擔潛在中斷的風險來執行此步驟,由您決定,而這取決於您的特定建置和團隊。
本章節的其餘部分涵蓋您在遷移期間可能會遇到的常見情況,例如相依性管理和使用 Ant 任務。
使用已匯入的建置
匯入 Ant 建置不受 組態快取 支援。您需要完成轉換至 Gradle,才能獲得快取的優點。 |
許多遷移的第一步會包含使用 ant.importBuild()
匯入 Ant 建置。那麼,您要如何朝向標準 Gradle 建置邁進,而不用一次取代所有內容?
要記住的重要事項是 Ant 目標會變成真正的 Gradle 任務,這表示您可以執行修改任務相依性、附加額外的任務動作等操作。這讓您可以用等效的 Ant 任務取代原生 Gradle 任務,並維護與其他現有任務的任何連結。
舉例來說,假設您有一個 Java 函式庫專案,您想要從 Ant 遷移至 Gradle。Gradle 建置指令碼有匯入 Ant 建置的行,現在想要使用標準 Gradle 機制來編譯 Java 原始檔。但是,您想要繼續使用現有的 package
任務,來建立函式庫的 JAR 檔。
在圖表形式中,情況看起來如下所示,其中每個方塊代表一個目標/任務

這個想法是將標準 Gradle compileJava
任務替換為 Ant build
任務。這個替換包含幾個步驟
-
套用 Java 函式庫外掛程式。
這會提供圖表中顯示的
compileJava
任務。 -
重新命名舊的
build
任務。名稱
build
與 基本外掛程式 (透過 Java 函式庫外掛程式) 所提供的標準build
任務衝突。 -
設定編譯,以使用現有的目錄結構。
Ant 建置很可能不符合標準 Gradle 目錄結構,因此您需要告訴 Gradle 在何處尋找原始檔,以及將編譯後的類別放置在何處,以便
package
可以找到它們。 -
更新任務相依性。
compileJava
必須相依於prepare
,package
必須相依於compileJava
,而不是ant_build
,而assemble
必須相依於package
,而不是標準 Gradlejar
任務。
套用外掛程式就像在 Gradle 建置指令碼的開頭插入 plugins {}
區塊一樣簡單,即在 ant.importBuild()
之前。以下是套用 Java 函式庫外掛程式的步驟
plugins {
`java-library`
}
plugins {
id 'java-library'
}
若要重新命名 build
工作,請使用 AntBuilder.importBuild() 的變體,它接受轉換器,如下所示
ant.importBuild("build.xml") { oldTargetName ->
if (oldTargetName == "build") "ant_build" else oldTargetName (1)
}
ant.importBuild('build.xml') { String oldTargetName ->
return oldTargetName == 'build' ? 'ant_build' : oldTargetName (1)
}
1 | 將 build 目標重新命名為 ant_build ,並保留所有其他目標不變 |
在 建立 Java 和 JVM 專案 中說明了設定來源的不同路徑。您可以以類似的方式變更已編譯類別的輸出目錄。
例如,如果原始 Ant 建置將這些路徑儲存在 Ant 屬性中;src.dir
適用於 Java 來源檔案,classes.dir
適用於輸出。以下是設定 Gradle 以使用這些路徑的方式
sourceSets {
main {
java.setSrcDirs(listOf(ant.properties["src.dir"]))
java.destinationDirectory = file(ant.properties["classes.dir"] ?: layout.buildDirectory.dir("classes"))
}
}
sourceSets {
main {
java {
srcDirs = [ ant.properties['src.dir'] ]
destinationDirectory = file(ant.properties['classes.dir'])
}
}
}
您最終應該切換到您專案類型的標準目錄結構,這樣您就能移除此自訂設定。
最後一步驟很簡單,涉及使用 Task.dependsOn 屬性和 Task.dependsOn() 方法來分離和連結工作。此屬性適用於取代相依性,而此方法是新增至現有相依性的首選方式。
以下是範例情境的必要工作相依性設定,它應該在 Ant 建置匯入後
tasks {
compileJava {
dependsOn("prepare") (1)
}
named("package") {
setDependsOn(listOf(compileJava)) (2)
}
assemble {
setDependsOn(listOf("package")) (3)
}
}
compileJava.dependsOn 'prepare' (1)
tasks.named('package') { dependsOn = [ 'compileJava' ] } (2)
assemble.dependsOn = [ 'package' ] (3)
1 | 使編譯相依於 prepare 工作 |
2 | 將 package 從 ant_build 工作分離,並使它相依於 compileJava |
3 | 將 assemble 從標準 Gradle jar 工作分離,並使它相依於 package |
這四個步驟將成功地用 Gradle 實作取代舊的 Ant 編譯。即使是這麼小的遷移,也能讓您享有 Gradle 的 增量 Java 編譯 優勢,以加快建置速度。
這是分階段遷移的一個範例。在此階段中,將資源處理(例如屬性檔案)和包裝與編譯納入其中可能更有意義。 |
您必須問自己的其中一個重要問題是,每個階段要遷移多少工作。一次遷移的數量越多越好,但風險會隨著受變更影響的 Ant 建置中的自訂步驟數量而增加。
例如,如果 Ant 建構遵循標準的編譯、靜態資源、封裝和單元測試方法,那麼將所有這些一起遷移可能是值得的。但如果建構對編譯的類別執行一些額外的處理,或在處理靜態資源時執行一些獨特的操作,那麼將這些任務拆分為獨立的階段可能是值得的。
管理相依性
Ant 建構通常採用兩種方法之一來處理二進位 相依性(例如函式庫)
-
將它們與專案儲存在本地的「lib」目錄中
-
使用 Apache Ivy 來管理它們
它們各自需要不同的技術來遷移到 Gradle,但無論哪種情況,你都會發現這個過程很簡單。讓我們在以下各節中詳細了解每個案例。
從目錄提供相依性
當你嘗試遷移將其相依性儲存在檔案系統(無論是本機還是網路)中的建構時,你應該考慮是否最終要使用遠端儲存庫移至受管理的相依性。這是因為你可以使用兩種方式之一將檔案系統相依性納入 Gradle 建構
如果你採用第一種方法,則較容易遷移到從 Maven 或與 Ivy 相容的儲存庫提供的受管理相依性,但這樣做需要你的所有檔案都符合命名慣例「<moduleName>-<version>.<extension>」。
如果你將相依性儲存在標準的 Maven 儲存庫配置中 — <repoDir>/<group>/<module>/<version> — 那麼你可以使用 file:// URL 定義 自訂 Maven 儲存庫。
|
為了展示這兩種技術,請考慮一個在 libs
目錄中有以下函式庫 JAR 的專案
libs ├── our-custom.jar ├── awesome-framework-2.0.jar └── utility-library-1.0.jar
檔案 our-custom.jar
沒有版本號,因此必須將其新增為檔案相依性。其他兩個 JAR 符合所需的命名慣例,並且可以宣告為從平面目錄儲存庫擷取的常態 模組相依性。
以下範例建構指令碼示範如何將所有這些函式庫納入建構中
repositories {
flatDir {
name = "libs dir"
dir(file("libs")) (1)
}
}
dependencies {
implementation(files("libs/our-custom.jar")) (2)
implementation(":awesome-framework:2.0") (3)
implementation(":utility-library:1.0") (3)
}
repositories {
flatDir {
name = 'libs dir'
dir file('libs') (1)
}
}
dependencies {
implementation files('libs/our-custom.jar') (2)
implementation ':awesome-framework:2.0' (3)
implementation ':utility-library:1.0' (3)
}
1 | 指定包含 JAR 檔案的目錄路徑 |
2 | 為未設定版本的 JAR 宣告檔案相依性 |
3 | 使用標準相依性座標宣告相依性 — 請注意,未指定群組,但每個識別碼都有開頭的 : ,表示空群組 |
上述範例會將 our-custom.jar
、awesome-framework-2.0.jar
和 utility-library-1.0.jar
新增至 implementation
組態,用於編譯專案的程式碼。
您也可以在這些模組相依性中指定群組,即使它們實際上沒有群組。這是因為平面目錄存放庫會忽略這些資訊。然後,如果您稍後新增正常的 Maven 或 Ivy 相容存放庫,Gradle 會從該存放庫下載宣告有群組的模組相依性,而不是平面目錄存放庫。 |
轉移 Ivy 相依性
Apache Ivy 是與 Ant 廣泛搭配使用的獨立相依性管理工具。它的運作方式類似 Gradle。事實上,它們都讓您可以
-
定義您自己的 組態
-
從彼此延伸組態
-
將相依性附加至組態
-
從 Ivy 相容存放庫解析相依性
-
將人工製品發佈至 Ivy 相容存放庫
最顯著的差異是,Gradle 有針對特定專案類型的標準組態。例如,Java 外掛程式定義了像 implementation
、testImplementation
和 runtimeOnly
等組態。如有需要,您可以定義您自己的相依性組態。
因此,從 Ivy 轉移至 Gradle 通常很簡單
-
將相依性宣告從您的模組描述檔轉錄至 Gradle 建置指令碼的 dependencies {} 區塊,理想情況下使用您套用的任何外掛程式所提供的標準組態。
-
將任何組態宣告從您的模組描述檔轉錄至建置指令碼的 configurations {} 區塊,針對任何無法由 Gradle 的標準組態取代的客製化組態。
-
將解析器從您的 Ivy 設定檔轉錄至建置指令碼的 repositories {} 區塊。
Ivy 提供多個 Ant 任務,用於處理 Ivy 取得相依性的程序。該程序的基本步驟包括
-
組態 — 套用 Ivy 設定檔中定義的組態
-
解析 — 找出宣告的相依性,並在必要時將它們下載至快取
-
擷取 — 將快取的相依性複製至另一個目錄
Gradle 的程序類似,但您不必明確呼叫前兩個步驟,因為它會自動執行這些步驟。第三個步驟根本不會發生 — 除非您建立一個任務來執行它 — 因為 Gradle 通常會直接在類別路徑中使用相依性快取中的檔案,並將它們作為組裝應用程式套件的來源。
讓我們更詳細地了解 Ivy 的步驟如何對應到 Gradle
- 組態
-
Gradle 大部分與相依性相關的組態都內建在建置指令碼中,正如您在
dependencies {}
區塊等元素中所見。另一個特別重要的組態元素是 resolutionStrategy,它可以從相依性組態中存取。這提供了許多您可能從 Ivy 的衝突管理員中獲得的功能,而且是控制傳遞相依性和快取的強大方式。有些 Ivy 組態選項在 Gradle 中沒有對應的選項。例如,沒有鎖定策略,因為 Gradle 保證其相依性快取是執行緒安全的。沒有「最新策略」方法,因為採用單一且可靠的衝突解決策略比較簡單。如果選取了「錯誤」版本,您可以使用強制版本或其他解決方案來覆寫它。
請參閱 控制傳遞相依性 章節以取得更多資訊。
- 解決
-
在建置開始時,Gradle 會自動解決您已宣告的任何相依性,並將它們下載到其快取中。Gradle 會在儲存庫中搜尋這些相依性,搜尋順序由 宣告儲存庫的順序 定義。
值得注意的是,Gradle 支援與 Ivy 相同的動態版本語法,因此您仍然可以使用
1.0.+
等慣例。您也可以使用特殊標籤latest.integration
和latest.release
。如果您決定使用這種 動態 和 變更 相依性,您可以透過 resolutionStrategy 來組態它們的快取行為。 - 擷取
-
如前所述,Gradle 不会自動從相依性快取中複製檔案。其標準任務通常會直接使用檔案。如果您要將相依性複製到本機目錄,您可以在建置指令碼中使用類似以下內容的 Copy 任務
範例 6. 將相依性複製到本機目錄build.gradle.ktstasks.register<Copy>("retrieveRuntimeDependencies") { into(layout.buildDirectory.dir("libs")) from(configurations.runtimeClasspath) }
build.gradletasks.register('retrieveRuntimeDependencies', Copy) { into layout.buildDirectory.dir('libs') from configurations.runtimeClasspath }
組態也是一個檔案集合,因此它可以在
from()
組態中使用。您可以使用類似的技術將組態附加到編譯任務或產生文件檔的任務。請參閱 使用檔案 章節以取得更多範例和有關 Gradle 檔案 API 的資訊。
發布成品
使用 Ivy 管理依賴項目的專案,通常也會使用它將 JAR 和其他成品發布到儲存庫。如果您要移轉此類建置,您會很樂意知道 Gradle 內建支援將成品發布到與 Ivy 相容的儲存庫。
在嘗試移轉建置的這個特定面向之前,請閱讀發布章節,以瞭解 Gradle 的發布模型。章節範例基於 Maven 儲存庫,但相同模型用於 Ivy 儲存庫。
基本的移轉流程如下
-
將Ivy 發布外掛程式套用到您的建置
-
設定至少一個發布,表示要發布的內容(包括其他成品,如果需要的話)
完成所有這些動作後,您將能夠為每個發布產生 Ivy 模組描述符,並將它們發布到一個或多個儲存庫。
假設您已定義一個名為「myLibrary」的發布,以及一個名為「myRepo」的儲存庫。Ivy 的 Ant 任務會像這樣對應到 Gradle 任務
-
<deliver>
→generateDescriptorFileForMyLibraryPublication
-
<publish>
→publishMyLibraryPublicationToMyRepoRepository
還有一個方便的 publish
任務,它會將所有發布發布到所有儲存庫。如果您要將發布限制到特定儲存庫,請查看發布章節的相关區段。
Ivy 在預設情況下,會在產生模組描述符時,自動用已解析的「靜態」版本取代依賴項的動態版本。Gradle 不會 模仿此行為,已宣告的依賴項版本保持不變。
您可以透過使用Nebula Ivy Resolved 外掛程式來複製 Ivy 的預設行為。或者,您可以自訂描述符檔案,以便它包含您想要的版本。
處理自訂 Ant 任務
Ant 的其中一個優點是,建立自訂任務並將其納入建置中相當容易。如果您有此類任務,則有兩個主要選項可將它們移轉到 Gradle 建置
第一個選項通常快速且簡單。如果您想將任務整合到增量建置中,您必須使用增量建置執行時期 API。您也常必須使用 Ant 路徑和檔案集,這可能會造成不便。
第二個選項從長遠來看較佳。Gradle 任務類型傾向於比 Ant 任務更簡單,因為它們不必使用基於 XML 的介面。您也可以獲得 Gradle 豐富 API 的好處。此方法啟用了基於類型化屬性的類型安全增量建置 API。
處理檔案
Ant 有許多用於處理檔案的任務,其中大多數都有 Gradle 等效項。與 Ant 到 Gradle 遷移的其他領域一樣,您可以在 Gradle 建置中使用那些 Ant 任務。但是,我們強烈建議在可能的情況下遷移到原生 Gradle 建構,以便建置受益於
-
更容易與建置的其他部分整合,例如相依性設定
-
更多慣用語法建置指令碼
使用沒有直接等效項的 Ant 任務可能會很方便,例如 <checksum>
和 <chown>
。但是,從長遠來看,最好將這些轉換為使用標準 Java API 或第三方程式庫的原生 Gradle 任務類型。
以下是 Ant 建置使用最常見的與檔案相關的元素,以及 Gradle 等效項
您可以在處理檔案章節中看到 Gradle 檔案 API 的幾個範例,並進一步了解它。
Ant 使用路徑狀結構和檔案集的概念,讓使用者可以處理檔案和目錄的集合。Gradle 有個更簡單、更強大的模型,基於 FileCollection 和 FileTree,可以當作建置中的物件處理。這兩種型態都允許根據 Ant 的 glob 語法進行篩選,例如 **/books_*
。您可以在 使用檔案 章節中進一步了解這些型態和 Gradle 檔案 API 的其他面向。
如果您需要與需要 Ant 路徑和檔案集的 Ant 工作互動,您可以透過 ant
物件在建置中建構 Ant 路徑和檔案集。〈Ant 整合〉章節中有使用 <path>
和 <fileset>
的範例。〈FileCollection〉上也有方法,可以將檔案集合轉換成檔案集或類似的 Ant 型態。
移轉 Ant 屬性
Ant 使用屬性映射儲存建置中可以重複使用的值。這種方法最大的缺點在於屬性值都是字串,而且屬性本身的行為就像全域變數。
有時您會想要直接從 Gradle 建置中使用 Ant 工作,而且該工作需要設定一個或多個 Ant 屬性。
如果是這樣,您可以透過 ant
物件輕鬆設定這些屬性,如〈從 Gradle 使用 Ant〉章節中所述。
Gradle 使用類似形式的 專案屬性,這是參數化建置的合理方式。這些屬性可以從命令列、〈gradle.properties
檔案〉,或透過特別命名的系統屬性和環境變數設定。
如果您有現有的 Ant 屬性檔案,可以將其內容複製到專案的 gradle.properties
檔案中。只要注意
-
在
gradle.properties
中設定的屬性不會覆寫建置指令碼中以相同名稱定義的 額外專案屬性 -
匯入的 Ant 任務不會自動「看到」Gradle 專案屬性,您必須將它們複製到 Ant 屬性對應中,才會發生這種情況
另一個要了解的重要因素是,Gradle 建置指令碼會使用物件導向 API,而且通常最好在可能的情況下使用任務、來源組和其他物件的屬性。例如,這個建置指令碼片段會建立任務,以將 Javadoc 文件包裝成 JAR 並解壓縮它,透過其屬性連結任務
val tmpDistDir = layout.buildDirectory.dir("dist")
tasks.register<Jar>("javadocJarArchive") {
from(tasks.javadoc) (1)
archiveClassifier = "javadoc"
}
tasks.register<Copy>("unpackJavadocs") {
from(zipTree(tasks.named<Jar>("javadocJarArchive").get().archiveFile)) (2)
into(tmpDistDir) (3)
}
def tmpDistDir = layout.buildDirectory.dir('dist')
tasks.register('javadocJarArchive', Jar) {
from javadoc (1)
archiveClassifier = 'javadoc'
}
tasks.register('unpackJavadocs', Copy) {
from zipTree(javadocJarArchive.archiveFile) (2)
into tmpDistDir (3)
}
1 | 封裝所有 javadoc 的輸出檔案,等同於 from javadoc.destinationDir |
2 | 使用 javadocJar 任務所保留的 Javadoc JAR 位置 |
3 | 使用稱為 tmpDistDir 的專案屬性來定義「dist」目錄的位置 |
從 tmpDistDir
的範例中可以看到,通常需要透過屬性定義路徑,因此 Gradle 也提供 額外屬性,可以附加到專案、任務和一些其他類型的物件。
移轉多專案建置
多專案建置是特別難以移轉的,因為 Ant 中沒有標準方法來建構它們或處理專案間的相依性。
幸運的是,Gradle 的多專案支援可以處理相當多樣化的專案結構,而且它提供比 Ant 更強大且有用的支援,用於建構和維護多專案建置。ant.importBuild()
方法也會透明地處理 <ant>
和 <antcall>
任務,這允許分階段移轉。
下列步驟重點說明建議的移轉多專案建置方法
-
首先學習 Gradle 如何設定多專案建置。
-
在建置的每個專案中建立 Gradle 建置指令碼,將其內容設定為這行
ant.importBuild 'build.xml'
ant.importBuild("build.xml")
將
build.xml
取代為對應到專案的實際 Ant 建置檔案路徑。如果沒有對應的 Ant 建置檔案,請將 Gradle 建置指令碼留空。即使您的建置不適合這種移轉方法,請繼續執行這些步驟,看看是否仍有辦法進行分階段移轉。 -
建立設定檔,包含所有現在有 Gradle 建置指令碼的專案。
-
實作專案間的相依性。
多專案建置中的一些專案會相依於該建置中一個或多個其他專案產生的成品。此類專案需要確保它們所相依的專案已產生其成品,而且已知道這些成品的路徑。
確保產生所需的成品通常表示透過
<ant>
任務呼叫其他專案的建置。不幸的是,這會繞過 Gradle 建置,否定您對 Gradle 建置指令碼所做的任何變更。您需要將使用<ant>
任務的目標替換為 Gradle 任務相依性。例如,您的網路專案仰賴屬於同一建置一部分的「util」函式庫。針對「web」的 Ant 建置檔案可能會有類似這樣的目標
web/build.xml<target name="buildRequiredProjects"> <ant dir="${root.dir}/util" target="build"/> (1) </target>
1 root.dir
必須由建置定義這可以用對應的 Gradle 建置指令碼中的專案間任務相依性取代,如下範例所示,假設「web」專案的「compile」任務需要事先建置「util」
web/build.gradle.ktsant.importBuild("build.xml") tasks { named<Task>("compile") { setDependsOn(listOf(":util:build")) } }
web/build.gradleant.importBuild 'build.xml' compile.dependsOn = [ ':util:build' ]
這不如 Gradle 的 專案相依性 強大或穩健,但它在不大幅變更建置的情況下解決了立即的問題。只要小心移除或覆寫對委派給其他子專案的任務的任何相依性,例如
buildRequiredProjects
任務。 -
找出沒有相依於其他專案的專案,並將它們轉移到慣用的 Gradle 建置指令碼。
遵循本指南中其餘部分的建議,轉移個別專案建置。如前所述,您應盡可能使用 Gradle 標準外掛程式。這表示您可能需要將額外的複製任務新增到每個建置,以將產生的成品複製到 Ant 建置的其餘部分預期的位置。
-
在專案僅相依於已完全轉移到 Gradle 建置的專案時,轉移專案。
此時,您應該能夠切換為使用附加到適當相依性組態的正確專案相依性。
-
一旦 Ant 建置的任何部分不再相依於專案,就清理專案。
我們在步驟 5 中提到您可能需要新增複製任務,以滿足相依 Ant 建置的需求。一旦這些建置轉移,就不再需要此類建置邏輯,應予以移除。
在流程結束時,您應該有一個 Gradle 建置,您確信它能如預期般運作,而且建置邏輯比之前少很多。
延伸讀物
本章節涵蓋了將 Ant 建置遷移至 Gradle 的主要主題。其餘的幾個領域可能有助於遷移
-
了解如何設定 Gradle 的建置環境,包括用於執行它的 JVM 設定
-
了解如何有效地建構建置
-
設定 Gradle 的記錄並從建置中使用它
最後,本指南僅介紹了 Gradle 的幾個功能,我們鼓勵您從使用者手冊的其他章節中了解其餘功能。