Gradle入門系列(5):創(chuàng)建多項(xiàng)目構(gòu)建

轉(zhuǎn)載:
本文由 伯樂(lè)在線 - JustinWu 翻譯,黃利民 校稿嬉橙。未經(jīng)許可,禁止轉(zhuǎn)載寥假!
英文出處:petrikainulainen市框。歡迎加入翻譯組

盡管我們可以僅使用單個(gè)組件來(lái)創(chuàng)建可工作的應(yīng)用程序糕韧,但有時(shí)候更廣泛的做法是將應(yīng)用程序劃分為多個(gè)更小的模塊枫振。

由于這是一個(gè)非常普通的案例喻圃,因此每個(gè)成熟的構(gòu)建工具都必須支持這項(xiàng)功能,Gradle也不例外粪滤。倘若Gradle項(xiàng)目擁有多于一個(gè)組件斧拍,我們就將其稱之為多項(xiàng)目構(gòu)建(multi-project build)。

這篇教程描述了如何使用Gradle創(chuàng)建一個(gè)多項(xiàng)目構(gòu)建杖小。

我們先來(lái)看一看Gradle構(gòu)建的一些需求肆汹。
擴(kuò)展閱讀:如果你對(duì)Gradle不太熟悉,在閱讀這篇教程前你應(yīng)該先閱讀以下文章予权。

Gradle Build 的需求

我們的示例程序擁有兩個(gè)模塊:

core模塊包含一些通用的組件攒至,它們能夠被程序的其他模塊使用。在我們的例子上躁劣,只包含一個(gè)類:MessageService類返回‘Hello World!’字符串迫吐。該模塊只有一個(gè)依賴:它包含一個(gè)單元測(cè)試,使用Junit 4.11账忘。

app模塊包含HelloWorld類渠抹,是程序的開端,它從MessageService對(duì)象中獲取信息闪萄,并將接收到的信息寫入一個(gè)日志文件中梧却。該模塊擁有兩個(gè)依賴:它需要core模塊,還使用Log4j 1.2.17作為日志庫(kù)败去。

我們的Gradle構(gòu)建還有其他兩個(gè)需求:

  • 我們必須要使用Gradle運(yùn)行程序放航。
  • 我們必須要?jiǎng)?chuàng)建一個(gè)可運(yùn)行的二進(jìn)制發(fā)布,而且不能使用所謂的“fat jar”方式圆裕。

如果你還不清楚怎樣使用Gradle運(yùn)行程序广鳍,以及創(chuàng)建可運(yùn)行的二進(jìn)制發(fā)布,在閱讀這篇教程前吓妆,你應(yīng)該先閱讀以下文章赊时。
Gradle入門系列(4):創(chuàng)建二進(jìn)制發(fā)布版本

我們繼續(xù)來(lái)探討一下如何創(chuàng)建一個(gè)多項(xiàng)目構(gòu)建來(lái)滿足我們的需求。

創(chuàng)建一個(gè)多項(xiàng)目構(gòu)建

下一步行拢,我們將創(chuàng)建一個(gè)多項(xiàng)目的Gradle構(gòu)建祖秒,包括兩個(gè)子項(xiàng)目:app 和 core。初始階段,先要建立Gradle構(gòu)建的目錄結(jié)構(gòu)竭缝。

建立目錄結(jié)構(gòu)

由于core和app模塊都使用Java語(yǔ)言房维,而且它們都使用Java項(xiàng)目的默認(rèn)項(xiàng)目布局,我們根據(jù)以下步驟建立正確的目錄結(jié)構(gòu):

  1. 建立core模塊的根目錄(core)抬纸,并建立以下子目錄:
    • src/main/java目錄包含core模塊的源代碼咙俩。
    • src/test/java目錄包含core模塊的單元測(cè)試。
  2. 建立app模塊的根目錄(app)湿故,并建立以下子目錄:
    • src/main/java目錄包含app模塊的源代碼阿趁。
    • src/main/resources目錄包含app模塊的資源文件。

現(xiàn)在坛猪,我們已經(jīng)創(chuàng)建了所需的目錄脖阵,下一步是配置Gradle構(gòu)建,先對(duì)包含在多項(xiàng)目構(gòu)建中的項(xiàng)目進(jìn)行配置砚哆。

