Создание элемента в стиле 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}
каталоги на этой иллюстрации, но должно быть возможно адаптировать вышеупомянутое для этого.