我有一个典型的Antlr4.5项目,其中包含两个语法文件: MyLexer.g4和MyParser.g4。Antlr从中生成6个输出文件: MyLexer.java、MyLexer.tokens、MyParser.java、MyParser.tokens、MyParserBaseListener.java和MyParserListener.java。gradle任务都正常工作,因此输出文件都是按照预期生成、编译和测试的。
问题是gradle认为6个目标文件总是过时的,所以每个运行或调试会话都必须重新生成它们,因此即使没有源文件更改,也必须重新编译主java项目。
生成文件的gradle任务将输出规范定义为生成6个输出文件的文件夹。我想我需要一种方法将它定义为6个特定的文件,而不是输出文件夹。我只是不知道这样做的语法。
下面是我的build.gradle文件的相关部分:
ext.antlr4 = [
antlrSource: "src/main/antlr",
destinationDir: "src/main/java/com/myantlrquestion/core/antlr/generated",
grammarpackage: "com.myantlrquestion.core.antlr.generated"
]
task makeAntlrOutputDir << {
file(antlr4.destinationDir).mkdirs()
}
task compileAntlrGrammars(type: JavaExec, dependsOn: makeAntlrOutputDir) {
// Grammars are conveniently sorted alphabetically. I assume that will remain true.
// That ensures that files named *Lexer.g4 are listed and therefore processed before the corresponding *Parser.g4
// It matters because the Lexer must be processed first since the Parser needs the .tokens file from the Lexer.
// Also note that the output file naming convention for combined grammars is slightly different from separate Lexer and Parser grammars.
def grammars = fileTree(antlr4.antlrSource).include('**/*.g4')
def target = file("${antlr4.destinationDir}")
inputs.files grammars
// TODO: This output spec is incorrect, so this task is never considered up to date.
// TODO: Tweak the outputs collection so it is correct with combined grammars as well as separate Lexer and Parser grammars.
outputs.dir target
main = 'org.antlr.v4.Tool'
classpath = configurations.antlr4
// Antlr command line args are at https://theantlrguy.atlassian.net/wiki/display/ANTLR4/ANTLR+Tool+Command+Line+Options
args = ["-o", target,
"-lib", target,
//"-listener", //"-listener" is the default
//"-no-visitor", //"-no-visitor" is the default
"-package", antlr4.grammarpackage,
grammars.files
].flatten()
// include optional description and group (shown by ./gradlew tasks command)
description = 'Generates Java sources from ANTLR4 grammars.'
group = 'Build'
}
compileJava {
dependsOn compileAntlrGrammars
// this next line isn't technically needed unless the antlr4.destinationDir is not under buildDir, but it doesn't hurt either
source antlr4.destinationDir
}
task cleanAntlr {
delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr发布于 2015-04-27 02:58:26
我发现问题并不在于目标文件过期,而是由于cleanAntlr任务中的一个错误,每次运行任何gradle任务时,它们都会被删除。问题是cleanAntlr中的所有代码都在gradle的初始化和配置阶段运行,即使cleanAntlr任务本身没有执行。
最初,该任务被定义为:
task cleanAntlr {
delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr解决方案是这样定义它:(注意任务名称后面的"<<“。)
task cleanAntlr << {
delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr..。或者,为了更清楚起见,可以使用这个更详细但功能相同的任务定义:
task cleanAntlr {
doLast() {
// Be sure to wrap the execution phase code inside doLast().
// Otherwise it will run during the initialization or configuration phase, even when an unrelated task is is run.
// It would also run when the NetBeas IDE first loaded the project.
//println 'Deleting Antlr Directory: ' + antlr4.destinationDir
delete antlr4.destinationDir
}
}
clean.dependsOn cleanAntlr修复了这个错误之后,compileAntlrGrammars任务的原始输出规范就可以正常工作了。不需要指定每个单独的输出文件。这在https://gradle.org/docs/current/userguide/more_about_tasks.html的15.9.2小节中有很好的解释。
def grammars = fileTree(antlr4.antlrSource).include('**/*.g4')
def target = file("${antlr4.destinationDir}")
inputs.files grammars
outputs.dir target发布于 2015-04-23 15:27:05
你能不能试试下面这段代码:
generatedFiles = ['MyLexer.java',] // and so on..
generatedFiles.each { f -> outputs.file("$target/$f") }https://stackoverflow.com/questions/29805091
复制相似问题