【译】在 Linux 上不安装 Mono 构建 .NET Framework 类库
在这篇文章中,我展示了如何在 Linux 上构建针对 .NET Framework 版本的.NET项目,而不使用 Mono。通用使用微软新发布的 Mocrosoft.NETFramework.ReferenceAssemblies NuGet 包,您将不需要安装除 .NET Core SDK 之外的任何其他软件包!总的来说,在 Linux 系统上构建 .NET Framework 类库时,只需要在你的项目文件中添加下面的节点即可:
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0-preview.2" />
背景:在 Linux 上构建 full-framework 类库
如果您正在构建 .NET Standard NuGet 软件包,并且希望为用户提供最佳体验(并避免一些依赖性),那么您将需要查看有关跨平台定位的建议。那里有很多可以做和不可以做的建议,但我倾向于将其归结为:如果您的目标是任何版本的 .NET Standard,那么您至少需要以下目标框架:
<TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks>
如果您的目标是.NET Standard 1.x,那么将其添加到构建目标中时,重要的是包含两个 .NET Framework 目标以避免 .NET Standard 2.0 垫片出现问题。
这就引出了一些问题 - 完整的 .NET 框架目标理论上只能在 Windows 上构建。在上一篇文章中,我展示了如何通过安装 Mono 并使用它提供的程序集来解决这个问题。在那篇文章中,我也展示了在 Linux 上运行 .NET Framework 测试套件。到目前为止,这对我来说非常有效,但它有几个缺点:
- 它需要你安装 Mono
- 它需要添加一个有点hacky .props文件
- 它没有得到官方的支持,所以如果它不起作用,你就得自己想办法
.props 文件将 FrameworkPathOverride MSBuild 变量设置为 Mono 引用程序集,这是我们能够构建的方式。但正如 Jon Skeet在评论中指出的那样,Mono 实际上并不是必需的。我们只需要一种方法来轻松获取要编译的引用程序集。那就是微软提供的 Microsoft.NETFramework.ReferenceAssemblies 包。
通过 NuGet 使用程序集 Microsoft.NETFramework.ReferenceAssemblies
在我看到 Muhammad Rehan Saeed 的这条推文之前,我完全没有注意到 Microsoft.NETFramework.ReferenceAssemblies NuGet 包。这是一条非常棒的信息,构建 full .NET Framework 类库只需要在 Linux 上安装 .NET Core SDK !
我们来举个例子吧。
您可以使用 dotnet new classlib 创建一个 .NET Core 类库,它将提供一个如下所示的 .csproj 文件:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup> </Project>
修改 .csproj 项目文件,添加更多的构建目标:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks>
</PropertyGroup> </Project>
如果此时尝试在 Linux 上使用 dotnet build ,您将看到类似以下内容的错误:
/usr/share/dotnet/sdk/2.1./Microsoft.Common.CurrentVersion.targets(,):
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.
终于到了见证奇迹的时刻。添加 Microsoft.NETFramework.ReferenceAssemblies NuGet 包到你的项目文件:
<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>
再次执行 dotnet build ,竟然构建成功了。
Build succeeded.
Warning(s)
Error(s)
使用 PrivateAssets 特性可防止 Microsoft.NETFramework.ReferenceAssemblies 包“泄漏”到依赖项目或已发布的 NuGet 包中;它只是一个构建时依赖。
只需将软件包添加到项目中就可以获得比安装 Mono 更好的体验。最重要的是,这将是从现在开始 .NET Core 支持的方法。并且在 .NET Core 3.0 SDK 中它将变得更好,必要时 .NET Core SDK 将自动引用此包,所以,理论上根本不需要我们手工编辑项目文件添加配置节点去构建 .NET Framework 项目!
它是如何工作的:a meta-package, a .targets, and lots of dlls
如果你对包的工作方式感兴趣,我建议你阅读相关的问题,但我会在这里提供一个高级的大纲。
我们将从 Microsoft.NETFramework.ReferenceAssemblies NuGet 包本身开始。这个包是一个不包含代码的元包,但是对于每个受支持的 .NET Framework 版本都依赖于不同的 NuGet 包:
例如:以 .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
原文链接:https://andrewlock.net/using-reference-assemblies-to-build-net-framework-libararies-on-linux-without-mono/
【译】在 Linux 上不安装 Mono 构建 .NET Framework 类库的更多相关文章
- jemalloc在linux上从安装到使用
jemalloc在linux上从安装到使用 上次在引导大家安装Redis时提到可能会报错: 发现了redis有用到jemalloc. 首先,jemalloc是干什么的? 我们看看作者自己的介绍: j ...
- 分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装
redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...
- GIT在Linux上的安装和使用简介
GIT最初是由Linus Benedict Torvalds为了更有效地管理Linux内核开发而创立的分布式版本控制软件,与常用的版本控制工具如CVS.Subversion不同,它不必服务器端软件支持 ...
- 分布式缓存技术redis学习(一)——redis简介以及linux上的安装
redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...
- 在Linux上怎么安装和配置Apache Samza
samza是一个分布式的流式数据处理框架(streaming processing),它是基于Kafka消息队列来实现类实时的流式数据处理的.(准确的说,samza是通过模块化的形式来使用kafka的 ...
- ODI11G 在Linux上的安装配置
ODI11G 在Linux上的安装配置 OS环境:Red hat Linux x86_64 一.JDK安装 1. 去oracle官网上下载 http://www.oracle.com/technetw ...
- 【JAVAWEB学习笔记】27_Redis:在Linux上的安装、Jedis和常用命令
一.Redis简介 1.关于关系型数据库和nosql数据库 关系型数据库是基于关系表的数据库,最终会将数据持久化到磁盘上,而nosql数据 库是基于特殊的结构,并将数据存储到内存的数据库.从性 ...
- 【数据库】Mean web开发 04-MongoDB在Linux上的安装及遇到的问题
简介 Mean是JavaScript的全栈开发框架.更多介绍 用MongoDB实现持久数据的存储是Mean Web全栈开发中的一部分. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非 ...
- linux上redis安装配置及其防漏洞配置及其攻击方法
Linux上redis安装: 需先在服务器上安装yum(虚拟机可使用挂载的方式安装) 安装配置所需要的环境运行指令: yum -y install gcc 进入解压文件执行make 指令进行编译 执 ...
随机推荐
- 04 Javascript的运算符
js中的运算符跟python中的运算符有点类似,但也有不同.所谓运算,在数学上,是一种行为,通过已知量的可能的组合,获得新的量. 1.赋值运算符 以var x = 12,y=5来演示示例| 2.算数运 ...
- 机器学习经典算法之KNN
一.前言 KNN 的英文叫 K-Nearest Neighbor,应该算是数据挖掘算法中最简单的一种. 先用一个例子体会下. /*请尊重作者劳动成果,转载请标明原文链接:*/ /* https://w ...
- 由django请求生命周期延伸出的知识点大总结
django项目搭建见: https://www.cnblogs.com/dongxixi/p/10981577.html django请求生命周期图: 由浏览器发起请求开始 知识点1: 浏览器与服务 ...
- springboot 2.X 在访问静态资源的的时候出现404的问题
通过idea快速搭建一个springboot项目: springboot版本2.1.6 在网上看的资料,springboot静态资源访问如下: "classpath:/META‐INF/re ...
- HBase 学习之路(九)——HBase容灾与备份
一.前言 本文主要介绍Hbase常用的三种简单的容灾备份方案,即CopyTable.Export/Import.Snapshot.分别介绍如下: 二.CopyTable 2.1 简介 CopyTabl ...
- eclipse下jdbc数据源与连接池的配置及功能简介
今天在做四则运算网页版的时候遇到了一个困惑,由于需要把每个产生的式子存进 数据库,所以就需要很多次重复的加载驱动,建立连接等操作,这样一方面写程序不方便,加大了程序量,另一方面,还有导致数据库的性能急 ...
- 从无到有构建vue实战项目(三)
四.响应式布局的实现 elemnt-ui参考bootatrap提供了响应式布局,附上地址:https://element.eleme.cn/#/zh-CN/component/layout 以下是我的 ...
- HDU 1394:Minimum Inversion Number(线段树区间求和单点更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number Problem Description The in ...
- CentOS中对MySql的root用户重置密码
由于一般的修改ini文件来完成无密码登录数据库容易造成较大风险,所以使用修改启动服务参数的方式来更新user表,达到无密码登陆的目的. 1.关闭系统下运行的mysql服务 (1)杀掉进程号达到关闭目的 ...
- ZigBee入门第一天
按键查询控制灯的状态 1.宏定义灯和按键 2.按键和灯初始化 3.用if语句消抖的方法,实现按键控制灯的状态 相关寄存器 PxSEL PxDIR #include"ioCC2530.h&qu ...