Search code examples
visual-studiovisual-studio-2008msbuild64-bit

How can I use a single Visual Studio solution to build both x86 and x64 at the same time?


I've got an x86 Visual Studio solution with many project files in it. Some of the DLL files are designed to work as plug-ins to other applications on a user's system.

We're expanding some of the DLL files to be able to support 64-bit applications. I'd like to set up the solution/projects so that just hitting "Build" will build both the x86 and x64 versions of those DLL files. The solution contains both C++ and C# projects.

I realize that "Batch Build" is capable of building both, though it would be more convenient if developers could just click the same button as they have previously and have all of the output DLL files generated.

Here are a couple of the modifications that I've tried to a test project, but that I haven't gotten to work:

I've tried modifying the <Target Name="AfterBuild"> to try:

<Target Name="AfterBuild" Condition=" '$(Platform)' == 'x86' ">
  <PropertyGroup>
    <Platform>x64</Platform>
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>
  <CallTarget Targets="Build"/>
</Target>

But that results in the following error:

C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(565,5): error MSB4006: There is a circular dependency in the target dependency graph involving target "Build".

I think my conditions will prevent infinite recursion, but I understand how MSBuild could not see it that way.

I've also tried:

<Project DefaultTargets="MyBuild86;MyBuild64" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
...
<Target Name="MyBuild86">
  <PropertyGroup>
    <Platform>x86</Platform>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
  <CallTarget Targets="Build"/>
</Target>
<Target Name="MyBuild64">
  <PropertyGroup>
    <Platform>x64</Platform>
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>
  <CallTarget Targets="Build"/>
</Target>

But my DefaultTargets appears to be ignored from within the Visual Studio IDE.

Last, I've tried creating a separate project that imports the first project:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform>x64</Platform>
    <PlatformTarget>x64</PlatformTarget>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputPath>..\$(Configuration)\x64\</OutputPath>
    <ProjectGuid>{A885CAC3-2BBE-4808-B470-5B8D482CFF0A}</ProjectGuid>
  </PropertyGroup>
  <Import Project="BuildTest.csproj" />
</Project>

And this so far has shown the most promise. However, Visual Studio seems to ignore my OutputPath setting from this new project and instead outputs the EXE/DLL file to the path specified in the original project. There isn't any PropertyGroup block that I can see that is being executed in the original project to override this, so I'm not sure what's happening.


Solution

  • We do something similar to build core assemblies for .NET Compact Framework.

    Try this:

    <Target Name="AfterBuild">
        <MSBuild Condition=" '$(Platform)' == 'x86' " Projects="$(MSBuildProjectFile)" Properties="Platform=x64;PlatFormTarget=x64" RunEachTargetSeparately="true" />
    </Target>