Ant笔记(二)Ant使用

本文为翻译官方文档而来,不当之处请指正。

Ant的构建文件写在xml文件当中,每一个构建文件包含一个project和至少一个(默认的)target。Targets包含task elements。每一个task element都有一个id属性,可以提供给此值的引用。当然id属性是唯一的。

Project

一个project有三个属性

属性 描述 必须的
name 项目名称
default 如果没有任何target的话,需要这个默认的target 否,自从蚂蚁1.6.0,每个项目包括一个隐含的目标,包含所有的顶级任务和/或类型。这一目标将永远作为项目的初始化部分执行,即使当蚂蚁运行时有projecthelp选项。
basedir 用于指定基路径的位置。该属性没有指定时,使用 Ant 的构件文件的父目录作为基准目录
<project name="XXX" default="xxxx" basedir="."></project>

Target

属性 描述 必须的
name Target名
depends 依赖
if 某property必须设置了才可以运行这个target或者property扩展属性评估是true
unless 某property必须没有设置才可以运行这个target或者property扩展属性评估是false
description Target功能的描述
extensionOf 当这个target添加到extension-point的依赖列表中,1.8.0开始
onMissingExtensionPoint 如果这个target视图扩展丢失的extension-point该怎么办

命名name

可以是任何xml文件中合法的string,例如空字符串””,逗号”,”和空格” ”,尽量避免用这些字符串命名你的target,ant将来的版本可能不会支持因为不同的IDE中对这些字串的解释并不相同。

以连字符开始是不合法的,例如”-restart”,因为他们不能被命令行直接命令。因为ant会默认连字符开始的是它自己的而不是一个target。

依赖depends

一个target可以依赖其他的targets.例如,你有一个编译的target,还有一个创建可分配的target,你只能在你已经编译的时候才能构建一个可分配的,因为这个可分配的target依赖编译target。Ant可以解决这些依赖关系。

依赖只影响顺序,而不规定是否执行

需要注意的是,ant依赖属性只指定了执行targets的顺序,如果依赖的目标不需要执行,则不影响指定依赖关系的目标是否执行,即虽然我只能在你后面执行,如果你不执行,那么我就直接执行。

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

如果因为某些原因clean这个target不会执行,那么init这个target依旧执行

基准的依赖最先执行

<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
D的时候,执行的顺序是A --> B --> C --> D
为什么呢?因为D依赖C,C又依赖B,B又依赖A,所以顺序是这样的。
<target name="A"/>
<target name="B"/>
<target name="C"/>
<target name="D" depends="C,B,A"/>
这样写的话,顺序才是C,B,A,D

可以控制target是否执行-if / unless

<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless="module-A-present"/>

第一句话意思是如果module-A-present这个属性被设置了,我就执行build-module-A这个target
第二句话的意思是如果module-A-present这个属性没有被设置,我就执行build-own-fake-module-A这个target

只根据property是否存在控制,并不规定值

需要注意的是只要设置了这个属性就被控制,而没有规定其中设置什么值,例如

<property name=” module-A-present”/>

即使没有设置什么值,我也会运行第一个target,也就是build-module-A

如果想要根据值来控制,可以运用if/unless attributes 属性扩展
1.7.1前不支持,即使这个property中没有设置value或是空字串,1.8.0ant支持属性扩展。即true,on,yes(相反值:false,off,no)可以让他运行(不运行)

<target name="build-module-A" if="{module-A-present}"/>

只可以有一个property

If/unless中只可以有一个property

不影响他们一来的target是否运行

If/unless只控制他们自己,其实他们的depends在他们之前都已经运行完毕了。

Extension-Pints

和target类似的是他们拥有一个name和依赖列表,可以从命令行直接执行,他们在构建过程中代表着一种状态。
和target不同的是他们不包含任何tasks,他们主要的目的就是收集那些在他们的依赖列表中为所需状态做出贡献的targets 。

