Четверг, 19.06.2025 19:00

Создаем msi-установщик для нашей программы в Windows с помощью CMAKE

Создаем msi-установщик для нашей программы в Windows с помощью CMAKE

Для установки в Windows можно использовать два типа установщиков. Установщики в виде исполняемого файла - .exe и установщики в формате .msi (Microsoft Software Installer). Главное преимущество msi-установщика – нативная поддержка на уровне операционной системы. 

Сегодня мы рассмотрим создание msi-установщика с помощью WIX (Windows Installer XML) и CMake.

Настройка проекта

Начнем мы с проекта, размещенного в git-репозитории. Мы продолжим настройку проекта из прошлой статьи.

Если папка:

c:\project\colortable_msi

уже существует, переместите или удалите её:

cd c:\projects
rmdir /q/s colortable_msi

Мы будем использовать проект из git-репозитория:

cd c:\projects
rmdir /q/s articles_blog_altuninvv_ru
git clone https://gitflic.ru/project/vasiliyaltunin/articles_blog_altuninvv_ru.git --depth 1

Скопируем папку с проектом:

xcopy /y/e .\articles_blog_altuninvv_ru\qt6\colorconsole_copy_dll\ .\colortable_msi\

Установка .NET SDK

Для запуска WIX нам потребуется .NET SDK!

Со страницы https://dotnet.microsoft.com/en-us/download

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

https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-9.0.305-windows-x64-installer

Или использовать консоль:

cd %userprofile%\Downloads
curl https://builds.dotnet.microsoft.com/dotnet/Sdk/9.0.305/dotnet-sdk-9.0.305-win-x64.exe --output dotnet-sdk-9.0.305-win-x64.exe

Установим:

.\dotnet-sdk-9.0.305-win-x64.exe

Закроем все окна консоли и в новом окне запустим:

dotnet --info
Среда выполнения:
OS Name:     Windows
OS Version:  10.0.19045
OS Platform: Windows
RID:         win-x64
Base Path:   C:\Program Files\dotnet\sdk\9.0.305\
Установленные рабочие нагрузки .NET:
Нет установленных рабочих нагрузок для отображения.
Настроено на использование loose manifests при установке новых манифестов.
Host:
 Version:      9.0.9
 Architecture: x64
 Commit:       893c2ebbd4
.NET SDKs installed:
 9.0.305 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
 Microsoft.AspNetCore.App 9.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
 Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
 Microsoft.NETCore.App 9.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
 Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
 Microsoft.WindowsDesktop.App 9.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
 None
Environment variables:
 Not set
global.json file:
 Not found
Learn more:
 https://aka.ms/dotnet/info
Download .NET:
 https://aka.ms/dotnet/download
Dotnet установлен и готов к работе

Установка WIX                 

Установка WIX осуществляется средствами .NET SDK.

Запустим из обычной консоли, не под правами администратора:

dotnet tool install --global wix 
Так как вы только что установили пакет SDK для .NET, перед его запуском нужно заново открыть окно командной строки.
Вы можете вызвать это средство с помощью следующей команды: wix
Средство "wix" (версии "6.0.2") успешно установлено.

Обязательно закройте все окна консоли, в которых будете работать с WIX, в том числе и окна Far Manager!

Проверим 

wix --version
6.0.2+b3f3403

WIX успешно установлен.

Установка расширений для WIX

Для сборки установщика с использованием WIN нам потребуются дополнительные компоненты для самого WIX давайте их установим:

wix extension add -g WixToolset.UI.wixext

Проверим что все установилось, откроем новое окно консоли и запустим:

wix extension list
WixToolset.UI.wixext 6.0.2

Обязательно также перезапустите VSCode!

Дорабатываем копирование разделяемой библиотеки

Откроем наш проект:

cd C:\projects\colortable_msi
code .

До сих пор мы использовали команду прямого копирования, чтобы скопировать файл libcolorconsole.dll в папку с исполняемым файлом.

