Building .NET projects using the Microsoft.Build.Traversal SDK

 
 
  • Gérald Barré

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 fail on these platforms.

One way to deal with this problem is to create a new sln file or to 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 to select the projects to build or test using the MSBuild syntax wich includes globbing. To use the SDK, you need to create a global.json file at the root of your repository with the following content:

JSON
// 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:

csproj (MSBuild project file)
<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:

Shell
dotnet build dirs.proj --configuration Release /bl

Shell
dotnet test dirs.proj

Shell
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:

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub