`
topzhujia
  • 浏览: 54274 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Ant 基础

    博客分类:
  • JAVA
阅读更多

Ant 生成文件剖析

Ant 没有定义它自己的自定义语法;相反,它的生成文件是用 XML 编写的。存在一组 Ant 能够理解的预定义 XML 元素,而且就像您将在下一节中看到的一样,还可以定义新的元素来扩展 Ant 的功能。每个生成文件由单个 project 元素组成,该元素又包含一个或多个 target 元素。一个目标(target)是生成过程中已定义的一个步骤,它执行任意数量的操作,比如编译一组源文件。这些操作本身是由其他专用任务标签执行的,我们将在后面看到这一点。然后这些任务将根据需要被分组到各个 target 元素中。一次生成过程所必需的所有操作可以放入单个 target 元素中,但是那样会降低灵活性。将那些操作划分为逻辑生成步骤,每个步骤包含在它自己的 target 元素中,这样通常更为可取。这样可以执行整体生成过程的单独部分,却不一定要执行其他部分。例如,通过仅调用某些目标,您可以编译项目的源代码,却不必创建可安装的项目映像。

顶级 project 元素需要包含一个 default 属性,如果在 Ant 被调用时没有指定目标,这个属性将指定要执行的目标。然后需要使用 target 元素来定义该目标本身。下面是一个最基本的生成文件:

<?xml version="1.0"?>

<project default="init">

<target name="init">

</target>

</project>

注意这是一个结构良好的 XML 文档,其中一个 XML 声明指定了所使用的 XML 的版本(这不是当前的 Ant 所必需的,但是这样做是一个好习惯),而且每个元素都正确地关闭了。一次性打开和关闭一个元素也是可以做到的。因此,与其像上面那样对 target 元素使用单独的起始和结束标签,

我们可以将它写为如下形式:

<target name="init"/>

当元素没有包含任何内容时,更简练的形式会更清晰。

添加描述:

我们在前一小节中看到的生成文件是优雅简练的,但它并没有包含多少关于正在生成的实际项目的信息。可以通过许多方式来使它更具描述性,同时无需改变其功能。下面是一个例子:

<?xml version="1.0"?>

<project default="init" name="Project Argon">

<description>

A simple project introducing the use of descriptive tags in Ant build files.

</description>

<!-- XML comments can also be used -->

<target name="init" description="Initialize Argon database">

<!-- perform initialization steps here -->

</target>

</project>

可以看出,XML 注释可以使用在整个生成文件中以提高清晰性。而且,Ant 定义了它自己的description 元素和 description 属性,它们可用于提供更结构化的注释。

属性

Ant 中的属性 类似编程语言中的变量,它们都具有名称和值。然而与通常的变量不同,一经设置,Ant 中的属性就不可更改;它们是不可变的,就像 Java 语言中的 String 对象。这起初看来似乎很有限制性,但这样是为了遵循 Ant 的简单原则:毕竟,它是一个生成工具,而不是一种编程语言。如果尝试给某个现有属性赋予一个新的值,这不会被看作是一个错误,但是该属性仍然会保留其现有值。(我们将会看到,这种行为是有用的。)

基于元素的描述性名称和到目前为止所见到的属性,在 Ant 中用于设置属性的机制看起来如下就没有什么奇怪了:

<property name="metal" value="beryllium"/>

为了在生成文件的其他部分引用这个属性,您会使用以下语法:

${metal}

例如,为了使用这样一个值,它是另一个属性的值的组成部分,您会将标签写为下面这样:

<property name="metal-database" value="${metal}.db"/>

Ant 中有许多预定义的属性。首先,Java 环境设置用于运行 Ant 的所有系统属性,均可作为 Ant 属性使用,比如 ${user.home} 。除了这些属性之外,Ant 还定义了它自己的一小组属性,包括${ant.version},这个属性包含 Ant 的版本;以及 ${basedir},这个属性是项目目录的绝对路径(由包含生成文件的目录所定义,或者由 project 元素的可选 basedir 属性所定义)。

属性经常用于引用文件系统上的文件或目录,但是对于使用不同路径分隔符(例如,/ \)的平台来说,这样可能在跨越不同平台时导致问题。Ant location 属性专门设计用于以平台无关的方式包含文件系统路径。您会像下面这样使用 location 来代替value

<property name="database-file" location="archive/databases/${metal}.db"/>

用于 location 属性的路径分隔字符将被转换为当前平台的正确格式;而且由于文件名是相对的,它被认为是相对于项目的基目录。我们同样可以容易地写为下面这样:

<property name="database-file" location="archive\databases\${metal}.db"/>

这个标签的两个版本都会在不同的平台具有相同的行为。如果可移植性是必需的,唯一要避免的内容就是文件名中的 DOS 风格的驱动器号。在可能的地方使用相对路径名称而不是绝对路径名称,这样还会更加灵活。

定义依赖关系

生成一个项目一般需要许多步骤 —— 例如首先要编译源代码,然后将它打包为 Java 归档文件(Java Archive FileJAR)。这其中许多步骤都具有清楚定义的顺序 —— 例如,在编译器从源代码生成类文件之前,您不能打包类文件。与顺序指定 target 所不同的是,Ant 采用一种更灵活的方法来定义依赖关系 ,就像 make 和类似的生成工具所做的那样。每个目标的定义依据的是在它在能够执行之前必须完成的其他所有目标。这是使用 target 元素的 depends 属性来实现的。例如:

<target name="init"/>

<target name="preprocess" depends="init"/>

<target name="compile" depends="init,preprocess"/>

<target name="package" depends="compile"/>

这种方法允许您执行项目任何阶段的生成过程;Ant 会首先执行已定义的先决阶段。在上面的例子中,如果让 Ant 完成 compile 步骤,它将判断出需要首先执行 init preprocess 这两个目标。

init 目标不依赖其他任何目标,因此它将首先被执行。然后 Ant 检查preprocess target,发现它依赖 init 目标;由于已经执行了后者,Ant 不会再次执行它,因而开始执行 preprocess 目标。最后可以执行 compile 任务本身。注意目标出现在生成文件中的顺序并不重要:执行顺序是由depends 属性唯一确定的。

从命令行运行 Ant

从命令提示符调用 Ant 可以简单得只需键入单独的 ant。如果您这样做,Ant 将使用默认的生成文件;该生成文件中指定的默认目标就是 Ant 尝试要生成的目标。还可以指定许多命令行选项,后面跟着任意数量的生成目标,Ant 将按顺序生成这其中的每个目标,并在此过程中解决所有依赖关系。是从命令行执行的 Ant 生成任务的一些典型输出:

Buildfile: build.xml

init:

[echo] ant version: Apache Ant version 1.7.1 compiled on September 8 2010

[mkdir] Created dir: /home/zhujia/Developer/workspace/I18N_ANT/bin

[mkdir] Created dir: /home/zhujia/Developer/workspace/I18N_ANT/dest

build:

[javac] Compiling 1 source file to /home/zhujia/Developer/workspace/I18N_ANT/bin

dist:

[jar] Building jar: /home/zhujia/Developer/workspace/I18N_ANT/dest/I18N-20101005.jar

[jar] Building jar: /home/zhujia/Developer/workspace/I18N_ANT/dest/I18N-src-20101005.jar

BUILD SUCCESSFUL

Total time: 1 second

命令行选项

就像 make 工具默认情况下寻找一个名为 makefile 的生成文件一样,Ant 寻找一个名为build.xml 的文件。因此,如果您的生成文件使用这个名称,就不需要在命令行指定它。当然,有时使用具有其他名称的生成文件更方便,在那样的情况下,您需要对 Ant 使用 -buildfile <file>参数(-f <file> 是其简写形式)。

另一个有用的选项是 -D,它用于设置随后可以在生成文件中使用的属性。这对于配置您想要以某种方式开始的生成过程是非常有用的。例如,为了将 name 属性设置为某个特定的值,您会使用一个类似下面这样的选项:

-Dmetal=beryllium

这个功能可用于覆盖生成文件中的初始属性设置。正如前面指出过的,属性的值一经设置就不能改变。-D 标志在读取生成文件中的任何信息之前设置某个属性;由于生成文件中的指派落在这个初始指派之后,因此它不会改变其值。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics