MSBuild overwriting dependencies

msbuild

Ok, so I've got a somewhat complicated problem with my build environment that I'm trying to deal with.

I have a solution file that contains multiple C# projects which is built by a NAnt script calling MSBuild – passing MSBuild the name of the solution file and a path to copy the binaries to. This is because I want my automated build environment (CruiseControl.Net) to create a folder named after the revision of each build – this way I can easily go back to previous binaries for any reason.

So idealy I have a folder layout like this

c:\build\nightly\rev1
c:\build\nightly\rev2
c:\build\nightly\rev3
...
c:\build\nightly\rev10
etc.

The problem that's arisen is I recently added the latest version of the Unity IoC container to my project, checking it directly out of MS's online SVN repository. What's happening is I have a Silverlight 3 project that references the Silverlight version of Unity but I also have other projects (namely my Unit testing project) that reference the standard (non-Silverlight) version of Unity.

So what happens is since MSBuild is dumping everything into one single folder the Silverlight version of the Unity assembly is overwriting the non-Silverlight version because they have the exact same assembly file name.

Then when CruistControl runs my unit tests they fail because they don't have the proper dependencies available anymore (they try to load the Silverlight specific Unity assembly which obviously doesn't work).

So what I want to do is:

  • keep my desired output directory
    structure (folder\revision)
  • I don't want to have to manually edit
    every single proj file I have as this
    is error prone when adding new
    projects to the solution

Idealy I would like MSBuild to put everything into a folder structure similar to this:

nightly\revision1\project1
nightly\revision1\project2
nightly\revision1\project3
...
nightly\revision2\project1
nightly\revision2\project2
nightly\revision2\project3
etc

I can't modify the Unity project to give it a different file name because it comes from another SVN repository I cannot commit changes to. I found a similar question posted here and the suggested solution was to use a "master" MSBuild file that used a custom task to extract all the project file names out of the solution then loop over each one building them. I tried that but it doesn't build them in the order of their dependencies, so it fails for my project.

Help?

Best Answer

Firstly I would always have the build server delete the old working copy and check out a fresh copy to avoid any problems with stale artifacts from the previous build.

Next I would have nant or msbuild build the solutions as before with the artifacts from each build going to their local working output folders.

After that I'd move the artifacts from their working paths to their output paths, this shouldn't require digging through the project files since you can just tell msbuild/nant to copy working\project1\bin\release\**\*.* to artifacts\project1\.

The script that does this should ideally be stored along with the source with the main file, e.g. build.nant or build.proj in top level of the trunk.