1

我有一个ant构建许多android项目的构建脚本。

我正在按照文本文件中的属性给我的特定顺序构建所有项目。

ant构建脚本调用每个项目自己的文件build.xml来构建该项目。

如果一个项目无法构建,我怎么能从ant它因为错误而停止的地方继续构建?

基本上,如果我正在构建项目A、、、和。并且构建过程失败了,当开发人员再次开始构建时,我该怎么做才能让构建过程继续?BCDECC

此外,构建过程需要重建开发人员更改的内容。例如, 中的问题C是由于 中的问题A,并且C取决于A。因此,它需要重建A、跳过B、重建C和继续。oO

寻找想法或者是否已经有这样做的东西。

谢谢!

4

2 回答 2

2

与 Make 一样,Ant 非常擅长在您停止时确定从哪里继续。除非更新源,否则该<javac>任务不会重新编译代码。默认情况下,该<copy>任务不会重新复制文件。但是,如果您将构建分解为多个文件,然后使用<ant>任务而不是使用您的depends参数<target>,您将破坏这个系统。

假设您有独立的项目ABCD。你build.xml所做的就是在每一个中调用正确的目标。假设每个人都构建了一个 jar 文件。由于 Java 错误,该过程在项目C上中断。开发商修好了。你build.xml再次运行你的,它会再次调用项目AB。但是,由于这些项目已经建成,他们不应该做任何事情。您会看到对AB的调用,但什么都不会发生。

即使在项目C中,构建过程也会从它停止的地方开始。也就是说,如果您没有做任何事情来破坏 Ant 计算其构建的能力。

破解 Ant 的方法有很多。例如,不要在构建过程中删除文件。如果目标文件不再存在,Ant 就无法使用时间戳来确定要做什么。

有时,流程需要一些帮助来避免构建。Ant 有一个内置<uptodate>任务,但我发现它<outofdate>更容易使用。例如,假设项目A生成项目B使用的 jar 文件。如果 jar 中使用的类文件和资源早于 jar 上的时间戳,您可能希望使用这些任务之一不复制该 jar。

否则,如果您只是盲目地将 jar 复制到 Project B,Project B将看到类文件所依赖的文件已更新。因此,项目B将重新编译所有内容。然后复制所有内容,并重建它正在构建的任何罐子或战争。我遇到了直接更新 Java 类文件的第三方任务的问题,并且不得不使用监视文件来确保我没有运行两次编译,尤其是处理类文件的任务。

顺便说一句,不要对 Ant 所说的正在执行的目标感到不安。Ant 将执行这些目标,但构成这些目标的任务将不会运行,除非更新某些内容。


更新:使用<outofdate>来自 Ant-Contrib

假设在您的主项目文件中,您有以下目标:

<target name="build"
    description="Builds every sub project">
    <ant antfile=${project.a.dir}/build.xml target="build"/>
    <ant antfile=${project.b.dir}/build.xml target="build"/>
    <ant antfile=${project.c.dir}/build.xml target="build"/>
    <ant antfile=${project.d.dir}/build.xml target="build"/>

使用<outofdate>

<target name="build"
    description="Builds every sub project">

    <outofdate>
       <sourcefiles>
           <fileset dir="${project.a.srcdir}"/>
       </sourcefiles>
       <targetfiles>
           <fileset dir="${project.a.dir}/target">
              <include name="*.jar"/>
           </fileset>
       </targetfiles>
       <sequential>
           <ant antfile=${project.a.dir}/build.xml
               target="build"/>
       </sequential>
    </outofdate>

    <outofdate>
       <sourcefiles>
           <fileset dir="${project.b.srcdir}"/>
       </sourcefiles>
       <targetfiles>
           <fileset dir="${project.a.dir}/target">
              <include name="*.jar"/>
           </fileset>
       </targetfiles>
       <sequential>
           <echo>CALLING PROJECT: ${project.b.dir}</echo>
           <ant antfile=${project.b.dir}/build.xml
               target="build"/>
       </sequential>
    </outofdate>

    <etc, etc, etc/>

如果设置正确,您可能可以在 Ant-Contrib<for>循环中完成整个操作,因此您不必为每个子项目都这样做。

我不知道这是否更快。该<outofdate>任务仍然需要遍历所有文件并进行日期比较,但至少您没有看到它调用了子项目文件中的所有目标。

于 2012-10-26T03:18:17.450 回答
1

尽可能尝试使您的个人项目构建具有幂等性(即,如果您重新运行构建并且自上次以来没有任何更改,那么它不必重新构建所有内容)。像这样的标准任务已经像javac这样copy工作了,例如javac只重新编译.java比它们对应的.class. 对于不自己进行依赖检查的情况,您可以使用该uptodate任务自己进行检查。更新手册页中的示例显示了如何执行此操作。

这个想法是让每个构建都做它必须做的最少的工作,以使一切都保持最新。如果你能做到这一点,那么重建C原因AB再次运行并不重要,因为如果它们实际上没有任何事情可做,它们将很快完成。

于 2012-10-25T22:10:26.203 回答