Gradle多项目构建依赖循环:如何将generator整合进自动化构建流程?
解决方案:整合Generator到Gradle构建流程并打破依赖循环
1. 调整项目结构
新增独立模块game-generated,专门存放generator生成的代码,避免直接修改game模块源码目录,同时拆解依赖循环:
game-generated:仅存自动生成代码,依赖:engine和:game(生成代码会引用这两个模块的类):engine:仅运行时依赖:game-generated(通过反射加载,编译期无需依赖,保持引擎独立性):generator:依赖:engine和:game,负责生成代码到game-generated的源码目录:game:保持原有依赖(仅依赖:engine)- 平台模块(
:desktop/:android):依赖:game和:game-generated(运行时需要生成的代码)
调整settings.gradle添加新模块:
include ':game-generated'
2. 配置各模块Build脚本
2.1 :engine 模块
project(":engine") { dependencies { // 第三方依赖 runtimeOnly project(":game-generated") // 仅运行时依赖生成代码,不破坏编译期独立性 } }
2.2 :game-generated 模块
无需手写代码,仅配置源码目录让Gradle自动编译生成内容:
project(":game-generated") { apply plugin: 'java' sourceSets { main { java { srcDirs = ['src/main/java'] // generator会将代码写入此目录 } } } dependencies { api project(":engine") api project(":game") } }
2.3 :generator 模块
添加自定义任务,清理旧代码并运行generator,同时依赖:game和:engine的编译结果:
project(":generator") { apply plugin: 'java' dependencies { api project(":engine") api project(":game") } // 清理game-generated的旧生成代码 task cleanGeneratedCode(type: Delete) { delete project(":game-generated").sourceSets.main.java.srcDirs doFirst { // 确保目标目录存在 file(project(":game-generated").sourceSets.main.java.srcDirs[0]).mkdirs() } } // 运行generator生成新代码 task generateCode(type: JavaExec) { dependsOn cleanGeneratedCode, compileJava, project(":game").compileJava, project(":engine").compileJava classpath = sourceSets.main.runtimeClasspath mainClass = 'com.yourpackage.GeneratorMain' // 替换为generator的主类全路径 // 传递生成代码的目标目录作为参数 args project(":game-generated").sourceSets.main.java.srcDirs[0].absolutePath } }
2.4 :desktop 模块(平台模块示例)
project(":desktop") { dependencies { api project(":game") api project(":game-generated") // 运行时需要生成的代码 } // 让启动任务自动触发代码生成流程 run.dependsOn project(":generator").generateCode, project(":game-generated").compileJava }
3. 整合后的构建流程
现在只需执行命令:
./gradlew desktop:run
Gradle会自动完成以下步骤:
- 编译
:engine和:game模块 - 清理
:game-generated的旧代码 - 运行
:generator生成新代码 - 编译
:game-generated模块 - 启动
:desktop游戏进程
4. 额外优化
- 避免重复执行generator:给
generateCode任务添加输入输出缓存,仅当:game或:engine代码变更时才重新生成:generateCode { inputs.files project(":game").sourceSets.main.java.srcDirs, project(":engine").sourceSets.main.java.srcDirs outputs.dir project(":game-generated").sourceSets.main.java.srcDirs } - 调整generator归属:若想让generator属于engine组件,可将其改为
:engine:generator子模块,只需同步调整依赖路径即可,不影响整体逻辑。
内容的提问来源于stack exchange,提问作者therainycat
相关产品推荐
相关产品推荐

