From Fedora Project Wiki

(Updated the example because of the mingw32-filesystem >= 68 changes)
 
(14 intermediate revisions by 3 users not shown)
Line 1: Line 1:
= Packaging Guidelines for MinGW Windows cross-compiler =
= Packaging Guidelines for MinGW Windows cross-compiler =


<b>Please note this is a draft</b>. "Rationale" sections are
{{admon/important|Future Changes|These guidelines apply to all active Fedora releases (including RHEL-6 and older). New guidelines for MinGW have been approved, but are not yet in use: [[Packaging:MinGW_Future]] }}
for discussion and will be deleted from the final document.


== Naming ==
= Introduction =


Packages should be named by prefixing the upstream package name
The Fedora MinGW project's mission is to provide an excellent
with <code>mingw-</code>
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.


<i>Rationale</i>  Debian name their packages <code>mingw32-*</code>.
= Track Fedora native package versions =
However I can't see a reason for including '32' in the name, particularly
since (a) the upstream package is just called mingw and (b)
we may want to build 64 bit binaries.


== Base packages ==
In general terms, MinGW packages which provide cross-compiled versions
of packages 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 base packages provide a root filesystem, base libraries,
The MinGW SIG have written an RPM comparison tool which makes it
binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc)
possible to compare MinGW packages with the Fedora native packages, in
and the Win32 API.  Packages may need to depend on one or more of
order to determine whether versions, patches and configuration are
these.  In particular, almost any conceivable package should
aligned.
depend on <code>mingw-runtime</code>.
 
= Follow Fedora policy =
 
MinGW packages must follow Fedora policy, except where noted in this
document.  MinGW packages go through the same review process, CVS
admin process etc as other Fedora packages.
 
= Package naming =
 
Built packages should be named by prefixing the upstream package name
with <code>mingw32-</code>
 
Source packages can be named starting with <code>mingw-</code> in order to more easily support a transition to the new MinGW guidelines which mandate that naming.  Otherwise two separate package repositories must be set up ("mingw32-foo" and "mingw-foo") with one needing to be marked EOL.
 
= Base packages =
 
The base packages provide a root filesystem, base libraries, binutils
(basic programs like 'strip', 'ld' etc), the compiler (gcc) and the
Win32 API.  Packages may need to depend on one or more of these.  In
particular, almost any conceivable package should depend on
<code>mingw32-filesystem</code> and <code>mingw32-runtime</code>.


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


<i>Rationale</i>  I've used the same names as the upstream packages, and also the same
= Filesystem layout =
names as Debian (minus the unnecessary '32' which Debian has in the name).
 
== Filesystem layout ==


  [root]
  [root]
Line 45: Line 71:
   |  +- rpm
   |  +- rpm
   |      |
   |      |
   |      +- macros.mingw
   |      +- macros.mingw32
   |
   |
   +- usr
   +- usr
Line 51: Line 77:
       +- bin  - Links to cross compiler toolchain
       +- bin  - Links to cross compiler toolchain
       |  |
       |  |
       |  +- i686-pc-mingw-cpp
       |  +- i686-pc-mingw32-cpp
       |  +- i686-pc-mingw-gcc
       |  +- i686-pc-mingw32-gcc
       |  +- i686-pc-mingw-g++
       |  +- i686-pc-mingw32-g++
       |  +- ... etc..
       |  +- ... etc..
       |
       |
Line 60: Line 86:
       |  +- rpm
       |  +- rpm
       |      |
       |      |
       |      +- mingw-defs  - custom helper scripts for auto-requires, binary stripping, etc
       |      +- mingw32-defs  - custom helper scripts for auto-requires, binary stripping, etc
       |      +- mingw-find-provides.sh - extra DLL names
       |      +- mingw32-find-provides.sh - extra DLL names
       |      +- mingw-find-requires.sh - discover required DLL names
       |      +- mingw32-find-requires.sh - discover required DLL names
       |
       |
       +- i686-pc-mingw - root of mingw toolchain and binaryes - see next diagram
       +- i686-pc-mingw32 - root of mingw toolchain and binaries - see next diagram




  [mingw-root]
  /usr/i686-pc-mingw32
   |
   |
   +- bin  - Cross compiler toolchain   
   +- bin  - Cross compiler toolchain   
