У меня есть типичный проект Antlr 4.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