I have a project targeting multiple frameworks using <TargetFrameworks> (plural) in my .csproj file.
This works fine, but I'm unable to do framework-specific things in .csproj since the $(TargetFramework) property is always empty.
If I target a single framework using <TargetFramework> (singular) everything works as expected.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>
<Target Name="DoSomethingFrameworkSpecific" AfterTargets="Build">
<Message Text="$(TargetFramework)" /><!-- Empty string -->
</Target>
<ItemGroup>
<None Include="MyProject.targets">
<Pack>True</Pack>
<PackagePath>build\$(TargetFramework)</PackagePath><!-- File ends up in \build, not build\net5.0 etc -->
</None>
</ItemGroup>
</Project>
I was under the impression that MSBuild would pass the current framework version for each pass (i.e. for each framework) so that we can do things like framework-specific paths or other conditionals depending on the version being built?
The official docs suggest this is possible: https://learn.microsoft.com/en-us/dotnet/standard/frameworks#how-to-specify-a-target-framework
Related questions on SO seem to deal with preprocessor directives only, not getting the current framework version in MSBuild scripts.
If you need to use $(TargetFramework) in a nuget pack path when targeting multiple TFMs, change <None> to <TfmSpecificPackageFile> otherwise it won't work. By default nuget will evaluate files to pack from the outside build not the TFM-specific build, but if you use <TfmSpecificPackageFile> then it will re-evaluate the pack item from the inner TFM-specific build.
As for the message - I tested it and it works fine, although I do get an empty message at the end for the outer build plus the TFM-specific messages above that in the output. If you want to remove the empty outer build message then just add a condition. Final result should look something like this:
<Target Name="DoSomethingFrameworkSpecific" AfterTargets="Build" Condition="'$(TargetFramework)' != ''">
<Message Text="Message from TFM: $(TargetFramework)" />
</Target>
<ItemGroup>
<TfmSpecificPackageFile Include="MyProject.targets">
<Pack>True</Pack>
<PackagePath>build\$(TargetFramework)</PackagePath>
</TfmSpecificPackageFile>
</ItemGroup>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With