MSBuild如何决定是否需要重建C#库?

时间:2011-02-22 17:28:19

标签: c# visual-studio compiler-construction msbuild

当MSBuild针对C#项目文件运行时,它是如何决定是否需要重建库(即调用csc)?

我想(但想确认):

  • 如果没有输出目录,请重建(duh :))
  • 如果C#文件已更改,请重建
  • 如果标记为“复制”的包含文件始终更改,则重建
    • 或者它是否足够聪明,不能重建,只是将文件复制到现有输出?
  • 如果标记为copy-if-newer的包含文件已更改,则重建
    • 与上述相同的问题

3 个答案:

答案 0 :(得分:12)

如果查看Microsoft.CSharp.targets(用于编译C#项目的MSBuild文件),CoreCompile目标会定义一组输入和输出。这些用于执行依赖性检查以查看CoreCompile是否需要运行。输入列表包括C#文件,资源文件,应用程序图标,强名称密钥文件以及您可以定义的其他自定义输入。

如果您有解决方案并在其上运行MSBuild并启用了诊断日志记录(/ v:diag命令行参数),那么如果输出是最新的,您可能会看到此消息:

  

跳过目标“CoreCompile”因为   所有输出文件都是最新的   尊重输入文件。

目标文件位于.NET Framework目录(C:\windows\Microsoft.NET\Framework\v3.5 or v4.0.30319)。

答案 1 :(得分:4)

MSBuild具有内置功能。<​​/ p>

Target有两个属性,InputsOutputs

每当Input更改或Output更旧或遗失时,Target都会被执行。

答案 2 :(得分:3)

事情是,任何看似合理的启发式都可能不会削减它。当你要求编译器(构建系统)产生输出时,你最好保证输出符合你的预期。

据我所知,MSBuild不会这样做。它总是重建(从头开始)整个解决方案/项目。但是,从Visual Studio中调用MSBuild时,临时编译单元将保留在项目的\ obj文件夹中。清空该文件夹与重建相同。

如果编译器或构建系统要重用输出,那么它将使用实际文件内容的校验和来确定是否可以从其他地方检索编译输出。这基本上是唯一可靠的方法,您可以确定文件是否实际需要从头开始重新编译。 仅供参考,这是由Visual C#编译器而不是MSBuild完成的。

文件系统“上次修改日期”属性与跨系统不一致,因此最终不会用于确定是使用缓存输出构建还是从头开始构建。