HowTo: создание двоичного SDK(набора библиотек) для Windows с использованием vcpkg

HowTo: создание двоичного SDK (набора библиотек) для Windows с использованием vcpkg.

В этом HowTo мы рассмотрим подготовку пакетов vcpkg для использования в двоичном виде.

В качестве «подопытных кроликов» будету выступать Qt6, QCustomPlot и я.

Spoiler: с QCustomPlot придется немного пострадать, но обычно все проще.

TLDR: vcpkg export

Предварительные требования:

Для создания набора библиотек потребуются установленные:

  • Git For Windows

  • CMake

  • Visual Studio с установленным набором для разработки на C++

Вся работа будет происходить в Git Bash(можно и в другом терминале: cmd, powershell, etc)

CMake и Git для удобства лучше установить в директории с короткими именами и добавить в PATH

В примерах для этого будут использованы директории /d/tools/{cmake,git,vcpkg}

Открываем терминал и переходим в базовую директорию

cd /d/tools

Установка vcpkg

Установка состоит в клонировании репозитория с «рецептами» пакетов

git clone https://github.com/microsoft/vcpkg.git
cd vcpkg

Посмотрим список релизных версий

git show-ref

21816e0df975ab3ba13ab75263c4deeb080ef681 refs/heads/master
21816e0df975ab3ba13ab75263c4deeb080ef681 refs/remotes/origin/HEAD
21816e0df975ab3ba13ab75263c4deeb080ef681 refs/remotes/origin/master
e2049cb9754006b6a2abed781d34030e16702fad refs/tags/2019.06
455223d009fc6fef0d9293e511d64e9e372abdb0 refs/tags/2019.07

...

b322364f06308bdd24823f9d8f03fe0cc86fd46f refs/tags/2024.12.16
6f29f12e82a8293156836ad81cc9bf5af41fe836 refs/tags/2025.01.13
d5ec528843d29e3a52d745a64b469f810b2cedbf refs/tags/2025.02.14
b02e341c927f16d991edbd915d8ea43eac52096c refs/tags/2025.03.19

Указанные в нем хеши коммитов потребуются для использования версионирования.
Сейчас это не рассматриваем и переключаемся на последний релиз:

git checkout 2025.03.19
Note: switching to '2025.03.19'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c 

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at b02e341c92 [imgui] update to 1.91.9 (#44425)

Загрузим сам vcpkg

./bootstrap-vcpkg.bat -disableMetrics

Ключ -disableMetrics отключает отправку телеметрии.
Если Вам нужно отравлять телеметрию в Microsoft — удалите из команды.

Настройка переменных окружения

Для сборки пакетов нужно указать «триплеты» для целевой и хостовой системы.
Иначе будут использованы настройки «по умолчанию».
Для Windows это сборка 32хбитных вариантов библиотек и утилит.

Будем собирать для и на Windows x64 поэтому установим x64-windows

export VCPKG_DEFAULT_TRIPLET=x64-windows
export VCPKG_DEFAULT_HOST_TRIPLET=x64-windows
export VCPKG_ROOT=d:/tools/vcpkg # необязательно

Для упрощения дальнейшей работы можно сохранить их в настройках системы.

Установка набора библиотек

Идем на https://vcpkg.io/en/packages и ищем названия пакетов
Для QCustomPlot без неожиданностей — qcustomplot

Можно так же воспользоваться встроенным поиском:

./vcpkg search qcustomplot
qcustomplot              2.1.1#1          QCustomPlot is a Qt C++ widget for plotting and data visualization.
The result may be outdated. Run `git pull` to get the latest results.
If your port is not listed, please open an issue at and/or consider making a pull request.  -  https://github.com/Microsoft/vcpkg/issues

Собственно установка:

./vcpkg install qcustomplot

vcpkg скачает и скомпилирует все необходимые зависимости.
Это может занять прилично времени — можно сходить попить кофе.

У меня установка заняла полчаса.

Starting submission of qcustomplot:x64-windows@2.1.1#1 to 1 binary cache(s) in the background
Elapsed time to handle qcustomplot:x64-windows: 30 s
qcustomplot:x64-windows package ABI: 51d7df0801247592f000a45e1136824367618965ada4458385f5fd3a0a036152
Total install time: 29 min
Completed submission of qtbase[brotli,concurrent,core,dbus,dnslookup,doubleconversion,freetype,gui,harfbuzz,icu,jpeg,network,opengl,openssl,pcre2,png,sql,sql-ps
ql,sql-sqlite,testlib,thread,widgets,zstd]:x64-windows@6.8.2#1 to 1 binary cache(s) in 27 s
Waiting for 2 remaining binary cache submissions...
Completed submission of vcpkg-qmake:x64-windows@2023-03-22#3 to 1 binary cache(s) in 11 s (1/2)
Completed submission of qcustomplot:x64-windows@2.1.1#1 to 1 binary cache(s) in 13 s (2/2)

real    29m1.567s
user    0m0.015s
sys     0m0.000s

Сборка двоичного пакета

Тут есть несколько вариантов

  • создать директорию

  • упаковать в архив

  • создать пакеты для NuGet (удобно для VS. Наверно)

Просто скопируем все в директорию /d/tools/bin-pkgs:

./vcpkg export --raw --output=../bin-pkgs --x-all-installed

Результат можно запаковать и использовать на другом ПК.

Использование двоичного пакета в CMake

Подобрались к тому, ради чего всё это было.

Создадим простой проект

mkdir ../pkg-test
cd ../pkg-test
touch main.cpp
touch CMakeLists.txt

В любом текстовом редакторе набросаем код

///@file: main.cpp
#include 
#include 

int main(int argc, char** argv)
{
	QApplication app{argc, argv};
	QCustomPlot plot;
	
	plot.show();
	
	return app.exec();
}
# @file: CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(pkg-test)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)


set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt6 COMPONENTS Core Widgets REQUIRED)
find_package(QCustomPlot REQUIRED)


add_executable(pkg_test WIN32)

target_sources(pkg_test
	PRIVATE
		main.cpp
)

target_link_libraries(pkg_test
    PRIVATE
        Qt::Core Qt::Widgets
        qcustomplot
)

Конфигурация

Для использования пакетов нужно установить переменную CMAKE_TOOLCHAIN_FILE

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=../bin-pkgs/scripts/buildsystems/vcpkg.cmake

-- Selecting Windows SDK version 10.0.26100.0 to target Windows 10.0.19045.
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - not found
-- Found Threads: TRUE
-- Performing Test HAVE_STDATOMIC
-- Performing Test HAVE_STDATOMIC - Success
-- Found WrapAtomic: TRUE
CMake Error at D:/tools/bin-pkgs/scripts/buildsystems/vcpkg.cmake:893 (_find_package):
  By not providing "FindQCustomPlot.cmake" in CMAKE_MODULE_PATH this project
  has asked CMake to find a package configuration file provided by
  "QCustomPlot", but CMake did not find one.

  Could not find a package configuration file provided by "QCustomPlot" with
  any of the following names:

    QCustomPlotConfig.cmake
    qcustomplot-config.cmake

  Add the installation prefix of "QCustomPlot" to CMAKE_PREFIX_PATH or set
  "QCustomPlot_DIR" to a directory containing one of the above files.  If
  "QCustomPlot" provides a separate development package or SDK, be sure it
  has been installed.
Call Stack (most recent call first):
  CMakeLists.txt:15 (find_package)


-- Configuring incomplete, errors occurred!

Хм. Ошибка — QCustomPlot не найден.

Обычно всё проще.

К сожалению, не все пакеты предоставляют конфиги для CMake.
Поэтому приходится писать их самостоятельно.
Либо подставлять костыли. Что и сделаем.

Немного изменим файл проекта:

- find_package(QCustomPlot REQUIRED)
+ #find_package(QCustomPlot REQUIRED)

И переконфигурируем

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=../bin-pkgs/scripts/buildsystems/vcpkg.cmake
-- Selecting Windows SDK version 10.0.26100.0 to target Windows 10.0.19045.
-- Configuring done (0.2s)
-- Generating done (0.3s)
-- Build files have been written to: D:/tools/pkg-test/build

Успешно.

В директории build создались скрипты для компиляции и проект для Visual Studio:

