-
24 February 2010, 16:40
MacroDef Task
I've used Ant for a long time to build my projects, whether they be in Java or not. But recently, I learned about a new task that I wish I had known much earlier. This task is
MacroDef.As the name suggests, it defines a macro, a single instruction that results in a series of instructions. I have no idea how many times I have had similar instruction sets for several different tasks. A macro would have made my past build scripts so much cleaner.
Let's go straight to a simple example.
Here I have given the complete<project name="macro test" default="macro"> <macrodef name="testing"> <attribute name="v" default="NOT SET"/> <sequential> <echo>v is @{v}</echo> </sequential> </macrodef> <target name="macro"> <testing v="'V!'"/> </target> </project>build.xml; from now on I will only redefine themacrodefandtargetfor brevity. The location of the macro definition and its call-location will not change.What's going on here? Well, first, I am defining what the macro actually does. Here it is nothing special. The
nameattribute of themacrodefelement defines a new XML element that we can use later to call the macro. Here it is named "testing". Theattributeelement is pretty obvious; it defines the attributes available to the new macro. If you specify a default value, the attribute becomes optional. To use the above-define attribute, type "@{v}"; this should look familiar to properties (${prop-name}). To escape the "@" symbol, use "@@", just like "$$" with properties. The bread and butter of the macro is defined in thesequentialelement. Again, nothing you wouldn't expect here. In that element, you simply list the tasks that you want in the order you want them to execute.Now, there's something else that I think is useful with
MacroDef. That is the ability to define nested elements in the macro. The contents of the nested element are inserted into the macro where the tag name is in the template. It's less complicated than it seems.<macrodef name="testing"> <attribute name="v" default="NOT SET"/> <element name="pre" optional="yes"/> <element name="post" optional="yes"/> <sequential> <pre/> <echo>v is @{v}</echo> <post/> </sequential> </macrodef> <testing v="'V!'"> <pre> <echo>pre!</echo> </pre> <post> <echo>post! </post> </testing>This is how I imagine myself using this task in the future. I have defined
preandpostelements that are optional and act like bookends to the main section of my new macro. I can put any task that I want into thepreandpostelements and they will execute as if they had been defined right in the macro. In the main body of the macro you can do anything like compile your source files and process any important resources you might have.