Рекомендации по упаковке для кросс-компиляторов MinGW

Введение

Миссия проекта Fedora MinGW — предоставить превосходную среду разработки для пользователей Fedora, желающих кросс-компилировать свои программы для запуска в Windows, минимизируя необходимость использования Windows вообще. В прошлом разработчикам приходилось портировать и компилировать все библиотеки и инструменты, которые им были нужны, и эта огромная работа выполнялась независимо много раз. Мы стремимся устранить дублирование работы для разработчиков приложений, предоставляя набор библиотек и инструментов разработки, которые уже были портированы в среду кросс-компилятора MinGW. Это означает, что разработчикам не нужно будет перекомпилировать стек приложений самостоятельно, а можно сосредоточиться только на изменениях, необходимых для их собственного приложения.

Цели Win32 и Win64 поддерживаются со средой выполнения MSVCRT. Цель Win64 со средой выполнения UCRT также поддерживается, однако только для базового инструментария. Сборки для UCRT не включены для пакетов выше инструментария на данный момент.

Отдельные и интегрированные исходные пакеты MinGW

Существует два разрешённых способа предоставления сборок MinGW программного обеспечения в Fedora:

  • Отдельные исходные пакеты: Существуют отдельные RPM spec-файлы для нативной и MinGW сборок, поддерживаемые как независимые компоненты Fedora. Это традиционный подход к упаковке MinGW в Fedora

  • Интегрированные исходные пакеты: Существует единый RPM spec-файл для нативной и MinGW сборок, как единый компонент Fedora. Сборки MinGW выпускаются как бинарные под-RPM. Это современный, предпочтительный подход к упаковке MinGW в Fedora.

Традиционный подход полностью разделённых исходных пакетов был принят изначально из-за опасений, что нестабильность в инструментарии MinGW или сборках Windows может помешать своевременным обновлениям нативного пакета. Опыт в Fedora с тех пор показал, что это, как правило, не проблема, влияющая на большинство пакетов, особенно там, где поддержка Windows является явно тестируемым результатом проекта upstream.

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

  • Добавление поддержки MinGW должно пройти полный процесс проверки новых пакетов Fedora, в значительной степени дублируя проверку, уже выполненную для нативного пакета.

  • Существует постоянное бремя для мейнтейнера — обеспечивать отслеживание исходным пакетом MinGW изменений соответствующего нативного исходного пакета при его перебазировании на новые выпуски.

  • Существует дополнительная работа по обработке патчей/обновлений в ответ на отчёты об ошибках. Отчёты об ошибках часто поступают только по одному из двух компонентов, а не по обоим, но при уязвимостях безопасности создаётся вдвое большее число отчётов об ошибках. Затем также есть несколько сборок koji и обновлений для обработки.

При подходе с интегрированной упаковкой существует небольшая дополнительная нагрузка на мейнтейнера нативного пакета для обеспечения работоспособности сборок MinGW и небольшая дополнительная нагрузка в виде специфичных для MinGW отчётов об ошибках. Это обычно незначительно по сравнению с накладными расходами на поддержку разделённых пакетов.

С учётом этого рекомендация рабочей группы MinGW SIG такова:

  • Если один и тот же контрибьютор Fedora намерен поддерживать как нативную, так и MinGW сборки пакета, он ДОЛЖЕН использовать интегрированный подход к упаковке.

  • Если проект upstream явно поддерживает платформу Windows как цель сборки и имеет автоматизированную CI, контрибьюторы СЛЕДУЕТ предпочитать интегрированный подход к упаковке MinGW. Мейнтейнеры нативных пакетов СЛЕДУЕТ обычно принимать добавление интегрированной поддержки MinGW. Если запрос отклоняется, нативный мейнтейнер должен обосновать своё решение.

  • Если проект upstream не имеет автоматизированного тестирования сборок Windows, поддержка пакета MinGW МОЖЕТ использовать любой подход к упаковке. Нативный мейнтейнер может по своему усмотрению отклонить запрос на интегрированную упаковку.

  • Если проект upstream поддерживает только сборки Windows, ДОЛЖЕН использоваться отдельный подход к упаковке. Соответствующий нативный пакет в Fedora не ожидается. Эта ситуация очень редка.

  • Когда контрибьютор предлагает новый нативный пакет для Fedora, предоставляющий библиотеки, которые, как известно, поддерживают Windows, рецензент СЛЕДУЕТ поинтересоваться, не хочет ли контрибьютор одновременно добавить сборки MinGW. Контрибьютор может по своему усмотрению отклонить этот запрос.

Добавление поддержки MinGW вместе с новым нативным пакетом

Когда соответствующий нативный пакет ещё не существует, всегда потребуется пройти стандартный процесс проверки новых пакетов Fedora. Предлагаемая поддержка MinGW ДОЛЖНА следовать интегрированному подходу к упаковке, чтобы обеспечить как сборки MinGW, так и нативные, где это технически возможно. Как отмечено в предыдущем разделе, в некоторых редких ситуациях не будет соответствующего нативного пакета, что потребует использования отдельного подхода к упаковке.

Добавление поддержки MinGW к существующему нативному пакету

Когда соответствующий нативный пакет уже присутствует в Fedora, предпочтительно добавить поддержку MinGW к нативному исходному пакету.

Когда изменения исходного пакета просты, контрибьютор СЛЕДУЕТ:

  • Внести необходимые дополнения в spec-файл в своей ветке (форке) пакета

  • Отправить на сборку koji scratch-build, чтобы доказать, что изменения дают ожидаемый эффект

  • Открыть merge request к нативному пакету с изменениями spec-файла, добавив ссылку на результаты koji scratch-build в качестве комментария.

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

Если есть сомнения в жизнеспособности следования интегрированному подходу к упаковке, МОЖЕТ быть открыт баг к пакету до начала работы, чтобы обсудить два варианта упаковки с мейнтейнером нативного пакета.

