如何在 build.xml 文件中创建动态 path/fileset 元素或其他随机 XML 节点

how to create dynamic path/fileset elements or other random XML nodes in a build.xml file

我有一个项目对其他项目(相同代码库)有许多编译时依赖项。 所以编译类路径的定义有点像下面这样:

<path id = "compile.classpath">
  <fileset dir="${dependency-a.dist.dir}">
    <include name ="*.jar"/>
  </fileset>
  <fileset dir="${dependency-b.dist.dir}">
    <include name ="*.jar"/>
  </fileset>
  <fileset dir="${dependency-c.dist.dir}">
    <include name ="*.jar"/>
  </fileset>
  <fileset dir="${dependency-d.dist.dir}">
    <include name ="*.jar"/>
  </fileset>
</path>

此外,您可以为依赖项等映射相应的 build 目标。 为了减少重复,我需要以某种方式动态生成这些结构。

我认为捕获这些依赖项的一种 Ant 友好方法可能是创建一个 deps 目录并将符号链接添加到我项目的所有编译时依赖项。

所以问题是:是否有 Ant 方法来编写 macrodef 或自定义 Ant 任务来扫描该目录(或者,读取配置文件)并展开 into/generate自动生成必要的文件集/构建目标,实际上在运行时更改 build.xml 文件的 XML 节点?我正在寻找一种通用的 Ant 方法来做到这一点(如果存在的话),这样我就不必使用更具破坏性的方法来从其他配置中完整地生成 build.xml 文件。我不是在问如何使用 subant 等,因为我想知道在运行时是否存在 extending/enriching Ant 构建文件的更全面的功能,该功能也适用于不涉及构建依赖项的其他情况。

编写构建路径的任务非常简单,但是一旦构建文件被解析,Ant 目标就固定了。 Ant 构建目标的有向图,然后执行它们。

可以通过任何目标本身之外的任务添加新目标。 include就是这样的任务。可以通过自定义任务生成包含路径和目标的构建文件片段,稍后将其包含在内。不幸的是 include 不允许您将其嵌入 macrodef 因此这两个步骤必须成对出现。

当然,您可以使用 Ant 的 API 而不是 include 来添加路径和目标。您将在收到的 Project 实例上使用 getReference 获取现有的 Path,并将您的文件集添加到其中。全新的数据类型使用addReferenceaddTarget用于目标。

您是否考虑过使用 ivy?它是一个依赖项管理器,提供一组可用于控制类路径的 ANT 任务,但它也可以从托管存储库(如 Maven)下载 jar。

以下答案可以让您了解常春藤的使用方式:

  • sample example which explain how to use filesystem resolver
  • How to avoid copying dependencies with Ivy

Ivy 提供了更强大的解决方案,因为它还可以防止同一 jar 的版本冲突。例如,几个依赖项都包含一个像 log4j 这样的通用 jar 的副本。

总而言之,ivy 乍一看可能很复杂,但我可以向您保证,它正在解决一个复杂的问题。