如果值为空,如何省略Ant中的清单属性?

时间:2013-11-29 10:25:52

标签: ant

这在Ant中定义了一个清单:

<manifest>
  <attribute name="Main-Class" value="${main-class}"/>
</manifest>

当属性包含空字符串时,如何在清单中省略空的主类条目?

4 个答案:

答案 0 :(得分:2)

唯一干净的解决方案是将ant任务写入两次:使用和不使用清单。

但如果您不想这样做,可以使用以下技巧。创建两个清单文件:一个包含主类,另一个没有。第一个清单中的主要类应替换为占位符(标记)(例如@main-class@)。然后就可以了

<condition
    property="manifest-file"
    value="manifest-without-main-class.mf"
    else="manifest-with-main-class.mf"
>
    <length string="${main-class}" trim="true" length="0" />
</condition>

<copy file="manifest-template.mf" tofile="manifest-with-main-class.mf"/>
<replace
    file="manifest-with-main-class.mf"
    token="@main-class@"
    value="${manifest-file}"
/>

<jar manifest="${manifest-file}" ...>
   ...
</jar>

使用manifest-template.mf

Manifest-Version: 1.0
Created-By: ...
Built-By: ...
Main-Class: @main-class@

manifest-without-main-class.mf

Manifest-Version: 1.0
Created-By: ...
Built-By: ...

答案 1 :(得分:2)

您还可以选择使用“更新”更新您的清单。模式:

<ac:if>
    <length string="${module.dependencies}" trim="true" when="greater" length="0" />
    <then>
        <echo>Adding Dependencies (${module.dependencies}) to manifest file ${manifest-file}</echo>
        <manifest file="${manifest-file}" mode="update">
            <attribute name="Dependencies" value="${module.dependencies}" />
        </manifest>
    </then>
</ac:if>

这只会在填写时添加您需要的属性。

答案 2 :(得分:1)

一种选择是利用<macrodef>任务将任意元素传递给它的能力。

的build.xml

以下脚本使用第三方Ant-Contrib库。

<project name="ant-macrodef-with-optional-element" default="test" basedir=".">
    <taskdef resource="net/sf/antcontrib/antlib.xml" />

    <macrodef name="create-manifest">
        <attribute name="file"/>
        <attribute name="main-class"/>
        <sequential>
            <if>
                <length string="@{main-class}" length="0"/>
                <then>
                    <create-manifest-internal file="@{file}"/>
                </then>
                <else>
                    <create-manifest-internal file="@{file}">
                        <main-class-attribute>
                            <attribute name="Main-Class" value="@{main-class}"/>
                        </main-class-attribute>
                    </create-manifest-internal>
                </else>
            </if>
        </sequential>
    </macrodef>

    <macrodef name="create-manifest-internal">
        <attribute name="file"/>
        <element name="main-class-attribute" optional="yes" />
        <sequential>
            <manifest file="@{file}">
                <main-class-attribute/>
            </manifest>
        </sequential>
    </macrodef>

    <target name="test">
        <create-manifest file="manifest-1-out.txt" main-class="com.example.Main"/>
        <loadfile property="manifest-1-out-result" srcFile="manifest-1-out.txt"/>
        <echo>manifest-1-out.txt:</echo>
        <echo>${manifest-1-out-result}</echo>

        <create-manifest file="manifest-2-out.txt" main-class=""/>
        <loadfile property="manifest-2-out-result" srcFile="manifest-2-out.txt"/>
        <echo>manifest-2-out.txt:</echo>
        <echo>${manifest-2-out-result}</echo>
    </target>
</project>

输出

test:
     [echo] manifest-1-out.txt:
     [echo] Manifest-Version: 1.0
     [echo] Ant-Version: Apache Ant 1.8.2
     [echo] Created-By: 1.7.0_40-b43 (Oracle Corporation)
     [echo] Main-Class: com.example.Main
     [echo]
     [echo] manifest-2-out.txt:
     [echo] Manifest-Version: 1.0
     [echo] Ant-Version: Apache Ant 1.8.2
     [echo] Created-By: 1.7.0_40-b43 (Oracle Corporation)
     [echo]

这种方法的主要缺点是将值从调用者传递到外部宏定义然后传递到内部宏定义所需的属性重复。

答案 3 :(得分:0)

我的 Ant 技能不是很好,但我这样解决了。这有点像黑客,但它只使用一个jar任务。如果需要,它会输入Main-Class,否则会添加一个平淡的Comment条目。

<强>的build.xml

<project name="Builder">

   <target name="default">
       <build-me name="FooBar" main-class="foo.bar.Main"/>
       <build-me name="BarFoo" />
   </target>

   <macrodef name="build-me">
       <attribute name="name" />
       <attribute name="main-class" default="" />
       <sequential>
          <tstamp>
             <format property="now" pattern="E d MMM yyyy HH:mm:ss zzz" locale="en,UK"/>
          </tstamp>         

          <!-- Compile and other steps ommited -->

           <condition property="optional-main" value="Main-class" else="Comments">
              <and>
                 <not>
                    <equals arg1="" arg2="@{main-class}" />
                 </not>
             </and>
          </condition>
          <condition property="main-class" value="@{main-class}" else="no main class">
             <and>
                <not>
                   <equals arg1="" arg2="@{main-class}" />
                </not>
             </and>
          </condition>

          <jar destfile="@{name}.jar" basedir="build/@{name}">
             <manifest>
                <attribute name="Build-Date" value="${now}" />
                <attribute name="${optional-main}" value="${main-class}" />
            </manifest>
         </jar>
      </sequential>
   </macrodef>
</project>

结果:

<强> FooBar的

MANIFEST.MF

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Build-Date: Tue 2 Aug 2016 11:02:46 BST
Main-class: foo.bar.Main

BarFoo

MANIFEST.MF

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Build-Date: Tue 2 Aug 2016 11:02:46 BST
Comments: no main class