CMake和MsVS-NuGet

时间:2013-08-08 10:32:11

标签: c++ visual-studio-2012 cmake nuget-package

我目前正在开发一个桌面应用程序,使用C ++ REST SDK(代号Casablanca),Qt5和其他一些库。

对于项目设置,我使用CMake。

如何让CMake安装NuGet包?

我现在必须每次手动安装它,如果我重新运行CMake,这不是一个真正的选择。

3 个答案:

答案 0 :(得分:20)

NuGet的命令行参考位于http://docs.nuget.org/docs/reference/command-line-reference

您可以使用nuget installnuget restore命令安装软件包。 nuget update更新已安装的软件包(restore必须运行beforhand)。

您可以使用以下命令指示cmake在每次构建之前运行NuGet:

add_custom_command(TARGET ${PROJECT_NAME}
    PRE_BUILD
    COMMAND nuget restore ${CMAKE_BINARY_DIR}\yourSolution.sln
)

或在配置时使用execute_process

您可以使用configure_file准备nuget配置文件,也可以直接使用相应的nuget install命令。

答案 1 :(得分:1)

对于@Markus Mayer的出色回答表示由衷的感谢。我同意了这个建议,但是发现如果从头开始生成VS项目/解决方案文件,则使用nuget命令行不会起作用。具体来说,nuget命令行不会更新项目文件(.csproj),似乎需要一些手动操作才能告诉您的项目在哪里可以找到已安装的依赖项。以下步骤概述了我如何为一个具有Nuget包依赖项的简单项目解决此问题:

  1. 在Visual Studio中使用Nuget软件包管理器安装了Nuget软件包依赖项。
  2. 复制了生成的packages.config文件(在与受影响的.csproj文件相同的目录中生成)。将副本放入源目录,并将其重命名为packages.config.in。现在,我们可以告诉CMake在configure_file的配置阶段将此文件复制回CMake二进制目录。如果缺少依赖项,Nuget将使用它来安装/恢复依赖项。
  3. 记下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>
  1. 卸载了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 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()
# 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"
)

答案 2 :(得分:0)

根据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)