隨着信息化的快速發展,IT項目變得愈來愈複雜,一般都是由多個子系統共同協做完成。對於這種多系統、多項目的狀況,不少構建工具都已經提供 了不錯的支持,像maven、ant。Gradle除了借鑑了ant或者maven的繼承的方式定義子項目,也提供了一種更爲方便的集中配置的方式,大大 減小了構建帶來的複雜度。除此以外,Gradle還提供了清晰的Project樹模型來映射多項目的組織結構。下面,讓咱們瞭解一下如何使用Gradle 構建多項目。android
1. 多項目定義及結構ios
在Gradle中,使用文件settings.gradle定義當前項目的子項目,格式以下所示: web
include 'sub-project1', 'sub-project2', 'sub-project3',maven
它表示在當前的項目下創建三個子項目,分別爲'sub-project1', 'sub-project2', 'sub-project3'。默認狀況下,每一個子項目的名稱對應着當前操做系統目錄下的一個子目錄。ide
當Gradle運行時,會根據settings.gradle的配置狀況,構建一個單根節點的項目樹。其中的每一個子節點表明一個項目(Project),每一個項目都有一個惟一的路徑表示它在當前樹中的位置,路徑的定義方式相似:
工具
Root:<Level1-子節點>:<Level2-子節點>:<Level3-子節點>gradle
也能夠簡寫成「:<Level1-子節點>:<Level2-子節點>:<Level3-子節點>」。藉助這種路徑的定義方式,咱們能夠在build.gradle去訪問不一樣的子項目。另外,對於單項目,其實是一種特殊的、只存在根節點,沒有子節點的項目樹。
網站
例 如,咱們有個產品A,包括如下幾個組件core,web,mobile。分別表明"核心邏輯"、"網站"、「手機客戶端」。 由於每一個組件是獨立的部分,這個時候最好咱們能定義多個子項目,讓每一個子項目分別管理本身的構建。因而咱們能夠這樣定義 A/settings.gradle
ui
include 'core', 'web', 'mobile'spa
按照以前描述的,core組件對應A/core目錄,web組件對應A/web目錄,mobile組件對應A/mobile目錄。接下來,咱們就能夠在每一個組件內部,定義build.gradle負責管理當前組件的構建。
Gradle提供了一個內建的task 'gradle projects',能夠 幫助咱們查看當前項目所包含的子項目,下面讓咱們看看gradle projects的輸出結果:
$ gradle projects
:projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'A'
+--- Project ':core'
+--- Project ':mobile'
\--- Project ':web
結果一目瞭然,首先是Root級別的項目A,而後是A下面的子項目'core', 'mobile', 'mobile'
最終的文件以及目錄結構以下所示:
A
--settings.gradle
--build.gradle
--core
--build.gradle
--web
--build.gradle
--mobile
--build.gradle
若是你不喜歡這種默認的結構,也能夠按照以下方式定義子項目的名稱和物理目錄結構:
include(':core)
project(':core').projectDir = new File(settingsDir, 'core-xxx')
include(':web)
project(':web').projectDir = new File(settingsDir, 'web-xxx')
include(':mobile)
project(':mobile').projectDir = new File(settingsDir, 'mobile-xxx')
在這個例子中,子項目core實際上對應的物理目錄爲A/core-xxx,web實際上對應的是A/web-xxx,mobile也相似。
雖然咱們更改了子項目的物理目錄結構,不過因爲咱們在build.gradle中使用的是相似 「 :<SubProject>」的方式訪問對應的子項目,因此目錄結構的改變,對咱們Gradle的構建腳本並不會產生影響。
接下來,考慮一個更復雜的狀況,隨着產品的發展,mobile這個組件慢慢的劃分紅了Android和IOS兩個部分,這時咱們只須要在目錄A/mobile下定義新的settings.gradle,並加入以下部分:
include 'android', 'ios'
如今,mobile組件下將存在兩個新的子項目 "android"和"ios"
因而,這時候'gradle projects'的目錄結構就變成
A
--settings.gradle
--core
--build.gradle
--web
--build.gradle
--mobile
--settings.gradle
--ios
--build.gradle
--android
--build.gradle
2. 多項目的集中配置
對於大多數構建工具,對於子項目的配置,都是基於繼承的方式。Gradle除了提供繼承的方式來設置子項目,還提供了另一種集中的配置方式,方便咱們統一管理子項目的信息。下面看一個例子,打開A/build.gradle,輸入以下部分:
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I am the sub project of A"}
}
project(':core').hello << {
println "- I'm the core component and provide service for other parts."
}
對於上面所示的代碼,已經很表意了:
allprojects{xxx} 這段代碼表示,對於全部的project,Gradle都將定義一個名稱是hello的Task { println "I'm $task.project.name"} 。
subprojects{xxxx}的這段代碼表示,對於全部的子project,將在名稱爲hello的Task上追加Action {println "- I am the sub project of A"}
注意:關於Task和Action的關係,請看我以前寫的本系列的第一部分。
project(':core') 的這段代碼表示,對於名稱爲core的project,將在名稱爲hello的Task上追加Action { println "- I'm the core component and provide service for other parts." }
3. 多項目的Task執行
以前咱們已經瞭解了多項目的結構以及如何經過路徑去訪問子項目。如今讓咱們看看如何使用Gradle來執行多項目。
在 Gradle中,當在當前項目上執行gradle <Task>時,gradle會遍歷當前項目以及其全部的子項目,依次執行全部的同名Task,注意:子項目的遍歷順序並非按照 setting.gradle中的定義順序,而是按照子項目的首字母排列順序。
基於剛纔的例子,若是咱們在根目錄下,執行gradle hello,那麼全部子項目的「hello」 Task都會被執行。若是咱們在mobile目錄下執行gradle hello,那麼mobile、android以及IOS的「hello」 Task都會被執行。關於該例子的運行結果,這裏就不貼出來了。你們若是有興 趣的話能夠試試。
4. 總結這篇文章主要描述了使用Gradle管理多項目的知識。相比Ant或者Maven,Gradle提供了更靈活的配置方式。更重要的是,Gradle還提供了不少內建的Task幫助咱們查看或者管理項目。此次就先聊到這裏,下次咱們來看看Gradle的生命週期。