子构建任务

自 Apache Ant 1.6 起

描述

调用所有定义的子构建的给定目标。这是 Ant 用于批量项目执行的扩展。此任务不能在target之外使用,如果它调用了它所属的同一个构建文件。

subant 在内部使用 ant,因此 ant 的手册页 中提到的许多内容也适用于此。

与目录一起使用

subant 可以与目录集一起使用,以从不同的目录执行构建。提供了 2 种不同的选项

参数

属性 描述 类型 必需
antfile 构建文件名,与目录一起使用。 字符串 否;默认为 build.xml,如果设置了 genericantfile,则忽略
buildpath 设置用于查找子项目的构建路径。 路径
buildpathref 要使用的构建路径,通过引用。 引用
failonerror 设置是否在错误时使用构建异常失败,或者继续。 布尔值
genericantfile 构建文件路径,与目录一起使用。
使用 genericantfile,以便使用不同的 basedir 运行同一个构建文件。
如果设置了此属性,则忽略 antfile
文件
inheritall 对应于 <ant>inheritall 属性,但在此任务中默认为 false 布尔值
inheritrefs 对应于 <ant>inheritrefs 属性。 布尔值
output 对应于 <ant>output 属性。 字符串
target   字符串
verbose 启用/禁用显示每个子构建路径何时进入/退出时的日志消息。 布尔值 否;默认值为 false

作为嵌套元素的参数

任何基于文件系统的 资源集合

这包括 <fileset><dirset><filelist>,它们是 Ant 1.7 之前支持的嵌套资源集合。

dirset (org.apache.tools.ant.types.DirSet)

将目录集添加到隐式构建路径。

请注意,目录将以不确定的顺序添加到构建路径,因此如果顺序很重要,则应使用文件列表!

filelist (org.apache.tools.ant.types.FileList)

将有序文件列表添加到隐式构建路径。

请注意,与文件和目录集相反,文件列表可以引用不存在的文件或目录!

fileset (org.apache.tools.ant.types.FileSet)

将文件集添加到隐式构建路径。

请注意,目录将以不确定的顺序添加到构建路径,因此如果顺序很重要,则应使用文件列表!

property (org.apache.tools.ant.taskdefs.Property)

对应于 <ant> 的嵌套 <property> 元素。

当多个嵌套的 <property> 元素设置相同名称的属性时,最后声明的元素将获胜。这是出于向后兼容性的原因,即使它与构建文件中 <property> 任务的行为方式不同。

propertyset (org.apache.tools.ant.types.PropertySet)

对应于 <ant> 的嵌套 <propertyset> 元素。

buildpath (org.apache.tools.ant.types.Path)

创建一个嵌套构建路径,并将其添加到隐式构建路径。

buildpathelement (org.apache.tools.ant.types.Path.PathElement)

创建一个嵌套的 <buildpathelement>,并将其添加到隐式构建路径。

target (org.apache.tools.ant.taskdefs.Ant.TargetElement)

自 Ant 1.7 起.

你可以使用嵌套的 <target> 元素指定多个目标,而不是使用 target 属性。这些将被执行,就好像 Ant 被调用了一个目标,该目标的依赖项是如此指定的目标,按指定的顺序。

属性 描述 必需
name 调用的目标的名称。

示例

此代码段构建文件将在项目目录的每个子目录中运行 ant,其中可以找到名为 build.xml 的文件。属性 build.dir 将在 subant 调用的 Ant 项目中具有值 subant1.build

<project name="subant" default="subant1">
    <property name="build.dir" value="subant.build"/>
    <target name="subant1">
        <subant target="">
            <property name="build.dir" value="subant1.build"/>
            <property name="not.overloaded" value="not.overloaded"/>
            <fileset dir="." includes="*/build.xml"/>
        </subant>
    </target>
</project>

此代码段构建文件将在项目目录的每个子目录中运行 ant,其中可以找到名为 build.xml 的文件。所有名称以 foo 开头的属性都将被传递,它们的名称将更改为以 bar 开头。

<subant target="">
    <propertyset>
        <propertyref prefix="toplevel"/>
        <mapper type="glob" from="foo*" to="bar*"/>
    </propertyset>
    <fileset dir="." includes="*/build.xml"/>
</subant>

假设项目目录的子目录名为 projects1projects2projects3,此代码段将执行 /opt/project/build1.xmlcompile 目标,将 basedir 设置为 projects1projects2projects3

<subant target="compile" genericantfile="/opt/project/build1.xml">
    <dirset dir="." includes="projects*"/>
</subant>

现在是一个更复杂但有用的场景。假设我们有这样的目录结构

root
  |  common.xml
  |  build.xml
  |
  +-- modules
        +-- modA
        |     +-- src
        +-- modB
              +-- src

common.xml:
<project> <property name="src.dir" value="src"/> <property name="build.dir" value="build"/> <property name="classes.dir" value="${build.dir}/classes"/> <target name="compile"> <mkdir dir="${classes.dir}"/> <javac srcdir="${src.dir}" destdir="${classes.dir}"/> </target> <!-- more targets --> </project> build.xml:
<project> <macrodef name="iterate"> <attribute name="target"/> <sequential> <subant target="@{target}"> <fileset dir="modules" includes="*/build.xml"/> </subant> </sequential> </macrodef> <target name="compile"> <iterate target="compile"/> </target> <!-- more targets --> </project> modules/modA/build.xml:
<project name="modA"> <import file="../../common.xml"/> </project>

这导致模块中的构建文件非常小,可维护的构建文件 (common.xml) 和清晰的项目结构。此外,根构建文件能够对所有模块运行整个构建。

此任务对每个子项目执行 clean build

<subant failonerror="false">
    <fileset dir="." includes="**/build.xml" excludes="build.xml"/>
    <target name="clean"/>
    <target name="build"/>
</subant>

提示:因为构建文件是纯 XML,所以你可以使用 XSLT 转换从公共构建文件生成主构建文件

<xslt in="common.xml"
      out="master.xml"
      style="${ant.home}/etc/common2master.xsl"/>