Доработаем проект, таким образом, чтобы копирование производилось во время копирования остальных разделяемых библиотек.

Для этого в файле cmake\shared_deps.cmake.in изменим строку:

# Задаем папку, в которой нужно искать разделяемые библиотеки
set(MY_DEPENDENCY_PATHS C:/msys64/mingw64/bin ${CMAKE_CURRENT_BINARY_DIR}/_deps/colorconsole-build)

Здесь 

${CMAKE_CURRENT_BINARY_DIR}/_deps/colorconsole-build

Будет преобразовано в:

C:/projects/colortable_msi/build/_deps/colorconsole-build/

В файле cmake/install.cmake.in удалим блок:

# Копируем разделяемую библиотеку из папки сборки библиотеки в папку сборки нашего проекта
add_custom_command(
      TARGET ${PROJECT_NAME} POST_BUILD
      COMMAND ${CMAKE_COMMAND} -E copy
             ${colorconsole_BINARY_DIR}/libcolorconsole.dll
             ${CMAKE_CURRENT_BINARY_DIR}/libcolorconsole.dll)

Теперь копирование разделяемой библиотеки будет производится командами определенными в файле cmake\shared_deps.cmake.in.

Запустим:

rmdir /q/s .\build
cmake -S . -B build
cmake --build build
cmake --build build --target install
[0/1] Install the project...-- Install configuration: ""
== Searching for shared DLL
== Search completed
== DLL Copying started…
Dependency copied: C:/projects/colorconsole_copy_dll/build/_deps/colorconsole-build/libcolorconsole.dll
Dependency copied: C:/msys64/mingw64/bin/libgcc_s_seh-1.dll
Dependency copied: C:/msys64/mingw64/bin/libstdc++-6.dll
Dependency copied: C:/msys64/mingw64/bin/libwinpthread-1.dll
== DLL Copying finished

Файл был скопирован из папки, в которой собирается наша библиотека!

Проверим:

dir /w .\build\*.dll
 Содержимое папки C:\projects\colorconsole_copy_dll\build
libcolorconsole.dll   libgcc_s_seh-1.dll    libstdc++-6.dll       libwinpthread-1.dll

Файлы с разделяемыми библиотеками присутствуют в папке с исполняемым файлом.

Добавляем поддержку WIX в проект CMake

В CMake уже есть встроенный модуль для работы с WIX, всё что нужно установить настройки и включить его.

В файл cmake\settings.cmake.in добавим:

# Указываем CPACK использовать WIX
set(CPACK_GENERATOR WIX)
# Указываем CPACK должен использовать WIX 4 версии
set(CPACK_WIX_VERSION 4)

В файл conf.cmake.in добавим:

include(CPack)

В файл install.cmake.in добавим:

install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)

Здесь мы просто добавили настройки для WIX, подключили модуль CMake для работы с ним и указали target для установки.

Проверим сборку проекта. Запустим конфигурирование и сборку:

cmake -S . -B build 
cmake --build build

Всё собралось без ошибок

Запустим:

.\build\colorconsoleapp.exe

Программа запустилась без ошибок.

Запуск сборки msi-пакета

Модуль WIX добавляет новый target в наш проект CMake - package.

Запустим:

cmake --build build --target package 
[0/1] Run CPack packaging tool...CPack: Create package using WIX
CPack: Install projects
CPack: - Install project: colorconsoleapp []
== Searching for shared DLL
== Search completed
== DLL Copying started…
Dependency copied: C:/projects/colortable_msi/build/libcolorconsole.dll
Dependency copied: C:/msys64/mingw64/bin/libgcc_s_seh-1.dll
Dependency copied: C:/msys64/mingw64/bin/libstdc++-6.dll
Dependency copied: C:/msys64/mingw64/bin/libwinpthread-1.dll
== DLL Copying finished
CPack: Create package
CPack Warning: CPACK_WIX_UPGRADE_GUID implicitly set to ACCAB579-F454-4389-92B9-9FC61214FF76 . Please refer to the documentation on how and why you might want to set this explicitly.
CPack: - package: C:/projects/colortable_msi/build/colorconsoleapp-0.1-win64.msi generated.

В папке .\build будет создан файл

colorconsoleapp-0.1-win64.msi

Запустим:

.\build\colorconsoleapp-0.1-win64.msi

Будет запущен обычный установщик:

Изображение удалено.Изображение удалено.Изображение удалено.Изображение удалено.Изображение удалено.

Программа будет установлена в папку:

C:\Program Files\colorconsoleapp 0.1\bin

Посмотрим что получилось:

tree /f "C:\Program Files\colorconsoleapp 0.1\bin"
Структура папок
Серийный номер тома: 00000018 2668:2FDC
C:\PROGRAM FILES\COLORCONSOLEAPP 0.1\BIN
    colorconsoleapp.exe

Подпапки отсутствуют

Так как мы не скопировали фалы с разделяемыми библиотеками, то программа не запуститься.

Настройка проекта WIX с помощью CMake

Модуль WIX для CMake предоставляет некоторые опции для управления нашим проектом. Их немного но для создания обычного установочного пакета нам их хватит. Добавим отдельный файл для настроек WIX.

Создадим файл cmake\wix.cmake.in:

type nul > cmake\wix.cmake.in

Добавим к нему содержимое:

# Больше информации о доступных опциях
# https://cmake.org/cmake/help/latest/cpack_gen/wix.html

# Устанавливаем имя
set(CPACK_PACKAGE_NAME "colortable")

# Устанавливаем папку для установки в c:\Program Files
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "AltuninVV-Apps")

# Если раскомментировать эти строки, то установка будет выполнена в 
# папку C:\msys64\mingw64\bin
#SET(CPACK_PACKAGE_INSTALL_DIRECTORY "C:/msys64/mingw64/bin")
#SET(CPACK_WIX_SKIP_PROGRAM_FOLDER TRUE)

# Путь к файлу с лицензией
#set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/cmake/wix/license.rtf)

# Язык установщика 
set(CPACK_WIX_CULTURES "ru-RU")

# Иконка нашей программы
#set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/cmake/wix/icon.png")

# Баннер отображаемый вверху каждой страницы установщика. Обязательные размеры 493x58 px
#set(CPACK_WIX_UI_BANNER "${PROJECT_SOURCE_DIR}/cmake/wix/top_bg.png")

# Баннер отображаемый на странице приветствия и на последней странице установщика. Обязательные размеры 493x312px
#set(CPACK_WIX_UI_DIALOG "${PROJECT_SOURCE_DIR}/cmake/wix/welcome.png")

# Имя папки в меню Пуск
#set(CPACK_WIX_PROGRAM_MENU_FOLDER "AltuninVV Tools")

# Задаем постоянный GUID это важно! В противном случае каждый раз после упаковки
# и последующей установке Windows будет считать разные версии программы разными приложениями!
# Создаем GUID под Windows командой .NET SDK:
# uuidgen
set(CPACK_WIX_UPGRADE_GUID "3dc342db-ccb3-4efa-9757-44e499ebc7af")

message("=== WiX setup complete")

Здесь я привел все значимые настройки для WIX, если вам нужна установка разных компонентов и что-то более сложное, чем просто копирование файлов, то вам всё равно придется создавать шаблоны WIX, но это тема для отдельной статьи.

Многие опции закомментированы их мы будем использовать в будущих статьях.

В файл settings.cmake.in добавим

