Skip to content

构建缓存

构建缓存是 Gradle 的强大功能,可以在不同机器、不同时间复用相同的构建结果,大幅加速 CI 构建。

本地构建缓存

bash
# 启用(单次)
./gradlew build --build-cache

# 查看缓存效果
> Task :compileJava FROM-CACHE    ← 从缓存恢复,节省时间
> Task :test FROM-CACHE
properties
# gradle.properties(永久启用)
org.gradle.caching=true

本地缓存位置:~/.gradle/caches/build-cache/

远程构建缓存

远程缓存允许多台机器(开发者和 CI)共享构建结果:

kotlin
// settings.gradle.kts
buildCache {
    local {
        isEnabled = true  // 本地缓存(默认开启)
    }
    
    remote<HttpBuildCache> {
        url = uri("https://build-cache.example.com/cache/")
        isPush = System.getenv("CI") != null  // 只有 CI 推送,开发者只读
        isEnabled = true
        
        credentials {
            username = System.getenv("CACHE_USERNAME") ?: ""
            password = System.getenv("CACHE_PASSWORD") ?: ""
        }
    }
}

使任务可缓存

任务必须满足以下条件才能被缓存:

  1. 有定义的输出(@Output
  2. 标注了 @CacheableTask
kotlin
@CacheableTask
abstract class ProcessCodeTask : DefaultTask() {
    @get:InputFiles
    @get:PathSensitive(PathSensitivity.RELATIVE)  // 缓存时路径不影响 Key
    abstract val sources: ConfigurableFileCollection
    
    @get:OutputDirectory
    abstract val outputDir: DirectoryProperty
    
    @TaskAction
    fun process() {
        // 处理逻辑
    }
}

缓存命中率分析

bash
# 生成 Build Scan 查看缓存情况
./gradlew build --build-cache --scan

# 查看哪些任务被缓存
./gradlew build --build-cache --info 2>&1 | grep "FROM-CACHE\|EXECUTED"

常见问题

任务不被缓存

原因:

  • 没有 @CacheableTask 注解
  • 输出中包含时间戳(导致每次 Key 不同)
  • 使用了绝对路径作为输入(应使用 @PathSensitive
kotlin
// ❌ 包含时间戳导致缓存失效
tasks.named<Jar>("jar") {
    manifest {
        attributes("Build-Timestamp" to System.currentTimeMillis())  // 每次不同!
    }
}

// ✅ 可缓存版本
tasks.named<Jar>("jar") {
    manifest {
        attributes("Build-Version" to project.version)  // 相同版本结果相同
    }
}

下一步