One of Team Build’s behaviors that I often get questions about is it overriding the OutDir property and putting all of the build outputs in a single directory per platform and configuration. The typical reason that people want to split the Team Build outputs is to match how they’ll be deployed, for example, into a “Client” directory, a “WindowsService” directory, and a “WebSite” directory.
There’s a number of solutions to this problem but there’s a very simple one that I’ve used numerous times and have recommended to several people so I wanted to blog it so I can just point people at this post. It won’t work in all scenarios but if it does work in your scenario it’s undoubtedly the easiest solution while still offering some flexibility.
Team Build will create a directory for each platform and configuration pair so we can leverage this to split our outputs by defining solution-level configurations for each split of the outputs we want. Since most people find Configuration useful (to allow switching between Debug and Release) we’ll use Platform to define the different sets of outputs we want.
In the following example I’ll be building a solution containing four projects, “Client”, “Common”, “WebSite”, and “WindowsService”. We’re going to create three folders in the drop, “Client” (containing the outputs from the “Client” and “Common” projects), “WebSite” (containing the outputs from the “WebSite” and “Common” projects), and “WindowsService” (containing the outputs from the “WindowsService” and “Common” projects). I usually also create a platform called “All” containing all projects which is the one developers would select in Visual Studio when working with the solution.
The first thing we need to do is define each of the “platforms” we want to be able to build. To do this:
- Open the solution in Visual Studio.
- From the Configuration dropdown on the toolbar select Configuration Manager. You can also access this by selecting Configuration Manager from the Build Menu.
- For each “platform” you want to create in the drop (in our example, “Client”, “WindowsService”, and “WebSite”):
- From the Active Solution Platform dropdown select New.
- Enter the name that you want the directory in the drop to be called, for example, “Client”.
- Select <Empty> from the Copy Settings From dropdown to start with a blank list.
- Make sure that Create New Project Platforms is not checked. Otherwise, the platform will be added to each of your projects. We want to create solution-level platforms and map these to existing project-level platforms.
- Click OK.
- For each project whose outputs you want dropped in this folder tick the corresponding checkbox in the Build column. You must tick any dependencies as well, these won’t automatically be built.
- Repeat step 3.6 for each configuration in the Active Solution Configuration dropdown (e.g. “Debug” and “Release”). This ensures that the correct projects will be built regardless of the Configuration selected.
- You may also want to remove the built-in platforms (such as Mixed Platforms, Any CPU, x86). To do this select Edit from the Active Solution Platform dropdown, select the platform, and click Remove.
- Save the solution and check it into version control.
These screenshots show the Debug and Release configurations for the WindowsService “platform”:
Finally, we need to configure the build definition to build each of our new platforms:
- Edit the build definition in Visual Studio.
- Click the Process tab.
- Select the Items To Build process parameter and click the ellipsis button on the right-hand side.
- Click the Configurations tab.
- For each “platform” you want to create in the drop:
- Click Add.
- Select or enter the configuration you want to build in the Configuration column.
- Enter the name of the “platform” you want to build (e.g. “Client”) in the Platform column.
- Click Close.
- Save the build definition.
This screenshot shows the Items To Build dialog configured to build the “Client”, “WebSite”, and “WindowsService” “platforms” using Debug and Release configurations:
These screenshots show the resulting drop structure for the “Client” “platform”: