如何减少MSBuild次数

18 msbuild build-automation build-process build

我的情况

在C#项目中我正在研究我们有一个相当大的解决方案(80多个项目).现在重建时间为5分钟+使用Visual Studio 2008中的 MSBuild确实变得非常困难.

在我上周做的分析中,我发现我的构建时间花费如下:

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

  2. 调用postbuild进行反编译/编译.(20%)

  3. 进行实际编译等(20%)

除了'普通'项目bin\debug文件夹输出也被复制到外部目录以设置主'加载'程序.主程序结构有点像这样:

\loader\bin\loader.exe

\loader\plugin\plugin1\plugin1.dll

\loader\plugin\plugin1\somedependency.dll
Run Code Online (Sandbox Code Playgroud)

我做了什么

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

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

  2. 对MSBuild使用并行性(/ m).这对构建时间的帮助很小.

  3. 尝试减少项目之间的依赖关系,这当然是一件好事.

  4. 投资硬件.我发现了一些关于固态驱动器的研究,但这似乎并不乐观.

我的问题

我还注意到,当我对依赖树的根目录下的项目进行更改时,所有内容都会重建.即使改变仅在"私人"部分,并且项目的界面没有改变.

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

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

除了这个特定的建议,我一定会感谢所有建议,以使构建时间更快.

Lud*_*dwo 26

我正在开发500多个C#应用程序项目.项目并行编译,copylocal设置为false.编译时间约为37分钟,没有单元测试和代码覆盖率.增量构建13分钟,代码没有任何变化.

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

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

以下是我的经历:

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

是的,MSBuild使用依赖项目的时间戳来确定项目是否需要重建.它将输入文件(代码文件,引用的程序集,临时文件,...)时间戳与输出程序集进行比较.如果更改了某些内容,则会重新编译您的项目.尝试减少项目之间的依赖关系数量,以尽量减少重新编译.如果您的更改仅在项目的"私有"部分中,则将更改输出程序集,更改程序集时间戳,并且还将重建所有相关项目.你不能做这件事.

使用诊断详细程度运行您的构建两次,而不对代码进行任何更改,并像我在此处所描述的那样"完全"检查"构建目标"CoreCompile .您的项目文件可能有问题,每次都会重新编译项目.如果您不更改任何内容,则构建日志不应包含"构建目标"CoreCompile"完全"日志.

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

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

SSD驱动器每天对高I/O敏感.它对保修有影响.

我希望它可以帮助某人...;)


Pre*_*ous 4

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

固态硬盘非常有前途。一位同事在他的笔记本电脑中安装了固态硬盘,发现它现在比他巨大的主开发盒快得多。没有详细信息,但他声称速度快了很多倍。

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

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

  • 因为我的构建受到 I/O 限制,所以使用/m:2-4会使调试构建速度变慢
  • 发布版本通常要快得多。
  • 代码分析增加了大量时间。

总体情况:实际上,与获取源代码和运行单元测试相比,编译对我来说是相当小的成本。在我们的构建服务器上,集成测试和打包几乎一直在进行。对于我的开发盒,我安排了一个批处理文件,用于在上班前和午餐时获取源代码、构建、运行单元测试。够好了。

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

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

  1. /m: 4,通过代码分析进行调试 1:38
  2. /m: 1,通过代码分析进行调试 1:30
  3. /m: 4,不进行代码分析进行调试 1:30
  4. /m: 1,不进行代码分析进行调试 1:30
  5. /m: 1, 发布并进行代码分析: 1:30
  6. /m: 4,发布并包含代码分析:1:05
  7. /m: 4,没有代码分析的发布:0:53

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