Wednesday, 8 May 2013

MSBuild and locked files

In a previous post I had bemoaned how the latest incarnation of MSBuild refuses to recognize projects beyond the scope of the active solution configuration (something which Microsoft have no intention of fixing), and how this had given me the push to extract key functionality from MSBuild and bring it in-house as it were.

Well, I thought I'd journal a few interesting technical points along the way:

Building dependent projects

It would seem that whilst MSBuild won't recognize referenced projects outside the current solution configuration scope; however, this rule seems to be only applied to the CSC compiler activities. I hit a conundrum today, that in theory should have not been possible.

I was building several code projects in a specific order, the order was established so that all dependencies were satisfied in the correct order. And yet, two projects (built in parallel)  were failing to build over a mysterious locked file, in a third and seemingly unrelated project.

A little investigation later, revealed that MSBuild can and will (when you're not expecting it, or even want it) build referenced project(s), even after they've already been built!

In my case it was the Entity Framework (EDMX) compiler being invoked by both independent build processes, being asked to compile the same referenced project.

You can imagine my rage. Weeks of effort poured into developing a solution to work around the fact that MSBuild would no longer "see" referenced projects, only to hit this problem further down the line, when it's secretly doing the very thing it wouldn't do in the first place!

Anyhow, I'm not being entirely fair, I'm not caring apples with apples as they say.

When working in a solution, the solution configurations create virtual walled gardens around the projects. When compiling projects independently, the behavior is obviously different, there are no virtual walls, and referenced code projects are rebuilt.

If, like me, you've already taken care of this reference dependency, and MSBuild's "default rebuild" behavior  is not desirable:

MSBuild.exe "YourTask.csproj" /p:BuildProjectReferences=False