Как вызвать macrodef из другого файла

Я написал небольшой макрос в отдельном файле:

macrodefs.xml

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

  <sequential>
    <echo message="@{message}" />
  </sequential>
</macrodef>

Я получил второй файл, мой основной файл сборки:

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>

Как вы можете догадаться, это не работает. Сообщение об ошибке выглядит примерно так:

Target 'do-cool-stuff' does not exist in this project.

Единственное возможное решение, которое я нашел, - предоставить дополнительную цель в файле macrodefs.xml для переадресации вызовов ant.

Есть ли возможность вызвать macrodef из другого файла?

Заранее спасибо.

1 ответ

Решение

Вы можете import файл и использовать макрос, как это:

<import file="macrodefs.xml" />
<do-cool-stuff message="Hello, World!" />

Обратите внимание, что в определении макроса вы должны использовать @{curlybrackets} при ссылке на атрибуты макроса:

<sequential>
    <echo message="@{message}" />
</sequential>

Есть несколько примеров в конце муравья macrodef документация по заданию.

Больше

То, что вы пытаетесь сделать, не очень хорошо поддерживается Ant. ant а также antcall задачи не позволяют "вызываемому" напрямую влиять на вызывающего. Вы можете записывать файлы в вызываемую задачу, а затем загружать их в вызывающую программу. Но, как вы заметили, задачи перед процессом import а также include нельзя вызвать изнутри цели. Задачи 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>

Внутренний-build.xml:

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

    <target name="target-runner">
        <ant antfile="build.xml" target="${target}" />
    </target>
</project>

Эффективно вы будете делать

build.xml --> inner-build.xml --> build.xml (again)
(cvs)         (import macros)     (use macros)

Внутренний сборочный файл потенциально может быть сгенерирован на лету основной сборкой - скажем, если вы хотите импортировать несколько файлов определений макросов - но это становится слишком громоздким.

Другие вопросы по тегам