Line 93: Line 119:
               +- man
               +- man


== Standard mingw RPM macros ==
= Filenames of the cross-compilers and binutils =
 
The 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.
 
The cross-compilers and binutils which generate i686 binaries for Windows are named:
 
%{_bindir}/i686-pc-mingw32-gcc
%{_bindir}/i686-pc-mingw32-g++
%{_bindir}/i686-pc-mingw32-ld
%{_bindir}/i686-pc-mingw32-as
%{_bindir}/i686-pc-mingw32-strip
etc.
 
The same binaries are present in
<code>%{_prefix}/i686-pc-mingw32/bin</code> without any prefix in the
name, ie:
 
%{_prefix}/i686-pc-mingw32/bin/gcc
%{_prefix}/i686-pc-mingw32/bin/g++
%{_prefix}/i686-pc-mingw32/bin/ld
%{_prefix}/i686-pc-mingw32/bin/as
%{_prefix}/i686-pc-mingw32/bin/strip
etc.
 
= Naming of the root filesystem =


The <code>mingw-filesystem</code> 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 packages submitted to Fedora.
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 i686 target) is provided by the macro:


=== Toolchain macros ===
%{_mingw32_sysroot}  %{_prefix}/i686-pc-mingw32/sys-root
 
= Standard mingw RPM macros =
 
The <code>mingw32-filesystem</code> 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 packages
submitted to Fedora.
 
== Toolchain macros ==


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


{|
{|
| _mingw_ar || i686-pc-mingw32-ar || cross compiler 'ar' binary
| _mingw32_ar || i686-pc-mingw32-ar || cross compiler 'ar' binary
|-
|-
| _mingw_cc || i686-pc-mingw32-gcc || cross compiler 'gcc' binary
| _mingw32_cc || i686-pc-mingw32-gcc || cross compiler 'gcc' binary
|-
|-
| _mingw_cflags || -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -I%{_mingw_includedir} || Rationale: we need to remove the -m64 flag from standar RPM_OPTS_FLAGS
| _mingw32_cflags || -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 ||
|-
|-
| _mingw_configure || CC="%{_mingw_cc}"  CFLAGS="%{_mingw_cflags}"  ./configure  --build=%_build --host=%{_mingw_host} --target=%{_mingw_target}  --prefix=%{_mingw_prefix} || standard invocation for autotools 'configure' scripts
| _mingw32_configure || CC="%{_mingw32_cc}"  CFLAGS="%{_mingw32_cflags}"  ./configure  --build=%_build --host=%{_mingw32_host} --target=%{_mingw32_target}  --prefix=%{_mingw32_prefix} || standard invocation for autotools 'configure' scripts
|-
|-
| _mingw_cpp || i686-pc-mingw32-gcc -E || cross compiler 'cpp' binary
| _mingw32_cpp || i686-pc-mingw32-gcc -E || cross compiler 'cpp' binary
|-
|-
| _mingw_host || i686-pc-mingw32  || Host platform for build
| _mingw32_host || i686-pc-mingw32  || Host platform for build
|-
|-
| _mingw_objdump || i686-pc-mingw32-objdump || cross compiler 'objdump' binary
| _mingw32_objdump || i686-pc-mingw32-objdump || cross compiler 'objdump' binary
|-
|-
| _mingw_ranlib || i686-pc-mingw32-ranlib || cross compiler 'ranlib' binary
| _mingw32_ranlib || i686-pc-mingw32-ranlib || cross compiler 'ranlib' binary
|-
|-
| _mingw_strip || i686-pc-mingw32-strip || cross compiler 'strip' binary  
| _mingw32_strip || i686-pc-mingw32-strip || cross compiler 'strip' binary  
|-
|-
| _mingw_target || i686-pc-mingw32 || Target platform for build
| _mingw32_target || i686-pc-mingw32 || Target platform for build
|}
|}


=== Filesystem location macros ===
== Filesystem location macros ==


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


