Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting MSBuild to compile project with dependencies for Win32 and Win64 platforms

I have a large solution with over 10 projects in it, in C++.

The entire solution is x64 only, except for project P which needs both both x64 and win32 versions ( the proper one is loaded at runtime).

Project P depends on several other projects for lib files: C and H which are compiled into libs.

P has a reference to C and H like so:

<ProjectReference Include="..\C\C.vcxproj">
   <Project>{....}</Project>
</ProjectReference>
<ProjectReference Include="..\H\H.vcxproj">
   <Project>{....}</Project>
</ProjectReference>

I want to build project P for both platforms.

I chose to do this from a meta-P project, which calls on P like so:

<MSBuild Projects="..\P\P.vcxproj" Properties="Platform=Win32"/>
<MSBuild Projects="..\P\P.vcxproj" Properties="Platform=x64"/>

This allows P to be changed freely by the developers, and then both versions are built at once by building meta-P.

The problem is that when meta-P calls MSBuild on project P the references to C and H are affected by the Solution environment (in which the active platform is always x64).

When it comes to linking the Win32 P to its proper C.lib and H.lib, the open solution configuration kicks in, and studio attempts to link it with the x64 version, and fails.

I temporarily solved it using an exec task in meta-P to run MsBuild.exe directly on P. This ignored the Visual Studio environment properties.

What is the correct solution to have the platform correctly read?

like image 244
Sirotnikov Avatar asked Sep 30 '22 03:09

Sirotnikov


1 Answers

The correct solution is to add an undocumented property called ShouldUnsetParentConfigurationAndPlatform and set it to false.

The only correct place to put it, is within each Project Reference item in the P project, otherwise it gets ignored.

So it ends up looking like this:

<ProjectReference Include="..\C\C.vcxproj">
  <Project>{....}</Project>
  <Properties>ShouldUnsetParentConfigurationAndPlatform=false</Properties>
</ProjectReference>
<ProjectReference Include="..\H\H.vcxproj">
  <Project>{....}</Project>
  <Properties>ShouldUnsetParentConfigurationAndPlatform=false</Properties>
</ProjectReference>

This causes Visual Studio to follow through with C's and H's inherited properties, instead of reading them from the Solution environment.

Edit: see useful reference from comment: https://github.com/Microsoft/msbuild/blob/98d38cb/src/XMakeTasks/AssignProjectConfiguration.cs#L198-L218

like image 185
Sirotnikov Avatar answered Oct 25 '22 20:10

Sirotnikov