如何从另一个文件中调用macrodef

sch*_*eld 10 ant build macrodef

我在单独的文件中写了一个小的macrodef:

macrodefs.xml

<macrodef name="do-cool-stuff">
  <attribute name="message"/>

  <sequential>
    <echo message="@{message}" />
  </sequential>
</macrodef>
Run Code Online (Sandbox Code Playgroud)

我有第二个文件,我的主要构建文件:

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>
Run Code Online (Sandbox Code Playgroud)

你可能会猜到这不会起作用.错误消息类似于:

Target 'do-cool-stuff' does not exist in this project.
Run Code Online (Sandbox Code Playgroud)

我发现唯一可行的解​​决方案是在macrodefs.xml中提供额外的目标来转发ant调用.

是否有可能从另一个文件中调用macrodef?

提前致谢.

mar*_*ton 18

你可以import在文件中使用宏,如下所示:

<import file="macrodefs.xml" />
<do-cool-stuff message="Hello, World!" />
Run Code Online (Sandbox Code Playgroud)

请注意,在宏定义中,您应该@{curlybrackets}在引用宏属性时使用:

<sequential>
    <echo message="@{message}" />
</sequential>
Run Code Online (Sandbox Code Playgroud)

Ant macrodef任务文档末尾有一些示例.

更多

你想要做的是Ant没有得到很好的支持.在antantcall任务不允许"被叫",直接影响到调用者.您可以在被调用的任务中写入文件,然后在调用者中加载这些文件.但是,正如你所观察到,前期处理任务importinclude不能从目标中调用.ant/antcall任务只允许您在子构建中运行目标,而不是宏.

一种解决方法(这可能类似于您提到的方法,但允许您将所有实际工作放在顶级构建中)将是一个内部构建文件,其中包含macrodefs.xml的顶级导入.

像下面这样的东西.macrodefs.xml文件与以前一样.(但请注意,导入的文件 - 包括宏定义 - 需要是完整的Ant项目文件,因此它们必须包含项目元素.)

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>
Run Code Online (Sandbox Code Playgroud)

内的build.xml:

<project>
    <import file="macrodefs.xml" />

    <target name="target-runner">
        <ant antfile="build.xml" target="${target}" />
    </target>
</project>
Run Code Online (Sandbox Code Playgroud)

你会有效地做到

build.xml --> inner-build.xml --> build.xml (again)
(cvs)         (import macros)     (use macros)
Run Code Online (Sandbox Code Playgroud)

内部构建文件可能由主构建器即时生成 - 例如,如果您要导入多个宏定义文件 - 但这可能过于笨拙.

  • @martinclayton很棒的答案,但缺少一件事.你的答案并没有说_imported_ XML需要是一个完整的构建文件 - _full_,因为它必须有一个顶级的`project`标签.在我弄清楚之前,我试图为_hours_导入一个XML片段.我应该责备,因为我无法解读'Unexpected element'{} macrodef"...`错误信息,但仍然如此.如果你能更新你的答案以便面对这个问题的新来者可以快速前进,那就太好了.[这里有一些关于包括片段的信息.](http://ant.apache.org/faq.html#xml-entity-include). (4认同)