From Fedora Project Wiki
(markup)
 
(71 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= Packaging Guidelines for cross compiler framework =
= Packaging Guidelines for MinGW Cross Compilers =


{{admon/warning|Based on the MinGW guidelines|These draft guidelines are based on the [[Packaging:MinGW|MinGW guidelines]] and will obsolete them}}
{{admon/important|Updated Guidelines|These guidelines apply to all current Fedora releases. For RHEL-5 and RHEL-6 the old guidelines still apply which can be be found here: [[Packaging:MinGW_Old]] }}


= Introduction =
= Introduction =


The Fedora MinGW project's mission is to provide an excellent
The Fedora MinGW project's mission is to provide an excellent development environment for Fedora users who wish to cross-compile their programs to run on Windows, minimizing the need to use Windows at all.  In the past developers have had to port and compile all of the libraries and tools they have needed, and this huge effort has happened independently many times over.  We aim to eliminate duplication of work for application developers by providing a range of libraries and development tools which have already been ported to the MinGW cross-compiler environment.  This means that developers will not need to recompile the application stack themselves, but can concentrate just on the changes needed to their own application.
development environment for Fedora users who wish to cross-compile
their programs to run on Windows, minimizing the need to use Windows
at all.  In the past developers have had to port and compile all of
the libraries and tools they have needed, and this huge effort has
happened independently many times over.  We aim to eliminate
duplication of work for application developers by providing a range of
libraries and development tools which have already been ported to the
cross-compiler environment.  This means that developers will not need
to recompile the application stack themselves, but can concentrate
just on the changes needed to their own application.


As of Fedora 15 a set of RPM macros and packages have been introduced
As of Fedora 17 a set of RPM macros and packages have been introduced which help packagers compile binaries for multiple targets. The targets Win32 and Win64 are supported.
which help packagers compile binaries for multiple targets. Initially, the
targets Win32 and Win64 will be supported. However support for other
targets (such as Mac OS X) will become easy to implement.
 
Note that when deciding to contribute a new cross compiled library to
the Fedora project, it is advisable to start with our example specfile:
http://hg.et.redhat.com/misc/fedora-mingw--devel/?fl=7e95a9b24e2d;file=example/mingw32-example.spec


= Track Fedora native package versions =
= Track Fedora native package versions =


In general terms, cross-compiled versions of packages which already
In general terms, cross-compiled MinGW versions of packages which are already natively available in Fedora, should follow the native Fedora package as closely as possible. This means they should stay at the same version, include all the same patches as the native
natively available in Fedora, should follow the native Fedora
package as closely as possible. This means they should stay at
the same version, include all the same patches as the native
Fedora package, and be built with the same configuration options.
Fedora package, and be built with the same configuration options.


The MinGW SIG have written an RPM comparison tool which makes it possible
The MinGW SIG have written an RPM comparison tool which makes it possible to compare cross compiled MinGW packages with the Fedora native packages, in order to determine whether versions, patches and configuration are aligned.
to compare cross compiled packages with the Fedora native packages, in
order to determine whether versions, patches and configuration are
aligned.


= Follow Fedora policy =
= Follow Fedora policy =


Cross compiled packages must follow Fedora policy, except where noted in this
Cross compiled MinGW packages must follow Fedora policy, except where noted in this document. Cross compiled packages go through the same review process, GIT admin process etc as other Fedora packages.
document. Cross compiled packages go through the same review process, GIT
admin process etc as other Fedora packages.


= Package naming =
= Package naming =


Packages should be named by prefixing the upstream package name
MinGW packages require special naming to denote the appropriate CPU architecture the binaries have been built for. There should '''never''' be a package prefixed with <code>mingw-</code> output during a build. The <code>mingw-</code> prefix is exclusive for RPM spec file names and the source RPM file name. The CPU architecture specific packages are created by sections with <code>%files -n mingw32-foo</code> or <code>%files -n mingw64-foo</code>.
with one of the following terms:
 
{|
{|
| <code>cross-</code> || Used for packages which can be built for multiple targets
| <code>mingw-</code> || Used for source package and RPM spec name
|-
| <code>mingw-</code> || Used for packages which can be built for both Win32 and Win64 but not for other targets
|-
|-
| <code>mingw32-</code> || Used for packages which can only be built for Win32
| <code>mingw32-</code> || Used for packages which are built for Win32
|-
|-
| <code>mingw64-</code> || Used for packages which can only be built for Win64
| <code>mingw64-</code> || Used for packages which are built for Win64
|}
|}
Examples:
The [http://www.gtk.org glib2] package can be built for both Win32, Win64 as well as other targets (such as Mac OS X), hence it should be named <code>cross-glib2</code>
The [http://code.google.com/p/win-iconv/ win-iconv] package only supports Win32 and Win64, hence it should be named <code>mingw-win-iconv</code>


= Base packages =
= Base packages =


The base packages provide a root filesystem, base libraries, binutils
The base packages provide a root filesystem, base libraries, binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc) and the Win32/Win64 API.  Packages may need to depend on one or more of these. In particular, almost all packages should BuildRequire <code>mingw32-filesystem</code>, <code>mingw64-filesystem</code>, <code>mingw32-gcc</code> and <code>mingw64-gcc</code>. The correct Requires flags will get added automatically when the <code>%{?mingw_package_header}</code> macro is mentioned in the spec file (as will be described later on in these guidelines)
(basic programs like 'strip', 'ld' etc), the compiler (gcc) and the
Win32/Win64 API.  Packages may need to depend on one or more of these.  
In particular, almost any conceivable package should depend on
<code>cross-filesystem</code> and <code>cross-gcc</code>.


{|
{|
| <code>cross-filesystem</code> || Core filesystem directory layout, and RPM macros for spec files.  Equivalent to 'filesystem' RPM
| <code>mingw32-filesystem</code> / <code>mingw64-filesystem</code> || Core filesystem directory layout, and RPM macros for spec files.  Equivalent to 'filesystem' RPM
|-
|-
| <code>cross-binutils</code> || Cross-compiled binutils (utilities like 'strip', 'as', 'ld') which understand Windows executables and DLLs.  Equivalent to 'binutils' RPM
| <code>mingw32-binutils</code> / <code>mingw64-binutils</code> || Cross-compiled binutils (utilities like 'strip', 'as', 'ld') which understand Windows executables and DLLs.  Equivalent to 'binutils' RPM
|-
|-
| <code>cross-gcc</code> || GNU compiler collection.  Compilers for C and C++ which cross-compile to a Windows target.  Equivalent to gcc RPM
| <code>mingw32-gcc</code> / <code>mingw64-gcc</code> || GNU compiler collection.  Compilers for C and C++ which cross-compile to a Windows target.  Equivalent to gcc RPM
|-
|-
| <code>mingw-crt</code> || Base libraries for core MinGW runtime & development environment.  Equivalent to 'glibc' RPM
| <code>mingw32-crt</code> / <code>mingw64-crt</code> || Base libraries for core MinGW runtime & development environment.  Equivalent to 'glibc' RPM
|-
|-
| <code>mingw-headers</code> || Win32 and Win64 API.  A free (public domain) reimplementation of the header files required to link to the Win32 and Win64 API.  No direct equivalent in base Fedora - glibc-devel is closest
| <code>mingw32-headers</code> / <code>mingw64-headers</code> || Win32 and Win64 API.  A free (public domain) reimplementation of the header files required to link to the Win32 and Win64 API.  No direct equivalent in base Fedora - glibc-devel is closest
|}
|}


= Build for multiple targets =
= Build for multiple targets =


The goal of the cross compiler framework is to provide an easy way for package maintainers
The goal of the MinGW framework is to provide an easy way for package maintainers to build their packages for multiple targets using one .spec file. To aid developers in this several RPM macros have been developed which are part of the mingw-filesystem package.
to build their packages for multiple targets using one .spec file. To aid developers in
this several RPM macros have been developed which are part of the cross-filesystem package.
These RPM macros will be explained later on in these guidelines.
These RPM macros will be explained later on in these guidelines.


Several RPM macros depend on the package name minus the prefix, so each package must
By default a MinGW package will be built for both the Win32 and Win64 targets.
contain <code>%global _cross_pkg_name foo</code> (where <code>foo</code> is the name of the package, for example glib2)


To indicate which targets should be build, the package must contain at least one of the following lines:
When a package can only be built for either one of these targets this can be indicated by setting one of these:
{|
{|
| <code>%global _cross_build_win32 1</code> || Build for the Win32 target
| <code>%global mingw_build_win32 0</code> || Don't build for the Win32 target
|-
|-
| <code>%global _cross_build_win64 1</code> || Build for the Win64 target
| <code>%global mingw_build_win64 0</code> || Don't build for the Win64 target
|}
|}


= One source RPM, per-target binary RPMs =
= One source RPM, separate binary RPMs per-target =
 
Each cross compiled package which builds binaries for a specific target should put the binaries
for that target in a separate subpackage. So if a package <code>foo</code> builds binaries for
the Win32 and Win64 targets, then the source RPM should provide two subpackages named <code>mingw32-foo</code> and <code>mingw64-foo</code>.


The main package (<code>cross-foo</code> in our example) must have <code>Requires: xxx</code> tags for all the targets.
Each cross compiled MinGW package which builds binaries for a specific target should put the binaries for that target in a separate subpackage. So if a package <code>foo</code> builds binaries for the Win32 and Win64 targets, then the source RPM should provide two subpackages named <code>mingw32-foo</code> and <code>mingw64-foo</code>.
To aid in this, the RPM macro <code>%{?_cross_default_requires}</code> should be added to the spec file


This means that a spec file must contains %package and %files sections for all the targets.
This means that a spec file must contains %package and %files sections for all the targets.  
We're still looking for methods to simplify this as it currently introduces quite an amount of duplication


If a package contains translations then all calls to the <code>%find_lang</code> must be replaced by <code>%_cross_find_lang</code>.
If a package contains translations then all calls to the <code>%find_lang</code> must be replaced by <code>%mingw_find_lang</code>.
This causes all translation filelists to be split in per-target filelists.
This causes all translation filelists to be split in per-target filelists.
For example: when a spec file contains something like this:
For example: when a spec file contains something like this:
%global _cross_build_win32 1
<pre>
%global _cross_build_win64 1
<snip>  
  %install
  %install
  <snip>
  <snip>
  %_cross_find_lang foo
  %mingw_find_lang foo
</pre>
then two files will get created named <code>mingw32-foo.lang</code> and <code>mingw64-foo.lang</code>.
then two files will get created named <code>mingw32-foo.lang</code> and <code>mingw64-foo.lang</code>.
These file lists can be included in the %files section for the targets:
These file lists can be included in the %files section for the targets:
<pre>
  %files -n mingw32-foo -f mingw32-foo.lang
  %files -n mingw32-foo -f mingw32-foo.lang
  <snip>
  <snip>
  %files -n mingw64-foo -f mingw64-foo.lang
  %files -n mingw64-foo -f mingw64-foo.lang
</pre>


= Filesystem layout =
= Filesystem layout =
Line 135: Line 92:
   |  +- rpm
   |  +- rpm
   |      |
   |      |
   |      +- macros.cross
   |      +- macros.mingw
   |      +- macros.mingw32
   |      +- macros.mingw32
   |      +- macros.mingw64
   |      +- macros.mingw64
Line 141: Line 98:
   +- usr
   +- usr
       |
       |
       +- bin  - Links to cross compiler toolchain
       +- bin  - Links to MinGW cross compiler toolchain
       |  |
       |  |
       |  +- i686-w64-mingw32-cpp
       |  +- i686-w64-mingw32-cpp
Line 155: Line 112:
       |  +- rpm
       |  +- rpm
       |      |
       |      |
       |      +- cross-find-debuginfo.sh - extract debug information from Win32 and Win64 binaries
       |      +- mingw-find-debuginfo.sh - extract debug information from Win32 and Win64 binaries
       |      +- cross-find-lang.sh - generates per-target file lists containing translations
       |      +- mingw-find-lang.sh - generates per-target file lists containing translations
       |      +- cross-find-provides.sh - extra DLL names
       |      +- mingw-find-provides.sh - extra DLL names
       |      +- cross-find-requires.sh - discover required DLL names
       |      +- mingw-find-requires.sh - discover required DLL names
       |
       |
       +- i686-w64-mingw32  - root of mingw toolchain and binaries for the Win32 target - see next diagram
       +- i686-w64-mingw32  - root of mingw toolchain and binaries for the Win32 target - see next diagram
Line 177: Line 134:
   +- lib  - Binutils toolchain support libraries / files for the target
   +- lib  - Binutils toolchain support libraries / files for the target
   |
   |
   +- sys-root  - root for cross compiled binaries
   +- sys-root  - root for cross compiled MinGW binaries
       |
       |
       +- mingw
       +- mingw
           |
           |
           +- bin    - cross-compiled binaries & runtime DLL parts
           +- bin    - cross-compiled MinGW binaries & runtime DLL parts
           +- etc    - configuration files
           +- etc    - configuration files
           +- include - include files for cross compiled libs
           +- include - include files for cross compiled MinGW libs
           +- lib    - cross-compiled static libraries & linktime DLL parts
           +- lib    - cross-compiled static MinGW libraries & linktime DLL parts
           |  |
           |  |
           |  +- pkgconfig  - pkg-config definitions for libraries
           |  +- pkgconfig  - pkg-config definitions for libraries
Line 194: Line 151:
= Filenames of the cross-compilers and binutils =
= Filenames of the cross-compilers and binutils =


The cross-compilers and binutils are Fedora binaries and are therefore
The MinGW cross-compilers and binutils are Fedora binaries and are therefore placed in <code>%{_bindir}</code> (ie. <code>/usr/bin</code>) according to the FHS and Fedora guidelines.
placed in <code>%{_bindir}</code> (ie. <code>/usr/bin</code>)
according to the FHS and Fedora guidelines.
 
The cross-compilers and binutils which generate i686 binaries for Windows are named:


The MinGW cross-compilers and binutils which generate i686 binaries for Windows are named:
<pre>
  %{_bindir}/i686-w64-mingw32-gcc
  %{_bindir}/i686-w64-mingw32-gcc
  %{_bindir}/i686-w64-mingw32-g++
  %{_bindir}/i686-w64-mingw32-g++
Line 206: Line 161:
  %{_bindir}/i686-w64-mingw32-strip
  %{_bindir}/i686-w64-mingw32-strip
  etc.
  etc.
</pre>


The same binaries are present in
The same binaries are present in
<code>%{_prefix}/i686-w64-mingw32/bin</code> without any prefix in the
<code>%{_prefix}/i686-w64-mingw32/bin</code> without any prefix in the
name, ie:
name, ie:
 
<pre>
  %{_prefix}/i686-w64-mingw32/bin/gcc
  %{_prefix}/i686-w64-mingw32/bin/gcc
  %{_prefix}/i686-w64-mingw32/bin/g++
  %{_prefix}/i686-w64-mingw32/bin/g++
Line 217: Line 173:
  %{_prefix}/i686-w64-mingw32/bin/strip
  %{_prefix}/i686-w64-mingw32/bin/strip
  etc.
  etc.
</pre>


The same also applies for the x86_64 target. This target uses 'x86_64-w64-mingw32' as prefix instead of 'i686-w64-mingw32'
The same also applies for the x86_64 target. This target uses 'x86_64-w64-mingw32' as prefix instead of 'i686-w64-mingw32'
Line 222: Line 179:
= Naming of the root filesystem =
= Naming of the root filesystem =


The root filesystem contains Windows executables and DLLs and any other Windows-only
The root filesystem contains Windows executables and DLLs and any other Windows-only files.  It is necessary both because we need to store Windows libraries in order to link further libraries which depend on them, and also because MinGW requires a root filesystem location.  
files.  It is necessary both because we need to store Windows libraries in order to
link further libraries which depend on them, and also because MinGW requires a
root filesystem location.  


The location for Win32 target is provided by the macro:
The location for Win32 target is provided by the macro:
  %{_mingw32_sysroot}  %{_prefix}/i686-w64-mingw32/sys-root
<pre>
  %{mingw32_sysroot}  %{_prefix}/i686-w64-mingw32/sys-root
</pre>
And the Win64 target is provided by the macro:
And the Win64 target is provided by the macro:
  %{_mingw64_sysroot}  %{_prefix}/x86_64-w64-mingw32/sys-root
<pre>
  %{mingw64_sysroot}  %{_prefix}/x86_64-w64-mingw32/sys-root
</pre>


= Standard mingw RPM macros =
= Standard mingw RPM macros =


The <code>cross-filesystem</code> package provides a number of
The <code>mingw-filesystem</code> package provides a number of convenience macros for the cross compiled sysroot directories, and
convenience macros for the cross compiled sysroot directories, and
toolchain. It is mandatory to use these macros in all MinGW cross compiled packages submitted to Fedora.
toolchain. It is mandatory to use these macros in all cross compiled
packages submitted to Fedora.


== Toolchain macros ==
== Toolchain macros ==
Line 245: Line 201:
Generic macros:
Generic macros:
{|
{|
| _cross_cmake  || || Call the cmake binary for all the configured targets (_cross_build_win32/_cross_build_win64)
| <b>Macro</b> || <b>Available in<br>mingw-filesystem</b> || <b>Explanation</b>
|-
|-
| _cross_configure || || Call the configure command for all the configured targets (_cross_build_win32/_cross_build_win64)
| mingw_cmake  || >= 95 || Call the cmake binary for all the configured targets
|-
|-
| _cross_make  || || Call the 'make' command for all the configured targets (_cross_build_win32/_cross_build_win64)
| mingw_cmake_kde4 || >= 95 || Call the cmake binary for all the configured targets with KDE4 specific parameters set
|-
|-
| _cross_make_install  || || Call the 'make install' command for all the configured targets (_cross_build_win32/_cross_build_win64)
| mingw_configure || >= 95 || Call the configure command for all the configured targets
|-
|-
| _cross_objcopy || mingw-objcopy || cross compiler 'objcopy' binary (which supports both Win32 and Win64 binaries)
| mingw_make  || >= 95 || Call the 'make' command for all the configured targets
|-
|-
| _cross_objdump || mingw-objdump || cross compiler 'objdump' binary (which supports both Win32 and Win64 binaries)
| mingw_objcopy || >= 95 || cross compiler 'objcopy' binary (which supports both Win32 and Win64 binaries)
|-
|-
| _cross_strip || mingw-strip || cross compiler 'strip' binary (which supports both Win32 and Win64 binaries)
| mingw_objdump || >= 95 || cross compiler 'objdump' binary (which supports both Win32 and Win64 binaries)
|-
| mingw_qmake_qt4 || >= 95 || Call the Qt4 qmake binary for all configured targets (requires mingw32-qt-qmake and/or mingw64-qt-qmake to be installed)
|-
| mingw_qmake_qt5 || >= 96 || Call the Qt5 qmake binary for all configured targets (requires mingw32-qt5-qmake and/or mingw64-qt5-qmake to be installed)
|-
| mingw_strip || >= 95 || cross compiler 'strip' binary (which supports both Win32 and Win64 binaries)
|}
|}


Line 263: Line 225:
Win32 specific macros:
Win32 specific macros:
{|
{|
| _mingw32_ar || i686-w64-mingw32-ar || cross compiler 'ar' binary
| <b>Macro</b> || <b>Available in<br>mingw32-filesystem</b> || <b> Value</b> || <b>Explanation</b>
|-
| mingw32_ar || >= 95 || i686-w64-mingw32-ar || cross compiler 'ar' binary
|-
|-
| _mingw32_cc || i686-w64-mingw32-gcc || cross compiler 'gcc' binary
| mingw32_cc || >= 95 || i686-w64-mingw32-gcc || cross compiler 'gcc' binary
|-
|-
| _mingw32_cflags || -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -mms-bitfields|| Default compiler flags for C/C++ binaries
| mingw32_cflags || >= 95 || -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 || Default compiler flags for C/C++ binaries
|-
|-
| _mingw32_cmake ||  || Call the cmake binary for the Win32 target
| mingw32_cmake || >= 95 ||  || Call the cmake binary for the Win32 target
|-
|-
| _mingw32_configure ||  || standard invocation for autotools 'configure' scripts
| mingw32_configure || >= 95 ||  || standard invocation for autotools 'configure' scripts
|-
|-
| _mingw32_cpp || i686-w64-mingw32-gcc -E || cross compiler 'cpp' binary
| mingw32_cpp || >= 95 || i686-w64-mingw32-gcc -E || cross compiler 'cpp' binary
|-
|-
| _mingw32_env ||  || Set the correct environment variables for the Win32 target
| mingw32_env || >= 95 ||  || Set the correct environment variables for the Win32 target
|-
|-
| _mingw32_host || i686-w64-mingw32  || Host platform for build
| mingw32_host || >= 95 || i686-w64-mingw32  || Host platform for build
|-
|-
| _mingw32_objcopy ||  i686-w64-mingw32-objcopy || cross compiler 'objcopy' binary
| mingw32_objcopy || >= 95 ||  i686-w64-mingw32-objcopy || cross compiler 'objcopy' binary
|-
|-
| _mingw32_objdump || i686-w64-mingw32-objdump || cross compiler 'objdump' binary
| mingw32_objdump || >= 95 || i686-w64-mingw32-objdump || cross compiler 'objdump' binary
|-
|-
| _mingw32_pkg_config || || Call the pkg-config command for the Win32 target
| mingw32_pkg_config || >= 95 || i686-w64-mingw32-pkg-config || Call the pkg-config command for the Win32 target
|-
|-
| _mingw32_ranlib || i686-w64-mingw32-ranlib || cross compiler 'ranlib' binary
| mingw32_qmake_qt4 || >= 95 || mingw32-qmake-qt4  || Call the Qt4 qmake command for the Win32 target
|-
|-
| _mingw32_strip || i686-w64-mingw32-strip || cross compiler 'strip' binary
| mingw32_qmake_qt5 || >= 96 || mingw32-qmake-qt5  || Call the Qt5 qmake command for the Win32 target
|-
|-
| _mingw32_target || i686-w64-mingw32 || Target platform for build
| mingw32_ranlib || >= 95 || i686-w64-mingw32-ranlib || cross compiler 'ranlib' binary
|-
| mingw32_strip || >= 95 || i686-w64-mingw32-strip || cross compiler 'strip' binary
|-
| mingw32_target || >= 95 || i686-w64-mingw32 || Target platform for build
|}
|}


Line 295: Line 263:
Win64 specific macros:
Win64 specific macros:
{|
{|
| _mingw64_ar || x86_64-w64-mingw32-ar || cross compiler 'ar' binary
| <b>Macro</b> || <b>Available in<br>mingw64-filesystem</b> || <b> Value</b> || <b>Explanation</b>
|-
| mingw64_ar || >= 95 || x86_64-w64-mingw32-ar || cross compiler 'ar' binary
|-
| mingw64_cc || >= 95 || x86_64-w64-mingw32-gcc || cross compiler 'gcc' binary
|-
| mingw64_cflags  || >= 95 || -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 || Default compiler flags for C/C++ binaries
|-
|-
| _mingw64_cc || x86_64-w64-mingw32-gcc || cross compiler 'gcc' binary
| mingw64_cmake  || >= 95 || || Call the cmake binary for the Win64 target
|-
|-
| _mingw64_cflags  || -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -mms-bitfields|| Default compiler flags for C/C++ binaries
| mingw64_configure || >= 95 ||  || standard invocation for autotools 'configure' scripts
|-
|-
| _mingw64_cmake  || || Call the cmake binary for the Win64 target
| mingw64_cpp || >= 95 || x86_64-w64-mingw32-gcc -E || cross compiler 'cpp' binary
|-
|-
| _mingw64_configure ||  || standard invocation for autotools 'configure' scripts
| mingw64_env  || >= 95 ||  || Set the correct environment variables for the Win64 target
|-
|-
| _mingw64_cpp || x86_64-w64-mingw32-gcc -E || cross compiler 'cpp' binary
| mingw64_host || >= 95 || x86_64-w64-mingw32 || Host platform for build
|-
|-
| _mingw64_env  || || Set the correct environment variables for the Win64 target
| mingw64_objcopy || >= 95 ||   x86_64-w64-mingw32-objcopy || cross compiler 'objcopy' binary
|-
|-
| _mingw64_host || x86_64-w64-mingw32 || Host platform for build
| mingw64_objdump || >= 95 || x86_64-w64-mingw32-objdump || cross compiler 'objdump' binary
|-
|-
| _mingw64_objcopy ||   x86_64-w64-mingw32-objcopy || cross compiler 'objcopy' binary
| mingw64_pkg_config  || >= 95 || x86_64-w64-mingw32-pkg-config || Call the pkg-config command for the Win64 target
|-
|-
| _mingw64_objdump || x86_64-w64-mingw32-objdump || cross compiler 'objdump' binary
| mingw64_qmake_qt4 || >= 95 || mingw64-qmake-qt4  || Call the Qt4 qmake command for the Win64 target
|-
|-
| _mingw64_pkg_config  ||  || Call the pkg-config command for the Win64 target
| mingw64_qmake_qt5 || >= 96 || mingw64-qmake-qt5 || Call the Qt5 qmake command for the Win64 target
|-
|-
| _mingw64_ranlib || x86_64-w64-mingw32-ranlib || cross compiler 'ranlib' binary
| mingw64_ranlib || >= 95 || x86_64-w64-mingw32-ranlib || cross compiler 'ranlib' binary
|-
|-
| _mingw64_strip || x86_64-w64-mingw32-strip || cross compiler 'strip' binary  
| mingw64_strip || >= 95 || x86_64-w64-mingw32-strip || cross compiler 'strip' binary  
|-
|-
| _mingw64_target || x86_64-w64-mingw32 || Target platform for build
| mingw64_target || >= 95 || x86_64-w64-mingw32 || Target platform for build
|}
|}


Line 330: Line 304:
For the Win32 target:
For the Win32 target:
{|
{|
|_mingw32_bindir || %{_mingw32_prefix}/bin || Location of Windows executables.
| mingw32_bindir || %{mingw32_prefix}/bin || Location of Windows executables.
|-
|-
|_mingw32_datadir || %{_mingw32_prefix}/share || Shared data used under Windows.
| mingw32_datadir || %{mingw32_prefix}/share || Shared data used under Windows.
|-
|-
|_mingw32_docdir || %{_mingw32_prefix}/share/doc || Documentation.
| mingw32_docdir || %{mingw32_prefix}/share/doc || Documentation.
|-
|-
|_mingw32_infodir || %{_mingw32_prefix}/share/info || Info files (see note below).
| mingw32_infodir || %{mingw32_prefix}/share/info || Info files (see note below).
|-
|-
|_mingw32_includedir || %{_mingw32_prefix}/include || Header files used when cross-compiling for Windows.
| mingw32_includedir || %{mingw32_prefix}/include || Header files used when cross-compiling for Windows.
|-
|-
|_mingw32_libdir || %{_mingw32_prefix}/lib || Windows libraries (see sections below).
| mingw32_libdir || %{mingw32_prefix}/lib || Windows libraries (see sections below).
|-
|-
|_mingw32_libexecdir || %{_mingw32_prefix}/libexec ||
| mingw32_libexecdir || %{mingw32_prefix}/libexec ||
|-
|-
|_mingw32_mandir || %{_mingw32_prefix}/share/man || Man pages (see note below).
| mingw32_mandir || %{mingw32_prefix}/share/man || Man pages (see note below).
|-
|-
|_mingw32_prefix || %{_mingw32_sysroot}/mingw || Windows equivalent of %{_prefix}, required by MinGW.
| mingw32_prefix || %{mingw32_sysroot}/mingw || Windows equivalent of %{_prefix}, required by MinGW.
|-
|-
|_mingw32_sbindir || %{_mingw32_prefix}/sbin ||
| mingw32_sbindir || %{mingw32_prefix}/sbin ||
|-
|-
|_mingw32_sysconfdir || %{_mingw32_prefix}/etc || Configuration files used when running under Windows.
| mingw32_sysconfdir || %{mingw32_prefix}/etc || Configuration files used when running under Windows.
|-
|-
|_mingw32_sysroot || %{_prefix}/i686-w64-mingw32/sys-root || Windows system root.
| mingw32_sysroot || %{_prefix}/i686-w64-mingw32/sys-root || Windows system root.
|}
|}


Line 358: Line 332:
For the Win64 target:
For the Win64 target:
{|
{|
|_mingw64_bindir || %{_mingw64_prefix}/bin || Location of Windows executables.
| mingw64_bindir || %{mingw64_prefix}/bin || Location of Windows executables.
|-
|-
|_mingw64_datadir || %{_mingw64_prefix}/share || Shared data used under Windows.
| mingw64_datadir || %{mingw64_prefix}/share || Shared data used under Windows.
|-
|-
|_mingw64_docdir || %{_mingw64_prefix}/share/doc || Documentation.
| mingw64_docdir || %{mingw64_prefix}/share/doc || Documentation.
|-
|-
|_mingw64_infodir || %{_mingw64_prefix}/share/info || Info files (see note below).
| mingw64_infodir || %{mingw64_prefix}/share/info || Info files (see note below).
|-
|-
|_mingw64_includedir || %{_mingw64_prefix}/include || Header files used when cross-compiling for Windows.
| mingw64_includedir || %{mingw64_prefix}/include || Header files used when cross-compiling for Windows.
|-
|-
|_mingw64_libdir || %{_mingw64_prefix}/lib || Windows libraries (see sections below).
| mingw64_libdir || %{mingw64_prefix}/lib || Windows libraries (see sections below).
|-
|-
|_mingw64_libexecdir || %{_mingw64_prefix}/libexec ||
| mingw64_libexecdir || %{mingw64_prefix}/libexec ||
|-
|-
|_mingw64_mandir || %{_mingw64_prefix}/share/man || Man pages (see note below).
| mingw64_mandir || %{mingw64_prefix}/share/man || Man pages (see note below).
|-
|-
|_mingw64_prefix || %{_mingw64_sysroot}/mingw || Windows equivalent of %{_prefix}, required by MinGW.
| mingw64_prefix || %{mingw64_sysroot}/mingw || Windows equivalent of %{_prefix}, required by MinGW.
|-
|-
|_mingw64_sbindir || %{_mingw64_prefix}/sbin ||
| mingw64_sbindir || %{mingw64_prefix}/sbin ||
|-
|-
|_mingw64_sysconfdir || %{_mingw64_prefix}/etc || Configuration files used when running under Windows.
| mingw64_sysconfdir || %{mingw64_prefix}/etc || Configuration files used when running under Windows.
|-
|-
|_mingw64_sysroot || %{_prefix}/x86_64-w64-mingw32/sys-root || Windows system root.
| mingw64_sysroot || %{_prefix}/x86_64-w64-mingw32/sys-root || Windows system root.
|}
|}


Line 388: Line 362:
If one has to write this all out in a spec file then it will lead to duplicate code.
If one has to write this all out in a spec file then it will lead to duplicate code.
To reduce the amount of duplication, several RPM macros have been introduced to help with the compilation.
To reduce the amount of duplication, several RPM macros have been introduced to help with the compilation.
These macros are <code>%{_cross_configure}</code>, <code>%{_cross_cmake}</code>, <code>%{_cross_make}</code> and <code>%{_cross_make_install}</code>
These macros are <code>%mingw_configure</code>, <code>%mingw_cmake</code>, <code>%mingw_cmake_kde4</code>, <code>%mingw_qmake_qt4</code>, <code>%mingw_qmake_qt5</code> and <code>%mingw_make</code>


These macros use out of source compilation to build binaries for all the targets.
These macros use out of source compilation to build binaries for all the targets.
Line 394: Line 368:
Packages which don't support out of source compilation may require a different approach like performing everything in the %install phase.
Packages which don't support out of source compilation may require a different approach like performing everything in the %install phase.
If you happen to stumble across a package which requires a different approach feel free to contact us on the Fedora MinGW mailing list
If you happen to stumble across a package which requires a different approach feel free to contact us on the Fedora MinGW mailing list
There's a difference in the behavior between these macros and the original <code>%{_mingw32_xxx}</code> macros.
As all commands will get executed multiple times (once for each target) one has to indicate what arguments should be used.
For example, with the original Fedora MinGW toolchain you could do:
%{_mingw32_configure} --disable-xlib --enable-win32
This has to be changed to something like this:
%{_cross_configure "--disable-xlib" "--enable-win32"}
The quotes mentioned above are mandatory! If you forget them then rpmbuild will fail or the arguments might not get passed to the ./configure calls.
Also note that the '}' character needs to be placed after all the arguments


Some packages need to be built multiple times for each target. Examples of this are packages which have to be built once for a static version and once for a shared version.
Some packages need to be built multiple times for each target. Examples of this are packages which have to be built once for a static version and once for a shared version.
Such packages can add a custom suffix to the build directory used.
Such packages can add a custom suffix to the build directory used.
Say you've got something like below:
Say you've got something like below:
<pre>
  mkdir build_shared
  mkdir build_shared
  pushd build_shared
  pushd build_shared
  %{_mingw32_configure} --enable-shared
  %{mingw32_configure} --enable-shared
  popd
  popd
  mkdir build_static
  mkdir build_static
  pushd build_static
  pushd build_static
  %{_mingw32_configure} --enable-static
  %{mingw32_configure} --enable-static
  popd
  popd
</pre>
This can be rewritten to something like this:
This can be rewritten to something like this:
  %{_cross_configure -s shared "--enable-shared"}
<pre>
  %{_cross_configure -s static "--enable-static"}
  MINGW_BUILDDIR_SUFFIX=shared %mingw_configure --enable-shared
  MINGW_BUILDDIR_SUFFIX=static %mingw_configure --enable-static
</pre>


Most packages used the command <code>make %{?_smp_mflags}</code> to build the package.
Most packages used the command <code>make %{?_smp_mflags}</code> to build the package.
In the cross compiler framework you have to use <code>%{_cross_make %{?_smp_mflags}}</code> to build the package for all configured targets
In the MinGW cross compiler framework you have to use <code>%mingw_make %{?_smp_mflags}</code> to build the package for all configured targets.
As with the <code>%{_cross_configure}</code> macro you can also use the </code>-s</code> argument to indicate a custom suffix to the build directory used
As with the <code>%mingw_configure</code> macro you can also use the MINGW_BUILDDIR_SUFFIX environment variable to indicate a custom suffix to the build directory used


To install the package the command <code>make install DESTDIR=$RPM_BUILD_ROOT</code> was used in almost all cases.
To install the package the command <code>make install DESTDIR=$RPM_BUILD_ROOT</code> was used in almost all cases.
This can be rewritten to <code>%{_cross_make_install DESTDIR=$RPM_BUILD_ROOT}</code> to install the package for all configured targets
This can be rewritten to <code>%mingw_make install DESTDIR=$RPM_BUILD_ROOT</code> to install the package for all configured targets
The <code>-s</code> argument can also be used here
The environment variable MINGW_BUILDDIR_SUFFIX can also be used here


Some packages require some custom instructions before the files are ready to be packaged. Such code can remain as is. However, you may need to duplicate these instructions multiple times (for all configured targets).  
Some packages require some custom instructions before the files are ready to be packaged. Such code can remain as is. However, you may need to duplicate these instructions multiple times (for all configured targets).


= Dependencies =
= Dependencies =


If a package contains binaries which depend on a DLL provided by
If a package contains binaries which depend on a DLL provided by another package, these dependencies should be expressed in the form:
another package, these dependencies should be expressed in the form:
<pre>
 
  mingw32(foo.dll)
  mingw32(foo.dll)
</pre>
where <code>foo.dll</code> is the name of the DLL.  The name must be converted to lowercase because Windows binaries contain case
insensitive dependencies. The form 'mingw32(foo.dll)' should be used for Win32 binaries and the form 'mingw64(foo.dll)' for Win64 binaries.


where <code>foo.dll</code> is the name of the DLL. The name must be
Correct dependency generation is done automatically.  Packagers should start their spec files with this line:
converted to lowercase because Windows binaries contain case
<pre>
insensitive dependencies. The form 'mingw32(foo.dll)' should be used
%{?mingw_package_header}
for Win32 binaries and the form 'mingw64(foo.dll)' for Win64 binaries
</pre>
All binary packages should depend on <code>mingw32-filesystem</code> or <code>mingw64-filesystem</code> (depending on the files in the package). If the line mentioned above is used then it will be added automatically, so you don't have to add it yourself


Correct dependency generation is done automatically.  Packagers should
All specfiles should BuildRequire at least one of these (depending on the targets for which you want to build):
include these lines in all library packages:


  %global _use_internal_dependency_generator 0
  BuildRequires:  mingw32-filesystem >= minimum-version
  %global __find_requires %{_cross_findrequires}
  BuildRequires: mingw64-filesystem >= minimum-version
  %global __find_provides %{_cross_findprovides}


All binary packages should depend on <code>mingw32-filesystem</code> or
and any other BuildRequires that they need.
<code>mingw64-filesystem</code> (depending on the files in the package).
If the lines mentioned above are used then it will be added automatically, so
you don't have to add it yourself
 
All specfiles should BuildRequire at least:
 
BuildRequires:  cross-filesystem >= minimum-version


and any other BuildRequires that they need.
The <code>minimum-version</code> must be at least 95 or any later version which provides the functionality you need


= Build architecture =
= Build architecture =
Line 471: Line 434:
All libraries must be built as DLLs.
All libraries must be built as DLLs.


Because of the peculiarity of Windows, DLLs are stored in the
Because of the peculiarity of Windows, DLLs are stored in the <code>%{mingw32_bindir}</code> directory, along with a control file in
<code>%{_mingw32_bindir}</code> directory, along with a control file in
the <code>%{mingw32_libdir}</code> directory.  For example, for a library called <code>foo</code> there would be:
the <code>%{_mingw32_libdir}</code> directory.  For example, for a
<pre>
library called <code>foo</code> there would be:
%{mingw32_bindir}/foo.dll
%{mingw32_libdir}/foo.dll.a
</pre>
The <code>foo.dll</code> file is the main library, <code>foo.dll.a</code> is a stub linked to applications so they can find the library at runtime.  All of these files are required in those locations in order to link successfully. The <code>.dll</code> may contain a version number although not always (eg. <code>foo-0.dll</code>).
 
== Do not use %{mingw32_bindir}/* or %{mingw32_libdir}/* in %files section ==
 
The <code>%files</code> section must list DLLs and import libraries separately.  Packages must NOT use <code>%{mingw32_bindir}/*</code> or
<code>%{mingw32_libdir}/*</code>
 
The reason for this is that libtool is very fragile and will give up on building a DLL very easily.  Therefore we force the name of the DLL to be listed explicitly in the <code>%files</code> section in order to catch this during RPM builds.
 
== Stripping ==
 
Libraries and executables should be stripped.  This is done correctly and automatically if the spec file starts with this line:
 
<pre>
%{?mingw_package_header}
</pre>
 
{{admon/warning|%mingw_package_header|The %mingw_package_header macro sets the strip, objdump, and debuginfo generating commands appropriately for windows binaries.  Without this line Windows binaries may be corrupted by the automatic tasks that rpm performs on the built binaries.}}
 
== Debuginfo subpackage ==
 
Most binaries contain debugging symbols when the package gets built. To split the debugging symbols to a separate debuginfo package (as is done with native Fedora packages) the spec file must include these lines:
<pre>
%{?mingw_package_header}
[...]
%{?mingw_debug_package}
</pre>
 
The <code>%{?mingw_debug_package}</code> line must be placed after the <code>%description tag</code>. Otherwise spectool and other RPM tools may fail to function
 
= Executables (EXEs) =
 
Most libraries also provide executables. These can include executables which can be used to test or showcase the library in question (for example gtk3-demo.exe in mingw-gtk3).
Other examples are helper executables which are used by the library itself internally (for example gspawn-win32-helper.exe in mingw-glib2).
It is allowed to bundle all executables which built while compiling libraries in the binary rpms.
These executables have to be added to the main <code>mingw32-foo</code> / <code>mingw64-foo</code> subpackages (where the regular libraries and headers are also placed).
 
= Files which are already part of native packages =
 
There are various types of files which are simply duplicates of equivalent files found in Fedora native packages. These files should not be packaged in the MinGW package.
The following files don't need to be packaged in the MinGW package when their native counterpart already contains them:
* Man pages (<code>%{mingw32_mandir}</code> / <code>%{mingw64_mandir}</code>)
* Info files (<code>%{mingw32_infodir}</code> / <code>%{mingw64_infodir}</code>)
* Generic documentation (<code>%{mingw32_docdir}</code> / <code>%{mingw64_docdir}</code>)
* Autoconf files (<code>%{mingw32_datadir}/aclocal</code> / <code>%{mingw64_datadir}/aclocal</code>)
* gtk-doc files (<code>%{mingw32_datadir}/gtk-doc</code> / <code>%{mingw64_datadir}/gtk-doc</code>)
 
= Example Specfile =
<pre>
%{?mingw_package_header}
 
Name:          mingw-example
Version:        1.0.0
Release:        1%{?dist}
Summary:        MinGW compiled example library
 
License:        LGPLv2+
URL:            http://fedoraproject.org
Source0:        http://fedoraproject.org/example-%{version}.tar.bz2
 
BuildArch:      noarch
 
BuildRequires:  mingw32-filesystem >= 95
BuildRequires:  mingw32-gcc
BuildRequires:  mingw32-binutils
BuildRequires:  mingw32-gettext
BuildRequires:  mingw32-win-iconv
BuildRequires:  mingw32-zlib
 
BuildRequires:  mingw64-filesystem >= 95
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.


%{_mingw32_bindir}/foo.dll
# Win64
%{_mingw32_libdir}/foo.dll.a
%package -n mingw64-example
%{_mingw32_libdir}/foo.la
Summary:      MinGW compiled example library for the Win64 target


All files are required in those locations in order to link successfully.
%description -n mingw64-example
The <code>.dll</code> may contain a version number although not always
MinGW compiled example library for the Win64 target.
(eg. <code>foo-0.dll</code>).


== Do not use %{_mingw32_bindir}/* or %{_mingw32_libdir}/* in %files section ==
%package -n mingw64-example-static
Summary:      Static version of the MinGW Win64 compiled example library
Requires:      mingw64-example = %{version}-%{release}


The <code>%files</code> section must list DLLs separately. Packages
%description -n mingw64-example-static
must NOT use <code>%{_mingw32_bindir}/*</code> or
Static version of the MinGW Win64 compiled example library.
<code>%{_mingw32_libdir}/*</code>


The reason for this is that libtool is very fragile and will give up
on building a DLL very easily.  Therefore we force the name of the DLL
to be listed explicitly in the <code>%files</code> section in order to
catch this during RPM builds.


== Manpages and info files ==
%{?mingw_debug_package}


If manpages or info files are simply duplicates of equivalent
documentation found in Fedora native packages, then they should not be
packaged in the MinGW package.


== Static libraries ==
%prep
%setup -q -n example-%{version}


In accordance with ordinary Fedora policy, static libraries should not
be built, and if they are then they should be placed in a
<code>-static</code> subpackage.


== Stripping ==
%build
%mingw_configure --enable-static --enable-shared --enable-foo
%mingw_make %{?_smp_mflags}
 
 
%install
%mingw_make install DESTDIR=$RPM_BUILD_ROOT
 
# Libtool files don't need to be bundled
find $RPM_BUILD_ROOT -name "*.la" -delete
 
%mingw_find_lang example
 
 
# Note: there should be no %%files section for the main package!


Libraries and executables should be stripped.  This is done correctly
# Static subpackages are optional (as mentioned earlier)
and automatically if the spec file includes these lines:


%global __strip %{_cross_strip}
# Win32
%global __objdump %{_cross_objdump}
%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


(Note that if __strip and __objdump are not overridden in the specfile
%files -n mingw32-example-static
then this can sometimes cause Windows binaries to be corrupted).
%{mingw32_libdir}/libexample.a


== Debuginfo subpackage ==
# 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


Most binaries contain debugging symbols when the package gets built.
%files -n mingw64-example-static
To split the debugging symbols to a separate debuginfo package (as is done
%{mingw64_libdir}/libexample-0.a
with native Fedora packages) the spec file must include these lines:
%define __debug_install_post %{_cross_debug_install_post}
%{?_cross_debug_package}
Note that <code>%define</code> really must be used here. If you use <code>%global</code>
then the automatic generation of a debuginfo subpackage won't work


= Porting guide =


Users who already maintain a mingw32-* package in Fedora can use the [[MinGW/CrossCompilerFramework#Porting_guide porting guide]] to
%changelog
find more details about the exact changes which are required to make it build for multiple targets
* Sun Apr 15 2012 Erik van Pienbroek <epienbro@fedoraproject.org> - 1.0.0-1
- Initial release
</pre>


[[Category:Packaging guidelines drafts]]
[[Category:Packaging guidelines drafts]]

Latest revision as of 16:53, 19 May 2013

Packaging Guidelines for MinGW Cross Compilers

Updated Guidelines
These guidelines apply to all current Fedora releases. For RHEL-5 and RHEL-6 the old guidelines still apply which can be be found here: Packaging:MinGW_Old

Introduction

The Fedora MinGW project's mission is to provide an excellent development environment for Fedora users who wish to cross-compile their programs to run on Windows, minimizing the need to use Windows at all. In the past developers have had to port and compile all of the libraries and tools they have needed, and this huge effort has happened independently many times over. We aim to eliminate duplication of work for application developers by providing a range of libraries and development tools which have already been ported to the MinGW cross-compiler environment. This means that developers will not need to recompile the application stack themselves, but can concentrate just on the changes needed to their own application.

As of Fedora 17 a set of RPM macros and packages have been introduced which help packagers compile binaries for multiple targets. The targets Win32 and Win64 are supported.

Track Fedora native package versions

In general terms, cross-compiled MinGW versions of packages which are already natively available in Fedora, should follow the native Fedora package as closely as possible. This means they should stay at the same version, include all the same patches as the native Fedora package, and be built with the same configuration options.

The MinGW SIG have written an RPM comparison tool which makes it possible to compare cross compiled MinGW packages with the Fedora native packages, in order to determine whether versions, patches and configuration are aligned.

Follow Fedora policy

Cross compiled MinGW packages must follow Fedora policy, except where noted in this document. Cross compiled packages go through the same review process, GIT admin process etc as other Fedora packages.

Package naming

MinGW packages require special naming to denote the appropriate CPU architecture the binaries have been built for. There should never be a package prefixed with mingw- output during a build. The mingw- prefix is exclusive for RPM spec file names and the source RPM file name. The CPU architecture specific packages are created by sections with %files -n mingw32-foo or %files -n mingw64-foo.

mingw- Used for source package and RPM spec name
mingw32- Used for packages which are built for Win32
mingw64- Used for packages which are built for Win64

Base packages

The base packages provide a root filesystem, base libraries, binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc) and the Win32/Win64 API. Packages may need to depend on one or more of these. In particular, almost all packages should BuildRequire mingw32-filesystem, mingw64-filesystem, mingw32-gcc and mingw64-gcc. The correct Requires flags will get added automatically when the %{?mingw_package_header} macro is mentioned in the spec file (as will be described later on in these guidelines)

mingw32-filesystem / mingw64-filesystem Core filesystem directory layout, and RPM macros for spec files. Equivalent to 'filesystem' RPM
mingw32-binutils / mingw64-binutils Cross-compiled binutils (utilities like 'strip', 'as', 'ld') which understand Windows executables and DLLs. Equivalent to 'binutils' RPM
mingw32-gcc / mingw64-gcc GNU compiler collection. Compilers for C and C++ which cross-compile to a Windows target. Equivalent to gcc RPM
mingw32-crt / mingw64-crt Base libraries for core MinGW runtime & development environment. Equivalent to 'glibc' RPM
mingw32-headers / mingw64-headers Win32 and Win64 API. A free (public domain) reimplementation of the header files required to link to the Win32 and Win64 API. No direct equivalent in base Fedora - glibc-devel is closest

Build for multiple targets

The goal of the MinGW framework is to provide an easy way for package maintainers to build their packages for multiple targets using one .spec file. To aid developers in this several RPM macros have been developed which are part of the mingw-filesystem package. These RPM macros will be explained later on in these guidelines.

By default a MinGW package will be built for both the Win32 and Win64 targets.

When a package can only be built for either one of these targets this can be indicated by setting one of these:

%global mingw_build_win32 0 Don't build for the Win32 target
%global mingw_build_win64 0 Don't build for the Win64 target

One source RPM, separate binary RPMs per-target

Each cross compiled MinGW package which builds binaries for a specific target should put the binaries for that target in a separate subpackage. So if a package foo builds binaries for the Win32 and Win64 targets, then the source RPM should provide two subpackages named mingw32-foo and mingw64-foo.

This means that a spec file must contains %package and %files sections for all the targets.

If a package contains translations then all calls to the %find_lang must be replaced by %mingw_find_lang. This causes all translation filelists to be split in per-target filelists. For example: when a spec file contains something like this:

 %install
 <snip>
 %mingw_find_lang foo

then two files will get created named mingw32-foo.lang and mingw64-foo.lang. These file lists can be included in the %files section for the targets:

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

Filesystem layout

[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++
      |   +- ... 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 - see next diagram
      +- x86_64-w64-mingw32  - root of mingw toolchain and binaries for the Win64 target - see next diagram


/usr/i686-w64-mingw32
/usr/x86_64-w64-mingw32
  |
  +- 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

Filenames of the cross-compilers and binutils

The MinGW cross-compilers and binutils are Fedora binaries and are therefore placed in %{_bindir} (ie. /usr/bin) according to the FHS and Fedora guidelines.

The MinGW cross-compilers and binutils which generate i686 binaries for Windows are named:

 %{_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.

The same binaries are present in %{_prefix}/i686-w64-mingw32/bin without any prefix in the name, ie:

 %{_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.

The same also applies for the x86_64 target. This target uses 'x86_64-w64-mingw32' as prefix instead of 'i686-w64-mingw32'

Naming of the root filesystem

The root filesystem contains Windows executables and DLLs and any other Windows-only files. It is necessary both because we need to store Windows libraries in order to link further libraries which depend on them, and also because MinGW requires a root filesystem location.

The location for Win32 target is provided by the macro:

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

And the Win64 target is provided by the macro:

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

Standard mingw RPM macros

The mingw-filesystem package provides a number of convenience macros for the cross compiled sysroot directories, and toolchain. It is mandatory to use these macros in all MinGW cross compiled packages submitted to Fedora.

Toolchain macros

The following macros are for the %build and %install section of the spec

Generic macros:

Macro Available in
mingw-filesystem
Explanation
mingw_cmake >= 95 Call the cmake binary for all the configured targets
mingw_cmake_kde4 >= 95 Call the cmake binary for all the configured targets with KDE4 specific parameters set
mingw_configure >= 95 Call the configure command for all the configured targets
mingw_make >= 95 Call the 'make' command for all the configured targets
mingw_objcopy >= 95 cross compiler 'objcopy' binary (which supports both Win32 and Win64 binaries)
mingw_objdump >= 95 cross compiler 'objdump' binary (which supports both Win32 and Win64 binaries)
mingw_qmake_qt4 >= 95 Call the Qt4 qmake binary for all configured targets (requires mingw32-qt-qmake and/or mingw64-qt-qmake to be installed)
mingw_qmake_qt5 >= 96 Call the Qt5 qmake binary for all configured targets (requires mingw32-qt5-qmake and/or mingw64-qt5-qmake to be installed)
mingw_strip >= 95 cross compiler 'strip' binary (which supports both Win32 and Win64 binaries)


Win32 specific macros:

Macro Available in
mingw32-filesystem
Value Explanation
mingw32_ar >= 95 i686-w64-mingw32-ar cross compiler 'ar' binary
mingw32_cc >= 95 i686-w64-mingw32-gcc cross compiler 'gcc' binary
mingw32_cflags >= 95 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 Default compiler flags for C/C++ binaries
mingw32_cmake >= 95 Call the cmake binary for the Win32 target
mingw32_configure >= 95 standard invocation for autotools 'configure' scripts
mingw32_cpp >= 95 i686-w64-mingw32-gcc -E cross compiler 'cpp' binary
mingw32_env >= 95 Set the correct environment variables for the Win32 target
mingw32_host >= 95 i686-w64-mingw32 Host platform for build
mingw32_objcopy >= 95 i686-w64-mingw32-objcopy cross compiler 'objcopy' binary
mingw32_objdump >= 95 i686-w64-mingw32-objdump cross compiler 'objdump' binary
mingw32_pkg_config >= 95 i686-w64-mingw32-pkg-config Call the pkg-config command for the Win32 target
mingw32_qmake_qt4 >= 95 mingw32-qmake-qt4 Call the Qt4 qmake command for the Win32 target
mingw32_qmake_qt5 >= 96 mingw32-qmake-qt5 Call the Qt5 qmake command for the Win32 target
mingw32_ranlib >= 95 i686-w64-mingw32-ranlib cross compiler 'ranlib' binary
mingw32_strip >= 95 i686-w64-mingw32-strip cross compiler 'strip' binary
mingw32_target >= 95 i686-w64-mingw32 Target platform for build


Win64 specific macros:

Macro Available in
mingw64-filesystem
Value Explanation
mingw64_ar >= 95 x86_64-w64-mingw32-ar cross compiler 'ar' binary
mingw64_cc >= 95 x86_64-w64-mingw32-gcc cross compiler 'gcc' binary
mingw64_cflags >= 95 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 Default compiler flags for C/C++ binaries
mingw64_cmake >= 95 Call the cmake binary for the Win64 target
mingw64_configure >= 95 standard invocation for autotools 'configure' scripts
mingw64_cpp >= 95 x86_64-w64-mingw32-gcc -E cross compiler 'cpp' binary
mingw64_env >= 95 Set the correct environment variables for the Win64 target
mingw64_host >= 95 x86_64-w64-mingw32 Host platform for build
mingw64_objcopy >= 95 x86_64-w64-mingw32-objcopy cross compiler 'objcopy' binary
mingw64_objdump >= 95 x86_64-w64-mingw32-objdump cross compiler 'objdump' binary
mingw64_pkg_config >= 95 x86_64-w64-mingw32-pkg-config Call the pkg-config command for the Win64 target
mingw64_qmake_qt4 >= 95 mingw64-qmake-qt4 Call the Qt4 qmake command for the Win64 target
mingw64_qmake_qt5 >= 96 mingw64-qmake-qt5 Call the Qt5 qmake command for the Win64 target
mingw64_ranlib >= 95 x86_64-w64-mingw32-ranlib cross compiler 'ranlib' binary
mingw64_strip >= 95 x86_64-w64-mingw32-strip cross compiler 'strip' binary
mingw64_target >= 95 x86_64-w64-mingw32 Target platform for build

Filesystem location macros

The following macros are for use in %build, %install and %files sections of the RPM spec

For the Win32 target:

mingw32_bindir %{mingw32_prefix}/bin Location of Windows executables.
mingw32_datadir %{mingw32_prefix}/share Shared data used under Windows.
mingw32_docdir %{mingw32_prefix}/share/doc Documentation.
mingw32_infodir %{mingw32_prefix}/share/info Info files (see note below).
mingw32_includedir %{mingw32_prefix}/include Header files used when cross-compiling for Windows.
mingw32_libdir %{mingw32_prefix}/lib Windows libraries (see sections below).
mingw32_libexecdir %{mingw32_prefix}/libexec
mingw32_mandir %{mingw32_prefix}/share/man Man pages (see note below).
mingw32_prefix %{mingw32_sysroot}/mingw Windows equivalent of %{_prefix}, required by MinGW.
mingw32_sbindir %{mingw32_prefix}/sbin
mingw32_sysconfdir %{mingw32_prefix}/etc Configuration files used when running under Windows.
mingw32_sysroot %{_prefix}/i686-w64-mingw32/sys-root Windows system root.


For the Win64 target:

mingw64_bindir %{mingw64_prefix}/bin Location of Windows executables.
mingw64_datadir %{mingw64_prefix}/share Shared data used under Windows.
mingw64_docdir %{mingw64_prefix}/share/doc Documentation.
mingw64_infodir %{mingw64_prefix}/share/info Info files (see note below).
mingw64_includedir %{mingw64_prefix}/include Header files used when cross-compiling for Windows.
mingw64_libdir %{mingw64_prefix}/lib Windows libraries (see sections below).
mingw64_libexecdir %{mingw64_prefix}/libexec
mingw64_mandir %{mingw64_prefix}/share/man Man pages (see note below).
mingw64_prefix %{mingw64_sysroot}/mingw Windows equivalent of %{_prefix}, required by MinGW.
mingw64_sbindir %{mingw64_prefix}/sbin
mingw64_sysconfdir %{mingw64_prefix}/etc Configuration files used when running under Windows.
mingw64_sysroot %{_prefix}/x86_64-w64-mingw32/sys-root Windows system root.

Compilation of binaries

In order to build binaries for multiple targets we have to call commands like ./configure and make multiple times (once for each target). If one has to write this all out in a spec file then it will lead to duplicate code. To reduce the amount of duplication, several RPM macros have been introduced to help with the compilation. These macros are %mingw_configure, %mingw_cmake, %mingw_cmake_kde4, %mingw_qmake_qt4, %mingw_qmake_qt5 and %mingw_make

These macros use out of source compilation to build binaries for all the targets. Almost all packages support out of source compilation or require slight patching. The only known exceptions to date are zlib and openssl. Packages which don't support out of source compilation may require a different approach like performing everything in the %install phase. If you happen to stumble across a package which requires a different approach feel free to contact us on the Fedora MinGW mailing list

Some packages need to be built multiple times for each target. Examples of this are packages which have to be built once for a static version and once for a shared version. Such packages can add a custom suffix to the build directory used. Say you've got something like below:

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

This can be rewritten to something like this:

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

Most packages used the command make %{?_smp_mflags} to build the package. In the MinGW cross compiler framework you have to use %mingw_make %{?_smp_mflags} to build the package for all configured targets. As with the %mingw_configure macro you can also use the MINGW_BUILDDIR_SUFFIX environment variable to indicate a custom suffix to the build directory used

To install the package the command make install DESTDIR=$RPM_BUILD_ROOT was used in almost all cases. This can be rewritten to %mingw_make install DESTDIR=$RPM_BUILD_ROOT to install the package for all configured targets The environment variable MINGW_BUILDDIR_SUFFIX can also be used here

Some packages require some custom instructions before the files are ready to be packaged. Such code can remain as is. However, you may need to duplicate these instructions multiple times (for all configured targets).

Dependencies

If a package contains binaries which depend on a DLL provided by another package, these dependencies should be expressed in the form:

 mingw32(foo.dll)

where foo.dll is the name of the DLL. The name must be converted to lowercase because Windows binaries contain case insensitive dependencies. The form 'mingw32(foo.dll)' should be used for Win32 binaries and the form 'mingw64(foo.dll)' for Win64 binaries.

Correct dependency generation is done automatically. Packagers should start their spec files with this line:

 %{?mingw_package_header}

All binary packages should depend on mingw32-filesystem or mingw64-filesystem (depending on the files in the package). If the line mentioned above is used then it will be added automatically, so you don't have to add it yourself

All specfiles should BuildRequire at least one of these (depending on the targets for which you want to build):

BuildRequires:  mingw32-filesystem >= minimum-version
BuildRequires:  mingw64-filesystem >= minimum-version

and any other BuildRequires that they need.

The minimum-version must be at least 95 or any later version which provides the functionality you need

Build architecture

All packages should have:

BuildArch: noarch

unless they contain Fedora native executables.

Libraries (DLLs)

All libraries must be built as DLLs.

Because of the peculiarity of Windows, DLLs are stored in the %{mingw32_bindir} directory, along with a control file in the %{mingw32_libdir} directory. For example, for a library called foo there would be:

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

The foo.dll file is the main library, foo.dll.a is a stub linked to applications so they can find the library at runtime. All of these files are required in those locations in order to link successfully. The .dll may contain a version number although not always (eg. foo-0.dll).

Do not use %{mingw32_bindir}/* or %{mingw32_libdir}/* in %files section

The %files section must list DLLs and import libraries separately. Packages must NOT use %{mingw32_bindir}/* or %{mingw32_libdir}/*

The reason for this is that libtool is very fragile and will give up on building a DLL very easily. Therefore we force the name of the DLL to be listed explicitly in the %files section in order to catch this during RPM builds.

Stripping

Libraries and executables should be stripped. This is done correctly and automatically if the spec file starts with this line:

 %{?mingw_package_header}
%mingw_package_header
The %mingw_package_header macro sets the strip, objdump, and debuginfo generating commands appropriately for windows binaries. Without this line Windows binaries may be corrupted by the automatic tasks that rpm performs on the built binaries.

Debuginfo subpackage

Most binaries contain debugging symbols when the package gets built. To split the debugging symbols to a separate debuginfo package (as is done with native Fedora packages) the spec file must include these lines:

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

The %{?mingw_debug_package} line must be placed after the %description tag. Otherwise spectool and other RPM tools may fail to function

Executables (EXEs)

Most libraries also provide executables. These can include executables which can be used to test or showcase the library in question (for example gtk3-demo.exe in mingw-gtk3). Other examples are helper executables which are used by the library itself internally (for example gspawn-win32-helper.exe in mingw-glib2). It is allowed to bundle all executables which built while compiling libraries in the binary rpms. These executables have to be added to the main mingw32-foo / mingw64-foo subpackages (where the regular libraries and headers are also placed).

Files which are already part of native packages

There are various types of files which are simply duplicates of equivalent files found in Fedora native packages. These files should not be packaged in the MinGW package. The following files don't need to be packaged in the MinGW package when their native counterpart already contains them:

  • Man pages (%{mingw32_mandir} / %{mingw64_mandir})
  • Info files (%{mingw32_infodir} / %{mingw64_infodir})
  • Generic documentation (%{mingw32_docdir} / %{mingw64_docdir})
  • Autoconf files (%{mingw32_datadir}/aclocal / %{mingw64_datadir}/aclocal)
  • gtk-doc files (%{mingw32_datadir}/gtk-doc / %{mingw64_datadir}/gtk-doc)

Example Specfile

%{?mingw_package_header}

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

License:        LGPLv2+
URL:            http://fedoraproject.org
Source0:        http://fedoraproject.org/example-%{version}.tar.bz2

BuildArch:      noarch

BuildRequires:  mingw32-filesystem >= 95
BuildRequires:  mingw32-gcc
BuildRequires:  mingw32-binutils
BuildRequires:  mingw32-gettext
BuildRequires:  mingw32-win-iconv
BuildRequires:  mingw32-zlib

BuildRequires:  mingw64-filesystem >= 95
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
%setup -q -n example-%{version}


%build
%mingw_configure --enable-static --enable-shared --enable-foo
%mingw_make %{?_smp_mflags}


%install
%mingw_make install DESTDIR=$RPM_BUILD_ROOT

# Libtool files don't need to be bundled
find $RPM_BUILD_ROOT -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