4

移植到 .NET 标准版本,您的源可能与可移植库相同,但支持的平台可能不一样。

例如.NET standard 1.6,可能是您的 api 可从便携式中获得的最低版本Profile47Profile47支持.net 4.5 或更高版本,nut.NET Standard 1.6仅支持4.6.1 及更高版本

使用新的msbuild 15 csproj/fsproj (也是 VS2017)的新多目标,是否可以同时为便携式库.Net 标准进行编译以使过渡更容易?

4

2 回答 2

6

的,但它不像交叉编译那样明显,.netstandard.net45不像.net40预定义的可移植库那样不容易命名。

在新 sdk 的Microsoft.NET.TargetFrameworkInference.targets中它说:

对于不支持推理的情况,可以明确指定标识符、版本和配置文件,如下所示:

   <PropertyGroup>
     <TargetFrameworks>portable-net451+win81;xyz1.0</TargetFrameworks>
   <PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'portable-net451+win81'">
     <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <TargetFrameworkProfile>Profile44</TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'xyz1.0'">
     <TargetFrameworkIdentifier>Xyz</TargetFrameworkVersion>
   <PropertyGroup>

TargetFrameworkProfile您可以从旧的 csproj/fsproj 中获得它。那是您的便携式库的配置文件标识符。您也可以从Nuget Target Frameworks中查找它。

TargetFrameworkIdentifier很简单,它是.NETPortable

TargetFrameworkProfile可能也可以从您的旧 csproj/fsprog 中获取。但是您也可以检查C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\和检查v4.0v4.5v4.6Profile 目录并找到您的 Profile。这些目录的列表如下:

v4.0

Profile1/    Profile143/  Profile2/    Profile3/    Profile4/   Profile6/
Profile102/  Profile147/  Profile225/  Profile328/  Profile41/  Profile88/
Profile104/  Profile154/  Profile23/   Profile336/  Profile42/  Profile92/
Profile131/  Profile158/  Profile24/   Profile344/  Profile46/  Profile95/
Profile136/  Profile18/   Profile240/  Profile36/   Profile47/  Profile96/
Profile14/   Profile19/   Profile255/  Profile37/   Profile5/

v4.5

Profile111/  Profile259/  Profile49/  Profile7/  Profile75/  Profile78/

v4.6

Profile151/  Profile157/  Profile31/  Profile32/  Profile44/  Profile84/

您为便携式目标选择的绰号是?是也不是,自动打包 nuget 很重要,因此最好使用Nuget Target Frameworks中的值,但要注意一点。我不确定这是否是因为最新版本的 nuget,但它似乎希望将TargetFrameworkVersion添加到portable名字对象中。所以对于Profile47, 也就是v4.0, 实际上应该是portable40-net45+sl5+win8

另一个添加编译器定义的项目,您可能会发现使用DefineConstants很有用。您可以随意制作它,它在历史上一直是大写的 PROFILEXXX,只需将其添加到条件组中即可。

<DefineConstants>$(DefineConstants);PROFILE47</DefineConstants>

最后要注意的是,未提供默认参考包括,因此您必须添加自己的。

<ItemGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8'">
  <Reference Include="System" />
  <Reference Include="System.Core" />
  <Reference Include="System.Windows" />
</ItemGroup>

CSharp 示例

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

  <PropertyGroup>
    <TargetFrameworks>netstandard1.6;portable40-net45+sl5+win8</TargetFrameworks>
    <Description>YOUR DESCRIPTION</Description>
    <Company>YOUR COMPANY</Company>
    <Authors> YOUR AUTHORS </Authors>
    <Copyright>YOUR COPYRIGHT</Copyright>
    <AssemblyVersion>YOUR VERSION</AssemblyVersion>
    <FileVersion>YOUR VERSION</FileVersion>
    <PackageProjectUrl>YOUR PROJECT URL</PackageProjectUrl>
    <PackageLicenseUrl>YOUR LICENSE</PackageLicenseUrl>
    <PackageTags>YOUR TAGS</PackageTags>
    <IncludeSymbols>True</IncludeSymbols>
    <IncludeSource>True</IncludeSource>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
    <Version>YOUR NUGET VERSION</Version>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8'">
     <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <TargetFrameworkProfile>Profile47</TargetFrameworkProfile>
     <DefineConstants>$(DefineConstants);PROFILE47</DefineConstants>
   </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8'">
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Windows" />
  </ItemGroup>