Если нативный мейнтейнер отклоняет предложение добавить поддержку MinGW к существующему пакету, ДОЛЖЕН быть соблюдён обычный процесс Fedora для новых пакетов, чтобы ввести поддержку MinGW в соответствии с отдельным подходом к упаковке.

Отслеживание версий нативных пакетов Fedora

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

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

Следование политике Fedora

Кросс-компилированные пакеты MinGW должны следовать политике Fedora, за исключением случаев, отмеченных в этом документе. Кросс-компилированные пакеты проходят тот же процесс проверки, процесс администрирования GIT и т. д., что и другие пакеты Fedora.

Именование пакетов

Пакеты MinGW требуют специального именования для обозначения соответствующей архитектуры ЦП, для которой были собраны двоичные файлы. Во время сборки никогда не должно быть пакета с префиксом mingw-. Префикс mingw- используется исключительно для имён RPM spec-файлов и имени файла исходного RPM. Пакеты, специфичные для архитектуры ЦП, создаются разделами с %files -n mingw32-foo, %files -n mingw64-foo или %files -n ucrt64-foo.

mingw-

Используется для исходного пакета и имени RPM spec (только там, где выбран отдельный подход к упаковке)

mingw32-

Используется для пакетов, собранных для Win32 со средой выполнения MSVCRT

mingw64-

Используется для пакетов, собранных для Win64 со средой выполнения MSVCRT

ucrt64-

Используется для пакетов, собранных для Win64 со средой выполнения UCRT

Базовые пакеты

Базовые пакеты предоставляют корневую файловую систему, базовые библиотеки, binutils (базовые программы, такие как 'strip', 'ld' и т. д.), компилятор (gcc) и API Win32/Win64. Пакеты могут зависеть от одного или нескольких из них. В частности, почти все пакеты должны иметь BuildRequire mingw32-filesystem, mingw64-filesystem, mingw32-gcc и mingw64-gcc.

mingw32-filesystem / mingw64-filesystem / ucrt64-filesystem

Основная структура каталогов файловой системы и RPM-макросы для spec-файлов. Эквивалент RPM 'filesystem'

mingw32-binutils / mingw64-binutils / ucrt64-binutils

Кросс-компилированные binutils (утилиты, такие как 'strip', 'as', 'ld'), которые понимают исполняемые файлы Windows и DLL. Эквивалент RPM 'binutils'

mingw32-gcc / mingw64-gcc / ucrt64-gcc

Коллекция компиляторов GNU. Компиляторы для C и C++, которые кросс-компилируют под цель Windows. Эквивалент RPM gcc

mingw32-crt / mingw64-crt / ucrt64-crt

Базовые библиотеки для основной среды выполнения и разработки MinGW. Эквивалент RPM 'glibc'

mingw32-headers / mingw64-headers / ucrt64-headers

API Win32 и Win64. Бесплатная (общественное достояние) реализация заголовочных файлов, необходимых для компоновки с API Win32 и Win64. Нет прямого эквивалента в базовой Fedora — ближайший — glibc-devel

Сборка для нескольких целей

Цель фреймворка MinGW — предоставить простой способ для мейнтейнеров пакетов собирать свои пакеты для нескольких целей, используя один .spec-файл. Чтобы помочь разработчикам в этом, было разработано несколько RPM-макросов, которые являются частью пакета mingw-filesystem. Эти RPM-макросы будут объяснены далее в этих рекомендациях.

По умолчанию поддержка MinGW будет собрана как для целей Win32, так и Win64 со средой выполнения MSVCRT. Сборка цели Win64 со средой выполнения UCRT64 пока не включена по умолчанию.

Когда пакет может быть собран только для подмножества этих целей, это можно указать, задав один или несколько из следующих параметров:

%global mingw_build_win32 0

Не собирать для цели Win32 со средой выполнения MSVCRT

%global mingw_build_win64 0

Не собирать для цели Win64 со средой выполнения MSVCRT

%global mingw_build_ucrt64 0

Не собирать для цели Win64 со средой выполнения UCRT

Один исходный RPM, отдельные бинарные RPM для каждой цели

Каждый кросс-компилированный пакет MinGW, который собирает двоичные файлы для конкретной цели, должен помещать двоичные файлы для этой цели в отдельный подпакет. Так если пакет mingw-foo или foo собирает двоичные файлы для целей Win32 и Win64 со средой выполнения MSVCRT, то исходный RPM должен предоставлять два подпакета с именами mingw32-foo и mingw64-foo. Если пакет собирается для среды выполнения UCRT, он также будет иметь подпакет ucrt64-foo.

Это означает, что spec-файл должен содержать разделы %package и %files для всех целей.

При использовании отдельного подхода к упаковке пакеты, содержащие переводы, должны использовать %mingw_find_lang вместо %find_lang.

При использовании интегрированного подхода к упаковке пакеты, содержащие переводы, должны использовать %find_lang`, за которым следует `%mingw_find_lang+.

Это приводит к тому, что все списки файлов переводов разделяются на списки файлов для каждой цели. Например: когда spec-файл содержит что-то вроде этого:

 %install
 <snip>
 %mingw_find_lang foo

то будет создан один файл на каждую цель mingw с именами mingw32-foo.lang, mingw64-foo.lang и ucrt64-foo.lang. Эти списки файлов можно включить в раздел %files для соответствующих целей:

 %files -n mingw32-foo -f mingw32-foo.lang
 <snip>
 %files -n mingw64-foo -f mingw64-foo.lang
 <snip>
 %files -n ucrt64-foo -f ucrt64-foo.lang

Структура файловой системы

Интеграция в основную структуру корневой файловой системы следующая:

