<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>MSBuild Team Blog : multiproc</title><link>http://blogs.msdn.com/msbuild/archive/tags/multiproc/default.aspx</link><description>Tags: multiproc</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>How would you spend $100 on MSBuild?</title><link>http://blogs.msdn.com/msbuild/archive/2007/11/17/how-would-you-spend-100-on-msbuild.aspx</link><pubDate>Sat, 17 Nov 2007 21:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6341759</guid><dc:creator>msbuild</dc:creator><slash:comments>117</slash:comments><comments>http://blogs.msdn.com/msbuild/comments/6341759.aspx</comments><wfw:commentRss>http://blogs.msdn.com/msbuild/commentrss.aspx?PostID=6341759</wfw:commentRss><description>&lt;P&gt;We're currently planning for our next version (aka, "Dev10" - no code name this time) and subsequent releases. In that spirit, I'd like to do a quick poll of MSBuild aficionados to help us keep our "vision" for MSBuild aligned with yours, our customers. &lt;/P&gt;
&lt;P&gt;First, a caveat - while ideally I would like to rank the results and work down the list, the reality is that we have other constraints: although we are a separate build platform, our biggest customer by far is Visual Studio and its customers. There's a lot more Visual Studio users than direct MSBuild users, so when Visual Studio needs to add a feature that requires work on MSBuild, we have to help. Then there's other constraints, like team resources. There's no guarantee which of these will appear in what version, and some of them may not be worth any investment. Some of them I just made up.&lt;/P&gt;
&lt;P&gt;OK. Here’s some brainstormed features. Some of them are properly Visual Studio features, but they overlap closely with build:&lt;/P&gt;
&lt;P&gt;1) Higher performance multiprocessor support. For example, we suspect there is plenty of room to improve the scheduling we do, and find speedups elsewhere in the code. As more and more of us have multicore machines, this might be a good place to invest.&lt;/P&gt;
&lt;P&gt;2) VC support. This means converting VC projects (.vcproj) to MSBuild format, a customizable and extensible build process entirely defined by MSBuild .targets files rather than in makefiles or built into the VC project system, reuseable tasks for native code tools just like we have today for managed code, changing the VS project system for VC projects to sit on top of MSBuild format projects and build process, and replacing use of vcbuild.exe with msbuild.exe.&lt;/P&gt;
&lt;P&gt;3) Support for other Microsoft project types that aren't yet in MSBuild format: Deployment/MSI (.vdproj), SQL Reporting (.rptproj), Biztalk (.btproj), Speech server (.prproj)&amp;nbsp;etc -- whether currently supported by a VS project system or not. This is essentially a process of internal evangelization and encouragement for us.&lt;/P&gt;
&lt;P&gt;4) Conversion of Visual Studio solution files (.sln files) and their (rudimentary) build process to MSBuild format and the VS support for reading and writing these, opening the way to create a targets file useful for traversing a tree of projects, and to let VS cleanly support n-level project hierarchies. &lt;/P&gt;
&lt;P&gt;5) Extensible up-to-date checking: a way to plug in up-to-date checker extensions that you could use on selected Targets as an alternative to the simple timestamp checking you are currently restricted to. Perhaps including a ready-made extension that would by some means automatically support transitive dependencies - header files are an example of these; or to compare public interfaces for significant changes.&lt;/P&gt;
&lt;P&gt;6) Distributed Build. (Like multiprocessor build we are now shipping, but building spread over a set of machines that you have pre-provisioned; possibly opening the way for future Team Build support for it too.)&lt;/P&gt;
&lt;P&gt;7) Extensible reuseable inline tasks. This means the ability to create extensions that consume the language or description format of your choice and to create a task that you could use without explicit compilation or deployment. For example, a Powershell extension that you could use to create tasks implemented in Powershell. Think of putting script underneath a &amp;lt;UsingTask&amp;gt; element. These inline tasks would be easy to create and share online. Might include ready-made extensions for Powershell, and/or a data-description format for tool switches, so you could quickly create a task wrapping a command line tool without any compilation.&lt;/P&gt;
&lt;P&gt;8) Typing and scoping for items and properties. For example, declaring an item to contain a path; letting a property fall out of scope at the end of a target.&lt;/P&gt;
&lt;P&gt;9) Extensible functions. Today we have only 'exists(..)' and it's stepchild 'hastrailingslash(...)'. This would be an extension allowing new functions to be created for use in conditional expressions, and possibly elsewhere, and some functions like perhaps combinepath($(root),$(file)). Perhaps more built-in metadata to go along with %(Filename) and such.&lt;/P&gt;
&lt;P&gt;11) An MSBuild debugger with full Visual Studio support for stepping, inspecting locals, and breakpoints. Today you have to use &amp;lt;Message&amp;gt; tasks and gaze at diagnostic logging output.&lt;/P&gt;
&lt;P&gt;12) Visualization for project and target dependencies, mining of what files are consumed by what projects, impact analysis for changes to particular files, possibly leading to support for build refactoring at the project/tree level. This is essentially richer logging and datamining and a high level on a huge source tree.&lt;/P&gt;
&lt;P&gt;So now here's the poll. If you had only $100 to spend, how would you distribute it amongst them? &lt;/P&gt;
&lt;P&gt;Dan&lt;/P&gt;
&lt;P&gt;(Edit: gave Distributed build a unique number :-) )&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6341759" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/msbuild/archive/tags/MSBuild+in+Visual+Studio/default.aspx">MSBuild in Visual Studio</category><category domain="http://blogs.msdn.com/msbuild/archive/tags/Dan+Moseley/default.aspx">Dan Moseley</category><category domain="http://blogs.msdn.com/msbuild/archive/tags/object+model/default.aspx">object model</category><category domain="http://blogs.msdn.com/msbuild/archive/tags/multiproc/default.aspx">multiproc</category><category domain="http://blogs.msdn.com/msbuild/archive/tags/msbuild/default.aspx">msbuild</category></item><item><title>Enabling multiprocessor support in an MSBuild host</title><link>http://blogs.msdn.com/msbuild/archive/2007/10/22/enabling-multiprocessor-support-in-an-msbuild-host.aspx</link><pubDate>Mon, 22 Oct 2007 02:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5587111</guid><dc:creator>msbuild</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/msbuild/comments/5587111.aspx</comments><wfw:commentRss>http://blogs.msdn.com/msbuild/commentrss.aspx?PostID=5587111</wfw:commentRss><description>&lt;P&gt;As you know, MSBuild in .NET 3.5 adds support for building projects concurrently. MSBuild.exe exposes this support with the new&amp;nbsp;&lt;A class="" href="http://blogs.msdn.com/aaronhallberg/archive/2007/10/02/fancy-new-command-line-options-for-msbuild.aspx" mce_href="http://blogs.msdn.com/aaronhallberg/archive/2007/10/02/fancy-new-command-line-options-for-msbuild.aspx"&gt;/m switch&lt;/A&gt;, and because &lt;A class="" href="http://blogs.msdn.com/aaronhallberg/default.aspx" mce_href="http://blogs.msdn.com/aaronhallberg/default.aspx"&gt;Team Build&lt;/A&gt;&amp;nbsp;uses MSBuild to build projects, it will get a speed up as well. In this release, Visual Studio doesn't use this to build managed projects concurrently, but you can write your own host that can build in parallel. &lt;/P&gt;
&lt;P&gt;There are some limitations. In 3.5, you can't build in-memory projects concurrently, only project files. Also, I don't like the API much. Msbuild.exe was the only host we were focusing on in 3.5 and we didn't make it pretty. That will change.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Anyway, here's an example. It assumes you have a sleep.exe in the same directory as the projects. So "sleep 3" will pause for 3 seconds. Our objective here&amp;nbsp;is to run two sleeps concurrently :-)&lt;/P&gt;
&lt;P&gt;using System;&lt;BR&gt;using Microsoft.Build.BuildEngine;&lt;BR&gt;using Microsoft.Build.Framework;&lt;BR&gt;using System.Reflection;&lt;/P&gt;
&lt;P&gt;namespace HostMsBuildExeTest&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class Program&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [STAThread]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main(string[] args)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We need to tell MSBuild where msbuild.exe is, so it can launch child nodes&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string parameters = @"MSBUILDLOCATION=" + System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + @"\..\Microsoft.NET\Framework\v3.5";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We need to tell MSBuild whether nodes should hang around for 60 seconds after the build is done in case they are needed again&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool nodeReuse = true; // e.g.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!nodeReuse)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameters += ";NODEREUSE=false";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We need to tell MSBuild the maximum number of nodes to use. It is usually fastest to pick about the same number as you have CPU cores&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int maxNodeCount = 3; // e.g.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the engine with this information&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Engine buildEngine = new Engine(null, ToolsetDefinitionLocations.Registry | ToolsetDefinitionLocations.ConfigurationFile, maxNodeCount, parameters);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create a file logger with a matching forwarding logger, e.g.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileLogger fileLogger = new FileLogger();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileLogger.Verbosity = LoggerVerbosity.Detailed;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assembly engineAssembly = Assembly.GetAssembly(typeof(Engine));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string loggerAssemblyName = engineAssembly.GetName().FullName;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoggerDescription fileLoggerForwardingLoggerDescription = new LoggerDescription("Microsoft.Build.BuildEngine.ConfigurableForwardingLogger", loggerAssemblyName, null, String.Empty, LoggerVerbosity.Detailed);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create a regular console logger too, e.g.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConsoleLogger logger = new ConsoleLogger();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logger.Verbosity = LoggerVerbosity.Normal;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Register all of these loggers&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buildEngine.RegisterDistributedLogger(fileLogger, fileLoggerForwardingLoggerDescription);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buildEngine.RegisterLogger(logger);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do a build&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buildEngine.BuildProjectFile("root.proj");&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Finish cleanly&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buildEngine.Shutdown();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Now&amp;nbsp;for testing purposes, I created three projects like this:&lt;/P&gt;
&lt;P&gt;root.proj&lt;BR&gt;Project xmlns="&lt;A href="http://schemas.microsoft.com/developer/msbuild/2003"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/A&gt;" ToolsVersion="3.5"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Target Name="t"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Message Importance="high" Text="## in&amp;nbsp;root building children ##"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;MSBuild Projects="1.csproj;2.csproj" BuildInParallel="true"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Message Importance="high" Text="## in&amp;nbsp;root done building&amp;nbsp;##"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Target&amp;gt;&lt;BR&gt;&amp;lt;/Project&amp;gt;&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;1.csproj&lt;/P&gt;
&lt;P&gt;&amp;lt;Project xmlns="&lt;A href="http://schemas.microsoft.com/developer/msbuild/2003"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/A&gt;" ToolsVersion="3.5"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Target Name="t"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Message Importance="high" Text="## starting&amp;nbsp;1 ##"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Exec Command="sleep 3"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Message Importance="high" Text="## finishing&amp;nbsp;1 ##"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Target&amp;gt;&lt;BR&gt;&amp;lt;/Project&amp;gt;&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;2.csproj&lt;/P&gt;
&lt;P&gt;&amp;lt;Project xmlns="&lt;A href="http://schemas.microsoft.com/developer/msbuild/2003"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/A&gt;" ToolsVersion="3.5"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Target Name="t"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Message Importance="high" Text="## starting 2 ##"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Exec Command="sleep 3"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Message Importance="high" Text="## finishing&amp;nbsp;2 ##"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Target&amp;gt;&lt;BR&gt;&amp;lt;/Project&amp;gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Notice that the root project uses the &amp;lt;MSBuild&amp;gt; task with the parameter BuildInParallel="true". This is where the parallelism starts: you still only invoke the build on a single root project. Without BuildInParallel="true", the &amp;lt;MSBuild&amp;gt; task will build serially. In a tree of projects, you would want every node to build its children with BuildInParallel="true".&lt;/P&gt;
&lt;P&gt;Here's the output&amp;nbsp;I get:&lt;/P&gt;
&lt;P&gt;c:\test&amp;gt;test.exe&lt;BR&gt;Build started 10/21/2007 5:02:55 PM.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;gt;Project "c:\test\projects\root.proj" on node 0 (defaul&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t targets).&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ## in&amp;nbsp;root building children ##&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;gt;Project "c:\test\projects\root.proj" (1) is building "&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\test\projects\1.csproj" (2) on node 1 (default tar&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gets).&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ## starting&amp;nbsp;1 ##&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;gt;Project "c:\test\projects\root.proj" (1) is building "&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\test\projects\2.csproj" (3) on node 2 (default tar&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gets).&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ## starting 2 ##&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;gt;t:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ## in&amp;nbsp;root done building ##&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;gt;Done Building Project "c:\test\projects\root.proj" (de&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fault targets).&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;gt;t:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ## finishing&amp;nbsp;2 ##&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;gt;Done Building Project "c:\test\projects\2.proj" (de&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fault targets).&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;gt;t:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ## finishing&amp;nbsp;1 ##&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;gt;Done Building Project "c:\test\projects\1.proj" (de&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fault targets).&lt;/P&gt;
&lt;P&gt;Build succeeded.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Warning(s)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Error(s)&lt;/P&gt;
&lt;P&gt;Time Elapsed 00:00:03.21&lt;/P&gt;
&lt;P&gt;As you can see, the two 3-second sleeps ran concurrently, so the build took 3.21 seconds overall. &lt;/P&gt;
&lt;P&gt;Just to prove it I changed the "3" to "1" and got this:&lt;/P&gt;
&lt;P&gt;Build succeeded.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Warning(s)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Error(s)&lt;/P&gt;
&lt;P&gt;Time Elapsed 00:00:06.11&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There's lots more to say about multiproc support, especially to explain the types of loggers I attached here, and that will be the subject of future posts. Even if you don't host MSBuild, you may want to create "traversal" projects (something like solution files, but nestable) that build their children in parallel. I'll explain that too in due course.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Just to be clear though, for most of us, it isn't necessary to know any of this. We can just point msbuild.exe at our solution file and throw the "/m" switch and our build will be faster.&lt;/P&gt;
&lt;P&gt;Dan&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5587111" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/msbuild/archive/tags/Dan+Moseley/default.aspx">Dan Moseley</category><category domain="http://blogs.msdn.com/msbuild/archive/tags/object+model/default.aspx">object model</category><category domain="http://blogs.msdn.com/msbuild/archive/tags/multiproc/default.aspx">multiproc</category></item></channel></rss>