Using if:set, unless:set etc. with macrodefs in Ant

September 13, 2013 [Ant, Programming, Tech]

In a previous post I outlined how to use if:set and unless:set to execute tasks conditionally in Ant 1.9.1.

Unfortunately, this does not work with macrodefs. When I try to execute a macrodef conditionally like this:

<project
    xmlns:if="ant:if"
    xmlns:unless="ant:unless"
    default="build"
>

    <macrodef name="mymacro">
        <sequential>
            <echo message="inside mymacro"/>
        </sequential>
    </macrodef>

    <target name="build">
        <mymacro if:set="doit"/>
    </target>

</project>

When I set the "doit" property and run like this, it fails:

$ ant -Ddoit=true
Buildfile: build.xml

build:

BUILD FAILED
build.xml:14: Unknown attribute [ant:if:if:set]

Total time: 0 seconds

It looks to me like this is a bug: the if:set attribute is getting passed into the macro, which is complaining that it doesn't expect an attribute with that name. (If you try to create an attribute with that name, you'll find that "if:set" is an illegal name...)

However, there is a workaround. You can wrap the call to your macrodef in a <sequential> tag:

<project
    xmlns:if="ant:if"
    xmlns:unless="ant:unless"
    default="build"
>

    <macrodef name="mymacro">
        <sequential>
            <echo message="inside mymacro"/>
        </sequential>
    </macrodef>

    <target name="build">
        <sequential if:set="doit">
            <mymacro/>
        </sequential>
    </target>

</project>

And now it works!

$ ant -Ddoit=true
Buildfile: build.xml

build:
     [echo] inside mymacro

BUILD SUCCESSFUL
Total time: 0 seconds
$ ant

Buildfile: build.xml

build:

BUILD SUCCESSFUL Total time: 0 seconds

Conditional execution even when calling a macrodef. Enjoy.