Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check TargetFramework Using Intrinsic Function #5799

Merged
merged 6 commits into from
Jun 30, 2021

Conversation

benvillalobos
Copy link
Member

Fixes #5792

We had two areas where MSBuild checked TargetFramework based on whether it started with netcore and netstandard.

Ex:

<PropertyGroup Condition="$(TargetFramework.StartsWith('netstandard')) or $(TargetFramework.StartsWith('netcore'))">

With net5.0 resolving to net5.0 instead of netcoreapp5.0, this logic would no longer succeed, so here's a quick fix via intrinsic function GetTargetFrameworkIdentifier introduced in #5429.


Some other notes:

There are a few other areas that look like we could use these intrinsic functions, but it would overcomplicate the logic. Here's what I found with rg -iF "StartsWith('net"

src\MSBuild.Bootstrap\MSBuild.Bootstrap.csproj
55:  <Import Project="..\Package\GetBinPaths.targets" Condition="$(TargetFramework.StartsWith('net4'))"/>

src\Directory.Build.props
71:  <PropertyGroup Condition="$(TargetFramework.StartsWith('net4'))">
77:  <PropertyGroup Condition="!$(TargetFramework.StartsWith('net4'))">

src\Directory.Build.targets
141:  <Import Project="$(BUILD_STAGINGDIRECTORY)\MicroBuild\Plugins\MicroBuild.Plugins.IBCMerge.*\**\build\MicroBuild.Plugins.*.targets" Condition="'$(BUILD_STAGINGDIRECTORY)' != '' and $(TargetFramework.StartsWith('net4')) and '$(MicroBuild_EnablePGO)' != 'false'" />

src\Directory.BeforeCommon.targets
19:  <PropertyGroup Condition="$(TargetFramework.StartsWith('net4')) Or $(TargetFramework.StartsWith('net3'))">

eng\BootStrapMSBuild.targets
15:    <BootstrapDependsOn Condition="$(TargetFramework.StartsWith('net4'))">BootstrapFull</BootstrapDependsOn>
16:    <BootstrapDependsOn Condition="!$(TargetFramework.StartsWith('net4'))">BootstrapNetCore</BootstrapDependsOn>

These checks are likely better than

[MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework' and [MSBuild]::GetTargetPlatformVersion('$(TargetFramework)', 1)) == '4'

@benvillalobos benvillalobos added this to the MSBuild 16.9 milestone Oct 14, 2020
@benvillalobos
Copy link
Member Author

benvillalobos commented Oct 14, 2020

Team Triage: We can't do this until both the hosted azure devops build machines and the internal build pool that does our official builds is updated to 16.8.

@Nirmal4G
Copy link
Contributor

PR Title should have TargetFramework instead of TargetPlatform.

@benvillalobos benvillalobos changed the title Check TargetPlatform Using Intrinsic Function Check TargetFramework Using Intrinsic Function Oct 16, 2020
@benvillalobos
Copy link
Member Author

@Nirmal4G thanks! updated

@rainersigwald
Copy link
Member

Looking at PRs this morning--this should work now.

@rainersigwald
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rainersigwald
Copy link
Member

Oh, of course: all the Core build job flavors won't work because they build with an old .NET Core SDK. So this is blocked on #5515.

@Forgind
Copy link
Member

Forgind commented Mar 8, 2021

Is this unblocked now that we're on .NET 5?

@benvillalobos
Copy link
Member Author

@Forgind Good question. I'll rebase and run the tests again

@benvillalobos
Copy link
Member Author

This is ready for review.

Base automatically changed from master to main March 15, 2021 20:09
@@ -69,6 +69,10 @@
<PackageReference Update="Microsoft.NETCore.App" PrivateAssets="All" />
</ItemGroup>

<PropertyGroup Condition="'$(MonoBuild)' != 'true' and '$(TargetFrameworkIdentifier)' == ''">
<TargetFrameworkIdentifier>$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))</TargetFrameworkIdentifier>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you verify this comes before the one from D.BC.t? Also, is $(TargetFrameworkIdentifier) really not used?

