Antlib 文件是一个根元素为 antlib
的 xml 文件。Antlib 的元素是 Apache Ant 定义任务,例如 Taskdef 或任何扩展 org.apache.tools.ant.taskdefs.AntlibDefinition
的 Ant 任务。
当前与 Ant 捆绑在一起的声明集执行此操作的是
一组任务和类型可以在 antlib 文件中一起定义。例如,文件 sample.xml 包含以下内容
<?xml version="1.0"?> <antlib> <typedef name="if" classname="org.acme.ant.If"/> <typedef name="scriptpathmapper" classname="org.acme.ant.ScriptPathMapper" onerror="ignore"/> <macrodef name="print"> <attribute name="file"/> <sequential> <concat taskname="print"> <fileset dir="." includes="@{file}"/> </concat> </sequential> </macrodef> </antlib>
它定义了两种类型或任务,if
和 scriptpathmapper
。此 antlib 文件可以在构建脚本中使用,如下所示
<typedef file="sample.xml"/>
<typedef>
的其他属性也可以使用。例如,假设 sample.xml 位于包含类的 jar 文件 sample.jar 中,以下构建片段将定义 if
和 scriptpathmapper
任务/类型,并将它们放置在命名空间 URI samples:/acme.org
中。
<typedef resource="org/acme/ant/sample.xml" uri="samples:/acme.org"/>
然后可以按如下方式使用这些定义
<sample:if valuetrue="${props}" xmlns:sample="samples:/acme.org"> <sample:scriptpathmapper language="beanshell"> some bean shell </sample:scriptpathmapper> </sample:if>
具有模式 antlib:java.package
的命名空间 URI 会得到特殊处理。
当 Ant 遇到具有此模式的命名空间 URI 的元素时,它将检查默认类路径中的包目录中是否存在名为 antlib.xml 的资源。
例如,假设文件 antcontrib.jar 已放置在目录 ${ant.home}/lib 中,并且它包含资源 net/sf/antcontrib/antlib.xml,其中包含所有 antcontrib 的定义,以下构建文件将自动加载 antcontrib 定义在位置 HERE
<project default="deletetest" xmlns:antcontrib="antlib:net.sf.antcontrib"> <macrodef name="showdir"> <attribute name="dir"/> <sequential> <antcontrib:shellscript shell="bash"> <!-- HERE --> ls -Rl @{dir} </antcontrib:shellscript> </sequential> </macrodef> <target name="deletetest"> <delete dir="a" quiet="yes"/> <mkdir dir="a/b"/> <touch file="a/a.txt"/> <touch file="a/b/b.txt"/> <delete> <fileset dir="a"/> </delete> <showdir dir="a"/> </target> </project>
资源位于默认类路径中的要求可能会在 Ant 的未来版本中删除。
如果您想将 antlib 与本地 Ant 安装分开,例如因为您想将该 jar 保存在项目的 SCM 系统中,则必须指定一个类路径,以便 Ant 可以找到该 jar。最好的解决方案是使用 <taskdef>
加载 antlib。
<project xmlns:antcontrib="antlib:net.sf.antcontrib"> <taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml" classpath="path/to/ant-contrib.jar"/> <target name="iterate"> <antcontrib:for param="file"> <fileset dir="."/> <sequential> <echo message="- @{file}"/> </sequential> </antcontrib:for> </target> </project>
在 antlib 中定义的定义可以在 antlib 中使用。但是,定义所在的命名空间取决于使用 antlib 的 <typedef>
。为了解决这个问题,在 antlib 执行期间,定义将放置在命名空间 URI ant:current
中。例如,以下 antlib 定义了任务 <if>
、类型 <isallowed>
和一个宏 <ifallowed>
,该宏使用任务和类型
<antlib xmlns:current="ant:current"> <taskdef name="if" classname="org.acme.ant.If"/> <typedef name="isallowed" classname="org.acme.ant.Isallowed"/> <macrodef name="ifallowed"> <attribute name="action"/> <element name="do"/> <sequential> <current:if> <current:isallowed test="@{action}"/> <current:then> <do/> </current:then> </current:if> </sequential> </macrodef> </antlib>
Antlib 可以使用其他 antlib。
由于 antlib 中定义的名称位于调用 <typedef>
或通过自动元素解析指定的命名空间 URI 中,因此可以重复使用核心 Ant 类型和任务中的名称,前提是调用方使用命名空间 URI。例如,以下 antlib 可用于为各种任务定义默认值
<antlib xmlns:antcontrib="antlib:net.sf.antcontrib"> <presetdef name="javac"> <javac deprecation="${deprecation}" debug="${debug}"/> </presetdef> <presetdef name="delete"> <delete quiet="yes"/> </presetdef> <presetdef name="shellscript"> <antcontrib:shellscript shell="bash"/> </presetdef> </antlib>
这可以按如下方式使用
<project xmlns:local="localpresets"> <typedef file="localpresets.xml" uri="localpresets"/> <local:shellscript> echo "hello world" </local:shellscript> </project>