Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何声明gradle Antlr任务输出规格以避免不必要的重建_Java_Gradle_Dependencies_Antlr - Fatal编程技术网

Java 如何声明gradle Antlr任务输出规格以避免不必要的重建

Java 如何声明gradle Antlr任务输出规格以避免不必要的重建,java,gradle,dependencies,antlr,Java,Gradle,Dependencies,Antlr,我有一个典型的Antlr 4.5项目,其中包含两个语法文件:MyLexer.g4和MyParser.g4。Antlr从中生成6个输出文件:MyLexer.java、MyLexer.tokens、MyParser.java、MyParser.tokens、MyParserBaseListener.java和MyParserListener.java。gradle任务都正常工作,因此输出文件都按预期生成、编译和测试 问题是gradle认为6个目标文件总是过时,因此每次运行或调试会话都必须重新生成它们

我有一个典型的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
ext.antlr4=[
AntlResource:“src/main/antlr”,
destinationDir:“src/main/java/com/myantlQuestion/core/antlr/generated”,
grammarpackage:“com.myantlrquestion.core.antlr.generated”
]

task MakeantlOutputDir请尝试以下代码:

generatedFiles = ['MyLexer.java',] // and so on..
generatedFiles.each { f -> outputs.file("$target/$f") }

我发现问题不在于目标文件已经过时,而是由于cleanAntlr任务中的一个bug,每次运行gradle任务时,目标文件都会被删除。问题是,cleanAntlr中的所有代码都是在gradle的初始化和配置阶段运行的,即使cleanAntlr任务本身没有被执行

最初,任务定义为:

task cleanAntlr {
    delete antlr4.destinationDir
}
clean.dependsOn cleanAntlr

解决方法是这样定义它:(注意"谢谢你的回复。你的代码并没有最终解决问题,但它做到了我最初要求的,也就是说,它定义了单独的输出文件,而不是文件夹。正如我在我发布的答案中所解释的,这不是真正的问题。我最终不需要这段代码,但我认为我必须稍微调整一下语法才能让它实现我认为正确编译的语法是这样的:generatedFiles=['MyLexer.java',]//等等..generatedFiles.each{f->outputs.file(“{$target}/{$f}”)}这个解决方案也解决了我在中描述的问题
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
def grammars = fileTree(antlr4.antlrSource).include('**/*.g4')
def target = file("${antlr4.destinationDir}")
inputs.files grammars
outputs.dir target