[root]
  |
  +- etc
  |   |
  |   +- rpm
  |       |
  |       +- macros.mingw
  |       +- macros.mingw32
  |       +- macros.mingw64
  |
  +- usr
      |
      +- bin   - Links to MinGW cross compiler toolchain
      |   |
      |   +- i686-w64-mingw32-cpp
      |   +- i686-w64-mingw32-gcc
      |   +- i686-w64-mingw32-g++
      |   +- x86_64-w64-mingw32-cpp
      |   +- x86_64-w64-mingw32-gcc
      |   +- x86_64-w64-mingw32-g++
      |   +- x86_64-w64-mingw32ucrt-cpp
      |   +- x86_64-w64-mingw32ucrt-gcc
      |   +- x86_64-w64-mingw32ucrt-g++
      |   +- ... etc..
      |
      +- lib
      |   |
      |   +- rpm
      |       |
      |       +- mingw-find-debuginfo.sh - extract debug information from Win32 and Win64 binaries
      |       +- mingw-find-lang.sh - generates per-target file lists containing translations
      |       +- mingw-find-provides.sh - extra DLL names
      |       +- mingw-find-requires.sh - discover required DLL names
      |
      +- i686-w64-mingw32  - root of mingw toolchain and binaries for the Win32 target with MSVCRT runtime - see next diagram
      +- x86_64-w64-mingw32  - root of mingw toolchain and binaries for the Win64 target with MSVCRT runtime - see next diagram+`
      +- x86_64-w64-mingw32urt  - root of mingw toolchain and binaries for the Win64 target with UCRT runtime - see next diagram+`

Основная часть упакованного содержимого находится под соответствующим корнем MinGW, одним из /usr/i686-w64-mingw32, /usr/x86_64-w64-mingw32 и /usr/x86_64-w64-mingw32ucrt:

[mingw-root]
  |
  +- bin  - Binutils toolchain binaries for the target
  |   |
  |   +- ar
  |   +- as
  |   +- dlltool
  |   +- ld
  |   +- ... etc ...
  |
  +- lib  - Binutils toolchain support libraries / files for the target
  |
  +- sys-root  - root for cross compiled MinGW binaries
      |
      +- mingw
          |
          +- bin     - cross-compiled MinGW binaries & runtime DLL parts
          +- etc     - configuration files
          +- include - include files for cross compiled MinGW libs
          +- lib     - cross-compiled static MinGW libraries & linktime DLL parts
          |   |
          |   +- pkgconfig  - pkg-config definitions for libraries
          |
          +- share
              |
              +- man

Имена файлов кросс-компиляторов и binutils

Кросс-компиляторы и binutils MinGW являются двоичными файлами Fedora и поэтому размещаются в %{_bindir} (то есть /usr/bin) согласно FHS и рекомендациям Fedora.

Кросс-компиляторы и binutils MinGW, которые генерируют двоичные файлы i686 для Windows со средой выполнения MSVCRT, называются:

 %{_bindir}/i686-w64-mingw32-gcc
 %{_bindir}/i686-w64-mingw32-g++
 %{_bindir}/i686-w64-mingw32-ld
 %{_bindir}/i686-w64-mingw32-as
 %{_bindir}/i686-w64-mingw32-strip
 etc.

Те же самые двоичные файлы присутствуют в %{_prefix}/i686-w64-mingw32/bin без какого-либо префикса в имени, то есть:

 %{_prefix}/i686-w64-mingw32/bin/gcc
 %{_prefix}/i686-w64-mingw32/bin/g++
 %{_prefix}/i686-w64-mingw32/bin/ld
 %{_prefix}/i686-w64-mingw32/bin/as
 %{_prefix}/i686-w64-mingw32/bin/strip
 etc.

То же самое относится и к цели x86_64 с обеими средами выполнения MSVCRT и UCRT. Цель с MSVCRT использует 'x86_64-w64-mingw32' в качестве префикса вместо 'i686-w64-mingw32', тогда как UCRT использует 'x86_64-w64-mingw32ucrt'.

Именование корневой файловой системы

Корневая файловая система содержит исполняемые файлы Windows и DLL, а также любые другие файлы, предназначенные только для Windows. Она необходима как потому, что нам нужно хранить библиотеки Windows для компоновки дальнейших библиотек, которые от них зависят, так и потому, что MinGW требует расположения корневой файловой системы.

Расположение для цели Win32 со средой выполнения MSVCRT предоставляется макросом:

 %{mingw32_sysroot}   %{_prefix}/i686-w64-mingw32/sys-root

Цель Win64 со средой выполнения MSVCRT предоставляется макросом:

 %{mingw64_sysroot}   %{_prefix}/x86_64-w64-mingw32/sys-root

Цель Win64 со средой выполнения UCRT предоставляется макросом:

 %{ucrt64_sysroot}   %{_prefix}/x86_64-w64-mingw32ucrt/sys-root

Стандартные RPM-макросы mingw

Пакет mingw-filesystem предоставляет ряд удобных макросов для кросс-компилированных каталогов sysroot и инструментария. Обязательно использовать эти макросы во всех кросс-компилированных пакетах MinGW, отправляемых в Fedora.

Макросы инструментария

Следующие макросы предназначены для разделов %build и %install spec-файла

Общие макросы:

Макрос

Доступен в mingw-filesystem

Объяснение

mingw_cmake

>= 95

Вызвать двоичный файл 'cmake' для всех настроенных целей

mingw_cmake_kde4

>= 95

Вызвать двоичный файл 'cmake' для всех настроенных целей с установленными специфичными для KDE4 параметрами

mingw_configure

>= 95

Вызвать команду configure для всех настроенных целей

mingw_make

>= 95

Вызвать команду 'make' для всех настроенных целей

mingw_make_build

>= 113

Вызвать команду 'make -O -j<nprocs> V=1 VERBOSE=1' для всех настроенных целей

mingw_make_install

>= 113

Вызвать 'make install DESTDIR=$RPM_BUILD_ROOT 'INSTALL=/usr/bin/install -p' для всех настроенных целей

mingw_meson

>= 104

Вызвать двоичный файл meson для всех настроенных целей

mingw_ninja

>= 104

Вызвать двоичный файл ninja для всех настроенных целей

mingw_objcopy

>= 95

двоичный файл кросс-компилятора 'objcopy' (который поддерживает как двоичные файлы Win32, так и Win64)

mingw_objdump

>= 95

двоичный файл кросс-компилятора 'objdump' (который поддерживает как двоичные файлы Win32, так и Win64)

mingw_qmake_qt4

>= 95

Вызвать двоичный файл Qt4 qmake для всех настроенных целей (требуется установка mingw32-qt-qmake и/или mingw64-qt-qmake)

mingw_qmake_qt5

>= 96

Вызвать двоичный файл Qt5 qmake для всех настроенных целей (требуется установка mingw32-qt5-qmake и/или mingw64-qt5-qmake)

mingw_strip

>= 95

двоичный файл кросс-компилятора 'strip' (который поддерживает как двоичные файлы Win32, так и Win64)

Макросы, специфичные для Win32 со средой выполнения MSVCRT:

Макрос

Доступен в mingw32-filesystem

Значение

Объяснение

mingw32_ar

>= 95

i686-w64-mingw32-ar

двоичный файл кросс-компилятора 'ar'

mingw32_cc

>= 95

i686-w64-mingw32-gcc

двоичный файл кросс-компилятора 'gcc'

mingw32_cflags

>= 95

-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4

Флаги компилятора по умолчанию для двоичных файлов C/C++

mingw32_cmake

>= 95

Вызвать двоичный файл 'cmake' для цели Win32

mingw32_configure

>= 95

стандартный вызов для скриптов 'configure' autotools

mingw32_cpp

>= 95

i686-w64-mingw32-gcc -E

двоичный файл кросс-компилятора 'cpp'

mingw32_env

>= 95

Установить правильные переменные окружения для цели Win32

mingw32_host

>= 95

i686-w64-mingw32

Хост-платформа для сборки

mingw32_meson

>= 104

Вызвать двоичный файл meson для цели Win32

mingw32_ninja

>= 104

Вызвать двоичный файл ninja для цели Win32

mingw32_objcopy

>= 95

i686-w64-mingw32-objcopy

двоичный файл кросс-компилятора 'objcopy'

mingw32_objdump

>= 95

i686-w64-mingw32-objdump

двоичный файл кросс-компилятора 'objdump'

mingw32_pkg_config

>= 95

i686-w64-mingw32-pkg-config

Вызвать команду pkg-config для цели Win32

mingw32_qmake_qt4

>= 95

mingw32-qmake-qt4

Вызвать команду Qt4 qmake для цели Win32

mingw32_qmake_qt5

>= 96

mingw32-qmake-qt5

Вызвать команду Qt5 qmake для цели Win32

mingw32_ranlib

>= 95

i686-w64-mingw32-ranlib

двоичный файл кросс-компилятора 'ranlib'

mingw32_strip

>= 95

i686-w64-mingw32-strip

двоичный файл кросс-компилятора 'strip'

mingw32_target

>= 95

i686-w64-mingw32

Целевая платформа для сборки

Макросы, специфичные для Win64 со средой выполнения MSVCRT:

Макрос

Доступен в mingw64-filesystem

Значение

Объяснение

mingw64_ar

>= 95

x86_64-w64-mingw32-ar

двоичный файл кросс-компилятора 'ar'

mingw64_cc

>= 95

x86_64-w64-mingw32-gcc

двоичный файл кросс-компилятора 'gcc'

mingw64_cflags

>= 95

-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4

Флаги компилятора по умолчанию для двоичных файлов C/C++

mingw64_cmake

>= 95

Вызвать двоичный файл 'cmake' для цели Win64

mingw64_configure

>= 95

стандартный вызов для скриптов 'configure' autotools

mingw64_cpp

>= 95

x86_64-w64-mingw32-gcc -E

двоичный файл кросс-компилятора 'cpp'

mingw64_env

>= 95

Установить правильные переменные окружения для цели Win64

mingw64_host

>= 95

x86_64-w64-mingw32

Хост-платформа для сборки

mingw64_meson

>= 104

Вызвать двоичный файл meson для цели Win64

mingw64_ninja

>= 104

Вызвать двоичный файл ninja для цели Win64

mingw64_objcopy

>= 95

x86_64-w64-mingw32-objcopy

двоичный файл кросс-компилятора 'objcopy'

mingw64_objdump

>= 95

x86_64-w64-mingw32-objdump

двоичный файл кросс-компилятора 'objdump'

mingw64_pkg_config

>= 95

x86_64-w64-mingw32-pkg-config

Вызвать команду pkg-config для цели Win64

mingw64_qmake_qt4

>= 95

mingw64-qmake-qt4

Вызвать команду Qt4 qmake для цели Win64

mingw64_qmake_qt5

>= 96

mingw64-qmake-qt5

Вызвать команду Qt5 qmake для цели Win64

mingw64_ranlib

>= 95

x86_64-w64-mingw32-ranlib

двоичный файл кросс-компилятора 'ranlib'

mingw64_strip

>= 95

x86_64-w64-mingw32-strip

двоичный файл кросс-компилятора 'strip'

mingw64_target

>= 95

x86_64-w64-mingw32

Целевая платформа для сборки

Макросы, специфичные для Win64 со средой выполнения UCRT:

Макрос

Доступен в ucrt64-filesystem

Значение

Объяснение

ucrt64_ar

>= 133

x86_64-w64-mingw32ucrt-ar

двоичный файл кросс-компилятора 'ar'

ucrt64_cc

>= 133

x86_64-w64-mingw32ucrt-gcc

двоичный файл кросс-компилятора 'gcc'

ucrt64_cflags

>= 133

-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4

Флаги компилятора по умолчанию для двоичных файлов C/C++

ucrt64_cmake

>= 133

Вызвать двоичный файл 'cmake' для цели Win64

ucrt64_configure

>= 133

стандартный вызов для скриптов 'configure' autotools

ucrt64_cpp

>= 133

x86_64-w64-mingw32ucrt-gcc -E

двоичный файл кросс-компилятора 'cpp'

ucrt64_env

>= 133

Установить правильные переменные окружения для цели Win64

ucrt64_host

>= 133

x86_64-w64-mingw32

Хост-платформа для сборки

ucrt64_meson

>= 104

Вызвать двоичный файл meson для цели Win64

ucrt64_ninja

>= 104

Вызвать двоичный файл ninja для цели Win64

ucrt64_objcopy

>= 133

x86_64-w64-mingw32ucrt-objcopy

двоичный файл кросс-компилятора 'objcopy'

ucrt64_objdump

>= 133

x86_64-w64-mingw32ucrt-objdump

двоичный файл кросс-компилятора 'objdump'

ucrt64_pkg_config

>= 133

x86_64-w64-mingw32ucrt-pkg-config

Вызвать команду pkg-config для цели Win64

ucrt64_qmake_qt4

>= 133

ucrt64-qmake-qt4

Вызвать команду Qt4 qmake для цели Win64

ucrt64_qmake_qt5

>= 133

ucrt64-qmake-qt5

Вызвать команду Qt5 qmake для цели Win64

ucrt64_ranlib

>= 133

x86_64-w64-mingw32ucrt-ranlib

двоичный файл кросс-компилятора 'ranlib'

ucrt64_strip

>= 133

x86_64-w64-mingw32ucrt-strip

двоичный файл кросс-компилятора 'strip'

ucrt64_target

>= 133

x86_64-w64-mingw32

Целевая платформа для сборки

Макросы расположения файловой системы

Следующие макросы предназначены для использования в разделах %build, %install и %files RPM spec-файла

Для цели Win32 со средой выполнения MSVCRT:

mingw32_bindir

%{mingw32_prefix}/bin

Расположение исполняемых файлов Windows.

mingw32_datadir

%{mingw32_prefix}/share

Общие данные, используемые под Windows.

mingw32_docdir

%{mingw32_prefix}/share/doc

Документация.

mingw32_infodir

%{mingw32_prefix}/share/info

Файлы Info (см. примечание ниже).

mingw32_includedir

%{mingw32_prefix}/include

Заголовочные файлы, используемые при кросс-компиляции для Windows.

mingw32_libdir

%{mingw32_prefix}/lib

Библиотеки Windows (см. разделы ниже).

mingw32_libexecdir

%{mingw32_prefix}/libexec

mingw32_mandir

%{mingw32_prefix}/share/man

Страницы руководства (см. примечание ниже).

mingw32_prefix

%{mingw32_sysroot}/mingw

Эквивалент %{_prefix} для Windows, требуемый MinGW.

mingw32_sbindir

%{mingw32_prefix}/sbin

mingw32_sysconfdir

%{mingw32_prefix}/etc

Файлы конфигурации, используемые при работе под Windows.

mingw32_sysroot

%{_prefix}/i686-w64-mingw32/sys-root

Системный корень Windows.

Для цели Win64 со средой выполнения MSVCRT:

mingw64_bindir

%{mingw64_prefix}/bin

Расположение исполняемых файлов Windows.

mingw64_datadir

%{mingw64_prefix}/share

Общие данные, используемые под Windows.

mingw64_docdir

%{mingw64_prefix}/share/doc

Документация.

mingw64_infodir

%{mingw64_prefix}/share/info

Файлы Info (см. примечание ниже).

mingw64_includedir

%{mingw64_prefix}/include

Заголовочные файлы, используемые при кросс-компиляции для Windows.

mingw64_libdir

%{mingw64_prefix}/lib

Библиотеки Windows (см. разделы ниже).

mingw64_libexecdir

%{mingw64_prefix}/libexec

mingw64_mandir

%{mingw64_prefix}/share/man

Страницы руководства (см. примечание ниже).

mingw64_prefix

%{mingw64_sysroot}/mingw

Эквивалент %{_prefix} для Windows, требуемый MinGW.

mingw64_sbindir

%{mingw64_prefix}/sbin

mingw64_sysconfdir

%{mingw64_prefix}/etc

Файлы конфигурации, используемые при работе под Windows.

mingw64_sysroot

%{_prefix}/x86_64-w64-mingw32/sys-root

Системный корень Windows.

Для цели Win64 со средой выполнения UCRT:

ucrt64_bindir

%{ucrt64_prefix}/bin

Расположение исполняемых файлов Windows.

ucrt64_datadir

%{ucrt64_prefix}/share

Общие данные, используемые под Windows.

ucrt64_docdir

%{ucrt64_prefix}/share/doc

Документация.

ucrt64_infodir

%{ucrt64_prefix}/share/info

Файлы Info (см. примечание ниже).

ucrt64_includedir

%{ucrt64_prefix}/include

Заголовочные файлы, используемые при кросс-компиляции для Windows.

ucrt64_libdir

%{ucrt64_prefix}/lib

Библиотеки Windows (см. разделы ниже).

ucrt64_libexecdir

%{ucrt64_prefix}/libexec

ucrt64_mandir

%{ucrt64_prefix}/share/man

Страницы руководства (см. примечание ниже).

ucrt64_prefix

%{ucrt64_sysroot}/mingw

Эквивалент %{_prefix} для Windows, требуемый MinGW.

ucrt64_sbindir

%{ucrt64_prefix}/sbin

ucrt64_sysconfdir

%{ucrt64_prefix}/etc

Файлы конфигурации, используемые при работе под Windows.

ucrt64_sysroot

%{_prefix}/x86_64-w64-mingw32ucrt/sys-root

Системный корень Windows.

Компиляция двоичных файлов

Чтобы собрать двоичные файлы для нескольких целей, нам приходится вызывать команды, такие как ./configure и make, несколько раз (по одному разу для каждой цели). Если приходится всё это прописывать в spec-файле, это приводит к дублированию кода. Чтобы уменьшить объём дублирования, было введено несколько RPM-макросов для помощи в компиляции. Эти макросы — %mingw_configure, %mingw_cmake, %mingw_cmake_kde4, %mingw_qmake_qt4, %mingw_qmake_qt5 и %mingw_make

