编辑:从 CMake 3.15 开始,CMake 支持使用 VS_PACKAGE_REFERENCES 引用 Nuget 包。现在,这是一个更比下面之前提出的解决方法更清洁的解决方案。要将 Nuget 包引用添加到 CMake 目标,请使用包名称和包版本,并用 _ 下划线分隔。这是BouncyCastle 版本1.8.5 的示例:
set_property(TARGET MyApplication
PROPERTY VS_PACKAGE_REFERENCES "BouncyCastle_1.8.5"
)
documentation 展示了如何通过用分号分隔 ; 包来添加多个 Nuget 包。
对于早于 3.15 的 CMake 版本,这是一种潜在的解决方法:
感谢@Markus Mayer 的出色回答。我接受了这个建议,但发现如果您要从头开始生成 VS 项目/解决方案文件,则使用 nuget 命令行并不能成立。。具体来说,nuget 命令行不会更新项目文件 (.csproj),并且似乎需要一些手动操作来告诉您的项目在哪里可以找到已安装的依赖项。以下步骤概述了我如何针对一个具有一个 Nuget 包依赖项的简单项目解决此问题:
- 在 Visual Studio 中使用 Nuget 包管理器安装了 Nuget 包依赖项。
- 复制了生成的
packages.config 文件(与受影响的.csproj 文件在同一目录中生成)。将副本放入源目录,并将其重命名为packages.config.in。现在,我们可以使用configure_file 告诉 CMake 在配置阶段将此文件复制回 CMake 二进制目录。如果缺少依赖项,Nuget 将使用它来安装/恢复依赖项。
- 记下 Nuget 为该软件包安装 DLL 的位置。在我的机器上,它位于
packages 目录中的 CMake 二进制目录中。
我们可以使用这个路径告诉 CMake 我们的参考包的位置:
set_property(TARGET MyApplication PROPERTY VS_DOTNET_REFERENCE_MyReferenceLib
${CMAKE_BINARY_DIR}/packages/path/to/lib/MyReferenceLib.dll)
我们还可以在.csproj 文件中查看此依赖项的安装位置,以验证我们获得了正确的路径(请参阅HintPath),并且没有遗漏任何其他依赖项:
<Reference Include="MyReferenceLib, Version=2.5.0, Culture=neutral, PublicKeyToken=1234567891234567, processorArchitecture=MSIL">
<HintPath>packages\path\to\lib\MyReferenceLib.dll</HintPath>
</Reference>
- 卸载了 Nuget 包,因为现在我们拥有了让 CMake 完成所有繁重工作所需的所有信息。
综合起来,CMake 命令如下所示:
# Find Nuget (install the latest CLI here: https://www.nuget.org/downloads).
find_program(NUGET nuget)
if(NOT NUGET)
message(FATAL "CMake could not find the nuget command line tool. Please install it!")
else()
# Copy the Nuget config file from source location to the CMake build directory.
configure_file(packages.config.in packages.config COPYONLY)
# Run Nuget using the .config file to install any missing dependencies to the build directory.
execute_process(COMMAND
${NUGET} restore packages.config -SolutionDirectory ${CMAKE_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endif()
# Provide the path to the Nuget-installed references, in case this is a fresh project build.
set_property(TARGET MyApplication PROPERTY
VS_DOTNET_REFERENCE_MyReferenceLib
${CMAKE_BINARY_DIR}/packages/path/to/lib/MyReferenceLib.dll)
虽然这现在还将为新的 CMake 构建提供 VS 项目的包路径,但有一个警告。如果要升级正在使用的 Nuget 安装包的版本,则必须重新执行上述手动步骤。
TL;DR:这是我使用 Nuget 安装的 SQLite 试用的完整 CMakeLists.txt 文件:
cmake_minimum_required(VERSION 3.8)
# Project name
project(MyProject LANGUAGES CSharp)
# Include CMake utilities for CSharp, for WinForm and WPF application support.
include(CSharpUtilities)
set(MyProject_SOURCES
Form1.cs
Form1.Designer.cs
Form1.resx
Program.cs
Properties/AssemblyInfo.cs
Properties/Resources.Designer.cs
Properties/Resources.resx
Properties/Settings.Designer.cs
Properties/Settings.settings
)
# Define the executable, including any .cs files.
# The .resx and other Properties files are optional here, but including them makes them visible in the VS solution for easy editing.
add_executable(MyWinFormApp ${MyProject_SOURCES})
# Set the source file properties for Windows Forms use.
csharp_set_windows_forms_properties(${MyProject_SOURCES})
# Find Nuget (install the latest CLI here: https://www.nuget.org/downloads).
find_program(NUGET nuget)
if(NOT NUGET)
message(FATAL "CMake could not find the nuget command line tool. Please install it!")
else()
# Copy the Nuget config file from source location to the CMake build directory.
configure_file(packages.config.in packages.config COPYONLY)
# Run Nuget using the .config file to installing any missing dependencies to the build directory.
execute_process(COMMAND
${NUGET} restore packages.config -SolutionDirectory ${CMAKE_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endif()
# Set the .NET Framework version for the executable.
set_property(TARGET MyWinFormApp PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
# Provide the path to the Nuget-installed references, in case this is a fresh project build.
set_property(TARGET MyWinFormApp PROPERTY
VS_DOTNET_REFERENCE_EntityFramework
${CMAKE_BINARY_DIR}/packages/EntityFramework.6.2.0/lib/net45/EntityFramework.dll)
set_property(TARGET MyWinFormApp PROPERTY
VS_DOTNET_REFERENCE_EntityFramework.SqlServer
${CMAKE_BINARY_DIR}/packages/EntityFramework.6.2.0/lib/net45/EntityFramework.SqlServer.dll)
set_property(TARGET MyWinFormApp PROPERTY
VS_DOTNET_REFERENCE_System.Data.SQLite
${CMAKE_BINARY_DIR}/packages/System.Data.SQLite.Core.1.0.110.0/lib/net46/System.Data.SQLite.dll)
set_property(TARGET MyWinFormApp PROPERTY
VS_DOTNET_REFERENCE_System.Data.SQLite.EF6
${CMAKE_BINARY_DIR}/packages/System.Data.SQLite.EF6.1.0.110.0/lib/net46/System.Data.SQLite.EF6.dll)
set_property(TARGET MyWinFormApp PROPERTY
VS_DOTNET_REFERENCE_System.Data.SQLite.Linq
${CMAKE_BINARY_DIR}/packages/System.Data.SQLite.Linq.1.0.110.0/lib/net46/System.Data.SQLite.Linq.dll)
# Add in the .NET reference libraries.
set_property(TARGET MyWinFormApp PROPERTY VS_DOTNET_REFERENCES
"System"
"System.Core"
"System.Data"
"System.Windows.Forms"
)