msbuild_hack:在Visual Studio IDE中并行MSBuild

msbuild

msbuild

There were a number of interesting comments from my post on Faster Builds with MSBuild using Parallel Builds and Multicore CPUs.

我的帖子中有许多关于使用并行构建和多核CPU的MSBuild快速构建的有趣评论。

Here's a few good ones, and some answers. First,

这里有一些好的,还有一些答案。 第一,

Is the developer that sits inside of VS all day debugging able to take advantage of the same build performance improvements?

整天参与VS调试的开发人员是否能够利用相同的构建性能改进?

Yes, I think. This post is about my own hack to make it work.

是的,我认为。 这篇文章是关于我自己的技巧,以使其正常工作。

@Scott, there are still people using VS2005 and .Net 2.0 (our employers are either too cheap to upgrade or we work in non-profit[my case]) So it would be nice for posts like this to clearly denote that these are things only available in the 3.0/3.5+ world. Or should I just assume that .Net 2.0 is dead?

@Scott,仍有人使用VS2005和.Net 2.0(我们的雇主要么价格太便宜而不能升级,要么我们从事非营利性工作[我的情况])因此,像这样的帖子清楚地指出这些是很不错的仅在3.0 / 3.5 +版本中可用。 还是我应该假设.Net 2.0已死?

Certainly 2.0 is not dead, considering that 3.5 is still built on the the 2.0 CLR. Additionally, if you're a 2.0 shop, there's really no reason not to upgrade to VS2008 and get all the IDE improvements while still building for .NET 2.0SP1 as MSBUild supports multitargeting.

考虑到3.5仍建立在2.0 CLR上,因此2.0肯定还没死。 此外,如果您是一家2.0商店,那么实际上没有理由不升级到VS2008并获得所有IDE改进,同时仍为.NET 2.0SP1进行构建,因为MSBUild支持多目标

However, the underlying question here is, "why are you teasing me?" as this gentleman clearly wants faster builds on .NET 2.0. Well, this trick under VS2008 still works when building 2.0 stuff.

但是,这里的基本问题是:“为什么要逗我?” 因为这位先生显然希望更快地在.NET 2.0上进行构建。 好吧,VS2008下的这个技巧在构建2.0版本时仍然有效。

If you're using a Solution File (SLN) it's automatic, and if you're using custom MSBuild files, you can build .NET 2.0 stuff with the 3.5 MSBuild by putting

如果您使用的是自动生成的解决方案文件(SLN),并且使用的是自定义MSBuild文件,则可以使用3.5 MSBuild来构建.NET 2.0内容,方法是:

<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>

<TargetFrameworkVersion> v2.0 </ TargetFrameworkVersion>

under a <PropertyGroup> in your C# project. Then you can use /m and get multiproc builds. Not much changes though, because either way your build output is running on CLR2.0. (.NET 3.0 and .NET 3.5 use CLR2.0 underneath.) You will get some warnings if you try to use v3.0/v3.5 types.

在C#项目的<PropertyGroup>下。 然后,您可以使用/ m并获得multiproc构建。 但是,变化不大,因为无论哪种方式,您的构建输出都在CLR2.0上运行。 (.NET 3.0和.NET 3.5在下面使用CLR2.0。)如果尝试使用v3.0 / v3.5类型,则会收到一些警告。

It's true that parallel managed code compilation lags behind unmanaged.

的确,并行托管代码编译滞后于非托管代码。

Welcome, msbuild, to the 21st century. ;-) GNU make has the -j switch (the equivalent to /m here) _at least_ since the early-to-mid 1990's. We use its mingw port to drive Visual Studio 2003's commandline interface to build vcproj files and to handle dependencies, and since we got multi-core build machines, our build times have improved tremendously (we're talking about roughly 2,5 million SLOCs).

欢迎使用msbuild进入21世纪。 ;-)自1990年代初期到中期,GNU make至少具有-j开关(在此等效于/ m)。 我们使用其mingw端口驱动Visual Studio 2003的命令行界面来构建vcproj文件并处理依赖关系,并且由于我们拥有多核构建机,因此构建时间已大大缩短(我们正在谈论大约250万个SLOC) 。

There's a number of reasons for that. For example, Visual Basic is compiling in the background all the time while you're typing in VS using a non-reentrant in-proc compiler. The in-proc C# compiler is the same way.

有很多原因。 例如,当您使用不可重入的In-proc编译器输入VS时,Visual Basic始终在后台进行编译。 进程内C#编译器是相同的方法。

VS Hack的多核MSBuild (The Multicore MSBuild with VS Hack)

This trick is unsupported because it hasn’t been tested. Off the top of our collective head, I can’t think of why it wouldn’t work OK, at least if your solution is all VB/C#. Having VC projects in your solution, especially if there are project references with the VB/C# projects, would probably not work so well. That’s because VC projects are not native MSBuild format in VS2008.

