【问题标题】:Create a Union and Macrodef-style element with dynamic content at runtime in Ant在 Ant 运行时创建具有动态内容的 Union 和 Macrodef 样式元素
【发布时间】:2012-05-07 21:10:02
【问题描述】:

我有一个在 Ant 中构建的构建脚本,它有一个带有一些默认参数的宏定义,目标、根等,然后是可选的两个,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,我会喜欢关于如何正确执行此操作的正确方向的指针,创建一个包罗万象的模板构建在一个测试多个源的宏定义(或目标,如果这是唯一的方法)中文件针对一个构建的文件,同时还传递额外的类或库路径,最好是在一个列表中。

【问题讨论】:

    标签: ant union element macrodef


    【解决方案1】:

    也许您可以使用几个&lt;scriptdef&gt; 任务来帮助分解这些宏。

    首先,它采用逗号分隔的目录列表并从中生成&lt;union&gt;。您提供要使用的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 属性并在内部生成联合和类路径,或者可能在其他地方生成一次并传入引用。

    我没有尝试在此插图中包含 @{root} 目录,但应该可以针对上述内容进行调整。

    【讨论】:

    • 抱歉,嗯,反应慢。
    • 哈哈,马丁不用担心,即使迟到了,我们也总是很感谢您的回复。自从我问了这个问题后,我不再在同一家公司工作,但我仍然经常使用 Ant 脚本,并且不知道 scriptdef,非常感谢!
    猜你喜欢
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多