本文是邊看Gradle英文文檔邊作的筆記:Chapter 11. Composite builds
建議看的時候動手實驗一下,幫助理解java
簡單地說,Gradle的複合構建就是一個構建包含了其它構建。
Gradle的複合構建跟多項目構建很類似,
惟一的區別是多項目構建引入的是單個project(引入的java依賴可使用),
而複合構建引入的是一個完整的構建(除了引入的java依賴,引入的task也可使用)。web
能夠先看如下代碼示例,有個直觀的區分:微信
多項目構建:app
文件:my-app/build.gradle: dependencies { compile project(':util') compile project(':web') } //這裏假設有一個my-app的構建,my-app構建依賴了util工程和web工程。
複合構建:ide
文件:my-app/build.gradle: dependencies { compile "org.sample:util:1.0" compile "org.sample:web:1.0" } //my-app構建沒有直接依賴util和web。而是聲明瞭對util和web的構建結果(class文件)的依賴
多項目構建和複合構建很是類似,所以比較難區分,我是從兩種構建方式關注點上區分的。函數
複合構建適用的場景:微信支付
被複合構建(my-app)引用的構建(util、web),只會向複合構建提供構建的結果,而配置信息是不會被導入到複合構建中的。gradle
若是被複合構建(my-app)包含的構建(util、web)中有依賴能夠知足複合構建的依賴,會優先採用(util、web)該依賴。ui
Gradle默認會自行決定是否採用引入構建的依賴,可是官方建議最好顯式聲明(11.4, 「Declaring the dependencies substituted by an included build」)idea
複合構建(my-app)能夠直接聲明對包含的構建(util、web)的task的依賴,
可是被包含的構建(util、web)因爲它們是獨立的,
被包含的構建(util、web)不能依賴複合構建(my-app)中的task,
也不能依賴其它被包含的構建的task。
首先須要聲明覆合構建的依賴
下面的多個例子演示如何將2個獨立開發的構建組合到一個複合構建裏面。
在例子裏面,my-utils是一個多項目構建,包含了2個java庫的構建(number-utils和string-utils),
而my-app則是一個複合構建,my-app使用了這兩個java庫裏面的函數。
須要注意的是,my-app不是直接依賴my-utils,而是聲明對my-utils的兩個java庫的打包結果的依賴
聲明my-app的依賴項:
my-app/build.gradle
apply plugin: 'java' apply plugin: 'application' apply plugin: 'idea' group "org.sample" version "1.0" mainClassName = "org.sample.myapp.Main" dependencies { compile "org.sample:number-utils:1.0"//<--依賴number-utils子項目的產出結果 compile "org.sample:string-utils:1.0"//<--依賴string-utils子項目的產出結果 } repositories { jcenter() }
方式1:經過gradle命令行的--include-build選項實現複合構建
目錄結構是這樣的:
/samples/compositeBuilds/basic |--my-app |--build.gradle |--src/main/java |--my-utils |--number-utils |--src/main/java |--string-utils |--src/main/java |--build.gradle |--setting.gradle
在my-app目錄下運行命令行:gradle --include-build ../my-utils run
便可實現複合構建
這個命令行意思是:
經過gradle --include-build ../my-utils
命令告訴gradle先去執行my-utils的構建,my-utils如無心外會產出兩個java庫的構建,number-utils和string-utils目錄下會出現build目錄,build目錄就是構建的產出結果。
而後,因爲my-app/build.gradle中聲明瞭對number-utils和string-utils產出結果的依賴(就是下面的那部分代碼),因此my-app的構建也能成功執行。
dependencies { compile "org.sample:number-utils:1.0"//<--依賴number-utils子項目的產出結果 compile "org.sample:string-utils:1.0"//<--依賴string-utils子項目的產出結果 }
最後,對my-app執行run任務,即運行my-app的代碼。
方式2:在setting.gradle文件中使用includeBuild語句聲明覆合構建
實現以下:
my-app/build.gradle的配置依舊不變
...... dependencies { compile "org.sample:number-utils:1.0"//<--依賴number-utils子項目的產出結果 compile "org.sample:string-utils:1.0"//<--依賴string-utils子項目的產出結果 } ......
my-app/setting.gradle
rootProject.name = 'my-app' includeBuild '../my-utils'
方式2-補充:不修改my-app/setting.gradle文件實現複合構建
方式2中經過在my-app/setting.gradle文件中添加includeBuild '../my-utils'
配置來引入my-utils構建。
若是有特定場景要求不能修改my-app項目的任何文件該怎麼辦呢?這時能夠採起另外一種方式來實現,創建一個新的構建(即一個目錄),在新構建中引入my-app和my-utils,注意,原來是在my-app中引入my-utils的。
實現以下:
目錄結構是這樣的:
/samples/compositeBuilds/basic |--composite |--build.gradle |--setting.gradle |--my-app |--build.gradle |--src/main/java |--my-utils |--number-utils |--src/main/java |--string-utils |--src/main/java |--build.gradle |--setting.gradle
composite/setting.gradle:
//在composite構建中引入my-app構建和my-utils構建 rootProject.name='adhoc' includeBuild '../my-app' includeBuild '../my-utils'
因爲咱們新建了一個名爲composite的構建來包含my-app構建和my-utils構建,可是composite構建到目前爲止是沒有run
任務的(原來的my-app構建中定義了mainClassName = "org.sample.myapp.Main"
因此能執行run
任務),那該怎麼辦呢?
答案就是咱們在composite構建中定義一個的run
任務,把該run
任務的執行委派給my-app構建的run
任務:
composite/build.gradle:
apply plugin: 'idea' defaultTasks 'run' task run { //composite構建中定義一個run任務,委派給my-app的run任務 dependsOn gradle.includedBuild('my-app').task(':run') }
注意:一個構建須要知足什麼條件才能被複合構建引入?