@Forgind
Copy link
Member

Forgind commented Jun 1, 2021

Any recent progress on this? Would be nice to finish it or close it until you're ready to come back to it.

@benvillalobos benvillalobos force-pushed the tfm-conditions branch 2 times, most recently from 15d3ba6 to a6534d0 Compare June 3, 2021 23:48
Comment on lines 53 to 54
<TargetFrameworkIdentifier Condition="'$(TargetFrameworkIdentifier)' == ''">$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))</TargetFrameworkIdentifier>
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">$([MSBuild]::GetTargetFrameworkVersion($(TargetFramework)))</TargetFrameworkIdentifier>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worries me. Does it really not conflict with something NuGet does?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a general concern overriding these, so I added the check to see if it didn't already have a value. Do you think this could mess with something nuget does where they do a similar "set it if it isn't already set" check?

When setting these values here, I considered prefixing this with an underscore for safety. Maybe we have a different naming convention for "Values that likely won't change during a build that we store for msbuild specific purposes"?

Co-authored-by: Forgind <Forgind@users.noreply.github.com>
@Forgind
Copy link
Member

Forgind commented Jun 14, 2021

Team triage: This can break projects that don't have TFI defined and don't expect to define it. We fixed this in other ways in other parts of our repo.

@Forgind Forgind closed this Jun 14, 2021
@benvillalobos
Copy link
Member Author

At minimum shouldn't this be

<GenAPIShortFrameworkIdentifier Condition="'$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))' == '.NETFramework'">net</GenAPIShortFrameworkIdentifier>
<GenAPIShortFrameworkIdentifier Condition="'$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))' == '.NETStandard'">netstandard</GenAPIShortFrameworkIdentifier>
<GenAPIShortFrameworkIdentifier Condition="'$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))' == '.NETCoreApp'">netstandard</GenAPIShortFrameworkIdentifier>

Or save $([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework))) into some unique property just before this and check that?

Or should #5792 be closed?

@benvillalobos benvillalobos reopened this Jun 14, 2021
@rainersigwald
Copy link
Member

Yes, changing the checks to use the property function for our own repo is appropriate. Adding it to common.targets is riskier and I don't think we should do it now.

@benvillalobos
Copy link
Member Author

@rainersigwald ah too broadly scoped, got it. Will revert it to mostly the first version of this PR

src/Directory.BeforeCommon.targets Outdated Show resolved Hide resolved
src/Tasks/Microsoft.Common.CurrentVersion.targets Outdated Show resolved Hide resolved
@rainersigwald rainersigwald modified the milestones: MSBuild 16.9, 17.0 Jun 15, 2021
@@ -110,7 +110,7 @@
<DefineConstants Condition="$([MSBuild]::IsOSPlatform('windows'))">$(DefineConstants);TEST_ISWINDOWS</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(MonoBuild)' != 'true' and ($([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'netcoreapp1.0')) or $(TargetFramework.StartsWith('netstandard')))">
<PropertyGroup Condition="'$(MonoBuild)' != 'true' and $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp' or $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/Directory.BeforeCommon.targets(113,18): error MSB4130: The condition "'$(MonoBuild)' != 'true' and $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp' or $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard'" may have been evaluated incorrectly in an earlier version of MSBuild. Please verify that the order of the AND and OR clauses is written as intended. To avoid this warning, add parentheses to make the evaluation order explicit.

The bug to remove this old warning (#1698) is 4 years old. The warning itself was commited on 2006-06-13 16:04:38.

😔

However, let's go ahead and overparenthesize.

Suggested change
<PropertyGroup Condition="'$(MonoBuild)' != 'true' and $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp' or $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard'">
<PropertyGroup Condition="'$(MonoBuild)' != 'true' and ($([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp' or $([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard' )">

@benvillalobos
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Jun 26, 2021
@AR-May AR-May merged commit 4f7de9a into dotnet:main Jun 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix conditions which incorrectly parse TargetFramework
5 participants