Gradle官网:百度搜索“Gradle官网”,可以看到Gradle的基础知识和特性。
一、Gradle是什么
Gradle 是一个用于管理并自动化构建流程的构建工具。(自动化构建工具)
它会帮你下载项目所需的依赖、 将你的项目代码打包并准备编译。
二、Gradle的发行
Gradle安装:
1.下载Gradle:访问Gradle官方网站(https://gradle.org/releases/)并下载最新版本的Gradle。您可以选择二进制分发版(适用于大多数平台)或源码分发版(如果您想查看或修改源代码)。
2.解压
3.配置环境变量:
export GRADLE_HOME=/Users/liangyaru/Downloads/AS_Workspace/gradle/gradle-8.10
export PATH={GRADLE_HOME}/bin
判断Gradle是否安装:在终端中运行 gradle -v
来检查 Gradle 是否已安装
Gradle 支持将 Kotlin 和 Groovy 作为主要的构建语言。Gradle 附带了自己的 Kotlin 和 Groovy 库,因此不需要安装它们。
Wrapper 是一个脚本,用于调用声明的 Gradle 版本,是执行 Gradle 构建的推荐方法。它位于项目根目录中,作为 gradlew
或 gradlew.bat
文件
Gradle版本更新:缓存的大小和缓存加载时间进行更新(性能方面)
Gradle 构建,可以看到项目结构、依赖项(常规和项目间依赖项)、正在使用的插件以及构建的控制台输出
Gradle可以:调用任务/添加依赖项
Maven 配置文件在配置 build 中的作用以及 Gradle 中的替代方法
断点调试gradle文件:
Add configuration——Remote——Remote Debug Gradle
查看Gradle配置:View
--> Tool Windows
--> Gradle,然后点击刷新图标
Gradle 在 Java 虚拟机 (JVM) 上运行
Android studio 如何使用和配置 Gradle?去官网查看
gradlew
或 gradlew.bat
:用于调用声明的Gradle版本
三、运行Gradle构建
概念:
插件基础:
核心插件:
为构建 Java 项目提供支持
添加对编译和测试 Groovy 源文件的支持
添加了对为企业应用程序构建 EAR 文件的支持
教程:
1.初始化项目:
.gradle:项目缓存目录
gradlew:macOS 和 Linux 脚本,用于使用 Gradle Wrapper 执行构建。
gradlew.bat:用于使用 Gradle Wrapper 执行构建的 Windows 脚本。
settings.gradle.kts:用于定义子项目列表的项目设置文件。
Gradle Wrapper:启动 Gradle 构建
构建文件:
kotlin中定义一个块:
val result = run { val a = 10 val b = 20 a + b } println(result) // 输出:30
2.运行任务:
列出项目中的所有可用任务:./gradlew tasks
任务用途:负责编译、复制和移动文件、创建 JAR 文件、生成 Javadoc、将工件发布到存储库或许多其他离散的工作单元。
Gradle 提供了许多内置任务,开发人员可以使用这些任务来增强构建脚本。
此示例任务使用 Copy
内置任务将 *.war
文件从源
目录复制到目标
目录。
tasks.register<Copy>("copyTask") {
from("source")
into("target")
include("*.war")
}
Copy - 可用于复制文件。
Delete - 可用于删除文件和目录。
Exec - 可用于执行任意 O/S 命令。
Zip - 可用于捆绑文件。
3.了解依赖关系:
Gradle版本目录:gradle/libs.versions.toml
引用版本目录中定义的库,请执行以下操作:
dependencies { implementation(libs.guava) testImplementation(libs.junit.jupiter) }
依赖项管理:
repositories { // Use Maven Central for resolving dependencies. mavenCentral() } dependencies { // Use JUnit Jupiter for testing. testImplementation(libs.junit.jupiter) testRuntimeOnly("org.junit.platform:junit-platform-launcher") // This dependency is used by the application. implementation(libs.guava) }
mavenCentral:依赖项的来源
dependencies:声明依赖项
查看项目依赖项:./gradlew :app:dependencies
传递依赖项:
com.google.code.findbugs:jsr305:3.0.2
传递依赖项来自 com.google.guava:guava:32.1.2-jre
依赖项。
运行Java应用程序:./gradlew run
4.应用Gradle插件
插件是在项目中组织构建逻辑和重用构建逻辑的主要方法。
插件还用于将自定义任务作为打包代码分发。
将插件应用于项目将执行可创建任务、配置属性以及以其他方式扩展项目功能的代码。通常,插件使用 Gradle API 来提供额外的功能并扩展 Gradle 的核心功能。
插件可以:
将任务添加到项目中(例如编译、测试)。
扩展基本的 Gradle 模型(例如,添加可配置的新 DSL 元素)。
根据约定配置项目(例如,添加新任务或配置合理的默认值)。
应用特定配置(例如,添加组织存储库或强制实施标准)。
通过扩展向现有类型添加新属性和方法。
项目目前应用了一个插件,即与 Gradle 捆绑在一起的 Application Plugin:(Groovy)
plugins { // Apply the application plugin to add support for building a CLI application in Java. id 'application' }
有一个插件由 Gradle 维护和分发,称为 Maven Publish Plugin。Maven 发布插件提供了将构建构件发布到 Apache Maven 存储库的功能。它还可以发布到 Maven local,这是位于您计算机上的存储库,位置存放在用户名/.m2下。
通过将 maven-publish
添加到 build.gradle(.kts)
中的 plugins 块来应用插件:
plugins { // Apply the application plugin to add support for building a CLI application in Java. id 'application' id 'maven-publish' }
Maven Publish 插件中的新任务现在可在 IntelliJ 的 Gradle 右侧窗格中使用。
配置插件:将发布信息添加到您的 build.gradle(.kts)
文件中:(Groovy)
publishing { publications { create("maven", MavenPublication) { groupId = "com.gradle.tutorial" artifactId = "tutorial" version = "1.0" from(components["java"]) } } }
Gradle构建:先配置插件再应用插件。
在Gradle构建过程中,应用好插件后还需要进行配置的原因在于,插件本身并不能直接实现所有功能
使用插件:通过运行 publishToMavenLocal
任务来运行 ./gradlew :app:publishToMavenLocal
5.探索增量构建
Gradle 会以多种方式优化您的 build。其中一种优化称为 增量构建。
增量构建是一种构建,它避免运行自上一个构建以来输入未更改的任务,从而无需执行此类任务。
要使增量构建正常工作,任务必须定义其输入和输出。在构建时,Gradle 将确定输入或输出是否已更改。如果它们已更改,Gradle 将执行该任务。否则,它将跳过执行。
查看增量构建的实际效果,我们将控制台输出切换到 verbose。
gradle.properties增加这行代码: org.gradle.console=verbose
6.启用build缓存
gradle.properties添加:
org.gradle.console=verbose
org.gradle.caching=true
FROM-CACHE
- 已从本地构建缓存中获取任务。
UP-TO-DATE
- 使用增量生成且未重新运行的任务。
四、编写Gradle构建
基础学习:
1.Gradle目录
Gradle 使用两个主要目录来执行和管理其工作:Gradle User Home 目录和 Project Root 目录。
Gradle User Home 目录,即用户主目录:默认情况下,Gradle 用户主目录下(~/.gradle
或 C:\Users\<USERNAME>\.gradle
)存储全局配置属性、初始化脚本、缓存和日志文件。
结构大致如下:
1>全局缓存目录(用于非特定于项目的所有内容)。
2>特定于版本的缓存(例如,为了支持增量构建)。
3>共享缓存(例如,用于依赖项的工件)。
4>守护程序的注册表和日志。
5>全局初始化脚本。
6>工具链支持下载的 JDK。
7>由 Gradle Wrapper 下载的发行版。
8>Global Gradle 配置属性。
项目根目录:包含项目中的所有源文件。
还包含 Gradle 生成的文件和目录,例如 .gradle
和 build
。
1>由 Gradle 生成的特定于项目的缓存目录。
2>特定于版本的缓存(例如,为了支持增量构建)。
3>此项目的 build 目录,Gradle 会将所有 build 工件生成到该目录。
4>包含 Gradle 包装器的 JAR 文件和配置。
5>特定于项目的 Gradle 配置属性。
6>用于使用 Gradle Wrapper 执行构建的脚本。
7>用于定义子项目列表的项目设置文件。
8>通常,一个项目被组织成一个或多个子项目。
9>每个子项目都有自己的 Gradle 构建脚本。
2.多项目构建
多项目构建由一个根项目和一个或多个子项目组成。
识别项目结构:gradle -q projects
在相对于具有该任务的当前工作目录的任何子项目中执行测试
任务:gradle test
如果您从根项目目录运行该命令,您将在子模块 中运行 test
。
执行特定子项目中的特定:gradle :services:webservice:build
3.Gradle构建生命周期
1>初始化
Gradle 首先评估设置文件 settings.gradle(.kts),
然后实例化 Settings
对象。然后,Gradle 会实例化每个项目的 Project
实例。
2>配置
评估参与生成的每个项目的生成脚本 build.gradle(.kts)。
为请求的任务创建任务图。
在配置阶段,Gradle 会将任务和其他属性添加到初始化阶段找到的项目中。
3>执行
计划并执行所选任务。
任务之间的依赖关系决定了执行顺序。
任务的执行可以并行进行。
Gradle 使用配置阶段生成的任务执行图来确定要执行的任务。
4.编写配置文件:(用的是 Gradle API)
设置文件是每个 Gradle 构建的入口点。
找到设置文件 settings.gradle(.kts)
后,Gradle 会实例化一个 Settings
对象。
Settings
对象的用途之一是允许声明 要包含在构建中 的所有项目。
设置脚本可以是 Groovy 中的 settings.gradle
文件,也可以是 Kotlin 中的 settings.gradle.kts
文件。
在 Gradle 组装项目以进行构建之前,它会创建一个 Settings
实例并针对它执行设置文件。
当设置脚本执行时,它会配置此 Settings
。因此,设置文件定义 Settings
对象。
Settings
实例和 settings.gradle(.kts)
文件之间存在一一对应的关系。
我们可以使用 Settings.rootProject
属性在设置脚本中设置根项目名称:
settings.rootProject.name = "root"
通常缩写为:rootProject.name = "root"
include()
:将给定的项目添加到构建中。
设置 脚本 结构:
设置脚本是对 Gradle API 的一系列方法调用,通常使用 { ... }
,这是 Groovy 和 Kotlin 语言中的特殊快捷方式。{ }
块在 Kotlin 中称为 lambda,在 Groovy 中称为闭包。
简单地说,plugins{ }
块是一种方法调用,其中 Kotlin lambda 对象或 Groovy 闭包对象作为参数传递。它是以下各项的简称:方法调用 id(“plugin”)
对象的 this
类型为 PluginDependenciesSpec
。
plugins(function() { id("plugin") })
具体的配置文件可以看官网。重点看。
注意:include("app") 实际上是:settings.include("app")
5.编写构建脚本:
生成脚本用于配置项目,并与 Project
类型的对象相关联。
在执行生成脚本时,它会配置 Project
。
Project
对象是 Gradle API 的一部分。
添加依赖项:
dependencies { implementation("com.google.guava:guava:32.1.1-jre") }
使用 Project.getDependencies()
方法返回的 DependencyHandler
来管理依赖项。
使用 Project.getRepositories()
方法返回的 RepositoryHandler
来管理存储库。
设置属性:
application { mainClass = "com.example.Main" }
Project
对象具有关联的 ExtensionContainer
对象,该对象包含已应用于项目的插件的所有设置和属性。
在示例中,应用程序
插件添加了一个 application
属性,该属性用于详细说明 Java 应用程序的主类
注册和配置任务:
在项目中注册任务:
tasks.register("zip-reports") { from 'Reports/' include '*' archiveName 'Reports.zip' destinationDir(file('/dir')) }
使用以下 TaskCollection.named(java.lang.String)
方法找到任务以对其进行配置:
tasks.named("test") { useJUnitPlatform() }
将 Javadoc
任务配置为从 Java 代码自动生成 HTML 文档:
tasks.named("javadoc").configure { exclude 'app/Internal.java' exclude 'app/internal/' exclude 'app/internal/*' }
生成脚本由零个或多个语句和脚本块组成:
println(project.layout.projectDirectory);
语句可以包括方法调用、属性赋值和局部变量定义:
version = '1.0.0.GA'
脚本块是一种方法调用,它以 closure/lambda 作为参数:
configurations { }
closure/lambda 在执行时配置一些委托对象:
repositories { google() }
Extra Properties 额外属性:
Gradle 的增强对象(包括项目、任务和源代码集)可以保存用户定义的属性。
通过拥有对象的 ext
属性添加、读取和设置额外的属性。或者,您可以使用 ext
块同时添加多个属性。
ext { springVersion = "3.1.0.RELEASE" emailNotification = "build@master.org" } sourceSets.all { ext.purpose = null }
sourceSets { main { purpose = "production" } test { purpose = "test" } plugin { purpose = "production" } }
具体看官网。
6.使用任务
Gradle 可以在项目中执行的工作由一个或多个任务定义。
任务表示生成执行的某个独立工作单元。可以是编译一些类、创建 JAR、生成 Javadoc 或将一些存档发布到存储库。
当用户在命令行中运行 ./gradlew build
时,Gradle 将执行构建
任务以及它所依赖的任何其他任务。
注册任务后,可以通过 TaskProvider API 访问任务以进行进一步配置。
比如:运行时动态地向任务添加依赖项。
或者:向现有任务添加行为
7.编写任务:
Gradle 任务是通过扩展 DefaultTask
创建的。eg:
abstract class HelloTask : DefaultTask() { @TaskAction fun hello() { println("hello from HelloTask") } } // Register the hello Task with type HelloTask tasks.register("hello") { group = "Custom tasks" description = "A lovely greeting task." }
但是,泛型 DefaultTask
没有为 Gradle 提供任何操作。如果用户想要扩展 Gradle 及其构建脚本的功能,则必须使用内置任务或创建自定义任务:
内置任务 - Gradle 提供内置实用程序任务,例如 Copy
、Jar
、Zip
、Delete
等。
自定义任务 - Gradle 允许用户将 DefaultTask
子类化以创建自己的任务类型。
可以选择使用 TaskCollection.named()
方法在构建脚本中配置任务。
tasks.named("createFileTask") { fileText.set("HELLO FROM THE NAMED METHOD") // Override with custom message }
8.使用插件
Gradle 的大部分功能都是通过插件提供的,包括随 Gradle 分发的核心插件、第三方插件以及构建中定义的脚本插件。
插件引入了新任务(例如 JavaCompile
)、域对象(例如 SourceSet
)、约定(例如,将 Java 源代码定位在 src/main/java
)以及扩展核心或其他插件对象。
插件有三种方式可用:
核心插件 - Gradle 开发并维护一组核心插件。
社区插件 - 在远程存储库(如 Maven 或 Gradle 插件门户)中共享的 Gradle 插件。
本地插件 - Gradle 使用户能够使用 API 创建自定义插件。
要使用封装在插件中的构建逻辑,Gradle 需要执行两个步骤。首先,它需要解析插件,然后需要将插件应用于目标,通常是 Project
,在项目上执行插件的
Plugin.apply(T)
。
Gradle 在其分发过程中提供了核心插件(例如 JavaPlugin
、GroovyPlugin
、MavenPublishPlugin
等),这意味着它们会自动解析。
plugins { id «plugin id» version «plugin version» }
必须在设置文件中指定插件的位置:settings.gradle pluginManagement { repositories { gradlePluginPortal() maven { url 'https://maven.example.com/plugins' } } }
1>使用 plugins{} 块应用插件:plugins 块配置 PluginDependenciesSpec
的实例
plugins {}
块机制和 “传统” apply()
方法机制之间存在一些关键差异。具体看官网。略着看就可以。
多项目构建中,子项目构建脚本中的plugins{}
块 不带版本
2>应用 buildSrc 目录中的插件:
buildSrc
是 Gradle 项目根目录中的可选目录,其中包含用于构建主项目的构建逻辑(即插件)。您可以应用驻留在项目的 buildSrc
目录中的插件,只要它们具有定义的 ID。
定义一个插件:
gradlePlugin { plugins { myPlugins { id = 'my-plugin' implementationClass = 'my.MyPlugin' } } }
3>使用 buildscript{} 块应用插件
buildscript
块用于:
构建项目所需的全局依赖项
和存储库
(在子项目中应用)。
声明哪些插件可在构建脚本中使用(在 build.gradle(.kts)
文件中)。
当你想在构建脚本本身中使用一个库时,你必须使用 buildScript
在脚本 classpath 上添加这个库:
buildscript { repositories { // this is where the plugins are located mavenCentral() google() } dependencies { // these are the plugins that can be used in subprojects or in the build file itself classpath group: 'commons-codec', name: 'commons-codec', version: '1.2' // used in the task below classpath 'com.android.tools.build:gradle:4.1.0' // used in subproject } }
可以在需要它的子项目中应用全局声明的依赖项:
plugins { id 'com.android.application' }
4>使用旧版 apply() 方法应用脚本插件
插件管理:
pluginManagement{}
块用于配置用于插件解析的存储库,以及定义在构建脚本中应用的插件的版本约束。
pluginManagement{}
块可以在 settings.gradle(.kts)
文件中使用,其中它必须是文件中的第一个块:
自定义插件仓库:请使用 pluginManagement{}
中的 repositories{}
块:
settings.gradle pluginManagement { repositories { maven { url './maven-repo' } gradlePluginPortal() ivy { url './ivy-repo' } } }
9.编写插件
插件是 Plugin
接口的任何类。
编写插件:
abstract class SamplePlugin : Plugin { override fun apply(project: Project) { project.tasks.create("SampleTask") { println("Hello world!") } } }
扩展 org.gradle.api.Plugin
接口。覆盖apply() 方法。
教程:
1.初始化项目:gradle init
Application 插件由 gradle init
自动添加,有助于创建可执行的 JVM 应用程序
4.编写Settings文件,include是一个方法
5.编写构建脚本:
Project 对象的用途是创建 Task 对象的集合、应用插件和检索依赖项。
6.编写任务
Task 是包含操作序列的可执行代码段。
操作通过 doFirst{}
和 doLast{}
闭包添加到 Task 中。
Task 可以依赖于其他 Task。
注册任务:tasks.register
配置任务:tasks.named
构建:
子项目之间的依赖关系:eg:子项目依赖 shared 和 api
dependencies { testImplementation "junit:junit:4.13" implementation project(':shared') implementation project(':api') }
复合构建:通过设置文件定义复合构建,settings.gradle.kts includeBuild("my-utils")
开发任务:
组添加,任务可见;否则,为隐藏任务
tasks.register("helloTask") { group = "Other" description = "Hello task" println 'Hello' }
使用 Gradle 任务时,需要考虑三种状态:
注册任务(register)
配置任务(named)
实施任务(创建自定义任务类,扩展 Gradle 的 DefaultTask
类来完成)
延迟配置任务:lazy属性的一个重要功能是它们可以连接在一起,以便对一个属性的更改会自动反映在其他属性中。
下面是一个示例,其中任务的属性连接到项目扩展的属性:
// A project extension
// MessageExtension 是一个接口,它定义了一个可配置的问候语属性 greeting。 // Property<String> 是Gradle中的一个类型,表示一个可以配置的字符串属性。 interface MessageExtension { // A configurable greeting Property getGreeting() }
// A task that displays a greeting abstract class Greeting extends DefaultTask { // Configurable by the user @Input abstract Property getGreeting() // Read-only property calculated from the greeting @Internal final Provider message = greeting.map { it + ' from Gradle' } @TaskAction void printMessage() { logger.quiet(message.get()) } } // Create the project extension
// 这行代码在项目中创建了一个名为 messages 的 MessageExtension 实例。 project.extensions.create('messages', MessageExtension) // Create the greeting task tasks.register("greeting", Greeting) { // Attach the greeting from the project extension // Note that the values of the project extension have not been configured yet greeting = messages.greeting } messages { // Configure the greeting on the extension // Note that there is no need to reconfigure the task's greeting
property. This is automatically updated as the extension property changes greeting = 'Hi' }
此示例调用 Property.set(Provider) 方法将 Provider
附加到 Property
以提供属性的值。在这种情况下,Provider
恰好也是一个 Property
,但您可以连接任何 Provider
实现,例如使用 Provider.map()
创建的实现
一段代码:
layout.buildDirectory = layout.projectDirectory.dir('output')
这行代码是在Gradle构建脚本中设置构建输出目录的路径。具体来说,它将构建输出目录设置为项目目录下的 output
文件夹。
以下是代码的详细解释:
layout
:这是Gradle构建脚本中的一个对象,提供了对构建布局的访问。buildDirectory
:这是一个属性,表示构建输出目录的路径。layout.projectDirectory
:这是项目根目录的路径。dir('output')
:这是一个方法调用,表示在项目根目录下创建一个名为output
的子目录。
因此,这行代码的作用是将构建输出目录设置为项目根目录下的 output
文件夹。例如,如果项目根目录是 /path/to/project
,那么构建输出目录将是 /path/to/project/output
。
开发并行任务:接下来的篇章自己遇到问题再去查阅。以看会代码,理解代码为主。
开发高级任务:略
插件有三类:脚本插件,预编译的脚本插件,二进制插件。
发布gradle插件
五、依赖关系管理
基础知识:
声明依赖项,依赖项配置,声明仓库,集中依赖关系,依赖关系冲突和冲突解决
六、编写JVM版本
七、优化构建性能
提高gradle构建的性能:腾讯元宝搜索即可得到答案
八、编写 C++/Swift 版本
九、参考
一些命令:
安装Gradle,将Gradle版本更新到8.10:gradle wrapper --gradle-version 8.10
初始化Gradle/初始化项目:gradle init
运行clean任务,然后运行build任务:./gradlew :app:clean :app:build
运行Gradle构建:./gradlew :app:build
仅构建库:./gradlew :lib:build
仅构建 license-plugin:./gradlew :license-plugin:plugin:build
运行Gradle构建/构建应用程序和库:gradle build
删除构建目录:gradle clean
查看项目依赖项:./gradlew :app:dependencies
查看项目结构:gradle projects
识别项目结构:gradle -q projects
打印任务里的值:gradle -q {注册的task任务名称}
列出Gradle默认任务:./gradlew tasks 或 gradle tasks
查看根目录中的任务:./gradlew tasks --all
执行任务:gradle {注册的task任务名称}
查看子项目中的可用任务:/gradlew :app:tasks
查看有关任务的信息:gradle help --task <task-name>
编译和运行gradle/运行应用程序:gradle run
运行应用程序:gradle -q run
再次运行构建任务:gradlew build --scan
编译名为 "api" 的 Gradle 子项目:./gradlew :api:compile
复合构建:./gradlew run --include-build ../my-utils
附加:Kotlin语言与Groovy语言的不同
末尾为.kts就是kotlin语言,否则是Groovy语言(eg:settings.gradle.kts)
eg1:
Kotlin:
repositories { // Use Maven Central for resolving dependencies. mavenCentral() } dependencies { // Use JUnit Jupiter for testing. testImplementation(libs.junit.jupiter) testRuntimeOnly("org.junit.platform:junit-platform-launcher") // This dependency is used by the application. implementation(libs.guava) }
Groovy:
repositories { // Use Maven Central for resolving dependencies. mavenCentral() } dependencies { // Use JUnit Jupiter for testing. testImplementation libs.junit.jupiter testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // This dependency is used by the application. implementation libs.guava }
eg2:
Kotlin:
plugins { // Apply the application plugin to add support for building a CLI application in Java. application }
Groovy:
plugins { // Apply the application plugin to add support for building a CLI application in Java. id 'application' }
附加:问题定位