Building .NET projects using the Microsoft.Build.Traversal SDK
Your continuous integration script often looks like dotnet build mysolution.sln
and dotnet test mysolution.sln
. In my case, I have a solution that contains multiple class libraries and a few WPF projects. I want to create NuGet packages and also test projects on Windows, Linux, and Mac. However, you cannot build WPF projects on Linux or Mac. This means dotnet build
fails on these platforms.
One way to deal with this problem is to create a new sln file or use a filtered solution (slnf). This way you can remove the WPF projects when building on non-Windows operating systems. However, I don't like this solution as you need to keep the filtered solution up to date when you add a new project.
A better way is to use the Microsoft.Build.Traversal
SDK. This custom SDK allows you to select the projects to build or test using the MSBuild syntax which includes globbing. To use the SDK, you need to create a global.json
file at the root of your repository with the following content:
// https://learn.microsoft.com/en-us/dotnet/core/tools/global-json?WT.mc_id=DT-MVP-5003978
{
"sdk": {
"version": "5.0.201",
"rollForward": "patch"
},
"msbuild-sdks": {
"Microsoft.Build.Traversal": "3.0.3"
}
}
Then, you can create a new project file named dirs.proj
(you can use another name if you prefer) with the following content:
<Project Sdk="Microsoft.Build.Traversal">
<ItemGroup>
<!-- Build all csproj and vbproj -->
<ProjectReference Include="**/*.*proj" />
</ItemGroup>
<!-- Remove WPF projects when building on Linux or Mac -->
<ItemGroup Condition="$([MSBuild]::IsOsPlatform('WINDOWS')) == false">
<ProjectReference Remove="src/Meziantou.Framework.WPF/Meziantou.Framework.WPF.csproj" />
<ProjectReference Remove="tests/Meziantou.Framework.WPF.Tests/Meziantou.Framework.WPF.Tests.csproj" />
</ItemGroup>
</Project>
Finally, you can use the dotnet
CLI to build, test, and pack the project. The SDK will forward the command to all referenced projects:
dotnet build dirs.proj --configuration Release /bl
dotnet test dirs.proj
dotnet pack dirs.proj
#Visual Studio integration
It is not currently possible to open dirs.proj
files into Visual Studio as a solution replacement. If you don't like sln files, you can upvote the following issues:
- Open Microsoft.Build.Traversal project files as solutions
- [Discussion] Clean up sln (VisualStudio solution) files
#Additional resources
Do you have a question or a suggestion about this post? Contact me!