visual-studio.net-coremsbuildconditional-compilationtarget-framework

How do I conditionally build .Net Core 3.0 only if supported by tooling?


I would like to use the TargetFrameworks .csproj element to multi-target both .Net Core 3.0 (netcoreapp3.0) and .Net Framework 4.8 (net48) for a console application, like so:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFrameworks>netcoreapp3.0;net48</TargetFrameworks>
        <AssemblyName>MyConsoleApp</AssemblyName>
    </PropertyGroup>
</Project>

However, I would like the same .csproj file to degrade gracefully in older tooling and compile only .Net Framework 4.8 when the tooling does not support netcoreapp3.0 (such as with Visual Studio 2017).

I reviewed the conditional compilation documentation, but it seems to talk only about changing settings when compiling, not whether to do the compilation in the first place.

How can I accomplish this?


Solution

  • I reviewed the conditional compilation documentation, but it seems to talk only about changing settings when compiling, not whether to do the compilation in the first place.

    Yes, msbuild conditions should work inside the <Project> node. For your requirement, I can only imagine one possible way that you add the conditions to the first PropertyGroup( Condition="'$(VisualStudioVersion)'=='16.0'"), something similar to this format:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup Condition="'$(VisualStudioVersion)'=='16.0'">
        <OutputType>Exe</OutputType>
        <TargetFrameworks>netcoreapp3.0;net48</TargetFrameworks>
      </PropertyGroup>
    
      <PropertyGroup Condition="'$(VisualStudioVersion)'!='16.0'">
        <OutputType>Exe</OutputType>
        <TargetFramework>net48</TargetFramework>
      </PropertyGroup>
    
      <!-- ... other PropertyGroup with conditions-->
    
      <!--I use this script to confirm that when building the project in VS2017(msbuild15.0),the VS version is 15.0 while in VS2019(msbuild16.0), VS version is 16.0-->
      <Target Name="TestVersion" AfterTargets="build">
        <Message Text="version=>$(VisualStudioVersion)" Importance="high"/>
      </Target>
    </Project>
    

    Have to say most of the time, we use Multi-targets for class library projects instead of console projects, not sure about your specific reason to do this... Hope it makes some help :)

    Update:

    To build .net projects when VS is not installed, we can consider using Build Tools for VS package, here's the link of build tools for VS2019(contains the msbuild 16.0). In All downloads=>Tools for VS2019 we can find the build tools package.

    To make sure we can use the msbuild.exe from this package to build .net framework4.8 and .net core3.0 console projects, make sure we enabled these workloads and components when installing:

    enter image description here

    enter image description here

    We can navigate to Individual Components to make sure .net core 3.0 and .net 4.8 is enabled.