dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.23k stars 1.35k forks source link

TargetPlatformIdentifier is not inferred for .NET Core C++/CLI Projects - prevents successful builds #5709

Closed vatsan-madhavan closed 4 years ago

vatsan-madhavan commented 4 years ago

TargetPlatformIdentifier is not inferred in .NET Core C++/CLI projects correctly. This affects (a) restore of C++/CLI .vcxproj and (b) creation of a new .NET Core C++/CLI .vcxproj in Visual Studio.

In both instances, the problem looks like this:

Restore log:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(93,5): error MSB4184: The expression "[Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformSDKLocation('', 10.0.19041.0)" cannot be evaluated. Parameter "targetPlatformIdentifier" cannot have zero length. [D:\src\repos\wpf\src\Microsoft.DotNet.Wpf\src\System.Printing\System.Printing.vcxproj]

New Project creation failure:

HMF6WMg0ke

The project actually gets created - it just seems like a failure. It's possible to open the project in Visual Studio. Trying to build the project leads to failure again -

Build started... 1>------ Build started: Project: CppCliClassLibrary3, Configuration: Debug Win32 ------ 1>The expression "[Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformSDKLocation('', 10.0.19041.0)" cannot be evaluated. Parameter "targetPlatformIdentifier" cannot have zero length. C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets 1>Error: The expression "[Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformSDKLocation('', 10.0.19041.0)" cannot be evaluated. Parameter "targetPlatformIdentifier" cannot have zero length. C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

==

I believe this is a regression introduced by #5624 (/cc @sfoslund).

In addition to generically blocking C++/CLI scenarios from working well with .NET 5, I also predict that this will impede dotnet/wpf's ability to update its repo-wide global.json to point to a newer version of the .NET 5 SDK.

/cc @ryalanms, @dsplaisted, @richaverma1

richaverma1 commented 4 years ago

/cc @wli3 also. I thought https://github.com/dotnet/sdk/issues/12916 fixed it.

wli3 commented 4 years ago

Why targetplatformversion need to get set for c++/CLI? Only thing it does is to get cswinrt, which is c# projection.

wli3 commented 4 years ago

Weird. A created project can build. But not in new project.

wli3 commented 4 years ago

@vatsan-madhavan this is rc1 build?

vatsan-madhavan commented 4 years ago

Weird. A created project can build. But not in new project.

I suspect that a restored project can build (I had mixed luck).

wli3 commented 4 years ago

No repro for the latest val build. This bug does exist in older version. cppcli

vatsan-madhavan commented 4 years ago

What about it makes it a no-repro? I mean, where is the TargetPlatformIdentifier being set ?

CBenghi commented 4 years ago

@wli3, I am encountering the same problem with the following setting. Is there a workaround for us?

Microsoft Visual Studio Community 2019 Preview
Version 16.8.0 Preview 2.1
VisualStudio.16.Preview/16.8.0-pre.2.1+30428.66
Microsoft .NET Framework
Version 4.8.04084

Installed Version: Community

Visual C++ 2019   00435-60000-00000-AA383
Microsoft Visual C++ 2019

Microsoft Visual C++ Wizards   1.0
Microsoft Visual Studio VC Package   1.0
vatsan-madhavan commented 4 years ago

So #5624 changed the logic and added an extra check for $(_EnableDefaultWindowsPlatform) != false

https://github.com/dotnet/msbuild/blob/c7790e1ed37c2e6cb4fc38e76c06ed1fb15d3148/src/Tasks/Microsoft.Common.CurrentVersion.targets#L89

In Microsoft.NET.TargetFrameworkInference.targets@L161-L165, I see this at present:

  <!--C++/CLI has its own logic of determine TargetPlatformIdentifier and TargetPlatformVersion-->
  <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), 5.0)) and '$(Language)' != 'C++'">
    <_EnableDefaultWindowsPlatform>false</_EnableDefaultWindowsPlatform>
    <UseOSWinMdReferences>false</UseOSWinMdReferences>
  </PropertyGroup>

In the version of the SDK where I encountered the bug, this is what I saw though:

  <PropertyGroup  Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), 5.0))">
    <_EnableDefaultWindowsPlatform>false</_EnableDefaultWindowsPlatform>
    <UseOSWinMdReferences>false</UseOSWinMdReferences>
  </PropertyGroup>

That probably explains the fact that the bug is fixed - the current version of the SDK has a condition that looks for $(Language) != 'C++' before settings _EnableDefaultWindowsPlatform=false. This didn't happen in older SDK's - thus the bug.

==

I expect that a newer SDK would overcome this problem (haven't tried this yet, but it stands to reason...)

dsplaisted commented 4 years ago

This should be fixed in RC1. #13111 is the PR that fixed it.