如何在多源码目录的Gradle SourceSet中保持输出结构
解决方案
你遇到的编译错误是因为自定义SourceSet之间默认没有建立依赖关系,导致编译某个SourceSet时无法找到其他SourceSet中的类。以下是无需修改代码结构的解决方法:
1. 配置带依赖关系的SourceSet
通过为每个SourceSet指定编译依赖的类路径,同时自定义class文件输出目录,实现编译时的依赖解析和class文件分目录存放:
sourceSets { // 清空默认main SourceSet的源码目录,避免重复编译 main { java { srcDirs = [] } } A { java { srcDir "A/src" } // 指定A的class文件输出目录 output.classesDir = file("$buildDir/classes/A") // 根据实际依赖关系配置编译类路径:假设A依赖B和C compileClasspath += sourceSets.B.output + sourceSets.C.output runtimeClasspath += sourceSets.B.output + sourceSets.C.output } B { java { srcDir "B/src" } output.classesDir = file("$buildDir/classes/B") // 假设B依赖C,根据实际情况调整 compileClasspath += sourceSets.C.output runtimeClasspath += sourceSets.C.output } C { java { srcDir "C/src" } output.classesDir = file("$buildDir/classes/C") // 如果C无其他依赖,无需额外配置类路径 } }
2. 配置Jar任务
基于每个SourceSet的输出配置Jar打包任务,确保生成对应模块的Jar文件:
// 打包A模块的class文件 task jarA(type: Jar) { from sourceSets.A.output.classesDirs archiveFileName = "A.jar" } // 打包B模块的class文件 task jarB(type: Jar) { from sourceSets.B.output.classesDirs archiveFileName = "B.jar" } // 打包C模块的class文件 task jarC(type: Jar) { from sourceSets.C.output.classesDirs archiveFileName = "C.jar" } // 让build任务自动触发Jar打包 build.dependsOn(jarA, jarB, jarC)
关键说明
- 依赖关系需与代码实际依赖一致:比如如果B依赖A,要将
sourceSets.A.output添加到B的compileClasspath中。 - 避免循环依赖:如果存在A依赖B、B依赖A的循环依赖场景,Gradle无法处理这种SourceSet循环依赖,此时需要重构代码消除循环依赖,或合并相关模块到同一个SourceSet。
内容的提问来源于stack exchange,提问作者BoroBoro
相关产品推荐
相关产品推荐

