添加对 Gradle 中生成的源集的运行时依赖

Tom*_*son 5 code-generation gradle

我想创建一个项目,其构建过程包括一些代码生成。生成的代码在编译时依赖于主代码(它扩展了公共基类)和 JCenter 的模块。主代码实际上对生成的代码具有运行时依赖性;也许更正确的说法是应用程序对主代码和生成代码都具有运行时依赖性,以及两者的模块依赖性。

\n\n

编辑:为了使依赖关系更清晰,这是一个粗劣的图表,其中箭头从配置指向它所依赖的东西。正如您所看到的,依赖图中没有循环。

\n\n
main compile \xe2\x86\x90 generated compile \xe2\x86\x92 generated module\n      \xe2\x86\x91                \xe2\x86\x91\nmain runtime \xe2\x86\x92 generated runtime\n
Run Code Online (Sandbox Code Playgroud)\n\n

我真的很想将生成的代码放在主代码的单独源集中。我也很想使用应用程序插件来提供gradle rungradle installDist.

\n\n

我正在使用最新的 Gradle 3.3。

\n\n

我创建了一个项目来尝试这个。其中,源集是:

\n\n
sourceSets {\n    generated {\n        java {\n            srcDirs = ["$buildDir/src/generated/java"]\n            compileClasspath += sourceSets.main.output\n        }\n    }\n    main {\n        java {\n            runtimeClasspath += sourceSets.generated.output + sourceSets.generated.runtimeClasspath\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

还有一个生成代码的任务:

\n\n
task generateSource {\n    doLast {\n        // generate the code into sourceSets.generated.java.srcDirs[0] here\n    }\n}\n\ncompileGeneratedJava.dependsOn generateSource\n
Run Code Online (Sandbox Code Playgroud)\n\n

生成的代码的生成和编译工作正常。如果我说gradle generatedClasses,它会编译主代码,生成源代码,然后编译生成的代码。

\n\n

但是,运行和分发都无法正常工作。如果我说gradle run,它不会尝试生成或编译生成的代码。如果我说gradle generatedClasses run,那么生成的代码将被生成并编译,但不会添加到所执行的 Java 进程的类路径中。如果我说gradle installDist,那么它不会尝试生成或编译生成的代码,并且类似地,如果我说gradle generatedClasses installDist,则生成并编译生成的代码,但不包含在发行版中。

\n\n

生成的源集的模块依赖项也不包含在类路径或发行版中。

\n\n

真正奇怪的是,如果我通过自己的运行任务版本定义:

\n\n
task runProperly(type: JavaExec) {\n    classpath = sourceSets.main.runtimeClasspath\n    main = mainClassName\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

效果非常好!

\n\n

那么,为什么编译的类和生成的源集的模块依赖项都没有包含在运行或分发类路径中?

\n

Vya*_*ets 3

因为application插件在更改源集之前已经设置了类路径。如果您在构建apply plugin: 'application'后移动,它将按您的预期工作。sourcesets {}

但我认为 asourceset不是生成代码的正确位置。您的构建应该如下所示:

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
}
Run Code Online (Sandbox Code Playgroud)