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.
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.
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.
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.
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.
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...
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With