【问题标题】:Linking Ant build files链接 Ant 构建文件
【发布时间】:2012-10-09 21:51:44
【问题描述】:

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

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

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

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

另外,看看这些构建文件,您是否发现了一种更好的方法来做我想做的事情?现在我在想我必须将客户端战争和服务器耳朵放在同一个位置,然后才能制作最终的捆绑耳朵。不过,我对此的想法可能存在缺陷,因为这些脚本看起来过于复杂。

【问题讨论】:

    标签: xml ant


    【解决方案1】:

    <import> 任务的ant documentation 为您提供有关如何完成此任务的信息。

    根据导入的文件解析文件

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

    <!-- 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>
    

    然而,这个 sn-p 将根据 importing.xml 的basedir 解析imported.properties,因为Ant 忽略了importing.xml 的basedir。正确使用imported.properties的方法是:

    <!-- imported.xml -->
    <project name="imported" basedir="." default="...">
      <dirname property="imported.basedir" file="${ant.file.imported}"/>
      <property file="${imported.basedir}/imported.properties"/>
    </project>
    

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

    基本上,您不能真正使用${basedir} 变量,也不能在项目标签中使用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>
    

    您可以对 build-server.xml 执行相同的操作,唯一需要注意的是项目名称在 ${ant.file.[project name]} 文件属性中为 &lt;dirname /&gt; 提供。

    【讨论】:

      【解决方案2】:

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

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

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

      Subant 更强大,但实施起来更棘手。使用 Subant,您可以让它搜索 build.xml 文件。大多数情况下,使用&lt;ant&gt; 会更容易,而且可以随心所欲。


      我真正推荐的是使用 Ivy 来处理依赖问题。 Ivy 不仅可以处理客户端中的服务器依赖项,还可以处理所有第三方 jar 依赖项。不再在项目中存储 jarfile。当您将 jar 文件存储在项目中时,您会丢失有关其实际版本和历史记录的信息。您在项目中看到 commons-io.jar,但您不知道它是什么版本,甚至不知道它是官方的 `commons-io.jar,还是您的某个开发人员在某个时候修改了它。

      问题是 Ivy 需要做一些工作来实现。您需要使用 Ivy 存储库管理器,例如 NexusArtifactoryArchiva。 (实际上,这些是 Maven 存储库管理器,但 Ivy 与它们配合得非常好。)

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

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

      • 创建一个包含 ivy.jar 的 Ivy 项目和一个为您设置所有内容的 XML 文件。我在Github 有一个你可以看看。 XML 文件名为ivy.tasks.xml
      • 然后在你的项目中,使用svn:externals来导入这个项目。
      • 在您的build.xml 中,您需要做两件事:
        • 在您的 &lt;project&gt; 实体中添加 Ivy 命名空间。
        • 使用&lt;import&gt; 任务导入已完成所有设置的 Ivy XML 文件。

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

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

      【讨论】:

        【解决方案3】:

        我在 ant 中注意到的一件事是我无法让变量按我想要的方式改变

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

        ant target1 target2

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

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

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

        这是 ant 为每个目标使用正确变量的唯一方法,如果这些变量具有相同的名称

        【讨论】:

          猜你喜欢
          • 2011-04-19
          • 1970-01-01
          • 2011-03-23
          • 2010-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多