如何构建多平台nuget包

虽然C#可以直接编译成 AnyCPU,可以直接在 x86x64ARM平台运行。

但是实际项目中,我们可能避免不了会引用一些外部的依赖库,而这些外部依赖库又不能编译成 AnyCPU!

通常解决这种问题可以通过进程隔离来解决,也可以通过动态加载程序集来解决。

所以采用动态程序集加载的方式的话,我们的nuget包就需要同时把 x86,x64,arm相关的运行库同时打包进去了。

之前我们已经讲过, 如何手动构建nuget包,如果还不太清楚的小伙伴,可以回顾下手动构建nuget包。

构建多平台 nuget包之前,需要先了解一些基础知识:

  1. 手动创建nuget包的基本方法

  2. nuget的目录结构

  3. csproj的结构的基础

  4. 编译过程

这里不做详细描述~

Nuget包的基础结构

├─ Build│  ├─net462│  │    └─*.props│  │    └─*.targets│  └─netstandard1.3├─lib│  ├─net462│  └─netstandard1.3└─runtimes    ├─win-arm64    │  └─native    ├─win-x64    │  └─native    └─win-x86        └─native

说明:

  1. Build 文件夹,存放用于参与编译的配置文件。包含 *.props和 *.targets格式文件。 *.props通常用于设置 csproj文件中特定的属性,可以理解为 一个普通类的属性,这个属性值可以先设置,用不用就不关它事情。 *.targets通常用于执行某个操作,可以理解为 一个普通类里面的方法,可以使用其它属性执行某个操作。需要注意的是:上述描述主要是为了方便理解,普通属性的设置也可以存放在 *.targets文件中。

  2. lib 文件夹,存放参与编译的相关(动态/静态)链接库,可同时存放多个。编译时,默认情况下,该文件夹的文件会自动拷贝到输出目录下。

  3. runtimes 文件夹,存放运行时所依赖的相关(动态/静态)链接库。该文件夹的结构请参考上述结构来存放。虽然该结构并不是nuget包里面的强制要求,但是按照这种结构会比较规范。尤其是在 .NET CORE的应用中,运行时将会自动在该结构中查找对应的依赖库。

细心的朋友会发现,这个结构和上一次的结构会有什么区别?

是的,多了Build目录!所以这次构建多平台 nuget包,就需要用到它。

要想同时支持多平台,就需要在 AnyCPU的条件编译下,将 Nuget包内部的文件,动态输出到指定的目录。程序运行的时候,再动态加载该文件即可。

Nuget包内部文件组织步骤

这里以.net framework net45为例,命名为 nuget.test其它框架下修改对应的框架名称即可:

  1. 分别创建 build->net45lib->net45runtimes->win-x86runtimes->win-x64等文件夹

  2. 将需要打包的文件分别拖动到对应的文件夹中。

  3. 创建 nuget.test.targets文件

编辑该文件,输入以下内容:


<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup Condition="'$(Platform)' == 'AnyCPU' Or '$(Platform)' == 'Any CPU'">
        <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x86\native\CefSharp.Wpf.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>runtimes\win-x86\native\CefSharp.Wpf.dll</Link>
            <Visible>false</Visible>
        </Content>
        <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x64\native\CefSharp.Wpf.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>runtimes\win-x64\native\CefSharp.Wpf.dll</Link>
            <Visible>false</Visible>
        </Content>
    </ItemGroup>
</Project>

上面这段配置的主要目的,是根据编译器的条件编译,把nuget包中不同平台下的文件,复制到输出目录。

上述配置简要说明:

$(Platform) 表示编译平台:x86,x64,Any CPU,ARM64$(MSBuildThisFileDirectory) 表示当前文件所在的目录,这里是指 nuget.test.targets 文件所在的目录绝对路径。Content 表示项目内容CopyToOutputDirectory 复制到输出目录    PreserveNewest        较新才复制    Always               总是复制    Never                 从不Link                  需要输出的文件目录位置,以输出目录作为根目录。

有这段配置文件后,编译的时候就会根据条件编译配置,自动把文件添加到输出目录中。x86,x64的条件编译的方法也是一样的,大家可以自行补充。

注意事项:

  1. 一个nuget包的 *.targets和 *.props文件只能创建一个

  2. *.targets和 *.props 前缀文件名需要和包名一致

  3. 配置文件中的格式不能有无故的换行,空格。参见:诡异的编译错误

根据上述方法,可以尝试打一个多平台的nuget包了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷眼Σ(-᷅_-᷄๑)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值