How to reference platform specific (x86/x64) assemblies in Visual Studio projects

Let’s say you have a third party library that you want to reference from your project. By default platform target in Visual Studio is “Any CPU”. But the library is compiled for specific target – x86 or x64. When you’re working in a team, have a build server and all of them is in different platforms you’ll start to have issues. Like, project with an x64 referenced assembly working ok on your x64 machine and failing on x86 computers and so on.

For us it was the “System.Data.SQLite” – the ADO.NET provider for SQLite. It is provided compiled separately for 32 and 64 bit systems. It was not easy to figure out how to manage references to SQLite provider without making too much changes in our projects and build scripts.

I’ve found an elegant solution for it: manually modifying project files that are using it to add a conditional elements to <Project> node. Look at this code:

  <Choose>
    <When Condition=”$(PROCESSOR_ARCHITECTURE) == ‘AMD64′ Or $(PROCESSOR_ARCHITEW6432) == ‘AMD64′”>
      <ItemGroup>
        <Reference Include=”System.Data.SQLite, Version=1.0.65.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64″>
          <SpecificVersion>False</SpecificVersion>
          <HintPath>..\Lib\x64\System.Data.SQLite.DLL</HintPath>
        </Reference>
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <Reference Include=”System.Data.SQLite, Version=1.0.65.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86″>
          <SpecificVersion>False</SpecificVersion>
          <HintPath>..\Lib\x86\System.Data.SQLite.DLL</HintPath>
        </Reference>
      </ItemGroup>
    </Otherwise>
  </Choose>

<Choose> <When Condition= … /> <Otherwise … /> </Choose> – it’s fun how people are trying to add “behavior” to a such static thing as XML. Well, it works, sometimes…

Detection of the current platform is based on checking of two environment variables: PROCESSOR_ARCHITECTURE and PROCESSOR_ARCHITEW6432 to detect “bitness” of running OS/processes. Details of this you can find in the post of David Wang HOWTO: Detect Process Bitness.

Working like a charm for us.

  1. #1 by Bert on September 11, 2010 - 20:16

    How do you cope with the fact that your build server can only be one architecture at the time? Do you use 2 build servers for building versions for both architectures?

    • #2 by Valeriu Caraulean on September 12, 2010 - 15:16

      Well, I’ve need for such solution in order to be able to run tests on my x64 dev rig and on an older x86 buildserver. As for your question, yes, I think you have to use two different build servers if you want x86 and x64 builds. But are you sure you need that? Unless you have some interop/native components in your code bound to specific platforms, the “Any CPU” target works just wonderful.

  2. #3 by Dave Black on January 3, 2011 - 22:39

    Hi Bert,

    You shouldn’t need to 2 build servers unless you are doing any of the following:

    1. Running ‘ngen.exe’ on the compiled app/dll’s
    2. Actually running the compiled app on the build server

    Remember that the VisualStudio/MSBuild compiler only produces IL (Intermediate Language). The IL for either platform can be produced on any platform. The IL isn’t actually turned into native code (x86, x64, ia64) until the JIT hits it. The JIT will produce the native code in either of the 2 scenarios mentioned above.

    HTH

    Dave Black, MCPD, MCTS
    .NET Solution Architect

Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.