CPack NuGet 包

blo*_*dev 5 c# clr cmake nuget cpack

语境

我有一个托管 C++/CLR 库,它是使用 CMake 3.17 构建的,并使用 CPack 打包到 NuGet 包中。生成的 nupkg 文件无法导入到 C# 项目中,因为包管理器会发出以下错误:“[snip] 包不包含与 [.NETFramework,Version=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 使用包含的源文件构建托管 C++ 库,并在相应的目标上设置以下属性ManagedLibrary

set_target_properties (ManagedLibrary PROPERTIES DOTNET_TARGET_FRAMEWORK_VERSION "v4.5.2")
set_target_properties (ManagedLibrary PROPERTIES COMMON_LANGUAGE_RUNTIME "")
Run Code Online (Sandbox Code Playgroud)

文档指出,这将生成 CLR/混合代码并按照宣传的那样工作,因此我能够成功地针对目标框架进行构建。下一步是将库安装在我认为正确的位置:

install (TARGET ManagedLibrary DESTINATION . COMPONENT MixedCLR)
Run Code Online (Sandbox Code Playgroud)

支持(本机 C++)库的安装方式类似:

install (FILES [various..] DESTINATION . COMPONENT MixedCLR)
Run Code Online (Sandbox Code Playgroud)

我还将 CPACK_GENERATOR 设置为“NuGet”,然后从 CLI 运行 PACKAGE 步骤,使用cmake --build . --target PACKAGE该步骤成功生成 n​​upkg 文件。

问题

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

  1. 是否需要 nuspec 文件?如果是这样,其中至少必须包含哪些内容,以及如何将其包含在目标 CMakeLists.txt 中?
  2. 将托管库与支持本机库一起放在包的根目录中是否可以接受?如果没有,他们应该去哪里?
  3. nupkg 文件中通常还包含其他文件吗?

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

blo*_*dev 3

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

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?
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

他们去?

正如已经讨论过的,托管库进入libs/blah. 另一方面,本机库位于运行时 IDruntimes/<RID>/native所在的位置。RID就我而言,我希望以 Windows 64 位为目标,因此运行时 ID 为win-x64.

Are any other files generally included in a nupkg file?
Run Code Online (Sandbox Code Playgroud)

为了方便起见,我捆绑了 PDB,但不需要指定任何其他文件或属性。

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

如果针对多个框架版本,只需创建多个目标并将其安装到相应的文件夹中,没有什么更复杂的处理方法了。

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

lib/
  net452/
    ManagedLib.dll
    ManagedLib.pdb
runtimes/
  win-x64/
    native/
      NativeLib1.dll
      NativeLib2.dll
      ...
Run Code Online (Sandbox Code Playgroud)

我希望这对将来的人有帮助。