Gradle
可以輕鬆處理各種大小規模的專案。小專案由一個單一的構建檔和一個源代碼樹構成。 大專案可以將其拆分成更小的,相互依賴的模組,以便更容易理解。Gradle完美支持這種多專案構建的場景。
多專案構建的結構
這種構建有各種形狀和大小,但它們都有一些共同的特點 -
- 在專案的根目錄或主目錄中都有一個
settings.gradle
檔。 - 根目錄或主目錄都有一個
build.gradle
檔。 - 具有自己的
*.gradle
構建檔的子目錄(某些多專案構建可能會省略子項目構建腳本)。
要列出構建檔中的所有專案,可以使用以下命令。
D:/water>gradle -q projects
如果命令執行成功,將獲得以下輸出。
D:/water>gradle -q projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'water'
+--- Project ':bluewhale'
/--- Project ':krill'
To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :bluewhale:tasks
報告將顯示每個專案的描述(如果指定)。可以使用以下命令指定描述。 將其粘貼到build.gradle
檔中。
description = 'The shared API for the application'
指定常規構建配置
在根專案中的build.gradle
檔中,常規配置可以應用於所有專案或僅應用於子項目。
allprojects {
group = 'com.example.gradle'
version = '0.1.0'
}
subprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
}
這指定了一個公共com.example.gradle
組和一個0.1.0
版本到所有專案。subprojects
閉合所有應用對子專案通用配置,但不對根專案應用,如:allprojects
閉合。
專案指定配置和依賴關係
核心ui
和util
子項目也可以有自己的build.gradle
檔,如果它們有特定的需求,那麼一般不會應用根專案配置。
例如,ui
專案通常具有對核心專案的依賴性。所以在ui
專案中需要有配置自己的build.gradle
檔來指定這個依賴。
dependencies {
compile project(':core')
compile 'log4j:log4j:1.2.17'
}
專案依賴項可使用專案方法指定。
Gradle多專案構建的示例
定義公共行為
讓我們看看下麵的一個例子的專案樹。這是一個多專案構建,其中包含一個名為water
的根專案和一個名稱為bluewham
的子項目。在這個示例中,我們把在創建一個目錄D:/water
,作為根專案的目錄。
多專案樹 - water
和bluewham
專案的構建佈局如下圖所示 -
water/
build.gradle
settings.gradle
bluewhale/
首先,創建一個檔 settings.gradle 並寫入以下代碼內容 -
include 'bluewhale'
bluewhale
專案的構建腳本在哪里? 在Gradle中構建腳本是可選的。顯然,對於單個專案構建,如果沒有構建腳本那麼專案是沒有意義的。但對於多專案構建情況不同。讓我們看看water
專案的構建腳本並執行它,創建一個檔build.gradle
並寫入以下代碼:
Closure cl = { task -> println "I'm $task.project.name" }
task hello << cl
project(':bluewhale') {
task hello << cl
}
並執行 gradle -q hello
輸出結果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
Gradle允許從構建腳本中訪問多專案構建的任何專案。 Project API提供了一個名稱為project()
的方法,它將一個路徑作為參數,並返回此路徑的Project
對象。
為每個專案顯式添加任務是不方便的。我們可以稍微做一下調整,先將另一個名稱為krill
的專案添加到多專案構建中。
現在目錄結構看起來如下所示 -
water/
build.gradle
settings.gradle
bluewhale/
krill/
再次編輯 settings.gradle
將以下代碼加入到檔中 -
include 'bluewhale', 'krill'
現在我們已經重寫 water
構建腳本並將其放在一行中。
將檔water
專案中的 build.gradle
並寫入以下代碼:
allprojects {
task hello << { task -> println "I'm $task.project.name" }
}
並執行 gradle -q hello
輸出結果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
I'm krill
這是如何工作的? Project API提供了一個屬性allprojects
,它返回當前專案及其下麵所有子項目的列表。 如果使用閉包調用allprojects
,則閉包的語句將委派給與所有專案相關聯的專案。當然也可以通過allprojects.each
進行迭代,但這將更冗長。
其他構建系統使用繼承作為定義公共行為的主要方法。Gradle也為專案提供繼承,您將在後面看到。但Gradle使用配置注入作為定義公共行為的常用方式。這是一種非常強大和靈活的配置多專案構建的方式。共用配置的另一種可能性是使用公共外部腳本。
子項目配置
Project API
還提供了一個僅用於訪問子項目的屬性。
定義公共行為
定義所有專案和子項目的公共行為,編輯 build.gradle
檔使用以下代碼 -
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I depend on water"}
}
並執行 gradle -q hello
輸出結果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
- I depend on water
I'm krill
- I depend on water
注意兩個代碼片段引用“hello
”任務。 第一個,它使用“task
”關鍵字,構建任務並提供它的基本配置。第二部分不使用“task
”關鍵字,因為它進一步配置現有的“hello
”任務。只能在專案中構建一次任務,但可以添加任意數量的代碼塊以提供其他配置。
添加指定行為
可以在常見行為之上添加指定的行為。要應用這個特定的行為,通常將專案特定的行為放在專案的構建腳本中。我們可以為 bluewhale
專案添加專案特定的行為,如下所示:
編輯 build.gradle
檔使用以下代碼 -
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I depend on water"}
}
project(':bluewhale').hello << {
println "- I'm the largest animal that has ever lived on this planet."
}
並執行 gradle -q hello
輸出結果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
- I depend on water
- I'm the largest animal that has ever lived on this planet.
I'm krill
- I depend on water
正如上面所說的,通常把專案特定的行為放入這個專案的構建腳本中。現在重構代碼並向krill
專案添加一些專案特定的行為。
定義 krill
專案的具體行為
構建佈局如下圖中所示 -
water/
build.gradle
settings.gradle
bluewhale/
build.gradle
krill/
build.gradle
settings.gradle
檔的內容 -
include 'bluewhale', 'krill'
bluewhale/build.gradle
檔的內容 -
hello.doLast {
println "- I'm the largest animal that has ever lived on this planet."
}
krill/build.gradle
檔的內容 -
hello.doLast {
println "- The weight of my species in summer is twice as heavy as all human beings."
}
build.gradle
檔的內容 -
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I depend on water"}
}
並執行 gradle -q hello
輸出結果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
- I depend on water
- I'm the largest animal that has ever lived on this planet.
I'm krill
- I depend on water
- The weight of my species in summer is twice as heavy as all human beings.
參考
- https://docs.gradle.org/current/userguide/multi_project_builds.html
- https://www.petrikainulainen.net/getting-started-with-gradle/