Chapter 22. Build Item Rules and Automatically Generated Code

Table of Contents

22.1. Build Item Rules
22.2. Code Generator Example for Make
22.3. Code Generator Example for Groovy
22.4. Multiple Wrapper Scripts
22.5. Dependency on a Make Variable
22.6. Caching Generated Files
22.6.1. Caching Generated Files Example

In this chapter, we show how to use abuild with custom rules provided by build items. The most common application of build item-supplied rules is to support automatic code generation. Examples are presented for both the GNU Make backend and the Groovy/ant as the mechanisms are very similar.

22.1. Build Item Rules

The most important thing to realize about code generators in abuild is that code generation can be viewed as a just another service that a build item can offer, just like libraries or header files. In many build systems, code generators are problematic because you need to take special steps to make sure generated code appears before compilation or dependency generation begin. With abuild, code generators get run at the correct stage by virtue of appearing in the correct place in the dependency tree.

Any build item may provide custom rules. [45] To provide custom rules, a build item creates a rules directory. The rules themselves go in a subdirectory of rules either named all, for rules that can be used by any build item, or named after the target type (one of object-code, java, or platform-independent) for rules that are available only to build items of the specified target type. When searching for rules, abuild always looks the directory under rules corresponding to the build item's target type first, and then it searches the all directory. The basic procedure for providing build item rules is essentially the same for both backends. The differences are mainly syntactic. We describe the mechanisms in turn for each backend.

In order for a make-based build item to provide code generation, it must supply additional make rules. The rules are in the form of a make fragment. The name of the rules file is, where rulename is whatever you are calling the rules. This is what people who use the rules will place in their RULES variable in their file. Any rules provided by a build item are run from the abuild output directory of the build item that is using the rules, just as is the case with built-in rules. That means that if the rules need to refer to files inside the build item that provides the rules, they must do so by either accessing interface variables defined in that build item's Abuild.interface or by prefixing the files with a variable that abuild provides. Specifically, for a build item named build-item, abuild provides variable called abDIR_build-item that can be accessed from the rules implementation file. Note that abuild only provides these variables for build items in your dependency chain. Also, use of these variables from files is strongly discouraged as it can cause your build tree to contain path-based dependencies instead of name-based dependencies, which would defeat one of the most compelling advantages of abuild. The best practice is to refer to files in your own build item from your own files by using the abuild-provided variable name to find your own path, and to define interface variables for files that you intend for other build items to access. Either way, there are certain things that it are important to keep in mind when writing GNU Make rules for use inside of abuild. For a discussion of this topic, please see Section 30.2, “Guidelines for Make Rule Authors”.

In order for a Groovy-based build item to provide rules, it must supply additional groovy code in a file called rulename.groovy. Build items can use the rule by adding rulename to the abuild.rules parameter in their Abuild.groovy files. Within the context of the build item-supplied, the variables abuild.sourceDirectory and abuild.buildDirectory are File objects that represent the build item directory and output directory of the item on behalf of which the rules are being invoked. If the rules need to reference a file inside of the build item that is providing the rules, it should either set an interface variable or access its location by name using abuild.itemPaths[item-name], where item-name is the name of the build item providing the rules. Abuild only provides locations for build items that are plugins or that are in the dependency chain of the item being built.

A build item may actually provide rules for both backends at the same time as .mk and .groovy files can co-mingle in the rules directory. Whichever type of rules are being provided, rule authors are encouraged to create a help file that gives the user information needed to use the rules. The help file is called rulename-help.txt and resides in the same directory as the rules.

[45] Actually, there is no way for build items using the deprecated xml-based ant backend to provide custom rules. They are limited to providing code for specific hooks in the set rule structure. It is possible for plugins to provide custom targets using preplugin-ant.xml.