Эти макросы используют компиляцию вне источника для сборки двоичных файлов для всех целей. Почти все пакеты поддерживают компиляцию вне источника или требуют небольшого патча. Единственные известные на сегодняшний день исключения — zlib и openssl. Пакеты, которые не поддерживают компиляцию вне источника, могут требовать иного подхода, например выполнения всего в фазе %install. Если вам случайно попадётся пакет, требующий иного подхода, не стесняйтесь связаться с нами в списке рассылки Fedora MinGW

Некоторые пакеты нужно собирать несколько раз для каждой цели. Примерами этого являются пакеты, которые нужно собрать один раз для статической версии и один раз для разделяемой версии. Такие пакеты могут добавить собственный суффикс к используемому каталогу сборки. Допустим, у вас есть что-то вроде приведённого ниже:

 mkdir build_shared
 pushd build_shared
 %{mingw32_configure} --enable-shared
 popd
 mkdir build_static
 pushd build_static
 %{mingw32_configure} --enable-static
 popd

Это можно переписать примерно так:

 MINGW_BUILDDIR_SUFFIX=shared %mingw_configure --enable-shared
 MINGW_BUILDDIR_SUFFIX=static %mingw_configure --enable-static

Большинство пакетов использовали команду make %{?_smp_mflags} для сборки пакета. В фреймворке кросс-компилятора MinGW вы должны использовать %mingw_make %{?_smp_mflags} для сборки пакета для всех настроенных целей. Как и с макросом %mingw_configure, вы также можете использовать переменную окружения MINGW_BUILDDIR_SUFFIX, чтобы указать собственный суффикс для используемого каталога сборки

Для установки пакета команда make install DESTDIR=$RPM_BUILD_ROOT использовалась почти во всех случаях. Это можно переписать как %mingw_make install DESTDIR=$RPM_BUILD_ROOT, чтобы установить пакет для всех настроенных целей. Переменную окружения MINGW_BUILDDIR_SUFFIX также можно использовать здесь.

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

Зависимости

Если пакет содержит двоичные файлы, которые зависят от DLL, предоставляемой другим пакетом, эти зависимости должны быть выражены в форме:

 mingw32(foo.dll)

где foo.dll — имя DLL. Имя должно быть преобразовано в нижний регистр, потому что двоичные файлы Windows содержат зависимости без учёта регистра. Форма 'mingw32(foo.dll)' должна использоваться для двоичных файлов Win32, а форма 'mingw64(foo.dll)' — для двоичных файлов Win64.

Правильная генерация зависимостей выполняется автоматически. Упаковщикам следует начинать свои spec-файлы с этой строки:

 %{?mingw_package_header}

Все бинарные пакеты должны зависеть от mingw32-filesystem или mingw64-filesystem (в зависимости от файлов в пакете).

Все spec-файлы должны иметь BuildRequire как минимум одного из этих (в зависимости от целей, для которых вы хотите собирать):

 BuildRequires:  mingw32-filesystem
 BuildRequires:  mingw64-filesystem

и любые другие BuildRequires, которые им нужны.

Можно предположить, что большинство RPM-макросов mingw существуют во всех не-EOL выпусках Fedora. Однако если пакет полагается на недавно введённый макрос, следует использовать версионную зависимость от пакетов mingw-XX-filesystem.

Архитектура сборки

Все пакеты должны иметь:

 BuildArch: noarch

если только они не содержат нативных исполняемых файлов Fedora. При использовании отдельного подхода к упаковке тег BuildArch должен присутствовать в общем заголовке spec-файла. При использовании интегрированного подхода к упаковке тег BuildArch должен присутствовать в заголовке %package для каждого присутствующего под-RPM MinGW.

Библиотеки (DLL)

Все библиотеки должны быть собраны как DLL.

Из-за особенности Windows DLL хранятся в каталоге %{mingw32_bindir} вместе с управляющим файлом в каталоге %{mingw32_libdir}. Например, для библиотеки с именем foo там будет:

 %{mingw32_bindir}/foo.dll
 %{mingw32_libdir}/foo.dll.a

Файл foo.dll — это основная библиотека, foo.dll.a — это заглушка, скомпонованная с приложениями, чтобы они могли найти библиотеку во время выполнения. Все эти файлы требуются в этих расположениях для успешной компоновки. .dll может содержать номер версии, хотя и не всегда (например, foo-0.dll).

