我想创建一个项目,其构建过程包括一些代码生成。生成的代码对主代码(它扩展了一个公共基类)和JCenter上的模块具有编译时依赖性。主代码有效地对生成的代码具有运行时依赖性;也许更正确的说法是应用程序对主代码和生成代码都有运行时依赖性,加上两者的模块依赖性。
编辑:为了使依赖关系更加清晰,这里是一个伪劣的图表,其中箭头从配置指向它所依赖的东西。如您所见,依赖图中没有循环。main compile ← generated compile → generated module
↑ ↑
main runtime → generated runtime
我真的想将生成的代码放在一个单独的源代码集中。我也非常想使用应用程序插件来提供gradle run
和gradle installDist
。
我正在使用最新推出的Gradle 3.3。
我创建了一个project to try this。其中,源集是:
sourceSets {
generated {
java {
srcDirs = ["$buildDir/src/generated/java"]
compileClasspath += sourceSets.main.output
}
}
main {
java {
runtimeClasspath += sourceSets.generated.output + sourceSets.generated.runtimeClasspath
}
}
}
有一项任务是生成代码:
task generateSource {
doLast {
// generate the code into sourceSets.generated.java.srcDirs[0] here
}
}
compileGeneratedJava.dependsOn generateSource
生成和编译生成的代码工作正常。如果我说gradle generatedClasses
,它会编译主代码,生成源代码,然后编译生成的代码。
但是,运行和分发都不能正常工作。如果我说gradle run
,它不会尝试生成或编译生成的代码。如果我说gradle generatedClasses run
,则生成并编译生成的代码,但不将其添加到执行的Java进程的类路径中。如果我说gradle installDist
,那么它不会尝试生成或编译生成的代码,同样,如果我说gradle generatedClasses installDist
,生成和编译生成的代码,但不包括在分发中
生成的源集的模块依赖性也不包括在类路径或分发中。
真正奇怪的是,如果我通过自己的运行任务版本定义:
task runProperly(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = mainClassName
}
完美无缺!
那么,为什么生成的源集的编译类和模块依赖性都不包含在运行或分发类路径中?
答案 0 :(得分:2)
因为application
插件在更改源集之前已设置了类路径。如果您在apply plugin: 'application'
之后移动sourcesets {}
,则构建将按预期工作。
但是从我看来,sourceset
不是生成代码的正确位置。您的构建应该如下所示:
apply plugin: 'application'
repositories {
jcenter()
}
dependencies {
compile group: 'org.fusesource.jansi', name: 'jansi', version: '1.14'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.22'
runtime group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.9'
}
mainClassName = 'Application'
task generateSources {
outputs.dir temporaryDir
doLast {
// Generate some code into temporaryDir
}
}
compileJava {
source generateSources
}