Gradle 基礎(chǔ)用法

命令行

執(zhí)行任務(wù)

可以通過命令行執(zhí)行一個(gè)或多個(gè)任務(wù)

# 執(zhí)行任務(wù) compile
> gradle compile

# 按順序執(zhí)行多個(gè)任務(wù)任務(wù) compile, test
> gradle compile test

任務(wù)依賴

下面定義四個(gè)任務(wù),disttest依賴于comile任務(wù),執(zhí)行gradle dist test時(shí)compile任務(wù)只會(huì)被執(zhí)行一次。

tasks

build.gradle

task compile {
    doLast {
        println 'compiling source'
    }
}

task compileTest(dependsOn: compile) {
    doLast {
        println 'compiling unit tests'
    }
}

task test(dependsOn: [compile, compileTest]) {
    doLast {
        println 'running unit tests'
    }
}

task dist(dependsOn: [compile, test]) {
    doLast {
        println 'building the distribution'
    }
}

執(zhí)行gradle dist test后輸出

> gradle dist test
:compile
compiling source
:compileTest
compiling unit tests
:test
running unit tests
:dist
building the distribution

BUILD SUCCESSFUL in 0s
4 actionable tasks: 4 executed

任務(wù)名稱縮寫

在命令行指定任務(wù)名時(shí)不必使用完整的任務(wù)名,只需提供能唯一識(shí)別任務(wù)的部分即可。

比如任務(wù)zee可以通過以下命令執(zhí)行:

> gradle z
> gradle ze
> gradle zee 

假設(shè)同時(shí)存在任務(wù)zee,zoo,執(zhí)行gradle z 將失敗。

可以對(duì)駝峰式任務(wù)名中的各個(gè)單詞使用縮寫,比如任務(wù)fooBar可以通過以下命令執(zhí)行:

> gradle fB
> gradle foB
> gradle fooB 
...
> gradle foBa
... 
> gradle fooBar 

獲取構(gòu)建信息

Gradle提供了一些內(nèi)建任務(wù)以獲取特定的構(gòu)建信息,以便調(diào)試問題和理解構(gòu)建的結(jié)構(gòu)與依賴。

# 以樹形結(jié)構(gòu)列出當(dāng)前項(xiàng)目子項(xiàng)目
> gradle -q projects

# 顯示當(dāng)前項(xiàng)目項(xiàng)的任務(wù)列表
> gradle -q tasks 
# 顯示當(dāng)前項(xiàng)目項(xiàng)的所有任務(wù)
> gradle -q tasks --all

# 查看任務(wù)信息
> gradle -q help --task <task>
 
# 顯示當(dāng)前項(xiàng)目的依賴
> gradle dependencies
# 顯示指定子項(xiàng)目的依賴
> gradle <subproject>:dependencies

# 顯示當(dāng)前項(xiàng)目buildscript的依賴
> gradle buildEnvironment
# 顯示指定子項(xiàng)目buildscript的依賴
> gradle <subproject>:buildEnvironment

# 查看特定配置中指定依賴的依賴
> gradle -q <subproject>:dependencyInsight --dependency <dependency> --configuration <configuration>

# 查看項(xiàng)目屬性 
> gradle -q <subproject>:properties

命令行選項(xiàng)

  • -?,-h,--help: 打印所有的命令行選項(xiàng)
  • -i, --info: 改變?nèi)罩炯?jí)別為INFO
  • -q, --quiet: 只打印錯(cuò)誤信息
  • -S, --full-stacktrace: 發(fā)生錯(cuò)誤時(shí)打印完整堆棧信息
  • -s, --stacktrace: 發(fā)生錯(cuò)誤時(shí)打印堆棧信息
  • -b, --build-file: 指定執(zhí)行的構(gòu)建腳本(默認(rèn)build.gradle)
  • -c, --settings-file: 指定配置腳本(默認(rèn)settings.gradle)
  • -D, --system-prop: 傳遞一個(gè)系統(tǒng)屬性給JVM,比如:-Dmyprop=myvalue
  • -P, --project-prop: 傳遞一個(gè)項(xiàng)目屬性值給構(gòu)建腳本,比如:-Pmyprop=myvalue
  • --offline: 以離線模式運(yùn)行構(gòu)建(Gradle只檢查本地緩存中的依賴)
  • -x, --exclude-task: 執(zhí)行構(gòu)建時(shí)排除指定任務(wù)

參考

https://docs.gradle.org/current/userguide/command_line_interface.html

構(gòu)建腳本

Gradle 的一切建立在 項(xiàng)目(project)與任務(wù)(task) 這兩個(gè)基本概念上。 參考

  • 每個(gè)Gradle構(gòu)建由一個(gè)或多個(gè)項(xiàng)目組成,項(xiàng)目代表什么取決于你想用做什么。它可以是一個(gè)JAR庫(kù)或Web應(yīng)用,也可以是一個(gè)由其它項(xiàng)目發(fā)行了ZIP。
  • 每個(gè)項(xiàng)目由一個(gè)或多個(gè)任務(wù)組成,任務(wù)表示在構(gòu)建中執(zhí)行的某些原子的工作內(nèi)容。比如編譯一個(gè)類,創(chuàng)建一個(gè)JAR,生成Javadoc等。

