【问题标题】:How to decrease MSBuild times如何减少 MSBuild 时间
【发布时间】:2025-12-27 13:50:12
【问题描述】:

我的情况

在我现在正在处理的 C# 项目中,我们有一个相当大的解决方案(80 多个项目)。现在,使用来自Visual Studio 2008 的 MSBuild,5 分钟以上的重建时间确实成为一个相当大的问题。

在我上周进行的一项分析中,结果表明我的构建时间花费如下:

  1. 将文件复制到项目并重新复制到依赖它的项目(CopyToLocal)等(60%)

  2. 调用 postbuild 来反编译/编译。 (20%)

  3. 做实际编译等(20%)

除了“正常”项目bin\debug 文件夹的输出也被复制到外部目录以设置主“加载器”程序。主程序结构有点像这样:

\loader\bin\loader.exe

\loader\plugin\plugin1\plugin1.dll

\loader\plugin\plugin1\somedependency.dll

我做了什么

为了让事情进展得更快一点,我想到了以下几点:

  1. 将所有文件复制到一个大的 bin 目录中,不要使用 CopyTolocal。我不喜欢这样,因为我们不能再使用同一个 DLL 文件的不同版本,而且我的 bin 目录变得一团糟。

  2. Use parallelism (/m) for MSBuild。这对构建时间的帮助很小。

  3. 尽量减少项目之间的依赖,这当然是一件好事。

  4. 投资硬件。我找到了一些research on solid-state drives,但这似乎并不乐观。

我的问题

我还注意到,当我对位于我的依赖关系树根目录的项目进行更改时,所有内容都会重新构建。即使只是在“私人”部分进行了更改,并且项目的界面没有更改。

MSBuild 是否使用依赖项目的时间戳来确定项目是否需要重建?

这可以更改为不同的条件吗?比如文件的校验和?

除了这个具体的建议之外,我肯定会感谢所有缩短构建时间的建议。

【问题讨论】:

标签: msbuild build-process build build-automation


【解决方案1】:

我正在处理 500 多个 C# 应用程序项目。项目是并行编译的,并且 copylocal 设置为 false。在没有单元测试和代码覆盖的情况下,编译时间约为 37 分钟。增量构建需要 13 分钟,无需更改任何代码。

如果我关闭并行编译并将 copylocal 设置为 true,编译时间将超过 1 小时 40 分钟。

对于本地构建、门控签入构建和部署阶段的服务器构建(夜间构建),我有不同的配置。

以下是我的经验:

  1. 如果您想在没有将 CopyLocal 设置为 false 的情况下并行构建项目,则将输出文件复制到一个目录不是一个好主意。当多个项目引用同一个程序集并且 MSBuild 尝试同时将此引用复制到输出文件夹时,我的程序集有时会被锁定。 This solution 对我很有帮助。我将所有引用的 copylocal 设置为 false,并且我的构建目录大小降低了 10 倍(I/O 减少了 10 倍)。对于本地构建和服务器构建,我有不同的设置。门控签入构建和完整部署构建的不同设置。
  2. 如果我启用并行构建,构建会更快、更快。如果你有一个强大的构建服务器,你的 /m:2 构建应该比 /m:1 构建快 2 倍。它与项目之间的依赖关系无关(如果将copylocal设置为false)。
  3. 如果您想要快速增量构建,您应该减少项目之间的依赖关系。它对完整构建没有影响(copylocal false)。增量编译时间取决于构建树中更改的项目位置。

是的,MSBuild 使用依赖项目的时间戳来确定项目是否需要重建。它将输入文件(代码文件、引用的程序集、临时文件……)时间戳与输出程序集进行比较。如果有什么改变,你的项目会被重新编译。尽量减少项目之间的依赖数量,以尽量减少重新编译。如果您的更改仅在项目的“私有”部分中,您的输出程序集将被更改,程序集时间戳将被更改,并且所有相关项目也将被重建。您对此无能为力。

在代码中没有任何更改的情况下,以诊断详细程度运行您的构建两次,并检查“完全构建目标“CoreCompile””,就像我在here 中描述的那样。您的项目文件中可能有问题,并且每次都会重新编译您的项目。如果您不更改任何内容,则您的构建日志不应包含“完全构建目标“CoreCompile””日志。

我们的构建服务器是虚拟机,而不是真正的硬件。将 VM 用于构建服务器并不是一个好主意,但这不是我的决定。

如果您有多 GB RAM,请尝试将其中的一部分用作内存硬盘。你的构建应该更快:)

SSD 驱动器对每天的高 I/O 很敏感。它会影响保修。

我希望它对某人有所帮助... ;)

