The simplest antlr build seems to always place generated code at the base of build/generated-src/antlr/main/. This causes java errors if a package was defined in the .g files, like this:
@header {
package com.example.foo.antlr;
}
I realize it might be difficult for the Antlr plugin to be aware of that package information, but an alternate solution would be to mirror the source folder structure like resources do:
Thus this .g file:
src/main/antlr/com/example/foo/antlr/Foo.g
Should have generated code placed under a similar package structure:
build/generated-src/antlr/main/com/example/foo/antlr/Foo.java
(I should mention that simply specifying the outputDirectory does not work in the case of multiple .g files with different packages)
And what’s worse is that this seems to be a regression. I believe that this used to work in versions of Gradle prior to 2.3/2.4 when the Antlr plugin was significantly changed.
For additional information… putting the grammar file in the proper “package directory structure”… the plugin does find the grammar files, but it flattens the output back out into a root directory rather than honoring the “package directory structure”.
Interestingly (not sure how) compiling the generated sources works out ok. Using Henry’s example…
Foo.g declares package com.example.foo.antlr;
No matter where that file exists under src/main/antlr it is found, but the generated sources end up in ${buildDir}/generated-src/antlr/main rather than in ${buildDir}/generated-src/antlr/main/com/example/foo/antlr
On compile, somehow, the right thing does happen. Not only are the classes compiled, but somehow they get put into ${buildDir}/classes/main/com/example/foo/antlr
The Hibernate build[1] illustrates this if you need a way to reproduce. Hibernate is using Antlr 2, while it would appear that Henry is using Antlr 3 or 4. So that may be a difference too.
Ultimately the issue is in IDEs. If you import the Hibernate project into your IDE it (properly) shows ${buildDir}/generated-src/antlr/main as a source directory, however it shows it being incorrect since the sources are not in their proper directories according to their package statements.
I find it fascinating that the compiled classes end up in the proper directory. I am almost positive javac is not doing that.
Please note that even though Gradle is able to compile the generated source files (even though they are not placed in correct folder structure), other tools may not. I had to manually correct the folder structure, because IntelliJ Idea refused to “make” my Gradle project using Antlr 4. Therefore I hope this bug will be fixed also for Antlr 4.
It would be nice if Gradle’s Antlr plugin guessed “package” parameter value from the location of the grammar file, without needing to set “@header” inside the grammar file itself. This is how Maven’s Antlr4 plugin works - you just put your .g file to src/main/antlr4/your/package/ and generated .java files land in your/package/ folder.