在命令行使用gradle命令時(shí),它會(huì)在當(dāng)前目錄尋找build.gradle文件,這個(gè)文件就是構(gòu)建腳本(build script),定義了項(xiàng)目和它的任務(wù)。

任務(wù)基本寫法

// 通過命令 gradle hello 執(zhí)行
// 使用-q參數(shù)不輸出日志 gradle -q hello
task hello {
    doLast {
        println 'Hello world!'
    }
} 

// 任務(wù)可以有依賴關(guān)系
task intro(dependsOn: hello) {
    doLast {
        println "I'm Gradle"
    }
}

// doFirst和doLast可以被執(zhí)行多次,動(dòng)作被添加到列表中,任務(wù)執(zhí)行時(shí)被依次調(diào)用。
hello.doLast {
    println 'Hello Mars'
}
hello {
    doLast {
        println 'Hello Jupiter'
    }
}

// 為任務(wù)添加額外的屬性
task myTask {
    ext.myProperty = "myValue"
} 
task printTaskProperties {
    doLast {
        // 訪問添加的屬性
        println myTask.myProperty
    }
}

構(gòu)建的生命周期(build lifecycle)

構(gòu)建分為三個(gè)階段

  • 初始化(Initialization),Gradle支持單項(xiàng)目和多項(xiàng)目構(gòu)建,在初始化階段,確定哪些項(xiàng)目是構(gòu)建的一部分,并創(chuàng)建Project實(shí)例。
  • 配置(Configuration),在這個(gè)階段所有項(xiàng)目對(duì)象(任務(wù)...)都被配置,屬于構(gòu)建的所有項(xiàng)目的build scripts都被執(zhí)行。
  • 執(zhí)行(Execution),確定要被執(zhí)行任務(wù)的子集并執(zhí)行,此任務(wù)子集由命令行傳入的任務(wù)名和當(dāng)前目錄決定。

settings.gradle 在初始化階段被執(zhí)行

println '===> initialization'

build.gradle

println '===> configuration - build.gradle - project a'

afterEvaluate {
    println '===> evaluation - build.gradle - project.after'
}

beforeEvaluate {
    println '===> evaluation - build.gradle - project.before'
}

task testOne {
    println '===> configuration - build.gradle - task.one'
}

println '===> configuration - build.gradle - project b'

task testTwo {
    doLast {
        println '===> execution - build.gradle - task.two'
    }
}

task testThree {
    doFirst {
        println '===> execution - build.gradle - task.three.doFirst'
    }
    doLast {
        println '===> execution - build.gradle - task.three.doLast'
    }
    println '===> configuration - build.gradle - task.three'
}

執(zhí)行 gradle testOne testTwo testThree 后輸出

> gradle testOne testTwo testThree
===> initialization
===> configuration - build.gradle - project a
===> configuration - build.gradle - task.one
===> configuration - build.gradle - project b
===> configuration - build.gradle - task.three
===> evaluation - build.gradle - project.after
:app:testOne UP-TO-DATE
:app:testTwo
===> execution - build.gradle - task.two 
:app:testThree
===> execution - build.gradle - task.three.doFirst
===> execution - build.gradle - task.three.doLast

為項(xiàng)目添加屬性(gradle.properties)

Gradle 有多種方式以特定的順序?yàn)轫?xiàng)目添加屬性,以不同方式設(shè)置的相同屬性排序靠后的將被設(shè)置:

  1. 父項(xiàng)目目錄的 gradle.properties 文件
  2. 項(xiàng)目目錄的 gradle.properties 文件
  3. Gradle 用戶根目錄的 gradle.properties 文件(~/.gradle/gradle.properties)
  4. ORG_GRADLE_PROJECT_ 開始的環(huán)境變量,對(duì)于環(huán)境變量 ORG_GRADLE_PROJECT_myProperty,會(huì)設(shè)置名為 myProperty 的屬性。
  5. -Dorg.gradle.project. 開始的系統(tǒng)屬性,對(duì)于系統(tǒng)屬性 -Dorg.gradle.project.myProperty,會(huì)設(shè)置名為 myProperty 的屬性。
  6. 在命令行中設(shè)置的 -P 參數(shù)

參考

https://docs.gradle.org/current/userguide/build_environment.html

Gradle 包裝器

Gradle 包裝器會(huì)自動(dòng)下載并安裝指定版本的Gradle運(yùn)行時(shí),為開發(fā)人員提供一致的構(gòu)建環(huán)境。

wrapper 任務(wù)

可以為wrapper任務(wù)指定一些參數(shù)

  • --gradle-version 指定gradle運(yùn)行時(shí)版本
  • --distribution-type 指定發(fā)行包類型:bin只有二進(jìn)制文件;all包含二進(jìn)制,源碼和文檔
  • --gradle-distribution-url 指定發(fā)行包下載地址