對(duì)包含在多項(xiàng)目構(gòu)建中的項(xiàng)目進(jìn)行配置

我們可以通過(guò)以下步驟,對(duì)包含在多項(xiàng)目構(gòu)建中的項(xiàng)目進(jìn)行配置:

  1. 在根項(xiàng)目的根目錄下創(chuàng)建settings.gradle文件屑墨,一個(gè)多項(xiàng)目Gradle構(gòu)建必須含有這個(gè)文件躁锁,因?yàn)樗该髁四切┌诙囗?xiàng)目構(gòu)建中的項(xiàng)目。
  2. 確保app和core項(xiàng)目包含在我們的多項(xiàng)目構(gòu)建中卵史。

我們的settings.gradle文件如下:

include 'app'
include 'core'

擴(kuò)展閱讀:

配置 core 項(xiàng)目

我們可以通過(guò)以下步驟對(duì)core項(xiàng)目進(jìn)行配置:

  1. 在core項(xiàng)目的根目錄下創(chuàng)建build.gradle文件战转。
  2. 使用Java插件創(chuàng)建一個(gè)Java項(xiàng)目。
  3. 確保core項(xiàng)目從Maven2中央倉(cāng)庫(kù)(central Maven2 repository)中獲取依賴以躯。
  4. 聲明JUnit依賴(版本4.11)槐秧,并使用testCompile配置項(xiàng),該配置項(xiàng)表明:core項(xiàng)目在它的單元測(cè)試被編譯前忧设,需要JUnit庫(kù)刁标。

core項(xiàng)目的build.gradle文件如下:

apply plugin: 'java';
 
repositories {
    mavenCentral()
}
 
dependencies {
    testCompile 'junit:junit:4.11';
}

擴(kuò)展閱讀:

我們繼續(xù)對(duì)app項(xiàng)目進(jìn)行配置。

配置App項(xiàng)目

在配置app項(xiàng)目之前址晕,我們先來(lái)快速瀏覽一下對(duì)一些特殊依賴的依賴管理膀懈,這些依賴都是同一個(gè)多項(xiàng)目構(gòu)建的一部分,我們將其稱之為”項(xiàng)目依賴“谨垃。

如果多項(xiàng)目構(gòu)建擁有項(xiàng)目A和B启搂,同時(shí),項(xiàng)目B的編譯需要項(xiàng)目A刘陶,我們可以通過(guò)在項(xiàng)目B的build.gradle文件中添加以下依賴聲明來(lái)進(jìn)行依賴配置胳赌。

dependencies {
    compile project(':A')
}

擴(kuò)展閱讀

現(xiàn)在,我們可以按照以下步驟配置app項(xiàng)目:

  1. 在app項(xiàng)目的根目錄下創(chuàng)建build.gradle文件匙隔。
  2. 用Java插件創(chuàng)建一個(gè)Java項(xiàng)目疑苫。
  3. 確保app項(xiàng)目從Maven2中央倉(cāng)庫(kù)(central Maven2 repository)中獲取依賴。
  4. 配置所需的依賴,app項(xiàng)目在編譯時(shí)需要兩個(gè)依賴:
    • Log4j (version 1.2.17)
    • 'core'模塊
  5. 創(chuàng)建二進(jìn)制發(fā)布版本

app項(xiàng)目的build.gradle文件如下:

apply plugin: 'application'
apply plugin: 'java'
 
repositories {
    mavenCentral()
}
 
dependencies {
    compile 'log4j:log4j:1.2.17'
    compile project(':core')
}
 
mainClassName = 'net.petrikainulainen.gradle.client.HelloWorld'
 
task copyLicense {
    outputs.file new File('$buildDir/LICENSE')
    doLast {
        copy {
            from 'LICENSE'
            into '$buildDir'
        }
    }
}
 
applicationDistribution.from(copyLicense) {
    into ""
}

我們繼續(xù)缀匕,下面是移除core和app項(xiàng)目的構(gòu)建腳本中的重復(fù)配置纳决。

移除重復(fù)配置

當(dāng)我們對(duì)多項(xiàng)目構(gòu)建中的子項(xiàng)目進(jìn)行配置時(shí),我們?cè)赾ore和app項(xiàng)目的構(gòu)建腳本中添加了重復(fù)的配置乡小。

  • 由于兩個(gè)項(xiàng)目都是Java項(xiàng)目阔加,因此它們都使用Java插件。
  • 兩個(gè)項(xiàng)目都使用Maven2中央倉(cāng)庫(kù)(central Maven2 repository)满钟。

