CMake and MsVS-NuGet
CMake and MsVS-NuGet
我目前正在开发一个桌面应用程序,使用C++REST SDK(代号Casablanca)、Qt5和其他一些库。
对于项目设置,我使用CMake。
如何让CMake安装NuGet软件包?
如果我重新运行CMake,我现在每次都必须手动安装它,这不是一个真正的选项。
EDIT:这个答案不适用于C++项目。
EDIT:自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"
)
该文档展示了如何通过分号分隔;
来添加多个Nuget包。
对于3.15之前的CMake版本,这里有一个潜在的解决方案:
感谢@Markus Mayer的出色回答。我运行了这个建议,但发现如果您从头开始生成VS项目/解决方案文件,那么使用nuget
命令行是行不通的。具体来说,nuget
命令行不会更新项目文件(.csproj
),并且似乎需要一些手动操作来告诉您的项目在哪里可以找到已安装的依赖项。以下步骤概述了我如何为一个简单的项目解决这个问题,该项目有一个Nuget包依赖项:
- 在Visual Studio中使用Nuget包管理器安装了Nuget包依赖项
- 复制生成的
packages.config
文件(与受影响的.csproj
文件在同一目录中生成)。将副本放入源目录,并将其重命名为packages.config.in
。现在,我们可以告诉CMake在配置阶段使用configure_file
将此文件复制回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>packagespathtolibMyReferenceLib.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"
)
NuGet的命令行引用位于http://docs.nuget.org/docs/reference/command-line-reference
您可以使用nuget install
或nuget restore
命令安装软件包。nuget update
更新已安装的程序包(必须先运行restore
)。
您可以使用以下命令指示cmake在每次构建之前运行NuGet:
add_custom_command(TARGET ${PROJECT_NAME}
PRE_BUILD
COMMAND nuget restore ${CMAKE_BINARY_DIR}yourSolution.sln
)
或者在配置时使用CCD_ 21。
您可以使用configure_file
或直接使用适当的nuget install
命令来准备nuget配置文件。
根据https://github.com/clarkezone/flutter_win_webview/commit/ce603ec8c96bed50e4443c49a150ce4d3d352896
find_program(NUGET_EXE NAMES nuget)
exec_program(${NUGET_EXE}
ARGS install "Microsoft.Web.WebView2" -Version 0.9.579 -ExcludeVersion -OutputDirectory ${CMAKE_BINARY_DIR}/packages)
target_link_libraries(${PLUGIN_NAME} PRIVATE ${CMAKE_BINARY_DIR}/packages/Microsoft.Web.WebView2/build/native/Microsoft.Web.WebView2.targets)
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- OpenSSL BIO and SSL_read
- Gurobi GRBModel and GRBmodel in C++
- std::multimap<std::chrono::milliseconds, T>::rbegin 在 MSVS-13 中指向 end()?
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- different between int **arr =new int [ n]; and int a[i][j]?
- 使用 NuGet 填充 Visual Studio 2019 中的 CMake 依赖项
- C++ getenv and setenv
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- Inference pytorch C++ with alexnet and cv::imread image
- Visual Studio 2019 C++ and std::filesystem
- 保证逻辑 AND 表达式中的函数调用
- CMake and MsVS-NuGet