不支持此技巧,因为尚未对其进行测试。 在我们集体负责人的头上,我想不出为什么它行不通,至少在您的解决方案全部是VB / C#的情况下。 在解决方案中包含VC项目,尤其是在VB / C#项目中有项目引用的情况下,可能效果不佳。 这是因为VC项目不是VS2008中的本机MSBuild格式。

To start with, this is a totally obvious hack. We'll add an External Tool to Visual Studio to call MSBuild, then add some Toolbar buttons.

首先,这是一个完全显而易见的hack。 我们将在Visual Studio中添加一个外部工具来调用MSBuild,然后添加一些工具栏按钮。

First, Tools | External Tools. We'll add MSBuild, pointing it to the v3.5 .NET Framework folder. Then, we'll add /m to the arguments for multi-proc and /v:m (where the v is verbosity and the m is minimal) to tone down MSBuild's chattiness. Finally, we'll check the Use Output Window box and set the initial directory to the current Solution's Directory.

一,工具外部工具。 我们将添加MSBuild,将其指向v3.5 .NET Framework文件夹。 然后,我们将/ m添加到multi-proc和/ v:m的参数中(其中v是冗长而m是最小),以降低MSBuild的即时消息。 最后,我们将选中“使用输出窗口”框,并将初始目录设置为当前解决方案的目录。

Adding MSBuild to External Tools

Next, we'll right click on the Toolbar, and hit Customize.

接下来,我们将右键单击工具栏,然后单击“自定义”。

External Tools in Visual Studio

