在Ant中创建运行时具有动态内容的Union和Macrodef样式元素
我在Ant中构建了一个构建脚本,它有一个宏定义,它接受一些默认参数,target、root等等,然后是可选的两个参数,extrasrc-f和extrasrc-c。在他们进来之后,我喜欢对所有相关资源进行最新检查,然后只在目标过时的情况下进行构建 我现在所拥有的在Ant中创建运行时具有动态内容的Union和Macrodef样式元素,ant,union,element,macrodef,Ant,Union,Element,Macrodef,我在Ant中构建了一个构建脚本,它有一个宏定义,它接受一些默认参数,target、root等等,然后是可选的两个参数,extrasrc-f和extrasrc-c。在他们进来之后,我喜欢对所有相关资源进行最新检查,然后只在目标过时的情况下进行构建 我现在所拥有的 <?xml version="1.0" encoding="UTF-8"?> <project name="Custom build" default="default"> <taskdef res
<?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中创建一个catchall,模板构建(或者目标,如果这是唯一的方法的话),它可以针对一个构建的文件测试多个源文件,同时还传递额外的类或库路径,最好在一个列表中。也许您可以使用几个任务来帮助分解这些宏 首先,它采用逗号分隔的目录列表,并从中生成
。您提供要用于将联合称为id
属性的refid
。有可选的包含和排除
<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}
目录包含在这幅插图中,但应该可以对上面的内容进行调整。对于,呃,反应缓慢表示歉意。哈哈,不要担心,Martin,即使反应很晚,我们也非常感谢。因为我问了这个问题,我不再在同一家公司工作了,但我仍然经常使用Ant脚本,而且不知道scriptdef,非常感谢!