換句話說(shuō)胜榔,兩個(gè)構(gòu)建腳本都包含以下配置:

apply plugin: 'java'
 
repositories {
    mavenCentral()
}

讓我們將這項(xiàng)配置轉(zhuǎn)移到根項(xiàng)目的build.gradle文件中,在此之前湃番,我們必須先學(xué)習(xí)一下如何在根項(xiàng)目的build.gradle文件中配置子項(xiàng)目夭织。

如果我們想要在一個(gè)稱為core的子項(xiàng)目中添加配置,那么就必須在根項(xiàng)目的build.gradle文件中添加以下片段:

project(':core') {
    //Add core specific configuration here
}

換句話說(shuō)吠撮,如果想要將重復(fù)的配置轉(zhuǎn)移到根項(xiàng)目的構(gòu)建腳本中尊惰,就必須將以下配置添加到build.gradle文件中:

project(':app') {
    apply plugin: 'java'
 
    repositories {
        mavenCentral()
    }
}
 
project(':core') {
    apply plugin: 'java'
 
    repositories {
        mavenCentral()
    }
}

不過(guò)這種做法在實(shí)質(zhì)上并沒有改變什么,在構(gòu)建腳本中依然還存在重復(fù)配置泥兰,唯一的區(qū)別是重復(fù)配置現(xiàn)在轉(zhuǎn)移到了根項(xiàng)目的build.gradle文件中弄屡。讓我們來(lái)消滅這些重復(fù)配置。

如果我們想要在根項(xiàng)目的子項(xiàng)目中添加通用的配置鞋诗,需要將以下片段添加到根項(xiàng)目的build.gradle文件中:

subprojects {
    //Add common configuration here
}

在根項(xiàng)目的build.gradle文件中移除了重復(fù)配置后膀捷,代碼如下:

subprojects {
    apply plugin: 'java'
 
    repositories {
        mavenCentral()
    }
}

如果我們的配置項(xiàng)是被多項(xiàng)目構(gòu)建中的所有項(xiàng)目所共享的,那么需要在根項(xiàng)目的build.gradle文件中添加以下片段:

allprojects {
    //Add configuration here
}

擴(kuò)展閱讀:

現(xiàn)在削彬,我們可以從子項(xiàng)目的構(gòu)建腳本中移除重復(fù)配置全庸,子項(xiàng)目新的構(gòu)建腳本如下:

core/build.gradle文件如下:

dependencies {
    testCompile 'junit:junit:4.11'
}

app/build.gradle文件如下:

apply plugin: 'application'
 
dependencies {
    compile 'log4j:log4j:1.2.17'
    compile project(':core')
}
 
mainClassName = 'net.petrikainulainen.gradle.client.HelloWorld'
 
task copyLicense {
    outputs.file new File("$buildDir/LICENSE")
    doLast {
        copy {
            from "LICENSE"
            into "$buildDir"
        }
    }
}
 
applicationDistribution.from(copyLicense) {
    into ""
}

現(xiàn)在,我們已經(jīng)創(chuàng)建了一個(gè)多項(xiàng)目Gradle構(gòu)建融痛,下面讓我們來(lái)直觀的感受一下我們做了些什么壶笼。

我們剛剛做了什么?

在我們的多項(xiàng)目構(gòu)建的根目錄下執(zhí)行命令gradle projects雁刷,可以看到如下輸出:

> gradle projects
:projects
 
------------------------------------------------------------
Root project
------------------------------------------------------------
 
Root project 'multi-project-build'
+--- Project ':app'
--- Project ':core'
 
To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :app:tasks
 
BUILD SUCCESSFUL

正如我們所看到的拌消,這條命令列出了根項(xiàng)目的子項(xiàng)目(app和core),這意味著我們剛才已經(jīng)創(chuàng)建了一個(gè)多項(xiàng)目Gradle構(gòu)建安券,它擁有兩個(gè)子項(xiàng)目墩崩。

在我們的多項(xiàng)目構(gòu)建的根目錄下執(zhí)行命令gradle tasks,可以看到如下輸出(僅列出相關(guān)部分):

