如何在多个平台上的 Nuget 中包含本机资产,仅限 64 位

How to include native assets in Nuget on multiple platforms, only 64-bit

提问人:Veksi 提问时间:3/8/2018 最后编辑:AeroXVeksi 更新时间:10/30/2020 访问量:7108

问:

我正在创建一个具有以下想法的 NuGet 包:

  • 具有与平台相关的可执行文件和 dll(Windows、Linux 和 MacOS)。
  • 本机二进制文件是 64 位二进制文件。
  • 用于使用这些本机资源的 .NET Standard 2.0 库。
  • 在 .NET 库开发和测试期间,本机资源应包含在生成中,以便它们可用。

这个想法不是嵌入本机资源然后提取它们,而是与使用它们的 .NET 库一起分发。但是,我遇到了一些问题,我想问一下。

1. 从根到外部依赖是否有普遍接受的约定?目前,我的结构是:

.\Solution.sln
.\Solution.nuspec
.\runtimes\win-x64\native\<.exe and .dll>
.\Project\Project.csproj

此 .NET Standard 2.0 库项目编译为 .我想知道根目录是否有其他约定或名称。我已经阅读了其他来源和 GitHub 项目创建 NuGet 包Project\bin\Debug\netstandard2.0

2. 拿文件本来很普通,我想知道我应该如何安排文件引用?我阅读了 Nuspec 替换令牌中的说明,在文件中我有一个部分告诉:.nuspec.nuspec

<files>
  <file src="bin/$configuration$/$id$.pdb" target="lib/netstandard20" />
  <file src="bin/$configuration$/$id$.dll" target="lib/netstandard20" />
  <file src="runtimes/win-x64/native/.exe" target="runtimes/win-x64/native/.exe" />
  <file src="runtimes/win-x64/native/.dll" target="runtimes/win-x64/native/.dll" />
</files>

但是本机文件不会被包含。当我尝试设置一个相对路径时也是如此(我仍然可能有这个错误,可能只是睡了一会儿,然后再试一次)。..\

3. 我是否应该包含某种文件,然后将包装器和本机资源正确地包含给使用 Nuget 库的人?应对其进行设置,以便包含所有本机资源的两个文件,并设置它们与其他生成项目一起复制到项目输出。.props

4. 我应该做一些特别的安排吗?或者也许更好的问题是,我应该注意一些强有力的实践吗?我看到有问题和答案,例如 https://github.com/aspnet/websdk/issues/204#issuecomment-302482115。或者实际上,自动将本机 dll 复制到 Visual Studio 中引用项目的 bin 文件夹,自动从 Nuget 包中提取本机和托管 DLL。 我应该在我只设置:Project.csprojProject.csproj

<PropertyGroup>
  <RuntimeIdentifiers>win-x64;osx.10-11-x64;ubuntu.16.04-x64;debian.8-x64</RuntimeIdentifiers>
  <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>

编辑:哎呀!我正在尝试通过 创建包,它不使用该文件。也许一个好方法是使用 Nuget 元数据工具,如 .NET Core 的 csproj 格式的添加中所述。dotnet pack .\Project\Project.csproj.nuspec

编辑2:似乎试图通过打包存在一些问题,更多的是 https://github.com/NuGet/Home/issues/2372.csproj

编辑3:在 VS 2017 中,选项卡似乎是添加详细信息的最佳方式。然后需要修改,比如Package.csproj

<PropertyGroup>
  <TargetFramework>netstandard2.0</TargetFramework>
  <RuntimeIdentifiers>win-x64;debian-x64</RuntimeIdentifiers>
</PropertyGroup>

<ItemGroup>
  <Content Include="lib\runtimes\win-x64\native\.exe">
    <PackagePath>lib/runtimes/win-x64/native/.exe</PackagePath>
    <Pack>true</Pack>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

本机资源包含在 NuGet 包中,但未正确还原。

编辑4:其他人也有类似的问题。更多链接和理由见 https://github.com/NuGet/Home/issues/6645

编辑5:使用上述结构,最后需要添加的文件是lib

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Content Include="$(MSBuildThisFileDirectory)../../lib/runtimes/win-x64/native/.exe">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>.exe</Link>
      <Visible>false</Visible>
    </Content>
  </ItemGroup>
</Project>

然后到里面添加Project.csprojItemGroup

<Content Include="lib/{your_libraryname}.targets">
  <PackagePath>build/netstandard2.0/</PackagePath>
  <Pack>true</Pack>
</Content>

有了这些,这看起来就像是解决了。

. nuget .net-standard

评论

0赞 Jerahmeel 3/21/2018
感谢您发布更新。我正在尝试完成同样的事情(我正在尝试通过nuget分发带有C#绑定的rust二进制文件)。您的项目是否可公开查看?否则,我将尝试关注您的更新。谢谢!
0赞 Patrick Stalph 1/25/2019
哇,这是一条漫长的路。我会尽量按照你的步骤......明天!

答: 暂无答案