我有一个ant
构建脚本,可以构建许多android
个项目。
我正按照文本文件中的属性给我的特定顺序构建所有项目。
ant
构建脚本调用每个项目自己的build.xml
文件来构建该项目。
如果某个项目无法构建,我怎能让ant
继续构建它因错误而停止的位置?
基本上,如果我正在构建项目A
,B
,C
,D
和E
。并且构建过程在C
处失败,当开发人员再次启动构建时,我可以做些什么来使构建过程在C
继续?
此外,构建过程需要重建开发人员更改的内容。例如,C
中的问题是由于A
中的问题,C
取决于A
。因此,需要重建A
,跳过B
,然后重建C
并继续。 o.O
寻找想法或者是否已经有了这样做。
谢谢!
答案 0 :(得分:2)
Ant,就像Make一样,非常擅长在你离开时找出继续的地方。除非更新源,否则<javac>
任务不会重新编译代码。默认情况下,<copy>
任务不会重新复制文件。但是,如果您将构建分解为多个文件,然后使用<ant>
任务而不是使用depends
的{{1}}参数,则会破坏此系统。
假设您有独立项目 A , B , C 和 D 。您<target>
所做的就是在每个build.xml
中调用正确的目标。假设每个都构建一个jar文件。由于Java错误,该过程在项目 C 上破坏了。开发人员修复了它。您再次运行build.xml
,它将再次调用项目 A 和 B 。但是,由于这些项目已经建成,它们不应该做任何事情。您会看到对 A 和 B 的调用,但不会发生任何事情。
即使在项目 C 中,构建过程也会从停止的位置开始。也就是说,如果你没有采取任何措施来破坏Ant的构建能力。
有许多方法可以打破Ant。例如,不要在构建过程中删除文件。如果目标文件不再存在,Ant就无法使用时间戳来确定要执行的操作。
有时,一个过程需要一些帮助来避免构建。 Ant有一个内置的<uptodate>
任务,但我发现<outofdate>
更容易使用。例如,假设Project A 生成Project B 使用的jar文件。如果jar中使用的类文件和资源早于jar上的时间戳,您可能希望使用其中一个任务来复制该jar。
否则,如果你只是盲目地将jar复制到Project B ,Project B 将会看到classfiles所依赖的文件已经更新。因此,Project B 将重新编译所有内容。然后复制一切,重建它正在建造的任何罐子或战争。我遇到了third party task直接更新Java类文件的问题,并且必须使用监视文件来确保我没有运行编译两次,或者特别是那个使用类文件的任务。
顺便说一下,不要对目标蚂蚁说它正在执行的人感到沮丧。 Ant将执行这些目标,但构成这些目标的任务将不会运行,除非更新某些内容。
<outofdate>
假设在您的主项目文件中,您有以下目标:
<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>
任务仍然必须遍历所有文件并进行日期比较,但至少您没有看到它调用子项目文件中的所有目标。
答案 1 :(得分:1)
尽可能尝试使您的个人项目构建idempotent(即,如果您重新运行构建,并且自上次以来没有任何更改,那么它不必重建所有内容)。像javac
和copy
这样的标准任务已经像这样工作,例如javac
只重新编译比其对应的.java
更新的.class
个文件。对于不进行自己的依赖性检查的情况,您可以使用uptodate
任务自行进行检查。 manual page for uptodate中有一些示例说明了如何执行此操作。
这个想法是让每个构建完成它必须做的最小工作,以便使所有内容都更新。如果你能做到这一点那么重建C
会导致A
和B
再次运行并不重要,因为如果它们实际上没有任何东西它们会很快完成要做。