0
votes

I have three projects in my solution:

ProjectA : contains reference to ProjectC
ProjectB : contains reference to ProjectC
ProjectC : references third.party.dll.A or third.party.dll.B

During compilation, I want Project C to reference either third.party.dll.A or third.party.dll.B depending on which one of ProjectA or ProjectB that I a have set as the startup project and am launching/compiling via the IDE.

How can I set up my solution so I can use an MSBuild conditional reference in ProjectC.csproj to determine whether ProjectA or ProjectB is currently being compiled?

(In the .csproj file I tried checking if $(DefineConstants) contains a certain value, but it seems like $(DefineConstants) only contains the symbols defined in ProjectC, and not those defined in ProjectA and ProjectB.)

(FYI: I am using Xamarin Studio on a Mac. But I assume that if there is a way to make this work for Visual Studio, it should also work in Xamarin Studio.)

1

1 Answers

0
votes

No, you cannot do that. Project references in MSBuild are not configurable to the extend you want them to be, configuration of the build for referenced projects are hard-coded in standard msbuild .targets files.

There are couple of possible workarounds for your case. The easiest one is to create two projects: ProjectC1 and ProjectC2. C1 will use one of the third-party library, while C2 will use another one. You can make ProjectC1 and ProjectC2 share the same source files, so there will be no code duplication.

Another possible workaround is to make references to third.party.dll.A and third.party.dll.B with conditional assignment, like this:

<ItemGroup>
  <ProjectReference Condition="'$(BuildA)' == 'true'" Include="pathto\third.party.dll.A">
    <Name>third.party.dll.A</Name>
  </ProjectReference>
  <ProjectReference Condition="'$(BuildB)' == 'true'" Include="pathto\third.party.dll.B">
    <Name>third.party.dll.B</Name>
  </ProjectReference>
</ItemGroup>

If you do this, you should also set similar conditions for the build output directories, based on values of properties BuildA and BuildB you should configure $(IntDir) and $(OutDir) to separate locations, because your incremental build will be seriously broken otherwise.

Then you can build from command line passing additional parameters:

> msbuild ProjectA.csproj /p:BuildA=true

or

> msbuild ProjectB.csproj /p:BuildB=true

To make the build work like this in Visual Studio, or Xamarin Studio, you have to set environment variable before launching the VS or XS. Note that you cannot switch from one configuration to another without re-launching VS or XS.