Visual-studio – Building an MSBuild 2.0 project from 3.5

msbuildvisual-studio-2005visual-studio-2008

I have a VS 2005/MSBuild 2.0 project (let's call it "Project A") that I must keep in VS 2005 (it uses a third-party VS 2005 Designer.) Project A is referenced by one of the projects in my new VS 2008 solution (we'll call them "Project C" and "Solution B" respectively.) Ideally, I'd like to chain the building of Project A into the building of Solution B, and I believe that the "ToolsVersion" attribute is the key. So, to recap, this is what I need to do:

  1. Start a build on Solution B either through the command-line or Visual C# 2008 Express. It is critical that it work through both!
  2. Have Project C trigger the building of Project A.
  3. Have the output of Project A (a class library) copied to Project C.
  4. Build Project C and the remaining projects in Solution B.

Here's a diagram:
MSBuild 3.5 or VS2008->
[Solution B (3.5)]->
[Project C (3.5)]->
[Project A (2.0)]->
Copy output of A to C->
Continue building Solution B

Any ideas on how I should set this up? Clips from working project files would be hugely appreciated! Thanks in advance!

SOLUTION
Here's what needed added to Project C, to make this work:

<ItemGroup>
   <ProjectToBuild Include="..\ProjectA\ProjectA.csproj" />
</ItemGroup>
<Target Name="BeforeBuild">
   <MSBuild
     Projects="@(ProjectToBuild)"
     Targets="Rebuild" ToolsVersion="2.0">
              <Output
              TaskParameter="TargetOutputs"
              ItemName="AssembliesBuiltByChildProjects" />
   </MSBuild>
   <Copy SourceFiles="@(AssembliesBuiltByChildProjects)"
            DestinationFolder="$(MSBuildProjectDirectory)"
    />
</Target>

Note there is a known issue with getting the TargetOutputs of a solution with the MSBuild task. This was supposed to be fixed in MSBuild 3.5, but I'm guessing that the ToolsVersion attribute is causing it to resurface. That's why I'm referencing ProjectA.csproj directly, instead of its solution file.

Best Answer

  1. Ensure that the project C is a dependency of project B. (In this case there isn't a project B but if there was then make sure.)
  2. Edit project C's proj file in a text editor. Add the followingat the bottom of the file but before the closing project tag, where a.sln is the solution for project A.

    <ItemGroup>
       <ProjectsToBuild Include="a.sln"/>
    </ItemGroup>
    <Target Name="BeforeBuild">
       <MSBuild
             Projects="@(ProjectsToBuild)"
             Targets="Build" ToolsVersion="2.0">
                      <Output
                      TaskParameter="TargetOutputs"
                      ItemName="AssembliesBuiltByChildProjects" />
        </MSBuild>
        <Copy SourceFiles="@(TargetOutputs)"
                    DestinationFolder="@(SolutionDir)\References"
          />
      </Target>

  3. Create a references folder under you solution and ensure that it is marked as a reference folder for project C.

  4. Build Project B.

I haven't tested it but the concept should work.