.netmsbuild.net-core

Conditional per TargetFramework in MsBuild 15


With the new MsBuild version it's really easy to target multiple frameworks and framework versions in .csproj project:

<TargetFrameworks>net40;net45;net461;netcoreapp1.1</TargetFrameworks>

Now, how do I get a constant defined for each of them so that I can have certain code only be part of e.g. netcoreapp1.1 pass and not full framework compilation?

I'd like to be able to add a preprocessor directive like this one:

#if NET_CORE
    // some code
#endif

And the same for full .NET Framework and possibly .NET Standard.

The other questions I found don't take new <TargetFrameworks> way of defining the framework into accounts. Stuff like this doesn't work:

<DefineConstants Condition=" '$(TargetFramework)' == '.NETCoreApp' ">NET_CORE</DefineConstants>

Solution

  • There are already various preprocessor symbols defined that you can use. From the docs:

    .NET Framework

    Framework/Version Symbol
    .NET Framework (any version) NETFRAMEWORK
    .NET Framework 2.0 NET20
    .NET Framework 3.5 NET35
    .NET Framework 4.0 NET40
    .NET Framework 4.5 NET45
    .NET Framework 4.5.1 NET451
    .NET Framework 4.5.2 NET452
    .NET Framework 4.6 NET46
    .NET Framework 4.6.1 NET461
    .NET Framework 4.6.2 NET462
    .NET Framework 4.7 NET47
    .NET Framework 4.7.1 NET471
    .NET Framework 4.7.2 NET472
    .NET Framework 4.8 NET48

    .NET Standard

    Framework/Version Symbol
    .NET Standard (any version) NETSTANDARD
    .NET Standard 1.0 NETSTANDARD1_0
    .NET Standard 1.1 NETSTANDARD1_1
    .NET Standard 1.2 NETSTANDARD1_2
    .NET Standard 1.3 NETSTANDARD1_3
    .NET Standard 1.4 NETSTANDARD1_4
    .NET Standard 1.5 NETSTANDARD1_5
    .NET Standard 1.6 NETSTANDARD1_6
    .NET Standard 2.0 NETSTANDARD2_0
    .NET Standard 2.1 NETSTANDARD2_1

    .NET Core

    Framework/Version Symbol
    .NET [Core] (any version) NETCOREAPP
    .NET Core 1.0 NETCOREAPP1_0
    .NET Core 1.1 NETCOREAPP1_1
    .NET Core 2.0 NETCOREAPP2_0
    .NET Core 2.1 NETCOREAPP2_1
    .NET Core 2.2 NETCOREAPP2_2
    .NET Core 3.0 NETCOREAPP3_0
    .NET Core 3.1 NETCOREAPP3_1

    .NET 5+

    Framework/Version Symbol
    .NET 5.0 NET5_0
    .NET 6.0 NET6_0
    .NET 7.0 NET7_0

    Additional <framework>_OR_GREATER Symbols

    From the release of .NET6, a suite of <framework>_OR_GREATER symbols were added:

    For example:

    Target Framework Symbols
    .NET Framework NET48_OR_GREATER, NET472_OR_GREATER, NET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATER, NET451_OR_GREATER, NET45_OR_GREATER, NET40_OR_GREATER, NET35_OR_GREATER, NET20_OR_GREATER
    .NET Standard NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, NETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATER, NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, NETSTANDARD1_1_OR_GREATER, NETSTANDARD1_0_OR_GREATER
    .NET 5+ (and .NET Core) NET7_0_OR_GREATER,NET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP_OR_GREATER,

    NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATER, NETCOREAPP2_2_OR_GREATER, NETCOREAPP2_1_OR_GREATER, NETCOREAPP2_0_OR_GREATER, NETCOREAPP1_1_OR_GREATER, NETCOREAPP1_0_OR_GREATER
    .NET 5+ (and .NET Core), OS Specific NET6_0_ANDROID_OR_GREATER, NET6_0_IOS_OR_GREATER, NET6_0_MACOS_OR_GREATER, NET6_0_MACCATALYST_OR_GREATER, NET6_0_TVOS_OR_GREATER, NET6_0_WINDOWS_OR_GREATER
    #if NETSTANDARD1_6
        Console.WriteLine("This is .Net Standard 1.6");
    #endif
    
    #if NETCOREAPP2_0
        Console.WriteLine("This is .Net Core 2.0");
    #endif