链接Ant构建文件

时间:2012-10-09 21:51:44

标签: xml ant

我有一个客户端和一个我用Ant构建的服务器。客户端在构建之前依赖于首先构建的服务器。我有所有必需的库,除了客户端中捆绑的服务器ear文件。

我创建了3个蚂蚁文件build.xmlbuild-client.xmlbuild-server.xml。 (单击任何文件名以查看它们)文件build-client.xmlbuild-server.xml包含在build.xml中,以便它可以从中运行目标。

我遇到的问题是basedir变量从构建文件更改为构建文件。因此,如果我从build-client.xml build.xml中运行目标,则basedir变量相对于build.xml

如何在Ant脚本中多次更改basedir变量?

另外,看看这些构建文件,您是否看到了更好的方法来做我想做的事情?现在,我想我必须在同一个位置同时拥有客户端战争和服务器耳朵,才能制作最终的捆绑耳朵。我对此的想法可能有缺陷,因为这些脚本似乎不必要地复杂。

3 个答案:

答案 0 :(得分:5)

<import> <!-- importing.xml --> <project name="importing" basedir="." default="..."> <import file="${path_to_imported}/imported.xml"/> </project> <!-- imported.xml --> <project name="imported" basedir="." default="..."> <property file="imported.properties"/> </project> 任务为您提供有关如何完成此任务的信息。

根据导入的文件解析文件

假设名为imports.xml的主构建文件导入位于文件系统任何位置的构建文件imported.xml,并且imported.xml从imported.properties中读取一组属性:

basedir

但是,此代码段将针对imports.xml的basedir解析imported.properties,因为Ant会忽略imported.xml的<!-- imported.xml --> <project name="imported" basedir="." default="..."> <dirname property="imported.basedir" file="${ant.file.imported}"/> <property file="${imported.basedir}/imported.properties"/> </project> 。使用imported.properties的正确方法是:

${ant.file.imported}

如上所述,<dirname>存储构建脚本的路径,该路径定义了名为imported的项目(简而言之,它存储了imported.xml的路径),${basedir}获取了其目录。此技术还允许将imported.xml用作独立文件(不在其他项目中导入)。

基本上,您无法真正使用项目代码中的basedir="./../GrahamsProjClient"变量或<!-- build-client.xml --> <project name="GPClient" default="dist" > <dirname property="client.root.dir" file="${ant.file.GPClient}"/> <property name="real.basedir" value="${client.root.dir}/../GrahamsProjClient"/> <!-- Then from then on, replace ${basedir} with ${real.basedir} --> ... </project> 属性,而是可以构建它:

${ant.file.[project name]}

您可以对build-server.xml执行相同操作,唯一需要注意的是项目名称包含在<dirname />的{​​{1}}文件属性中。

答案 1 :(得分:3)

我的正常规则是在正常构建过程中不使用<ant><subant>,因为它会破坏依赖性检查。我们让开发人员将build.xml分解为七个单独的构建文件,并且由于<ant>任务不断调用其他构建文件中的内容,他执行相同的目标最多14次。然后,他想知道为什么他的构建需要这么长时间。将七个构建文件拼接成一个build.xml并使用depends参数<target>将构建时间缩短到不到两分钟。

但是,在这种情况下,你所拥有的实际上是两个独立的项目和一个build.xml,你用它来调用这两个独立的项目。在这种情况下,您最好使用<ant><subant>来电,而不是<import>

  • 这些来电不会干扰${basedir}
  • 这些调用允许您指定要包含在这些单独文件中的属性和资源。 (可能的答案是 none )。
  • 多个目标共享同一个名称没有问题。客户端构建中的 compile 目标不会与服务器构建中的_compile_目标重叠。

Subant功能更强大,但实施起来比较棘手。使用Subant,您可以让它搜索build.xml文件。大部分时间使用<ant>都比较容易,也可以做到你想要的。


我真正推荐的是使用Ivy来处理依赖性问题。 Ivy不仅可以处理客户端中的服务器依赖项,还可以处理所有第三方jar依赖项。不再在项目中存储jarfiles。在项目中存储jar文件时,会丢失有关其实际版本及其历史记录的信息。您在项目中看到commons-io.jar,并且您不知道它是什么版本,或者即使它是官方的`commons-io.jar,或者您的某个开发人员将其视为某些点。

问题是Ivy需要做一些工作才能实现。您需要使用Ivy存储库管理器,例如NexusArtifactoryArchiva。 (实际上,这些是Maven存储库管理器,但Ivy与它们的工作非常顺利。)

然后,您需要将ivy.jar导入项目并获取ivysettings.xml文件以指向 Maven Ivy存储库服务器。

如果您使用Subversion作为版本控制系统,则可以执行以下操作:

  • 创建一个包含ivy.jar的常春藤项目,以及一个为您设置所有内容的XML文件。我可以看一下Github中的一个。 XML文件名为ivy.tasks.xml
  • 然后在您的项目中,使用svn:externals导入此项目。
  • build.xml中,您需要做两件事:
    • <project>实体中添加Ivy名称空间。
    • 使用<import>任务导入包含所有设置的Ivy XML文件。

优点是更改您的常春藤项目将自动更改与Ivy交互的所有项目。例如,如果您更改Ivy服务器的URL,或者您需要重新定义Ivy缓存目录。

如果您这样做,只需创建一个定义依赖关系的ivy.xml文件,然后使用<ivy:cachepath><ivy:retrieve>检索您需要的第三方jar。这将包括您的客户需要的服务器jar。

答案 2 :(得分:0)

我注意到蚂蚁的一件事是我无法像我想要的那样改变变量

解决方案是让命令行中的ant运行您想要执行的每个目标,而不是执行命令行语句,例如

ant target1 target2

<target name="target1">
   <antcall target="target2">
</target>

我不得不从命令行顺序执行目标调用 ant target1 ant target2

所以我选择将这些ant调用放在python脚本中,这只是调用os.system("");,我的命令行语句就在引号内。 bash也可以做到这一点

如果这些变量具有相同的名称,这是蚂蚁为每个目标使用适当变量的唯一方法