将第 3 方库重新打包为 NuGet 包

Repackage 3rd party libraries as NuGet package

我正在使用支持 .NET Core 但不支持 .NET Standard 的第 3 方库。他们为他们支持的每个平台提供单独的二进制 SDK; win-x86、linux-x64 等。每个平台都有一个 CoolSdkDotNetCore.dll 和一个 coolsdk.dll/so/dylib。 CoolSdkDotNetCore.dll 文件对于每个平台确实不同 - 它们的大小完全相同,但具有不同的 SHA 哈希值。

为了我自己的理智,我想将所有这些重新打包为一个 .nupkg 使用运行时标识符为给定平台引入正确的东西,以便我可以为 Windows 构建, docker, 等而无需交换二进制文件。我有一个这样的项目文件:

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageId>CoolSdk.NetStandard</PackageId>
    <Version>1.2.3</Version>
    <RootNamespace>coolsdk</RootNamespace>
    <AssemblyName>coolsdk</AssemblyName>
  </PropertyGroup>

  <ItemGroup>

    <None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>

    <None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>

  </ItemGroup>

</Project>

这会生成一个 .nupkg,它似乎拥有我需要的一切,但使用项目实际上并没有获得对 CoolSdkDotNetCore 程序集的引用。在 bin 文件夹中,我看到一个包含 native 组件的运行时文件夹,但没有 lib 文件夹(lib 文件夹肯定存在于实际的 nupkg 中)。

我在这里错过了什么?我是否需要回去自己写一个 nuspec 而不是尝试使用 csproj 为我生成它,或者我可以使用其他技巧吗?


编辑:

将上面的库路径从 runtimes/<rid>/lib/netcore 更改为 runtimes/<rid>/netcoreapp 允许将 lib 文件夹复制到使用项目中的 bin 文件夹,但我仍然无法实际引用程序集.手动添加对 CoolSdkDotNetCore 的引用,例如:

<Reference Include="CoolSdkDotNetCore">
  <HintPath>CoolSdkDotNetCore.dll</HintPath>
</Reference>

生成 MSB3245 - Could not resolve this reference....

答案是将 .NET Core 程序集的单个副本作为 "ref"。哪一个并不重要——这个程序集永远不会 运行,只在编译时由 IDE 加载。在 运行 时,将从 runtimes 文件夹加载正确的程序集。作为最后的陷阱,nuget 不会将同一个文件打包两次;如果您在项目组中有两个或更多项目具有相同的 Update 键值,则实际上只有最后一个项目会被添加到最终的 .nupkg。因此,随机选择我在项目的根目录中复制了 windows/x64 dll,并因此更新了我的 csproj:

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageId>CoolSdk.NetStandard</PackageId>
    <Version>1.2.3</Version>
    <RootNamespace>coolsdk</RootNamespace>
    <AssemblyName>coolsdk</AssemblyName>
    <IncludeBuildOutput>false</IncludeBuildOutput>
  </PropertyGroup>

  <ItemGroup>
    <None Pack="true" PackagePath="ref/netcoreapp2.1/CoolSdkDotNetCore.dll" Update="CoolSdkDotNetCore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>

    <None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>

    <None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>

  </ItemGroup>

</Project>