包含

自 Apache Ant 1.8.0 起

描述

将另一个构建文件包含到当前项目中。

注意 此任务严重依赖于 ProjectHelper 实现,并且本身不执行任何工作。如果您已配置 Ant 使用除 Ant 默认值以外的 ProjectHelper,则此任务可能有效也可能无效。

执行时,它将读取另一个 Ant 文件到同一个项目中,重写包含的目标 namedepends 列表。这与 Ant 常见问题解答中解释的实体包含 不同,因为目标名称以包含项目的 nameas 属性为前缀,并且不会像文件包含在包含文件中一样出现。

include 任务只能用作顶级任务。这意味着它不能在目标中使用。

还有两个与该任务相关的功能方面,而实体包含无法实现。

目标重写

包含文件中的任何目标都将重命名为 prefix.name,其中 name 是原始目标的名称,prefixas 属性的值或包含文件的 project 标签的 name 属性。

所有包含目标的 depends 属性都被重写,以便所有目标名称也都被添加前缀。这使得包含文件自包含。

注意,前缀会嵌套,因此如果一个构建文件包含一个前缀为 q 的文件,而包含的文件又包含另一个前缀为 b 的文件,那么最后一个构建文件的目标将以 a.b. 为前缀。

<import> 也对前缀有贡献,但前提是它们的 as 属性已指定。

特殊属性

包含文件被视为它们在主构建文件中存在的方式。这使得它易于理解,但它使得它们无法引用相对于其路径的文件和资源。因此,对于每个包含文件,Ant 添加一个包含包含构建文件路径的属性。使用此路径,包含的构建文件可以保留资源并能够相对于其位置引用它们。

因此,如果我包含一个名为 builddocsdocsbuild.xml 文件,我可以通过 ant.file.builddocs 获取其路径,类似于主构建文件的 ant.file 属性。

注意,builddocs 不是文件名,而是包含的 project 标签中存在的 name 属性。

如果包含的文件没有 name 属性,则不会设置 ant.file.projectname 属性。

如果您需要知道当前构建文件的源是文件还是 URL,您可以查询属性 ant.file.type.projectname(使用与上面相同的示例 ant.file.type.builddocs),它要么具有值 file,要么具有值 url

解析相对于包含文件的

假设您的主构建文件名为 including.xml,它包含一个构建文件 included.xml,该文件位于文件系统的任何位置,并且 included.xmlincluded.properties 中读取一组属性。

<!-- including.xml -->
<project name="including" basedir="." default="...">
  <include file="${path_to_included}/included.xml"/>
</project>

<!-- included.xml -->
<project name="included" basedir="." default="...">
  <property file="included.properties"/>
</project>

但是,此代码段将解析相对于 including.xmlbasedirincluded.properties,因为 included.xmlbasedir 被 Ant 忽略。使用 included.properties 的正确方法是

<!-- included.xml -->
<project name="included" basedir="." default="...">
  <dirname property="included.basedir" file="${ant.file.included}"/>
  <property file="${included.basedir}/included.properties"/>
</project>

如上所述,ant.file.included 存储定义名为 included 的项目的构建脚本的路径(简而言之,它存储 included.xml 的路径),并且 <dirname> 获取其目录。此技术还允许 included.xml 作为独立文件使用(无需包含在其他项目中)。

以上描述仅适用于实际从文件而不是从 URL 包含的包含文件。对于使用相对于包含文件的资源从 URL 包含的文件,您需要首先使用可以处理非文件资源的任务。要创建相对资源,您可以使用类似于以下内容的内容

<loadproperties>
  <url baseUrl="${ant.file.included}"
       relativePath="included.properties"/>
</loadproperties>

参数

属性 描述 必需
文件 要包含的文件。如果这是一个相对文件名,则文件名将相对于包含文件解析。注意,这与大多数其他 ant 文件属性不同,在其他 ant 文件属性中,相对文件相对于 ${basedir} 解析。 是或嵌套资源集合
可选 如果为 true,则如果文件不存在,则不会停止构建。 否;默认值为 false
作为 指定添加到目标名称之前的前缀。 是,如果包含文件的 project 标签没有指定 name 属性(否则将作为默认值使用)
prefixSeparator 指定用于前缀和目标名称之间的分隔符。 否;默认为 .

作为嵌套元素指定的参数

任何 资源 或资源集合

将包含指定的资源。

示例

<include file="../common-targets.xml"/>

包含来自父目录中的 common-targets.xml 文件的目标。

<include file="${deploy-platform}.xml"/>

包含由属性 deploy-platform 定义的项目

<include>
  <javaresource name="common/targets.xml">
    <classpath location="common.jar"/>
  </javaresource>
</include>

包含来自 common.jar 文件中的 common 目录内的 targets.xml 文件的目标。

<import> 与 <include> 有什么区别?

简而言之:如果您打算覆盖目标,请使用 import,否则请使用 include

当使用 import 时,导入的目标最多可以使用两个名称:没有前缀的“正常”名称,以及可能带前缀的名称(as 属性的值或导入项目的 name 属性,如果有)。

当使用 include 时,包含的目标只能以带前缀的形式使用。

当使用 import 时,导入目标的 depends 属性保持不变,即它使用“正常”名称,并允许您覆盖依赖列表中的目标。

当使用 include 时,包含的目标不能被覆盖,并且它们的 depends 属性被重写,以便使用带前缀的名称。这允许包含文件编写者控制作为依赖项的一部分调用的目标。

可以使用不同的前缀多次 include 同一个文件;不能多次 import 同一个文件。

示例

nested.xml 应为

<project>
  <target name="setUp">
    <property name="prop" value="in nested"/>
  </target>

  <target name="echo" depends="setUp">
    <echo>prop has the value ${prop}</echo>
  </target>
</project>

当使用 import 时,如

<project default="test">
  <target name="setUp">
    <property name="prop" value="in importing"/>
  </target>

  <import file="nested.xml" as="nested"/>

  <target name="test" depends="nested.echo"/>
</project>

运行构建文件将发出

setUp:

nested.echo:
     [echo] prop has the value in importing

test:

当使用 include 时,如

<project default="test">
  <target name="setUp">
    <property name="prop" value="in importing"/>
  </target>

  <include file="nested.xml" as="nested"/>

  <target name="test" depends="nested.echo"/>
</project>

运行目标构建文件将发出

nested.setUp:

nested.echo:
     [echo] prop has the value in nested

test:

并且包含构建文件中将不存在名为 echo 的目标。