CPack NuGet软件包

5

背景

我有一个使用CMake 3.17构建的Managed C++/CLR库,并使用CPack打包成NuGet包。生成的nupkg文件无法导入到C#项目中,因为包管理器会出现以下错误:"[snip]该包不包含与[.NET Framework,版本=v4.5.2]兼容的任何程序集引用或内容文件。"但是,将其添加到解决方案时,可以引用项目或生成的对应库文件。

C++/CLR详细信息

代码本身非常基础,可以产生有效的库文件,在手动通过Visual Studio 2017 -> 添加引用(可以通过项目或相应的库来添加),可以从另一个项目引用。

代码包括类本身,AssemblyInfo.cpp提供了描述元数据和版本信息的属性。依赖项只包括System、System::Runtime::InteropServices和一系列预先构建的本机库。

我没有添加.nuspec文件或nuget.config文件,后者我认为是由CPack NuGet生成器在构建包时生成的。

CMake / CPack详细信息

CPack NuGet支持相对较新,我一直没有找到可行的示例,但我已成功生成了一个nupkg文件。首先,CMake被指示使用包含的源文件构建一个带有以下属性的Managed C++库,并设置到对应目标ManagedLibrary:

set_target_properties (ManagedLibrary PROPERTIES DOTNET_TARGET_FRAMEWORK_VERSION "v4.5.2")
set_target_properties (ManagedLibrary PROPERTIES COMMON_LANGUAGE_RUNTIME "")

文档说明此操作将生成CLR/Mixed代码,并且效果与宣传一致,因此我可以成功地构建目标框架。下一步是将库安装在我认为是正确的位置:
install (TARGET ManagedLibrary DESTINATION . COMPONENT MixedCLR)

并且支持本地 C++ 库的安装方法也类似:

install (FILES [various..] DESTINATION . COMPONENT MixedCLR)

我还将CPACK_GENERATOR设置为'NuGet',并使用cmake --build . --target PACKAGE从CLI运行PACKAGE步骤,成功生成了nupkg文件。

问题

NuGet如何知道要添加哪些库的引用?

  1. 是否需要nuspec文件?如果需要,最少需要包含什么内容,并如何在目标CMakeLists.txt中包含它?
  2. 将托管库与支持的本机库放在包的根目录下是否可接受?如果不行,应该放在哪里?
  3. 通常在nupkg文件中还包括哪些其他文件?

最后,如果有人了解如何打包和多目标定位C++/CLR以支持不同的框架版本/体系结构/构建配置,任何相关说明都将受到高度赞赏。


3
https://github.com/Mizux/dotnet-native? - Mizux
1
这是一个非常受欢迎的链接,我特别感谢详细文档的包含。我会仔细研究一段时间并回报。 - blockchaindev
1个回答

3
NuGet如何知道要添加引用的库?
主要是通过包结构来推断要引用的库。托管程序集必须放在一个目录中,该目录为 libs / <TFWM> ,其中 TFWM 是目标框架标识符(例如:.NET Framework 4.5.2 => net452)。
Is a nuspec file required? If so, what must minimally be included in it, and how do I include it in the target CMakeLists.txt?
nuspec文件是由CPack在生成软件包时自动生成的。生成的文件将保存到输出目录,并保留由install命令指定的目录结构。
Is it acceptable to put the managed library, along with supporting native libraries, in the root of the package? If not, where should

they go?

如已讨论,托管库放在 libs/blah 中。另一方面,本地库放在 runtimes/<RID>/native 中,其中 RID 是运行时 ID。在我的情况下,我想要针对 Windows 64 位,所以运行时 ID 是 win-x64

Are any other files generally included in a nupkg file?

我为了方便打包PDB,但我不需要指定任何其他文件或属性。

最后,如果有人对C++/CLR中的打包和多目标支持不同版本框架/架构/构建配置有了解,任何相关注释都将不胜感激。

如果针对多个框架版本,只需创建并安装到各自的文件夹中即可,没有更复杂的处理。

最后,我的完成包结构如下:

lib/
  net452/
    ManagedLib.dll
    ManagedLib.pdb
runtimes/
  win-x64/
    native/
      NativeLib1.dll
      NativeLib2.dll
      ...

希望这能帮助到未来的某个人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接