Java 格雷德尔:我可以编译依赖于自身输出的代码吗?
这是一个奇怪的问题,但它不是理论上的Java 格雷德尔:我可以编译依赖于自身输出的代码吗?,java,compiler-construction,gradle,Java,Compiler Construction,Gradle,这是一个奇怪的问题,但它不是理论上的 我想做一个Gradle项目,它使用buildSrc,里面有一个java项目。该java项目定义了构建过程中使用的一些类 令人讨厌的技巧是,Gradle项目产生了一系列输出,包括修改的类,这些类属于buildSrc本身的Java项目 有没有什么方法可以表达这一点 我现在想到的唯一解决方案是:连续运行整个构建脚本两次。有什么办法可以避免吗?例如,通过为buildSrc生成修改后的代码,重新编译buildSrc,然后生成主Gradle项目的附加输出?我相信的第59
buildSrc
,里面有一个java项目。该java项目定义了构建过程中使用的一些类buildSrc
本身的Java项目我现在想到的唯一解决方案是:连续运行整个构建脚本两次。有什么办法可以避免吗?例如,通过为
buildSrc
生成修改后的代码,重新编译buildSrc
,然后生成主Gradle项目的附加输出?我相信的第59.4节可以帮助您
使用Gradle1.8,我尝试“从一个构建运行另一个Gradle构建”,其中另一个Gradle构建是buildSrc
这不涉及codegen,但可能足以提供帮助
为了复制,我在buildSrc中有一个简单的Java项目,其中build.gradle如下所示:
apply plugin: 'java'
build << {
println "TRACER: hello from buildSrc java build"
}
task compile2() << {
println "TRACER: hello from buildSrc compile2"
}
task build1() << {
println "TRACER: top-level build1"
}
task build2(type: GradleBuild) {
buildFile = 'buildSrc/build.gradle'
tasks = ['compile2']
}
build2.dependsOn build1
这表明:
- 编译buildSrc中的Java项目
- 调用根“build1”(在此处编译主项目)
- 调用buildSrc“compile2”
classpath和codegen很糟糕,但可能很直接 好的,以Michael Easter的绝妙示例为基础,我可以在自己的一个任务上调用主级构建调用
GradleBuild
:
task generateNewCode() << {
println("tracer top build")
// BuildTool is a Java class defined in `buildSrc`
// ... and it has a cyclic dependency on its own
// output (eek -- but that's what I'm dealing with!)
BuildTool.generateNewCode();
}
task generateDocs(type: GradleBuild) {
buildFile='build.gradle'
tasks = ['generateDocs_Real']
}
task generateDocs_Real << {
BuildTool.outputDocumentation();
}
generateDocs.dependsOn generateNewCode
task generateNewCode()您不能摆脱循环依赖关系吗?将Groovy项目分为代码生成模块和使用代码生成器输出的部分。(和/或可能是一些共享代码。)然后运行代码生成器,编译生成的Java,编译您的主要内容。这也是我的第一直觉。不幸的是,我正在处理一个遗留项目,其中代码生成实际上使用它输出的类。(这个过程不久前是手工引导的。)好的,但是循环依赖性意味着你不能一步完成。(从技术上讲,即使两个都不正确,正确的方法是重新运行代码生成器,直到没有任何变化。)我同意这是多个步骤(任务)。我只是想看看我是否能用一次调用Gradle就能做到。然后呢。。。将codegen拆分为自己的模块,并使用?它仍然有点脆弱,但至少在构建主模块时是自动化的。这本身就非常有用,我真的很欣赏这个具体的例子。但是如果我理解正确,在主构建脚本调用buildSrc
的compile2
之后,主构建脚本将不会有新编译的buildSrc
类可供执行。(也就是说,无法从新的buildSrc
交换新类)。是这样吗?
task generateNewCode() << {
println("tracer top build")
// BuildTool is a Java class defined in `buildSrc`
// ... and it has a cyclic dependency on its own
// output (eek -- but that's what I'm dealing with!)
BuildTool.generateNewCode();
}
task generateDocs(type: GradleBuild) {
buildFile='build.gradle'
tasks = ['generateDocs_Real']
}
task generateDocs_Real << {
BuildTool.outputDocumentation();
}
generateDocs.dependsOn generateNewCode