msbuild - 如何减少 MSBuild 时间

我的情况

在我现在正在处理的 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 ,但这似乎并不乐观。

我的问题

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

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

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

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

最佳答案

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

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

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

以下是我的经验:

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

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

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

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

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

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

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

https://stackoverflow.com/questions/819031/

相关文章:

macos - OS X : MACOSX_RPATH is not specified for t

build - 递归 CMake 搜索头文件和源文件

c - 如何编译 GnuTLS

Android NDK - 使两个 native 共享库相互调用

caching - Docker 构建未使用缓存

c++ - 当 CMake 中的生成器或输入发生更改时,如何仅构建自动生成的代码?

java - Ant scp 任务不起作用,即使在 ant/lib 上使用 jsch

c++ - C++ 依赖生产没有自动化的理论原因是什么?

java - 多个存储库的 Maven 设置

c++ - 解决 Visual Studio 2010 AlwaysCreate 重建问题