Targets可以通过extensionOf属性把他们自己加到extension-points的依赖列表中,如果多个target写在一起,相对位置没有意义。

扩展点的主要用途是充当要导入
(Import详见http://ant.apache.org/manual/Tasks/import.html)的构建文件的扩展点。在导入的文件中,扩展点定义必须到达的状态,并且来自其他构建文件的目标可以加入所述扩展点的依赖列表,以便对该状态作出贡献。
例如你要导入的构建文件可能需要编码:

<target name="create-directory-layout">
   ...
</target>
<extension-point name="ready-to-compile"
              depends="create-directory-layout"/>
<target name="compile" depends="ready-to-compile">
   ...
</target>

create-directory-layout --> 'empty slot' --> compile

需要在编译之前生成一些源代码,然后在主构建文件中使用类似于

<target name="generate-sources"
        extensionOf="ready-to-compile">
   ...
</target>
create-directory-layout --> generate-sources  --> compile

这样可以确保generate-sources这个target在compile target之前执行。

不要使用依赖列表,如果使用了依赖列表,generate-sources这个target只能通过它自己的依赖属性显示地依赖他们。

Task

一个task是一段可以执行的代码。一个task可以有很多属性attribute,属性attribute的值可以包含property的引用。在task执行前,这些相关的property就可以被解决。Task的id属性用来标识这个task

如果“任务”还没有运行,那么它没有配置(即,没有属性已设置),如果是要配置后,任何你所做的实例可以被改写。

Ant有一系列内置的task(详见:http://ant.apache.org/manual/tasklist.html),想写自己的task也很容易(详见:http://ant.apache.org/manual/develop.html#writingowntask

Properties特性

属性是自定义构建过程的一种重要方式,或者只为在构建文件中重复使用的字符串提供快捷方式。在最简单的表单中,属性在生成文件中定义(例如,属性任务),也可以在Ant之外设置。属性有名称和值;名称区分大小写。属性可用于任务属性值或支持它们的任务的嵌套文本中。这是通过将属性名放在属性值中的“”和“}”之间完成的。例如,如果有一个“builddir”属性的值“建立”,那么这可能是用于属性是这样的: { builddir } /classes。这在运行时作为buld/classes。

<property name="classes.dir" value="${webcontent.webinf.dir}/classes" description="原项目默认编译位置"/>

<!--清理目标位置 --> 
<target name="clean"> 
<delete dir="${classes.dir}" />
</target>

从ant1.8.0开始属性扩展比简单的键值对变得更加强大
许多task都可以设置properties,最常用的就是property 这个task,此外,属性可以通过命令行参数或来自Ant外部的类似机制定义。

它只表示字符串数据的名-值对。除了字符串以外,任何其他数据类型均不能与特性相关联。

优先级

Ant命令行声明的特性总是比其他位置定义的特性有更高的优先级。在此之后,ant会根据其何时首次发现所声明的特性来确定优先级。

顺序性

<property name=”property.onevalue=”${property.two}:one”>
<property name=”property.twovalue=”two”>

Property.one的值时什么呢,由于顺序,它的值是${property.two}:one而不是two:one

全局作用域

<target name=”target1”> 
  <property name=”prop2” value=”two”>
</target>

一旦构建了property prop2那么剩余的构建文件部分都可以使用prop2特性。

内置特性

系统特性

Ant提供对所有系统属性的访问,就像它们是使用< property >任务定义的一样。例如,${os.name }操作系统的名称。系统属性详见:https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getProperties%28%29

内置特性列表

basedir
作为的属性,它表示该项目的绝对路径
ant.file
构建文件的绝对路径
ant.version
Ant的版本
ant.project.name
目前运行的项目名称,的属性
ant.project.default-target
目前运行的项目默认target,的属性
ant.project.invoked-targets
当调用当前的项目时,命令行或IDE指定的以逗号分隔的targets列表
当第一个目标被执行时,此属性将被正确设置。
如果您在隐式目标中使用它(直接在“项目”标签下)列表将为空。
如果没有指定目标,将包含该项目的默认目标。
ant.java.version
JVM版本,目前它持有, “9”, “1.8”,”1.7”, “1.6”, “1.5”, “1.4”, “1.3” “1.2”.
ant.core.lib
ant.jar文件的绝对路径
还有另一个属性,但这是由Launcher 的脚本,因此也许不在IDE:
ant.home
ant的home目录
下面的属性只设置如果蚂蚁开始通过发射类(这意味着它可能没有设置在IDE的):
ant.library.dir
下载的ant的jar包的目录,大多数情况下是ANT_HOME/lib

路径形式

类似路径的结构
您可以指定路径和路径的类型引用使用“:”和“;”分隔符。Ant将将分隔符转换为当前操作系统的正确字符。

Property特性定义允许我们避免在构建文件中将目录名硬编码。这些路径通常都是相对于<project>元素所指定的基目录

<project name="XXX" default="xxxx" basedir=".">
  <property name=”src.dir” value=”src”>
</project>

在需要指定路径值的地方,可以使用嵌套元素。这是一般形式的:

<classpath>
    <pathelement path="${classpath}"/>
    <pathelement location="lib/helper.jar"/>
</classpath>

classpath属性指定与项目的基目录(或绝对文件名)相关的单个文件或目录,而path属性接受冒号或分号分隔的location列表。path属性意在与预定义路径一起使用——在任何其他情况下,都应该首选具有location属性的多个元素

从1.8.2开始location属性可以以通配结束为了java6 介绍的classpaths通配符使用。Java6以前的jvm使用时,ant将不会解释这个通配符,即path不能正常工作(以通配符结束)。
作为一种快捷方式,<classpath>标签支持path和自己的location属性,所以:

<classpath>
      <pathelement path="${classpath}"/>
    </classpath>

可以被缩写为:

<classpath path="${classpath}"/>

此外,一个或多个资源集合可以指定为嵌套元素(这些必须仅包含文件类型资源)。此外,应该指出的是,虽然资源集合的顺序处理遇到的,一定的资源的集合类型,如fileset,dirset和files方面的顺序是不确定的。

<classpath>
      <pathelement path="${classpath}"/>
      <fileset dir="lib">
        <include name="**/*.jar"/>
      </fileset>
      <pathelement location="classes"/>
      <dirset dir="${build.dir}">
        <include name="apps/**/classes"/>
        <exclude name="apps/**/*Test*"/>
      </dirset>
      <filelist refid="third-party_jars"/>
    </classpath>

如果您想要为几个任务使用相同的路径结构,您可以在与目标相同的级别上使用一个元素来定义它们,并通过它们的id属性引用它们.

<project ... >
  <target ... >
    <rmic ...>
      <classpath>
        <pathelement location="lib/"/>
        <pathelement path="${java.class.path}/"/>
        <pathelement path="${additional.path}"/>
      </classpath>
    </rmic>
  </target>

  <target ... >
    <javac ...>
      <classpath>
        <pathelement location="lib/"/>
        <pathelement path="${java.class.path}/"/>
        <pathelement path="${additional.path}"/>
      </classpath>
    </javac>
  </target>
</project>

可以这样简写:

<project ... >
  <path id="project.class.path">
    <pathelement location="lib/"/>
    <pathelement path="${java.class.path}/"/>
    <pathelement path="${additional.path}"/>
  </path>

  <target ... >
    <rmic ...>
      <classpath refid="project.class.path"/>
    </rmic>
  </target>

  <target ... >
    <javac ...>
      <classpath refid="project.class.path"/>
    </javac>
  </target>
</project>

默认情况下,一个类似路径的结构将在使用时重新评估所有嵌套的资源集合,这可能导致对文件系统进行不必要的重新扫描。因为蚂蚁1.8.0路径有一个可选的缓存属性,如果设置为true,该路径实例只会扫描其嵌套资源集合一次,假设它不会改变在建立了(缓存默认仍然是错误的)。即使只在单个任务中使用路径,如果使用复杂的嵌套结构,则可以提高整体性能,将缓存设置为true。

一个类似路径的结构可以通过嵌套的<路径>元素包括对另一个路径结构(路径本身就是资源集合)的引用:

<path id="base.path">
      <pathelement path="${classpath}"/>
      <fileset dir="lib">
        <include name="**/*.jar"/>
      </fileset>
      <pathelement location="classes"/>
    </path>

    <path id="tests.path" cache="true">
      <path refid="base.path"/>
      <pathelement location="testclasses"/>
    </path>

前面提到的<路径>快捷方式也适用于<路径>。例如:

<path id="base.path">
      <pathelement path="${classpath}"/>
    </path>

可以简写为:

 <path id="base.path" path="${classpath}"/>

Path快捷方式

Ant1.6中path增加了一个快捷方式
${toString:pathreference}

<path id="lib.path.ref">
    <fileset dir="lib" includes="*.jar"/>
  </path>
  <javac srcdir="src" destdir="classes">
    <compilerarg arg="-Xbootclasspath/p:${toString:lib.path.ref}"/>
  </javac>

datatype

一类表示复杂数据集合的元素,例如fileset和path
数据元素data element这个词包含了特性property和datatype

比如:

<property file=”user.properties”>

可表示在当前目录下找user.properties文件
有的时候property来表示文件路径非常麻烦:

<property name=”classpath” value=”${lib.dir}/j2ee.jar:${lib.dir}/activation.jar:${lib.dir}/servlet.jar:${lib.dir}/jasper.jar”>

而且在这个库中增加和删除jar都意味着你必须对此路径字符串做相应的增加和删除
这个时候你使用datatype就是非常好的办法:

<path id=”classpath”>
  <fileset  dir=”${lib.dir}”>
     <include name=”j2ee.jar”/>
     <include name=”activation.jar”/>
     <include name=”servlet.jar”/></fileset>
</path>

当然jar都在同一个目录下,使用通配符指定一个模式(而property却不可以指定模式)
<path id=”classpath”>
   <fileset dir=”${lib.dir}”>
      <include name=”**/*.jar”/>
  </fileset>
</path>

类型

Fileset只是可用DataType中的一种,以下列出其他可用的DataType:

argument

对于由一个ant构建文件调用的程序,向其传递命令行参数

environment

对于由一个ant构建文件调用的外部命令或程序,指定向其传递的环境变量

filelist

定义一个文件的命名列表,这些文件无需确实存在

fileset

定义一个文件的命名列表,这些文件必须确实存在

patternset

将一组模式分组在一起

filterset

将一组过滤分组在一起

path

以某种在不同操作系统间可移植的方式指定路径

mapper

定义一组输入文件和一组输出文件间的复杂关系。

简易命令行参考

语法:ant [option [option…]] [target[target…]]

ant -help可查出所有命令行命令
我们从包括build.xml文件的目录键入以下命令:
ant
Ant将打开一个默认的构建文件,即build.xml并执行此构建文件的默认目标(即project的default属性)(如果默认目标有依赖目标就会先去执行依赖目标再执行默认目标;如果默认目标不存在会返回一个错误)

指定构建文件名
ant -buildfile proj.xml

执行指定的target
ant -buildfile proj.xml clean

关于这个工程的构建详情
ant -projecthelp

Buildfile:build.xml
Default target:
Compile Compiles all sources code

Main targets:
All cleans,compiles,then builds the jar file
Clean removes all generated files
Compile compiles all source codes

Substargets:
Prepare

BUILD SUCCESSFUL
Total time:2 seconds

这个工程的帮助详情,其中targets被分为主目标和子目标,是根据有无描述descrption来区分的,但是执行的时候并无区别。在此只是为了显示。
All cleans,compiles,then builds the jar file
右侧的为all这个target的descrption属性

猜你喜欢

转载自blog.csdn.net/cc907566076/article/details/78604487
ANT