How to call macro-grandfather from another file
I wrote a little macrodef in a separate file:
macrodefs.xml
<macrodef name="do-cool-stuff"> <attribute name="message"/> <sequential> <echo message="@{message}" /> </sequential> </macrodef> I have a second file, my main build file:
build.xml
<target name="build"> <!-- do this and that --> <!-- cheking out macrodefs.xml via CVS --> <ant antfile="macrodefs.xml" target="do-cool-stuff" > <property name="message" value="Hello, World!" /> </ant> </target> As you might have guessed, this does not work. The error message looks something like this:
Target 'do-cool-stuff' does not exist in this project. The only possible solution I found is to provide an additional target in the macrodefs.xml file to redirect ant calls.
Is it possible to call macro-grandfather from another file?
Thanks in advance.
You can import file and use the macro as follows:
<import file="macrodefs.xml" /> <do-cool-stuff message="Hello, World!" /> Note that in the macro definition you must use @{curlybrackets} when referencing macro attributes:
<sequential> <echo message="@{message}" /> </sequential> There are several examples at the end of Ant macrodef task docs.
More details
What you are trying to do is poorly supported by Ant. The ant and antcall do not allow the "caller" to directly influence the caller. You can write files to the called task and then load them into the calling one. But, as you have noticed, import and include preprocess tasks cannot be called from the target. Ant / antcall tasks allow you to run targets only in child assemblies, not in macros.
One workaround (it may be similar to the one you mention, but allows you to put all the real work into a top-level assembly) will have an internal assembly file that includes the import of top-level macrodefects .xml.
Something like the following. The macrodefs.xml file is still. (But note that imported files, including macro definitions, must be full Ant project files, so they must include a project element.)
build.xml
<target name="build"> <!-- cvs actions --> <ant antfile="inner-build.xml" target="target-runner"> <property name="target" value="top-target" /> </ant> </target> <!-- this target will fail unless invoked from the inner build --> <target name="top-target"> <do-cool-stuff message="Hello, World!" /> </target> internal-build.xml
<project> <import file="macrodefs.xml" /> <target name="target-runner"> <ant antfile="build.xml" target="${target}" /> </target> </project> Effectively you will do
build.xml --> inner-build.xml --> build.xml (again) (cvs) (import macros) (use macros) An internal assembly file could potentially be generated on the fly using the main assembly — say, if you want to import multiple macro definition files, but that gets too cumbersome.