Sdk: User has to manually define TargetFrameworkIdentifier in some cases

Created on 18 Oct 2016  路  4Comments  路  Source: dotnet/sdk

Steps

  1. dotnet restore3
  2. dotnet build3

This.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
  <PropertyGroup>
    <VersionPrefix>1.0.0</VersionPrefix>
    <TargetFrameworks>net40-client</TargetFrameworks>
    <DebugType>portable</DebugType>
    <AssemblyName>net40client</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="**\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
    <EmbeddedResource Include="**\*.resx" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
    <EmbeddedResource Include="compiler\resources\**\*" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
    <PackageReference Include="Microsoft.NET.Sdk">
      <Version>1.0.0-alpha-20161018-2</Version>
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>
  </ItemGroup>
  <PropertyGroup Condition=" '$(TargetFramework)' == 'net40-client' ">
    <DefineConstants>$(DefineConstants);NET40_CLIENT</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <DefineConstants>$(DefineConstants);RELEASE;TRACE</DefineConstants>
    <Optimize>true</Optimize>
  </PropertyGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Expected

Things should build without any hiccup

Actual

User gets an error:

Microsoft (R) Build Engine version 15.1.0.0
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 10/17/2016 7:52:11 PM.
Project "C:\Users\jver\Desktop\net40client\net40client.csproj" on node 1 (Build target(s)).
Project "C:\Users\jver\Desktop\net40client\net40client.csproj" (1) is building "C:\Users\jver\Desktop\net40client\net40client.csproj" (1:2) on node 1 (Build target(s)).
C:\Users\jver\.nuget\packages\microsoft.net.sdk\1.0.0-alpha-20161018-2\build\Microsoft.NET.TargetFrameworkInference.targets(76,5): error : Cannot infer TargetFrameworkIdentifier and/or TargetFrameworkVersion from TargetFramework='net40-client'. See comment in C:\Users\jver\.nuget\packages\microsoft.net.sdk\1.0.0-alpha-20161018-2\build\Microsoft.NET.TargetFrameworkInference.targets showing how to specify them explicitly. [C:\Users\jver\Desktop\net40client\net40client.csproj]
Done Building Project "C:\Users\jver\Desktop\net40client\net40client.csproj" (Build target(s)) -- FAILED.

Done Building Project "C:\Users\jver\Desktop\net40client\net40client.csproj" (Build target(s)) -- FAILED.


Build FAILED.

"C:\Users\jver\Desktop\net40client\net40client.csproj" (Build target) (1) ->
"C:\Users\jver\Desktop\net40client\net40client.csproj" (Build target) (1:2) ->
(_CheckForUnsupportedTargetFramework target) ->
  C:\Users\jver\.nuget\packages\microsoft.net.sdk\1.0.0-alpha-20161018-2\build\Microsoft.NET.TargetFrameworkInference.targets(76,5): error : Cannot infer TargetFrameworkIdentifier and/or TargetFrameworkVersion from TargetFramework='net40-client'. See comment in C:\Users\jver\.nuget\packages\microsoft.net.sdk\1.0.0-alpha-20161018-2\build\Microsoft.NET.TargetFrameworkInference.targets showing how to specify them explicitly. [C:\Users\jver\Desktop\net40client\net40client.csproj]

    0 Warning(s)
    1 Error(s)

User has to drop this in their .csproj:

  <PropertyGroup Condition="'$(TargetFramework)' == 'net40-client'">
    <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>client</TargetFrameworkProfile>
  </PropertyGroup>

Suggested fix

A simple task should be written that uses NuGet APIs to get this information. It is very easy and NuGet is already there for restore3.

https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Frameworks/NuGetFramework.cs

/cc @nguerrera

Most helpful comment

Just wanted to thank you for providing this workaround/fix, as I couldn't find this in the docs:

  <PropertyGroup Condition="'$(TargetFramework)' == 'net40-client'">
    <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>client</TargetFrameworkProfile>
  </PropertyGroup>

I was migrating a project to csproj from xproj where it was targeting .NET 4.0 client profile in addition to .NET 4.5.1 and .NET Standard 1.3:

<TargetFrameworks>net40-client;net451;netstandard1.3</TargetFrameworks>

I was hitting "Cannot infer TargetFrameworkIdentifier and/or TargetFrameworkVersion from TargetFramework='net40-client'" after the upgrade.

All 4 comments

The suggested fix is not possible because TargetFrameworkIdentifier must be set before common targets during static evaluation. We cannot invoke a task for it.

We deliberarely opted to handle the most common cases and ask the users of less common cases to be explicit.

We can add more cases based on demand,-client would be easy but old plib profiles next to impossible.

Long term we would like this to be driven by a generated targets file that could handle this more exhaustively. The combinatorial alternate spellings of plib profiles would still be a problem, though.

Closing this since this is the current design. Setting the TFM through static evaluation offers lots of perf and other benefits and having to explicitly specify the TFM in some cases is a tradeoff we've made.

Just wanted to thank you for providing this workaround/fix, as I couldn't find this in the docs:

  <PropertyGroup Condition="'$(TargetFramework)' == 'net40-client'">
    <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>client</TargetFrameworkProfile>
  </PropertyGroup>

I was migrating a project to csproj from xproj where it was targeting .NET 4.0 client profile in addition to .NET 4.5.1 and .NET Standard 1.3:

<TargetFrameworks>net40-client;net451;netstandard1.3</TargetFrameworks>

I was hitting "Cannot infer TargetFrameworkIdentifier and/or TargetFrameworkVersion from TargetFramework='net40-client'" after the upgrade.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

noelitoa picture noelitoa  路  3Comments

krwq picture krwq  路  3Comments

davkean picture davkean  路  3Comments

thomaslevesque picture thomaslevesque  路  3Comments

moozzyk picture moozzyk  路  3Comments