{|
{|
|_mingw_bindir || %{_mingw_prefix}/bin
|_mingw32_bindir || %{_mingw32_prefix}/bin || Location of Windows executables.
|-
|_mingw32_datadir || %{_mingw32_prefix}/share || Shared data used under Windows.
|-
|-
|_mingw_datadir || %{_mingw_prefix}/share
|_mingw32_docdir || %{_mingw32_prefix}/share/doc || Documentation.
|-
|-
|_mingw_docdir || %{_mingw_prefix}/share/doc
|_mingw32_infodir || %{_mingw32_prefix}/share/info || Info files (see note below).
|-
|-
|_mingw_includedir || %{_mingw_prefix}/include
|_mingw32_includedir || %{_mingw32_prefix}/include || Header files used when cross-compiling for Windows.
|-
|-
|_mingw_libdir || %{_mingw_prefix}/lib
|_mingw32_libdir || %{_mingw32_prefix}/lib || Windows libraries (see sections below).
|-
|-
|_mingw_libexecdir || %{_mingw_prefix}/libexec
|_mingw32_libexecdir || %{_mingw32_prefix}/libexec ||
|-
|-
|_mingw_mandir || %{_mingw_prefix}/share/man
|_mingw32_mandir || %{_mingw32_prefix}/share/man || Man pages (see note below).
|-
|-
|_mingw_prefix || %{_mingw_sysroot}/mingw
|_mingw32_prefix || %{_mingw32_sysroot}/mingw || Windows equivalent of %{_prefix}, required by MinGW.
|-
|-
|_mingw_sbindir || %{_mingw_prefix}/sbin
|_mingw32_sbindir || %{_mingw32_prefix}/sbin ||
|-
|-
|_mingw_sysconfdir || %{_mingw_prefix}/etc
|_mingw32_sysconfdir || %{_mingw32_prefix}/etc || Configuration files used when running under Windows.
|-
|-
|_mingw_sysroot || %{_prefix}/i686-pc-mingw32/sys-root
|_mingw32_sysroot || %{_prefix}/i686-pc-mingw32/sys-root || Windows system root.
|}
|}


== Naming of the cross-compilers and binutils ==
= 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 <code>foo.dll</code> is the name of the DLL.  The name must be
converted to lowercase because Windows binaries contain case
insensitive dependencies.
 
All packages should depend on <code>mingw32-filesystem</code>.
 
Correct dependency generation is done automatically when using mingw32-filesystem >= 68
which is available in Fedora 15 and above.
 
When a package also needs to be made available for RHEL-5 or RHEL-6 then
packagers should include these lines in their packages:
 
%global _use_internal_dependency_generator 0
%global __find_requires %{_mingw32_findrequires}
%global __find_provides %{_mingw32_findprovides}
 
All specfiles should BuildRequire at least:


The 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.
BuildRequires:  mingw32-filesystem >= minimum-version


The cross-compilers and binutils which generate i686 binaries for Windows are named:
and any other BuildRequires that they need.


%{_bindir}/i686-pc-mingw32-gcc
= Build architecture =
%{_bindir}/i686-pc-mingw32-g++
%{_bindir}/i686-pc-mingw32-ld
%{_bindir}/i686-pc-mingw32-as
%{_bindir}/i686-pc-mingw32-strip
etc.


The same binaries are present in <code>%{_prefix}/i686-pc-mingw32/bin</code> without any prefix in the name, ie:
All packages should have:


  %{_prefix}/i686-pc-mingw32/bin/gcc
  BuildArch: noarch
%{_prefix}/i686-pc-mingw32/bin/g++
%{_prefix}/i686-pc-mingw32/bin/ld
%{_prefix}/i686-pc-mingw32/bin/as
%{_prefix}/i686-pc-mingw32/bin/strip
etc.


Note that we don't support generating x86-64 binaries (or any other architecture)
unless they contain Fedora native executables.
at the moment, but if we do those will have a different prefix.


<i>Rationale</i>  This is the name which autoconf configure scripts expect when they are
= Libraries (DLLs) =
invoked in cross-compiling mode.  The <code>/usr/i686-pc-mingw32/bin</code>
directory is required by GCC, otherwise it invokes the wrong assembler and linker.


== Naming of the root filesystem ==
All libraries must be built as DLLs.


The root filesystem contains Windows executables and DLLs and any other Windows-only
Because of the peculiarity of Windows, DLLs are stored in the
files.  It is necessary both because we need to store Windows libraries in order to
<code>%{_mingw32_bindir}</code> directory, along with a control file in
link further libraries which depend on them, and also because MinGW requires a
the <code>%{_mingw32_libdir}</code> directoryFor example, for a
root filesystem locationThe location (for i686 target) is provided by the macro:
library called <code>foo</code> there would be:


  %{_mingw_sysroot}   %{_prefix}/i686-pc-mingw/sys-root
  %{_mingw32_bindir}/foo.dll
%{_mingw32_libdir}/foo.dll.a
%{_mingw32_libdir}/foo.la


<i>Rationale</i> This is what the existing Fedora packages do, and very
All files are required in those locations in order to link
similar to what Debian is doing (they use a different and inconsistent name, but
successfully, except that the <code>.dll</code> may contain
it is still a directory located directly under /usr), and is what MinGW expects.
a version number although not always (eg. <code>foo-0.dll</code>).


== Packaging DLLs ==
Some packages also install a <code>.def</code> file in %{_mingw32_libdir}.
Such files can usually be deleted as they only contain information
which is needed to generate the <code>.dll</code> file in question and serve
no purpose for packages which want to link against these .dll files.


