Skip to content

PathogenPlayground/EarlyConfigurationPlatform

Repository files navigation

This repo demonstrates a common hazard of evaluating $(Configuration) and $(Platform) too early in MSBuild.

These properties don't have any special meaning, so they're empty by default just like anything else.

They will always get assigned a value when building a .sln due to solution configuration mapping, but never when building a project file directly.

This creates a hazard that not a lot of people are aware of, and it can be hard to notice if you're used to working from Visual Studio rather than the command line. (And even if you use the CLI, you might only test things by building the .sln.)

Depending on the context where the properties are used, the problems introduced by this can range from annoying (build output being barfed in weird spots) to hard to notice (like malformed NuGet package metadata) to destructive (like a clean target that unintentionally gets overscoped.)


As a bonus, there's an additional hazard caused by the convention that SDKs will typically give the properties a default value, but it happens too late for them to be used in Directory.Build.props. (In .NET it happens in Microsoft.NET.Sdk.props, in MSVC it happens in Microsoft.Cpp.Default.props.)

This means if you're moving things from your csproj or MSVC property sheets over to a common location imported via Directory.Build.props, you might be unknowingly introducing the same non-obvious bug.


You can see all three of these for yourself using the demo in this repo.

It prints the values of Configuration and Project as evaluated in:

  • When Directory.Build.props is evaluated (EARLY)
  • When EarlyConfigurationPlatform.csproj is evaluated (PROJ)
  • When the a target is run right before Build/Restore (LATE)

If you build the solution using dotnet build, you'll see that the configuration and platform is always assigned:

EARLY Configuration = 'Debug' Platform = 'AnyCPU'
PROJ  Configuration = 'Debug' Platform = 'AnyCPU'
LATE  Configuration = 'Debug' Platform = 'AnyCPU'

If you build the project using dotnet build EarlyConfigurationPlatform, you'll see that the configuration and platform was not present when evaluated in Directory.Build.props:

EARLY Configuration = '' Platform = ''
PROJ  Configuration = 'Debug' Platform = 'AnyCPU'
LATE  Configuration = 'Debug' Platform = 'AnyCPU'

Overall, this is why you'll always find this snippet in Directory.Build.props written by me (or the first file it imports):

<!-- Default configuration and platform when not present -->
<PropertyGroup>
  <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
  <Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
</PropertyGroup>

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Languages