> gradle tasks
:tasks
 
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
 
Application tasks
-----------------
distTar - Bundles the project as a JVM application with libs and OS specific scripts.
distZip - Bundles the project as a JVM application with libs and OS specific scripts.
installApp -Installs the project as a JVM application along with libs and OS specific scripts
run - Runs this project as a JVM application

正如我們所看到的侯勉,我們可以使用Gradle運(yùn)行程序鹦筹,并創(chuàng)建一個(gè)可運(yùn)行的二進(jìn)制發(fā)布,它沒有使用所謂的“fat jar”方式址貌。這表明我們已經(jīng)滿足了本文中要求實(shí)現(xiàn)的Gradle構(gòu)建的所有需求铐拐。

我們繼續(xù)來(lái)看一下徘键,從這篇教程中我們學(xué)到了什么。

總結(jié)

這篇教程教會(huì)了我們?nèi)糠謨?nèi)容:

  • 一個(gè)多項(xiàng)目構(gòu)建必須在根項(xiàng)目的根目錄下包含settings.gradle文件遍蟋,因?yàn)樗该髁四切┌诙囗?xiàng)目構(gòu)建中的項(xiàng)目吹害。
  • 如果需要在多項(xiàng)目構(gòu)建的所有項(xiàng)目中加入公用的配置或行為,我們可以將這項(xiàng)配置加入到根項(xiàng)目的build.gradle文件中(使用allprojects)虚青。
  • 如果需要在根項(xiàng)目的子項(xiàng)目中加入公用的配置或行為它呀,我們可以將這項(xiàng)配置加入到根項(xiàng)目的build.gradle文件中(使用subprojects)。

P.S. 你可以從Github上獲取這篇教程的演示程序棒厘。

關(guān)于作者:JustinWu

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纵穿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子奢人,更是在濱河造成了極大的恐慌谓媒,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件何乎,死亡現(xiàn)場(chǎng)離奇詭異句惯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)支救,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門抢野,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人搂妻,你說(shuō)我怎么就攤上這事蒙保≡铮” “怎么了欲主?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)逝嚎。 經(jīng)常有香客問(wèn)我扁瓢,道長(zhǎng),這世上最難降的妖魔是什么补君? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任引几,我火速辦了婚禮,結(jié)果婚禮上挽铁,老公的妹妹穿的比我還像新娘伟桅。我一直安慰自己,他們只是感情好叽掘,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布楣铁。 她就那樣靜靜地躺著,像睡著了一般更扁。 火紅的嫁衣襯著肌膚如雪盖腕。 梳的紋絲不亂的頭發(fā)上赫冬,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音溃列,去河邊找鬼劲厌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛听隐,可吹牛的內(nèi)容都是我干的补鼻。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼遵绰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼辽幌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起椿访,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤乌企,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后成玫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體加酵,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年哭当,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猪腕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖址愿,靈堂內(nèi)的尸體忽然破棺而出桃笙,到底是詐尸還是另有隱情,我是刑警寧澤腐缤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站肛响,受9級(jí)特大地震影響岭粤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜特笋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一剃浇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猎物,春花似錦虎囚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至质帅,卻和暖如春适揉,著一層夾襖步出監(jiān)牢的瞬間留攒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工嫉嘀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炼邀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓剪侮,卻偏偏與公主長(zhǎng)得像拭宁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓣俯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,332評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理杰标,服務(wù)發(fā)現(xiàn),斷路器彩匕,智...
    卡卡羅2017閱讀 134,716評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,867評(píng)論 6 342
  • 盡管我們可以僅使用單個(gè)組件來(lái)創(chuàng)建可工作的應(yīng)用程序驼仪,但有時(shí)候更廣泛的做法是將應(yīng)用程序劃分為多個(gè)更小的模塊掸犬。 由于這是...
    XLsn0w閱讀 402評(píng)論 0 4
  • 今天湾碎,咱們來(lái)聊聊簡(jiǎn)歷的事,不管是今年畢業(yè)的應(yīng)屆生奠货,還是跳槽面試的工作者介褥,都需要手拿一份簡(jiǎn)歷,來(lái)應(yīng)對(duì)面試递惋,如何在簡(jiǎn)...
    瘦壯的胖子閱讀 264評(píng)論 0 0