You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建仅含一份原生库的多目标.NET NuGet包?

问题:多目标框架NuGet包中重复打包原生库导致体积过大的解决办法

我正在为外部C++库编写.NET绑定项目,希望将平台相关的原生库(已构建x64、arm64等版本)纳入nupkg,用户安装包即可直接使用。项目目标框架包含net6.0和net8.0,但当前配置下NuGet会为每个.NET框架各打包一次library.so,还会在包根目录再放一份,共3份副本;即使只目标netstandard2.0,也会有两份。原生库体积很大,导致包体积至少是单架构库的2倍,无法上传到限制250MB的nuget.org。

当前csproj相关配置:

<ItemGroup>
  <Content Include="library.so" Pack="true" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

生成的Nupkg结构:

...
./contentFiles/any/net6.0/library.so
./contentFiles/any/net8.0/library.so
./content/library.so
...

该原生库对net6.0和net8.0完全相同,请问如何构建仅包含一次该文件的包?或有哪些方案可避免用户手动安装该库?


解决方案

1. 配置Content项指定共享路径

修改csproj中的Content节点,明确设置PackagePath和ContentTargetFolders为跨框架的共享位置,让文件只打包一次:

<ItemGroup>
  <Content Include="library.so" 
           Pack="true" 
           CopyToOutputDirectory="PreserveNewest"
           PackagePath="contentFiles/any/any"
           ContentTargetFolders="contentFiles/any/any" />
</ItemGroup>

配置后,文件只会出现在contentFiles/any/any/library.so,所有目标框架都会引用这个共享位置的文件,不会生成多份副本。

2. 改用NativeLibrary资产类型

原生库更适合用NuGet专门的NativeLibrary类型处理,它默认支持跨框架共享,不会重复打包:

<ItemGroup>
  <NativeLibrary Include="library.so" 
                 Pack="true" 
                 CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

文件会被打包到标准的原生资产目录,所有兼容的.NET框架都会自动识别并引用该文件。

3. 按运行时标识符(RID)分架构打包

如果原生库是分架构的(x64、arm64),可以按RID组织文件,每个架构只打包一次,NuGet会根据用户环境自动匹配:

<ItemGroup>
  <NativeLibrary Include="runtimes/linux-x64/native/library.so" 
                 Pack="true" 
                 CopyToOutputDirectory="PreserveNewest" />
  <NativeLibrary Include="runtimes/linux-arm64/native/library.so" 
                 Pack="true" 
                 CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

这种方式既避免了跨框架重复,还能让用户只获取对应架构的库,进一步缩减包体积。

4. 移除content目录的冗余副本

如果不需要兼容旧版packages.config项目,可以添加配置避免在包根目录的content下生成副本:

<ItemGroup>
  <Content Include="library.so" 
           Pack="true" 
           CopyToOutputDirectory="PreserveNewest"
           PackagePath="contentFiles/any/any"
           ContentTargetFolders="contentFiles/any/any"
           PackageCopyToOutput="false" />
  <Content Remove="library.so" PackagePath="content/" />
</ItemGroup>

内容的提问来源于stack exchange,提问作者python_kaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:05:16