|
| 1 | +--- |
| 2 | +title: Ant 简易教程 |
| 3 | +date: 2015-04-19 |
| 4 | +categories: |
| 5 | +- javatool |
| 6 | +tags: |
| 7 | +- java |
| 8 | +- tool |
| 9 | +- build |
| 10 | +--- |
| 11 | + |
| 12 | +## 前言 |
| 13 | + |
| 14 | +`Apache Ant` 是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发。由Apache软件基金会所提供。 |
| 15 | + |
| 16 | +Ant是纯Java语言编写的,所以具有很好的跨平台性。 |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | +## 下载和安装 |
| 21 | + |
| 22 | +### 下载 |
| 23 | + |
| 24 | +ant的官方下载地址:http://ant.apache.org/bindownload.cgi |
| 25 | + |
| 26 | +进入页面后,在下图的红色方框中可以下载最新版本。笔者下载的版本是 **apache-ant-1.9.4。** |
| 27 | + |
| 28 | + |
| 29 | + |
| 30 | +### 配置环境变量 |
| 31 | + |
| 32 | +配置环境变量(我的电脑 -> 属性 -> 高级 -> 环境变量)。 |
| 33 | + |
| 34 | +设置ant环境变量: |
| 35 | + |
| 36 | +**ANT_HOME** C:/ apache-ant-1.9.4 |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +**path ** C:/ apache-ant-1.9.4/bin |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +**classpath** C:/apache-ant-1.9.4/lib |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +### 验证 |
| 49 | + |
| 50 | +点击 开始 -> 运行 -> 输入cmd |
| 51 | + |
| 52 | +**执行构建文件** |
| 53 | + |
| 54 | +输入如下命令:**ant** |
| 55 | + |
| 56 | +如果出现如下内容,说明安装成功: |
| 57 | + |
| 58 | +> Buildfile: build.xml does not exist! |
| 59 | +> Build failed |
| 60 | +
|
| 61 | +注意:因为ant默认运行build.xml文件,这个文件需要我们创建。 |
| 62 | + |
| 63 | +如果不想命名为build.xml,运行时可以使用 **ant -buildfile test.xml** 命令指明要运行的构建文件。 |
| 64 | + |
| 65 | +**查看版本信息** |
| 66 | + |
| 67 | +输入 **ant -version**,可以查看版本信息。 |
| 68 | + |
| 69 | + |
| 70 | + |
| 71 | +但如果出现 'ant' 不是内部或外部命令,也不是可运行的程序或批处理文件,说明安装失败:(可以重复前述步骤,直至安装成功。) |
| 72 | + |
| 73 | +## 例子 |
| 74 | + |
| 75 | +在安装和配置成功后,我们就可以使用ant了。 |
| 76 | + |
| 77 | +为了让读者对ant有一个直观的认识,首先以Ant官方手册上的一个简单例子做一个说明。 |
| 78 | + |
| 79 | +以下是一个build.xml文件的内容: |
| 80 | + |
| 81 | +```xml |
| 82 | +<project name="MyProject" default="dist" basedir="."> |
| 83 | + <description> |
| 84 | + simple example build file |
| 85 | + </description> |
| 86 | + <!-- set global properties for this build --> |
| 87 | + <property name="src" location="src"/> |
| 88 | + <property name="build" location="build"/> |
| 89 | + <property name="dist" location="dist"/> |
| 90 | + |
| 91 | + <target name="init"> |
| 92 | + <!-- Create the time stamp --> |
| 93 | + <tstamp/> |
| 94 | + <!-- Create the build directory structure used by compile --> |
| 95 | + <mkdir dir="${build}"/> |
| 96 | + </target> |
| 97 | + |
| 98 | + <target name="compile" depends="init" |
| 99 | + description="compile the source " > |
| 100 | + <!-- Compile the java code from ${src} into ${build} --> |
| 101 | + <javac srcdir="${src}" destdir="${build}"/> |
| 102 | + </target> |
| 103 | + |
| 104 | + <target name="dist" depends="compile" |
| 105 | + description="generate the distribution" > |
| 106 | + <!-- Create the distribution directory --> |
| 107 | + <mkdir dir="${dist}/lib"/> |
| 108 | + |
| 109 | + <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --> |
| 110 | + <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/> |
| 111 | + </target> |
| 112 | + |
| 113 | + <target name="clean" |
| 114 | + description="clean up" > |
| 115 | + <!-- Delete the ${build} and ${dist} directory trees --> |
| 116 | + <delete dir="${build}"/> |
| 117 | + <delete dir="${dist}"/> |
| 118 | + </target> |
| 119 | +</project> |
| 120 | +``` |
| 121 | + |
| 122 | +在这个xml文件中,有几个target标签,每个target对应一个执行目标。 |
| 123 | + |
| 124 | +我们将这个build.xml放在 D:\Temp\ant_test 路径下,然后在dos界面下进行测试。 |
| 125 | + |
| 126 | +**ant init** |
| 127 | + |
| 128 | + |
| 129 | + |
| 130 | +在 D:\Temp\ant_test 路径下创建了一个build目录,执行成功。 |
| 131 | + |
| 132 | +**ant compile** |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | +提示错误,原来是在build.xml的所在目录下找不到src目录。好的,我们直接创建一个src目录,然后再次尝试。这次,执行成功。 |
| 137 | + |
| 138 | + |
| 139 | + |
| 140 | +**ant dist ** |
| 141 | + |
| 142 | + |
| 143 | + |
| 144 | +在 D:\Temp\ant_test 路径下创建了一个dist目录,执行成功。 |
| 145 | + |
| 146 | +**ant clean** |
| 147 | + |
| 148 | + |
| 149 | + |
| 150 | +清除创建的build和dist目录,执行成功。 |
| 151 | + |
| 152 | +**一个细节** |
| 153 | + |
| 154 | +细心的读者,想必已经发现一个问题——在执行 ant compile 和 ant dist 命令的时候把前面的命令也执行了。这是为什么呢? |
| 155 | + |
| 156 | +请留意一下build.xml中的内容。有部分 **target** 标签中含有 **depends** 关键字。 |
| 157 | + |
| 158 | + |
| 159 | + |
| 160 | +这表明,当前的 target 在执行时需要依赖其他的target,必须先执行依赖的target,然后再执行。 |
| 161 | + |
| 162 | +## 关键元素 |
| 163 | + |
| 164 | +Ant的构件文件都是XML格式的。每个构件文件包含一个project元素和至少一个target。 |
| 165 | + |
| 166 | +target元素可以包含多个task元素。 |
| 167 | + |
| 168 | +### Project 元素 |
| 169 | + |
| 170 | +**project 元素**是构建文件的根元素。 |
| 171 | + |
| 172 | +一个 project 元素可以有多个 target 元素,一个 target 元素可以有多个 task。 |
| 173 | + |
| 174 | +在上节的例子中,project标签里有三个属性。 |
| 175 | + |
| 176 | +```xml |
| 177 | +<project name="MyProject" default="dist" basedir="."> |
| 178 | +``` |
| 179 | + |
| 180 | +**name属性**,指示 project 元素的名字。例子中的名字就是 MyProject。 |
| 181 | + |
| 182 | +**default属性**,指示这个 project 默认执行的 target。在本文的例子中,默认执行的 target 为 dist。 |
| 183 | + |
| 184 | +如果我们输入命令 ant 时,不指定 target 参数,默认会执行 dist 这个 target。 |
| 185 | + |
| 186 | +**basedir属性**,指定根路径的位置。该属性没有指定时,使用Ant的构件文件的所在目录作为根目录。 |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | +### Target 元素 |
| 191 | + |
| 192 | +**target 元素**是 task 的容器,也就是 Ant 的一个基本执行单元。 |
| 193 | + |
| 194 | +以上节例子中的 compile 来举例。 |
| 195 | + |
| 196 | +```xml |
| 197 | +<target name="compile" depends="init" description="compile the source " > |
| 198 | + <!-- Compile the java code from ${src} into ${build} --> |
| 199 | + <javac srcdir="${src}" destdir="${build}"/> |
| 200 | +</target> |
| 201 | +``` |
| 202 | + |
| 203 | +这个 target 中出现了几个属性。 |
| 204 | + |
| 205 | +**name属性**,指示target元素的名称。 |
| 206 | + |
| 207 | +这个属性在一个project元素中必须是唯一的。这很好理解,如果出现重复,Ant就不知道具体该执行哪个 target 了。 |
| 208 | + |
| 209 | +**depends属性**,指示依赖的 target,当前的 target 必须在依赖的 target 之后执行。 |
| 210 | + |
| 211 | +**description属性**,是关于 target 的简短说明。 |
| 212 | + |
| 213 | +此外,还有其他几个未出现在构建文件中的属性。 |
| 214 | + |
| 215 | +**if属性**,验证指定的属性是否存在,若不存在,所在target将不会被执行。 |
| 216 | + |
| 217 | +**unless属性**,**正好和 if属性相反**,验证指定的属性是否存在,若存在,所在target将不会被执行。**** |
| 218 | + |
| 219 | +**extensionOf属性**,添加当前 target 到 **extension-point** 依赖列表。**——Ant1.8.0新特性。** |
| 220 | + |
| 221 | +> **extension-point 元素**和 target 元素十分类似,都可以指定依赖的target。但是不同的是,extension-point 中不能包含任何 task。 |
| 222 | +
|
| 223 | +请看以下实例: |
| 224 | + |
| 225 | +```xml |
| 226 | +<target name="create-directory-layout"> |
| 227 | + ... |
| 228 | +</target> |
| 229 | +<extension-point name="ready-to-compile" depends="create-directory-layout"/> |
| 230 | +<target name="compile" depends="ready-to-compile"> |
| 231 | + ... |
| 232 | +</target> |
| 233 | +``` |
| 234 | + |
| 235 | +**调用target顺序**: create-directory-layout --> 'empty slot' --> compile |
| 236 | + |
| 237 | +```xml |
| 238 | +<target name="generate-sources" extensionOf="ready-to-compile"> |
| 239 | + ... |
| 240 | +</target> |
| 241 | +``` |
| 242 | + |
| 243 | +**调用target顺序**: create-directory-layout --> generate-sources --> compile |
| 244 | + |
| 245 | +**onMissingExtensionPoint属性**:当无法找到一个extension-point时,target尝试去做的动作("fail", "warn", "ignore")。*——Ant1.8.2新特性* |
| 246 | + |
| 247 | +### Task 元素 |
| 248 | + |
| 249 | +task是一段可以被执行的代码。 |
| 250 | + |
| 251 | +一个task可以有多个属性, 一个属性可以包含对一个 **property** 的引用。 |
| 252 | + |
| 253 | +task的通常结构为 |
| 254 | + |
| 255 | +```xml |
| 256 | +<name attribute1="value1" attribute2="value2" ... /> |
| 257 | +``` |
| 258 | + |
| 259 | +其中,name 是 task 的名字, attributeN 是属性名, valueN 是这个属性的值。 |
| 260 | + |
| 261 | +还是以 compile 做为例子: |
| 262 | + |
| 263 | +```xml |
| 264 | +<target name="compile" depends="init" description="compile the source " > |
| 265 | + <!-- Compile the java code from srcintosrcinto{build} --> |
| 266 | + <javac srcdir="${src}" destdir="${build}"/> |
| 267 | +</target> |
| 268 | +``` |
| 269 | + |
| 270 | +在 compile 这个 target 标签中包含了一个任务。 |
| 271 | + |
| 272 | +这个任务的动作是:执行JAVA编译,编译src下的代码,并把编译生成的文件放在build目录中。 |
| 273 | + |
| 274 | +**常用task ** |
| 275 | + |
| 276 | +**javac**:用于编译一个或者多个Java源文件,通常需要srcdir和destdir两个属性,用于指定Java源文件的位置和编译后class文件的保存位置。 |
| 277 | + |
| 278 | +```xml |
| 279 | +<javac srcdir="${src}" destdir="${build}" classpath="abc.jar" debug="on" source="1.7" /> |
| 280 | +``` |
| 281 | + |
| 282 | +**java**:用于运行某个Java类,通常需要classname属性,用于指定需要运行哪个类。 |
| 283 | + |
| 284 | +```xml |
| 285 | +<java classname="test.Main"> |
| 286 | + <arg value="-h" /> |
| 287 | + <classpath> |
| 288 | + <pathelement location="dist/test.jar" /> |
| 289 | + </classpath> |
| 290 | +</java> |
| 291 | +``` |
| 292 | + |
| 293 | +**jar**:用于生成JAR包,通常需要指定destfile属性,用于指定所创建JAR包的文件名。除此之外,通常还应指定一个文件集,表明需要将哪些文件打包到JAR包里。 |
| 294 | + |
| 295 | +```xml |
| 296 | +<jar jarfile="dist/lib/MyProject−dist/lib/MyProject−{DSTAMP}.jar" basedir="${build}"/> |
| 297 | +``` |
| 298 | + |
| 299 | +**echo**:输出某个字符串。 |
| 300 | + |
| 301 | +```xml |
| 302 | +<echo message="Building to ${builddir}"/> |
| 303 | +<echo>You are using version ${java.version} of Java! This message spans two lines.</echo> |
| 304 | +``` |
| 305 | + |
| 306 | +**copy**:用于复制文件或路径。 |
| 307 | + |
| 308 | +```xml |
| 309 | +<copy todir="${builddir}/srccopy"> |
| 310 | + <fileset dir="${srcdir}"> |
| 311 | + <include name="**/*.java"/> |
| 312 | + </fileset> |
| 313 | + <filterset> |
| 314 | + <filter token="VERSION" value="${app.version}"/> |
| 315 | + </filterset> |
| 316 | +</copy> |
| 317 | +``` |
| 318 | + |
| 319 | +**delete**:用于删除文件或路径。 |
| 320 | + |
| 321 | +```xml |
| 322 | +<copy todir="${builddir}/srccopy"> |
| 323 | + <fileset dir="${srcdir}"> |
| 324 | + <include name="**/*.java"/> |
| 325 | + </fileset> |
| 326 | + <filterset> |
| 327 | + <filter token="VERSION" value="${app.version}"/> |
| 328 | + </filterset> |
| 329 | +</copy> |
| 330 | +``` |
| 331 | + |
| 332 | +**mkdir**:用于创建文件夹。 |
| 333 | + |
| 334 | +```xml |
| 335 | +<mkdir dir="${dist}/lib" /> |
| 336 | +``` |
| 337 | + |
| 338 | +**move**:用户移动文件和路径。 |
| 339 | + |
| 340 | +```xml |
| 341 | +<move todir="some/new/dir"> |
| 342 | + <fileset dir="my/src/dir"> |
| 343 | + <include name="**/*.jar" /> |
| 344 | + <exclude name="**/ant.jar" /> |
| 345 | + </fileset> |
| 346 | +</move> |
| 347 | +``` |
| 348 | + |
| 349 | +### Property 元素 |
| 350 | + |
| 351 | +Property 是对参数的定义。 |
| 352 | + |
| 353 | +project的属性可以通过property元素来设定,也可在Ant之外设定。若要在外部引入某文件,例如build.properties文件,可以通过如下内容将其引入:<property file=” build.properties”/>。 |
| 354 | + |
| 355 | +property元素可用作 task 的属性值。在task中是通过将属性名放在“${”和“}”之间,并放在task属性值的位置来实现的。 |
| 356 | + |
| 357 | +例如 complile 例子中,使用了前面定义的 src 作为源目录。 |
| 358 | + |
| 359 | +```xml |
| 360 | +<javac srcdir="${src}" destdir="${build}"/> |
| 361 | +``` |
| 362 | + |
| 363 | +Ant提供了一些内置的属性,它能得到的系统属性的列表与Java文档中System.getPropertis()方法得到的属性一致,这些系统属性可参考sun网站的说明。 |
| 364 | + |
| 365 | +### extension-point元素 |
| 366 | + |
| 367 | +和 target 元素十分类似,都可以指定依赖的target。但是不同的是,extension-point 中不能包含任何 task。 |
| 368 | + |
| 369 | +*——Ant1.8.0新增特性。* |
| 370 | + |
| 371 | +在 target元素中的例子里已提到过,不再赘述。 |
| 372 | + |
| 373 | +## 参考资料 |
| 374 | + |
| 375 | +- [ant官方手册](http://ant.apache.org/manual/index.html ) |
| 376 | +- [http://www.blogjava.net/amigoxie/archive/2007/11/09/159413.html](http://www.blogjava.net/amigoxie/archive/2007/11/09/159413.html) |
0 commit comments