【讨论】:

  • 如何运行单元/集成测试?我需要将 copylocal 设置为 true 以进行测试,因此所有必需的 dll 都在 test bin 文件夹中。您是否找到了不需要这样做的解决方案?
  • True 添加到单元测试项目中的所有 Reverence 和 ProjectReference 标记中。
  • 我可以这样做,它会构建得很好,但我将无法运行测试 - .NET 在被测试的 dll 文件夹中查找依赖的二进制文件。我已经阅读了有关探测和 DEVPATH 的信息,但它们似乎还不够好 - 在构建 Debug 和 Release 时会出现问题。将所有必需的 dll 放入 GAC 中是可行的,但这听起来很疯狂,无论如何都不是一种选择。
  • 在您的测试项目中添加所有依赖二进制文件作为参考,在所有引用上强制 copylocal = true (True) 并且您的构建应该将所有依赖二进制文件复制到输出文件夹(调试或发布)。它适用于我的解决方案。
  • 这正是我所做的并且效果很好(将总构建时间减少了三分之一)。但是,测试文件夹中仍然有 1.2gb 不必要的 dll 和 pdb 副本(我们有很多测试程序集)。必须有一些聪明的方法来避免复制...
【解决方案2】:

我们也有大量的解决方案。构建和编译都是关于 I/O 的。

固态硬盘非常有前途。一位同事在他的笔记本电脑中放置了一个固态驱动器,发现它现在比他巨大的主开发盒快得多。没有细节,但他声称要快很多倍。

我们一直在摆弄解决方案文件夹来对项目的各个部分进行分组:这使开发人员可以更轻松地卸载他们不从事的项目。 p>

/m 很少帮助 .NET 调试构建。几周前,我对此进行了一系列测试,发现了细微的差异。调查结果:

  • 由于我的构建受 I/O 限制,使用 /m:2-4 会使调试构建变慢
  • 发布版本通常要快得多。
  • 代码分析会增加很多时间。

大图:实际上,与获取源代码和运行单元测试相比,编译对我来说只是很小的成本。在我们的构建服务器上,集成测试和打包几乎一直在进行。对于我的开发箱,我安排了一个批处理文件,在我上班之前和吃午饭的时候获取源代码、构建、运行单元测试。够了。

在构建服务器上,它更复杂。我们正在考虑在各种机器上建立链式并行CruiseControl.NET。我们正在使用 VSTS 构建,但是像这样水平扩展太昂贵(而且耗时)。

我为注重细节的人提供的数字。配置从最慢到最快,运行 msbuild "bigsolution.sln" /target:clean - 在每个之间。

  1. /m: 4, Debug with code analysis 1:38
  2. /m: 1, Debug with code analysis 1:30
  3. /m: 4, Debug with no code analysis 1:30
  4. /m: 1, Debug with no code analysis 1:30
  5. /m: 1,发布代码分析:1:30
  6. /m: 4,发布代码分析:1:05
  7. /m: 4,无代码分析发布:0:53

无需重新构建或清理的构建时间:~ 4-10 秒

【讨论】:

  • 感谢您的回复。我可能会更多地研究固态驱动器。构建时间对我来说是个大问题,因为我喜欢使用 TDD 并构建很多 ;)
【解决方案3】:

如果您有足够的 RAM 并且正在使用 Visual C++(不确定 C#),您可以通过将整个 include 和 lib 目录复制到 RAM 驱动器来加快速度。

您还可以将临时构建项目放置在 RAM 驱动器上。当然,您需要大量的 RAM。包含和库的 2 GB RAM 驱动器就足够了。但是对于临时文件(*.obj 等),它取决于项目。因此,它可能会多出 1 到 4 GB 或更多。

【讨论】:

  • 您如何实际设置 RAM 驱动器?
【解决方案4】:

MSBuild 构建时间是一个多维问题。好消息很容易解决:

与构建机器上运行的大多数进程不同,构建进程因消耗 CPU、RAM 和 I/O 而臭名昭著。加速 MSBuild 构建的一般方法是“获得金钱可以买到的最好的机器”,尤其是:

  1. CPU - 至少两个 Intel 3.0 GHz Core 2 Duo。

  2. RAM - 至少 4 GB DDR3。如果这是开发人员构建机器,64 位操作系统和 8 GB RAM 是更好的选择。

  3. HDD - 最快的选择是高端 3ware RAID-1,带有板载电池和启用的写入缓存。快速 SSD 可能是另一个值得考虑的选择。

  4. 网络 - 至少 1 Gbit/s 卡。

这种简单的硬件优化可以将您的 MSBuild 加速 2-3 倍。

【讨论】: