Подтвердить что ты не робот

CMake и MsVS-NuGet

В настоящее время я разрабатываю настольное приложение, используя С++ REST SDK (кодовое имя Casablanca), Qt5 и некоторые другие библиотеки.

Для настройки проекта я использую CMake.

Как получить CMake для установки пакетов NuGet?

Теперь я должен установить его каждый раз вручную, если я перезапущу CMake, что на самом деле не вариант.

4b9b3361

Ответ 1

Ссылка на командную строку NuGet находится в http://docs.nuget.org/docs/reference/command-line-reference

Вы можете установить пакеты с помощью команды nuget install или nuget 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.

Вы можете подготовить конфигурационный файл nuget с помощью configure_file или использовать соответствующие команды nuget install.

Ответ 2

Слава @Markus Mayer за отличный ответ. Я побежал с предложением, но обнаружил, что с помощью nuget командной строки не выполняется, если вы генерируете файлы проекта/решения VS с нуля. В частности, nuget командная строка не обновляет файлы проект (.csproj), а некоторое ручное усилие представляется необходимым сказать, ваш проекту, где найти установленную зависимость. Следующие шаги описывают, как я работал с этим для простого проекта с одной зависимостью пакета Nuget:

  1. Установил зависимость пакета Nuget с помощью диспетчера пакетов Nuget в Visual Studio.
  2. Скопировал сгенерированный файл packages.config (сгенерированный в том же каталоге, что и затронутый файл .csproj). Поместил копию в исходный каталог и переименовал ее в packages.config.in. Теперь мы можем сказать CMake скопировать этот файл обратно в двоичный каталог CMake на этапе configure_file с помощью configure_file. Nuget будет использовать его для установки/восстановления зависимостей, если они отсутствуют.
  3. Обратите внимание, где Nuget установил DLL для этого пакета. На моей машине это было в двоичном каталоге CMake в каталоге packages.

Мы можем использовать этот путь, чтобы сообщить 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)

Хотя теперь это также предоставит пути к пакетам для проекта VS для новых сборок CMake, есть одно предупреждение. Если вы хотите обновить версию используемого вами установленного пакета Nuget, вам придется повторить вышеупомянутые шаги вручную.

TL; DR: вот полный файл CMakeLists.txt который я опробовал на установленном Nuget SQLite:

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"
)