</Project>

F# 示例

*警告:F# 目前需要此 fsproj 的 Mac 版 Mono 或 Visual Studio 2017 预览版 15.3 的 beta 版本。此外,示例的更改包括 PackageReferenceFSharp.Compiler.ToolsFSharp.Core4.1 最后一个支持的可移植 FSharp 版本(这是相对较新的版本。)

<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk" ToolsVersion="15.0">

  <PropertyGroup>
    <TargetFrameworks>netstandard1.6;portable40-net45+sl5+win8</TargetFrameworks>
    <Description>YOUR DESCRIPTION</Description>
    <Company>YOUR COMPANY</Company>
    <Authors> YOUR AUTHORS </Authors>
    <Copyright>YOUR COPYRIGHT</Copyright>
    <AssemblyVersion>YOUR VERSION</AssemblyVersion>
    <FileVersion>YOUR VERSION</FileVersion>
    <PackageProjectUrl>YOUR PROJECT URL</PackageProjectUrl>
    <PackageLicenseUrl>YOUR LICENSE</PackageLicenseUrl>
    <PackageTags>YOUR TAGS</PackageTags>
    <IncludeSymbols>True</IncludeSymbols>
    <IncludeSource>True</IncludeSource>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
    <Version>YOUR NUGET VERSION</Version>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8'">
     <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <TargetFrameworkProfile>Profile47</TargetFrameworkProfile>
     <DefineConstants>$(DefineConstants);PROFILE47</DefineConstants>
   </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8'">
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Windows" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="FSharp.Core" Version="4.1.*" />
    <PackageReference Include="FSharp.Compiler.Tools" Version="4.1.*" PrivateAssets="All" 
    />
    <PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" 
    />
  </ItemGroup>

  <ItemGroup>
    <Compile Include="YourModule1.fs" />
    <Compile Include="YourModule2.fs" />
  </ItemGroup>

</Project>
于 2017-07-07T20:53:20.543 回答
4

先前的答案是准确的,但实际上还不够。您需要参考可移植语言目标以获得正确的行为。也可能有其他 SDK 引用,您可能希望隐式定义ifdefsPROFILE328.

我写了一个 NuGet 包,你可以添加到你的项目中,在这里“做正确的事”:

https://github.com/onovotny/MSBuildSdkExtras

编辑:csproj 看起来像这样:

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

  <PropertyGroup>
    <TargetFrameworks>netstandard1.6;portable-net45+sl5+win8</TargetFrameworks>
    <Description>YOUR DESCRIPTION</Description>
    <Company>YOUR COMPANY</Company>
    <Authors> YOUR AUTHORS </Authors>
    <Copyright>YOUR COPYRIGHT</Copyright>
    <AssemblyVersion>YOUR VERSION</AssemblyVersion>
    <FileVersion>YOUR VERSION</FileVersion>
    <PackageProjectUrl>YOUR PROJECT URL</PackageProjectUrl>
    <PackageLicenseUrl>YOUR LICENSE</PackageLicenseUrl>
    <PackageTags>YOUR TAGS</PackageTags>
    <IncludeSymbols>True</IncludeSymbols>
    <IncludeSource>True</IncludeSource>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
    <Version>YOUR NUGET VERSION</Version>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MSBuild.Sdk.Extras" Version="1.0.5" PrivateAssets="all" />
  </ItemGroup>

  <Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
</Project>
于 2017-07-19T18:58:46.717 回答