Создание элемента в стиле Union и Macrodef с динамическим содержимым во время выполнения в Ant

У меня есть встроенный скрипт Ant, который имеет макроопределение, которое принимает несколько параметров по умолчанию, target, root и т.п., а затем необязательные два: extrasrc-f и extrasrc-c. После того, как они пришли, мне нравится проверять обновления всех соответствующих ресурсов, а затем делать сборку только в том случае, если цель устарела.

Что у меня на данный момент,

<?xml version="1.0" encoding="UTF-8"?>
<project name="Custom build" default="default">

    <taskdef resource="net/sf/antcontrib/antlib.xml"
        classpath="C:/dev/ant/ant-contrib/ant-contrib-1.0b3.jar"/>

    <macrodef name="checkuptodate">
        <attribute name="target" />
        <element name="resource" />
        <sequential>
            <condition property="needbuild">
                <and>
                    <resourcecount when="greater" count="0"> <resource /> </resourcecount>
                    <not>
                        <uptodate targetfile="@{target}">
                            <srcresources> <resource /> </srcresources>
                        </uptodate>
                    </not>
                </and>
            </condition>
        </sequential>
    </macrodef>

    <macrodef name="projbuild">
        <attribute name="root" />
        <attribute name="target" />

        <element name="extrasrc-f" optional="true" />
        <element name="extrasrc-c" optional="true" />
        <sequential>
            <local name="needbuild" />
            <checkuptodate target="@{root}/bin/@{target}">
                <resource>
                    <union>
                        <extrasrc-f />
                        <fileset dir="@{root}/src" includes="**/*.java" />
                    </union>
                </resource>
            </checkuptodate>

            <if>
                <istrue value="${needbuild}" />
                <then>
                    <javac
                        srcdir="@{root}/src"
                        destdir="@{root}/bin"
                        includeantruntime="false"
                    >
                        <extrasrc-c />
                    </javac>
                </then>
            </if>

        </sequential>
    </macrodef>

    <target name="default">

        <projbuild root="." target="EntryPoint.class">
            <extrasrc-f>
                <fileset dir="Proj2/src" includes="**/*.java" />
                <fileset dir="Proj3/src" includes="**/*.java" />
            </extrasrc-f>
            <extrasrc-c>
                <classpath location="Proj2/src" />
                <classpath location="Proj3/src" />
            </extrasrc-c>
        </projbuild>

    </target>

</project>

Но, как вы видите, на данный момент для меня неэффективно делать то, что я хочу, я должен создать и передать как минимум один набор файлов и несколько путей к классам. То, что я действительно хотел бы сделать, это просто передать список каталогов, а затем создать элементы extrasrc-f и extrasrc-c на лету из этой информации, но, судя по всему, я понятия не имею, как я " Я могу сделать это.

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

Я неправильно подхожу к этому, или я что-то упускаю? Если я действительно неправильно использую Ant, я бы хотел указатели в правильном направлении о том, как сделать это правильно, создать ловушку, шаблонную сборку в macrodef (или target, если это единственный способ сделать это), который тестирует несколько источников файлы против одного файла, который создается, но также передаются дополнительные пути к классам или библиотекам, предпочтительно в одном списке.

1 ответ

Возможно, вы можете использовать пару <scriptdef> задачи, чтобы помочь разбить эти макросы.

Во-первых, тот, который берет разделенный запятыми список каталогов и генерирует <union> от них. Вы поставляете refid вы хотите использовать для обозначения союза как id приписывать. Есть дополнительные включения и исключения.

<scriptdef name="dirs2union" language="javascript">
    <attribute name="dirs" />
    <attribute name="id" />
    <attribute name="includes" />
    <attribute name="excludes" />
    <![CDATA[
      var dirs = attributes.get( "dirs" ).split( "," );
      var includes = attributes.get( "includes" );
      var excludes = attributes.get( "excludes" );

      var union = project.createDataType( "union" );
      project.addReference( attributes.get( "id" ), union );

      for ( var i = 0; i < dirs.length; i++ ) {
          var fs = project.createDataType( "fileset" );
          fs.setDir( new java.io.File( dirs[i] ) );
          if ( includes )
              fs.setIncludes( includes );
          if ( excludes )
              fs.setExcludes( excludes );

          union.add( fs );
      }
    ]]>
</scriptdef>

Второй - очень похожий - скрипт делает эквивалент для генерации пути:

<scriptdef name="dirs2path" language="javascript">
    <attribute name="dirs" />
    <attribute name="id" />
    <![CDATA[
      var dirs = attributes.get( "dirs" ).split( "," );

      var path = project.createDataType( "path" );
      project.addReference( attributes.get( "id" ), path );

      for ( var i = 0; i < dirs.length; i++ ) {
          var pe = project.createDataType( "path" );
          pe.setLocation( new java.io.File( dirs[i] ) );
          path.add( pe );
      }
    ]]>
</scriptdef>

Пример использования может быть что-то вроде:

<property name="dirs" value="Proj2/src,Proj3/src" />

<dirs2union dirs="${dirs}" id="my.union" includes="**/*.java" />
<dirs2path  dirs="${dirs}" id="my.path" />

... later (e.g.) ...

<union refid="my.union" />
<classpath refid="my.path" />

Затем вы можете изменить ваши макросы, чтобы взять dirs Атрибутировать и сгенерировать union и classpath внутри, или, возможно, сгенерировать их один раз в другом месте и просто передать ссылки.

Я не пытался включить @{root} каталоги на этой иллюстрации, но должно быть возможно адаптировать вышеупомянутое для этого.

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