Рекомендации по упаковке для кросс-компиляторов 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.
|
Используется для исходного пакета и имени RPM spec (только там, где выбран отдельный подход к упаковке) |
|
Используется для пакетов, собранных для Win32 со средой выполнения MSVCRT |
|
Используется для пакетов, собранных для Win64 со средой выполнения MSVCRT |
|
Используется для пакетов, собранных для Win64 со средой выполнения UCRT |
Базовые пакеты
Базовые пакеты предоставляют корневую файловую систему, базовые библиотеки, binutils (базовые программы, такие как 'strip', 'ld' и т. д.), компилятор (gcc) и API Win32/Win64. Пакеты могут зависеть от одного или нескольких из них. В частности, почти все пакеты должны иметь BuildRequire mingw32-filesystem, mingw64-filesystem, mingw32-gcc и mingw64-gcc.
|
Основная структура каталогов файловой системы и RPM-макросы для spec-файлов. Эквивалент RPM 'filesystem' |
|
Кросс-компилированные binutils (утилиты, такие как 'strip', 'as', 'ld'), которые понимают исполняемые файлы Windows и DLL. Эквивалент RPM 'binutils' |
|
Коллекция компиляторов GNU. Компиляторы для C и C++, которые кросс-компилируют под цель Windows. Эквивалент RPM gcc |
|
Базовые библиотеки для основной среды выполнения и разработки MinGW. Эквивалент RPM 'glibc' |
|
API Win32 и Win64. Бесплатная (общественное достояние) реализация заголовочных файлов, необходимых для компоновки с API Win32 и Win64. Нет прямого эквивалента в базовой Fedora — ближайший — glibc-devel |
Сборка для нескольких целей
Цель фреймворка MinGW — предоставить простой способ для мейнтейнеров пакетов собирать свои пакеты для нескольких целей, используя один .spec-файл. Чтобы помочь разработчикам в этом, было разработано несколько RPM-макросов, которые являются частью пакета mingw-filesystem. Эти RPM-макросы будут объяснены далее в этих рекомендациях.
По умолчанию поддержка MinGW будет собрана как для целей Win32, так и Win64 со средой выполнения MSVCRT. Сборка цели Win64 со средой выполнения UCRT64 пока не включена по умолчанию.
Когда пакет может быть собран только для подмножества этих целей, это можно указать, задав один или несколько из следующих параметров:
|
Не собирать для цели Win32 со средой выполнения MSVCRT |
|
Не собирать для цели Win64 со средой выполнения MSVCRT |
|
Не собирать для цели 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
Want to help? Learn how to contribute to Fedora Docs ›