CPack NuGet 包

CPack NuGet Packages

上下文

我有一个托管 C++/CLR 库,它是使用 CMake 3.17 构建的,并使用 CPack 打包到 NuGet 包中。生成的 nupkg 文件无法导入到 C# 项目中,因为包管理器发出以下错误:“[snip] 包不包含任何程序集引用或与 [.NETFramework,Version=v4.5.2] 兼容的内容文件”。但是,在添加到解决方案时添加对项目的引用,或通过构建生成的相应库文件,都可以按预期工作。

C++/CLR 详细信息

代码本身非常基础,并生成一个有效的库,可以从另一个项目中引用,当通过 Visual Studio 2017 -> 添加引用手动添加引用时(项目或相应的库可以是以这种方式添加,它的工作原理都是一样的)。

代码由class本身组成,AssemblyInfo.cpp提供仅描述元数据和版本信息的属性。依赖项仅包括系统、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 "")

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

install (TARGET ManagedLibrary DESTINATION . COMPONENT MixedCLR)

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

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

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

问题

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

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

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

How does NuGet know what libraries to add a reference to?

主要是 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,但不需要指定任何其他文件或属性。

Finally, if anyone knows anything about packaging and multi-targeting in C++/CLR to support different framework versions / architectures / build configurations, any notes on that would be highly appreciated.

如果以多个框架版本为目标,只需创建多个目标并将其安装到相应的文件夹中即可,没有比这更复杂的事情了。

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

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

我希望这对以后的人有所帮助。