Then, from the Commands tab, drag the number of the newly added External Tool (mine is #3) to the Toolbar. I also added a little Lode Runner icon to the button. Additionally, I added a Clean Solution option, just because I like it handy.

然后,从“命令”选项卡中,将新添加的“外部工具”的编号(我的是#3)拖到工具栏上。 我还向按钮添加了一个Lode Runner图标。 另外,我添加了“干净解决方案”选项,只是因为我很喜欢它。

Parallel MSBuild Button in Visual Studio

You can also re-map Ctrl-Shift-B if it makes you happy, but I used Ctrl-Shift-M, mapping it to the Tools.ExternalCommand, again, in my case it is #3.

如果让您感到满意,您也可以重新映射Ctrl-Shift-B,但是我使用Ctrl-Shift-M将其映射到Tools.ExternalCommand,在我的情况下,它再次是#3。

image

At this point, I can now run MSBuild out-of-proc from inside Visual Studio.

在这一点上,我现在可以从Visual Studio内运行的MSBuild外的进程内

什么不起作用 (What DOESN'T Work)

The only thing that doesn't work for me so far is that the errors reported by MSBuild don't appear neatly parsed in the Error List. For some, this may be a deal breaker. However, the good news is that if you double click on the errors in the Output Window you WILL get taken automatically to the right file and line number which is all I personally care about. Still, sucks.

到目前为止,唯一对我不起作用的是,MSBuild报告的错误未在“错误列表”中很好地解析。 对于某些人来说,这可能会破坏交易。 但是,好消息是,如果您双击“输出窗口”中的错误,您将自动获得正确的文件和行号,这是我个人关心的全部。 不过,糟透了。

image

这个hack的陷阱 (Gotchas for this Hack)

If you're building against a SLN file you can use Project References or manually specified project dependencies otherwise MSBuild has no way to figure out the dependencies and you might get "file locked" or other weird concurrency errors.

如果要针对SLN文件进行构建,则可以使用项目引用或手动指定项目依赖项,否则MSBuild无法找出依赖项,并且可能会出现“文件锁定”或其他奇怪的并发错误。

Also, even if Project to Project references are set up, sometimes project authors are a bit sloppy (I've done this) and inadvertently access the same file in multiple projects, which can cause spurious file locking/access errors. If you see this behavior, turn off multiproc.

同样,即使设置了“项目到项目”引用,有时项目作者还是有点草率(我已经这样做了),并且无意间访问了多个项目中的同一文件,这可能导致虚假的文件锁定/访问错误。 如果您看到此行为,请关闭multiproc。

Note also that while you can do builds with MSBuild like this, if you get F5 and start a debug session the VS in-process compilers will do a quick build. It WILL figure out that it doesn't need to do anything, but it will check.

还要注意,虽然可以使用MSBuild进行这种构建,但是如果获得F5并启动调试会话,VS进程内编译器进行快速构建。 它会指出它不需要执行任何操作,但是会进行检查。

嘿,这对我来说不快吗? (Hey, it's NOT faster for me?)

If you have a small solution (<10 projects) and/or your solution is designed such that each project "lines up" in a dependency chain rather than a dependency tree, then there will be less parallelism possible.

如果您的解决方案很小(少于10个项目),并且/或者您设计的解决方案使得每个项目都在依赖关系而不是依赖关系树中“排队” 那么并行性可能会更少。

If you're using a small number of projects, or you're using Visual Basic on small projects, which is compiling in the background anyway, you might not get big changes. Additionally, remember that we're shelling out n new instances of MSBuild, while VS compiles using the in-process versions of the languages compilers. With a small number of projects, in-proc single-core might be faster.

如果您使用的项目数量很少,或者您正在小项目上使用Visual Basic(无论如何都是在后台进行编译),则可能不会有大的变化。 此外,请记住,我们正在炮轰n个新的MSBuild实例,而VS使用语言编译器的进程内版本进行编译。 对于少量项目,进程内单核可能会更快。

我有900个项目,而Visual Studio速度很慢,这是怎么回事? (I've got 900 Projects and Visual Studio is Slow, what's the deal?)

"Doctor, doctor, it's hurts what I do that!"

“医生,医生,我这样做很伤人!”

"Then don't do that"

“那就不要那样做”

Seriously, yes, there are limits. Personally, if you have more than 50 or so projects, it's time to break them out into sub-system SLN files, and keep the über-solution just for the build server.

严重的是,有限制。 就个人而言,如果您有超过50个左右的项目,是时候将它们分解为子系统SLN文件,并保留仅适用于构建服务器的über解决方案了。

The team is aware that if you have hundreds of projects in a solution VS totally breaks down. I, and many others, have made suggestions of things like a "tree of projects" where you could build from one point down, and there's ways you can simulate this with multiple-configurations, but it's kinda lame right now if you have a buttload of projects.

团队知道,如果您在解决方案中有数百个项目,则VS会完全崩溃。 我和其他许多人都提出了类似“项目树”的建议,您可以从一个点开始构建,并且有多种方法可以通过多种配置对此进行模拟,但是如果您的工作量很大,那么现在有点la脚项目。

Here's a post I did three years ago called How do you organize your code? and I think it still mostly works today. I was using NAnt at the time, but the same concepts apply to MSBuild. Forgive me now, as I quote myself:

这是我三年前写的一篇文章,您如何组织代码? 我认为今天它仍然可以正常工作。 我当时使用的是NAnt,但是相同的概念也适用于MSBuild。 现在请原谅我,正如我自己引用:

Every 'subsystem' has a folder, and usually (not always) a Subsystem is a bigger namespace. In this picture there's "Common" and it might have 5 projects under it. There's a peer Common.Test. Under CodeGeneration, for example, there's 14 projects. Seven are sub-projects within the CodeGeneration subsystem, and seven are the NUnit tests for each. The reason that you see Common and Common.Test at this stuff is that they are the 'highest." But the pattern follows as you traverse the depths. Each subsystem has it's own NAnt build file, and these are used by the primary default.build.

每个“子系统”都有一个文件夹,通常(并非总是)子系统是更大的名称空间。 在这张照片中有一个“ Common”,它下面可能有5个项目。 有一个对等的Common.Test。 例如,在CodeGeneration下,有14个项目。 七个是CodeGeneration子系统内的子项目,而七个则是每个项目的NUnit测试。 之所以会看到Common和Common.Test,是因为它们是“最高的”。但是在遍历深度时遵循的模式是:每个子系统都有自己的NAnt构建文件,并且主要默认使用这些文件。建立。

This is not only a nicer way to lay things out for the project, but also for the people on the project, most of whom are not making cross-subsystem changes.

这不仅是为项目布置事情的一种更好的方法,而且对于项目中的人们来说,大多数人并没有进行跨子系统的更改,这是一种更好的方法。

亲爱的读者,为您准备的行动项目 (Action Item for you, Dear Reader)

If you have feedback then email the MSBuild team at msbuild@ (you know the company name) and they will listen. I warned them you might be emailing, so be nice. If you DEEPLY want multi-proc builds in the next version of Visual Studio, flood them with your (kind) requests. They are aware of ALL these issues and really want to make things better.

如果您有反馈意见,请给MSBuild团队发送电子邮件至msbuild @(您知道公司名称),他们将进行监听。 我警告他们您可能正在通过电子邮件发送邮件,所以请保持友好。 如果您很想在下一版本的Visual Studio中进行多进程构建,请使用您的(种类)请求进行泛洪。 他们意识到所有这些问题,并真的希望使事情变得更好。

It's interesting as I've been at MSFT about 7 months now to realize that for something like multi-proc builds to work it involves (all) the Compiler Teams, the VS Tooling Teams, and the MSBuild folks. Each has to agree it's important and work towards the goal. Sometimes this is obvious and easy, and other times, less so.

有趣的是,我到MSFT大约7个月了才意识到,要使诸如multi-proc生成之类的东西起作用,它需要(全部)编译器团队,VS工具团队和MSBuild团队。 每个人都必须同意其重要性,并朝着目标努力。 有时这很明显且容易,而有时则不那么容易。

Thanks for Dan Moseley, Cliff Hudson and Cullen Waters for their help!

感谢Dan Moseley,Cliff Hudson和Cullen Waters的帮助!

Related Links

相关链接

翻译自: https://www.hanselman.com/blog/hack-parallel-msbuilds-from-within-the-visual-studio-ide

msbuild

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值