34

I have a large solution with more than 100 projects (C++, Managed C++, C#) and many of them depends on each others.

I have a TeamCity server and I want build this solution there.

When I build solution in VisualStudio everything goes fine, but with TeamCity I have a CS0006 error. I know why that so - TeamCity uses MSBuild 4 to build solutions, but there is a known bug in MSBuild 4 - it ignores build order and build projects from solutions in order it wants. Because of this behavior if you have:

Project A
Project B which has reference to A

MSBuild can build these project in such order:

1. B
2. A

The easiest solution is to set BuildProjectReferences=true (which is default) and all referenced project will be builded automatically. But I can't use this approach because not all referenced project in this solution, and I can't build projects from another solution.

Here is another fix for this problem - use ConfigurationManager and disable all projects, which shouldn't build, but it works only in VisualStudio - MSBuild ignores that and builds all referenced projects.

The problem is to restore build order which I can see in VisualStudio in window ProjectBuildOrder which is not true if I use MSBuild directly from Console.

igofed
  • 1,402
  • 1
  • 9
  • 15
  • This is a pretty general question, can you be more specific? Does it build in visual studio? – Ritch Melton Aug 06 '12 at 16:59
  • 1
    No, I use JetBrains TeamCity server, which uses MSBuild. If I run build from VisualStudio everything fine. – igofed Aug 06 '12 at 17:22
  • Could you be more specific -- how to fix _what_? Do you want to fix your pre-build events or fix a build when you disable building project references? – seva titov Aug 06 '12 at 19:59
  • I'm familiar with TeamCity. Are you referencing the solution file in its configuration? What is the actual build error? It seems like you are assuming some sort of 'known problem', but AFAIK all this stuff pretty much just works, unless you are doing something esoteric. 100 projects isn't horrible, I've had ~350 building under CI. – Ritch Melton Aug 07 '12 at 00:41
  • I updated question and tried to be more specific – igofed Aug 07 '12 at 09:28
  • Ritch Melton, problem not in TeamCity problem in MSBuild 4. – igofed Aug 07 '12 at 09:29
  • Sorry, I'd like to help, but I can't understand where the problem is. TeamCity seemingly has nothing to do with it as it sounds like your solution won't build from the command line. BuildProjectReferences is a red herring because MSBuild knows how to follow and build project references in the correct order and that behavior is a core feature that is enabled by default. – Ritch Melton Aug 07 '12 at 21:25
  • I hoped so, but from MSBuild 4 it has problem, which doesn't allow it to follow right build order and I can see it in TC log, where project B builds earlier than project A. (bug on Microsoft Connect http://connect.microsoft.com/VisualStudio/feedback/details/613284/msbuild-4-does-not-respect-build-order-when-building-a-solution) – igofed Aug 08 '12 at 12:31
  • It could be that issue, but is that what a '/v:diag' dump is telling you? A CS0006 error could be caused by path truncation, invalid reference paths (that work inside the IDE), or other issues. – Ritch Melton Aug 09 '12 at 18:09
  • No, everything is OK with path. As I said I can see in MSBuild logs, that my project B was built before A. That's a problem – igofed Aug 10 '12 at 12:47

4 Answers4

35

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...

sloth
  • 99,095
  • 21
  • 171
  • 219
Alexeyss
  • 3,216
  • 1
  • 17
  • 11
12

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>
Dave Maff
  • 798
  • 8
  • 12
  • This MSBuild "bug" persists with VisualStudio 2019. Same issue on my side, a .Net Standard project's pre-build script depended on a .Net Core WebAPI project. First I wanted to set only the build order in the sln which was ignored by MSBuild. Your solution resolved it, thanks! – Balázs Somorjai Oct 12 '21 at 08:44
8

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.

Saustrup
  • 758
  • 2
  • 7
  • 18
  • That is amazing. 3 days spent trying to figure this out. Do you have any idea what would cause the reference to be added as a reference rather than a project reference? Would be great if there was a tool to find all occurrences of this. – russelrillema Feb 26 '18 at 14:54
  • In my case this was in the project file not the solution file – russelrillema Feb 26 '18 at 15:05
0

Nothing mentioned above did not help for me. The aolution I used was to build the sln few times, passing /t:1stproject.csproj in the first run, then /t:2ndproject and at the end the sln without /t to comlete the rest of the solution.