KSP生成文件自动删除、下游模块未触发编译问题求助
问题原因分析
- 依赖传递性不足:module-core 使用
implementation依赖 module-ksp,导致下游的 module-other 无法获取到 module-ksp 中注解类的完整元信息,Gradle 增量编译无法感知上游注解变化对下游的影响。 - 增量编译触发逻辑缺失:默认情况下,Gradle 仅在模块自身代码或直接依赖的输出变更时触发编译,但 KSP 的生成逻辑依赖上游模块的注解定义/使用变化,现有配置未让 Gradle 追踪到这种传递性的变更关联。
- 生成代码目录被误清理:当 module-other 未触发编译时,Gradle 的增量清理机制会将未标记为“有效”的 KSP 生成目录视为过时内容删除,导致运行时反射异常。
解决方法
1. 调整依赖可见性
将 module-core 对 module-ksp 的依赖从 implementation 改为 api,确保下游 module-other 能获取到注解类的元信息:
如果是通过根项目统一配置,修改根 build.gradle.kts 的对应逻辑:
subprojects { // ... 原有配置 if (name != "module-ksp") { dependencies { // 给 module-core 配置 api 依赖,暴露注解给下游 if (name == "module-core") { api(project(":module-ksp")) } else { implementation(project(":module-ksp")) } ksp(project(":module-ksp")) // ... 其他全局依赖 } } }
2. 配置 KSP 增量编译属性
在根项目的 gradle.properties 中添加以下属性,增强 KSP 的增量编译感知能力:
# 启用 KSP 增量编译 ksp.incremental=true # 让 KSP 感知处理器类路径的变化 ksp.include.processor.classpath=true # 启用 Gradle 构建缓存与并行编译(提升增量编译效率) org.gradle.caching=true org.gradle.parallel=true
3. 强制 KSP 任务依赖上游模块编译
在根项目 build.gradle.kts 中,为所有模块的 KSP 编译任务添加上游依赖,确保上游模块编译完成后再执行下游 KSP 任务:
subprojects { // ... 原有配置 tasks.withType<com.google.devtools.ksp.gradle.KspCompileTask> { // 依赖所有编译类路径中模块的 Kotlin 编译任务 dependsOn(project.configurations.compileClasspath.map { classpath -> classpath.files .filter { it.isDirectory && project.rootProject.projects.containsKey(it.parentFile.name) } .map { project.rootProject.project(it.parentFile.name).tasks.named("compileKotlin") } }) // 标记 KSP 输出目录为持久化,避免被误清理 outputs.dir(outputDir).withPropertyName("kspGeneratedDir") } }
4. 临时应急方案:手动触发全量编译
修改上游模块后,若以上配置暂未生效,可执行全量编译命令强制所有模块重新生成代码:
./gradlew clean build
内容的提问来源于stack exchange,提问作者user27909701
相关产品推荐
相关产品推荐

