visual-c++dllvisual-studio-2017

Visual Studio reference multiple project configurations in the same build


I have a Visual Studio 2017 solution with four projects: a shared static LIB (C++), a DLL (C++) built with static dll linking, an EXE (C++) built with dynamic linking, and a SETUP project that references the DLL and the EXE. Both DLL and EXE projects reference the static LIB project, but they reference it with different linking options. LIB project has to be built twice, once with static linking (/MT) and once with dynamic (/MD), which I made possible with different project configurations. How to organize my solution so that building the setup is simple and intuitive?

My current solution is to use batch build so that both LIB configurations are built. DLL project references LIB directly (both projects are configured with static CRT linking, /MT), and EXE project does not have a project reference, but the LIB.lib (built with /MD option) is added manually to Additional Dependencies. But in all my other projects I don't use batch build, and I fear I will forget it in the future and build the solution with regular Build Solution (Ctrl+Alt+B), which will lead to bad builds.


Solution

  • When you add a project reference through the GUI an ItemGroup is added to the project file. This item needs to be changed and Properties item needs to be added to it:

    <ItemGroup>
      <ProjectReference Include="..\other_project_dir\other_project_name.vcxproj">
        <Project>{SOME-GUID-HERE}</Project>
        <Properties>Configuration=$(Configuration)</Properties>
      </ProjectReference>
    </ItemGroup>
    

    In my case Configuration=$(Configuration) is the needed item value by coincidence. This however just adds a reference, but does not force the other_project_name to be built in required configuration. We need to build it separately, with MSBuild target:

    <Target Name="MyBeforeBuild" BeforeTargets="InitializeBuildStatus">
      <MSBuild Projects="..\other_project_dir\other_project_name.vcxproj"
               Properties="Configuration=$(Configuration)"
               Targets="Build" />
    </Target>