Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild build order

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.

like image 574
igofed Avatar asked Aug 06 '12 16:08

igofed


People also ask

How do you set a build order?

In order to set the Build order for your Solution, right-click on the Solution in Solution Explorer and Select Project Build Order: Your Project Dependencies should be set correctly which is used to determine the Build order by Visual Studio.

Will MSBuild compile without any target?

If MSBuild determines that any output files are out of date with respect to the corresponding input file or files, then MSBuild executes the target. Otherwise, MSBuild skips the target. After the target is executed or skipped, any other target that lists it in an AfterTargets attribute is run.

What is the path to MSBuild?

For example, the path to MSBuild.exe installed with Visual Studio 2019 Community is C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe You can also use the following PowerShell module to locate MSBuild: vssetup.

What are targets in MSBuild?

A target element can have both Inputs and Outputs attributes, indicating what items the target expects as input, and what items it produces as output. If all output items are up-to-date, MSBuild skips the target, which significantly improves the build speed. This is called an incremental build of the target.


2 Answers

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

like image 81
Alexeyss Avatar answered Nov 09 '22 20:11

Alexeyss


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> 
like image 40
Dave Maff Avatar answered Nov 09 '22 21:11

Dave Maff