使用.NET Core 2.2创建带原生依赖的NuGet包及单元测试配置
解决方案:.NET Core 2.2 多平台原生依赖 NuGet 包及单元测试自动复制配置
我来帮你梳理清楚整个配置流程,从原生依赖的存放结构到项目文件的具体设置,确保打包和单元测试都能正常工作:
一、原生依赖在源码中的存放结构
首先,按照 NuGet 的官方 runtime 约定来组织你的文件,这样打包后 NuGet 能自动识别并在安装时分发对应平台的依赖。在你的主项目(要打包成 NuGet 的项目)根目录下创建如下结构:
YourMainProject/ ├── runtimes/ │ ├── win-x64/ │ │ └── native/ │ │ └── YourNativeLib.dll # Windows x64 预编译DLL │ ├── linux-x64/ │ │ └── native/ │ │ └── libYourNativeLib.so # Linux x64 预编译SO │ └── linux-arm/ │ └── native/ │ └── libYourNativeLib.so # Linux ARM 预编译SO ├── YourMainProject.csproj └── 其他源码文件...
这个结构是 NuGet 识别原生依赖的标准格式,不需要额外配置就能让包管理器正确处理跨平台分发。
二、主项目(NuGet 打包项目)的 .csproj 配置
虽然按照上面的结构放置文件后,dotnet pack 默认会包含这些文件,但为了保险起见,建议在主项目的 .csproj 中显式声明要打包的原生文件,避免遗漏:
<Project Sdk="Microsoft.NET.Sdk"> <!-- 其他项目配置 --> <ItemGroup> <!-- 显式包含各平台原生文件并指定打包路径 --> <None Include="runtimes/win-x64/native/*.dll" Pack="true" PackagePath="runtimes/win-x64/native/" /> <None Include="runtimes/linux-x64/native/*.so" Pack="true" PackagePath="runtimes/linux-x64/native/" /> <None Include="runtimes/linux-arm/native/*.so" Pack="true" PackagePath="runtimes/linux-arm/native/" /> </ItemGroup> </Project>
这样配置后,执行 dotnet pack 时,所有平台的原生依赖都会被正确打包到 NuGet 包的对应目录中。
三、单元测试项目的 .csproj 配置
单元测试项目需要根据当前构建的目标平台,自动复制对应路径下的原生依赖到输出目录。你可以通过条件性 ItemGroup 实现这一点:
方式一:分平台单独配置(更直观)
<Project Sdk="Microsoft.NET.Sdk"> <!-- 其他项目配置,包括对主项目的引用 --> <!-- 根据目标运行时复制对应平台的原生依赖 --> <ItemGroup Condition="'$(RuntimeIdentifier)' == 'win-x64'"> <None Include="..\YourMainProject\runtimes\win-x64\native\*.dll" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> <ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64'"> <None Include="..\YourMainProject\runtimes\linux-x64\native\*.so" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> <ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-arm'"> <None Include="..\YourMainProject\runtimes\linux-arm\native\*.so" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> </Project>
方式二:通用变量配置(更简洁)
利用 $(RuntimeIdentifier) 变量自动拼接路径,减少重复代码:
<Project Sdk="Microsoft.NET.Sdk"> <!-- 其他项目配置 --> <ItemGroup Condition="'$(RuntimeIdentifier)' != ''"> <None Include="..\YourMainProject\runtimes\$(RuntimeIdentifier)\native\*" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> </Project>
四、运行单元测试的注意事项
因为依赖是基于特定 RuntimeIdentifier 的,所以运行测试时需要指定目标平台:
- 使用命令行:
dotnet test -r win-x64(替换成你需要测试的平台:linux-x64/linux-arm) - 在 Visual Studio 中:打开单元测试项目的属性,在「生成」选项卡中设置「运行时标识符」,或者在调试配置中指定对应的 RuntimeIdentifier。
内容的提问来源于stack exchange,提问作者Hein Gustavsen
相关产品推荐
相关产品推荐

