MSBuild build order

See Incorrect solution build ordering when using MSBuild.exe at The Visual Studio Blog:

Follow this principle: do not use dependencies expressed in the solution file at all! Better to express dependencies in the file that has the dependency: put a project reference in the project, instead. In our example, that would be a project reference from B to C.

You may not have done that before because you didn’t want to reference the target of the project reference, but merely order the build. However, in 4.0 you can create a project reference that only orders the build without adding a reference. It would look like this – note the metadata element, and all this is inside an <ItemGroup> tag of course:

<ProjectReference Include="foo.csproj">
    <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>

Note that you have to add the child element with a text editor — Visual Studio can add a project reference, but doesn’t expose UI for this metadata.

I can tidy up by removing the dependency in the solution file as well – removing now-unnecessary lines like this — your GUID will be different, but use the VS dialog and it will do the job...


I had a problem much like this. It manifested itself in the solution, by requiring two builds before successfully building the entire solution.

As it turns out, I had accidentally added a Reference and not a ProjectReference (look for this in the .sln file), meaning VS/MSBuild would require and look for the referenced library file, but be completely unaware of how to build it if it was missing. Eventually the build process would come around to the project with the referenced library, building it and making it available for the next build attempt.

Depending on your dependency tree and the particular mood of the MS toolchain, this could turn up as a sporadic error, and thus be a bitch to debug.

Short version: Make sure references to projects inside the solution are listed as ProjectReference and not just Reference. Do this by adding the reference on the Solution tab instead of browsing and picking the DLL file.


The solution above didn't quite work for me when trying to build a .Net Standard project that depended on the output from a .Net Core project. I had to add an additional "SkipGetTargetFrameworkProperties" in order to get the solution to build in VS2017 and MSBuild.

<ProjectReference Include="foo.csproj">
    <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
</ProjectReference>