Android Project Executing Ant Build Before Compilation


I have an Android Project made up of 5 separate modules. Many of the modules contain .java files as well .thrift files; for these modules, Thrift must execute before the java build can begin. These modules have build.xml files which contain targets for the Thrift part of the build. In order to execute the Thrift build target for a module prior to its java build, I do the following:
1) Add the module's build.xml file to the Ant Build Window.
2) Select the module in the Ant Build window, right-click, and select "Execute on > Before Compilation".
My problem is that "Before Compilation" can only be set for one module at a time. I would like to be able to have "Before Compilation" set for all the individual modules that depend on Thrift (and not have to "toggle" the setting between modules).
My solution was to have a build.xml file at the top level Project directory that contains a target to do the Thrift part of the build for all modules that rely on Thrift. Now I just add the top-level build.xml to the Ant Build window and set that to "Execute on > Before Compilation". The problem with this solution is, now if I execute "Make Module" on a module in the Project window, the Before Compilation target is executed for all modules with a Thrift target (as opposed to just for the module being built).
Any suggestions for a better solution?


Comment actions Permalink

Hi Tom, 

For now I can only suggest employing ant's Uptodate task in your top-level build.xml to determine whether files in particular modules should be re-generated or not. The generation scope will be still project-wide, but the build will execute faster since it would re-generated only those files that were changed.

Another solution would be passing module context to your ant build file via ant properties. In the Ant View's build file properties you can define some name-value pairs that will be available in your build.xml as ant properties. For property value your can set a macro, that will be expanded depending on build execution context. The list of macros is available if you press the green "+" button in the value text field. Unfortunately builds executed before/after compilation only Project is available (hence only project-related macros can be properly expanded). We'll improve the context-awareness by providing module-related information too, when it is applicable and deducible from the compilation scope. For example, when you select a single module in the project view and invoke "Make module", the compilation scope contains this selected module and we can provide this information to the build, so that all module-related macros (module-name, module-source-path, module-dir) can be properly expanded. Your build then can use this information for smarter compilation.

Hope this helps

Comment actions Permalink

Great answer thanks a lot.

One of my colleagues heard about Ivy and thinks that might solve this problem. From what I've read so far, I don't see how incorporating Ivy will make much difference for the particular problem I described. Looks to me like Ivy is great for resolving external library dependencies (like Maven), and works with Ant to execute tasks. So my pre-compile tasks would still need to be specified in an Ant build.xml. Does that sound about right?

Comment actions Permalink

> Looks to me like Ivy is great for resolving external library dependencies (like Maven), and works with Ant to execute tasks

Yes, I understand Ivy's purpose exactly like this. This is a dependency resolution tool for Ant. The task that you are trying to solve is to speedup sources generation and perform it only when necessary for those files that really require this, instead of regenerating everything from scratch on every compilation.

Comment actions Permalink

Okay thanks.

By the way, my original request was to be able to set "Execute on > Before Compilation" on multiple module targets. However, after thinking about it, that would not solve my problem. Since it's an Android project, selecting "Make Module X" causes IntelliJ to do a java compile, so there's nothing that associates module X with a build.xml file.

For example, suppose I have module X and module Y, and there exists two build.xml files - one for module X and one for module Y. Now suppose IntelliJ allowed me to set "Execute on > Before Compilation" for two targets at the same time: in this case, one target from module X's build.xml file and the other from module Y's build.xml file. Now if we select "Make Module X", is it reasonable to expect IntelliJ to only execute the  Before Compilation target from module X's build.xml file? Probably not, because there is no convention that says a build.xml file is associated with whatever code happens to be in the same directory.



Please sign in to leave a comment.