# Список разделяемых библиотек, которые будут скопированы в папку с исполняемым файлом
set(MY_SHARED_LIB_FILES
   ${CMAKE_CURRENT_BINARY_DIR}/libcolorconsole.dll
   ${CMAKE_CURRENT_BINARY_DIR}/libgcc_s_seh-1.dll
    ${CMAKE_CURRENT_BINARY_DIR}/libstdc++-6.dll
    ${CMAKE_CURRENT_BINARY_DIR}/libwinpthread-1.dll
)

# Имена папок, которые будут скопированы при установке в папку с исполняемым файлом
set(MY_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
set(MY_IMG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/images)

В файл CmakeLists.txt добавим после:

include(${PROJECT_SOURCE_DIR}/cmake/settings.cmake.in)

строку:

# Настраиваем WIX
include(${PROJECT_SOURCE_DIR}/cmake/wix.cmake.in)

Настройка копирования разделяемых библиотек и сторонних файлов с помощью WIX и Cmake

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

Создадим несколько папки и файлы для копирования:

cd C:\projects\colortable_msi
mkdir images
mkdir data
type nul > .\data\db.sqlite
type nul > .\images\logo.png
type nul > .\images\bg.png

Заменим содержимое файла cmake\install.cmake.in:

# Задаем базовую установку
install(TARGETS ${PROJECT_NAME} RUNTIME 
DESTINATION ./bin
RENAME colortable.exe
)

# Копируем все требуемые разделяемые (shared) библиотеки
install(FILES ${MY_SHARED_LIB_FILES} DESTINATION ./bin)

install(DIRECTORY
        "${MY_DATA_DIR}" 
        DESTINATION . 
        PATTERN "*.sqlite")

install(DIRECTORY
        "${MY_IMG_DIR}" 
        DESTINATION . 
        PATTERN "*.png")

Здесь мы задаем target для установки и отдельно указываем просто скопировать файлы из списка MY_SHARED_LIB_FILES в папку с исполняемым файлом.

Так же мы копируем папки с картинками и базой данных, при этом указывает маску для расширения файлов, чтобы случайно не скопировать то что не нужно, это может быть полезно, по мере увеличения количества файлов.

Запустим сборку:

rmdir /q/s .\build
cmake -S . -B build 
cmake --build build

Запустим сборку дистрибутива:

 cmake --build build --target package 

Запускаем установку в пассивном режиме

Чтобы каждый раз не отвечать на кучу вопросов запустим установку в пассивном режиме. При этом будет отображаться индикатор копирования, но никаких запросов на установку не последует:

.\build\colortable-0.1-win64.msi /norestart /passive

Проверим папку с программой:

tree /f "C:\Program Files\AltuninVV-Apps\" 
Структура папок

C:\PROGRAM FILES\ALTUNINVV-APPS
├───bin
│       colorconsoleapp.exe
│       libcolorconsole.dll
│       libgcc_s_seh-1.dll
│       libstdc++-6.dll
│       libwinpthread-1.dll
│
├───data
│       db.sqlite
│
└───images
        bg.png
        logo.png

Попробуем запустить:

"C:\Program Files\AltuninVV-Apps\bin\colorconsoleapp.exe"

В консоль будет выведена таблица цветов.

Заключение

Сегодня мы рассмотрели создание установочного msi-файла для нашей программы с помощью WIX м CMake:

Установили .NET SDK и WIX;

Доработали наш проект, таким образом, чтобы копированием разделяемой библиотеки занимался GET_RUNTIME_DEPENDENCIES;

Добавили поддержку WIX в наш проект CMake;

Протестировали сборку установочного файла;

Добавили настройки для WIX;

Добавили команды для копирования разделяемых библиотек и прочих файлов;

Собрали установщик, запустили установку из консоли в пассивном режиме, проверили содержимое папки с установленной программой;

Запустили установленную программу.

В следующей статье мы рассмотрим настройку внешнего вида установщика - поменяем фон, баннер и текст лицензионного соглашения.

 

Категория C++
Теги Cpp cpp. cmake wix msi

Добавить комментарий

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 278