運(yùn)行wrapper任務(wù)

> gradle wrapper --gradle-version 3.3 
:wrapper

BUILD SUCCESSFUL

Total time: 1.416 secs

wrapper任務(wù)會(huì)生成以下文件

<project-root>/
  gradlew
  gradlew.bat
  gradle/wrapper/
    gradle-wrapper.jar
    gradle-wrapper.properties

在運(yùn)行g(shù)radlew命令構(gòu)建時(shí),它會(huì)先檢查指定版本的Gradle運(yùn)行時(shí)是否可用,如果不可用就先下載它。

下載的Gradle通常存放在 <project-root>/.gradle/wrapper/dists

參考

Gradle Wrapper
https://docs.gradle.org/current/userguide/gradle_wrapper.html

DSL Wrapper
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

使用插件

https://docs.gradle.org/current/userguide/plugins.html

使用分為兩步

  • 解析(resolve),找到正確的插件版本并添加到 script classpath。
    腳本插件是在應(yīng)用時(shí)自解析的,Gradle自帶的核心插件是自動(dòng)解析的。
  • 應(yīng)用(apply),在項(xiàng)目中對(duì)插件執(zhí)行Plugin.apply(T)
    此操作是冪等的,多次調(diào)用無副作用。

應(yīng)用插件

// 應(yīng)用腳本插件 
apply from: 'other.gradle'

// 根據(jù)類型應(yīng)用插件 
apply from: JavaPlugin

// 應(yīng)用二進(jìn)制插件 
apply from: ‘java’

使用buildscript解析插件并應(yīng)用

build.gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5"
    }
}

apply plugin: "com.jfrog.bintray"

使用 plugins DSL 應(yīng)用插件

plugins DSL 將解析與應(yīng)用合并在一步執(zhí)行,簡(jiǎn)化了用法。

plugins {
    // 應(yīng)用核心插件
    id 'java' 
    // 應(yīng)用已發(fā)布到 Gradle plugin portal 的插件
    id "com.jfrog.bintray" version "1.7.3"
}

使用 plugins DSL 應(yīng)用自定義倉(cāng)庫(kù)中的插件

在 settings.gradle 引入自定義插件倉(cāng)庫(kù)

pluginManagement {
    repositories {
        maven { url 'custom-repo' }
        gradlePluginPortal() 
    }
}

在 build.gradle 中應(yīng)用插件

plugins {
    id "ezy.example.gradleplugin" version "1.0.0"
}

自定義插件(Custom Plugin)

自定義插件可以可以放在以下幾個(gè)地方:

  • 可以直接寫在 build.gradle 中,但此插件不能被其它構(gòu)建引用。
  • 在單獨(dú)的文件中實(shí)現(xiàn)插件,放在buildSrc項(xiàng)目中(buildSrc/src/main/groovy/)。
    運(yùn)行 Gradle 時(shí),如果存在 buildSrc 目錄,不需要額外的指令,其中的代碼就會(huì)被編譯測(cè)試并添加到構(gòu)建腳本的 classpath 中,同一個(gè)工程中的所有構(gòu)建文件中都可以引用。
  • 在單獨(dú)的工程中自定義插件,上傳到遠(yuǎn)程倉(cāng)庫(kù)。通過添加依賴,引用這個(gè)插件。

簡(jiǎn)單的例子

以下代碼是一個(gè)簡(jiǎn)單的自定義插件示例。

在應(yīng)用插件后會(huì)創(chuàng)建一個(gè)任務(wù)(hello),并且可通過greeting.message傳入?yún)?shù),在命令行中輸入gradle hello執(zhí)行

build.gradle

apply plugin: SimplePlugin

// 其它一些配置
// ...

greeting {
    message = "hello, hahahahahahha!"
}


class GreetingPluginExtension {
    String message = 'Hello from GreetingPlugin'
}

class GreetingPlugin implements Plugin<Project> { 
    void apply(Project project) {
        println "===>>> GreetingPlugin"

        project.extensions.create('greeting', GreetingPluginExtension)

        project.task('hello') {
            doLast {
                println "===>>> task hello : ${extension.message}"
            }
        } 
    }
}

使用 java-gradle-plugin 自定義插件

如果希望自己發(fā)布到自定義倉(cāng)庫(kù)中的插件也能使用plugins DSL引用,需要用到插件 java-gradle-plugin

  • 它會(huì)為插件在META-INF目錄生成插件描述
  • 它會(huì)為每個(gè)插件生成一個(gè)Plugin Marker Artifact

Demo(https://docs.gradle.org/current/samples/sample_gradle_plugin.html)

plugins {
    id "java-gradle-plugin" 
}
// ...
gradlePlugin {
    plugins {
        greeting {
            id = 'com.example.plugin.greeting'
            implementationClass = 'com.example.plugin.GreetingPlugin'
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容