The Fedora MinGW SIG packages a range of common Linux libraries as Windows DLLs
== Do not use %{_mingw32_bindir}/* or %{_mingw32_libdir}/* in %files section ==
so that further libraries/programs can be compiled against them.


These libraries should be packaged in the directory provided by the macro:
The <code>%files</code> section must list DLLs separately.  Packages
must NOT use <code>%{_mingw32_bindir}/*</code> or
<code>%{_mingw32_libdir}/*</code>


  %{_mingw_libdir}    %{_mingw_sysroot}/lib
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.


<i>Rationale</i>  Specified by MinGW.  Putting them in %{_libdir} is not desirable
== Manpages and info files ==
because they are not intended for use on the host system. They are cross-compiled binaries only executable on the Windows platform, or under an environment like Wine.


== Packaging EXEs ==
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.


Any Windows binaries should be packaged in the directory given by the macro:
== Static libraries ==


%{_mingw_bindir}    %{_mingw_sysroot}/bin
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.


<i>Rationale</i> Specified by MinGW.  Not applicable for /usr/bin as these are cross-compiled binaries only intended for execution under Windows, or an environment like Wine.
The exception is the base package <code>mingw32-w32api</code> which
contains static libraries that are required for GCC to create
executables.


== Packaging header files and other auxiliary files ==
== Stripping ==


Any auxiliary Windows files should be placed in the standard subdirectories of the
Libraries and executables should be stripped.  This is done correctly
root filesystem, for example:
and automatically if the spec file includes these lines:


  %{_mingw_includedir} %{_mingw_sysroot}/include
  %global __strip %{_mingw32_strip}
  %{_mingw_datadir}    %{_mingw_sysroot}/share
  %global __objdump %{_mingw32_objdump}
etc.


== Dependencies ==
(Note that if __strip and __objdump are not overridden in the specfile
then this can sometimes cause Windows binaries to be corrupted).


If a package contains binaries which depend on a DLL provided by another package, these dependencies should be expressed in the form:
== Example Specfile ==
<pre>
%global __strip %{_mingw32_strip}
%global __objdump %{_mingw32_objdump}
%define __debug_install_post %{_mingw32_debug_install_post}


mingw(foo.dll)
Name:          mingw-example
Version:        1.2.3
Release:        1%{?dist}
Summary:       


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.
License:        LGPLv2+
Group:          Development/Libraries
URL:           
Source0:       


All packages should depend on <code>mingw-filesystem</code>.
BuildArch:      noarch


Correct dependency generation is done automatically. Packagers should include this line in all library packages:
BuildRequires:  mingw32-filesystem >= 68
BuildRequires: mingw32-gcc
BuildRequires: mingw32-binutils
# Any additional BuildRequires.


%include /usr/lib/rpm/mingw-defs
%description
# description


All specfiles should BuildRequire at least:
%package -n mingw32-example
Summary:
%description -n mingw32-example
# description


BuildRequires:  mingw-filesystem >= minimum-version


and any other BuildRequires at they need.
%{?_mingw32_debug_package}


== Build architecture ==


All packages should have:
%prep
%setup -q -n example-%{version}


BuildArch: noarch


unless they contain Fedora native executables.
%build
%{_mingw32_configure}
make %{?_smp_mflags}


<i>Rationale</i>  Windows executables always target 32 bit x86 at present, and so (in theory) should be
identical whatever Fedora architecture was used to build or host them.


== DLLs ==
%install
make DESTDIR=$RPM_BUILD_ROOT install


All libraries must be built as DLLs.
# Remove static libraries but DON'T remove *.dll.a files.
rm $RPM_BUILD_ROOT%{_mingw32_libdir}/libfoo.a


Because of the peculiarity of Windows, DLLs are stored in the %{_mingw_bindir} directory, along with a control file in the %{_mingw_libdir} directory.  For example, for a library called <code>foo</code> there would be:


%{_mingw_bindir}/foo.dll
%files -n mingw32-example
%{_mingw_libdir}/foo.dll.a
%doc COPYING
%{_mingw32_bindir}/foo.dll
%{_mingw32_libdir}/foo.dll.a
# etc.


Both files are requires in those locations in order to link correctly.


The <code>%files</code> section must list DLLs separately. Packages must NOT use <code>%{_mingw_bindir}/*</code>
%changelog
* Wed Sep 10 2008 Richard W.M. Jones <rjones@redhat.com> - 1.2.3-1
- Initial RPM release.
</pre>


<i>Rationale</i> 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.
[[Category:Packaging guidelines drafts]]

Latest revision as of 22:22, 30 November 2011

Packaging Guidelines for MinGW Windows cross-compiler

Future Changes
These guidelines apply to all active Fedora releases (including RHEL-6 and older). New guidelines for MinGW have been approved, but are not yet in use: Packaging:MinGW_Future

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 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.

Track Fedora native package versions

In general terms, MinGW packages which provide cross-compiled versions of packages 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 MinGW packages with the Fedora native packages, in order to determine whether versions, patches and configuration are aligned.

Follow Fedora policy

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

Package naming

Built packages should be named by prefixing the upstream package name with mingw32-

Source packages can be named starting with mingw- in order to more easily support a transition to the new MinGW guidelines which mandate that naming. Otherwise two separate package repositories must be set up ("mingw32-foo" and "mingw-foo") with one needing to be marked EOL.

Base packages

The base packages provide a root filesystem, base libraries, binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc) and the Win32 API. Packages may need to depend on one or more of these. In particular, almost any conceivable package should depend on mingw32-filesystem and mingw32-runtime.

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

Filesystem layout

[root]
  |
  +- etc
  |   |
  |   +- rpm
  |       |
  |       +- macros.mingw32
  |
  +- usr
      |
      +- bin   - Links to cross compiler toolchain
      |   |
      |   +- i686-pc-mingw32-cpp
      |   +- i686-pc-mingw32-gcc
      |   +- i686-pc-mingw32-g++
      |   +- ... etc..
      |
      +- lib
      |   |
      |   +- rpm
      |       |
      |       +- mingw32-defs   - custom helper scripts for auto-requires, binary stripping, etc
      |       +- mingw32-find-provides.sh - extra DLL names
      |       +- mingw32-find-requires.sh - discover required DLL names
      |
      +- i686-pc-mingw32  - root of mingw toolchain and binaries - see next diagram


/usr/i686-pc-mingw32
  |
  +- bin  - Cross compiler toolchain  
  |   |
  |   +- cpp
  |   +- gcc
  |   +- g++
  |   +- ... etc ...
  |
  +- lib  - Cross compiler toolchain support libraries / files
  |
  +- sys-root  - root for cross compiled binaries
      |
      +- mingw
          |
          +- bin     - cross-compiled binaries & runtime DLL parts
          +- doc     - documentation
          +- include - include files for cross compiled libs
          +- lib     - cross-compiled static libraries & linktime DLL parts
          |   |
          |   +- pkgconfig  - pkg-config definitions for libraries
          |
          +- share
              |
              +- man

Filenames of the cross-compilers and binutils

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

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

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

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

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

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 i686 target) is provided by the macro:

%{_mingw32_sysroot}   %{_prefix}/i686-pc-mingw32/sys-root

Standard mingw RPM macros

The mingw32-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 packages submitted to Fedora.

Toolchain macros

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

_mingw32_ar i686-pc-mingw32-ar cross compiler 'ar' binary
_mingw32_cc i686-pc-mingw32-gcc cross compiler 'gcc' binary
_mingw32_cflags -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4
_mingw32_configure CC="%{_mingw32_cc}" CFLAGS="%{_mingw32_cflags}" ./configure --build=%_build --host=%{_mingw32_host} --target=%{_mingw32_target} --prefix=%{_mingw32_prefix} standard invocation for autotools 'configure' scripts
_mingw32_cpp i686-pc-mingw32-gcc -E cross compiler 'cpp' binary
_mingw32_host i686-pc-mingw32 Host platform for build
_mingw32_objdump i686-pc-mingw32-objdump cross compiler 'objdump' binary
_mingw32_ranlib i686-pc-mingw32-ranlib cross compiler 'ranlib' binary
_mingw32_strip i686-pc-mingw32-strip cross compiler 'strip' binary
_mingw32_target i686-pc-mingw32 Target platform for build

Filesystem location macros

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

_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-pc-mingw32/sys-root Windows system root.

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.

All packages should depend on mingw32-filesystem.

Correct dependency generation is done automatically when using mingw32-filesystem >= 68 which is available in Fedora 15 and above.

When a package also needs to be made available for RHEL-5 or RHEL-6 then packagers should include these lines in their packages:

%global _use_internal_dependency_generator 0
%global __find_requires %{_mingw32_findrequires}
%global __find_provides %{_mingw32_findprovides}

All specfiles should BuildRequire at least:

BuildRequires:  mingw32-filesystem >= minimum-version

and any other BuildRequires that they 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
%{_mingw32_libdir}/foo.la

All files are required in those locations in order to link successfully, except that the .dll may contain a version number although not always (eg. foo-0.dll).

Some packages also install a .def file in %{_mingw32_libdir}. Such files can usually be deleted as they only contain information which is needed to generate the .dll file in question and serve no purpose for packages which want to link against these .dll files.

Do not use %{_mingw32_bindir}/* or %{_mingw32_libdir}/* in %files section

The %files section must list DLLs 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.

Manpages and info files

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

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

The exception is the base package mingw32-w32api which contains static libraries that are required for GCC to create executables.

Stripping

Libraries and executables should be stripped. This is done correctly and automatically if the spec file includes these lines:

%global __strip %{_mingw32_strip}
%global __objdump %{_mingw32_objdump}

(Note that if __strip and __objdump are not overridden in the specfile then this can sometimes cause Windows binaries to be corrupted).

Example Specfile

%global __strip %{_mingw32_strip}
%global __objdump %{_mingw32_objdump}
%define __debug_install_post %{_mingw32_debug_install_post}

Name:           mingw-example
Version:        1.2.3
Release:        1%{?dist}
Summary:        

License:        LGPLv2+
Group:          Development/Libraries
URL:            
Source0:        

BuildArch:      noarch

BuildRequires:  mingw32-filesystem >= 68
BuildRequires:  mingw32-gcc
BuildRequires:  mingw32-binutils
# Any additional BuildRequires.

%description
# description

%package -n mingw32-example
Summary:
%description -n mingw32-example
# description


%{?_mingw32_debug_package}


%prep
%setup -q -n example-%{version}


%build
%{_mingw32_configure}
make %{?_smp_mflags}


%install
make DESTDIR=$RPM_BUILD_ROOT install

# Remove static libraries but DON'T remove *.dll.a files.
rm $RPM_BUILD_ROOT%{_mingw32_libdir}/libfoo.a


%files -n mingw32-example
%doc COPYING
%{_mingw32_bindir}/foo.dll
%{_mingw32_libdir}/foo.dll.a
# etc.


%changelog
* Wed Sep 10 2008 Richard W.M. Jones <rjones@redhat.com> - 1.2.3-1
- Initial RPM release.