[Translation] does not install Mono on Linux to build .NET Framework Class Library

In this article, I showed you how to build a version of the .NET Framework for .NET projects, instead of using Mono on Linux. Universal use Microsoft's new release of Mocrosoft.NETFramework.ReferenceAssemblies NuGet package, you will not need to install any additional software packages in addition to .NET Core SDK is! In general, when building .NET Framework Class Library on a Linux system, you only need to add the following node in your project file:

<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0-preview.2" />

 

Background: Construction of full-framework libraries on Linux

If you are building a .NET Standard NuGet packages, and you want to provide users with the best experience ( and avoid some dependencies ), then you will need to check the cross-platform recommendations positioning. There are a lot of do's and do not recommend, but I tend to boil down to: If your goal is to any version of .NET Standard, then you need at least the following objectives framework:

<TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks>

If your goal is to .NET Standard 1.x, then add it to build the target, it is important that included two goals to avoid .NET Framework .NET Standard 2.0 gasket problems.

This raises a number of issues - the full .NET Framework target theoretically can only build on Windows. In the previous article , I showed how to solve this problem by installing and using Mono assemblies it provides. In that article , I also demonstrated running on Linux .NET Framework test suite. So far, it is very effective for me, but it has several drawbacks:

  • It requires you to install Mono
  • It is necessary to add a little hacky .props file
  • It does not get official support, so if it does not work, you have to think of ways

.props file FrameworkPathOverride MSBuild variable is set to Mono reference assemblies, which is able to build our way. But as Jon Skeet in the comments pointed out, Mono is not really necessary. We just need a way to easily get a reference to the compiled assembly. That is provided by Microsoft Microsoft.NETFramework.ReferenceAssemblies package.

By using the procedure set NuGet Microsoft.NETFramework.ReferenceAssemblies

I see Muhammad Rehan Saeed before this Tweet, I did not notice Microsoft.NETFramework.ReferenceAssemblies NuGet package. This information is a great building full .NET Framework Class Library only need to install the .NET Core SDK on Linux!

Let me give you an example.

You can use   dotnet new classlib   create a .NET Core library, which will provide a .csproj file as shown below:

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

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0</TargetFrameworks>
  </PropertyGroup>

</Project>

 Modify the .csproj project file, add more goals to build:

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

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks>
  </PropertyGroup>

</Project>

 If you try to use this time on Linux   DOTNET Build  , you will see an error similar to the following:

/usr/share/dotnet/sdk/2.1.700/Microsoft.Common.CurrentVersion.targets(1175,5): 
error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.6.1" 
were not found. To resolve this, install the SDK or Targeting Pack for this framework 
version or retarget your application to a version of the framework for which you have 
the SDK or Targeting Pack installed. Note that assemblies will be resolved from the 
Global Assembly Cache (GAC) and will be used in place of reference assemblies. 
Therefore your assembly may not be correctly targeted for the framework you intend.

 And finally to witness the miracle moment. Add Microsoft.NETFramework.ReferenceAssemblies NuGet package into your project file:

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

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks>
  </PropertyGroup>

  <!-- Add this reference-->
  <ItemGroup>
    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0-preview.2" />
  </ItemGroup>

</Project>

 Executed again   DOTNET Build  , actually constructed a success.

Build succeeded.
    0 Warning(s)
    0 Error(s)

Use PrivateAssets feature prevents Microsoft.NETFramework.ReferenceAssemblies package "leak" into the dependent project or published NuGet package; it is only dependent on a build.

Simply add the package to the project can get a better experience than installing Mono. Most importantly, this method will be from now on .NET Core support . And it will get better in the .NET Core 3.0 SDK, .NET Core SDK will automatically refer to this package, if necessary, so, in theory, we do not need to manually edit the configuration file to add the node project to build .NET Framework project!

How it works: a meta-package, a .targets, and lots of dlls

If you are interested in the work package, I suggest you read the relevant question , but I will provide a high-level outline here.

We will Microsoft.NETFramework.ReferenceAssemblies NuGet package itself begins. This package is a meta package does not contain a code, but for each of the supported versions of the .NET Framework are dependent on different NuGet package:

例如:以 .NET Framework 4.6.1 为目标时将依赖 Microsoft.NETFramework.ReferenceAssemblies.net461。此方法可以确保您只会下载到与目标框架一致的 NuGet 包。

如果你打开一个特定 Framework 的 NuGet 包,你会在 build 文件夹中发现两件事:

  • 一个 .targets 文件
  • 一个 .NETFramework 文件夹,其中包含引用的全部程序集(> 100MB)

.targets 文件与我上一篇文章中的 .props 文件的用途类似 - 它告诉 MSBuild 在哪里可以找到框架库。以下示例来自.NET 4.6.1包: 

<Project>
  <PropertyGroup Condition=" ('$(TargetFrameworkIdentifier)' == '.NETFramework') And ('$(TargetFrameworkVersion)' == 'v4.6.1') ">
    <TargetFrameworkRootPath>$(MSBuildThisFileDirectory)</TargetFrameworkRootPath>

    <!-- FrameworkPathOverride is typically not set to the correct value, and the common targets include mscorlib from FrameworkPathOverride.
         So disable FrameworkPathOverride, set NoStdLib to true, and explicitly reference mscorlib here. -->
    <EnableFrameworkPathOverride>false</EnableFrameworkPathOverride>
    <NoStdLib>true</NoStdLib>
  </PropertyGroup>

  <ItemGroup Condition=" ('$(TargetFrameworkIdentifier)' == '.NETFramework') And ('$(TargetFrameworkVersion)' == 'v4.6.1') ">
    <Reference Include="mscorlib" Pack="false" />
  </ItemGroup>

</Project>

 这会将 TargetFrameworkRootPath 参数设置为包含 .targets 文件的文件夹。MSBuild 遍历 NuGet 包的文件夹结构(.NETFramework \ v4.6.1),找到dll,并找到引用程序集: 

我已经使用.NET Core 2.1 SDK 和 2.2 SDK 测试了这些软件包,并且它的工作时间都非常出色。试试看!

Reference

 

Guess you like

Origin www.cnblogs.com/jRoger/p/using-reference-assemblies-to-build-net-framework-libararies-on-linux-without-mono.html