Не используйте %{mingw32_bindir}/* или %{mingw32_libdir}/* в разделе %files

Раздел %files должен перечислять DLL и библиотеки импорта отдельно. Пакеты НЕ ДОЛЖНЫ использовать %{mingw32_bindir}/* или %{mingw32_libdir}/*

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

Удаление отладочной информации (stripping)

Библиотеки и исполняемые файлы должны быть очищены от отладочной информации. Это делается правильно и автоматически, если spec-файл начинается с этой строки:

 %{?mingw_package_header}

Подпакет Debuginfo

Большинство двоичных файлов содержат отладочные символы при сборке пакета. Чтобы выделить отладочные символы в отдельный пакет debuginfo (как это делается с нативными пакетами Fedora), spec-файл должен включать эти строки:

 %{?mingw_package_header}
 [...]
 %{?mingw_debug_package}

Строка %{?mingw_debug_package} должна быть размещена после %description tag. Иначе spectool и другие инструменты RPM могут не работать.

При использовании интегрированного подхода к упаковке раздел %install должен также содержать вызов макроса %{mingw_debug_install_post} после того, как любые двоичные файлы были установлены в виртуальный корень:

 %install
 [...]
 %{?mingw_debug_install_post}

Список файлов

Пакеты MinGW предназначены для того, чтобы позволить разработчикам компилировать и тестировать поддержку Windows своих приложений. Кроме того, ожидается, что разработчики будут создавать установщики Windows (MSI) для своих приложений, используя содержимое пакета MinGW.

Таким образом, список файлов пакета Fedora MinGW должен включать содержимое, необходимое для удовлетворения либо использования при сборке/тестировании, либо создания установщиков Windows.

Исполняемые файлы (EXE)

Большинство библиотек также предоставляют исполняемые файлы. Они могут включать исполняемые файлы, которые можно использовать для тестирования или демонстрации рассматриваемой библиотеки (например, gtk3-demo.exe в mingw-gtk3). Другими примерами являются вспомогательные исполняемые файлы, которые используются самой библиотекой внутренне (например, gspawn-win32-helper.exe в mingw-glib2).

Исполняемые файлы, необходимые для правильного функционирования библиотек, должны быть упакованы в соответствующий подпакет mingw32/mingw64. Другие необязательные исполняемые файлы, предназначенные для конечных пользователей, должны быть упакованы (например, certtool.exe в GNUTLS). Исполняемые файлы, предназначенные для разработчиков, не поощряются, но могут быть упакованы в необязательные (зависимые) подпакеты по усмотрению упаковщика.

Файлы, которые уже являются частью нативных пакетов

Существуют различные типы файлов, которые просто дублируют эквивалентные файлы, найденные в нативных пакетах Fedora. Эти файлы не должны быть упакованы в пакет MinGW. Следующие файлы не нужно упаковывать в пакет MinGW, когда их нативный аналог уже содержит их:

  • Страницы руководства (%{mingw32_mandir} / %{mingw64_mandir} / %{ucrt64_mandir})

  • Файлы Info (%{mingw32_infodir} / %{mingw64_infodir} / %{ucrt64_infodir})

  • Общая документация (%{mingw32_docdir} / %{mingw64_docdir} / %{ucrt64_docdir})

  • Файлы Autoconf (%{mingw32_datadir}/aclocal / %{mingw64_datadir}/aclocal / %{ucrt64_datadir}/aclocal)

  • Файлы gtk-doc (%{mingw32_datadir}/gtk-doc / %{mingw64_datadir}/gtk-doc / %{ucrt64_datadir}/gtk-doc)

Обратите внимание, общую Документацию, ориентированную на конечных пользователей, а не на разработчиков, следует включать там, где вероятно, что разработчики приложений захотят включить её в свои установщики Windows.

Преобразование между отдельной и интегрированной упаковкой

В целом возможно преобразование в любом направлении между отдельным и интегрированным подходами к упаковке. Оба подхода дают абсолютно одинаковые бинарные RPM для содержимого MinGW, отличаясь только исходным RPM spec-файлом.

Чтобы преобразовать из отдельной в интегрированную упаковку

  • Убедитесь, что существующий нативный программный пакет имеет либо тот же (или более новый) номер версии, что и существующий пакет MinGW.

  • Добавьте поддержку MinGW в существующий spec-файл нативного пакета

  • Если и нативный, и существующий пакеты MinGW были на одной версии, убедитесь, что номер выпуска нативного пакета новее любой предыдущей сборки пакета MinGW.

  • Соберите новый нативный пакет с поддержкой MinGW

  • Выведите из эксплуатации отдельный пакет MinGW

Чтобы преобразовать из интегрированной в отдельную упаковку

  • Пройдите процесс проверки нового пакета для отдельного пакета MinGW, убедившись, что это тот же номер версии, что и у существующего интегрированного пакета

  • Импортируйте отдельный пакет MinGW в dist-git, но не собирайте его.

  • Удалите поддержку MinGW из существующего spec-файла нативного пакета

  • Соберите нативный пакет без поддержки MinGW

  • Убедитесь, что отдельный пакет MinGW имеет более новый номер выпуска, чем любые существующие бинарные под-RPM MinGW, собранные из нативного пакета

  • Соберите отдельный пакет MinGW

В обоих случаях опыт обновления должен быть прозрачным для пользователей, устанавливающих и обновляющих развёртывания Fedora.

Рекомендуется выполнять такие преобразования только в Rawhide. Если возникает необходимость выполнить преобразование из интегрированной в отдельную упаковку в стабильном потоке выпуска, одно обновление Bohdi должно включать как нативную, так и сборки пакетов mingw.

Отключение пакетов MinGW

При использовании интегрированного подхода к упаковке ДОЛЖНА быть возможность отключить сборку под-RPM MinGW, и сборка ДОЛЖНА быть отключена по умолчанию, за исключением цели дистрибутива Fedora. Это гарантирует, что нативный пакет всё ещё можно собрать в производных дистрибутивах, таких как RHEL, где инструментарии MinGW не включены. Это достигается включением условного оператора в начале spec-файла:

%if 0%{?fedora}
%bcond_without mingw
%else
%bcond_with mingw
%endif

а затем обернуть все связанные с MinGW определения %package / %files` и соответствующие команды `%build+ или %install в условную проверку:

%if %{with mingw}
%package -n mingw32-example
Summary: %{summary}
BuildArch: noarch
[...]
%endif

Пример spec-файла интегрированного пакета

%if 0%{?fedora}
%bcond_without mingw
%else
%bcond_with mingw
%endif

Name: example
Version: 1.0.0
Release: 1%{?dist}
Summary: Example library

License: LGPL-2.1-or-later
URL: https://fedoraproject.org
Source: https://fedoraproject.org/example-%{version}.tar.bz2

BuildRequires: gcc
BuildRequires: binutils
BuildRequires: gettext
BuildRequires: zlib

%if %{with mingw}
BuildRequires: mingw32-filesystem
BuildRequires: mingw32-gcc
BuildRequires: mingw32-binutils
BuildRequires: mingw32-gettext
BuildRequires: mingw32-win-iconv
BuildRequires: mingw32-zlib

BuildRequires: mingw64-filesystem
BuildRequires: mingw64-gcc
BuildRequires: mingw64-binutils
BuildRequires: mingw64-gettext
BuildRequires: mingw64-win-iconv
BuildRequires: mingw64-zlib
%endif

%description
Example library.

%package devel
Summary: Example library development package
...

%description devel
Example library development headers and library.

%if %{with mingw}
# If a package maintainer wishes to bundle static libraries then they
# can be placed in -static subpackages. Otherwise, the -static subpackages
# can be dropped

# Win32
%package -n mingw32-example
Summary: MinGW compiled example library for the Win32 target
BuildArch: noarch

%description -n mingw32-example
MinGW compiled example library for the Win32 target.

%package -n mingw32-example-static
Summary: Static version of the MinGW Win32 compiled example library
Requires: mingw32-example = %{version}-%{release}

%description -n mingw32-example-static
Static version of the MinGW Win32 compiled example library.

# Win64
%package -n mingw64-example
Summary: MinGW compiled example library for the Win64 target

%description -n mingw64-example
MinGW compiled example library for the Win64 target.
BuildArch: noarch

%package -n mingw64-example-static
Summary: Static version of the MinGW Win64 compiled example library
Requires: mingw64-example = %{version}-%{release}

%description -n mingw64-example-static
Static version of the MinGW Win64 compiled example library.

%{?mingw_debug_package}
%endif


%prep
%autosetup -p1 -n example-%{version}


%build

%define _configure ../../configure

mkdir -p build/native
cd build/native
%configure ...
%make_build
cd ../..

%if %{with mingw}
%mingw_configure --enable-static --enable-shared --enable-foo
%mingw_make_build
%endif

%install
cd build/native
%make_install

%find_lang example
cd ../..

%if %{with mingw}
%mingw_make_install

%mingw_find_lang example
%endif

%files
%{_libdir}/libexample.so.*

%files devel
%{_libdir}/libexample.so
%{_libdir}/pkgconfig/example.pc
%{_includedir}/example/

# Static subpackages are optional (as mentioned earlier)

%if %{with mingw}
# Win32
%files -n mingw32-example -f mingw32-example.lang
%{mingw32_bindir}/libexample-0.dll
%{mingw32_includedir}/example/
%{mingw32_libdir}/libexample.dll.a
%{mingw32_libdir}/pkgconfig/example.pc

%files -n mingw32-example-static
%{mingw32_libdir}/libexample.a

# Win64
%files -n mingw64-example -f mingw64-example.lang
%{mingw64_bindir}/libexample-0.dll
%{mingw64_includedir}/example/
%{mingw64_libdir}/libexample.dll.a
%{mingw64_libdir}/pkgconfig/example.pc

%files -n mingw64-example-static
%{mingw64_libdir}/libexample-0.a
%endif

%changelog
* Sun Apr 15 2012 Erik van Pienbroek <epienbro@fedoraproject.org> - 1.0.0-1
- Initial release

Пример spec-файла отдельного пакета

Spec-файл отдельного пакета по существу извлекает всё содержимое внутри условий %{with mingw} из предыдущего примера и помещает его в автономный spec-файл.

%{?mingw_package_header}

Name: mingw-example
Version: 1.0.0
Release: 1%{?dist}
Summary: MinGW compiled example library

License: LGPL-2.1-or-later
URL: https://fedoraproject.org
Source: https://fedoraproject.org/example-%{version}.tar.bz2

BuildArch: noarch

BuildRequires: mingw32-filesystem
BuildRequires: mingw32-gcc
BuildRequires: mingw32-binutils
BuildRequires: mingw32-gettext
BuildRequires: mingw32-win-iconv
BuildRequires: mingw32-zlib

BuildRequires: mingw64-filesystem
BuildRequires: mingw64-gcc
BuildRequires: mingw64-binutils
BuildRequires: mingw64-gettext
BuildRequires: mingw64-win-iconv
BuildRequires: mingw64-zlib


%description
MinGW compiled example library.


# If a package maintainer wishes to bundle static libraries then they
# can be placed in -static subpackages. Otherwise, the -static subpackages
# can be dropped

# Win32
%package -n mingw32-example
Summary: MinGW compiled example library for the Win32 target

%description -n mingw32-example
MinGW compiled example library for the Win32 target.

%package -n mingw32-example-static
Summary: Static version of the MinGW Win32 compiled example library
Requires: mingw32-example = %{version}-%{release}

%description -n mingw32-example-static
Static version of the MinGW Win32 compiled example library.

# Win64
%package -n mingw64-example
Summary: MinGW compiled example library for the Win64 target

%description -n mingw64-example
MinGW compiled example library for the Win64 target.

%package -n mingw64-example-static
Summary: Static version of the MinGW Win64 compiled example library
Requires: mingw64-example = %{version}-%{release}

%description -n mingw64-example-static
Static version of the MinGW Win64 compiled example library.


%{?mingw_debug_package}


%prep
%autosetup -p1 -n example-%{version}


%build
%mingw_configure --enable-static --enable-shared --enable-foo
%mingw_make_build


%install
%mingw_make_install

# Libtool files don't need to be bundled
find %{buildroot} -name "*.la" -delete

%mingw_find_lang example


# Note: there should be no %%files section for the main package!

# Static subpackages are optional (as mentioned earlier)

# Win32
%files -n mingw32-example -f mingw32-example.lang
%{mingw32_bindir}/libexample-0.dll
%{mingw32_includedir}/example/
%{mingw32_libdir}/libexample.dll.a
%{mingw32_libdir}/pkgconfig/example.pc

%files -n mingw32-example-static
%{mingw32_libdir}/libexample.a

# Win64
%files -n mingw64-example -f mingw64-example.lang
%{mingw64_bindir}/libexample-0.dll
%{mingw64_includedir}/example/
%{mingw64_libdir}/libexample.dll.a
%{mingw64_libdir}/pkgconfig/example.pc

%files -n mingw64-example-static
%{mingw64_libdir}/libexample-0.a


%changelog
* Sun Apr 15 2012 Erik van Pienbroek <epienbro@fedoraproject.org> - 1.0.0-1
- Initial release