Skip to content

net 6.0 throws NETSDK1005 error during publish as it does not accept the property "TargetFramework" #19487

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

Open
swetha-dran opened this issue Aug 3, 2021 · 8 comments
Milestone

Comments

@swetha-dran
Copy link

Below command fails with net 6.0,

dotnet publish "MY_TEST_APP_CSPROJ_PATH" -c Release -o "RELEASE_PROJ_PATH" -r win10-x64 /p:TargetFramework=net6.0

As a workaround, I updated csproj to accept the variable (TF)
<TargetFramework>$(TF)</TargetFramework>
and running the below command works,
dotnet publish "MY_TEST_APP_CSPROJ_PATH" -c Release -o "RELEASE_PROJ_PATH" -r win10-x64 /p:TF=net6.0

@ghost ghost added Area-NetSDK untriaged Request triage from a team member labels Aug 3, 2021
@ryank425
Copy link

ryank425 commented Aug 4, 2021

The workaround works because you are setting TargetFramework in your original csproj file to match what you have.

If you have

<TargetFramework>net5.0</TargetFramework>
and try to
dotnet publish "MY_TEST_APP_CSPROJ_PATH" -c Release -o "RELEASE_PROJ_PATH" -r win10-x64 /p:TargetFramework=net6.0

or,

<TargetFramework>net6.0</TargetFramework>
and try to
dotnet publish "MY_TEST_APP_CSPROJ_PATH" -c Release -o "RELEASE_PROJ_PATH" -r win10-x64 /p:TargetFramework=net5.0

both of these would not work.

If you want to target multiple frameworks, you would have

<TargetFrameworks>net6.0;net5.0</TargetFrameworks>
and remove <TargetFramework>...</TargetFramework>

Make sure that you have TargetFrameworks (Plural) tag.

@marcpopMSFT marcpopMSFT self-assigned this Aug 9, 2021
@marcpopMSFT
Copy link
Member

Ryan has the accurate summary here (thanks @ryank425 ). To add to this, MSBuild properties that are set by environment variables or CLI will get overwritten if you set them in your project file because MSBuild does an initial pass over all properties and whatever value is set last wins. That's why you'll find all throughout MSBuild and the SDK checks to see if a value is already set before overwriting it. Something like the below might work as well as it won't overwrite the value you set on the command line and will set it if it's not set.

  <PropertyGroup Condition="$(TargetFramework) == ''">
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

@KalleOlaviNiemitalo
Copy link
Contributor

That's not consistent with Global properties, which says the -property switch overrides values that would be set in the project file.

@iskiselev
Copy link

@marcpopMSFT, it doesn't work as expected, documented or as it worked before.
Let's start with very simple test project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <Target Name="Test" BeforeTargets="ResolvePackageAssets">
    <Warning Text="$(TargetFramework)" />
  </Target>
</Project>

If we try to compile it using SDK 5.4.0 with command: dotnet build /p:TargetFramework=netcoreapp3.1, it will succes. The output from "Test" target will be, as expected, "netcoreapp3.1".
When we compile the same with SDK 6.0.100-preview.7.21379.14, it fails with: error NETSDK1005: Assets file '...\testproj\obj\project.assets.json' doesn't have a target for 'netcoreapp3.1'. Ensure that restore has run and that you have included 'netcoreapp3.1' in the TargetFrameworks for your project. - it still has expected output "netcoreapp3.1" from "Test" target.

Really, as @KalleOlaviNiemitalo mentioned, /p switch should take precedence over content of project file, unless property is ii "TreatAsLocalProperty" attribute of "Project" element - and it works as documented, based on "Test" target output.

Even more - adding Condition="$(TargetFramework) == ''" to TargetFramework will not help, still resulting in same problem.

@marcpopMSFT
Copy link
Member

It's possible I misunderstood the original issue as reading it again, they say that the build failed. I assumed they meant that the TFM was not being set correctly but with the latest comment, it sounds like the /p switch is working correctly but rather that's triggering NETSDK1005.

@dsplaisted, this appears to be a change in behavior between 5.0 and 6.0 that 6.0 will give the NETSDK1005 if you don't restore first but net5.0 won't. Checking the binlogs, looks like the error shows up before the restore Target has run so there may be an ordering change in 6.0 that we need to resolve here.

@dsplaisted
Copy link
Member

dsplaisted commented Aug 13, 2021

The behavior for the .NET 6 SDK is the behavior we intended. I'm not sure why the .NET 5.0 SDK isn't behaving the same way, looking at the code makes it look like it should do the same thing. I'm guessing there was a bug that was fixed as part of the process of changing the command line parser to System.CommandLine for the .NET 6.0 SDK.

The reason this is the intended behavior is for the scenario where you have multiple TargetFrameworks defined in the project file, and you want to build one of them. In that case, we want to avoid invalidating the NuGet restore operation, so we exclude the TargetFramework property from being passed to Restore.

However, that design doesn't work for people who want to pass in a TargetFramework which is not listed in the project's TargetFrameworks property.

To correctly handle both cases, we would need to evaluate the project, and see if the TargetFramework passed in via the command-line was in the list of TargetFrameworks in the project file. If so, we would continue to remove the TargetFramework from the parameters passed to Restore. If not, we would allow the TargetFramework from the command line it to flow through to the restore operation.

The logic lives here: https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/commands/RestoringCommand.cs

@dsplaisted dsplaisted reopened this Aug 13, 2021
@marcpopMSFT
Copy link
Member

Here's some context from a few years back to explain why the implicit restore isn't set up in this situation:
dotnet/cli#7896 (comment)

Sounds like customers can do a separate restore or add /restore to workaround this. Not sure reading the project for the existing TFM and trying to change the behavior based on that is a high enough priority at the moment.

@iskiselev
Copy link

@marcpopMSFT, separate call of dotnet restore /p:TargetFramework=netcoreapp3.1 is not helping - looks like build will overwrite project.assets.json.
Calling build/publish command with --restore parameter helps.

@marcpopMSFT marcpopMSFT added the needs team triage Requires a full team discussion label Aug 25, 2021
marcpopMSFT added a commit that referenced this issue Aug 25, 2021
Made pass over A-M letters in project.

Had to fix a test to workaround bug #19487
@marcpopMSFT marcpopMSFT added this to the 6.0.2xx milestone Aug 25, 2021
@marcpopMSFT marcpopMSFT removed untriaged Request triage from a team member needs team triage Requires a full team discussion labels Aug 25, 2021
@marcpopMSFT marcpopMSFT removed their assignment Aug 25, 2021
@marcpopMSFT marcpopMSFT modified the milestones: 6.0.2xx, Backlog Jan 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants