Search code examples
.netvisual-studiomsbuildsolutionmsbuild-task

How to express artifact dependency on another solution


Our solution (A.sln) needs a binary that is built by another (legacy) solution (B.sln). I can't go into details about why this is necessary, it's a long and hairy story.

Constraints

The application produced by A only needs the artifacts of B at runtime, so it doesn't matter when in the build process this dependency is fullfilled. Because of naming conflicts we don't want to build both projects in the same directory, but rather copy some artifacts of B to a subdirectory of the output path of A.

I tried

1) Adding the dependency B as a build target to A by adding the following to A.sln

<Target Name="Build">
  <MSBuild Projects="$(SolutionDir)..\B\B.sln" Properties=" Platform=Win32; Configuration=$(Configuration); " />
</Target>

For some reason this builds B in the output directory of A, which is unwanted.

2) Adding a post build event to A calling msbuild on B by adding the following to A.sln

<PropertyGroup>
  <PostBuildEvent>
    msbuild $(SolutionDir)..\B\B.sln /p:configuration=$(ConfigurationName)
    xcopy /E /R /Y $(SolutionDir)..\B\$(ConfigurationName) $(SolutionDir)$(ConfigurationName)\B\
  </PostBuildEvent>
</PropertyGroup>

For some reason this works in the VS 2015 command prompt, but not in Visual Studio itself. VS (2015) complains that

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\CodeAnalysis\Microso
ft.CodeAnalysis.targets(219,5): error MSB4175: The task factory "CodeTaskFactory
" could not be loaded from the assembly "C:\Windows\Microsoft.NET\Framework64\v4
.0.30319\Microsoft.Build.Tasks.v12.0.dll". Could not load file or assembly 'file
:///C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Build.Tasks.v12.0.
dll' or one of its dependencies. The system cannot find the file specified. [C:\
Users\Chiel.tenBrinke\Projects\MyProject\B\CppSource\B.vcxproj]

So, what is the best (i.e. easiest, most maintainable, cleanest) way to go about this?


Solution

  • The way I ended up doing it was on a project level instead of solution level. The xml in the project of solution A is of the following form:

    <Target Name="AfterBuild">
      <MSbuild
          Projects="$(SolutionDir)..\B\CppSource\SomeProject.vcxproj"
          Properties="
          Configuration=$(ConfigurationName);
          OutDir=$(SolutionDir)$(ConfigurationName)\B\;
          "/>
    </Target>