MSBuild如何检查目标是否是最新的?

13

MSBuild会对最新的目标发出以下消息:

Skipping target "MyTarget" because all output files are up-to-date with respect to the input files.

实际的检查是如何进行的?


你是在说复制任务和SkipUnchangedFiles参数吗? - sll
我在谈论目标,而不是复制任务。 - sergtk
2个回答

16

检查增量构建的流程:

目标元素可以具有Inputs属性,表示目标期望作为输入的项目,也可以具有Outputs属性,表示其作为输出生成的项目。 MSBuild尝试在这些属性值之间找到1对1的映射关系。如果存在1对1的映射关系,则MSBuild将比较每个输入项的时间戳与其相应输出项的时间戳。 没有1对1映射关系的输出文件将与所有输入文件进行比较。如果输出文件与其输入文件或文件的时间戳相同或更新,则该项目被视为最新状态。

如果所有输出项目都是最新的,则MSBuild跳过该目标。这种增量构建目标可以显著提高构建速度。 如果只有一些文件是最新的,则MSBuild执行目标但跳过最新的项,并因此使所有项保持最新状态。这称为部分增量构建。


谢谢!这是否意味着msbuild具有带有时间戳的缓存数据? - sergtk
1
我认为在MSBuild进行此类检查时,它可能会持久化一些数据结构,该结构表示具有时间戳的文件列表,但不确定它在内存中保留多长时间,因为这仅对特定的输入和输出目录对才有意义。 - sll
1
@sergtk:它跟踪所有读取和写入的文件(以及相关的命令行),并将其记录在跟踪日志文件(“tlogs”)中。您可以在中间目录中查看这些文件。时间戳不会被保存 - 正如sll所引用的,如果输入比输出更新,则会重新编译输出,因此它只需要检查依赖关系图。 (个人而言,我更喜欢保存时间戳,因为这将减少边角情况,但遗憾的是...) - Cameron
2
有人知道时间戳检查的公差是多少吗?当我有几个项目(带有“ProjectReference”)时,如果它们在快速连续完成,则会多次重建引用。如果我在每个项目之间等待一分钟,那么它们将正确地看到先前构建的依赖项已经是最新的,并跳过它。 - Deanna

7

MSBuild比较输入和输出文件的时间戳以确定文件是否是最新的。详见增量构建


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接