Managed Incremental Build

Real-world solutions typically consist of multiple projects – often many projects. The projects are usually related to each other in some sort of dependency relationship. For example, consider a solution with 3 primary output targets (P1-3), a few intermediate components (I1-5), and a few shared dlls (L1-3). The dependencies might look something like this (totally arbitrary, but plausible example):

     Solution: P1, P2, P3

     P1: I1, I2

     P2: I1, I3, I4

     P3: I5, I2

     I1: L1

     I2: L1

     I3: L1, L2

     I4: L1, L3

     I5: L3

Now, this might be a really big solution. Who knows—it might take an hour or more to build the whole solution. But you probably don’t do full builds every time you make a change. Here, incremental build is your friend. Making a change in P1 only requires a build of P1. No surprise. But what if you make a change in L1? It depends on what kind of change, of course. If you change something in the headers that dependents of L1 use (or idl, etc.), then you’re basically rebuilding the whole world (everything except L2, L3). If you only change an implementation detail, nothing else needs to be rebuilt. That’s the way it’s been for years in the native world.

But suppose you’ve decided to use managed code for part of your solution.  Now you have a solution with both native and managed projects. Maybe you started with an existing huge solution, and you added a project written in C++/CLI or your managed language of choice. And maybe this project is a common dependency in your solution—your L1. As before, if you change something in L1 that affects the build of dependents, then all the dependents will build. Ok, but what if you only change a tiny implementation detail? In Visual Studio 2005 and earlier, we would rebuild the entire dependency tree from L1, because the assembly changed! This can really slow down iteration times when making implementation changes in L1. With Managed Incremental Build in Orcas, however, this scenario is greatly improved by not rebuilding anything else when only implementation details changed in L1.

How is this done? With a managed L1, you don’t need headers or idl files for the contact. The assembly is the contract. So there’s no simple file to check to see if it changed to determine whether dependents need to be rebuilt. But now, when a managed dependency changes (even if it’s not in your solution), we reflect over the exposed metadata in the assembly and save it. If there is already a saved version of this data, we compare it. If it is the same, then the assembly hasn’t changed in any way that impacts the build of dependents, so they are not rebuilt. If the metadata is different, then dependents are rebuilt. 

Build times in Orcas are now dramatically slashed for solutions where only an implementation detail changed in a dependent assembly.

Curt Carpenter

Visual C++ IDE