ls -l build/
total 324
-rw-r--r-- 1 maxim 197121 73424 Mar 25 17:00 ALL_BUILD.vcxproj
-rw-r--r-- 1 maxim 197121   272 Mar 25 16:34 ALL_BUILD.vcxproj.filters
-rw-r--r-- 1 maxim 197121   168 Mar 25 17:30 ALL_BUILD.vcxproj.user
-rw-r--r-- 1 maxim 197121 54604 Mar 25 16:34 CMakeCache.txt
drwxr-xr-x 1 maxim 197121     0 Mar 25 17:34 CMakeFiles/
drwxr-xr-x 1 maxim 197121     0 Mar 25 17:34 Debug/
-rw-r--r-- 1 maxim 197121 73544 Mar 25 17:00 ZERO_CHECK.vcxproj
-rw-r--r-- 1 maxim 197121   515 Mar 25 16:34 ZERO_CHECK.vcxproj.filters
-rw-r--r-- 1 maxim 197121  1729 Mar 25 16:34 cmake_install.cmake
-rw-r--r-- 1 maxim 197121  3116 Mar 25 16:34 pkg-test.sln
drwxr-xr-x 1 maxim 197121     0 Mar 25 16:37 pkg_test.dir/
-rw-r--r-- 1 maxim 197121 99062 Mar 25 17:20 pkg_test.vcxproj
-rw-r--r-- 1 maxim 197121  1163 Mar 25 16:34 pkg_test.vcxproj.filters
-rw-r--r-- 1 maxim 197121   168 Mar 25 17:30 pkg_test.vcxproj.user
drwxr-xr-x 1 maxim 197121     0 Mar 25 16:37 pkg_test_autogen/
drwxr-xr-x 1 maxim 197121     0 Mar 25 16:37 x64/

Компиляция

Компиляция запускается стандартно для проекта для CMake:

cmake --build build
Версия MSBuild 17.13.19+0d9f5a35a для .NET Framework

  1>Checking Build System
  Automatic MOC and UIC for target pkg_test
  Building Custom Rule D:/tools/pkg-test/CMakeLists.txt
  mocs_compilation_Debug.cpp
  main.cpp
  Generating Code...
D:\tools\pkg-test\main.cpp(4,10): error C1083: Cannot open include file: 'qcustomplot.h': No such file or directory [D:\tools\pkg-test\build\pkg_test.vcxproj]

И натыкаемся на очередную проблему с конфигурацией: путь к include не прописан.

Что ж. Попробуем исправить.
Заголовочные файлы находятся по пути /installed//include

Нужно как то определить в какой директории находятся пакеты.
Для этого будем использовать переменную VCPKG_INSTALLED_DIR:

Добавим в проект путь до заголовочных файлов:

include_directories("${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include")

Конфигурируем/компилируем

cmake --build build
Версия MSBuild 17.13.19+0d9f5a35a для .NET Framework

  Automatic MOC and UIC for target pkg_test
  mocs_compilation_Debug.cpp
  main.cpp
  Generating Code...
LINK : fatal error LNK1104: cannot open file 'qcustomplot.lib' [D:\tools\pkg-test\build\pkg_test.vcxproj]

Да что ж такое.
Нужно будет завести issue на QCustomPlot и по возможности pull request с патчем.
А пока захардкодим:

include_directories("${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib")

Конфигурируем/компилируем…

$ cmake --build build
Версия MSBuild 17.13.19+0d9f5a35a для .NET Framework

  Automatic MOC and UIC for target pkg_test
  pkg_test.vcxproj ->; D:\tools\pkg-test\build\Debug\pkg_test.exe
  Building Custom Rule D:/tools/pkg-test/CMakeLists.txt

Успех.

Конечный вариант файла проекта:

# @file: CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(pkg-test)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

# FIXME: dirty fix for QCustomPlot
include_directories("${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include")
link_directories("${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib")

find_package(Qt6 COMPONENTS Core Widgets REQUIRED)

add_executable(pkg_test WIN32)

target_sources(pkg_test
	PRIVATE
		main.cpp
)

target_link_libraries(pkg_test
    PRIVATE
        Qt::Core Qt::Widgets
        qcustomplot2
)

Что осталось «за кадром»

Не решен вопрос о запуске/отладке.
Но это видимо проблема именно пакета QCustomPlot — с другими возни меньше.

«Фото на память»

98b5ca62aea54f8db61defdf15a2b71f.png

© Habrahabr.ru